diff --git a/cumulus/Cargo.lock b/cumulus/Cargo.lock index feddcc5427cfc877b796eb9b908cfad5f4337ec2..6c5a4a2b06538e36bbdaf0ccfc8999266c833ff8 100644 --- a/cumulus/Cargo.lock +++ b/cumulus/Cargo.lock @@ -225,12 +225,15 @@ dependencies = [ [[package]] name = "async-global-executor" -version = "1.4.3" +version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73079b49cd26b8fd5a15f68fc7707fc78698dc2a3d61430f2a7a9430230dfa04" +checksum = "9586ec52317f36de58453159d48351bc244bc24ced3effc1fce22f3d48664af6" dependencies = [ + "async-channel", "async-executor", "async-io", + "async-mutex", + "blocking", "futures-lite", "num_cpus", "once_cell", @@ -256,6 +259,15 @@ dependencies = [ "winapi 0.3.9", ] +[[package]] +name = "async-lock" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6a8ea61bf9947a1007c5cada31e647dbc77b103c679858150003ba697ea798b" +dependencies = [ + "event-listener", +] + [[package]] name = "async-mutex" version = "1.4.0" @@ -283,17 +295,16 @@ dependencies = [ [[package]] name = "async-std" -version = "1.8.0" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f9f84f1280a2b436a2c77c2582602732b6c2f4321d5494d6e799e6c367859a8" +checksum = "d9f06685bad74e0570f5213741bea82158279a4103d988e57bfada11ad230341" dependencies = [ "async-attributes", "async-channel", "async-global-executor", "async-io", - "async-mutex", + "async-lock", "async-process", - "blocking", "crossbeam-utils 0.8.1", "futures-channel", "futures-core", @@ -331,6 +342,19 @@ version = "4.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e91831deabf0d6d7ec49552e489aed63b7456a7a3c46cff62adad428110b0af0" +[[package]] +name = "async-tls" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f23d769dbf1838d5df5156e7b1ad404f4c463d1ac2c6aeb6cd943630f8a8400" +dependencies = [ + "futures-core", + "futures-io", + "rustls 0.19.0", + "webpki 0.21.4", + "webpki-roots", +] + [[package]] name = "async-trait" version = "0.1.50" @@ -453,7 +477,7 @@ checksum = "6736e2428df2ca2848d846c43e88745121a6654696e349ce0054a420815a7409" [[package]] name = "beefy-gadget" version = "0.1.0" -source = "git+https://github.com/paritytech/grandpa-bridge-gadget?branch=master#021e233fab35301ad3914c6de2ee708a9d591bf4" +source = "git+https://github.com/paritytech/grandpa-bridge-gadget?branch=master#5f2d59bdaae602d381d02a3ee705c34b511a7114" dependencies = [ "beefy-primitives", "futures 0.3.14", @@ -481,7 +505,7 @@ dependencies = [ [[package]] name = "beefy-gadget-rpc" version = "0.1.0" -source = "git+https://github.com/paritytech/grandpa-bridge-gadget?branch=master#021e233fab35301ad3914c6de2ee708a9d591bf4" +source = "git+https://github.com/paritytech/grandpa-bridge-gadget?branch=master#5f2d59bdaae602d381d02a3ee705c34b511a7114" dependencies = [ "beefy-gadget", "beefy-primitives", @@ -502,7 +526,7 @@ dependencies = [ [[package]] name = "beefy-primitives" version = "0.1.0" -source = "git+https://github.com/paritytech/grandpa-bridge-gadget?branch=master#021e233fab35301ad3914c6de2ee708a9d591bf4" +source = "git+https://github.com/paritytech/grandpa-bridge-gadget?branch=master#5f2d59bdaae602d381d02a3ee705c34b511a7114" dependencies = [ "parity-scale-codec", "sp-api", @@ -685,7 +709,7 @@ dependencies = [ [[package]] name = "bp-header-chain" version = "0.1.0" -source = "git+https://github.com/paritytech/polkadot?branch=master#d67d2adf51ac836f4d549b059cbf33eb4d7cc6e3" +source = "git+https://github.com/paritytech/polkadot?branch=master#ca22bdca70a595db8b7ad1502919769d1472ffb9" dependencies = [ "finality-grandpa", "frame-support", @@ -700,7 +724,7 @@ dependencies = [ [[package]] name = "bp-messages" version = "0.1.0" -source = "git+https://github.com/paritytech/polkadot?branch=master#d67d2adf51ac836f4d549b059cbf33eb4d7cc6e3" +source = "git+https://github.com/paritytech/polkadot?branch=master#ca22bdca70a595db8b7ad1502919769d1472ffb9" dependencies = [ "bp-runtime", "frame-support", @@ -712,7 +736,7 @@ dependencies = [ [[package]] name = "bp-polkadot-core" version = "0.1.0" -source = "git+https://github.com/paritytech/polkadot?branch=master#d67d2adf51ac836f4d549b059cbf33eb4d7cc6e3" +source = "git+https://github.com/paritytech/polkadot?branch=master#ca22bdca70a595db8b7ad1502919769d1472ffb9" dependencies = [ "bp-messages", "bp-runtime", @@ -729,7 +753,7 @@ dependencies = [ [[package]] name = "bp-rococo" version = "0.1.0" -source = "git+https://github.com/paritytech/polkadot?branch=master#d67d2adf51ac836f4d549b059cbf33eb4d7cc6e3" +source = "git+https://github.com/paritytech/polkadot?branch=master#ca22bdca70a595db8b7ad1502919769d1472ffb9" dependencies = [ "bp-header-chain", "bp-messages", @@ -745,7 +769,7 @@ dependencies = [ [[package]] name = "bp-runtime" version = "0.1.0" -source = "git+https://github.com/paritytech/polkadot?branch=master#d67d2adf51ac836f4d549b059cbf33eb4d7cc6e3" +source = "git+https://github.com/paritytech/polkadot?branch=master#ca22bdca70a595db8b7ad1502919769d1472ffb9" dependencies = [ "frame-support", "hash-db", @@ -762,7 +786,7 @@ dependencies = [ [[package]] name = "bp-test-utils" version = "0.1.0" -source = "git+https://github.com/paritytech/polkadot?branch=master#d67d2adf51ac836f4d549b059cbf33eb4d7cc6e3" +source = "git+https://github.com/paritytech/polkadot?branch=master#ca22bdca70a595db8b7ad1502919769d1472ffb9" dependencies = [ "bp-header-chain", "ed25519-dalek", @@ -777,7 +801,7 @@ dependencies = [ [[package]] name = "bp-wococo" version = "0.1.0" -source = "git+https://github.com/paritytech/polkadot?branch=master#d67d2adf51ac836f4d549b059cbf33eb4d7cc6e3" +source = "git+https://github.com/paritytech/polkadot?branch=master#ca22bdca70a595db8b7ad1502919769d1472ffb9" dependencies = [ "bp-header-chain", "bp-messages", @@ -1384,7 +1408,7 @@ dependencies = [ "env_logger 0.7.1", "futures 0.3.14", "parity-scale-codec", - "parking_lot 0.9.0", + "parking_lot 0.10.2", "polkadot-node-primitives", "polkadot-node-subsystem", "polkadot-node-subsystem-test-helpers", @@ -1412,7 +1436,7 @@ dependencies = [ "cumulus-primitives-core", "futures 0.3.14", "parity-scale-codec", - "parking_lot 0.9.0", + "parking_lot 0.10.2", "polkadot-service", "sc-client-api", "sc-consensus-aura", @@ -1437,15 +1461,20 @@ name = "cumulus-client-consensus-common" version = "0.1.0" dependencies = [ "async-trait", + "cumulus-primitives-core", "cumulus-test-client", "cumulus-test-runtime", + "cumulus-test-service", "dyn-clone", "futures 0.3.14", "futures-timer 3.0.2", "parity-scale-codec", "polkadot-primitives", "polkadot-runtime", + "polkadot-test-client", + "sc-cli", "sc-client-api", + "sc-service", "sp-api", "sp-block-builder", "sp-blockchain", @@ -1456,7 +1485,8 @@ dependencies = [ "sp-tracing", "sp-trie", "substrate-prometheus-endpoint", - "tokio 0.1.22", + "substrate-test-utils", + "tokio 0.2.24", "tracing", ] @@ -1469,7 +1499,7 @@ dependencies = [ "cumulus-primitives-core", "futures 0.3.14", "parity-scale-codec", - "parking_lot 0.9.0", + "parking_lot 0.10.2", "polkadot-service", "sc-client-api", "sp-api", @@ -1515,19 +1545,55 @@ dependencies = [ "tracing", ] +[[package]] +name = "cumulus-client-pov-recovery" +version = "0.1.0" +dependencies = [ + "cumulus-primitives-core", + "cumulus-test-service", + "futures 0.3.14", + "futures-timer 3.0.2", + "parity-scale-codec", + "polkadot-node-primitives", + "polkadot-node-subsystem", + "polkadot-overseer", + "polkadot-parachain", + "polkadot-primitives", + "polkadot-service", + "polkadot-statement-table", + "polkadot-test-client", + "rand 0.8.3", + "sc-cli", + "sc-client-api", + "sc-service", + "sp-api", + "sp-consensus", + "sp-core", + "sp-keyring", + "sp-keystore", + "sp-maybe-compressed-blob", + "sp-runtime", + "substrate-test-utils", + "tokio 0.2.24", + "tracing", +] + [[package]] name = "cumulus-client-service" version = "0.1.0" dependencies = [ "cumulus-client-collator", "cumulus-client-consensus-common", + "cumulus-client-pov-recovery", "cumulus-primitives-core", - "futures 0.3.14", "parity-scale-codec", + "parking_lot 0.10.2", + "polkadot-overseer", "polkadot-primitives", "polkadot-service", "sc-chain-spec", "sc-client-api", + "sc-consensus-babe", "sc-service", "sc-telemetry", "sc-tracing", @@ -1915,6 +1981,8 @@ dependencies = [ name = "cumulus-test-service" version = "0.1.0" dependencies = [ + "async-trait", + "cumulus-client-consensus-common", "cumulus-client-consensus-relay-chain", "cumulus-client-network", "cumulus-client-service", @@ -2477,7 +2545,7 @@ checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] name = "fork-tree" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "parity-scale-codec", ] @@ -2495,7 +2563,7 @@ dependencies = [ [[package]] name = "frame-benchmarking" version = "3.1.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "frame-support", "frame-system", @@ -2514,7 +2582,7 @@ dependencies = [ [[package]] name = "frame-benchmarking-cli" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "Inflector", "chrono", @@ -2537,7 +2605,7 @@ dependencies = [ [[package]] name = "frame-election-provider-support" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "frame-support", "frame-system", @@ -2550,7 +2618,7 @@ dependencies = [ [[package]] name = "frame-executive" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "frame-support", "frame-system", @@ -2565,7 +2633,7 @@ dependencies = [ [[package]] name = "frame-metadata" version = "13.0.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "parity-scale-codec", "serde", @@ -2576,7 +2644,7 @@ dependencies = [ [[package]] name = "frame-support" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "bitflags", "frame-metadata", @@ -2602,7 +2670,7 @@ dependencies = [ [[package]] name = "frame-support-procedural" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "Inflector", "frame-support-procedural-tools", @@ -2614,7 +2682,7 @@ dependencies = [ [[package]] name = "frame-support-procedural-tools" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "frame-support-procedural-tools-derive", "proc-macro-crate 1.0.0", @@ -2626,7 +2694,7 @@ dependencies = [ [[package]] name = "frame-support-procedural-tools-derive" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "proc-macro2 1.0.26", "quote 1.0.9", @@ -2636,7 +2704,7 @@ dependencies = [ [[package]] name = "frame-system" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "frame-support", "impl-trait-for-tuples", @@ -2653,7 +2721,7 @@ dependencies = [ [[package]] name = "frame-system-rpc-runtime-api" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "parity-scale-codec", "sp-api", @@ -2662,7 +2730,7 @@ dependencies = [ [[package]] name = "frame-try-runtime" version = "0.9.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "frame-support", "parity-scale-codec", @@ -2843,7 +2911,7 @@ checksum = "3a1387e07917c711fb4ee4f48ea0adb04a3c9739e53ef85bf43ae1edc2937a8b" dependencies = [ "futures-io", "rustls 0.19.0", - "webpki", + "webpki 0.21.4", ] [[package]] @@ -3326,7 +3394,7 @@ dependencies = [ "rustls-native-certs", "tokio 0.2.24", "tokio-rustls", - "webpki", + "webpki 0.21.4", ] [[package]] @@ -3668,25 +3736,6 @@ dependencies = [ "slab", ] -[[package]] -name = "jsonrpsee-http-client" -version = "0.2.0-alpha.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2737440f37efa10e5ef7beeec43d059d29dc92640978be21fcdcef481a2edb0d" -dependencies = [ - "async-trait", - "fnv", - "hyper 0.13.9", - "hyper-rustls", - "jsonrpsee-types", - "jsonrpsee-utils", - "log", - "serde", - "serde_json", - "thiserror", - "url 2.2.0", -] - [[package]] name = "jsonrpsee-proc-macros" version = "0.2.0-alpha.6" @@ -3717,14 +3766,25 @@ dependencies = [ ] [[package]] -name = "jsonrpsee-utils" +name = "jsonrpsee-ws-client" version = "0.2.0-alpha.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d63cf4d423614e71fd144a8691208539d2b23d8373e069e2fbe023c5eba5e922" +checksum = "d6fdb4390bd25358c62e8b778652a564a1723ba07dca0feb3da439c2253fe59f" dependencies = [ - "futures-util", - "hyper 0.13.9", + "async-std", + "async-tls", + "async-trait", + "fnv", + "futures 0.3.14", "jsonrpsee-types", + "log", + "pin-project 1.0.4", + "serde", + "serde_json", + "soketto", + "thiserror", + "url 2.2.0", + "webpki 0.22.0", ] [[package]] @@ -3745,8 +3805,8 @@ dependencies = [ [[package]] name = "kusama-runtime" -version = "0.9.2" -source = "git+https://github.com/paritytech/polkadot?branch=master#d67d2adf51ac836f4d549b059cbf33eb4d7cc6e3" +version = "0.9.3" +source = "git+https://github.com/paritytech/polkadot?branch=master#ca22bdca70a595db8b7ad1502919769d1472ffb9" dependencies = [ "beefy-primitives", "bitvec", @@ -4602,7 +4662,7 @@ dependencies = [ [[package]] name = "metered-channel" version = "0.1.0" -source = "git+https://github.com/paritytech/polkadot?branch=master#d67d2adf51ac836f4d549b059cbf33eb4d7cc6e3" +source = "git+https://github.com/paritytech/polkadot?branch=master#ca22bdca70a595db8b7ad1502919769d1472ffb9" dependencies = [ "derive_more 0.99.11", "futures 0.3.14", @@ -5004,7 +5064,7 @@ dependencies = [ [[package]] name = "pallet-assets" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "frame-benchmarking", "frame-support", @@ -5017,7 +5077,7 @@ dependencies = [ [[package]] name = "pallet-aura" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "frame-support", "frame-system", @@ -5033,7 +5093,7 @@ dependencies = [ [[package]] name = "pallet-authority-discovery" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "frame-support", "frame-system", @@ -5048,7 +5108,7 @@ dependencies = [ [[package]] name = "pallet-authorship" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "frame-support", "frame-system", @@ -5062,7 +5122,7 @@ dependencies = [ [[package]] name = "pallet-babe" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "frame-benchmarking", "frame-support", @@ -5085,7 +5145,7 @@ dependencies = [ [[package]] name = "pallet-balances" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "frame-benchmarking", "frame-support", @@ -5099,7 +5159,7 @@ dependencies = [ [[package]] name = "pallet-beefy" version = "0.1.0" -source = "git+https://github.com/paritytech/grandpa-bridge-gadget?branch=master#021e233fab35301ad3914c6de2ee708a9d591bf4" +source = "git+https://github.com/paritytech/grandpa-bridge-gadget?branch=master#5f2d59bdaae602d381d02a3ee705c34b511a7114" dependencies = [ "beefy-primitives", "frame-support", @@ -5114,7 +5174,7 @@ dependencies = [ [[package]] name = "pallet-bounties" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "frame-support", "frame-system", @@ -5127,7 +5187,7 @@ dependencies = [ [[package]] name = "pallet-bridge-grandpa" version = "0.1.0" -source = "git+https://github.com/paritytech/polkadot?branch=master#d67d2adf51ac836f4d549b059cbf33eb4d7cc6e3" +source = "git+https://github.com/paritytech/polkadot?branch=master#ca22bdca70a595db8b7ad1502919769d1472ffb9" dependencies = [ "bp-header-chain", "bp-runtime", @@ -5148,7 +5208,7 @@ dependencies = [ [[package]] name = "pallet-collective" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "frame-support", "frame-system", @@ -5163,7 +5223,7 @@ dependencies = [ [[package]] name = "pallet-democracy" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "frame-benchmarking", "frame-support", @@ -5178,7 +5238,7 @@ dependencies = [ [[package]] name = "pallet-election-provider-multi-phase" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "frame-election-provider-support", "frame-support", @@ -5197,7 +5257,7 @@ dependencies = [ [[package]] name = "pallet-elections-phragmen" version = "4.0.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "frame-support", "frame-system", @@ -5213,7 +5273,7 @@ dependencies = [ [[package]] name = "pallet-gilt" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "frame-benchmarking", "frame-support", @@ -5227,7 +5287,7 @@ dependencies = [ [[package]] name = "pallet-grandpa" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "frame-benchmarking", "frame-support", @@ -5248,7 +5308,7 @@ dependencies = [ [[package]] name = "pallet-identity" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "enumflags2", "frame-benchmarking", @@ -5263,7 +5323,7 @@ dependencies = [ [[package]] name = "pallet-im-online" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "frame-support", "frame-system", @@ -5281,7 +5341,7 @@ dependencies = [ [[package]] name = "pallet-indices" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "frame-support", "frame-system", @@ -5296,7 +5356,7 @@ dependencies = [ [[package]] name = "pallet-membership" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "frame-benchmarking", "frame-support", @@ -5311,7 +5371,7 @@ dependencies = [ [[package]] name = "pallet-mmr" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "ckb-merkle-mountain-range", "frame-benchmarking", @@ -5328,7 +5388,7 @@ dependencies = [ [[package]] name = "pallet-mmr-primitives" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "frame-support", "frame-system", @@ -5344,7 +5404,7 @@ dependencies = [ [[package]] name = "pallet-mmr-rpc" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "jsonrpc-core", "jsonrpc-core-client", @@ -5362,7 +5422,7 @@ dependencies = [ [[package]] name = "pallet-multisig" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "frame-support", "frame-system", @@ -5376,7 +5436,7 @@ dependencies = [ [[package]] name = "pallet-nicks" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "frame-support", "frame-system", @@ -5389,7 +5449,7 @@ dependencies = [ [[package]] name = "pallet-offences" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "frame-support", "frame-system", @@ -5405,7 +5465,7 @@ dependencies = [ [[package]] name = "pallet-proxy" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "frame-support", "frame-system", @@ -5419,7 +5479,7 @@ dependencies = [ [[package]] name = "pallet-randomness-collective-flip" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "frame-support", "frame-system", @@ -5432,7 +5492,7 @@ dependencies = [ [[package]] name = "pallet-recovery" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "enumflags2", "frame-support", @@ -5446,7 +5506,7 @@ dependencies = [ [[package]] name = "pallet-scheduler" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "frame-benchmarking", "frame-support", @@ -5461,7 +5521,7 @@ dependencies = [ [[package]] name = "pallet-session" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "frame-support", "frame-system", @@ -5480,7 +5540,7 @@ dependencies = [ [[package]] name = "pallet-society" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "frame-support", "frame-system", @@ -5493,7 +5553,7 @@ dependencies = [ [[package]] name = "pallet-staking" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "frame-election-provider-support", "frame-support", @@ -5515,7 +5575,7 @@ dependencies = [ [[package]] name = "pallet-staking-reward-curve" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "proc-macro-crate 1.0.0", "proc-macro2 1.0.26", @@ -5526,7 +5586,7 @@ dependencies = [ [[package]] name = "pallet-staking-reward-fn" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "log", "sp-arithmetic", @@ -5535,7 +5595,7 @@ dependencies = [ [[package]] name = "pallet-sudo" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "frame-support", "frame-system", @@ -5548,7 +5608,7 @@ dependencies = [ [[package]] name = "pallet-timestamp" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "frame-benchmarking", "frame-support", @@ -5565,7 +5625,7 @@ dependencies = [ [[package]] name = "pallet-tips" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "frame-support", "frame-system", @@ -5579,7 +5639,7 @@ dependencies = [ [[package]] name = "pallet-transaction-payment" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "frame-support", "frame-system", @@ -5595,7 +5655,7 @@ dependencies = [ [[package]] name = "pallet-transaction-payment-rpc" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "jsonrpc-core", "jsonrpc-core-client", @@ -5612,7 +5672,7 @@ dependencies = [ [[package]] name = "pallet-transaction-payment-rpc-runtime-api" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "pallet-transaction-payment", "parity-scale-codec", @@ -5623,7 +5683,7 @@ dependencies = [ [[package]] name = "pallet-treasury" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "frame-support", "frame-system", @@ -5638,7 +5698,7 @@ dependencies = [ [[package]] name = "pallet-utility" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "frame-support", "frame-system", @@ -5652,7 +5712,7 @@ dependencies = [ [[package]] name = "pallet-vesting" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "enumflags2", "frame-support", @@ -5665,7 +5725,7 @@ dependencies = [ [[package]] name = "pallet-xcm" version = "0.1.0" -source = "git+https://github.com/paritytech/polkadot?branch=master#d67d2adf51ac836f4d549b059cbf33eb4d7cc6e3" +source = "git+https://github.com/paritytech/polkadot?branch=master#ca22bdca70a595db8b7ad1502919769d1472ffb9" dependencies = [ "frame-support", "frame-system", @@ -6133,7 +6193,7 @@ checksum = "989d43012e2ca1c4a02507c67282691a0a3207f9dc67cec596b43fe925b3d325" [[package]] name = "polkadot-approval-distribution" version = "0.1.0" -source = "git+https://github.com/paritytech/polkadot?branch=master#d67d2adf51ac836f4d549b059cbf33eb4d7cc6e3" +source = "git+https://github.com/paritytech/polkadot?branch=master#ca22bdca70a595db8b7ad1502919769d1472ffb9" dependencies = [ "futures 0.3.14", "polkadot-node-network-protocol", @@ -6147,7 +6207,7 @@ dependencies = [ [[package]] name = "polkadot-availability-bitfield-distribution" version = "0.1.0" -source = "git+https://github.com/paritytech/polkadot?branch=master#d67d2adf51ac836f4d549b059cbf33eb4d7cc6e3" +source = "git+https://github.com/paritytech/polkadot?branch=master#ca22bdca70a595db8b7ad1502919769d1472ffb9" dependencies = [ "futures 0.3.14", "polkadot-node-network-protocol", @@ -6160,7 +6220,7 @@ dependencies = [ [[package]] name = "polkadot-availability-distribution" version = "0.1.0" -source = "git+https://github.com/paritytech/polkadot?branch=master#d67d2adf51ac836f4d549b059cbf33eb4d7cc6e3" +source = "git+https://github.com/paritytech/polkadot?branch=master#ca22bdca70a595db8b7ad1502919769d1472ffb9" dependencies = [ "futures 0.3.14", "lru", @@ -6183,7 +6243,7 @@ dependencies = [ [[package]] name = "polkadot-availability-recovery" version = "0.1.0" -source = "git+https://github.com/paritytech/polkadot?branch=master#d67d2adf51ac836f4d549b059cbf33eb4d7cc6e3" +source = "git+https://github.com/paritytech/polkadot?branch=master#ca22bdca70a595db8b7ad1502919769d1472ffb9" dependencies = [ "futures 0.3.14", "lru", @@ -6201,8 +6261,8 @@ dependencies = [ [[package]] name = "polkadot-cli" -version = "0.9.2" -source = "git+https://github.com/paritytech/polkadot?branch=master#d67d2adf51ac836f4d549b059cbf33eb4d7cc6e3" +version = "0.9.3" +source = "git+https://github.com/paritytech/polkadot?branch=master#ca22bdca70a595db8b7ad1502919769d1472ffb9" dependencies = [ "frame-benchmarking-cli", "futures 0.3.14", @@ -6244,7 +6304,7 @@ dependencies = [ "nix", "pallet-sudo", "parity-scale-codec", - "parking_lot 0.9.0", + "parking_lot 0.10.2", "polkadot-cli", "polkadot-parachain", "polkadot-primitives", @@ -6295,7 +6355,7 @@ dependencies = [ [[package]] name = "polkadot-collator-protocol" version = "0.1.0" -source = "git+https://github.com/paritytech/polkadot?branch=master#d67d2adf51ac836f4d549b059cbf33eb4d7cc6e3" +source = "git+https://github.com/paritytech/polkadot?branch=master#ca22bdca70a595db8b7ad1502919769d1472ffb9" dependencies = [ "always-assert", "futures 0.3.14", @@ -6314,8 +6374,8 @@ dependencies = [ [[package]] name = "polkadot-core-primitives" -version = "0.9.2" -source = "git+https://github.com/paritytech/polkadot?branch=master#d67d2adf51ac836f4d549b059cbf33eb4d7cc6e3" +version = "0.9.3" +source = "git+https://github.com/paritytech/polkadot?branch=master#ca22bdca70a595db8b7ad1502919769d1472ffb9" dependencies = [ "parity-scale-codec", "parity-util-mem", @@ -6326,8 +6386,8 @@ dependencies = [ [[package]] name = "polkadot-erasure-coding" -version = "0.9.2" -source = "git+https://github.com/paritytech/polkadot?branch=master#d67d2adf51ac836f4d549b059cbf33eb4d7cc6e3" +version = "0.9.3" +source = "git+https://github.com/paritytech/polkadot?branch=master#ca22bdca70a595db8b7ad1502919769d1472ffb9" dependencies = [ "parity-scale-codec", "polkadot-node-primitives", @@ -6341,7 +6401,7 @@ dependencies = [ [[package]] name = "polkadot-gossip-support" version = "0.1.0" -source = "git+https://github.com/paritytech/polkadot?branch=master#d67d2adf51ac836f4d549b059cbf33eb4d7cc6e3" +source = "git+https://github.com/paritytech/polkadot?branch=master#ca22bdca70a595db8b7ad1502919769d1472ffb9" dependencies = [ "futures 0.3.14", "polkadot-node-network-protocol", @@ -6356,7 +6416,7 @@ dependencies = [ [[package]] name = "polkadot-network-bridge" version = "0.1.0" -source = "git+https://github.com/paritytech/polkadot?branch=master#d67d2adf51ac836f4d549b059cbf33eb4d7cc6e3" +source = "git+https://github.com/paritytech/polkadot?branch=master#ca22bdca70a595db8b7ad1502919769d1472ffb9" dependencies = [ "async-trait", "futures 0.3.14", @@ -6376,7 +6436,7 @@ dependencies = [ [[package]] name = "polkadot-node-collation-generation" version = "0.1.0" -source = "git+https://github.com/paritytech/polkadot?branch=master#d67d2adf51ac836f4d549b059cbf33eb4d7cc6e3" +source = "git+https://github.com/paritytech/polkadot?branch=master#ca22bdca70a595db8b7ad1502919769d1472ffb9" dependencies = [ "futures 0.3.14", "parity-scale-codec", @@ -6394,7 +6454,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-approval-voting" version = "0.1.0" -source = "git+https://github.com/paritytech/polkadot?branch=master#d67d2adf51ac836f4d549b059cbf33eb4d7cc6e3" +source = "git+https://github.com/paritytech/polkadot?branch=master#ca22bdca70a595db8b7ad1502919769d1472ffb9" dependencies = [ "bitvec", "derive_more 0.99.11", @@ -6423,7 +6483,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-av-store" version = "0.1.0" -source = "git+https://github.com/paritytech/polkadot?branch=master#d67d2adf51ac836f4d549b059cbf33eb4d7cc6e3" +source = "git+https://github.com/paritytech/polkadot?branch=master#ca22bdca70a595db8b7ad1502919769d1472ffb9" dependencies = [ "bitvec", "futures 0.3.14", @@ -6443,7 +6503,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-backing" version = "0.1.0" -source = "git+https://github.com/paritytech/polkadot?branch=master#d67d2adf51ac836f4d549b059cbf33eb4d7cc6e3" +source = "git+https://github.com/paritytech/polkadot?branch=master#ca22bdca70a595db8b7ad1502919769d1472ffb9" dependencies = [ "bitvec", "futures 0.3.14", @@ -6461,7 +6521,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-bitfield-signing" version = "0.1.0" -source = "git+https://github.com/paritytech/polkadot?branch=master#d67d2adf51ac836f4d549b059cbf33eb4d7cc6e3" +source = "git+https://github.com/paritytech/polkadot?branch=master#ca22bdca70a595db8b7ad1502919769d1472ffb9" dependencies = [ "futures 0.3.14", "polkadot-node-subsystem", @@ -6476,7 +6536,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-candidate-selection" version = "0.1.0" -source = "git+https://github.com/paritytech/polkadot?branch=master#d67d2adf51ac836f4d549b059cbf33eb4d7cc6e3" +source = "git+https://github.com/paritytech/polkadot?branch=master#ca22bdca70a595db8b7ad1502919769d1472ffb9" dependencies = [ "futures 0.3.14", "polkadot-node-primitives", @@ -6491,7 +6551,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-candidate-validation" version = "0.1.0" -source = "git+https://github.com/paritytech/polkadot?branch=master#d67d2adf51ac836f4d549b059cbf33eb4d7cc6e3" +source = "git+https://github.com/paritytech/polkadot?branch=master#ca22bdca70a595db8b7ad1502919769d1472ffb9" dependencies = [ "async-trait", "futures 0.3.14", @@ -6509,7 +6569,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-chain-api" version = "0.1.0" -source = "git+https://github.com/paritytech/polkadot?branch=master#d67d2adf51ac836f4d549b059cbf33eb4d7cc6e3" +source = "git+https://github.com/paritytech/polkadot?branch=master#ca22bdca70a595db8b7ad1502919769d1472ffb9" dependencies = [ "futures 0.3.14", "polkadot-node-subsystem", @@ -6522,7 +6582,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-parachains-inherent" version = "0.1.0" -source = "git+https://github.com/paritytech/polkadot?branch=master#d67d2adf51ac836f4d549b059cbf33eb4d7cc6e3" +source = "git+https://github.com/paritytech/polkadot?branch=master#ca22bdca70a595db8b7ad1502919769d1472ffb9" dependencies = [ "async-trait", "futures 0.3.14", @@ -6540,7 +6600,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-provisioner" version = "0.1.0" -source = "git+https://github.com/paritytech/polkadot?branch=master#d67d2adf51ac836f4d549b059cbf33eb4d7cc6e3" +source = "git+https://github.com/paritytech/polkadot?branch=master#ca22bdca70a595db8b7ad1502919769d1472ffb9" dependencies = [ "bitvec", "futures 0.3.14", @@ -6555,7 +6615,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-pvf" version = "0.1.0" -source = "git+https://github.com/paritytech/polkadot?branch=master#d67d2adf51ac836f4d549b059cbf33eb4d7cc6e3" +source = "git+https://github.com/paritytech/polkadot?branch=master#ca22bdca70a595db8b7ad1502919769d1472ffb9" dependencies = [ "always-assert", "assert_matches", @@ -6583,7 +6643,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-runtime-api" version = "0.1.0" -source = "git+https://github.com/paritytech/polkadot?branch=master#d67d2adf51ac836f4d549b059cbf33eb4d7cc6e3" +source = "git+https://github.com/paritytech/polkadot?branch=master#ca22bdca70a595db8b7ad1502919769d1472ffb9" dependencies = [ "futures 0.3.14", "memory-lru", @@ -6601,7 +6661,7 @@ dependencies = [ [[package]] name = "polkadot-node-jaeger" version = "0.1.0" -source = "git+https://github.com/paritytech/polkadot?branch=master#d67d2adf51ac836f4d549b059cbf33eb4d7cc6e3" +source = "git+https://github.com/paritytech/polkadot?branch=master#ca22bdca70a595db8b7ad1502919769d1472ffb9" dependencies = [ "async-std", "lazy_static", @@ -6619,7 +6679,7 @@ dependencies = [ [[package]] name = "polkadot-node-network-protocol" version = "0.1.0" -source = "git+https://github.com/paritytech/polkadot?branch=master#d67d2adf51ac836f4d549b059cbf33eb4d7cc6e3" +source = "git+https://github.com/paritytech/polkadot?branch=master#ca22bdca70a595db8b7ad1502919769d1472ffb9" dependencies = [ "futures 0.3.14", "parity-scale-codec", @@ -6634,7 +6694,7 @@ dependencies = [ [[package]] name = "polkadot-node-primitives" version = "0.1.0" -source = "git+https://github.com/paritytech/polkadot?branch=master#d67d2adf51ac836f4d549b059cbf33eb4d7cc6e3" +source = "git+https://github.com/paritytech/polkadot?branch=master#ca22bdca70a595db8b7ad1502919769d1472ffb9" dependencies = [ "futures 0.3.14", "parity-scale-codec", @@ -6656,7 +6716,7 @@ dependencies = [ [[package]] name = "polkadot-node-subsystem" version = "0.1.0" -source = "git+https://github.com/paritytech/polkadot?branch=master#d67d2adf51ac836f4d549b059cbf33eb4d7cc6e3" +source = "git+https://github.com/paritytech/polkadot?branch=master#ca22bdca70a595db8b7ad1502919769d1472ffb9" dependencies = [ "async-std", "async-trait", @@ -6686,7 +6746,7 @@ dependencies = [ [[package]] name = "polkadot-node-subsystem-test-helpers" version = "0.1.0" -source = "git+https://github.com/paritytech/polkadot?branch=master#d67d2adf51ac836f4d549b059cbf33eb4d7cc6e3" +source = "git+https://github.com/paritytech/polkadot?branch=master#ca22bdca70a595db8b7ad1502919769d1472ffb9" dependencies = [ "async-trait", "futures 0.3.14", @@ -6708,7 +6768,7 @@ dependencies = [ [[package]] name = "polkadot-node-subsystem-util" version = "0.1.0" -source = "git+https://github.com/paritytech/polkadot?branch=master#d67d2adf51ac836f4d549b059cbf33eb4d7cc6e3" +source = "git+https://github.com/paritytech/polkadot?branch=master#ca22bdca70a595db8b7ad1502919769d1472ffb9" dependencies = [ "async-trait", "futures 0.3.14", @@ -6736,7 +6796,7 @@ dependencies = [ [[package]] name = "polkadot-overseer" version = "0.1.0" -source = "git+https://github.com/paritytech/polkadot?branch=master#d67d2adf51ac836f4d549b059cbf33eb4d7cc6e3" +source = "git+https://github.com/paritytech/polkadot?branch=master#ca22bdca70a595db8b7ad1502919769d1472ffb9" dependencies = [ "async-trait", "futures 0.3.14", @@ -6753,8 +6813,8 @@ dependencies = [ [[package]] name = "polkadot-parachain" -version = "0.9.2" -source = "git+https://github.com/paritytech/polkadot?branch=master#d67d2adf51ac836f4d549b059cbf33eb4d7cc6e3" +version = "0.9.3" +source = "git+https://github.com/paritytech/polkadot?branch=master#ca22bdca70a595db8b7ad1502919769d1472ffb9" dependencies = [ "derive_more 0.99.11", "parity-scale-codec", @@ -6768,8 +6828,8 @@ dependencies = [ [[package]] name = "polkadot-primitives" -version = "0.9.2" -source = "git+https://github.com/paritytech/polkadot?branch=master#d67d2adf51ac836f4d549b059cbf33eb4d7cc6e3" +version = "0.9.3" +source = "git+https://github.com/paritytech/polkadot?branch=master#ca22bdca70a595db8b7ad1502919769d1472ffb9" dependencies = [ "bitvec", "frame-system", @@ -6798,7 +6858,7 @@ dependencies = [ [[package]] name = "polkadot-procmacro-overseer-subsystems-gen" version = "0.1.0" -source = "git+https://github.com/paritytech/polkadot?branch=master#d67d2adf51ac836f4d549b059cbf33eb4d7cc6e3" +source = "git+https://github.com/paritytech/polkadot?branch=master#ca22bdca70a595db8b7ad1502919769d1472ffb9" dependencies = [ "assert_matches", "proc-macro2 1.0.26", @@ -6809,7 +6869,7 @@ dependencies = [ [[package]] name = "polkadot-procmacro-subsystem-dispatch-gen" version = "0.1.0" -source = "git+https://github.com/paritytech/polkadot?branch=master#d67d2adf51ac836f4d549b059cbf33eb4d7cc6e3" +source = "git+https://github.com/paritytech/polkadot?branch=master#ca22bdca70a595db8b7ad1502919769d1472ffb9" dependencies = [ "assert_matches", "proc-macro2 1.0.26", @@ -6819,8 +6879,8 @@ dependencies = [ [[package]] name = "polkadot-rpc" -version = "0.9.2" -source = "git+https://github.com/paritytech/polkadot?branch=master#d67d2adf51ac836f4d549b059cbf33eb4d7cc6e3" +version = "0.9.3" +source = "git+https://github.com/paritytech/polkadot?branch=master#ca22bdca70a595db8b7ad1502919769d1472ffb9" dependencies = [ "beefy-gadget", "beefy-gadget-rpc", @@ -6852,8 +6912,8 @@ dependencies = [ [[package]] name = "polkadot-runtime" -version = "0.9.2" -source = "git+https://github.com/paritytech/polkadot?branch=master#d67d2adf51ac836f4d549b059cbf33eb4d7cc6e3" +version = "0.9.3" +source = "git+https://github.com/paritytech/polkadot?branch=master#ca22bdca70a595db8b7ad1502919769d1472ffb9" dependencies = [ "beefy-primitives", "bitvec", @@ -6922,8 +6982,8 @@ dependencies = [ [[package]] name = "polkadot-runtime-common" -version = "0.9.2" -source = "git+https://github.com/paritytech/polkadot?branch=master#d67d2adf51ac836f4d549b059cbf33eb4d7cc6e3" +version = "0.9.3" +source = "git+https://github.com/paritytech/polkadot?branch=master#ca22bdca70a595db8b7ad1502919769d1472ffb9" dependencies = [ "beefy-primitives", "bitvec", @@ -6964,8 +7024,8 @@ dependencies = [ [[package]] name = "polkadot-runtime-parachains" -version = "0.9.2" -source = "git+https://github.com/paritytech/polkadot?branch=master#d67d2adf51ac836f4d549b059cbf33eb4d7cc6e3" +version = "0.9.3" +source = "git+https://github.com/paritytech/polkadot?branch=master#ca22bdca70a595db8b7ad1502919769d1472ffb9" dependencies = [ "bitvec", "derive_more 0.99.11", @@ -7001,8 +7061,8 @@ dependencies = [ [[package]] name = "polkadot-service" -version = "0.9.2" -source = "git+https://github.com/paritytech/polkadot?branch=master#d67d2adf51ac836f4d549b059cbf33eb4d7cc6e3" +version = "0.9.3" +source = "git+https://github.com/paritytech/polkadot?branch=master#ca22bdca70a595db8b7ad1502919769d1472ffb9" dependencies = [ "beefy-gadget", "beefy-primitives", @@ -7094,7 +7154,7 @@ dependencies = [ [[package]] name = "polkadot-statement-distribution" version = "0.1.0" -source = "git+https://github.com/paritytech/polkadot?branch=master#d67d2adf51ac836f4d549b059cbf33eb4d7cc6e3" +source = "git+https://github.com/paritytech/polkadot?branch=master#ca22bdca70a595db8b7ad1502919769d1472ffb9" dependencies = [ "arrayvec 0.5.2", "futures 0.3.14", @@ -7114,8 +7174,8 @@ dependencies = [ [[package]] name = "polkadot-statement-table" -version = "0.9.2" -source = "git+https://github.com/paritytech/polkadot?branch=master#d67d2adf51ac836f4d549b059cbf33eb4d7cc6e3" +version = "0.9.3" +source = "git+https://github.com/paritytech/polkadot?branch=master#ca22bdca70a595db8b7ad1502919769d1472ffb9" dependencies = [ "parity-scale-codec", "polkadot-primitives", @@ -7124,8 +7184,8 @@ dependencies = [ [[package]] name = "polkadot-test-client" -version = "0.9.2" -source = "git+https://github.com/paritytech/polkadot?branch=master#d67d2adf51ac836f4d549b059cbf33eb4d7cc6e3" +version = "0.9.3" +source = "git+https://github.com/paritytech/polkadot?branch=master#ca22bdca70a595db8b7ad1502919769d1472ffb9" dependencies = [ "parity-scale-codec", "polkadot-node-subsystem", @@ -7149,8 +7209,8 @@ dependencies = [ [[package]] name = "polkadot-test-runtime" -version = "0.9.2" -source = "git+https://github.com/paritytech/polkadot?branch=master#d67d2adf51ac836f4d549b059cbf33eb4d7cc6e3" +version = "0.9.3" +source = "git+https://github.com/paritytech/polkadot?branch=master#ca22bdca70a595db8b7ad1502919769d1472ffb9" dependencies = [ "beefy-primitives", "bitvec", @@ -7206,8 +7266,8 @@ dependencies = [ [[package]] name = "polkadot-test-service" -version = "0.9.2" -source = "git+https://github.com/paritytech/polkadot?branch=master#d67d2adf51ac836f4d549b059cbf33eb4d7cc6e3" +version = "0.9.3" +source = "git+https://github.com/paritytech/polkadot?branch=master#ca22bdca70a595db8b7ad1502919769d1472ffb9" dependencies = [ "frame-benchmarking", "frame-system", @@ -7933,12 +7993,12 @@ dependencies = [ [[package]] name = "remote-externalities" version = "0.9.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "env_logger 0.8.3", "hex-literal 0.3.1", - "jsonrpsee-http-client", "jsonrpsee-proc-macros", + "jsonrpsee-ws-client", "log", "parity-scale-codec", "sp-core", @@ -8008,8 +8068,8 @@ dependencies = [ [[package]] name = "rococo-runtime" -version = "0.9.2" -source = "git+https://github.com/paritytech/polkadot?branch=master#d67d2adf51ac836f4d549b059cbf33eb4d7cc6e3" +version = "0.9.3" +source = "git+https://github.com/paritytech/polkadot?branch=master#ca22bdca70a595db8b7ad1502919769d1472ffb9" dependencies = [ "beefy-primitives", "bp-rococo", @@ -8131,7 +8191,7 @@ dependencies = [ "log", "ring", "sct", - "webpki", + "webpki 0.21.4", ] [[package]] @@ -8144,7 +8204,7 @@ dependencies = [ "log", "ring", "sct", - "webpki", + "webpki 0.21.4", ] [[package]] @@ -8216,7 +8276,7 @@ dependencies = [ [[package]] name = "sc-authority-discovery" version = "0.9.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "async-trait", "derive_more 0.99.11", @@ -8245,7 +8305,7 @@ dependencies = [ [[package]] name = "sc-basic-authorship" version = "0.9.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "futures 0.3.14", "futures-timer 3.0.2", @@ -8268,7 +8328,7 @@ dependencies = [ [[package]] name = "sc-block-builder" version = "0.9.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "parity-scale-codec", "sc-client-api", @@ -8284,7 +8344,7 @@ dependencies = [ [[package]] name = "sc-chain-spec" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "impl-trait-for-tuples", "parity-scale-codec", @@ -8305,7 +8365,7 @@ dependencies = [ [[package]] name = "sc-chain-spec-derive" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "proc-macro-crate 1.0.0", "proc-macro2 1.0.26", @@ -8316,7 +8376,7 @@ dependencies = [ [[package]] name = "sc-cli" version = "0.9.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "chrono", "fdlimit", @@ -8354,7 +8414,7 @@ dependencies = [ [[package]] name = "sc-client-api" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "derive_more 0.99.11", "fnv", @@ -8388,7 +8448,7 @@ dependencies = [ [[package]] name = "sc-client-db" version = "0.9.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "blake2-rfc", "hash-db", @@ -8418,7 +8478,7 @@ dependencies = [ [[package]] name = "sc-consensus" version = "0.9.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "parking_lot 0.11.1", "sc-client-api", @@ -8430,7 +8490,7 @@ dependencies = [ [[package]] name = "sc-consensus-aura" version = "0.9.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "async-trait", "derive_more 0.99.11", @@ -8461,7 +8521,7 @@ dependencies = [ [[package]] name = "sc-consensus-babe" version = "0.9.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "async-trait", "derive_more 0.99.11", @@ -8507,7 +8567,7 @@ dependencies = [ [[package]] name = "sc-consensus-babe-rpc" version = "0.9.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "derive_more 0.99.11", "futures 0.3.14", @@ -8531,7 +8591,7 @@ dependencies = [ [[package]] name = "sc-consensus-epochs" version = "0.9.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "fork-tree", "parity-scale-codec", @@ -8544,7 +8604,7 @@ dependencies = [ [[package]] name = "sc-consensus-slots" version = "0.9.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "async-trait", "futures 0.3.14", @@ -8572,7 +8632,7 @@ dependencies = [ [[package]] name = "sc-consensus-uncles" version = "0.9.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "sc-client-api", "sp-authorship", @@ -8583,7 +8643,7 @@ dependencies = [ [[package]] name = "sc-executor" version = "0.9.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "derive_more 0.99.11", "lazy_static", @@ -8612,7 +8672,7 @@ dependencies = [ [[package]] name = "sc-executor-common" version = "0.9.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "derive_more 0.99.11", "parity-scale-codec", @@ -8630,7 +8690,7 @@ dependencies = [ [[package]] name = "sc-executor-wasmi" version = "0.9.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "log", "parity-scale-codec", @@ -8645,7 +8705,7 @@ dependencies = [ [[package]] name = "sc-executor-wasmtime" version = "0.9.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "log", "parity-scale-codec", @@ -8663,7 +8723,7 @@ dependencies = [ [[package]] name = "sc-finality-grandpa" version = "0.9.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "async-trait", "derive_more 0.99.11", @@ -8703,7 +8763,7 @@ dependencies = [ [[package]] name = "sc-finality-grandpa-rpc" version = "0.9.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "derive_more 0.99.11", "finality-grandpa", @@ -8727,7 +8787,7 @@ dependencies = [ [[package]] name = "sc-finality-grandpa-warp-sync" version = "0.9.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "derive_more 0.99.11", "futures 0.3.14", @@ -8748,7 +8808,7 @@ dependencies = [ [[package]] name = "sc-informant" version = "0.9.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "ansi_term 0.12.1", "futures 0.3.14", @@ -8766,7 +8826,7 @@ dependencies = [ [[package]] name = "sc-keystore" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "async-trait", "derive_more 0.99.11", @@ -8786,7 +8846,7 @@ dependencies = [ [[package]] name = "sc-light" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "hash-db", "lazy_static", @@ -8805,7 +8865,7 @@ dependencies = [ [[package]] name = "sc-network" version = "0.9.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "async-std", "async-trait", @@ -8858,7 +8918,7 @@ dependencies = [ [[package]] name = "sc-network-gossip" version = "0.9.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "futures 0.3.14", "futures-timer 3.0.2", @@ -8875,7 +8935,7 @@ dependencies = [ [[package]] name = "sc-offchain" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "bytes 0.5.6", "fnv", @@ -8903,7 +8963,7 @@ dependencies = [ [[package]] name = "sc-peerset" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "futures 0.3.14", "libp2p", @@ -8916,7 +8976,7 @@ dependencies = [ [[package]] name = "sc-proposer-metrics" version = "0.9.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "log", "substrate-prometheus-endpoint", @@ -8925,7 +8985,7 @@ dependencies = [ [[package]] name = "sc-rpc" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "futures 0.3.14", "hash-db", @@ -8960,7 +9020,7 @@ dependencies = [ [[package]] name = "sc-rpc-api" version = "0.9.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "derive_more 0.99.11", "futures 0.3.14", @@ -8985,7 +9045,7 @@ dependencies = [ [[package]] name = "sc-rpc-server" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "futures 0.1.30", "jsonrpc-core", @@ -9003,7 +9063,7 @@ dependencies = [ [[package]] name = "sc-service" version = "0.9.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "async-trait", "directories", @@ -9067,7 +9127,7 @@ dependencies = [ [[package]] name = "sc-state-db" version = "0.9.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "log", "parity-scale-codec", @@ -9082,7 +9142,7 @@ dependencies = [ [[package]] name = "sc-sync-state-rpc" version = "0.9.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "jsonrpc-core", "jsonrpc-core-client", @@ -9102,7 +9162,7 @@ dependencies = [ [[package]] name = "sc-telemetry" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "chrono", "futures 0.3.14", @@ -9122,7 +9182,7 @@ dependencies = [ [[package]] name = "sc-tracing" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "ansi_term 0.12.1", "atty", @@ -9159,7 +9219,7 @@ dependencies = [ [[package]] name = "sc-tracing-proc-macro" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "proc-macro-crate 1.0.0", "proc-macro2 1.0.26", @@ -9170,7 +9230,7 @@ dependencies = [ [[package]] name = "sc-transaction-graph" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "derive_more 0.99.11", "futures 0.3.14", @@ -9192,7 +9252,7 @@ dependencies = [ [[package]] name = "sc-transaction-pool" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "futures 0.3.14", "futures-diagnose", @@ -9530,8 +9590,8 @@ dependencies = [ [[package]] name = "slot-range-helper" -version = "0.9.2" -source = "git+https://github.com/paritytech/polkadot?branch=master#d67d2adf51ac836f4d549b059cbf33eb4d7cc6e3" +version = "0.9.3" +source = "git+https://github.com/paritytech/polkadot?branch=master#ca22bdca70a595db8b7ad1502919769d1472ffb9" dependencies = [ "enumn", "parity-scale-codec", @@ -9622,7 +9682,7 @@ dependencies = [ [[package]] name = "sp-allocator" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "log", "sp-core", @@ -9634,7 +9694,7 @@ dependencies = [ [[package]] name = "sp-api" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "hash-db", "log", @@ -9651,7 +9711,7 @@ dependencies = [ [[package]] name = "sp-api-proc-macro" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "blake2-rfc", "proc-macro-crate 1.0.0", @@ -9663,7 +9723,7 @@ dependencies = [ [[package]] name = "sp-application-crypto" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "parity-scale-codec", "serde", @@ -9675,7 +9735,7 @@ dependencies = [ [[package]] name = "sp-arithmetic" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "integer-sqrt", "num-traits", @@ -9689,7 +9749,7 @@ dependencies = [ [[package]] name = "sp-authority-discovery" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "parity-scale-codec", "sp-api", @@ -9701,7 +9761,7 @@ dependencies = [ [[package]] name = "sp-authorship" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "async-trait", "parity-scale-codec", @@ -9713,7 +9773,7 @@ dependencies = [ [[package]] name = "sp-block-builder" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "parity-scale-codec", "sp-api", @@ -9725,7 +9785,7 @@ dependencies = [ [[package]] name = "sp-blockchain" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "futures 0.3.14", "log", @@ -9743,7 +9803,7 @@ dependencies = [ [[package]] name = "sp-chain-spec" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "serde", "serde_json", @@ -9752,7 +9812,7 @@ dependencies = [ [[package]] name = "sp-consensus" version = "0.9.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "async-trait", "futures 0.3.14", @@ -9779,7 +9839,7 @@ dependencies = [ [[package]] name = "sp-consensus-aura" version = "0.9.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "async-trait", "parity-scale-codec", @@ -9796,7 +9856,7 @@ dependencies = [ [[package]] name = "sp-consensus-babe" version = "0.9.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "async-trait", "merlin", @@ -9818,7 +9878,7 @@ dependencies = [ [[package]] name = "sp-consensus-slots" version = "0.9.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "parity-scale-codec", "sp-arithmetic", @@ -9828,7 +9888,7 @@ dependencies = [ [[package]] name = "sp-consensus-vrf" version = "0.9.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "parity-scale-codec", "schnorrkel", @@ -9840,7 +9900,7 @@ dependencies = [ [[package]] name = "sp-core" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "base58", "blake2-rfc", @@ -9884,7 +9944,7 @@ dependencies = [ [[package]] name = "sp-database" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "kvdb", "parking_lot 0.11.1", @@ -9893,7 +9953,7 @@ dependencies = [ [[package]] name = "sp-debug-derive" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "proc-macro2 1.0.26", "quote 1.0.9", @@ -9903,7 +9963,7 @@ dependencies = [ [[package]] name = "sp-externalities" version = "0.9.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "environmental", "parity-scale-codec", @@ -9914,7 +9974,7 @@ dependencies = [ [[package]] name = "sp-finality-grandpa" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "finality-grandpa", "log", @@ -9931,7 +9991,7 @@ dependencies = [ [[package]] name = "sp-inherents" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "async-trait", "impl-trait-for-tuples", @@ -9945,7 +10005,7 @@ dependencies = [ [[package]] name = "sp-io" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "futures 0.3.14", "hash-db", @@ -9970,7 +10030,7 @@ dependencies = [ [[package]] name = "sp-keyring" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "lazy_static", "sp-core", @@ -9981,7 +10041,7 @@ dependencies = [ [[package]] name = "sp-keystore" version = "0.9.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "async-trait", "derive_more 0.99.11", @@ -9998,7 +10058,7 @@ dependencies = [ [[package]] name = "sp-maybe-compressed-blob" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "ruzstd", "zstd", @@ -10007,7 +10067,7 @@ dependencies = [ [[package]] name = "sp-npos-elections" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "parity-scale-codec", "serde", @@ -10020,7 +10080,7 @@ dependencies = [ [[package]] name = "sp-npos-elections-compact" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "proc-macro-crate 1.0.0", "proc-macro2 1.0.26", @@ -10031,7 +10091,7 @@ dependencies = [ [[package]] name = "sp-offchain" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "sp-api", "sp-core", @@ -10041,7 +10101,7 @@ dependencies = [ [[package]] name = "sp-panic-handler" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "backtrace", ] @@ -10049,7 +10109,7 @@ dependencies = [ [[package]] name = "sp-rpc" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "rustc-hash", "serde", @@ -10060,7 +10120,7 @@ dependencies = [ [[package]] name = "sp-runtime" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "either", "hash256-std-hasher", @@ -10081,7 +10141,7 @@ dependencies = [ [[package]] name = "sp-runtime-interface" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "impl-trait-for-tuples", "parity-scale-codec", @@ -10098,7 +10158,7 @@ dependencies = [ [[package]] name = "sp-runtime-interface-proc-macro" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "Inflector", "proc-macro-crate 1.0.0", @@ -10110,7 +10170,7 @@ dependencies = [ [[package]] name = "sp-serializer" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "serde", "serde_json", @@ -10119,7 +10179,7 @@ dependencies = [ [[package]] name = "sp-session" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "parity-scale-codec", "sp-api", @@ -10132,7 +10192,7 @@ dependencies = [ [[package]] name = "sp-staking" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "parity-scale-codec", "sp-runtime", @@ -10142,7 +10202,7 @@ dependencies = [ [[package]] name = "sp-state-machine" version = "0.9.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "hash-db", "log", @@ -10165,12 +10225,12 @@ dependencies = [ [[package]] name = "sp-std" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" [[package]] name = "sp-storage" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "impl-serde", "parity-scale-codec", @@ -10183,7 +10243,7 @@ dependencies = [ [[package]] name = "sp-tasks" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "log", "sp-core", @@ -10196,7 +10256,7 @@ dependencies = [ [[package]] name = "sp-test-primitives" version = "2.0.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "parity-scale-codec", "parity-util-mem", @@ -10209,7 +10269,7 @@ dependencies = [ [[package]] name = "sp-timestamp" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "async-trait", "futures-timer 3.0.2", @@ -10226,7 +10286,7 @@ dependencies = [ [[package]] name = "sp-tracing" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "erased-serde", "log", @@ -10244,7 +10304,7 @@ dependencies = [ [[package]] name = "sp-transaction-pool" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "derive_more 0.99.11", "futures 0.3.14", @@ -10260,7 +10320,7 @@ dependencies = [ [[package]] name = "sp-trie" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "hash-db", "memory-db", @@ -10274,7 +10334,7 @@ dependencies = [ [[package]] name = "sp-utils" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "futures 0.3.14", "futures-core", @@ -10286,7 +10346,7 @@ dependencies = [ [[package]] name = "sp-version" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "impl-serde", "parity-scale-codec", @@ -10299,7 +10359,7 @@ dependencies = [ [[package]] name = "sp-version-proc-macro" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "parity-scale-codec", "proc-macro-crate 1.0.0", @@ -10311,7 +10371,7 @@ dependencies = [ [[package]] name = "sp-wasm-interface" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "impl-trait-for-tuples", "parity-scale-codec", @@ -10469,7 +10529,7 @@ dependencies = [ [[package]] name = "substrate-build-script-utils" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "platforms", ] @@ -10477,7 +10537,7 @@ dependencies = [ [[package]] name = "substrate-frame-rpc-system" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "frame-system-rpc-runtime-api", "futures 0.3.14", @@ -10500,7 +10560,7 @@ dependencies = [ [[package]] name = "substrate-prometheus-endpoint" version = "0.9.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "async-std", "derive_more 0.99.11", @@ -10514,7 +10574,7 @@ dependencies = [ [[package]] name = "substrate-test-client" version = "2.0.1" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "async-trait", "futures 0.1.30", @@ -10543,7 +10603,7 @@ dependencies = [ [[package]] name = "substrate-test-runtime" version = "2.0.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "cfg-if 1.0.0", "frame-support", @@ -10584,7 +10644,7 @@ dependencies = [ [[package]] name = "substrate-test-runtime-client" version = "2.0.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "futures 0.3.14", "parity-scale-codec", @@ -10605,7 +10665,7 @@ dependencies = [ [[package]] name = "substrate-test-utils" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "futures 0.3.14", "substrate-test-utils-derive", @@ -10615,7 +10675,7 @@ dependencies = [ [[package]] name = "substrate-test-utils-derive" version = "0.9.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "proc-macro-crate 1.0.0", "quote 1.0.9", @@ -10641,7 +10701,7 @@ dependencies = [ [[package]] name = "substrate-wasm-builder" version = "4.0.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "ansi_term 0.12.1", "atty", @@ -11017,7 +11077,7 @@ dependencies = [ "futures-core", "rustls 0.18.1", "tokio 0.2.24", - "webpki", + "webpki 0.21.4", ] [[package]] @@ -11319,7 +11379,7 @@ checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642" [[package]] name = "try-runtime-cli" version = "0.9.0" -source = "git+https://github.com/paritytech/substrate?branch=master#72e2c34695e839c2550b1b2736b9569ba8085bc1" +source = "git+https://github.com/paritytech/substrate?branch=master#cb308ac8d289b3089560a61a2bb6b6093af26f53" dependencies = [ "frame-try-runtime", "log", @@ -11951,13 +12011,23 @@ dependencies = [ "untrusted", ] +[[package]] +name = "webpki" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f095d78192e208183081cc07bc5515ef55216397af48b873e5edcd72637fa1bd" +dependencies = [ + "ring", + "untrusted", +] + [[package]] name = "webpki-roots" version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "82015b7e0b8bad8185994674a13a93306bea76cf5a16c5a181382fd3a5ec2376" dependencies = [ - "webpki", + "webpki 0.21.4", ] [[package]] @@ -11971,8 +12041,8 @@ dependencies = [ [[package]] name = "westend-runtime" -version = "0.9.2" -source = "git+https://github.com/paritytech/polkadot?branch=master#d67d2adf51ac836f4d549b059cbf33eb4d7cc6e3" +version = "0.9.3" +source = "git+https://github.com/paritytech/polkadot?branch=master#ca22bdca70a595db8b7ad1502919769d1472ffb9" dependencies = [ "beefy-primitives", "bitvec", @@ -12152,8 +12222,8 @@ dependencies = [ [[package]] name = "xcm" -version = "0.9.2" -source = "git+https://github.com/paritytech/polkadot?branch=master#d67d2adf51ac836f4d549b059cbf33eb4d7cc6e3" +version = "0.9.3" +source = "git+https://github.com/paritytech/polkadot?branch=master#ca22bdca70a595db8b7ad1502919769d1472ffb9" dependencies = [ "derivative", "impl-trait-for-tuples", @@ -12162,8 +12232,8 @@ dependencies = [ [[package]] name = "xcm-builder" -version = "0.9.2" -source = "git+https://github.com/paritytech/polkadot?branch=master#d67d2adf51ac836f4d549b059cbf33eb4d7cc6e3" +version = "0.9.3" +source = "git+https://github.com/paritytech/polkadot?branch=master#ca22bdca70a595db8b7ad1502919769d1472ffb9" dependencies = [ "frame-support", "frame-system", @@ -12181,8 +12251,8 @@ dependencies = [ [[package]] name = "xcm-executor" -version = "0.9.2" -source = "git+https://github.com/paritytech/polkadot?branch=master#d67d2adf51ac836f4d549b059cbf33eb4d7cc6e3" +version = "0.9.3" +source = "git+https://github.com/paritytech/polkadot?branch=master#ca22bdca70a595db8b7ad1502919769d1472ffb9" dependencies = [ "frame-support", "impl-trait-for-tuples", diff --git a/cumulus/Cargo.toml b/cumulus/Cargo.toml index 78898f202c771b02f0b44aab6af4980126a818af..b20ce59c27787be9078c560080ca0c0943e1e7ef 100644 --- a/cumulus/Cargo.toml +++ b/cumulus/Cargo.toml @@ -5,6 +5,7 @@ members = [ "client/consensus/common", "client/consensus/relay-chain", "client/network", + "client/pov-recovery", "client/service", "pallets/aura-ext", "pallets/dmp-queue", diff --git a/cumulus/client/collator/Cargo.toml b/cumulus/client/collator/Cargo.toml index 84a98f1c806bb087904f5a538755bf91e95ecb00..e5fbfa23ebae32024a9afd8f24ad2291b8c3ce87 100644 --- a/cumulus/client/collator/Cargo.toml +++ b/cumulus/client/collator/Cargo.toml @@ -27,7 +27,7 @@ cumulus-primitives-core = { path = "../../primitives/core" } # Other dependencies codec = { package = "parity-scale-codec", version = "2.0.0", features = [ "derive" ] } futures = { version = "0.3.1", features = ["compat"] } -parking_lot = "0.9" +parking_lot = "0.10.2" tracing = "0.1.25" [dev-dependencies] diff --git a/cumulus/client/consensus/aura/Cargo.toml b/cumulus/client/consensus/aura/Cargo.toml index 4240aeccc2f21c3240ffa6a91b8bb39476e1efae..dcfd2956a3f5210fd1dad088a02ee790e3682847 100644 --- a/cumulus/client/consensus/aura/Cargo.toml +++ b/cumulus/client/consensus/aura/Cargo.toml @@ -35,4 +35,4 @@ futures = { version = "0.3.8", features = ["compat"] } codec = { package = "parity-scale-codec", version = "2.0.0", features = [ "derive" ] } tracing = "0.1.22" async-trait = "0.1.42" -parking_lot = "0.9" +parking_lot = "0.10.2" diff --git a/cumulus/client/consensus/common/Cargo.toml b/cumulus/client/consensus/common/Cargo.toml index aa89f06ffa11704f501a5e336da39f58ad910a9e..cfbf5282909cf55e882defd23be72a68fd47fb78 100644 --- a/cumulus/client/consensus/common/Cargo.toml +++ b/cumulus/client/consensus/common/Cargo.toml @@ -24,7 +24,6 @@ polkadot-runtime = { git = "https://github.com/paritytech/polkadot", branch = "m # Other deps futures = { version = "0.3.8", features = ["compat"] } -tokio = "0.1.22" codec = { package = "parity-scale-codec", version = "2.0.0", features = [ "derive" ] } tracing = "0.1.25" async-trait = "0.1.42" @@ -33,10 +32,19 @@ dyn-clone = "1.0.4" [dev-dependencies] # Substrate deps sp-tracing = { git = "https://github.com/paritytech/substrate", branch = "master" } +substrate-test-utils = { git = "https://github.com/paritytech/substrate", branch = "master" } +sc-service = { git = "https://github.com/paritytech/substrate", branch = "master" } +sc-cli = { git = "https://github.com/paritytech/substrate", branch = "master" } # Cumulus dependencies cumulus-test-runtime = { path = "../../../test/runtime" } cumulus-test-client = { path = "../../../test/client" } +cumulus-test-service = { path = "../../../test/service" } +cumulus-primitives-core = { path = "../../../primitives/core" } + +# Polkadot deps +polkadot-test-client = { git = "https://github.com/paritytech/polkadot", branch = "master" } # Other deps +tokio = { version = "0.2.21", features = ["macros"] } futures-timer = "3.0.2" diff --git a/cumulus/client/consensus/common/src/lib.rs b/cumulus/client/consensus/common/src/lib.rs index 92bc6e53e6cfc058b7d1a6c1860a8fd6813e9ca1..bba1a4d9347a4c089936871d3bdaec8cd478bdf4 100644 --- a/cumulus/client/consensus/common/src/lib.rs +++ b/cumulus/client/consensus/common/src/lib.rs @@ -14,504 +14,14 @@ // You should have received a copy of the GNU General Public License // along with Cumulus. If not, see <http://www.gnu.org/licenses/>. -use sc_client_api::{ - Backend, BlockBackend, BlockImportNotification, BlockchainEvents, Finalizer, UsageProvider, -}; -use sp_api::ProvideRuntimeApi; -use sp_blockchain::{Error as ClientError, Result as ClientResult}; -use sp_consensus::{ - BlockImport, BlockImportParams, BlockOrigin, BlockStatus, Error as ConsensusError, - ForkChoiceStrategy, SelectChain as SelectChainT, -}; -use sp_runtime::{ - generic::BlockId, - traits::{Block as BlockT, Header as HeaderT}, -}; +use polkadot_primitives::v1::{Hash as PHash, PersistedValidationData}; +use sp_consensus::BlockImport; +use sp_runtime::traits::Block as BlockT; -use polkadot_primitives::v1::{ - Block as PBlock, Hash as PHash, Id as ParaId, OccupiedCoreAssumption, ParachainHost, - PersistedValidationData, -}; - -use codec::Decode; -use futures::{future, select, FutureExt, Stream, StreamExt}; - -use std::{marker::PhantomData, sync::Arc}; - -/// Errors that can occur while following the polkadot relay-chain. -#[derive(Debug)] -pub enum Error { - /// An underlying client error. - Client(ClientError), - /// Head data returned was not for our parachain. - InvalidHeadData, -} - -/// Helper for the relay chain client. This is expected to be a lightweight handle like an `Arc`. -pub trait RelaychainClient: Clone + 'static { - /// The error type for interacting with the Polkadot client. - type Error: std::fmt::Debug + Send; - - /// A stream that yields head-data for a parachain. - type HeadStream: Stream<Item = Vec<u8>> + Send + Unpin; - - /// Get a stream of new best heads for the given parachain. - fn new_best_heads(&self, para_id: ParaId) -> ClientResult<Self::HeadStream>; - - /// Get a stream of finalized heads for the given parachain. - fn finalized_heads(&self, para_id: ParaId) -> ClientResult<Self::HeadStream>; - - /// Returns the parachain head for the given `para_id` at the given block id. - fn parachain_head_at( - &self, - at: &BlockId<PBlock>, - para_id: ParaId, - ) -> ClientResult<Option<Vec<u8>>>; -} - -/// Follow the finalized head of the given parachain. -/// -/// For every finalized block of the relay chain, it will get the included parachain header -/// corresponding to `para_id` and will finalize it in the parachain. -async fn follow_finalized_head<P, Block, B, R>( - para_id: ParaId, - parachain: Arc<P>, - relay_chain: R, -) -> ClientResult<()> -where - Block: BlockT, - P: Finalizer<Block, B> + UsageProvider<Block>, - R: RelaychainClient, - B: Backend<Block>, -{ - let mut finalized_heads = relay_chain.finalized_heads(para_id)?; - - loop { - let finalized_head = if let Some(h) = finalized_heads.next().await { - h - } else { - tracing::debug!(target: "cumulus-consensus", "Stopping following finalized head."); - return Ok(()); - }; - - let header = match Block::Header::decode(&mut &finalized_head[..]) { - Ok(header) => header, - Err(err) => { - tracing::warn!( - target: "cumulus-consensus", - error = ?err, - "Could not decode parachain header while following finalized heads.", - ); - continue; - } - }; - - let hash = header.hash(); - - // don't finalize the same block multiple times. - if parachain.usage_info().chain.finalized_hash != hash { - if let Err(e) = parachain.finalize_block(BlockId::hash(hash), None, true) { - match e { - ClientError::UnknownBlock(_) => tracing::debug!( - target: "cumulus-consensus", - block_hash = ?hash, - "Could not finalize block because it is unknown.", - ), - _ => tracing::warn!( - target: "cumulus-consensus", - error = ?e, - block_hash = ?hash, - "Failed to finalize block", - ), - } - } - } - } -} - -/// Run the parachain consensus. -/// -/// This will follow the given `relay_chain` to act as consesus for the parachain that corresponds -/// to the given `para_id`. It will set the new best block of the parachain as it gets aware of it. -/// The same happens for the finalized block. -/// -/// # Note -/// -/// This will access the backend of the parachain and thus, this future should be spawned as blocking -/// task. -pub async fn run_parachain_consensus<P, R, Block, B>( - para_id: ParaId, - parachain: Arc<P>, - relay_chain: R, - announce_block: Arc<dyn Fn(Block::Hash, Option<Vec<u8>>) + Send + Sync>, -) -> ClientResult<()> -where - Block: BlockT, - P: Finalizer<Block, B> - + UsageProvider<Block> - + Send - + Sync - + BlockBackend<Block> - + BlockchainEvents<Block>, - for<'a> &'a P: BlockImport<Block>, - R: RelaychainClient, - B: Backend<Block>, -{ - let follow_new_best = follow_new_best( - para_id, - parachain.clone(), - relay_chain.clone(), - announce_block, - ); - let follow_finalized_head = follow_finalized_head(para_id, parachain, relay_chain); - select! { - r = follow_new_best.fuse() => r, - r = follow_finalized_head.fuse() => r, - } -} - -/// Follow the relay chain new best head, to update the Parachain new best head. -async fn follow_new_best<P, R, Block, B>( - para_id: ParaId, - parachain: Arc<P>, - relay_chain: R, - announce_block: Arc<dyn Fn(Block::Hash, Option<Vec<u8>>) + Send + Sync>, -) -> ClientResult<()> -where - Block: BlockT, - P: Finalizer<Block, B> - + UsageProvider<Block> - + Send - + Sync - + BlockBackend<Block> - + BlockchainEvents<Block>, - for<'a> &'a P: BlockImport<Block>, - R: RelaychainClient, - B: Backend<Block>, -{ - let mut new_best_heads = relay_chain.new_best_heads(para_id)?.fuse(); - let mut imported_blocks = parachain.import_notification_stream().fuse(); - // The unset best header of the parachain. Will be `Some(_)` when we have imported a relay chain - // block before the parachain block it included. In this case we need to wait for this block to - // be imported to set it as new best. - let mut unset_best_header = None; - - loop { - select! { - h = new_best_heads.next() => { - match h { - Some(h) => handle_new_best_parachain_head( - h, - &*parachain, - &mut unset_best_header, - ).await, - None => { - tracing::debug!( - target: "cumulus-consensus", - "Stopping following new best.", - ); - return Ok(()) - } - } - }, - i = imported_blocks.next() => { - match i { - Some(i) => handle_new_block_imported( - i, - &mut unset_best_header, - &*parachain, - &*announce_block, - ).await, - None => { - tracing::debug!( - target: "cumulus-consensus", - "Stopping following imported blocks.", - ); - return Ok(()) - } - } - } - } - } -} - -/// Handle a new import block of the parachain. -async fn handle_new_block_imported<Block, P>( - notification: BlockImportNotification<Block>, - unset_best_header_opt: &mut Option<Block::Header>, - parachain: &P, - announce_block: &(dyn Fn(Block::Hash, Option<Vec<u8>>) + Send + Sync), -) where - Block: BlockT, - P: UsageProvider<Block> + Send + Sync + BlockBackend<Block>, - for<'a> &'a P: BlockImport<Block>, -{ - // HACK - // - // Remove after https://github.com/paritytech/substrate/pull/8052 or similar is merged - if notification.origin != BlockOrigin::Own { - announce_block(notification.hash, None); - } - - let unset_best_header = match (notification.is_new_best, &unset_best_header_opt) { - // If this is the new best block or we don't have any unset block, we can end it here. - (true, _) | (_, None) => return, - (false, Some(ref u)) => u, - }; - - let unset_hash = if notification.header.number() < unset_best_header.number() { - return; - } else if notification.header.number() == unset_best_header.number() { - let unset_hash = unset_best_header.hash(); - - if unset_hash != notification.hash { - return; - } else { - unset_hash - } - } else { - unset_best_header.hash() - }; - - match parachain.block_status(&BlockId::Hash(unset_hash)) { - Ok(BlockStatus::InChainWithState) => { - drop(unset_best_header); - let unset_best_header = unset_best_header_opt - .take() - .expect("We checked above that the value is set; qed"); - - import_block_as_new_best(unset_hash, unset_best_header, parachain).await; - } - state => tracing::debug!( - target: "cumulus-consensus", - ?unset_best_header, - ?notification.header, - ?state, - "Unexpected state for unset best header.", - ), - } -} - -/// Handle the new best parachain head as extracted from the new best relay chain. -async fn handle_new_best_parachain_head<Block, P>( - head: Vec<u8>, - parachain: &P, - unset_best_header: &mut Option<Block::Header>, -) where - Block: BlockT, - P: UsageProvider<Block> + Send + Sync + BlockBackend<Block>, - for<'a> &'a P: BlockImport<Block>, -{ - let parachain_head = match <<Block as BlockT>::Header>::decode(&mut &head[..]) { - Ok(header) => header, - Err(err) => { - tracing::warn!( - target: "cumulus-consensus", - error = ?err, - "Could not decode Parachain header while following best heads.", - ); - return; - } - }; - - let hash = parachain_head.hash(); - - if parachain.usage_info().chain.best_hash == hash { - tracing::debug!( - target: "cumulus-consensus", - block_hash = ?hash, - "Skipping set new best block, because block is already the best.", - ) - } else { - // Make sure the block is already known or otherwise we skip setting new best. - match parachain.block_status(&BlockId::Hash(hash)) { - Ok(BlockStatus::InChainWithState) => { - unset_best_header.take(); - - import_block_as_new_best(hash, parachain_head, parachain).await; - } - Ok(BlockStatus::InChainPruned) => { - tracing::error!( - target: "cumulus-collator", - block_hash = ?hash, - "Trying to set pruned block as new best!", - ); - } - Ok(BlockStatus::Unknown) => { - *unset_best_header = Some(parachain_head); - - tracing::debug!( - target: "cumulus-collator", - block_hash = ?hash, - "Parachain block not yet imported, waiting for import to enact as best block.", - ); - } - Err(e) => { - tracing::error!( - target: "cumulus-collator", - block_hash = ?hash, - error = ?e, - "Failed to get block status of block.", - ); - } - _ => {} - } - } -} - -async fn import_block_as_new_best<Block, P>(hash: Block::Hash, header: Block::Header, parachain: &P) -where - Block: BlockT, - P: UsageProvider<Block> + Send + Sync + BlockBackend<Block>, - for<'a> &'a P: BlockImport<Block>, -{ - // Make it the new best block - let mut block_import_params = BlockImportParams::new(BlockOrigin::ConsensusBroadcast, header); - block_import_params.fork_choice = Some(ForkChoiceStrategy::Custom(true)); - block_import_params.import_existing = true; - - if let Err(err) = (&*parachain) - .import_block(block_import_params, Default::default()) - .await - { - tracing::warn!( - target: "cumulus-consensus", - block_hash = ?hash, - error = ?err, - "Failed to set new best block.", - ); - } -} - -impl<T> RelaychainClient for Arc<T> -where - T: sc_client_api::BlockchainEvents<PBlock> + ProvideRuntimeApi<PBlock> + 'static + Send + Sync, - <T as ProvideRuntimeApi<PBlock>>::Api: ParachainHost<PBlock>, -{ - type Error = ClientError; - - type HeadStream = Box<dyn Stream<Item = Vec<u8>> + Send + Unpin>; - - fn new_best_heads(&self, para_id: ParaId) -> ClientResult<Self::HeadStream> { - let polkadot = self.clone(); - - let s = self.import_notification_stream().filter_map(move |n| { - future::ready(if n.is_new_best { - polkadot - .parachain_head_at(&BlockId::hash(n.hash), para_id) - .ok() - .and_then(|h| h) - } else { - None - }) - }); - - Ok(Box::new(s)) - } - - fn finalized_heads(&self, para_id: ParaId) -> ClientResult<Self::HeadStream> { - let polkadot = self.clone(); - - let s = self.finality_notification_stream().filter_map(move |n| { - future::ready( - polkadot - .parachain_head_at(&BlockId::hash(n.hash), para_id) - .ok() - .and_then(|h| h), - ) - }); - - Ok(Box::new(s)) - } - - fn parachain_head_at( - &self, - at: &BlockId<PBlock>, - para_id: ParaId, - ) -> ClientResult<Option<Vec<u8>>> { - self.runtime_api() - .persisted_validation_data(at, para_id, OccupiedCoreAssumption::TimedOut) - .map(|s| s.map(|s| s.parent_head.0)) - .map_err(Into::into) - } -} - -/// Select chain implementation for parachains. -/// -/// The actual behavior of the implementation depends on the select chain implementation used by -/// Polkadot. -pub struct SelectChain<Block, PC, SC> { - polkadot_client: PC, - polkadot_select_chain: SC, - para_id: ParaId, - _marker: PhantomData<Block>, -} - -impl<Block, PC, SC> SelectChain<Block, PC, SC> { - /// Create new instance of `Self`. - /// - /// - `para_id`: The id of the parachain. - /// - `polkadot_client`: The client of the Polkadot node. - /// - `polkadot_select_chain`: The Polkadot select chain implementation. - pub fn new(para_id: ParaId, polkadot_client: PC, polkadot_select_chain: SC) -> Self { - Self { - polkadot_client, - polkadot_select_chain, - para_id, - _marker: PhantomData, - } - } -} - -impl<Block, PC: Clone, SC: Clone> Clone for SelectChain<Block, PC, SC> { - fn clone(&self) -> Self { - Self { - polkadot_client: self.polkadot_client.clone(), - polkadot_select_chain: self.polkadot_select_chain.clone(), - para_id: self.para_id, - _marker: PhantomData, - } - } -} - -impl<Block, PC, SC> SelectChainT<Block> for SelectChain<Block, PC, SC> -where - Block: BlockT, - PC: RelaychainClient + Clone + Send + Sync, - PC::Error: ToString, - SC: SelectChainT<PBlock>, -{ - fn leaves(&self) -> Result<Vec<<Block as BlockT>::Hash>, ConsensusError> { - let leaves = self.polkadot_select_chain.leaves()?; - leaves - .into_iter() - .filter_map(|l| { - self.polkadot_client - .parachain_head_at(&BlockId::Hash(l), self.para_id) - .map(|h| h.and_then(|d| <<Block as BlockT>::Hash>::decode(&mut &d[..]).ok())) - .transpose() - }) - .collect::<Result<Vec<_>, _>>() - .map_err(|e| ConsensusError::ChainLookup(e.to_string())) - } - - fn best_chain(&self) -> Result<<Block as BlockT>::Header, ConsensusError> { - let best_chain = self.polkadot_select_chain.best_chain()?; - let para_best_chain = self - .polkadot_client - .parachain_head_at(&BlockId::Hash(best_chain.hash()), self.para_id) - .map_err(|e| ConsensusError::ChainLookup(e.to_string()))?; - - match para_best_chain { - Some(best) => Decode::decode(&mut &best[..]).map_err(|e| { - ConsensusError::ChainLookup(format!("Error decoding parachain head: {}", e)) - }), - None => Err(ConsensusError::ChainLookup( - "Could not find parachain head for best relay chain!".into(), - )), - } - } -} +mod parachain_consensus; +#[cfg(test)] +mod tests; +pub use parachain_consensus::run_parachain_consensus; /// The result of [`ParachainConsensus::produce_candidate`]. pub struct ParachainCandidate<B> { @@ -604,330 +114,3 @@ where self.0.import_block(block_import_params, cache).await } } - -#[cfg(test)] -mod tests { - use super::*; - - use codec::Encode; - use cumulus_test_client::{ - runtime::{Block, Header}, - Client, InitBlockBuilder, TestClientBuilder, TestClientBuilderExt, - }; - use futures::{channel::mpsc, executor::block_on}; - use futures_timer::Delay; - use std::{sync::Mutex, time::Duration}; - - struct RelaychainInner { - new_best_heads: Option<mpsc::UnboundedReceiver<Header>>, - finalized_heads: Option<mpsc::UnboundedReceiver<Header>>, - new_best_heads_sender: mpsc::UnboundedSender<Header>, - finalized_heads_sender: mpsc::UnboundedSender<Header>, - } - - impl RelaychainInner { - fn new() -> Self { - let (new_best_heads_sender, new_best_heads) = mpsc::unbounded(); - let (finalized_heads_sender, finalized_heads) = mpsc::unbounded(); - - Self { - new_best_heads_sender, - finalized_heads_sender, - new_best_heads: Some(new_best_heads), - finalized_heads: Some(finalized_heads), - } - } - } - - #[derive(Clone)] - struct Relaychain { - inner: Arc<Mutex<RelaychainInner>>, - } - - impl Relaychain { - fn new() -> Self { - Self { - inner: Arc::new(Mutex::new(RelaychainInner::new())), - } - } - } - - impl RelaychainClient for Relaychain { - type Error = ClientError; - - type HeadStream = Box<dyn Stream<Item = Vec<u8>> + Send + Unpin>; - fn new_best_heads(&self, _: ParaId) -> ClientResult<Self::HeadStream> { - let stream = self - .inner - .lock() - .unwrap() - .new_best_heads - .take() - .expect("Should only be called once"); - - Ok(Box::new(stream.map(|v| v.encode()))) - } - - fn finalized_heads(&self, _: ParaId) -> ClientResult<Self::HeadStream> { - let stream = self - .inner - .lock() - .unwrap() - .finalized_heads - .take() - .expect("Should only be called once"); - - Ok(Box::new(stream.map(|v| v.encode()))) - } - - fn parachain_head_at( - &self, - _: &BlockId<PBlock>, - _: ParaId, - ) -> ClientResult<Option<Vec<u8>>> { - unimplemented!("Not required for tests") - } - } - - fn build_and_import_block(mut client: Arc<Client>) -> Block { - let builder = client.init_block_builder(None, Default::default()); - - let block = builder.build().unwrap().block; - let (header, body) = block.clone().deconstruct(); - - let mut block_import_params = BlockImportParams::new(BlockOrigin::Own, header); - block_import_params.fork_choice = Some(ForkChoiceStrategy::Custom(false)); - block_import_params.body = Some(body); - - block_on(client.import_block(block_import_params, Default::default())).unwrap(); - assert_eq!(0, client.chain_info().best_number); - - block - } - - #[test] - fn follow_new_best_works() { - sp_tracing::try_init_simple(); - - let client = Arc::new(TestClientBuilder::default().build()); - - let block = build_and_import_block(client.clone()); - let relay_chain = Relaychain::new(); - let new_best_heads_sender = relay_chain - .inner - .lock() - .unwrap() - .new_best_heads_sender - .clone(); - - let consensus = - run_parachain_consensus(100.into(), client.clone(), relay_chain, Arc::new(|_, _| {})); - - let work = async move { - new_best_heads_sender - .unbounded_send(block.header().clone()) - .unwrap(); - loop { - Delay::new(Duration::from_millis(100)).await; - if block.hash() == client.usage_info().chain.best_hash { - break; - } - } - }; - - block_on(async move { - futures::pin_mut!(consensus); - futures::pin_mut!(work); - - select! { - r = consensus.fuse() => panic!("Consensus should not end: {:?}", r), - _ = work.fuse() => {}, - } - }); - } - - #[test] - fn follow_finalized_works() { - sp_tracing::try_init_simple(); - - let client = Arc::new(TestClientBuilder::default().build()); - - let block = build_and_import_block(client.clone()); - let relay_chain = Relaychain::new(); - let finalized_sender = relay_chain - .inner - .lock() - .unwrap() - .finalized_heads_sender - .clone(); - - let consensus = - run_parachain_consensus(100.into(), client.clone(), relay_chain, Arc::new(|_, _| {})); - - let work = async move { - finalized_sender - .unbounded_send(block.header().clone()) - .unwrap(); - loop { - Delay::new(Duration::from_millis(100)).await; - if block.hash() == client.usage_info().chain.finalized_hash { - break; - } - } - }; - - block_on(async move { - futures::pin_mut!(consensus); - futures::pin_mut!(work); - - select! { - r = consensus.fuse() => panic!("Consensus should not end: {:?}", r), - _ = work.fuse() => {}, - } - }); - } - - #[test] - fn follow_finalized_does_not_stop_on_unknown_block() { - sp_tracing::try_init_simple(); - - let client = Arc::new(TestClientBuilder::default().build()); - - let block = build_and_import_block(client.clone()); - - let unknown_block = { - let block_builder = client.init_block_builder_at( - &BlockId::Hash(block.hash()), - None, - Default::default(), - ); - block_builder.build().unwrap().block - }; - - let relay_chain = Relaychain::new(); - let finalized_sender = relay_chain - .inner - .lock() - .unwrap() - .finalized_heads_sender - .clone(); - - let consensus = - run_parachain_consensus(100.into(), client.clone(), relay_chain, Arc::new(|_, _| {})); - - let work = async move { - for _ in 0..3usize { - finalized_sender - .unbounded_send(unknown_block.header().clone()) - .unwrap(); - - Delay::new(Duration::from_millis(100)).await; - } - - finalized_sender - .unbounded_send(block.header().clone()) - .unwrap(); - loop { - Delay::new(Duration::from_millis(100)).await; - if block.hash() == client.usage_info().chain.finalized_hash { - break; - } - } - }; - - block_on(async move { - futures::pin_mut!(consensus); - futures::pin_mut!(work); - - select! { - r = consensus.fuse() => panic!("Consensus should not end: {:?}", r), - _ = work.fuse() => {}, - } - }); - } - - // It can happen that we first import a relay chain block, while not yet having the parachain - // block imported that would be set to the best block. We need to make sure to import this - // block as new best block in the moment it is imported. - #[test] - fn follow_new_best_sets_best_after_it_is_imported() { - sp_tracing::try_init_simple(); - - let mut client = Arc::new(TestClientBuilder::default().build()); - - let block = build_and_import_block(client.clone()); - - let unknown_block = { - let block_builder = client.init_block_builder_at( - &BlockId::Hash(block.hash()), - None, - Default::default(), - ); - block_builder.build().unwrap().block - }; - - let relay_chain = Relaychain::new(); - let new_best_heads_sender = relay_chain - .inner - .lock() - .unwrap() - .new_best_heads_sender - .clone(); - - let consensus = - run_parachain_consensus(100.into(), client.clone(), relay_chain, Arc::new(|_, _| {})); - - let work = async move { - new_best_heads_sender - .unbounded_send(block.header().clone()) - .unwrap(); - - loop { - Delay::new(Duration::from_millis(100)).await; - if block.hash() == client.usage_info().chain.best_hash { - break; - } - } - - // Announce the unknown block - new_best_heads_sender - .unbounded_send(unknown_block.header().clone()) - .unwrap(); - - // Do some iterations. As this is a local task executor, only one task can run at a time. - // Meaning that it should already have processed the unknown block. - for _ in 0..3usize { - Delay::new(Duration::from_millis(100)).await; - } - - let (header, body) = unknown_block.clone().deconstruct(); - - let mut block_import_params = BlockImportParams::new(BlockOrigin::Own, header); - block_import_params.fork_choice = Some(ForkChoiceStrategy::Custom(false)); - block_import_params.body = Some(body); - - // Now import the unkown block to make it "known" - client - .import_block(block_import_params, Default::default()) - .await - .unwrap(); - - loop { - Delay::new(Duration::from_millis(100)).await; - if unknown_block.hash() == client.usage_info().chain.best_hash { - break; - } - } - }; - - block_on(async move { - futures::pin_mut!(consensus); - futures::pin_mut!(work); - - select! { - r = consensus.fuse() => panic!("Consensus should not end: {:?}", r), - _ = work.fuse() => {}, - } - }); - } -} diff --git a/cumulus/client/consensus/common/src/parachain_consensus.rs b/cumulus/client/consensus/common/src/parachain_consensus.rs new file mode 100644 index 0000000000000000000000000000000000000000..6f230bdeae708b2866bb4953e36d7af6adced9ce --- /dev/null +++ b/cumulus/client/consensus/common/src/parachain_consensus.rs @@ -0,0 +1,418 @@ +// Copyright 2019-2021 Parity Technologies (UK) Ltd. +// This file is part of Cumulus. + +// Cumulus 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. + +// Cumulus 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 Cumulus. If not, see <http://www.gnu.org/licenses/>. + +use sc_client_api::{ + Backend, BlockBackend, BlockImportNotification, BlockchainEvents, Finalizer, UsageProvider, +}; +use sp_api::ProvideRuntimeApi; +use sp_blockchain::{Error as ClientError, Result as ClientResult}; +use sp_consensus::{BlockImport, BlockImportParams, BlockOrigin, BlockStatus, ForkChoiceStrategy}; +use sp_runtime::{ + generic::BlockId, + traits::{Block as BlockT, Header as HeaderT}, +}; + +use polkadot_primitives::v1::{ + Block as PBlock, Id as ParaId, OccupiedCoreAssumption, ParachainHost, +}; + +use codec::Decode; +use futures::{future, select, FutureExt, Stream, StreamExt}; + +use std::{pin::Pin, sync::Arc}; + +/// Helper for the relay chain client. This is expected to be a lightweight handle like an `Arc`. +pub trait RelaychainClient: Clone + 'static { + /// The error type for interacting with the Polkadot client. + type Error: std::fmt::Debug + Send; + + /// A stream that yields head-data for a parachain. + type HeadStream: Stream<Item = Vec<u8>> + Send + Unpin; + + /// Get a stream of new best heads for the given parachain. + fn new_best_heads(&self, para_id: ParaId) -> Self::HeadStream; + + /// Get a stream of finalized heads for the given parachain. + fn finalized_heads(&self, para_id: ParaId) -> Self::HeadStream; + + /// Returns the parachain head for the given `para_id` at the given block id. + fn parachain_head_at( + &self, + at: &BlockId<PBlock>, + para_id: ParaId, + ) -> ClientResult<Option<Vec<u8>>>; +} + +/// Follow the finalized head of the given parachain. +/// +/// For every finalized block of the relay chain, it will get the included parachain header +/// corresponding to `para_id` and will finalize it in the parachain. +async fn follow_finalized_head<P, Block, B, R>(para_id: ParaId, parachain: Arc<P>, relay_chain: R) +where + Block: BlockT, + P: Finalizer<Block, B> + UsageProvider<Block>, + R: RelaychainClient, + B: Backend<Block>, +{ + let mut finalized_heads = relay_chain.finalized_heads(para_id); + + loop { + let finalized_head = if let Some(h) = finalized_heads.next().await { + h + } else { + tracing::debug!(target: "cumulus-consensus", "Stopping following finalized head."); + return; + }; + + let header = match Block::Header::decode(&mut &finalized_head[..]) { + Ok(header) => header, + Err(err) => { + tracing::warn!( + target: "cumulus-consensus", + error = ?err, + "Could not decode parachain header while following finalized heads.", + ); + continue; + } + }; + + let hash = header.hash(); + + // don't finalize the same block multiple times. + if parachain.usage_info().chain.finalized_hash != hash { + if let Err(e) = parachain.finalize_block(BlockId::hash(hash), None, true) { + match e { + ClientError::UnknownBlock(_) => tracing::debug!( + target: "cumulus-consensus", + block_hash = ?hash, + "Could not finalize block because it is unknown.", + ), + _ => tracing::warn!( + target: "cumulus-consensus", + error = ?e, + block_hash = ?hash, + "Failed to finalize block", + ), + } + } + } + } +} + +/// Run the parachain consensus. +/// +/// This will follow the given `relay_chain` to act as consesus for the parachain that corresponds +/// to the given `para_id`. It will set the new best block of the parachain as it gets aware of it. +/// The same happens for the finalized block. +/// +/// # Note +/// +/// This will access the backend of the parachain and thus, this future should be spawned as blocking +/// task. +pub async fn run_parachain_consensus<P, R, Block, B>( + para_id: ParaId, + parachain: Arc<P>, + relay_chain: R, + announce_block: Arc<dyn Fn(Block::Hash, Option<Vec<u8>>) + Send + Sync>, +) where + Block: BlockT, + P: Finalizer<Block, B> + + UsageProvider<Block> + + Send + + Sync + + BlockBackend<Block> + + BlockchainEvents<Block>, + for<'a> &'a P: BlockImport<Block>, + R: RelaychainClient, + B: Backend<Block>, +{ + let follow_new_best = follow_new_best( + para_id, + parachain.clone(), + relay_chain.clone(), + announce_block, + ); + let follow_finalized_head = follow_finalized_head(para_id, parachain, relay_chain); + select! { + _ = follow_new_best.fuse() => {}, + _ = follow_finalized_head.fuse() => {}, + } +} + +/// Follow the relay chain new best head, to update the Parachain new best head. +async fn follow_new_best<P, R, Block, B>( + para_id: ParaId, + parachain: Arc<P>, + relay_chain: R, + announce_block: Arc<dyn Fn(Block::Hash, Option<Vec<u8>>) + Send + Sync>, +) where + Block: BlockT, + P: Finalizer<Block, B> + + UsageProvider<Block> + + Send + + Sync + + BlockBackend<Block> + + BlockchainEvents<Block>, + for<'a> &'a P: BlockImport<Block>, + R: RelaychainClient, + B: Backend<Block>, +{ + let mut new_best_heads = relay_chain.new_best_heads(para_id).fuse(); + let mut imported_blocks = parachain.import_notification_stream().fuse(); + // The unset best header of the parachain. Will be `Some(_)` when we have imported a relay chain + // block before the parachain block it included. In this case we need to wait for this block to + // be imported to set it as new best. + let mut unset_best_header = None; + + loop { + select! { + h = new_best_heads.next() => { + match h { + Some(h) => handle_new_best_parachain_head( + h, + &*parachain, + &mut unset_best_header, + ).await, + None => { + tracing::debug!( + target: "cumulus-consensus", + "Stopping following new best.", + ); + return + } + } + }, + i = imported_blocks.next() => { + match i { + Some(i) => handle_new_block_imported( + i, + &mut unset_best_header, + &*parachain, + &*announce_block, + ).await, + None => { + tracing::debug!( + target: "cumulus-consensus", + "Stopping following imported blocks.", + ); + return + } + } + }, + } + } +} + +/// Handle a new import block of the parachain. +async fn handle_new_block_imported<Block, P>( + notification: BlockImportNotification<Block>, + unset_best_header_opt: &mut Option<Block::Header>, + parachain: &P, + announce_block: &(dyn Fn(Block::Hash, Option<Vec<u8>>) + Send + Sync), +) where + Block: BlockT, + P: UsageProvider<Block> + Send + Sync + BlockBackend<Block>, + for<'a> &'a P: BlockImport<Block>, +{ + // HACK + // + // Remove after https://github.com/paritytech/substrate/pull/8052 or similar is merged + if notification.origin != BlockOrigin::Own { + announce_block(notification.hash, None); + } + + let unset_best_header = match (notification.is_new_best, &unset_best_header_opt) { + // If this is the new best block or we don't have any unset block, we can end it here. + (true, _) | (_, None) => return, + (false, Some(ref u)) => u, + }; + + let unset_hash = if notification.header.number() < unset_best_header.number() { + return; + } else if notification.header.number() == unset_best_header.number() { + let unset_hash = unset_best_header.hash(); + + if unset_hash != notification.hash { + return; + } else { + unset_hash + } + } else { + unset_best_header.hash() + }; + + match parachain.block_status(&BlockId::Hash(unset_hash)) { + Ok(BlockStatus::InChainWithState) => { + drop(unset_best_header); + let unset_best_header = unset_best_header_opt + .take() + .expect("We checked above that the value is set; qed"); + + import_block_as_new_best(unset_hash, unset_best_header, parachain).await; + } + state => tracing::debug!( + target: "cumulus-consensus", + ?unset_best_header, + ?notification.header, + ?state, + "Unexpected state for unset best header.", + ), + } +} + +/// Handle the new best parachain head as extracted from the new best relay chain. +async fn handle_new_best_parachain_head<Block, P>( + head: Vec<u8>, + parachain: &P, + unset_best_header: &mut Option<Block::Header>, +) where + Block: BlockT, + P: UsageProvider<Block> + Send + Sync + BlockBackend<Block>, + for<'a> &'a P: BlockImport<Block>, +{ + let parachain_head = match <<Block as BlockT>::Header>::decode(&mut &head[..]) { + Ok(header) => header, + Err(err) => { + tracing::warn!( + target: "cumulus-consensus", + error = ?err, + "Could not decode Parachain header while following best heads.", + ); + return; + } + }; + + let hash = parachain_head.hash(); + + if parachain.usage_info().chain.best_hash == hash { + tracing::debug!( + target: "cumulus-consensus", + block_hash = ?hash, + "Skipping set new best block, because block is already the best.", + ) + } else { + // Make sure the block is already known or otherwise we skip setting new best. + match parachain.block_status(&BlockId::Hash(hash)) { + Ok(BlockStatus::InChainWithState) => { + unset_best_header.take(); + + import_block_as_new_best(hash, parachain_head, parachain).await; + } + Ok(BlockStatus::InChainPruned) => { + tracing::error!( + target: "cumulus-collator", + block_hash = ?hash, + "Trying to set pruned block as new best!", + ); + } + Ok(BlockStatus::Unknown) => { + *unset_best_header = Some(parachain_head); + + tracing::debug!( + target: "cumulus-collator", + block_hash = ?hash, + "Parachain block not yet imported, waiting for import to enact as best block.", + ); + } + Err(e) => { + tracing::error!( + target: "cumulus-collator", + block_hash = ?hash, + error = ?e, + "Failed to get block status of block.", + ); + } + _ => {} + } + } +} + +async fn import_block_as_new_best<Block, P>(hash: Block::Hash, header: Block::Header, parachain: &P) +where + Block: BlockT, + P: UsageProvider<Block> + Send + Sync + BlockBackend<Block>, + for<'a> &'a P: BlockImport<Block>, +{ + // Make it the new best block + let mut block_import_params = BlockImportParams::new(BlockOrigin::ConsensusBroadcast, header); + block_import_params.fork_choice = Some(ForkChoiceStrategy::Custom(true)); + block_import_params.import_existing = true; + + if let Err(err) = (&*parachain) + .import_block(block_import_params, Default::default()) + .await + { + tracing::warn!( + target: "cumulus-consensus", + block_hash = ?hash, + error = ?err, + "Failed to set new best block.", + ); + } +} + +impl<T> RelaychainClient for Arc<T> +where + T: sc_client_api::BlockchainEvents<PBlock> + ProvideRuntimeApi<PBlock> + 'static + Send + Sync, + <T as ProvideRuntimeApi<PBlock>>::Api: ParachainHost<PBlock>, +{ + type Error = ClientError; + + type HeadStream = Pin<Box<dyn Stream<Item = Vec<u8>> + Send>>; + + fn new_best_heads(&self, para_id: ParaId) -> Self::HeadStream { + let relay_chain = self.clone(); + + self.import_notification_stream() + .filter_map(move |n| { + future::ready(if n.is_new_best { + relay_chain + .parachain_head_at(&BlockId::hash(n.hash), para_id) + .ok() + .flatten() + } else { + None + }) + }) + .boxed() + } + + fn finalized_heads(&self, para_id: ParaId) -> Self::HeadStream { + let relay_chain = self.clone(); + + self.finality_notification_stream() + .filter_map(move |n| { + future::ready( + relay_chain + .parachain_head_at(&BlockId::hash(n.hash), para_id) + .ok() + .flatten(), + ) + }) + .boxed() + } + + fn parachain_head_at( + &self, + at: &BlockId<PBlock>, + para_id: ParaId, + ) -> ClientResult<Option<Vec<u8>>> { + self.runtime_api() + .persisted_validation_data(at, para_id, OccupiedCoreAssumption::TimedOut) + .map(|s| s.map(|s| s.parent_head.0)) + .map_err(Into::into) + } +} diff --git a/cumulus/client/consensus/common/src/tests.rs b/cumulus/client/consensus/common/src/tests.rs new file mode 100644 index 0000000000000000000000000000000000000000..7f6b2d6df49bfa81f9c46e4bc397ed846bff72af --- /dev/null +++ b/cumulus/client/consensus/common/src/tests.rs @@ -0,0 +1,338 @@ +// Copyright 2019-2021 Parity Technologies (UK) Ltd. +// This file is part of Cumulus. + +// Cumulus 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. + +// Cumulus 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 Cumulus. If not, see <http://www.gnu.org/licenses/>. + +use crate::*; + +use codec::Encode; +use cumulus_test_client::{ + runtime::{Block, Header}, + Client, InitBlockBuilder, TestClientBuilder, TestClientBuilderExt, +}; +use futures::{channel::mpsc, executor::block_on, select, FutureExt, Stream, StreamExt}; +use futures_timer::Delay; +use polkadot_primitives::v1::{Block as PBlock, Id as ParaId}; +use sc_client_api::UsageProvider; +use sp_blockchain::{Error as ClientError, Result as ClientResult}; +use sp_consensus::{BlockImport, BlockImportParams, BlockOrigin, ForkChoiceStrategy}; +use sp_runtime::generic::BlockId; +use std::{ + sync::{Arc, Mutex}, + time::Duration, +}; + +struct RelaychainInner { + new_best_heads: Option<mpsc::UnboundedReceiver<Header>>, + finalized_heads: Option<mpsc::UnboundedReceiver<Header>>, + new_best_heads_sender: mpsc::UnboundedSender<Header>, + finalized_heads_sender: mpsc::UnboundedSender<Header>, +} + +impl RelaychainInner { + fn new() -> Self { + let (new_best_heads_sender, new_best_heads) = mpsc::unbounded(); + let (finalized_heads_sender, finalized_heads) = mpsc::unbounded(); + + Self { + new_best_heads_sender, + finalized_heads_sender, + new_best_heads: Some(new_best_heads), + finalized_heads: Some(finalized_heads), + } + } +} + +#[derive(Clone)] +struct Relaychain { + inner: Arc<Mutex<RelaychainInner>>, +} + +impl Relaychain { + fn new() -> Self { + Self { + inner: Arc::new(Mutex::new(RelaychainInner::new())), + } + } +} + +impl crate::parachain_consensus::RelaychainClient for Relaychain { + type Error = ClientError; + + type HeadStream = Box<dyn Stream<Item = Vec<u8>> + Send + Unpin>; + + fn new_best_heads(&self, _: ParaId) -> Self::HeadStream { + let stream = self + .inner + .lock() + .unwrap() + .new_best_heads + .take() + .expect("Should only be called once"); + + Box::new(stream.map(|v| v.encode())) + } + + fn finalized_heads(&self, _: ParaId) -> Self::HeadStream { + let stream = self + .inner + .lock() + .unwrap() + .finalized_heads + .take() + .expect("Should only be called once"); + + Box::new(stream.map(|v| v.encode())) + } + + fn parachain_head_at(&self, _: &BlockId<PBlock>, _: ParaId) -> ClientResult<Option<Vec<u8>>> { + unimplemented!("Not required for tests") + } +} + +fn build_and_import_block(mut client: Arc<Client>) -> Block { + let builder = client.init_block_builder(None, Default::default()); + + let block = builder.build().unwrap().block; + let (header, body) = block.clone().deconstruct(); + + let mut block_import_params = BlockImportParams::new(BlockOrigin::Own, header); + block_import_params.fork_choice = Some(ForkChoiceStrategy::Custom(false)); + block_import_params.body = Some(body); + + block_on(client.import_block(block_import_params, Default::default())).unwrap(); + assert_eq!(0, client.chain_info().best_number); + + block +} + +#[test] +fn follow_new_best_works() { + sp_tracing::try_init_simple(); + + let client = Arc::new(TestClientBuilder::default().build()); + + let block = build_and_import_block(client.clone()); + let relay_chain = Relaychain::new(); + let new_best_heads_sender = relay_chain + .inner + .lock() + .unwrap() + .new_best_heads_sender + .clone(); + + let consensus = + run_parachain_consensus(100.into(), client.clone(), relay_chain, Arc::new(|_, _| {})); + + let work = async move { + new_best_heads_sender + .unbounded_send(block.header().clone()) + .unwrap(); + loop { + Delay::new(Duration::from_millis(100)).await; + if block.hash() == client.usage_info().chain.best_hash { + break; + } + } + }; + + block_on(async move { + futures::pin_mut!(consensus); + futures::pin_mut!(work); + + select! { + r = consensus.fuse() => panic!("Consensus should not end: {:?}", r), + _ = work.fuse() => {}, + } + }); +} + +#[test] +fn follow_finalized_works() { + sp_tracing::try_init_simple(); + + let client = Arc::new(TestClientBuilder::default().build()); + + let block = build_and_import_block(client.clone()); + let relay_chain = Relaychain::new(); + let finalized_sender = relay_chain + .inner + .lock() + .unwrap() + .finalized_heads_sender + .clone(); + + let consensus = + run_parachain_consensus(100.into(), client.clone(), relay_chain, Arc::new(|_, _| {})); + + let work = async move { + finalized_sender + .unbounded_send(block.header().clone()) + .unwrap(); + loop { + Delay::new(Duration::from_millis(100)).await; + if block.hash() == client.usage_info().chain.finalized_hash { + break; + } + } + }; + + block_on(async move { + futures::pin_mut!(consensus); + futures::pin_mut!(work); + + select! { + r = consensus.fuse() => panic!("Consensus should not end: {:?}", r), + _ = work.fuse() => {}, + } + }); +} + +#[test] +fn follow_finalized_does_not_stop_on_unknown_block() { + sp_tracing::try_init_simple(); + + let client = Arc::new(TestClientBuilder::default().build()); + + let block = build_and_import_block(client.clone()); + + let unknown_block = { + let block_builder = + client.init_block_builder_at(&BlockId::Hash(block.hash()), None, Default::default()); + block_builder.build().unwrap().block + }; + + let relay_chain = Relaychain::new(); + let finalized_sender = relay_chain + .inner + .lock() + .unwrap() + .finalized_heads_sender + .clone(); + + let consensus = + run_parachain_consensus(100.into(), client.clone(), relay_chain, Arc::new(|_, _| {})); + + let work = async move { + for _ in 0..3usize { + finalized_sender + .unbounded_send(unknown_block.header().clone()) + .unwrap(); + + Delay::new(Duration::from_millis(100)).await; + } + + finalized_sender + .unbounded_send(block.header().clone()) + .unwrap(); + loop { + Delay::new(Duration::from_millis(100)).await; + if block.hash() == client.usage_info().chain.finalized_hash { + break; + } + } + }; + + block_on(async move { + futures::pin_mut!(consensus); + futures::pin_mut!(work); + + select! { + r = consensus.fuse() => panic!("Consensus should not end: {:?}", r), + _ = work.fuse() => {}, + } + }); +} + +// It can happen that we first import a relay chain block, while not yet having the parachain +// block imported that would be set to the best block. We need to make sure to import this +// block as new best block in the moment it is imported. +#[test] +fn follow_new_best_sets_best_after_it_is_imported() { + sp_tracing::try_init_simple(); + + let mut client = Arc::new(TestClientBuilder::default().build()); + + let block = build_and_import_block(client.clone()); + + let unknown_block = { + let block_builder = + client.init_block_builder_at(&BlockId::Hash(block.hash()), None, Default::default()); + block_builder.build().unwrap().block + }; + + let relay_chain = Relaychain::new(); + let new_best_heads_sender = relay_chain + .inner + .lock() + .unwrap() + .new_best_heads_sender + .clone(); + + let consensus = + run_parachain_consensus(100.into(), client.clone(), relay_chain, Arc::new(|_, _| {})); + + let work = async move { + new_best_heads_sender + .unbounded_send(block.header().clone()) + .unwrap(); + + loop { + Delay::new(Duration::from_millis(100)).await; + if block.hash() == client.usage_info().chain.best_hash { + break; + } + } + + // Announce the unknown block + new_best_heads_sender + .unbounded_send(unknown_block.header().clone()) + .unwrap(); + + // Do some iterations. As this is a local task executor, only one task can run at a time. + // Meaning that it should already have processed the unknown block. + for _ in 0..3usize { + Delay::new(Duration::from_millis(100)).await; + } + + let (header, body) = unknown_block.clone().deconstruct(); + + let mut block_import_params = BlockImportParams::new(BlockOrigin::Own, header); + block_import_params.fork_choice = Some(ForkChoiceStrategy::Custom(false)); + block_import_params.body = Some(body); + + // Now import the unkown block to make it "known" + client + .import_block(block_import_params, Default::default()) + .await + .unwrap(); + + loop { + Delay::new(Duration::from_millis(100)).await; + if unknown_block.hash() == client.usage_info().chain.best_hash { + break; + } + } + }; + + block_on(async move { + futures::pin_mut!(consensus); + futures::pin_mut!(work); + + select! { + r = consensus.fuse() => panic!("Consensus should not end: {:?}", r), + _ = work.fuse() => {}, + } + }); +} diff --git a/cumulus/client/consensus/relay-chain/Cargo.toml b/cumulus/client/consensus/relay-chain/Cargo.toml index d3da3ba601a568b954be3ba11df9372f35a7c9d5..db69dd59ce643c83f672c920a677af484cf88925 100644 --- a/cumulus/client/consensus/relay-chain/Cargo.toml +++ b/cumulus/client/consensus/relay-chain/Cargo.toml @@ -29,4 +29,4 @@ futures = { version = "0.3.8", features = ["compat"] } codec = { package = "parity-scale-codec", version = "2.0.0", features = [ "derive" ] } tracing = "0.1.22" async-trait = "0.1.42" -parking_lot = "0.9" +parking_lot = "0.10.2" diff --git a/cumulus/client/pov-recovery/Cargo.toml b/cumulus/client/pov-recovery/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..8fdfcafbe7c3ddc3e0638eadbda536a2273cd89d --- /dev/null +++ b/cumulus/client/pov-recovery/Cargo.toml @@ -0,0 +1,53 @@ +[package] +name = "cumulus-client-pov-recovery" +version = "0.1.0" +authors = ["Parity Technologies <admin@parity.io>"] +description = "Cumulus-specific networking protocol" +edition = "2018" + +[dependencies] +# Substrate deps +sp-consensus = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-api = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-core = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-maybe-compressed-blob = { git = "https://github.com/paritytech/substrate", branch = "master" } +sc-client-api = { git = "https://github.com/paritytech/substrate", branch = "master" } + +# Polkadot deps +polkadot-primitives = { git = "https://github.com/paritytech/polkadot", branch = "master" } +polkadot-statement-table = { git = "https://github.com/paritytech/polkadot", branch = "master" } +polkadot-node-primitives = { git = "https://github.com/paritytech/polkadot", branch = "master" } +polkadot-service = { git = "https://github.com/paritytech/polkadot", branch = "master" } +polkadot-parachain = { git = "https://github.com/paritytech/polkadot", branch = "master" } +polkadot-overseer = { git = "https://github.com/paritytech/polkadot", branch = "master" } +polkadot-node-subsystem = { git = "https://github.com/paritytech/polkadot", branch = "master" } + +# Cumulus deps +cumulus-primitives-core = { path = "../../primitives/core" } + +# other deps +codec = { package = "parity-scale-codec", version = "2.0.0", features = [ "derive" ] } +futures = { version = "0.3.1", features = ["compat"] } +futures-timer = "3.0.2" +tracing = "0.1.22" +rand = "0.8.3" + +[dev-dependencies] +tokio = { version = "0.2.21", features = ["macros"] } + +# Cumulus deps +cumulus-test-service = { path = "../../test/service" } + +# Polkadot deps +polkadot-test-client = { git = "https://github.com/paritytech/polkadot", branch = "master" } + +# substrate deps +sc-client-api = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-core = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-keyring = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-keystore = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-consensus = { git = "https://github.com/paritytech/substrate", branch = "master" } +sc-cli = { git = "https://github.com/paritytech/substrate", branch = "master" } +substrate-test-utils = { git = "https://github.com/paritytech/substrate", branch = "master" } +sc-service = { git = "https://github.com/paritytech/substrate", branch = "master" } diff --git a/cumulus/client/pov-recovery/src/active_candidate_recovery.rs b/cumulus/client/pov-recovery/src/active_candidate_recovery.rs new file mode 100644 index 0000000000000000000000000000000000000000..c797c0f9d767161c216b76573205dc597f47a058 --- /dev/null +++ b/cumulus/client/pov-recovery/src/active_candidate_recovery.rs @@ -0,0 +1,112 @@ +// Copyright 2021 Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Polkadot is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Polkadot. If not, see <http://www.gnu.org/licenses/>. + +use sp_runtime::traits::Block as BlockT; + +use polkadot_node_primitives::AvailableData; +use polkadot_node_subsystem::messages::AvailabilityRecoveryMessage; +use polkadot_overseer::OverseerHandler; + +use futures::{channel::oneshot, stream::FuturesUnordered, Future, FutureExt, StreamExt}; + +use std::{collections::HashSet, pin::Pin}; + +/// The active candidate recovery. +/// +/// This handles the candidate recovery and tracks the activate recoveries. +pub(crate) struct ActiveCandidateRecovery<Block: BlockT> { + /// The recoveries that are currently being executed. + recoveries: FuturesUnordered< + Pin<Box<dyn Future<Output = (Block::Hash, Option<AvailableData>)> + Send>>, + >, + /// The block hashes of the candidates currently being recovered. + candidates: HashSet<Block::Hash>, + overseer_handler: OverseerHandler, +} + +impl<Block: BlockT> ActiveCandidateRecovery<Block> { + pub fn new(overseer_handler: OverseerHandler) -> Self { + Self { + recoveries: Default::default(), + candidates: Default::default(), + overseer_handler, + } + } + + /// Recover the given `pending_candidate`. + pub async fn recover_candidate( + &mut self, + block_hash: Block::Hash, + pending_candidate: crate::PendingCandidate<Block>, + ) { + let (tx, rx) = oneshot::channel(); + + self.overseer_handler + .send_msg(AvailabilityRecoveryMessage::RecoverAvailableData( + pending_candidate.receipt, + pending_candidate.session_index, + None, + tx, + )) + .await; + + self.candidates.insert(block_hash); + + self.recoveries.push( + async move { + match rx.await { + Ok(Ok(res)) => (block_hash, Some(res)), + Ok(Err(error)) => { + tracing::debug!( + target: crate::LOG_TARGET, + ?error, + ?block_hash, + "Availability recovery failed", + ); + (block_hash, None) + } + Err(_) => { + tracing::debug!( + target: crate::LOG_TARGET, + "Availability recovery oneshot channel closed", + ); + (block_hash, None) + } + } + } + .boxed(), + ); + } + + /// Returns if the given `candidate` is being recovered. + pub fn is_being_recovered(&self, candidate: &Block::Hash) -> bool { + self.candidates.contains(candidate) + } + + /// Waits for the next recovery. + /// + /// If the returned [`AvailableData`] is `None`, it means that the recovery failed. + pub async fn wait_for_recovery(&mut self) -> (Block::Hash, Option<AvailableData>) { + loop { + if let Some(res) = self.recoveries.next().await { + self.candidates.remove(&res.0); + return res; + } else { + futures::pending!() + } + } + } +} diff --git a/cumulus/client/pov-recovery/src/lib.rs b/cumulus/client/pov-recovery/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..5d4f14f2004d8adaa9afcc04dc658b3fe3f73684 --- /dev/null +++ b/cumulus/client/pov-recovery/src/lib.rs @@ -0,0 +1,456 @@ +// Copyright 2021 Parity Technologies (UK) Ltd. +// This file is part of Cumulus. + +// Cumulus is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Polkadot is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Cumulus. If not, see <http://www.gnu.org/licenses/>. + +//! Parachain PoV recovery +//! +//! A parachain needs to build PoVs that are send to the relay chain to progress. These PoVs are +//! erasure encoded and one piece of it is stored by each relay chain validator. As the relay chain +//! decides on which PoV per parachain to include and thus, to progess the parachain it can happen +//! that the block corresponding to this PoV isn't propagated in the parachain network. This can have +//! several reasons, either a malicious collator that managed to include its own PoV and doesn't want +//! to share it with the rest of the network or maybe a collator went down before it could distribute +//! the block in the network. When something like this happens we can use the PoV recovery algorithm +//! implemented in this crate to recover a PoV and to propagate it with the rest of the network. This +//! protocol is only executed by the collators, to not overwhelm the relay chain validators. +//! +//! It works in the following way: +//! +//! 1. For every included relay chain block we note the backed candidate of our parachain. If the +//! block belonging to the PoV is already known, we do nothing. Otherwise we start +//! a timer that waits a random time between 0..relay_chain_slot_length before starting to recover +//! the PoV. +//! +//! 2. If between starting and firing the timer the block is imported, we skip the recovery of the +//! PoV. +//! +//! 3. If the timer fired we recover the PoV using the relay chain PoV recovery protocol. After it +//! is recovered, we restore the block and import it. +//! +//! If we need to recover multiple PoV blocks (which should hopefully not happen in real life), we +//! make sure that the blocks are imported in the correct order. + +use sc_client_api::{BlockBackend, BlockchainEvents, UsageProvider}; +use sp_api::ProvideRuntimeApi; +use sp_consensus::{ + import_queue::{ImportQueue, IncomingBlock}, + BlockOrigin, BlockStatus, +}; +use sp_runtime::{ + generic::BlockId, + traits::{Block as BlockT, Header as HeaderT, NumberFor}, +}; + +use polkadot_node_primitives::{AvailableData, POV_BOMB_LIMIT}; +use polkadot_overseer::OverseerHandler; +use polkadot_primitives::v1::{ + Block as PBlock, CandidateReceipt, CommittedCandidateReceipt, Id as ParaId, ParachainHost, + SessionIndex, +}; + +use cumulus_primitives_core::ParachainBlockData; + +use codec::Decode; +use futures::{select, stream::FuturesUnordered, Future, FutureExt, Stream, StreamExt}; +use futures_timer::Delay; +use rand::{thread_rng, Rng}; + +use std::{ + collections::{HashMap, VecDeque}, + pin::Pin, + sync::Arc, + time::Duration, +}; + +mod active_candidate_recovery; +use active_candidate_recovery::ActiveCandidateRecovery; + +const LOG_TARGET: &str = "cumulus-pov-recovery"; + +/// Represents a pending candidate. +struct PendingCandidate<Block: BlockT> { + receipt: CandidateReceipt, + session_index: SessionIndex, + block_number: NumberFor<Block>, +} + +/// Encapsulates the logic of the pov recovery. +pub struct PoVRecovery<Block: BlockT, PC, IQ, RC> { + /// All the pending candidates that we are waiting for to be imported or that need to be + /// recovered when `next_candidate_to_recover` tells us to do so. + pending_candidates: HashMap<Block::Hash, PendingCandidate<Block>>, + /// A stream of futures that resolve to hashes of candidates that need to be recovered. + /// + /// The candidates to the hashes are stored in `pending_candidates`. If a candidate is not + /// available anymore in this map, it means that it was already imported. + next_candidate_to_recover: FuturesUnordered<Pin<Box<dyn Future<Output = Block::Hash> + Send>>>, + active_candidate_recovery: ActiveCandidateRecovery<Block>, + /// Blocks that wait that the parent is imported. + /// + /// Uses parent -> blocks mapping. + waiting_for_parent: HashMap<Block::Hash, Vec<Block>>, + relay_chain_slot_duration: Duration, + parachain_client: Arc<PC>, + parachain_import_queue: IQ, + relay_chain_client: Arc<RC>, + para_id: ParaId, +} + +impl<Block: BlockT, PC, IQ, RC> PoVRecovery<Block, PC, IQ, RC> +where + PC: BlockBackend<Block> + BlockchainEvents<Block> + UsageProvider<Block>, + RC: ProvideRuntimeApi<PBlock> + BlockchainEvents<PBlock>, + RC::Api: ParachainHost<PBlock>, + IQ: ImportQueue<Block>, +{ + /// Create a new instance. + pub fn new( + overseer_handler: OverseerHandler, + relay_chain_slot_duration: Duration, + parachain_client: Arc<PC>, + parachain_import_queue: IQ, + relay_chain_client: Arc<RC>, + para_id: ParaId, + ) -> Self { + Self { + pending_candidates: HashMap::new(), + next_candidate_to_recover: Default::default(), + active_candidate_recovery: ActiveCandidateRecovery::new(overseer_handler), + relay_chain_slot_duration, + waiting_for_parent: HashMap::new(), + parachain_client, + parachain_import_queue, + relay_chain_client, + para_id, + } + } + + /// Handle a new pending candidate. + fn handle_pending_candidate( + &mut self, + receipt: CommittedCandidateReceipt, + session_index: SessionIndex, + ) { + let header = match Block::Header::decode(&mut &receipt.commitments.head_data.0[..]) { + Ok(header) => header, + Err(e) => { + tracing::warn!( + target: LOG_TARGET, + error = ?e, + "Failed to decode parachain header from pending candidate", + ); + return; + } + }; + + if *header.number() <= self.parachain_client.usage_info().chain.finalized_number { + return; + } + + let hash = header.hash(); + match self.parachain_client.block_status(&BlockId::Hash(hash)) { + Ok(BlockStatus::Unknown) => (), + // Any other state means, we should ignore it. + Ok(_) => return, + Err(e) => { + tracing::debug!( + target: "cumulus-consensus", + error = ?e, + block_hash = ?hash, + "Failed to get block status", + ); + return; + } + } + + if self + .pending_candidates + .insert( + hash, + PendingCandidate { + block_number: *header.number(), + receipt: receipt.to_plain(), + session_index, + }, + ) + .is_some() + { + return; + } + + // Wait some random time, with the maximum being the slot duration of the relay chain + // before we start to recover the candidate. + let delay = Delay::new(self.relay_chain_slot_duration.mul_f64(thread_rng().gen())); + self.next_candidate_to_recover.push( + async move { + delay.await; + hash + } + .boxed(), + ); + } + + /// Handle an imported block. + fn handle_block_imported(&mut self, hash: &Block::Hash) { + self.pending_candidates.remove(&hash); + } + + /// Handle a finalized block with the given `block_number`. + fn handle_block_finalized(&mut self, block_number: NumberFor<Block>) { + self.pending_candidates + .retain(|_, pc| pc.block_number > block_number); + } + + /// Recover the candidate for the given `block_hash`. + async fn recover_candidate(&mut self, block_hash: Block::Hash) { + let pending_candidate = match self.pending_candidates.remove(&block_hash) { + Some(pending_candidate) => pending_candidate, + None => return, + }; + + self.active_candidate_recovery + .recover_candidate(block_hash, pending_candidate) + .await; + } + + /// Clear `waiting_for_parent` from the given `hash` and do this recursively for all child + /// blocks. + fn clear_waiting_for_parent(&mut self, hash: Block::Hash) { + let mut blocks_to_delete = vec![hash]; + + while let Some(delete) = blocks_to_delete.pop() { + if let Some(childs) = self.waiting_for_parent.remove(&delete) { + blocks_to_delete.extend(childs.iter().map(BlockT::hash)); + } + } + } + + /// Handle a recovered candidate. + async fn handle_candidate_recovered( + &mut self, + block_hash: Block::Hash, + available_data: Option<AvailableData>, + ) { + let available_data = match available_data { + Some(data) => data, + None => { + self.clear_waiting_for_parent(block_hash); + return; + } + }; + + let raw_block_data = match sp_maybe_compressed_blob::decompress( + &available_data.pov.block_data.0, + POV_BOMB_LIMIT, + ) { + Ok(r) => r, + Err(error) => { + tracing::debug!(target: LOG_TARGET, ?error, "Failed to decompress PoV"); + + self.clear_waiting_for_parent(block_hash); + + return; + } + }; + + let block_data = match ParachainBlockData::<Block>::decode(&mut &raw_block_data[..]) { + Ok(d) => d, + Err(error) => { + tracing::warn!( + target: LOG_TARGET, + ?error, + "Failed to decode parachain block data from recovered PoV", + ); + + self.clear_waiting_for_parent(block_hash); + + return; + } + }; + + let block = block_data.into_block(); + + let parent = *block.header().parent_hash(); + + match self.parachain_client.block_status(&BlockId::hash(parent)) { + Ok(BlockStatus::Unknown) => { + if self.active_candidate_recovery.is_being_recovered(&parent) { + tracing::debug!( + target: "cumulus-consensus", + ?block_hash, + parent_hash = ?parent, + "Parent is still being recovered, waiting.", + ); + + self.waiting_for_parent + .entry(parent) + .or_default() + .push(block); + return; + } else { + tracing::debug!( + target: "cumulus-consensus", + ?block_hash, + parent_hash = ?parent, + "Parent not found while trying to import recovered block.", + ); + + self.clear_waiting_for_parent(block_hash); + + return; + } + } + Err(error) => { + tracing::debug!( + target: "cumulus-consensus", + block_hash = ?parent, + ?error, + "Error while checking block status", + ); + + self.clear_waiting_for_parent(block_hash); + + return; + } + // Any other status is fine to "ignore/accept" + _ => (), + } + + self.import_block(block).await; + } + + /// Import the given `block`. + /// + /// This will also recursivley drain `waiting_for_parent` and import them as well. + async fn import_block(&mut self, block: Block) { + let mut blocks = VecDeque::new(); + blocks.push_back(block); + + let mut incoming_blocks = Vec::new(); + + while let Some(block) = blocks.pop_front() { + let block_hash = block.hash(); + let (header, body) = block.deconstruct(); + + incoming_blocks.push(IncomingBlock { + hash: block_hash, + header: Some(header), + body: Some(body), + import_existing: false, + allow_missing_state: false, + justifications: None, + origin: None, + }); + + if let Some(waiting) = self.waiting_for_parent.remove(&block_hash) { + blocks.extend(waiting); + } + } + + self.parachain_import_queue + .import_blocks(BlockOrigin::ConsensusBroadcast, incoming_blocks); + } + + /// Run the pov-recovery. + pub async fn run(mut self) { + let mut imported_blocks = self.parachain_client.import_notification_stream().fuse(); + let mut finalized_blocks = self.parachain_client.finality_notification_stream().fuse(); + let pending_candidates = + pending_candidates(self.relay_chain_client.clone(), self.para_id).fuse(); + futures::pin_mut!(pending_candidates); + + loop { + select! { + pending_candidate = pending_candidates.next() => { + if let Some((receipt, session_index)) = pending_candidate { + self.handle_pending_candidate(receipt, session_index); + } else { + tracing::debug!( + target: LOG_TARGET, + "Pending candidates stream ended", + ); + return; + } + }, + imported = imported_blocks.next() => { + if let Some(imported) = imported { + self.handle_block_imported(&imported.hash); + } else { + tracing::debug!( + target: LOG_TARGET, + "Imported blocks stream ended", + ); + return; + } + }, + finalized = finalized_blocks.next() => { + if let Some(finalized) = finalized { + self.handle_block_finalized(*finalized.header.number()); + } else { + tracing::debug!( + target: LOG_TARGET, + "Finalized blocks stream ended", + ); + return; + } + }, + next_to_recover = self.next_candidate_to_recover.next() => { + if let Some(block_hash) = next_to_recover { + self.recover_candidate(block_hash).await; + } + }, + (block_hash, available_data) = + self.active_candidate_recovery.wait_for_recovery().fuse() => + { + self.handle_candidate_recovered(block_hash, available_data).await; + }, + } + } + } +} + +/// Returns a stream over pending candidates for the parachain corresponding to `para_id`. +fn pending_candidates<RC>( + relay_chain_client: Arc<RC>, + para_id: ParaId, +) -> impl Stream<Item = (CommittedCandidateReceipt, SessionIndex)> +where + RC: ProvideRuntimeApi<PBlock> + BlockchainEvents<PBlock>, + RC::Api: ParachainHost<PBlock>, +{ + relay_chain_client + .import_notification_stream() + .filter_map(move |n| { + let runtime_api = relay_chain_client.runtime_api(); + let res = runtime_api + .candidate_pending_availability(&BlockId::hash(n.hash), para_id) + .and_then(|pa| { + runtime_api + .session_index_for_child(&BlockId::hash(n.hash)) + .map(|v| pa.map(|pa| (pa, v))) + }) + .map_err(|e| { + tracing::error!( + target: LOG_TARGET, + error = ?e, + "Failed fetch pending candidates.", + ) + }) + .ok() + .flatten(); + + async move { res } + }) +} diff --git a/cumulus/client/pov-recovery/tests/pov_recovery.rs b/cumulus/client/pov-recovery/tests/pov_recovery.rs new file mode 100644 index 0000000000000000000000000000000000000000..f165b948794893da9007a4e112e3fdfc815d0610 --- /dev/null +++ b/cumulus/client/pov-recovery/tests/pov_recovery.rs @@ -0,0 +1,95 @@ +// Copyright 2021 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 cumulus_primitives_core::ParaId; +use cumulus_test_service::{initial_head_data, Keyring::*}; +use futures::join; +use sc_service::TaskExecutor; +use std::sync::Arc; + +/// Tests the PoV recovery. +/// +/// If there is a block of the parachain included/backed by the relay chain that isn't circulated in +/// the parachain network, we need to recover the PoV from the relay chain. Using this PoV we can +/// recover the block, import it and share it with the other nodes of the parachain network. +#[substrate_test_utils::test] +async fn pov_recovery(task_executor: TaskExecutor) { + let mut builder = sc_cli::LoggerBuilder::new(""); + builder.with_colors(false); + let _ = builder.init(); + + let para_id = ParaId::from(100); + + // Start alice + let alice = cumulus_test_service::run_relay_chain_validator_node( + task_executor.clone(), + Alice, + || {}, + vec![], + ); + + // Start bob + let bob = cumulus_test_service::run_relay_chain_validator_node( + task_executor.clone(), + Bob, + || {}, + vec![alice.addr.clone()], + ); + + // Register parachain + alice + .register_parachain( + para_id, + cumulus_test_service::runtime::WASM_BINARY + .expect("You need to build the WASM binary to run this test!") + .to_vec(), + initial_head_data(para_id), + ) + .await + .unwrap(); + + // Run charlie as parachain collator + let charlie = + cumulus_test_service::TestNodeBuilder::new(para_id, task_executor.clone(), Charlie) + .enable_collator() + .connect_to_relay_chain_nodes(vec![&alice, &bob]) + .wrap_announce_block(|_| { + // Never announce any block + Arc::new(|_, _| {}) + }) + .build() + .await; + + // Run dave as parachain full node + // + // It will need to recover the pov blocks through availability recovery. + let dave = cumulus_test_service::TestNodeBuilder::new(para_id, task_executor, Dave) + .enable_collator() + .use_null_consensus() + .connect_to_parachain_node(&charlie) + .connect_to_relay_chain_nodes(vec![&alice, &bob]) + .build() + .await; + + dave.wait_for_blocks(7).await; + + join!( + alice.task_manager.clean_shutdown(), + bob.task_manager.clean_shutdown(), + charlie.task_manager.clean_shutdown(), + dave.task_manager.clean_shutdown(), + ); +} diff --git a/cumulus/client/service/Cargo.toml b/cumulus/client/service/Cargo.toml index c9f4d4be86441df36da746a8ad9f89b28d4a2ed2..b4e1924c7f01833392c015858215f2c681490c27 100644 --- a/cumulus/client/service/Cargo.toml +++ b/cumulus/client/service/Cargo.toml @@ -8,6 +8,7 @@ edition = "2018" # Cumulus dependencies cumulus-client-consensus-common = { path = "../consensus/common" } cumulus-client-collator = { path = "../collator" } +cumulus-client-pov-recovery = { path = "../pov-recovery" } cumulus-primitives-core = { path = "../../primitives/core" } # Substrate dependencies @@ -16,6 +17,7 @@ sc-client-api = { git = "https://github.com/paritytech/substrate", branch = "mas sc-service = { git = "https://github.com/paritytech/substrate", branch = "master" } sc-telemetry = { git = "https://github.com/paritytech/substrate", branch = "master" } sc-tracing = { git = "https://github.com/paritytech/substrate", branch = "master" } +sc-consensus-babe = { git = "https://github.com/paritytech/substrate", branch = "master" } sp-consensus = { git = "https://github.com/paritytech/substrate", branch = "master" } sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "master" } sp-api = { git = "https://github.com/paritytech/substrate", branch = "master" } @@ -25,8 +27,9 @@ sp-blockchain = { git = "https://github.com/paritytech/substrate", branch = "mas # Polkadot dependencies polkadot-primitives = { git = "https://github.com/paritytech/polkadot", branch = "master" } polkadot-service = { git = "https://github.com/paritytech/polkadot", branch = "master" } +polkadot-overseer = { git = "https://github.com/paritytech/polkadot", branch = "master" } # Other deps -futures = "0.3.6" tracing = "0.1.22" codec = { package = "parity-scale-codec", version = "2.0.0" } +parking_lot = "0.10.2" diff --git a/cumulus/client/service/src/lib.rs b/cumulus/client/service/src/lib.rs index 4d112d40e6608fc7418b3c3b3cc468797ebc0087..a070dbd1a109f25484556e7ca5af7f79339ba12d 100644 --- a/cumulus/client/service/src/lib.rs +++ b/cumulus/client/service/src/lib.rs @@ -20,19 +20,25 @@ use cumulus_client_consensus_common::ParachainConsensus; use cumulus_primitives_core::{CollectCollationInfo, ParaId}; -use futures::FutureExt; +use polkadot_overseer::OverseerHandler; use polkadot_primitives::v1::{Block as PBlock, CollatorPair}; use polkadot_service::{AbstractClient, Client as PClient, ClientHandle, RuntimeApiCollection}; use sc_client_api::{ Backend as BackendT, BlockBackend, BlockchainEvents, Finalizer, UsageProvider, }; -use sc_service::{error::Result as ServiceResult, Configuration, Role, TaskManager}; +use sc_service::{Configuration, Role, TaskManager}; use sc_telemetry::TelemetryWorkerHandle; use sp_api::ProvideRuntimeApi; use sp_blockchain::HeaderBackend; -use sp_consensus::BlockImport; +use sp_consensus::{ + import_queue::{ImportQueue, IncomingBlock, Link, Origin}, + BlockImport, BlockOrigin, +}; use sp_core::traits::SpawnNamed; -use sp_runtime::traits::{BlakeTwo256, Block as BlockT}; +use sp_runtime::{ + traits::{BlakeTwo256, Block as BlockT, NumberFor}, + Justifications, +}; use std::{marker::PhantomData, sync::Arc}; pub mod genesis; @@ -41,7 +47,7 @@ pub mod genesis; type RFullNode<C> = polkadot_service::NewFull<C>; /// Parameters given to [`start_collator`]. -pub struct StartCollatorParams<'a, Block: BlockT, BS, Client, Spawner, RClient> { +pub struct StartCollatorParams<'a, Block: BlockT, BS, Client, Spawner, RClient, IQ> { pub block_status: Arc<BS>, pub client: Arc<Client>, pub announce_block: Arc<dyn Fn(Block::Hash, Option<Vec<u8>>) + Send + Sync>, @@ -51,6 +57,7 @@ pub struct StartCollatorParams<'a, Block: BlockT, BS, Client, Spawner, RClient> pub relay_chain_full_node: RFullNode<RClient>, pub task_manager: &'a mut TaskManager, pub parachain_consensus: Box<dyn ParachainConsensus<Block>>, + pub import_queue: IQ, } /// Start a collator node for a parachain. @@ -58,7 +65,7 @@ pub struct StartCollatorParams<'a, Block: BlockT, BS, Client, Spawner, RClient> /// A collator is similar to a validator in a normal blockchain. /// It is responsible for producing blocks and sending the blocks to a /// parachain validator for validation and inclusion into the relay chain. -pub async fn start_collator<'a, Block, BS, Client, Backend, Spawner, RClient>( +pub async fn start_collator<'a, Block, BS, Client, Backend, Spawner, RClient, IQ>( StartCollatorParams { block_status, client, @@ -69,7 +76,8 @@ pub async fn start_collator<'a, Block, BS, Client, Backend, Spawner, RClient>( task_manager, relay_chain_full_node, parachain_consensus, - }: StartCollatorParams<'a, Block, BS, Client, Spawner, RClient>, + import_queue, + }: StartCollatorParams<'a, Block, BS, Client, Spawner, RClient, IQ>, ) -> sc_service::error::Result<()> where Block: BlockT, @@ -88,6 +96,7 @@ where Spawner: SpawnNamed + Clone + Send + Sync + 'static, RClient: ClientHandle, Backend: BackendT<Block> + 'static, + IQ: ImportQueue<Block> + 'static, { relay_chain_full_node.client.execute_with(StartConsensus { para_id, @@ -95,6 +104,18 @@ where client: client.clone(), task_manager, _phantom: PhantomData, + }); + + relay_chain_full_node.client.execute_with(StartPoVRecovery { + para_id, + client: client.clone(), + import_queue, + task_manager, + overseer_handler: relay_chain_full_node + .overseer_handler + .clone() + .ok_or_else(|| "Polkadot full node did not provided an `OverseerHandler`!")?, + _phantom: PhantomData, })?; cumulus_client_collator::start_collator(cumulus_client_collator::StartCollatorParams { @@ -120,7 +141,7 @@ where pub struct StartFullNodeParams<'a, Block: BlockT, Client, PClient> { pub para_id: ParaId, pub client: Arc<Client>, - pub polkadot_full_node: RFullNode<PClient>, + pub relay_chain_full_node: RFullNode<PClient>, pub task_manager: &'a mut TaskManager, pub announce_block: Arc<dyn Fn(Block::Hash, Option<Vec<u8>>) + Send + Sync>, } @@ -134,7 +155,7 @@ pub fn start_full_node<Block, Client, Backend, PClient>( client, announce_block, task_manager, - polkadot_full_node, + relay_chain_full_node, para_id, }: StartFullNodeParams<Block, Client, PClient>, ) -> sc_service::error::Result<()> @@ -151,15 +172,15 @@ where Backend: BackendT<Block> + 'static, PClient: ClientHandle, { - polkadot_full_node.client.execute_with(StartConsensus { + relay_chain_full_node.client.execute_with(StartConsensus { announce_block, para_id, client, task_manager, _phantom: PhantomData, - })?; + }); - task_manager.add_child(polkadot_full_node.task_manager); + task_manager.add_child(relay_chain_full_node.task_manager); Ok(()) } @@ -186,7 +207,7 @@ where for<'b> &'b Client: BlockImport<Block>, Backend: BackendT<Block> + 'static, { - type Output = ServiceResult<()>; + type Output = (); fn execute_with_client<PClient, Api, PBackend>(self, client: Arc<PClient>) -> Self::Output where @@ -198,24 +219,60 @@ where { let consensus = cumulus_client_consensus_common::run_parachain_consensus( self.para_id, - self.client, - client, + self.client.clone(), + client.clone(), self.announce_block, ); - self.task_manager.spawn_essential_handle().spawn( - "cumulus-consensus", - consensus.then(|r| async move { - if let Err(e) = r { - tracing::error!( - target: "cumulus-service", - error = %e, - "Parachain consensus failed.", - ) - } - }), + self.task_manager + .spawn_essential_handle() + .spawn("cumulus-consensus", consensus); + } +} + +struct StartPoVRecovery<'a, Block: BlockT, Client, IQ> { + para_id: ParaId, + client: Arc<Client>, + task_manager: &'a mut TaskManager, + overseer_handler: OverseerHandler, + import_queue: IQ, + _phantom: PhantomData<Block>, +} + +impl<'a, Block, Client, IQ> polkadot_service::ExecuteWithClient for StartPoVRecovery<'a, Block, Client, IQ> +where + Block: BlockT, + Client: UsageProvider<Block> + + Send + + Sync + + BlockBackend<Block> + + BlockchainEvents<Block> + + 'static, + IQ: ImportQueue<Block> + 'static, +{ + type Output = sc_service::error::Result<()>; + + fn execute_with_client<PClient, Api, PBackend>(self, client: Arc<PClient>) -> Self::Output + where + <Api as sp_api::ApiExt<PBlock>>::StateBackend: sp_api::StateBackend<BlakeTwo256>, + PBackend: sc_client_api::Backend<PBlock>, + PBackend::State: sp_api::StateBackend<BlakeTwo256>, + Api: RuntimeApiCollection<StateBackend = PBackend::State>, + PClient: AbstractClient<PBlock, PBackend, Api = Api> + 'static, + { + let pov_recovery = cumulus_client_pov_recovery::PoVRecovery::new( + self.overseer_handler, + sc_consensus_babe::Config::get_or_compute(&*client)?.slot_duration(), + self.client, + self.import_queue, + client, + self.para_id, ); + self.task_manager + .spawn_essential_handle() + .spawn("cumulus-pov-recovery", pov_recovery.run()); + Ok(()) } } @@ -253,3 +310,38 @@ pub fn build_polkadot_full_node( ) } } + +/// A shared import queue +/// +/// This is basically a hack until the Substrate side is implemented properly. +#[derive(Clone)] +pub struct SharedImportQueue<Block: BlockT>(Arc<parking_lot::Mutex<dyn ImportQueue<Block>>>); + +impl<Block: BlockT> SharedImportQueue<Block> { + /// Create a new instance of the shared import queue. + pub fn new<IQ: ImportQueue<Block> + 'static>(import_queue: IQ) -> Self { + Self(Arc::new(parking_lot::Mutex::new(import_queue))) + } +} + +impl<Block: BlockT> ImportQueue<Block> for SharedImportQueue<Block> { + fn import_blocks(&mut self, origin: BlockOrigin, blocks: Vec<IncomingBlock<Block>>) { + self.0.lock().import_blocks(origin, blocks) + } + + fn import_justifications( + &mut self, + who: Origin, + hash: Block::Hash, + number: NumberFor<Block>, + justifications: Justifications, + ) { + self.0 + .lock() + .import_justifications(who, hash, number, justifications) + } + + fn poll_actions(&mut self, cx: &mut std::task::Context, link: &mut dyn Link<Block>) { + self.0.lock().poll_actions(cx, link) + } +} diff --git a/cumulus/polkadot-parachains/Cargo.toml b/cumulus/polkadot-parachains/Cargo.toml index 96f3d520a13431a55db08995dddbb9a03e8bbe23..38f379092bc5650447be865b0b520b0097840cf6 100644 --- a/cumulus/polkadot-parachains/Cargo.toml +++ b/cumulus/polkadot-parachains/Cargo.toml @@ -14,7 +14,7 @@ derive_more = "0.15.0" exit-future = "0.1.4" futures = { version = "0.3.1", features = ["compat"] } log = "0.4.8" -parking_lot = "0.9.0" +parking_lot = "0.10.2" trie-root = "0.15.2" codec = { package = "parity-scale-codec", version = "2.0.0" } structopt = "0.3.3" diff --git a/cumulus/polkadot-parachains/src/service.rs b/cumulus/polkadot-parachains/src/service.rs index 7f5cdac0fc432b7f019b8e6ca558baf21e497877..9eec9e3b02ec90c0300b93b85adb672326b37637 100644 --- a/cumulus/polkadot-parachains/src/service.rs +++ b/cumulus/polkadot-parachains/src/service.rs @@ -243,14 +243,14 @@ where let prometheus_registry = parachain_config.prometheus_registry().cloned(); let transaction_pool = params.transaction_pool.clone(); let mut task_manager = params.task_manager; - let import_queue = params.import_queue; + let import_queue = cumulus_client_service::SharedImportQueue::new(params.import_queue); let (network, network_status_sinks, system_rpc_tx, start_network) = sc_service::build_network(sc_service::BuildNetworkParams { config: ¶chain_config, client: client.clone(), transaction_pool: transaction_pool.clone(), spawn_handle: task_manager.spawn_handle(), - import_queue, + import_queue: import_queue.clone(), on_demand: None, block_announce_validator_builder: Some(Box::new(|_| block_announce_validator)), })?; @@ -304,6 +304,7 @@ where relay_chain_full_node, spawner, parachain_consensus, + import_queue, }; start_collator(params).await?; @@ -313,7 +314,7 @@ where announce_block, task_manager: &mut task_manager, para_id: id, - polkadot_full_node: relay_chain_full_node, + relay_chain_full_node, }; start_full_node(params)?; diff --git a/cumulus/primitives/core/src/lib.rs b/cumulus/primitives/core/src/lib.rs index 363d9285a80487d94d3960edf95b6df390096446..c97feea0a3ab84128f4b42e1ee3b766e085bf51a 100644 --- a/cumulus/primitives/core/src/lib.rs +++ b/cumulus/primitives/core/src/lib.rs @@ -215,6 +215,11 @@ impl<B: BlockT> ParachainBlockData<B> { } } + /// Convert `self` into the stored block. + pub fn into_block(self) -> B { + B::new(self.header, self.extrinsics) + } + /// Convert `self` into the stored header. pub fn into_header(self) -> B::Header { self.header diff --git a/cumulus/test/client/src/lib.rs b/cumulus/test/client/src/lib.rs index 24d06c7497df4db5ee666996d9d9422efc19febe..4fe379ccb1e9c392dee35545b214aad71d4dc230 100644 --- a/cumulus/test/client/src/lib.rs +++ b/cumulus/test/client/src/lib.rs @@ -47,7 +47,8 @@ pub use local_executor::LocalExecutor; pub type Backend = substrate_test_client::Backend<Block>; /// Test client executor. -pub type Executor = client::LocalCallExecutor<Backend, sc_executor::NativeExecutor<LocalExecutor>>; +pub type Executor = + client::LocalCallExecutor<Block, Backend, sc_executor::NativeExecutor<LocalExecutor>>; /// Test client builder for Cumulus pub type TestClientBuilder = diff --git a/cumulus/test/service/Cargo.toml b/cumulus/test/service/Cargo.toml index 268b9feee180b92f7a92882bc76d99b5bae26e95..05ae59b2594b682909cb88fd601b9f94472e1766 100644 --- a/cumulus/test/service/Cargo.toml +++ b/cumulus/test/service/Cargo.toml @@ -8,6 +8,7 @@ edition = "2018" codec = { package = "parity-scale-codec", version = "2.0.0" } rand = "0.7.3" serde = { version = "1.0.101", features = ["derive"] } +async-trait = "0.1.42" # Substrate frame-system = { git = "https://github.com/paritytech/substrate", branch = "master" } @@ -49,6 +50,7 @@ polkadot-overseer = { git = "https://github.com/paritytech/polkadot", branch = " cumulus-client-consensus-relay-chain = { path = "../../client/consensus/relay-chain" } cumulus-client-network = { path = "../../client/network" } cumulus-client-service = { path = "../../client/service" } +cumulus-client-consensus-common = { path = "../../client/consensus/common" } cumulus-primitives-core = { path = "../../primitives/core" } cumulus-primitives-parachain-inherent = { path = "../../primitives/parachain-inherent" } cumulus-test-runtime = { path = "../runtime" } diff --git a/cumulus/test/service/src/lib.rs b/cumulus/test/service/src/lib.rs index c958e76b521c73f4440aaa0e9ee91447f396699b..c424f74b045c75df4ca7fc25f4c52e558c21fde0 100644 --- a/cumulus/test/service/src/lib.rs +++ b/cumulus/test/service/src/lib.rs @@ -22,13 +22,14 @@ mod chain_spec; mod genesis; use core::future::Future; +use cumulus_client_consensus_common::{ParachainCandidate, ParachainConsensus}; use cumulus_client_network::BlockAnnounceValidator; use cumulus_client_service::{ prepare_node_config, start_collator, start_full_node, StartCollatorParams, StartFullNodeParams, }; use cumulus_primitives_core::ParaId; -use cumulus_test_runtime::{NodeBlock as Block, RuntimeApi}; -use polkadot_primitives::v1::CollatorPair; +use cumulus_test_runtime::{Hash, Header, NodeBlock as Block, RuntimeApi}; +use polkadot_primitives::v1::{CollatorPair, Hash as PHash, PersistedValidationData}; use sc_client_api::execution_extensions::ExecutionStrategies; use sc_executor::native_executor_instance; pub use sc_executor::NativeExecutor; @@ -45,11 +46,7 @@ use sp_arithmetic::traits::SaturatedConversion; use sp_blockchain::HeaderBackend; use sp_core::{Pair, H256}; use sp_keyring::Sr25519Keyring; -use sp_runtime::{ - codec::Encode, - generic, - traits::BlakeTwo256 -}; +use sp_runtime::{codec::Encode, generic, traits::BlakeTwo256}; use sp_state_machine::BasicExternalities; use sp_trie::PrefixedMemoryDB; use std::sync::Arc; @@ -62,6 +59,25 @@ pub use cumulus_test_runtime as runtime; pub use genesis::*; pub use sp_keyring::Sr25519Keyring as Keyring; +/// A consensus that will never produce any block. +#[derive(Clone)] +struct NullConsensus; + +#[async_trait::async_trait] +impl ParachainConsensus<Block> for NullConsensus { + async fn produce_candidate( + &mut self, + _: &Header, + _: PHash, + _: &PersistedValidationData, + ) -> Option<ParachainCandidate<Block>> { + None + } +} + +/// The signature of the announce block fn. +pub type AnnounceBlockFn = Arc<dyn Fn(Hash, Option<Vec<u8>>) + Send + Sync>; + // Native executor instance. native_executor_instance!( pub RuntimeExecutor, @@ -134,7 +150,9 @@ async fn start_node_impl<RB>( collator_key: Option<CollatorPair>, relay_chain_config: Configuration, para_id: ParaId, + wrap_announce_block: Option<Box<dyn FnOnce(AnnounceBlockFn) -> AnnounceBlockFn>>, rpc_ext_builder: RB, + consensus: Consensus, ) -> sc_service::error::Result<( TaskManager, Arc<TFullClient<Block, RuntimeApi, RuntimeExecutor>>, @@ -185,14 +203,14 @@ where let block_announce_validator_builder = move |_| Box::new(block_announce_validator) as Box<_>; let prometheus_registry = parachain_config.prometheus_registry().cloned(); - let import_queue = params.import_queue; + let import_queue = cumulus_client_service::SharedImportQueue::new(params.import_queue); let (network, network_status_sinks, system_rpc_tx, start_network) = sc_service::build_network(sc_service::BuildNetworkParams { config: ¶chain_config, client: client.clone(), transaction_pool: transaction_pool.clone(), spawn_handle: task_manager.spawn_handle(), - import_queue, + import_queue: import_queue.clone(), on_demand: None, block_announce_validator_builder: Some(Box::new(block_announce_validator_builder)), })?; @@ -224,43 +242,57 @@ where Arc::new(move |hash, data| network.announce_block(hash, data)) }; - if let Some(collator_key) = collator_key { - let proposer_factory = sc_basic_authorship::ProposerFactory::with_proof_recording( - task_manager.spawn_handle(), - client.clone(), - transaction_pool, - prometheus_registry.as_ref(), - None, - ); - - let relay_chain_client = relay_chain_full_node.client.clone(); - let relay_chain_backend = relay_chain_full_node.backend.clone(); + let announce_block = wrap_announce_block + .map(|w| (w)(announce_block.clone())) + .unwrap_or_else(|| announce_block); - let parachain_consensus = cumulus_client_consensus_relay_chain::RelayChainConsensus::new( - para_id, - proposer_factory, - move |_, (relay_parent, validation_data)| { - let parachain_inherent = - cumulus_primitives_parachain_inherent::ParachainInherentData::create_at( - relay_parent, - &*relay_chain_client, - &*relay_chain_backend, - &validation_data, + if let Some(collator_key) = collator_key { + let parachain_consensus: Box<dyn ParachainConsensus<Block>> = match consensus { + Consensus::RelayChain => { + let proposer_factory = sc_basic_authorship::ProposerFactory::with_proof_recording( + task_manager.spawn_handle(), + client.clone(), + transaction_pool, + prometheus_registry.as_ref(), + None, + ); + + let relay_chain_client = relay_chain_full_node.client.clone(); + let relay_chain_backend = relay_chain_full_node.backend.clone(); + + Box::new( + cumulus_client_consensus_relay_chain::RelayChainConsensus::new( para_id, - ); - async move { - let time = sp_timestamp::InherentDataProvider::from_system_time(); - - let parachain_inherent = parachain_inherent.ok_or_else(|| { - Box::<dyn std::error::Error + Send + Sync>::from(String::from("error")) - })?; - Ok((time, parachain_inherent)) - } - }, - client.clone(), - relay_chain_full_node.client.clone(), - relay_chain_full_node.backend.clone(), - ); + proposer_factory, + move |_, (relay_parent, validation_data)| { + let parachain_inherent = + cumulus_primitives_parachain_inherent::ParachainInherentData::create_at( + relay_parent, + &*relay_chain_client, + &*relay_chain_backend, + &validation_data, + para_id, + ); + + async move { + let time = sp_timestamp::InherentDataProvider::from_system_time(); + + let parachain_inherent = parachain_inherent.ok_or_else(|| { + Box::<dyn std::error::Error + Send + Sync>::from(String::from( + "error", + )) + })?; + Ok((time, parachain_inherent)) + } + }, + client.clone(), + relay_chain_full_node.client.clone(), + relay_chain_full_node.backend.clone(), + ), + ) + } + Consensus::Null => Box::new(NullConsensus), + }; let relay_chain_full_node = relay_chain_full_node.with_client(polkadot_test_service::TestClient); @@ -273,8 +305,9 @@ where task_manager: &mut task_manager, para_id, collator_key, - parachain_consensus: Box::new(parachain_consensus), + parachain_consensus, relay_chain_full_node, + import_queue, }; start_collator(params).await?; @@ -287,7 +320,7 @@ where announce_block, task_manager: &mut task_manager, para_id, - polkadot_full_node: relay_chain_full_node, + relay_chain_full_node, }; start_full_node(params)?; @@ -313,6 +346,12 @@ pub struct TestNode { pub rpc_handlers: RpcHandlers, } +enum Consensus { + /// Use the relay-chain provided consensus. + RelayChain, + /// Use the null consensus that will never produce any block. + Null, +} /// A builder to create a [`TestNode`]. pub struct TestNodeBuilder { @@ -323,8 +362,10 @@ pub struct TestNodeBuilder { parachain_nodes: Vec<MultiaddrWithPeerId>, parachain_nodes_exclusive: bool, relay_chain_nodes: Vec<MultiaddrWithPeerId>, + wrap_announce_block: Option<Box<dyn FnOnce(AnnounceBlockFn) -> AnnounceBlockFn>>, storage_update_func_parachain: Option<Box<dyn Fn()>>, storage_update_func_relay_chain: Option<Box<dyn Fn()>>, + consensus: Consensus, } impl TestNodeBuilder { @@ -342,8 +383,10 @@ impl TestNodeBuilder { parachain_nodes: Vec::new(), parachain_nodes_exclusive: false, relay_chain_nodes: Vec::new(), + wrap_announce_block: None, storage_update_func_parachain: None, storage_update_func_relay_chain: None, + consensus: Consensus::RelayChain, } } @@ -404,32 +447,43 @@ impl TestNodeBuilder { mut self, nodes: impl IntoIterator<Item = &'a polkadot_test_service::PolkadotTestNode>, ) -> Self { - self.relay_chain_nodes.extend(nodes.into_iter().map(|n| n.addr.clone())); + self.relay_chain_nodes + .extend(nodes.into_iter().map(|n| n.addr.clone())); self } - /// Allows accessing the parachain storage before the test node is built. - pub fn update_storage_parachain( + /// Wrap the announce block function of this node. + pub fn wrap_announce_block( mut self, - updater: impl Fn() + 'static, + wrap: impl FnOnce(AnnounceBlockFn) -> AnnounceBlockFn + 'static, ) -> Self { + self.wrap_announce_block = Some(Box::new(wrap)); + self + } + + /// Allows accessing the parachain storage before the test node is built. + pub fn update_storage_parachain(mut self, updater: impl Fn() + 'static) -> Self { self.storage_update_func_parachain = Some(Box::new(updater)); self } /// Allows accessing the relay chain storage before the test node is built. - pub fn update_storage_relay_chain( - mut self, - updater: impl Fn() + 'static, - ) -> Self { + pub fn update_storage_relay_chain(mut self, updater: impl Fn() + 'static) -> Self { self.storage_update_func_relay_chain = Some(Box::new(updater)); self } + /// Use the null consensus that will never author any block. + pub fn use_null_consensus(mut self) -> Self { + self.consensus = Consensus::Null; + self + } + /// Build the [`TestNode`]. pub async fn build(self) -> TestNode { let parachain_config = node_config( - self.storage_update_func_parachain.unwrap_or_else(|| Box::new(|| ())), + self.storage_update_func_parachain + .unwrap_or_else(|| Box::new(|| ())), self.task_executor.clone(), self.key.clone(), self.parachain_nodes, @@ -439,7 +493,8 @@ impl TestNodeBuilder { ) .expect("could not generate Configuration"); let mut relay_chain_config = polkadot_test_service::node_config( - self.storage_update_func_relay_chain.unwrap_or_else(|| Box::new(|| ())), + self.storage_update_func_relay_chain + .unwrap_or_else(|| Box::new(|| ())), self.task_executor, self.key, self.relay_chain_nodes, @@ -455,7 +510,9 @@ impl TestNodeBuilder { self.collator_key, relay_chain_config, self.para_id, + self.wrap_announce_block, |_| Default::default(), + self.consensus, ) .await .expect("could not create Cumulus test service"); @@ -611,7 +668,9 @@ impl TestNode { self.send_extrinsic( runtime::SudoCall::sudo_unchecked_weight(Box::new(call.into()), 1_000), Sr25519Keyring::Alice, - ).await.map(drop) + ) + .await + .map(drop) } } @@ -634,7 +693,10 @@ pub fn construct_extrinsic( let extra: runtime::SignedExtra = ( frame_system::CheckSpecVersion::<runtime::Runtime>::new(), frame_system::CheckGenesis::<runtime::Runtime>::new(), - frame_system::CheckEra::<runtime::Runtime>::from(generic::Era::mortal(period, current_block)), + frame_system::CheckEra::<runtime::Runtime>::from(generic::Era::mortal( + period, + current_block, + )), frame_system::CheckNonce::<runtime::Runtime>::from(nonce), frame_system::CheckWeight::<runtime::Runtime>::new(), pallet_transaction_payment::ChargeTransactionPayment::<runtime::Runtime>::from(tip),