diff --git a/Cargo.lock b/Cargo.lock index 2a1e220ef61..47fa32e6bba 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3156,7 +3156,7 @@ checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] name = "fork-tree" version = "3.0.0" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "parity-scale-codec", ] @@ -3179,7 +3179,7 @@ checksum = "6c2141d6d6c8512188a7891b4b01590a45f6dac67afb4f255c4124dbb86d4eaa" [[package]] name = "frame-benchmarking" version = "4.0.0-dev" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "frame-support", "frame-support-procedural", @@ -3204,7 +3204,7 @@ dependencies = [ [[package]] name = "frame-benchmarking-cli" version = "4.0.0-dev" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "Inflector", "array-bytes", @@ -3251,7 +3251,7 @@ dependencies = [ [[package]] name = "frame-election-provider-solution-type" version = "4.0.0-dev" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "proc-macro-crate 1.1.3", "proc-macro2", @@ -3262,7 +3262,7 @@ dependencies = [ [[package]] name = "frame-election-provider-support" version = "4.0.0-dev" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "frame-election-provider-solution-type", "frame-support", @@ -3279,7 +3279,7 @@ dependencies = [ [[package]] name = "frame-executive" version = "4.0.0-dev" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "frame-support", "frame-system", @@ -3308,7 +3308,7 @@ dependencies = [ [[package]] name = "frame-remote-externalities" version = "0.10.0-dev" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "futures", "log", @@ -3324,7 +3324,7 @@ dependencies = [ [[package]] name = "frame-support" version = "4.0.0-dev" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "bitflags 1.3.2", "environmental", @@ -3357,7 +3357,7 @@ dependencies = [ [[package]] name = "frame-support-procedural" version = "4.0.0-dev" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "Inflector", "cfg-expr", @@ -3372,7 +3372,7 @@ dependencies = [ [[package]] name = "frame-support-procedural-tools" version = "4.0.0-dev" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "frame-support-procedural-tools-derive", "proc-macro-crate 1.1.3", @@ -3384,7 +3384,7 @@ dependencies = [ [[package]] name = "frame-support-procedural-tools-derive" version = "3.0.0" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "proc-macro2", "quote", @@ -3394,7 +3394,7 @@ dependencies = [ [[package]] name = "frame-support-test" version = "3.0.0" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "frame-benchmarking", "frame-support", @@ -3418,7 +3418,7 @@ dependencies = [ [[package]] name = "frame-support-test-pallet" version = "4.0.0-dev" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "frame-support", "frame-system", @@ -3429,7 +3429,7 @@ dependencies = [ [[package]] name = "frame-system" version = "4.0.0-dev" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "frame-support", "log", @@ -3447,7 +3447,7 @@ dependencies = [ [[package]] name = "frame-system-benchmarking" version = "4.0.0-dev" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "frame-benchmarking", "frame-support", @@ -3462,7 +3462,7 @@ dependencies = [ [[package]] name = "frame-system-rpc-runtime-api" version = "4.0.0-dev" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "parity-scale-codec", "sp-api", @@ -3471,7 +3471,7 @@ dependencies = [ [[package]] name = "frame-try-runtime" version = "0.10.0-dev" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "frame-support", "parity-scale-codec", @@ -3761,16 +3761,16 @@ dependencies = [ name = "gear-authorship" version = "1.0.1" dependencies = [ - "demo-mul-by-const", + "demo-constructor", "env_logger", "frame-support", - "frame-system", "futures", "futures-timer", "gear-common", + "gear-core", "gear-node-testing", + "gear-runtime-common", "gear-runtime-primitives", - "gear-service", "log", "pallet-balances", "pallet-gear", @@ -3778,11 +3778,11 @@ dependencies = [ "pallet-gear-program", "pallet-gear-rpc-runtime-api", "pallet-sudo", - "pallet-timestamp", "parity-scale-codec", "sc-block-builder", "sc-client-api", "sc-proposer-metrics", + "sc-service", "sc-telemetry", "sc-transaction-pool", "sc-transaction-pool-api", @@ -3792,10 +3792,8 @@ dependencies = [ "sp-consensus-babe", "sp-core 7.0.0 (git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox)", "sp-inherents", - "sp-io 7.0.0 (git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox)", "sp-runtime 7.0.0 (git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox)", "sp-state-machine 0.13.0 (git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox)", - "sp-std 5.0.0 (git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox)", "sp-timestamp", "substrate-prometheus-endpoint", "vara-runtime", @@ -4501,7 +4499,7 @@ dependencies = [ [[package]] name = "generate-bags" version = "4.0.0-dev" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "chrono", "frame-election-provider-support", @@ -7166,7 +7164,7 @@ dependencies = [ [[package]] name = "pallet-authority-discovery" version = "4.0.0-dev" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "frame-support", "frame-system", @@ -7182,7 +7180,7 @@ dependencies = [ [[package]] name = "pallet-authorship" version = "4.0.0-dev" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "frame-support", "frame-system", @@ -7196,7 +7194,7 @@ dependencies = [ [[package]] name = "pallet-babe" version = "4.0.0-dev" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "frame-benchmarking", "frame-support", @@ -7220,7 +7218,7 @@ dependencies = [ [[package]] name = "pallet-bags-list" version = "4.0.0-dev" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "frame-benchmarking", "frame-election-provider-support", @@ -7240,7 +7238,7 @@ dependencies = [ [[package]] name = "pallet-balances" version = "4.0.0-dev" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "frame-benchmarking", "frame-support", @@ -7255,7 +7253,7 @@ dependencies = [ [[package]] name = "pallet-bounties" version = "4.0.0-dev" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "frame-benchmarking", "frame-support", @@ -7273,7 +7271,7 @@ dependencies = [ [[package]] name = "pallet-child-bounties" version = "4.0.0-dev" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "frame-benchmarking", "frame-support", @@ -7292,7 +7290,7 @@ dependencies = [ [[package]] name = "pallet-conviction-voting" version = "4.0.0-dev" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "assert_matches", "frame-benchmarking", @@ -7309,7 +7307,7 @@ dependencies = [ [[package]] name = "pallet-election-provider-multi-phase" version = "4.0.0-dev" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "frame-benchmarking", "frame-election-provider-support", @@ -7332,7 +7330,7 @@ dependencies = [ [[package]] name = "pallet-election-provider-support-benchmarking" version = "4.0.0-dev" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "frame-benchmarking", "frame-election-provider-support", @@ -7751,7 +7749,7 @@ dependencies = [ [[package]] name = "pallet-grandpa" version = "4.0.0-dev" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "frame-benchmarking", "frame-support", @@ -7774,7 +7772,7 @@ dependencies = [ [[package]] name = "pallet-identity" version = "4.0.0-dev" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "enumflags2 0.7.7", "frame-benchmarking", @@ -7790,7 +7788,7 @@ dependencies = [ [[package]] name = "pallet-im-online" version = "4.0.0-dev" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "frame-benchmarking", "frame-support", @@ -7810,7 +7808,7 @@ dependencies = [ [[package]] name = "pallet-multisig" version = "4.0.0-dev" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "frame-benchmarking", "frame-support", @@ -7826,7 +7824,7 @@ dependencies = [ [[package]] name = "pallet-nomination-pools" version = "1.0.0" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "frame-support", "frame-system", @@ -7843,7 +7841,7 @@ dependencies = [ [[package]] name = "pallet-nomination-pools-runtime-api" version = "1.0.0-dev" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "pallet-nomination-pools", "parity-scale-codec", @@ -7854,7 +7852,7 @@ dependencies = [ [[package]] name = "pallet-offences" version = "4.0.0-dev" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "frame-support", "frame-system", @@ -7871,7 +7869,7 @@ dependencies = [ [[package]] name = "pallet-preimage" version = "4.0.0-dev" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "frame-benchmarking", "frame-support", @@ -7888,7 +7886,7 @@ dependencies = [ [[package]] name = "pallet-proxy" version = "4.0.0-dev" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "frame-benchmarking", "frame-support", @@ -7903,7 +7901,7 @@ dependencies = [ [[package]] name = "pallet-ranked-collective" version = "4.0.0-dev" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "frame-benchmarking", "frame-support", @@ -7921,7 +7919,7 @@ dependencies = [ [[package]] name = "pallet-referenda" version = "4.0.0-dev" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "assert_matches", "frame-benchmarking", @@ -7940,7 +7938,7 @@ dependencies = [ [[package]] name = "pallet-scheduler" version = "4.0.0-dev" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "frame-benchmarking", "frame-support", @@ -7957,7 +7955,7 @@ dependencies = [ [[package]] name = "pallet-session" version = "4.0.0-dev" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "frame-support", "frame-system", @@ -7978,7 +7976,7 @@ dependencies = [ [[package]] name = "pallet-staking" version = "4.0.0-dev" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "frame-benchmarking", "frame-election-provider-support", @@ -8001,7 +7999,7 @@ dependencies = [ [[package]] name = "pallet-staking-reward-fn" version = "4.0.0-dev" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "log", "sp-arithmetic 6.0.0 (git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox)", @@ -8010,7 +8008,7 @@ dependencies = [ [[package]] name = "pallet-sudo" version = "4.0.0-dev" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "frame-support", "frame-system", @@ -8024,7 +8022,7 @@ dependencies = [ [[package]] name = "pallet-timestamp" version = "4.0.0-dev" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "frame-benchmarking", "frame-support", @@ -8042,7 +8040,7 @@ dependencies = [ [[package]] name = "pallet-transaction-payment" version = "4.0.0-dev" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "frame-support", "frame-system", @@ -8058,7 +8056,7 @@ dependencies = [ [[package]] name = "pallet-transaction-payment-rpc" version = "4.0.0-dev" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "jsonrpsee", "pallet-transaction-payment-rpc-runtime-api", @@ -8074,7 +8072,7 @@ dependencies = [ [[package]] name = "pallet-transaction-payment-rpc-runtime-api" version = "4.0.0-dev" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "pallet-transaction-payment", "parity-scale-codec", @@ -8086,7 +8084,7 @@ dependencies = [ [[package]] name = "pallet-treasury" version = "4.0.0-dev" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "frame-benchmarking", "frame-support", @@ -8103,7 +8101,7 @@ dependencies = [ [[package]] name = "pallet-utility" version = "4.0.0-dev" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "frame-benchmarking", "frame-support", @@ -8119,7 +8117,7 @@ dependencies = [ [[package]] name = "pallet-vesting" version = "4.0.0-dev" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "frame-benchmarking", "frame-support", @@ -8134,7 +8132,7 @@ dependencies = [ [[package]] name = "pallet-whitelist" version = "4.0.0-dev" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "frame-benchmarking", "frame-support", @@ -9621,7 +9619,7 @@ dependencies = [ [[package]] name = "sc-authority-discovery" version = "0.10.0-dev" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "async-trait", "futures", @@ -9649,7 +9647,7 @@ dependencies = [ [[package]] name = "sc-block-builder" version = "0.10.0-dev" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "parity-scale-codec", "sc-client-api", @@ -9664,7 +9662,7 @@ dependencies = [ [[package]] name = "sc-chain-spec" version = "4.0.0-dev" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "memmap2", "sc-chain-spec-derive", @@ -9683,7 +9681,7 @@ dependencies = [ [[package]] name = "sc-chain-spec-derive" version = "4.0.0-dev" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "proc-macro-crate 1.1.3", "proc-macro2", @@ -9694,7 +9692,7 @@ dependencies = [ [[package]] name = "sc-cli" version = "0.10.0-dev" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "array-bytes", "chrono", @@ -9734,7 +9732,7 @@ dependencies = [ [[package]] name = "sc-client-api" version = "4.0.0-dev" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "fnv", "futures", @@ -9760,7 +9758,7 @@ dependencies = [ [[package]] name = "sc-client-db" version = "0.10.0-dev" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "hash-db", "kvdb", @@ -9786,7 +9784,7 @@ dependencies = [ [[package]] name = "sc-consensus" version = "0.10.0-dev" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "async-trait", "futures", @@ -9811,7 +9809,7 @@ dependencies = [ [[package]] name = "sc-consensus-babe" version = "0.10.0-dev" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "async-trait", "fork-tree", @@ -9850,7 +9848,7 @@ dependencies = [ [[package]] name = "sc-consensus-babe-rpc" version = "0.10.0-dev" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "futures", "jsonrpsee", @@ -9872,7 +9870,7 @@ dependencies = [ [[package]] name = "sc-consensus-epochs" version = "0.10.0-dev" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "fork-tree", "parity-scale-codec", @@ -9885,7 +9883,7 @@ dependencies = [ [[package]] name = "sc-consensus-grandpa" version = "0.10.0-dev" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "ahash 0.8.3", "array-bytes", @@ -9925,7 +9923,7 @@ dependencies = [ [[package]] name = "sc-consensus-grandpa-rpc" version = "0.10.0-dev" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "finality-grandpa", "futures", @@ -9945,7 +9943,7 @@ dependencies = [ [[package]] name = "sc-consensus-slots" version = "0.10.0-dev" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "async-trait", "futures", @@ -9968,7 +9966,7 @@ dependencies = [ [[package]] name = "sc-executor" version = "0.10.0-dev" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "lru", "parity-scale-codec", @@ -9992,7 +9990,7 @@ dependencies = [ [[package]] name = "sc-executor-common" version = "0.10.0-dev" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "sp-allocator", "sp-maybe-compressed-blob", @@ -10005,7 +10003,7 @@ dependencies = [ [[package]] name = "sc-executor-wasmi" version = "0.10.0-dev" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "log", "sc-executor-common", @@ -10018,7 +10016,7 @@ dependencies = [ [[package]] name = "sc-executor-wasmtime" version = "0.10.0-dev" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "anyhow", "cfg-if", @@ -10036,7 +10034,7 @@ dependencies = [ [[package]] name = "sc-informant" version = "0.10.0-dev" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "ansi_term", "futures", @@ -10052,7 +10050,7 @@ dependencies = [ [[package]] name = "sc-keystore" version = "4.0.0-dev" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "array-bytes", "async-trait", @@ -10067,7 +10065,7 @@ dependencies = [ [[package]] name = "sc-network" version = "0.10.0-dev" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "array-bytes", "async-channel", @@ -10111,7 +10109,7 @@ dependencies = [ [[package]] name = "sc-network-bitswap" version = "0.10.0-dev" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "cid", "futures", @@ -10131,7 +10129,7 @@ dependencies = [ [[package]] name = "sc-network-common" version = "0.10.0-dev" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "array-bytes", "async-trait", @@ -10159,7 +10157,7 @@ dependencies = [ [[package]] name = "sc-network-gossip" version = "0.10.0-dev" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "ahash 0.8.3", "futures", @@ -10178,7 +10176,7 @@ dependencies = [ [[package]] name = "sc-network-light" version = "0.10.0-dev" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "array-bytes", "futures", @@ -10200,7 +10198,7 @@ dependencies = [ [[package]] name = "sc-network-sync" version = "0.10.0-dev" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "array-bytes", "async-trait", @@ -10234,7 +10232,7 @@ dependencies = [ [[package]] name = "sc-network-transactions" version = "0.10.0-dev" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "array-bytes", "futures", @@ -10254,7 +10252,7 @@ dependencies = [ [[package]] name = "sc-offchain" version = "4.0.0-dev" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "array-bytes", "bytes", @@ -10285,7 +10283,7 @@ dependencies = [ [[package]] name = "sc-peerset" version = "4.0.0-dev" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "futures", "libp2p", @@ -10298,7 +10296,7 @@ dependencies = [ [[package]] name = "sc-proposer-metrics" version = "0.10.0-dev" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "log", "substrate-prometheus-endpoint", @@ -10307,7 +10305,7 @@ dependencies = [ [[package]] name = "sc-rpc" version = "4.0.0-dev" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "futures", "jsonrpsee", @@ -10337,7 +10335,7 @@ dependencies = [ [[package]] name = "sc-rpc-api" version = "0.10.0-dev" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "jsonrpsee", "parity-scale-codec", @@ -10356,7 +10354,7 @@ dependencies = [ [[package]] name = "sc-rpc-server" version = "4.0.0-dev" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "http", "jsonrpsee", @@ -10371,7 +10369,7 @@ dependencies = [ [[package]] name = "sc-rpc-spec-v2" version = "0.10.0-dev" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "array-bytes", "futures", @@ -10397,7 +10395,7 @@ dependencies = [ [[package]] name = "sc-service" version = "0.10.0-dev" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "async-trait", "directories 4.0.1", @@ -10463,7 +10461,7 @@ dependencies = [ [[package]] name = "sc-state-db" version = "0.10.0-dev" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "log", "parity-scale-codec", @@ -10474,7 +10472,7 @@ dependencies = [ [[package]] name = "sc-storage-monitor" version = "0.1.0" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "clap 4.4.2", "fs4", @@ -10490,7 +10488,7 @@ dependencies = [ [[package]] name = "sc-sync-state-rpc" version = "0.10.0-dev" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "jsonrpsee", "parity-scale-codec", @@ -10509,7 +10507,7 @@ dependencies = [ [[package]] name = "sc-sysinfo" version = "6.0.0-dev" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "futures", "libc", @@ -10528,7 +10526,7 @@ dependencies = [ [[package]] name = "sc-telemetry" version = "4.0.0-dev" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "chrono", "futures", @@ -10547,7 +10545,7 @@ dependencies = [ [[package]] name = "sc-tracing" version = "4.0.0-dev" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "ansi_term", "atty", @@ -10578,7 +10576,7 @@ dependencies = [ [[package]] name = "sc-tracing-proc-macro" version = "4.0.0-dev" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "proc-macro-crate 1.1.3", "proc-macro2", @@ -10589,7 +10587,7 @@ dependencies = [ [[package]] name = "sc-transaction-pool" version = "4.0.0-dev" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "async-trait", "futures", @@ -10616,7 +10614,7 @@ dependencies = [ [[package]] name = "sc-transaction-pool-api" version = "4.0.0-dev" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "async-trait", "futures", @@ -10630,7 +10628,7 @@ dependencies = [ [[package]] name = "sc-utils" version = "4.0.0-dev" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "async-channel", "futures", @@ -11272,7 +11270,7 @@ dependencies = [ [[package]] name = "sp-allocator" version = "4.1.0-dev" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "log", "parity-scale-codec", @@ -11283,7 +11281,7 @@ dependencies = [ [[package]] name = "sp-api" version = "4.0.0-dev" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "hash-db", "log", @@ -11301,7 +11299,7 @@ dependencies = [ [[package]] name = "sp-api-proc-macro" version = "4.0.0-dev" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "Inflector", "blake2", @@ -11328,7 +11326,7 @@ dependencies = [ [[package]] name = "sp-application-crypto" version = "7.0.0" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "parity-scale-codec", "scale-info", @@ -11355,7 +11353,7 @@ dependencies = [ [[package]] name = "sp-arithmetic" version = "6.0.0" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "integer-sqrt", "num-traits", @@ -11369,7 +11367,7 @@ dependencies = [ [[package]] name = "sp-authority-discovery" version = "4.0.0-dev" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "parity-scale-codec", "scale-info", @@ -11382,7 +11380,7 @@ dependencies = [ [[package]] name = "sp-block-builder" version = "4.0.0-dev" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "parity-scale-codec", "sp-api", @@ -11394,7 +11392,7 @@ dependencies = [ [[package]] name = "sp-blockchain" version = "4.0.0-dev" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "futures", "log", @@ -11412,7 +11410,7 @@ dependencies = [ [[package]] name = "sp-consensus" version = "0.10.0-dev" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "async-trait", "futures", @@ -11427,7 +11425,7 @@ dependencies = [ [[package]] name = "sp-consensus-aura" version = "0.10.0-dev" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "async-trait", "parity-scale-codec", @@ -11445,7 +11443,7 @@ dependencies = [ [[package]] name = "sp-consensus-babe" version = "0.10.0-dev" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "async-trait", "merlin", @@ -11468,7 +11466,7 @@ dependencies = [ [[package]] name = "sp-consensus-grandpa" version = "4.0.0-dev" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "finality-grandpa", "log", @@ -11486,7 +11484,7 @@ dependencies = [ [[package]] name = "sp-consensus-slots" version = "0.10.0-dev" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "parity-scale-codec", "scale-info", @@ -11498,7 +11496,7 @@ dependencies = [ [[package]] name = "sp-consensus-vrf" version = "0.10.0-dev" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "parity-scale-codec", "scale-info", @@ -11554,7 +11552,7 @@ dependencies = [ [[package]] name = "sp-core" version = "7.0.0" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "array-bytes", "base58", @@ -11612,7 +11610,7 @@ dependencies = [ [[package]] name = "sp-core-hashing" version = "5.0.0" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "blake2b_simd", "byteorder", @@ -11626,7 +11624,7 @@ dependencies = [ [[package]] name = "sp-core-hashing-proc-macro" version = "5.0.0" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "proc-macro2", "quote", @@ -11637,7 +11635,7 @@ dependencies = [ [[package]] name = "sp-database" version = "4.0.0-dev" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "kvdb", "parking_lot 0.12.1", @@ -11656,7 +11654,7 @@ dependencies = [ [[package]] name = "sp-debug-derive" version = "5.0.0" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "proc-macro2", "quote", @@ -11677,7 +11675,7 @@ dependencies = [ [[package]] name = "sp-externalities" version = "0.13.0" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "environmental", "parity-scale-codec", @@ -11688,7 +11686,7 @@ dependencies = [ [[package]] name = "sp-inherents" version = "4.0.0-dev" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "async-trait", "impl-trait-for-tuples", @@ -11729,7 +11727,7 @@ dependencies = [ [[package]] name = "sp-io" version = "7.0.0" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "bytes", "ed25519 1.5.3", @@ -11754,7 +11752,7 @@ dependencies = [ [[package]] name = "sp-keyring" version = "7.0.0" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "lazy_static", "sp-core 7.0.0 (git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox)", @@ -11781,7 +11779,7 @@ dependencies = [ [[package]] name = "sp-keystore" version = "0.13.0" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "async-trait", "futures", @@ -11798,7 +11796,7 @@ dependencies = [ [[package]] name = "sp-maybe-compressed-blob" version = "4.1.0-dev" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "thiserror", "zstd", @@ -11807,7 +11805,7 @@ dependencies = [ [[package]] name = "sp-npos-elections" version = "4.0.0-dev" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "parity-scale-codec", "scale-info", @@ -11821,7 +11819,7 @@ dependencies = [ [[package]] name = "sp-offchain" version = "4.0.0-dev" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "sp-api", "sp-core 7.0.0 (git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox)", @@ -11841,7 +11839,7 @@ dependencies = [ [[package]] name = "sp-panic-handler" version = "5.0.0" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "backtrace", "lazy_static", @@ -11851,7 +11849,7 @@ dependencies = [ [[package]] name = "sp-rpc" version = "6.0.0" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "rustc-hash", "serde", @@ -11883,7 +11881,7 @@ dependencies = [ [[package]] name = "sp-runtime" version = "7.0.0" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "either", "hash256-std-hasher", @@ -11923,7 +11921,7 @@ dependencies = [ [[package]] name = "sp-runtime-interface" version = "7.0.0" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "bytes", "impl-trait-for-tuples", @@ -11953,7 +11951,7 @@ dependencies = [ [[package]] name = "sp-runtime-interface-proc-macro" version = "6.0.0" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "Inflector", "proc-macro-crate 1.1.3", @@ -11965,7 +11963,7 @@ dependencies = [ [[package]] name = "sp-session" version = "4.0.0-dev" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "parity-scale-codec", "scale-info", @@ -11979,7 +11977,7 @@ dependencies = [ [[package]] name = "sp-staking" version = "4.0.0-dev" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "parity-scale-codec", "scale-info", @@ -12011,7 +12009,7 @@ dependencies = [ [[package]] name = "sp-state-machine" version = "0.13.0" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "hash-db", "log", @@ -12036,7 +12034,7 @@ source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0 [[package]] name = "sp-std" version = "5.0.0" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" [[package]] name = "sp-storage" @@ -12054,7 +12052,7 @@ dependencies = [ [[package]] name = "sp-storage" version = "7.0.0" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "impl-serde", "parity-scale-codec", @@ -12067,7 +12065,7 @@ dependencies = [ [[package]] name = "sp-timestamp" version = "4.0.0-dev" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "async-trait", "futures-timer", @@ -12094,7 +12092,7 @@ dependencies = [ [[package]] name = "sp-tracing" version = "6.0.0" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "parity-scale-codec", "sp-std 5.0.0 (git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox)", @@ -12106,7 +12104,7 @@ dependencies = [ [[package]] name = "sp-transaction-pool" version = "4.0.0-dev" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "sp-api", "sp-runtime 7.0.0 (git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox)", @@ -12115,7 +12113,7 @@ dependencies = [ [[package]] name = "sp-transaction-storage-proof" version = "4.0.0-dev" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "async-trait", "log", @@ -12154,7 +12152,7 @@ dependencies = [ [[package]] name = "sp-trie" version = "7.0.0" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "ahash 0.8.3", "hash-db", @@ -12177,7 +12175,7 @@ dependencies = [ [[package]] name = "sp-version" version = "5.0.0" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "impl-serde", "parity-scale-codec", @@ -12194,7 +12192,7 @@ dependencies = [ [[package]] name = "sp-version-proc-macro" version = "4.0.0-dev" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "parity-scale-codec", "proc-macro2", @@ -12219,7 +12217,7 @@ dependencies = [ [[package]] name = "sp-wasm-interface" version = "7.0.0" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "anyhow", "impl-trait-for-tuples", @@ -12234,7 +12232,7 @@ dependencies = [ [[package]] name = "sp-wasm-interface-common" version = "7.0.0" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "parity-scale-codec", "sp-std 5.0.0 (git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox)", @@ -12259,7 +12257,7 @@ dependencies = [ [[package]] name = "sp-weights" version = "4.0.0" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "parity-scale-codec", "scale-info", @@ -12440,7 +12438,7 @@ dependencies = [ [[package]] name = "substrate-build-script-utils" version = "3.0.0" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "platforms 2.0.0", ] @@ -12448,7 +12446,7 @@ dependencies = [ [[package]] name = "substrate-frame-rpc-system" version = "4.0.0-dev" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "frame-system-rpc-runtime-api", "futures", @@ -12467,7 +12465,7 @@ dependencies = [ [[package]] name = "substrate-prometheus-endpoint" version = "0.10.0-dev" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "hyper", "log", @@ -12479,7 +12477,7 @@ dependencies = [ [[package]] name = "substrate-rpc-client" version = "0.10.0-dev" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "async-trait", "jsonrpsee", @@ -12492,7 +12490,7 @@ dependencies = [ [[package]] name = "substrate-state-trie-migration-rpc" version = "4.0.0-dev" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "jsonrpsee", "log", @@ -12511,7 +12509,7 @@ dependencies = [ [[package]] name = "substrate-test-client" version = "2.0.1" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "array-bytes", "async-trait", @@ -12557,7 +12555,7 @@ dependencies = [ [[package]] name = "substrate-wasm-builder" version = "5.0.0-dev" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "ansi_term", "build-helper", @@ -13302,7 +13300,7 @@ checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" [[package]] name = "try-runtime-cli" version = "0.10.0-dev" -source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#93aa762a96970dc7d5987a8c890a6be4912f3cd3" +source = "git+https://github.com/gear-tech/substrate.git?branch=gear-polkadot-v0.9.41-canary-no-sandbox#87bb086be2ef49b8cfbb56ae052c94ef11d64d7b" dependencies = [ "async-trait", "clap 4.4.2", diff --git a/common/src/lib.rs b/common/src/lib.rs index 64f47fd4aa4..ec85cff58f9 100644 --- a/common/src/lib.rs +++ b/common/src/lib.rs @@ -340,3 +340,14 @@ impl PaymentVoucher { + type Params: Send; + + fn deconstruct(self) -> (&'static C, Self::Params); + + fn restore(call: &C, params: Self::Params) -> Self; +} diff --git a/examples/constructor/src/builder.rs b/examples/constructor/src/builder.rs index 3b55569ab8c..64c0c5e558b 100644 --- a/examples/constructor/src/builder.rs +++ b/examples/constructor/src/builder.rs @@ -323,4 +323,8 @@ impl Calls { pub fn infinite_loop(self) -> Self { self.add_call(Call::Loop) } + + pub fn write_in_loop(self, count: impl Into>) -> Self { + self.add_call(Call::WriteN(count.into())) + } } diff --git a/examples/constructor/src/call.rs b/examples/constructor/src/call.rs index 06c0fde0edb..197d6487025 100644 --- a/examples/constructor/src/call.rs +++ b/examples/constructor/src/call.rs @@ -42,6 +42,7 @@ pub enum Call { Wake(Arg<[u8; 32]>), MessageId, Loop, + WriteN(Arg), } #[cfg(not(feature = "wasm-wrapper"))] @@ -317,6 +318,19 @@ mod wasm { Some(msg::id().encode()) } + fn write_n(self) -> Option> { + let Self::WriteN(count) = self else { + unreachable!() + }; + + let end = count.value(); + for i in 0_u64..end { + unsafe { DATA.insert("value".into(), i.encode()) }; + } + + None + } + pub(crate) fn process(self, previous: Option) -> CallResult { debug!("\t[CONSTRUCTOR] >> Processing {self:?}"); let call = self.clone(); @@ -347,6 +361,7 @@ mod wasm { Call::MessageId => self.message_id(), #[allow(clippy::empty_loop)] Call::Loop => loop {}, + Call::WriteN(..) => self.write_n(), }; (call, value) diff --git a/images/block-proposing-timing.svg b/images/block-proposing-timing.svg new file mode 100644 index 00000000000..6001295729d --- /dev/null +++ b/images/block-proposing-timing.svg @@ -0,0 +1,4 @@ + + + +
slot_duration
slot_duration
SlotWorker:: on_slot(...)
SlotWorker:: on_slot(....
SlotInfo
SlotInfo
proposing_remaining_duration (~ 50% of slot duration)
proposing_remaining_duration (~ 50% of slot durati...
end_proposing_at
end_proposing_...
SlotWorker:: propose(...)
SlotWorker:: propose(.....
proposing_remaining_duration = end_proposing_at - Instant::now()
proposing_remaining_duration = end_proposing_at - I...
Proposer:: propose(...)
Proposer:: propose(...)
max_duration = 0.98 * proposing_remaining_duration (~49%)
max_duration = 0.98 * proposing_remaining_duration...
end_proposing_at
end_proposing_at
proposing_remaining_duration
proposing_remaining_duration
Proposer:: propose_with(...)
Proposer:: propose_with(...)
max_duration
max_duration
finalize block
(on_idle, on_finalize)
finalize block...
time
time
weight
weight
max_block
max_block
max_total 
(DispatchClass::Normal)
max_total...
skipped tx
skipped tx
soft_deadline
soft_deadline
Runtime "realm"
Runtime "re...
Client "realm"
Client "rea...
deadline = 2/3 * max_duration (~33%)
deadline = 2/3 * max_duration (~3...
apply extrinsics
apply extrinsics
apply inherents
apply inher...
Text is not SVG - cannot display
\ No newline at end of file diff --git a/node/authorship/Cargo.toml b/node/authorship/Cargo.toml index 0ea077deb9a..b7acbfccab0 100644 --- a/node/authorship/Cargo.toml +++ b/node/authorship/Cargo.toml @@ -17,7 +17,6 @@ futures-timer.workspace = true log.workspace = true # Gear -runtime-primitives = { workspace = true, features = ["std"] } common = { workspace = true, features = ["std"] } pallet-gear-rpc-runtime-api = { workspace = true, features = ["std"] } @@ -28,6 +27,7 @@ sc-transaction-pool.workspace = true sc-transaction-pool-api.workspace = true sc-client-api.workspace = true sc-proposer-metrics.workspace = true +sc-service.workspace = true # Substrate Primitives sp-core = { workspace = true, features = ["std"] } @@ -38,26 +38,23 @@ sp-blockchain.workspace = true sp-inherents = { workspace = true, features = ["std"] } # Substrate Other -frame-system = { workspace = true, features = ["std"] } prometheus-endpoint.workspace = true [dev-dependencies] -common = { workspace = true, features = ["std"] } sc-transaction-pool.workspace = true frame-support = { workspace = true, features = ["std"] } -sp-io = { workspace = true, features = ["std"] } -sp-std = { workspace = true, features = ["std"] } sp-timestamp = { workspace = true, features = ["std"] } sp-consensus-babe = { workspace = true, features = ["std"] } sp-state-machine = { workspace = true, features = ["std"] } pallet-sudo = { workspace = true, features = ["std"] } -pallet-timestamp = { workspace = true, features = ["std"] } pallet-balances = { workspace = true, features = ["std"] } pallet-gear = { workspace = true, features = ["std"] } pallet-gear-messenger = { workspace = true, features = ["std"] } pallet-gear-program = { workspace = true, features = ["std"] } +runtime-primitives = { workspace = true, features = ["std"] } +gear-runtime-common = { workspace = true, features = ["std"] } +gear-core = { workspace = true, features = ["std"] } testing = {workspace = true, features = ["vara-native"] } vara-runtime = { workspace = true, features = ["std", "dev"] } -demo-mul-by-const = { workspace = true, features = ["debug"] } +demo-constructor = { workspace = true, features = ["std"] } env_logger.workspace = true -service = { workspace = true, features = ["vara-native"] } diff --git a/node/authorship/README.md b/node/authorship/README.md new file mode 100644 index 00000000000..fbd2e6611f7 --- /dev/null +++ b/node/authorship/README.md @@ -0,0 +1,73 @@ +# Gear block proposer and builder. + +This crate provides an extended implementations of the original Substrate's [`BlockBuilder`](https://docs.rs/sc-block-builder/latest/sc_block_builder/struct.BlockBuilder.html) utility and the corresponding runtime api, and a custom implementation of the [`Proposer`](https://docs.rs/sp-consensus/latest/sp_consensus/trait.Proposer.html) trait. + +The need for an custom implementations arises from the fact that in Gear a special pseudo-inherent exists that has to be added at the end of each block after all the normal extrinsics have been pushed. Furthermore, to guarantee consistent block production, this pseudo-inherent must not step beyond the block proposing deadline defined by the node client. This requires additional functionality that is not provided by the original `BlockBuilder` utility. + +## Overview + +For the correct network functioning it is crucial that blocks are created in each time slot. +This requires synchronization between the node client (which operates in terms of milli and nano-seconds) and the `Runtime` +whose notion of time is represented by the block `Weight`. + +In the default Substrate's implementation the deadline for the block creation goes through a series of transformations before the proposer actually gets to applying extrinsics to fill the block: + +

+ Gear +

+ +The original "source of truth" in terms of the block creation time is the same - the `SLOT_DURATOIN` runtime constant. Eventually, the time allocated for processing of extirnsics of all `DispatchClass`'es will constitute almost exactly 1/3 of the overall block time. The same idea is true for the `Runtime` - the `MAXIMUM_BLOCK_WEIGHT` constant calculated as 1/3 of the total possible block `Weight`: + +``` +` time, | weight | +` ms | | +` | | +` 3000 |------| 3*10^12|------| +` | | | | +` | | | | +` | | | | +` | | | | +` 980 |------|- proposal 10^12 |------|- max_block +` |//////| deadline |//////| +` |//////| |//////| +` 0 -------------------------------------------- +``` + +As long as this synchronization between how the client counts the remaining time and the `Runtime` that tracks the current block weight (provided the extrinsics benchmarking is adequate) is maintained, we can be almost sure the block timing is consistent: the `DispatchClass::Normal` extrinsics by default are allowed to take up to 80% of the weight, the rest being taken by the inherents, therefore the probability of exhausting the weight before the time has run out (and vise versa) is relatively low. +The finalization of the block is not supposed to be included in this time frame. + +## Gear flow specifics + +In our case there is a couple of potential pitfalls: +- the share of the `DispatchClass::Normal` extrinsics in the `Runtime` is about 25% as opposed to the default Substrate's 80% (see `NORMAL_DISPATCH_RATIO` constant). +This means that, provided the block proposing deadline is left intact in the client, in case the number of transactions in the `txpool`'s' `ready` queue is high, we can exhaust the allowed block weight for normal extrinsics way before the deadline is reached. It will lead to a situation when extrinsics are "skipped" (marked as "invalid" based on the `check_weight` signed extension) and placed into the `revalidation` queue for the following blocks, while the consumed weight in the current block doesn't change. This could in theory take up to the `soft_deadline` point, which is currently 50% of the whole proposing time. Then, the `Gear::run()` pseudo-inherent is executed before the block finalization, and it assumes it still has at least 3/4 of the block weight to spend. Even if the `Gear::run()` gas consumption matches the expected remaining weight this still may lead to the "Block production took too long" error and the block will be rejected. +
+ +- The amount of time the `Gear::run()` pseudo-inherent actually takes can also be somewhat indeterministic and depend on lots of variables we can't accurately measure and benchmark upfront. This can result in the same error, as well. + +## Custom Proposer implementation + +To mitigte the above and keep the block timing consistent a couple of things can be done in our custom block proposer implementation: + +- Align the proposing deadline with the block weight corresponding to the normal extrinsics. +There are two ways to go about it: + 1) Manually reduce the "hard" deadline for the extrinsics application proportionally to the respective block weight quota. + 2) Lower the `soft_deadline` percentage to limit the number of tries to add another extrinsic upon the block resources exhaustion. + + Both solutions serve the same purpose - to have a deterministic deadline for the extrinsics application in a block. + The difference is in nuances. + Following the first approach, we can set the proposal deadline to, say, `~300ms`, which should be sufficient to use up all the associated weight, at the same time setting the deterministic upper bound on the time interval during which the `Gear::run()` pseudo-inherent starts. + Following the second approach, we can lower the `soft_deadline` to roughly 20% to ensure that if it turns out we have started skipping extrinsics (exhausted the weight portion), it better be beyond the `soft_deadline` point, so that the maximum attempts to try adding more extrinsics will be limited to the `MAX_SKIPPED_TRANSACTIONS` constant (reduced to 5 from the default 8). This will also set more rigorous bounds on when the `Gear::run()` can start executing. The caveat is, however, that setting an inadeqate `soft_deadline` (too low) can lead to under-populated blocks. + + Current implementation follows the second approach as "less invasive" and more flexible. In case the "Block production took too long" issue persists, switching to the first approach can be considered. +
+- Introduce a timeout for the `Gear::run()` pseudo-inherent to make sure it doesn't spill over the allowed time (in milliseconds). If the timeout is triggered, the pseudo-inherent is dropped and the block is finalized as is (without message queue processing). If this issue persists for a number of blocks, action can be taken offchain to mitigate the problem (like restarting validators with the `--max-gas` option etc.). + +## Extended BlockBuilder implementation + +In order to serve the purpose, a `BlockBuilder` implementation must be able to: +- Call the Gear specific runtime api to obtain the encoded `Gear::run()` pseudo-inherent from the runtime. +
+- Clone self in order to maintain the underlying runtime api instance with the overlay that contains all the changes made to the state during the extrinsics application and wait for the `Gear::run()` pseudo-inherent completion on the cloned runtime api instance in a separate thread as long as the deadline is not reached. If the deadline has been slipped, the "backup" overlay is used to build the block. Otherwise, the updated overlay returned from the `Gear::run()` thread is used as per normal. + +The last point requires quite drastic changes in the original `BlockBuilder` implementation (also to the extent of making changes in the underlying Substrate code in our fork to make some times cloneable, which are not by default). Specifically, we need to be able to clone and destruct the runtime api object into parts and send those parts in a separate thread to restore the `BlockBuilder` in such a way that it has the same state as if it had called the block initialization and all the extrinsics application runtime apis before the `Gear::run()` extrinsic can be applied. diff --git a/node/authorship/src/authorship.rs b/node/authorship/src/authorship.rs index ec5d35050ea..acfae28048e 100644 --- a/node/authorship/src/authorship.rs +++ b/node/authorship/src/authorship.rs @@ -17,30 +17,39 @@ // along with this program. If not, see . use codec::Encode; +use common::RuntimeApiExt; use futures::{ channel::oneshot, future, - future::{Future, FutureExt}, + future::{Either, Future, FutureExt}, select, }; +use futures_timer::Delay; use log::{debug, error, info, trace, warn}; use pallet_gear_rpc_runtime_api::GearApi as GearRuntimeApi; use sc_block_builder::{BlockBuilderApi, BlockBuilderProvider}; use sc_client_api::backend; use sc_telemetry::{telemetry, TelemetryHandle, CONSENSUS_INFO}; use sc_transaction_pool_api::{InPoolTransaction, TransactionPool}; -use sp_api::{ApiExt, ProvideRuntimeApi}; +use sp_api::{ApiExt, ApiRef, ProvideRuntimeApi}; use sp_blockchain::{ApplyExtrinsicFailed::Validity, Error::ApplyExtrinsicFailed, HeaderBackend}; use sp_consensus::{DisableProofRecording, EnableProofRecording, ProofRecording, Proposal}; use sp_core::traits::SpawnNamed; use sp_inherents::InherentData; use sp_runtime::{ + generic::BlockId, traits::{BlakeTwo256, Block as BlockT, Hash as HashT, Header as HeaderT}, Digest, Percent, SaturatedConversion, }; -use std::{marker::PhantomData, pin::Pin, sync::Arc, time}; +use std::{ + marker::PhantomData, + ops::Deref, + pin::Pin, + sync::Arc, + time::{Duration, Instant}, +}; -use crate::block_builder::BlockBuilderExt; +use crate::block_builder::BlockBuilder; use prometheus_endpoint::Registry as PrometheusRegistry; use sc_proposer_metrics::{EndProposingReason, MetricsLink as PrometheusMetrics}; @@ -53,13 +62,15 @@ use sc_proposer_metrics::{EndProposingReason, MetricsLink as PrometheusMetrics}; /// transferred to other nodes. pub const DEFAULT_BLOCK_SIZE_LIMIT: usize = 4 * 1024 * 1024 + 512; -const DEFAULT_SOFT_DEADLINE_PERCENT: Percent = Percent::from_percent(50); +const DEFAULT_SOFT_DEADLINE_PERCENT: Percent = Percent::from_percent(20); /// [`Proposer`] factory. pub struct ProposerFactory { spawn_handle: Box, /// The client instance. client: Arc, + /// The backend instance. + backend: Arc, /// The transaction pool. transaction_pool: Arc, /// Prometheus Link, @@ -82,18 +93,19 @@ pub struct ProposerFactory { include_proof_in_block_size_estimation: bool, /// Hard limit for the gas allowed to burn in one block. max_gas: Option, - /// phantom member to pin the `Backend`/`ProofRecording` type. - _phantom: PhantomData<(B, PR)>, + /// phantom member to pin the `ProofRecording` type. + _phantom: PhantomData, } impl ProposerFactory { /// Create a new proposer factory. /// - /// Proof recording will be disabled when using proposers built by this instance to build - /// blocks. + /// Proof recording will be disabled when using proposers built by this instance + /// to build blocks. pub fn new( spawn_handle: impl SpawnNamed + 'static, client: Arc, + backend: Arc, transaction_pool: Arc, prometheus: Option<&PrometheusRegistry>, telemetry: Option, @@ -107,6 +119,7 @@ impl ProposerFactory { soft_deadline_percent: DEFAULT_SOFT_DEADLINE_PERCENT, telemetry, client, + backend, include_proof_in_block_size_estimation: false, max_gas, _phantom: PhantomData, @@ -124,12 +137,14 @@ impl ProposerFactory { pub fn with_proof_recording( spawn_handle: impl SpawnNamed + 'static, client: Arc, + backend: Arc, transaction_pool: Arc, prometheus: Option<&PrometheusRegistry>, telemetry: Option, ) -> Self { ProposerFactory { client, + backend, spawn_handle: Box::new(spawn_handle), transaction_pool, metrics: PrometheusMetrics::new(prometheus), @@ -190,12 +205,13 @@ where + 'static, C::Api: ApiExt> + BlockBuilderApi - + GearRuntimeApi, + + GearRuntimeApi + + Clone, { fn init_with_now( &mut self, parent_header: &::Header, - now: Box time::Instant + Send + Sync>, + now: Box Instant + Send + Sync>, ) -> Proposer { let parent_hash = parent_header.hash(); @@ -207,6 +223,7 @@ where let proposer = Proposer::<_, _, _, _, PR> { spawn_handle: self.spawn_handle.clone(), client: self.client.clone(), + backend: self.backend.clone(), parent_hash, parent_number: *parent_header.number(), transaction_pool: self.transaction_pool.clone(), @@ -237,7 +254,9 @@ where + 'static, C::Api: ApiExt> + BlockBuilderApi - + GearRuntimeApi, + + GearRuntimeApi + + Clone + + RuntimeApiExt, PR: ProofRecording, { type CreateProposer = future::Ready>; @@ -245,9 +264,7 @@ where type Error = sp_blockchain::Error; fn init(&mut self, parent_header: &::Header) -> Self::CreateProposer { - future::ready(Ok( - self.init_with_now(parent_header, Box::new(time::Instant::now)) - )) + future::ready(Ok(self.init_with_now(parent_header, Box::new(Instant::now)))) } } @@ -255,17 +272,18 @@ where pub struct Proposer { spawn_handle: Box, client: Arc, + backend: Arc, parent_hash: Block::Hash, parent_number: <::Header as HeaderT>::Number, transaction_pool: Arc, - now: Box time::Instant + Send + Sync>, + now: Box Instant + Send + Sync>, metrics: PrometheusMetrics, default_block_size_limit: usize, include_proof_in_block_size_estimation: bool, soft_deadline_percent: Percent, telemetry: Option, max_gas: Option, - _phantom: PhantomData<(B, PR)>, + _phantom: PhantomData, } impl sp_consensus::Proposer for Proposer @@ -281,7 +299,9 @@ where + 'static, C::Api: ApiExt> + BlockBuilderApi - + GearRuntimeApi, + + GearRuntimeApi + + Clone + + RuntimeApiExt, PR: ProofRecording, { type Transaction = backend::TransactionFor; @@ -299,7 +319,7 @@ where self, inherent_data: InherentData, inherent_digests: Digest, - max_duration: time::Duration, + max_duration: Duration, block_size_limit: Option, ) -> Self::Proposal { let (tx, rx) = oneshot::channel(); @@ -327,7 +347,7 @@ where /// If the block is full we will attempt to push at most /// this number of transactions before quitting for real. /// It allows us to increase block utilization. -const MAX_SKIPPED_TRANSACTIONS: usize = 8; +const MAX_SKIPPED_TRANSACTIONS: usize = 5; impl Proposer where @@ -342,28 +362,36 @@ where + 'static, C::Api: ApiExt> + BlockBuilderApi - + GearRuntimeApi, + + GearRuntimeApi + + Clone + + RuntimeApiExt, PR: ProofRecording, { async fn propose_with( self, inherent_data: InherentData, inherent_digests: Digest, - deadline: time::Instant, + deadline: Instant, block_size_limit: Option, ) -> Result, PR::Proof>, sp_blockchain::Error> { - let propose_with_start = time::Instant::now(); - let mut block_builder = BlockBuilderExt::new( - self.client - .new_block_at(self.parent_hash, inherent_digests, PR::ENABLED)?, - self.client.runtime_api(), - self.parent_hash, - ); + let propose_with_start = Instant::now(); + let parent_hash = self.parent_hash; + let parent_number = self + .client + .expect_block_number_from_id(&BlockId::Hash(parent_hash))?; + let mut block_builder = BlockBuilder::new( + self.client.as_ref(), + parent_hash, + parent_number, + PR::ENABLED.into(), + inherent_digests.clone(), + self.backend.as_ref(), + )?; - let create_inherents_start = time::Instant::now(); + let create_inherents_start = Instant::now(); let inherents = block_builder.create_inherents(inherent_data)?; - let create_inherents_end = time::Instant::now(); + let create_inherents_end = Instant::now(); self.metrics.report(|metrics| { metrics.create_inherents_time.observe( @@ -400,8 +428,8 @@ where let left = deadline.saturating_duration_since(now); let left_micros: u64 = left.as_micros().saturated_into(); let soft_deadline = - now + time::Duration::from_micros(self.soft_deadline_percent.mul_floor(left_micros)); - let block_timer = time::Instant::now(); + now + Duration::from_micros(self.soft_deadline_percent.mul_floor(left_micros)); + let block_timer = Instant::now(); let mut skipped = 0; let mut unqueue_invalid = Vec::new(); @@ -412,7 +440,7 @@ where let mut pending_iterator = select! { res = t1 => res, _ = t2 => { - log::warn!(target: "gear::authorship", + warn!(target: "gear::authorship", "Timeout fired waiting for transaction pool at block #{}. \ Proceeding with production.", self.parent_number, @@ -520,25 +548,87 @@ where self.transaction_pool.remove_invalid(&unqueue_invalid); - // Pushing a custom extrinsic that must run at the end of a block - let custom_extrinsic = block_builder.create_terminal_extrinsic(self.max_gas)?; + // Attempt to apply pseudo-inherent on top of the current overlay in a separate thread. + // In case the timeout is hit, we will proceed without it. + let client = self.client.clone(); + let backend = self.backend.clone(); + let pseudo_inherent = block_builder.create_terminal_extrinsic(self.max_gas)?; + let (extrinsics, api, version, _, _, estimated_header_size) = + block_builder.clone().deconstruct(); + // We need the overlay changes and transaction storage cache to send to a new thread. + // The cloned `RuntimaApi` object can't be sent to a new thread directly so we have to + // break it down into parts (that are `Send`) and then reconstruct it in the new thread. + // If changes applied successfully, the updated extrinsics and api parts will be sent back + // to update the original block builder and finalize the block. + let (_, api_params) = api.deref().clone().deconstruct(); + + let update_block = async move { + let (tx, rx) = oneshot::channel(); + let spawn_handle = self.spawn_handle.clone(); + + spawn_handle.spawn_blocking( + "block-builder-push", + None, + Box::pin(async move { + debug!(target: "gear::authorship", "⚙️ Pushing Gear::run extrinsic into the block..."); + let mut block_builder = BlockBuilder::<'_, Block, C, B>::from_parts( + extrinsics, + ApiRef::from(C::Api::restore(client.as_ref(), api_params)), + version, + parent_hash, + backend.as_ref(), + estimated_header_size); + let outcome = block_builder.push(pseudo_inherent).map(|_| { + let (extrinsics, api, _, _, _, _) = + block_builder.deconstruct(); + let (_, api_params) = api.deref().clone().deconstruct(); + (extrinsics, api_params) + }); + if tx.send(outcome).is_err() { + debug!( + target: "gear::authorship", + "🔒 Send failure: the receiver must have already closed the channel."); + }; + }), + ); - debug!(target: "gear::authorship", "⚙️ Pushing Gear::run extrinsic into the block..."); - match block_builder.push(custom_extrinsic) { - Ok(()) => { - debug!(target: "gear::authorship", "⚙️ ... pushed to the block"); - } - Err(ApplyExtrinsicFailed(Validity(e))) if e.exhausted_resources() => { - warn!(target: "gear::authorship", "⚠️ Dropping terminal extrinsic from an overweight block.") + rx.await? + }.boxed(); + match futures::future::select( + update_block, + // TODO: consider adding some tolerance here like `deadline` + 20% or something. + // We know we have almost 0.5s for block finalization while `on_finalize` hooks + // for the pallets in our Runtime take almost no weight. + Delay::new(deadline.saturating_duration_since((self.now)())), + ) + .await + { + Either::Left((res, _)) => { + match res { + Ok((extrinsics, api_params)) => { + debug!(target: "gear::authorship", "⚙️ ... pushed to the block"); + let mut api = C::Api::restore(self.client.as_ref(), api_params); + block_builder.set_api(&mut api); + block_builder.set_extrinsics(extrinsics); + } + Err(ApplyExtrinsicFailed(Validity(e))) if e.exhausted_resources() => { + warn!(target: "gear::authorship", "⚠️ Dropping terminal extrinsic from an overweight block."); + } + Err(e) => { + error!(target: "gear::authorship", + "❗️ Terminal extrinsic returned an error: {}. Dropping.", + e + ); + } + }; } - Err(e) => { - error!(target: "gear::authorship", - "❗️ Terminal extrinsic returned an error: {}. Dropping.", - e + Either::Right(_) => { + error!( + target: "gear::authorship", + "⌛️ Pseudo-inherent is taking too long and will not be included in the block." ); } - } - + }; let (block, storage_changes, proof) = block_builder.build()?.into_inner(); self.metrics.report(|metrics| { @@ -553,18 +643,19 @@ where }); info!( - "🎁 Prepared block for proposing at {} ({} ms) [hash: {:?}; parent_hash: {}; extrinsics ({}): [{}]]", - block.header().number(), - block_timer.elapsed().as_millis(), - block.header().hash(), - block.header().parent_hash(), - block.extrinsics().len(), - block.extrinsics() - .iter() - .map(|xt| BlakeTwo256::hash_of(xt).to_string()) - .collect::>() - .join(", ") - ); + target: "gear::authorship", + "🎁 Prepared block for proposing at {} ({} ms) [hash: {:?}; parent_hash: {}; extrinsics ({}): [{}]]", + block.header().number(), + block_timer.elapsed().as_millis(), + block.header().hash(), + block.header().parent_hash(), + block.extrinsics().len(), + block.extrinsics() + .iter() + .map(|xt| BlakeTwo256::hash_of(xt).to_string()) + .collect::>() + .join(", ") + ); telemetry!( self.telemetry; CONSENSUS_INFO; @@ -576,7 +667,7 @@ where let proof = PR::into_proof(proof).map_err(|e| sp_blockchain::Error::Application(Box::new(e)))?; - let propose_with_end = time::Instant::now(); + let propose_with_end = Instant::now(); self.metrics.report(|metrics| { metrics.create_block_proposal_time.observe( propose_with_end diff --git a/node/authorship/src/block_builder.rs b/node/authorship/src/block_builder.rs index 2ef70e5cb9f..3f514e4f544 100644 --- a/node/authorship/src/block_builder.rs +++ b/node/authorship/src/block_builder.rs @@ -16,21 +16,32 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . +use codec::Encode; use pallet_gear_rpc_runtime_api::GearApi as GearRuntimeApi; -use sc_block_builder::{BlockBuilder, BlockBuilderApi, BuiltBlock}; +use sc_block_builder::{BlockBuilderApi, BuiltBlock, RecordProof}; use sc_client_api::backend; -use sp_api::{ApiExt, ApiRef, ProvideRuntimeApi, TransactionOutcome}; -use sp_blockchain::Error; +use sp_api::{ApiExt, ApiRef, Core, ProvideRuntimeApi, TransactionOutcome}; +use sp_blockchain::{ApplyExtrinsicFailed, Error}; use sp_core::ExecutionContext; -use sp_runtime::traits::Block as BlockT; +use sp_runtime::{ + legacy, + traits::{Block as BlockT, Hash, HashFor, Header as HeaderT, NumberFor, One}, + Digest, +}; +use std::ops::DerefMut; -pub struct BlockBuilderExt<'a, Block: BlockT, A: ProvideRuntimeApi, B> { - block_builder: BlockBuilder<'a, Block, A, B>, +/// Utility for building new (valid) blocks from a stream of extrinsics. +pub struct BlockBuilder<'a, Block: BlockT, A: ProvideRuntimeApi, B> { + extrinsics: Vec, api: ApiRef<'a, A::Api>, + version: u32, parent_hash: Block::Hash, + backend: &'a B, + /// The estimated size of the block header. + estimated_header_size: usize, } -impl<'a, Block, A, B> BlockBuilderExt<'a, Block, A, B> +impl<'a, Block, A, B> BlockBuilder<'a, Block, A, B> where Block: BlockT, A: ProvideRuntimeApi + 'a, @@ -39,42 +50,167 @@ where + GearRuntimeApi, B: backend::Backend, { - /// Creating a block builder by wrapping an sc_block_builder::BlockBuilder object + /// Create a new instance of builder based on the given `parent_hash` and `parent_number`. + /// + /// While proof recording is enabled, all accessed trie nodes are saved. + /// These recorded trie nodes can be used by a third party to prove the + /// output of this block builder without having access to the full storage. pub fn new( - block_builder: BlockBuilder<'a, Block, A, B>, - api: ApiRef<'a, A::Api>, + api: &'a A, parent_hash: Block::Hash, - ) -> Self { - Self { - block_builder, - api, + parent_number: NumberFor, + record_proof: RecordProof, + inherent_digests: Digest, + backend: &'a B, + ) -> Result { + let header = <::Header as HeaderT>::new( + parent_number + One::one(), + Default::default(), + Default::default(), parent_hash, + inherent_digests, + ); + + let estimated_header_size = header.encoded_size(); + + let mut api = api.runtime_api(); + + if record_proof.yes() { + api.record_proof(); } + + api.initialize_block_with_context( + parent_hash, + ExecutionContext::BlockConstruction, + &header, + )?; + + let version = api + .api_version::>(parent_hash)? + .ok_or_else(|| Error::VersionInvalid("BlockBuilderApi".to_string()))?; + + Ok(Self { + parent_hash, + extrinsics: Vec::new(), + api, + version, + backend, + estimated_header_size, + }) } /// Push onto the block's list of extrinsics. + /// + /// This will ensure the extrinsic can be validly executed (by executing it). pub fn push(&mut self, xt: ::Extrinsic) -> Result<(), Error> { - self.block_builder.push(xt) + let parent_hash = self.parent_hash; + let extrinsics = &mut self.extrinsics; + let version = self.version; + + self.api.execute_in_transaction(|api| { + let res = if version < 6 { + #[allow(deprecated)] + api.apply_extrinsic_before_version_6_with_context( + parent_hash, + ExecutionContext::BlockConstruction, + xt.clone(), + ) + .map(legacy::byte_sized_error::convert_to_latest) + } else { + api.apply_extrinsic_with_context( + parent_hash, + ExecutionContext::BlockConstruction, + xt.clone(), + ) + }; + + match res { + Ok(Ok(_)) => { + extrinsics.push(xt); + TransactionOutcome::Commit(Ok(())) + } + Ok(Err(tx_validity)) => TransactionOutcome::Rollback(Err( + ApplyExtrinsicFailed::Validity(tx_validity).into(), + )), + Err(e) => TransactionOutcome::Rollback(Err(Error::from(e))), + } + }) } /// Consume the builder to build a valid `Block` containing all pushed extrinsics. - pub fn build(self) -> Result>, Error> { - self.block_builder.build() + /// + /// Returns the build `Block`, the changes to the storage and an optional `StorageProof` + /// supplied by `self.api`, combined as [`BuiltBlock`]. + /// The storage proof will be `Some(_)` when proof recording was enabled. + pub fn build(mut self) -> Result>, Error> { + let header = self + .api + .finalize_block_with_context(self.parent_hash, ExecutionContext::BlockConstruction)?; + + debug_assert_eq!( + header.extrinsics_root().clone(), + HashFor::::ordered_trie_root( + self.extrinsics.iter().map(Encode::encode).collect(), + sp_runtime::StateVersion::V0, + ), + ); + + let proof = self.api.extract_proof(); + + let state = self.backend.state_at(self.parent_hash)?; + + let storage_changes = self + .api + .into_storage_changes(&state, self.parent_hash) + .map_err(sp_blockchain::Error::StorageChanges)?; + + Ok(BuiltBlock { + block: ::new(header, self.extrinsics), + storage_changes, + proof, + }) } /// Create the inherents for the block. + /// + /// Returns the inherents created by the runtime or an error if something failed. pub fn create_inherents( &mut self, inherent_data: sp_inherents::InherentData, ) -> Result, Error> { - self.block_builder.create_inherents(inherent_data) + let parent_hash = self.parent_hash; + self.api + .execute_in_transaction(move |api| { + // `create_inherents` should not change any state, to ensure this we always rollback + // the transaction. + TransactionOutcome::Rollback(api.inherent_extrinsics_with_context( + parent_hash, + ExecutionContext::BlockConstruction, + inherent_data, + )) + }) + .map_err(|e| Error::Application(Box::new(e))) } /// Estimate the size of the block in the current state. + /// + /// If `include_proof` is `true`, the estimated size of the storage proof will be added + /// to the estimation. pub fn estimate_block_size(&self, include_proof: bool) -> usize { - self.block_builder.estimate_block_size(include_proof) + let size = self.estimated_header_size + self.extrinsics.encoded_size(); + + if include_proof { + size + self + .api + .proof_recorder() + .map(|pr| pr.estimate_encoded_size()) + .unwrap_or(0) + } else { + size + } } + /// Call runtime-api to get the correct extrinsic that should conclude the block. pub fn create_terminal_extrinsic( &mut self, max_gas: Option, @@ -90,4 +226,96 @@ where }) .map_err(|e| Error::Application(Box::new(e))) } + + #[cfg(test)] + pub fn extrinsics(&self) -> &[Block::Extrinsic] { + &self.extrinsics[..] + } + + #[cfg(test)] + pub fn into_storage_changes( + self, + ) -> Result, Block>, Error> { + let state = self.backend.state_at(self.parent_hash)?; + + let storage_changes = self + .api + .into_storage_changes(&state, self.parent_hash) + .map_err(sp_blockchain::Error::StorageChanges)?; + + Ok(storage_changes) + } + + /// Break a builder instance into its parts. + #[allow(clippy::type_complexity)] + pub fn deconstruct( + self, + ) -> ( + Vec, + ApiRef<'a, A::Api>, + u32, + Block::Hash, + &'a B, + usize, + ) { + ( + self.extrinsics, + self.api, + self.version, + self.parent_hash, + self.backend, + self.estimated_header_size, + ) + } + + /// Restore a builder instance from its parts. + pub fn from_parts( + extrinsics: Vec, + api: ApiRef<'a, A::Api>, + version: u32, + parent_hash: Block::Hash, + backend: &'a B, + estimated_header_size: usize, + ) -> Self { + Self { + extrinsics, + api, + version, + parent_hash, + backend, + estimated_header_size, + } + } + + /// Replace the runtime api with the given one. + pub fn set_api(&mut self, api: &mut A::Api) { + std::mem::swap(self.api.deref_mut(), api); + } + + /// Replace the extrinsics with the given ones. + pub fn set_extrinsics(&mut self, extrinsics: Vec) { + self.extrinsics = extrinsics; + } +} + +impl<'a, Block, A, B> Clone for BlockBuilder<'a, Block, A, B> +where + Block: BlockT, + A: ProvideRuntimeApi + 'a, + A::Api: ApiExt> + + BlockBuilderApi + + GearRuntimeApi + + Clone, + B: backend::Backend, +{ + fn clone(&self) -> Self { + Self { + extrinsics: self.extrinsics.clone(), + api: self.api.clone().into(), + version: self.version, + parent_hash: self.parent_hash, + backend: <&B>::clone(&self.backend), + estimated_header_size: self.estimated_header_size, + } + } } diff --git a/node/authorship/src/tests.rs b/node/authorship/src/tests.rs index c845fbbf692..1773a721ded 100644 --- a/node/authorship/src/tests.rs +++ b/node/authorship/src/tests.rs @@ -21,15 +21,21 @@ // The block proposer explicitly pushes the `pallet_gear::run` // extrinsic at the end of each block. -use crate::authorship::*; +#![allow(clippy::redundant_clone)] + +use crate::{block_builder::BlockBuilder, ProposerFactory}; use codec::{Decode, Encode}; use common::Program; use core::convert::TryFrom; -use frame_support::{storage::storage_prefix, traits::PalletInfoAccess}; +use demo_constructor::{Calls, Scheme, WASM_BINARY}; +use frame_support::{assert_ok, storage::storage_prefix, traits::PalletInfoAccess}; use futures::executor::block_on; +use gear_runtime_common::constants::BANK_ADDRESS; +use pallet_gear_rpc_runtime_api::GearApi; use runtime_primitives::BlockNumber; -use sc_client_api::Backend; +use sc_client_api::{Backend as _, ExecutionStrategy}; +use sc_service::client::Client; use sc_transaction_pool::BasicPool; use sc_transaction_pool_api::{ ChainEvent, MaintainedTransactionPool, TransactionPool, TransactionSource, @@ -45,17 +51,24 @@ use sp_inherents::InherentDataProvider; use sp_runtime::{ generic::BlockId, traits::{Block as BlockT, Header as HeaderT, NumberFor}, - Digest, DigestItem, + Digest, DigestItem, OpaqueExtrinsic, +}; +use sp_timestamp::Timestamp; +use std::{ + ops::Deref, + sync::Arc, + time::{self, SystemTime, UNIX_EPOCH}, }; -use std::{sync::Arc, thread::sleep, time}; use testing::{ client::{ClientBlockImportExt, TestClientBuilder, TestClientBuilderExt}, keyring::{alice, bob, sign, signed_extra, CheckedExtrinsic}, }; -use vara_runtime::{AccountId, Runtime, RuntimeCall, UncheckedExtrinsic, SLOT_DURATION, VERSION}; +use vara_runtime::{ + AccountId, Runtime, RuntimeApi as RA, RuntimeCall, UncheckedExtrinsic, SLOT_DURATION, VERSION, +}; const SOURCE: TransactionSource = TransactionSource::External; -const DEFAULT_GAS_LIMIT: u64 = 865_000_000; +const DEFAULT_GAS_LIMIT: u64 = 10_000_000_000; fn chain_event(header: B::Header) -> ChainEvent where @@ -80,41 +93,108 @@ fn pre_digest(slot: u64, authority_index: u32) -> Digest { } } -fn checked_extrinsics(n: u32, signer: AccountId, nonce: &mut u32) -> Vec { - use demo_mul_by_const::WASM_BINARY; - use std::fmt::Write; - - (0..n) - .map(|i| { - let mut salt = String::new(); - write!(salt, "salt_{}", *nonce).expect("Failure writing to String"); - let tx = CheckedExtrinsic { - signed: Some((signer.clone(), signed_extra(*nonce))), - function: RuntimeCall::Gear(pallet_gear::Call::upload_program { - code: WASM_BINARY.to_vec(), - salt: salt.as_bytes().to_vec(), - init_payload: (i as u64).encode(), - gas_limit: DEFAULT_GAS_LIMIT, - value: 0, - }), - }; - *nonce += 1; - tx +fn checked_extrinsics( + n: u32, + signer: AccountId, + starting_nonce: u32, + f: F, +) -> Vec +where + F: Fn() -> RuntimeCall, +{ + let last_nonce = starting_nonce + n; + (starting_nonce..last_nonce) + .map(|nonce| CheckedExtrinsic { + signed: Some((signer.clone(), signed_extra(nonce))), + function: f(), }) .collect() } -// TODO: replace with an import from runtime constants once available. -// Address of bank account represented as 32 bytes. -pub const BANK_ADDRESS: [u8; 32] = *b"gearbankgearbankgearbankgearbank"; -fn pre_fund_bank_account_call() -> RuntimeCall { - RuntimeCall::Sudo(pallet_sudo::Call::sudo { - call: Box::new(RuntimeCall::Balances(pallet_balances::Call::set_balance { - who: sp_runtime::MultiAddress::Id(AccountId::from(BANK_ADDRESS)), - new_free: 1_000_000_000_000_000, - new_reserved: 0, - })), - }) +fn sign_extrinsics( + extrinsics: Vec, + spec_version: u32, + tx_version: u32, + genesis_hash: [u8; 32], +) -> Vec +where + E: From, +{ + extrinsics + .into_iter() + .map(|x| sign(x, spec_version, tx_version, genesis_hash).into()) + .collect() +} + +fn salt() -> [u8; 16] { + SystemTime::now() + .duration_since(UNIX_EPOCH) + .unwrap() + .as_nanos() + .to_le_bytes() +} + +enum TestCall { + DepositToBank, + Noop, + InitLoop(u64), + ToggleRunQueue(bool), +} + +struct CallBuilder { + call: TestCall, +} +impl CallBuilder { + pub fn deposit_to_bank() -> Self { + Self { + call: TestCall::DepositToBank, + } + } + pub fn noop() -> Self { + Self { + call: TestCall::Noop, + } + } + pub fn long_init(count: u64) -> Self { + Self { + call: TestCall::InitLoop(count), + } + } + pub fn toggle_run_queue(value: bool) -> Self { + Self { + call: TestCall::ToggleRunQueue(value), + } + } + fn build(self) -> RuntimeCall { + match self.call { + TestCall::DepositToBank => RuntimeCall::Sudo(pallet_sudo::Call::sudo { + call: Box::new(RuntimeCall::Balances(pallet_balances::Call::set_balance { + who: sp_runtime::MultiAddress::Id(AccountId::from(BANK_ADDRESS)), + new_free: 1_000_000_000_000_000, + new_reserved: 0, + })), + }), + TestCall::Noop => RuntimeCall::Gear(pallet_gear::Call::upload_program { + code: WASM_BINARY.to_vec(), + salt: salt().to_vec(), + init_payload: Scheme::direct(Calls::builder().noop()).encode(), + gas_limit: DEFAULT_GAS_LIMIT, + value: 0, + }), + TestCall::InitLoop(count) => RuntimeCall::Gear(pallet_gear::Call::upload_program { + code: WASM_BINARY.to_vec(), + salt: salt().to_vec(), + init_payload: Scheme::direct(Calls::builder().write_in_loop(count)).encode(), + gas_limit: DEFAULT_GAS_LIMIT, + value: 0, + }), + TestCall::ToggleRunQueue(value) => RuntimeCall::Sudo(pallet_sudo::Call::sudo { + call: Box::new(RuntimeCall::Gear(pallet_gear::Call::set_execute_inherent { + value, + })), + }), + } + } } pub(crate) fn init_logger() { @@ -124,552 +204,480 @@ pub(crate) fn init_logger() { .try_init(); } -#[test] -fn custom_extrinsic_is_placed_in_each_block() { - init_logger(); - - let client = Arc::new( - TestClientBuilder::new() - .set_execution_strategy(sc_client_api::ExecutionStrategy::NativeWhenPossible) - .build(), - ); - let spawner = sp_core::testing::TaskExecutor::new(); - let txpool = BasicPool::new_full( - Default::default(), - true.into(), - None, - spawner.clone(), - client.clone(), - ); - - let genesis_hash = - <[u8; 32]>::try_from(&client.info().best_hash[..]).expect("H256 is a 32 byte type"); - let mut nonce = 0_u32; - let extrinsics = checked_extrinsics(1, bob(), &mut nonce) - .iter() - .map(|x| { - sign( - x.clone(), - VERSION.spec_version, - VERSION.transaction_version, - genesis_hash, - ) - .into() - }) - .collect::>(); +macro_rules! init { + { + $client:ident, + $backend:ident, + $txpool:ident, + $spawner:ident, + $genesis_hash:ident + } => { + let client_builder = + TestClientBuilder::new().set_execution_strategy(ExecutionStrategy::NativeWhenPossible); + let $backend = client_builder.backend(); + let mut $client = Arc::new(client_builder.build()); + let $spawner = sp_core::testing::TaskExecutor::new(); + let $txpool = BasicPool::new_full( + Default::default(), + true.into(), + None, + $spawner.clone(), + $client.clone(), + ); + + let $genesis_hash = + <[u8; 32]>::try_from(&$client.info().best_hash[..]).expect("H256 is a 32 byte type"); + } +} - block_on(txpool.submit_at(&BlockId::number(0), SOURCE, extrinsics)).unwrap(); - block_on( - txpool.maintain(chain_event( - client - .header( - client - .block_hash_from_id(&BlockId::Number(0_u32)) - .unwrap() - .unwrap(), - ) - .expect("get header error") - .expect("there should be a header"), - )), - ); - assert_eq!(txpool.ready().count(), 1); +macro_rules! propose_block { + { + $client:ident, + $backend:ident, + $txpool:ident, + $spawner:ident, + $best_hash:ident, + $block_id:ident, + $extrinsics:ident, + $timestamp:ident, + $max_duration:ident, + $max_gas:ident, + $proposal:ident, + { + $( $txpool_ready:tt )* + }, + { + $( $final_checks:tt )* + } + } => { + block_on($txpool.submit_at(&BlockId::number(0), SOURCE, $extrinsics)).unwrap(); + + block_on( + $txpool.maintain(chain_event( + $client + .header( + $client + .block_hash_from_id(&$block_id) + .unwrap() + .unwrap(), + ) + .expect("header get error") + .expect("there should be header"), + )), + ); + + $( $txpool_ready )* + + let mut proposer_factory = ProposerFactory::new( + $spawner.clone(), + $client.clone(), + $backend.clone(), + $txpool.clone(), + None, + None, + $max_gas, + ); + + let timestamp_provider = sp_timestamp::InherentDataProvider::new($timestamp); + let time_slot = $timestamp.as_millis() / SLOT_DURATION; + let inherent_data = + block_on(timestamp_provider.create_inherent_data()).expect("Create inherent data failed"); + + let proposer = block_on( + proposer_factory.init( + &$client + .header( + $client + .block_hash_from_id(&$block_id) + .unwrap() + .unwrap(), + ) + .expect("Database error querying block #0") + .expect("Block #0 should exist"), + ), + ) + .expect("Proposer initialization failed"); + + let $proposal = block_on(proposer.propose( + inherent_data, + pre_digest(time_slot, 0), + time::Duration::from_millis($max_duration), + None, + )) + .unwrap(); - let mut proposer_factory = - ProposerFactory::new(spawner, client.clone(), txpool, None, None, None); - let timestamp_provider = sp_timestamp::InherentDataProvider::from_system_time(); - let time_slot = sp_timestamp::Timestamp::current().as_millis() / SLOT_DURATION; + // Importing last block + block_on($client.import(BlockOrigin::Own, $proposal.block.clone())).unwrap(); - let proposer = block_on( - proposer_factory.init( - &client - .header( - client - .block_hash_from_id(&BlockId::number(0)) - .unwrap() - .unwrap(), - ) - .expect("Database error querying block #0") - .expect("Block #0 should exist"), - ), - ) - .expect("Proposer initialization failed"); - - let inherent_data = - block_on(timestamp_provider.create_inherent_data()).expect("Create inherent data failed"); - - let block = block_on(proposer.propose( - inherent_data, - pre_digest(time_slot, 0), - time::Duration::from_secs(20), - None, - )) - .map(|r| r.block) - .unwrap(); + let $best_hash = $client.info().best_hash; + assert_eq!($best_hash, $proposal.block.hash()); - // then - // block should have exactly 3 txs: an inherent (timestamp), a normal and a mandatory one - assert_eq!(block.extrinsics().len(), 3); + $( $final_checks )* + } } #[test] -fn proposed_storage_changes_match_execute_block_storage_changes() { +fn custom_extrinsic_is_placed_in_each_block() { init_logger(); - let client_builder = TestClientBuilder::new() - .set_execution_strategy(sc_client_api::ExecutionStrategy::NativeWhenPossible); - let backend = client_builder.backend(); - let client = Arc::new(client_builder.build()); - let spawner = sp_core::testing::TaskExecutor::new(); - let txpool = BasicPool::new_full( - Default::default(), - true.into(), - None, - spawner.clone(), - client.clone(), - ); - - let genesis_hash = - <[u8; 32]>::try_from(&client.info().best_hash[..]).expect("H256 is a 32 byte type"); - let mut nonce = 0_u32; - let extrinsics = checked_extrinsics(1, bob(), &mut nonce) - .iter() - .map(|x| { - sign( - x.clone(), - VERSION.spec_version, - VERSION.transaction_version, - genesis_hash, - ) - .into() - }) - .collect::>(); - - block_on(txpool.submit_at(&BlockId::number(0), SOURCE, extrinsics)).unwrap(); + init!(client, backend, txpool, spawner, genesis_hash); - block_on( - txpool.maintain(chain_event( - client - .header( - client - .block_hash_from_id(&BlockId::Number(0_u32)) - .unwrap() - .unwrap(), - ) - .expect("header get error") - .expect("there should be header"), - )), + // Test prelude: extrinsics, timeouts etc. + let extrinsics = sign_extrinsics( + checked_extrinsics(1, bob(), 0_u32, || CallBuilder::noop().build()), + VERSION.spec_version, + VERSION.transaction_version, + genesis_hash, ); + let num_extrinsics = extrinsics.len(); + + let block_id = BlockId::number(0); + let timestamp = Timestamp::current(); + let max_gas = None; + let max_duration = 1500_u64; + + propose_block!( + client, + backend, + txpool, + spawner, + best_hash, + block_id, + extrinsics, + timestamp, + max_duration, + max_gas, + proposal, + { + let num_ready = txpool.ready().count(); + assert_eq!(num_ready, num_extrinsics); + }, + { + // then + // block should have exactly 3 txs: an inherent (timestamp), a normal and a mandatory one + assert_eq!(proposal.block.extrinsics().len(), 3); + } + ); +} - let mut proposer_factory = - ProposerFactory::new(spawner, client.clone(), txpool, None, None, None); - let timestamp_provider = sp_timestamp::InherentDataProvider::from_system_time(); - let time_slot = sp_timestamp::Timestamp::current().as_millis() / SLOT_DURATION; - - let proposer = block_on( - proposer_factory.init( - &client - .header( - client - .block_hash_from_id(&BlockId::number(0)) - .unwrap() - .unwrap(), - ) - .expect("Database error querying block #0") - .expect("Block #0 should exist"), - ), - ) - .expect("Proposer initialization failed"); - - let inherent_data = - block_on(timestamp_provider.create_inherent_data()).expect("Create inherent data failed"); - - let proposal = block_on(proposer.propose( - inherent_data, - pre_digest(time_slot, 0), - time::Duration::from_secs(300), - None, - )) - .unwrap(); - - // 1 inherent + 1 signed extrinsic + 1 terminal unsigned one - assert_eq!(proposal.block.extrinsics().len(), 3); - - let api = client.runtime_api(); - api.execute_block(genesis_hash.into(), proposal.block) - .unwrap(); - - let state = backend.state_at(genesis_hash.into()).unwrap(); +#[test] +fn proposed_storage_changes_match_execute_block_storage_changes() { + init_logger(); - let storage_changes = api - .into_storage_changes(&state, genesis_hash.into()) - .unwrap(); + init!(client, backend, txpool, spawner, genesis_hash); - assert_eq!( - proposal.storage_changes.transaction_storage_root, - storage_changes.transaction_storage_root, + let extrinsics = sign_extrinsics( + checked_extrinsics(1, bob(), 0_u32, || CallBuilder::noop().build()), + VERSION.spec_version, + VERSION.transaction_version, + genesis_hash, ); - let queue_head_key = storage_prefix( - pallet_gear_messenger::Pallet::::name().as_bytes(), - "Head".as_bytes(), + let block_id = BlockId::number(0); + let timestamp = Timestamp::current(); + let max_gas = None; + let max_duration = 1500_u64; + + propose_block!( + client, + backend, + txpool, + spawner, + best_hash, + block_id, + extrinsics, + timestamp, + max_duration, + max_gas, + proposal, + {}, + { + // then + // 1 inherent + 1 signed extrinsic + 1 terminal unsigned one + assert_eq!(proposal.block.extrinsics().len(), 3); + + let api = client.runtime_api(); + api.execute_block(genesis_hash.into(), proposal.block) + .unwrap(); + let state = backend.state_at(best_hash).unwrap(); + + let storage_changes = api.into_storage_changes(&state, best_hash).unwrap(); + + assert_eq!( + proposal.storage_changes.transaction_storage_root, + storage_changes.transaction_storage_root, + ); + + let queue_head_key = storage_prefix( + pallet_gear_messenger::Pallet::::name().as_bytes(), + "Head".as_bytes(), + ); + // Ensure message queue is empty given the terminal extrinsic completed successfully + assert!(state.storage(&queue_head_key[..]).unwrap().is_none()); + } ); - // Ensure message queue is empty given the terminal extrinsic completed successfully - assert!(state.storage(&queue_head_key[..]).unwrap().is_none()); } #[test] -#[ignore = "Unstable due time timestamp inconsistency"] fn queue_remains_intact_if_processing_fails() { use sp_state_machine::IterArgs; init_logger(); - let client_builder = TestClientBuilder::new() - .set_execution_strategy(sc_client_api::ExecutionStrategy::NativeWhenPossible); - let backend = client_builder.backend(); - let mut client = Arc::new(client_builder.build()); - let spawner = sp_core::testing::TaskExecutor::new(); - let txpool = BasicPool::new_full( - Default::default(), - true.into(), - None, - spawner.clone(), - client.clone(), - ); + init!(client, backend, txpool, spawner, genesis_hash); - let genesis_hash = - <[u8; 32]>::try_from(&client.info().best_hash[..]).expect("H256 is a 32 byte type"); - let mut nonce = 0_u32; - let mut checked = checked_extrinsics(5, bob(), &mut nonce); - // Disable queue processing in Gear pallet as the root - checked.push(CheckedExtrinsic { + // Create an extrinsic that prefunds the bank account + let pre_fund_bank_xt = CheckedExtrinsic { signed: Some((alice(), signed_extra(0))), - function: RuntimeCall::Sudo(pallet_sudo::Call::sudo { - call: Box::new(RuntimeCall::Gear(pallet_gear::Call::set_execute_inherent { - value: false, - })), - }), - }); - let extrinsics = checked - .iter() - .map(|x| { - sign( - x.clone(), - VERSION.spec_version, - VERSION.transaction_version, - genesis_hash, - ) - .into() - }) - .collect::>(); + function: CallBuilder::deposit_to_bank().build(), + }; - block_on(txpool.submit_at(&BlockId::number(0), SOURCE, extrinsics)).unwrap(); + let mut checked = vec![pre_fund_bank_xt]; + checked.extend(checked_extrinsics(5, bob(), 0_u32, || CallBuilder::noop().build()).into_iter()); + let nonce = 5_u32; // Bob's nonce for the future - block_on( - txpool.maintain(chain_event( - client - .header( - client - .block_hash_from_id(&BlockId::Number(0_u32)) - .unwrap() - .unwrap(), - ) - .expect("header get error") - .expect("there should be header"), - )), + // Disable queue processing in Gear pallet as the root + checked.push(CheckedExtrinsic { + signed: Some((alice(), signed_extra(1))), + function: CallBuilder::toggle_run_queue(false).build(), + }); + let extrinsics = sign_extrinsics( + checked, + VERSION.spec_version, + VERSION.transaction_version, + genesis_hash, ); - let mut proposer_factory = - ProposerFactory::new(spawner, client.clone(), txpool.clone(), None, None, None); - let timestamp_provider = sp_timestamp::InherentDataProvider::from_system_time(); - - let proposer = block_on( - proposer_factory.init( - &client - .header( - client - .block_hash_from_id(&BlockId::number(0)) - .unwrap() - .unwrap(), - ) - .expect("Database error querying block #0") - .expect("Block #0 should exist"), - ), - ) - .expect("Proposer initialization failed"); - - let inherent_data = - block_on(timestamp_provider.create_inherent_data()).expect("Create inherent data failed"); - let time_slot = sp_timestamp::Timestamp::current().as_millis() / SLOT_DURATION; - - let proposal = block_on(proposer.propose( - inherent_data, - pre_digest(time_slot, 0), - time::Duration::from_secs(20), - None, - )) - .unwrap(); - - // Terminal extrinsic rolled back, therefore only have 1 inherent + 6 normal - assert_eq!(proposal.block.extrinsics().len(), 7); - - // Importing block #1 - block_on(client.import(BlockOrigin::Own, proposal.block.clone())).unwrap(); - - let best_hash = client.info().best_hash; - assert_eq!(best_hash, proposal.block.hash()); - - let state = backend.state_at(best_hash).unwrap(); - // Ensure message queue still has 5 messages - let queue_entry_prefix = storage_prefix( - pallet_gear_messenger::Pallet::::name().as_bytes(), - "Dispatches".as_bytes(), + let block_id = BlockId::number(0); + let timestamp = Timestamp::current(); + let max_gas = None; + let max_duration = 1500_u64; + + propose_block!( + client, + backend, + txpool, + spawner, + best_hash, + block_id, + extrinsics, + timestamp, + max_duration, + max_gas, + proposal, + {}, + { + // Terminal extrinsic rolled back, therefore only have 1 inherent + 6 normal + assert_eq!(proposal.block.extrinsics().len(), 8); + + // Importing block #1 + block_on(client.import(BlockOrigin::Own, proposal.block.clone())).unwrap(); + + let best_hash = client.info().best_hash; + assert_eq!(best_hash, proposal.block.hash()); + + let state = backend.state_at(best_hash).unwrap(); + // Ensure message queue still has 5 messages + let queue_entry_prefix = storage_prefix( + pallet_gear_messenger::Pallet::::name().as_bytes(), + "Dispatches".as_bytes(), + ); + let mut queue_entry_args = IterArgs::default(); + queue_entry_args.prefix = Some(&queue_entry_prefix); + + let mut queue_len = 0_u32; + + state + .keys(queue_entry_args) + .unwrap() + .for_each(|_k| queue_len += 1); + assert_eq!(queue_len, 5); + } ); - let mut queue_entry_args = IterArgs::default(); - queue_entry_args.prefix = Some(&queue_entry_prefix); - - let mut queue_len = 0_u32; - - state - .keys(queue_entry_args) - .unwrap() - .for_each(|_k| queue_len += 1); - assert_eq!(queue_len, 5); - - let best_block_id = BlockId::Hash(best_hash); // Preparing block #2 - let extrinsics = checked_extrinsics(3, bob(), &mut nonce) - .iter() - .map(|x| { - sign( - x.clone(), - VERSION.spec_version, - VERSION.transaction_version, - genesis_hash, - ) - .into() - }) - .collect::>(); - - // Pushing 3 more signed extrinsics that add 3 more messages to the queue - block_on(txpool.submit_at(&BlockId::number(0), SOURCE, extrinsics)).unwrap(); - - block_on( - txpool.maintain(chain_event( - client - .header(client.block_hash_from_id(&best_block_id).unwrap().unwrap()) - .expect("header get error") - .expect("there should be header"), - )), + let block_id = BlockId::Hash(best_hash); + let extrinsics = sign_extrinsics( + checked_extrinsics(3, bob(), nonce, || CallBuilder::noop().build()), + VERSION.spec_version, + VERSION.transaction_version, + genesis_hash, + ); + let timestamp = Timestamp::new(timestamp.as_millis() + SLOT_DURATION); + + propose_block!( + client, + backend, + txpool, + spawner, + best_hash, + block_id, + extrinsics, + timestamp, + max_duration, + max_gas, + proposal, + {}, + { + // Terminal extrinsic rolled back, therefore only have 1 inherent + 3 normal + assert_eq!(proposal.block.extrinsics().len(), 4); + + // Importing block #2 + block_on(client.import(BlockOrigin::Own, proposal.block.clone())).unwrap(); + + let state = backend.state_at(best_hash).unwrap(); + // Ensure message queue has not been drained and has now 8 messages + let mut queue_len = 0_u32; + let mut queue_entry_args = IterArgs::default(); + queue_entry_args.prefix = Some(&queue_entry_prefix); + state + .keys(queue_entry_args) + .unwrap() + .for_each(|_k| queue_len += 1); + assert_eq!(queue_len, 8); + } ); - - // Wait for a while until the next produced time_slot likely has a higher number - sleep(time::Duration::from_millis(SLOT_DURATION / 2)); - - let proposer = block_on( - proposer_factory.init( - &client - .header(client.block_hash_from_id(&best_block_id).unwrap().unwrap()) - .expect("Database error querying block #1") - .expect("Block #1 should exist"), - ), - ) - .expect("Proposer initialization failed"); - - let inherent_data = - block_on(timestamp_provider.create_inherent_data()).expect("Create inherent data failed"); - let time_slot = sp_timestamp::Timestamp::current().as_millis() / SLOT_DURATION; - - let proposal = block_on(proposer.propose( - inherent_data, - pre_digest(time_slot, 0), - time::Duration::from_secs(20), - None, - )) - .unwrap(); - - // Terminal extrinsic rolled back, therefore only have 1 inherent + 3 normal - assert_eq!(proposal.block.extrinsics().len(), 4); - - // Importing block #2 - block_on(client.import(BlockOrigin::Own, proposal.block.clone())).unwrap(); - - let best_hash = client.info().best_hash; - assert_eq!(best_hash, proposal.block.hash()); - - let state = backend.state_at(best_hash).unwrap(); - // Ensure message queue has not been drained and has now 8 messages - let mut queue_len = 0_u32; - let mut queue_entry_args = IterArgs::default(); - queue_entry_args.prefix = Some(&queue_entry_prefix); - state - .keys(queue_entry_args) - .unwrap() - .for_each(|_k| queue_len += 1); - assert_eq!(queue_len, 8); } #[test] fn block_max_gas_works() { use sp_state_machine::IterArgs; - init_logger(); + // Amount of gas burned in each block (even empty) by default + const FIXED_BLOCK_GAS: u64 = 25_000_000; - // Enough to fit 2 messages - const MAX_GAS: u64 = 2 * DEFAULT_GAS_LIMIT + 25_000_100; + init_logger(); - let client_builder = TestClientBuilder::new() - .set_execution_strategy(sc_client_api::ExecutionStrategy::NativeWhenPossible); - let backend = client_builder.backend(); - let mut client = Arc::new(client_builder.build()); - let spawner = sp_core::testing::TaskExecutor::new(); - let txpool = BasicPool::new_full( - Default::default(), - true.into(), - None, - spawner.clone(), - client.clone(), - ); + init!(client, backend, txpool, spawner, genesis_hash); - let genesis_hash = - <[u8; 32]>::try_from(&client.info().best_hash[..]).expect("H256 is a 32 byte type"); - let mut nonce = 0_u32; + // Prepare block #1 + let block_id = BlockId::number(0); + let timestamp = Timestamp::current(); + let mut max_gas = None; + let max_duration = 1500_u64; // Create an extrinsic that prefunds the bank account - let pre_fund_bank_xt = sign( + let extrinsics = vec![sign( CheckedExtrinsic { signed: Some((alice(), signed_extra(0))), - function: pre_fund_bank_account_call(), + function: CallBuilder::deposit_to_bank().build(), }, VERSION.spec_version, VERSION.transaction_version, genesis_hash, - ); - - let mut extrinsics = vec![pre_fund_bank_xt.into()]; - // Creating 5 extrinsics - extrinsics.extend(checked_extrinsics(5, bob(), &mut nonce).iter().map(|x| { - sign( - x.clone(), - VERSION.spec_version, - VERSION.transaction_version, - genesis_hash, - ) - .into() - })); - - block_on(txpool.submit_at(&BlockId::number(0), SOURCE, extrinsics)).unwrap(); - - block_on( - txpool.maintain(chain_event( - client - .header( - client - .block_hash_from_id(&BlockId::Number(0_u32)) - .unwrap() - .unwrap(), + ) + .into()]; + + propose_block!( + client, + backend, + txpool, + spawner, + best_hash, + block_id, + extrinsics, + timestamp, + max_duration, + max_gas, + proposal, + {}, + { + let api = client.runtime_api(); + let gear_core::gas::GasInfo { min_limit, .. } = api + .calculate_gas_info( + best_hash, + sp_core::H256::from(alice().as_ref()), + pallet_gear::HandleKind::Init(WASM_BINARY.to_vec()), + Scheme::direct(Calls::builder().noop()).encode(), + 0, + true, + None, + None, ) - .expect("header get error") - .expect("there should be header"), - )), + .unwrap() + .unwrap(); + // Just enough to fit 2 messages + max_gas = Some(2 * min_limit + FIXED_BLOCK_GAS + 100); + } ); - let mut proposer_factory = - ProposerFactory::new(spawner, client.clone(), txpool, None, None, Some(MAX_GAS)); - - let timestamp_provider = sp_timestamp::InherentDataProvider::from_system_time(); - - let proposer = block_on( - proposer_factory.init( - &client - .header( - client - .block_hash_from_id(&BlockId::number(0)) - .unwrap() - .unwrap(), - ) - .expect("Database error querying block #0") - .expect("Block #0 should exist"), - ), - ) - .expect("Proposer initialization failed"); - - let inherent_data = - block_on(timestamp_provider.create_inherent_data()).expect("Create inherent data failed"); - let time_slot = sp_timestamp::Timestamp::current().as_millis() / SLOT_DURATION; - - let proposal = block_on(proposer.propose( - inherent_data, - pre_digest(time_slot, 0), - time::Duration::from_secs(20), - None, - )) - .unwrap(); - - // All extrinsics have been included in the block: 1 inherent + sudo + 5 normal + 1 terminal - assert_eq!(proposal.block.extrinsics().len(), 8); - - // Importing block #1 - block_on(client.import(BlockOrigin::Own, proposal.block.clone())).unwrap(); - - let best_hash = client.info().best_hash; - assert_eq!(best_hash, proposal.block.hash()); - - let state = backend.state_at(best_hash).unwrap(); - // Ensure message queue still has 5 messages as none of the messages fit into the gas allownce - let queue_entry_prefix = storage_prefix( - pallet_gear_messenger::Pallet::::name().as_bytes(), - "Dispatches".as_bytes(), + // Preparing block #2 + // Creating 5 extrinsics + // let checked = checked_extrinsics(5, bob(), 0, || CallBuilder::noop().build()); + let checked = checked_extrinsics(5, bob(), 0, || CallBuilder::noop().build()); + let extrinsics = sign_extrinsics( + checked, + VERSION.spec_version, + VERSION.transaction_version, + genesis_hash, ); - let mut queue_entry_args = IterArgs::default(); - queue_entry_args.prefix = Some(&queue_entry_prefix); - let queue_len = state.keys(queue_entry_args).unwrap().count(); - - // 2 out of 5 messages have been processed, 3 remain in the queue - assert_eq!(queue_len, 3); - - let programs_prefix = storage_prefix( - pallet_gear_program::Pallet::::name().as_bytes(), - "ProgramStorage".as_bytes(), - ); - let mut iter_args = IterArgs::default(); - iter_args.prefix = Some(&programs_prefix); - - // The fact that 2 init messages out of 5 have been processed means - // that there should be 2 inited programs. - let inited_count = state.pairs(iter_args).unwrap().fold(0u32, |count, pair| { - let value = match pair { - Ok((_key, value)) => value, - _ => return count, - }; - - match Program::::decode(&mut &value[..]) { - Ok(p) if p.is_initialized() => count + 1, - _ => count, + let block_id = BlockId::Hash(best_hash); + let timestamp = Timestamp::new(timestamp.as_millis() + SLOT_DURATION); + + propose_block!( + client, + backend, + txpool, + spawner, + best_hash, + block_id, + extrinsics, + timestamp, + max_duration, + max_gas, + proposal, + {}, + { + // All extrinsics have been included in the block: 1 inherent + 5 normal + 1 terminal + assert_eq!(proposal.block.extrinsics().len(), 7); + + // Importing block #2 + block_on(client.import(BlockOrigin::Own, proposal.block.clone())).unwrap(); + + let state = backend.state_at(best_hash).unwrap(); + // Ensure message queue still has 5 messages as none of the messages fit into the gas allownce + let queue_entry_prefix = storage_prefix( + pallet_gear_messenger::Pallet::::name().as_bytes(), + "Dispatches".as_bytes(), + ); + let mut queue_entry_args = IterArgs::default(); + queue_entry_args.prefix = Some(&queue_entry_prefix); + + let queue_len = state.keys(queue_entry_args).unwrap().count(); + + // 2 out of 5 messages have been processed, 3 remain in the queue + assert_eq!(queue_len, 3); + + let programs_prefix = storage_prefix( + pallet_gear_program::Pallet::::name().as_bytes(), + "ProgramStorage".as_bytes(), + ); + let mut iter_args = IterArgs::default(); + iter_args.prefix = Some(&programs_prefix); + + // The fact that 2 init messages out of 5 have been processed means + // that there should be 2 inited programs. + let inited_count = state.pairs(iter_args).unwrap().fold(0u32, |count, pair| { + let value = match pair { + Ok((_key, value)) => value, + _ => return count, + }; + + match Program::::decode(&mut &value[..]) { + Ok(p) if p.is_initialized() => count + 1, + _ => count, + } + }); + assert_eq!(inited_count, 2); } - }); - assert_eq!(inited_count, 2); + ); } #[test] fn terminal_extrinsic_discarded_from_txpool() { init_logger(); - let client_builder = TestClientBuilder::new() - .set_execution_strategy(sc_client_api::ExecutionStrategy::NativeWhenPossible); - let mut client = Arc::new(client_builder.build()); - let spawner = sp_core::testing::TaskExecutor::new(); - let txpool = BasicPool::new_full( - Default::default(), - true.into(), - None, - spawner.clone(), - client.clone(), - ); - - let genesis_hash = - <[u8; 32]>::try_from(&client.info().best_hash[..]).expect("H256 is a 32 byte type"); + init!(client, backend, txpool, spawner, genesis_hash); // Create Gear::run() extrinsic - both unsigned and signed let unsigned_gear_run_xt = @@ -689,7 +697,7 @@ fn terminal_extrinsic_discarded_from_txpool() { let legit_xt = sign( CheckedExtrinsic { signed: Some((alice(), signed_extra(0))), - function: pre_fund_bank_account_call(), + function: CallBuilder::deposit_to_bank().build(), }, VERSION.spec_version, VERSION.transaction_version, @@ -702,49 +710,37 @@ fn terminal_extrinsic_discarded_from_txpool() { legit_xt.into(), ]; - // Attempt to submit extrinsics to txpool; expecting only one of the three to be validated - block_on(txpool.submit_at(&BlockId::number(0), SOURCE, extrinsics)).unwrap(); + let block_id = BlockId::number(0); + let timestamp = Timestamp::current(); + let max_gas = None; + let max_duration = 1500_u64; + + propose_block!( + client, + backend, + txpool, + spawner, + best_hash, + block_id, + extrinsics, + timestamp, + max_duration, + max_gas, + proposal, + { + let num_ready = txpool.ready().count(); + assert_eq!(num_ready, 1); + }, + { + // Both mandatory extrinsics should have been discarded, therefore there are only 3 txs + // in the block: 1 timestamp inherent + 1 normal extrinsic + 1 terminal + assert_eq!(proposal.block.extrinsics().len(), 3); - let new_header = client - .block_hash_from_id(&BlockId::Number(0_u32)) - .unwrap() - .unwrap(); - block_on( - txpool.maintain(chain_event( - client - .header(new_header) - .expect("header get error") - .expect("there should be header"), - )), + // Importing block #1 + block_on(client.import(BlockOrigin::Own, proposal.block.clone())).unwrap(); + } ); - let mut proposer_factory = - ProposerFactory::new(spawner, client.clone(), txpool, None, None, None); - - let timestamp_provider = sp_timestamp::InherentDataProvider::from_system_time(); - - let proposer = block_on( - proposer_factory.init( - &client - .header(new_header) - .expect("Database error querying block #0") - .expect("Block #0 should exist"), - ), - ) - .expect("Proposer initialization failed"); - - let inherent_data = - block_on(timestamp_provider.create_inherent_data()).expect("Create inherent data failed"); - let time_slot = sp_timestamp::Timestamp::current().as_millis() / SLOT_DURATION; - - let proposal = block_on(proposer.propose( - inherent_data, - pre_digest(time_slot, 0), - time::Duration::from_secs(600), - None, - )) - .unwrap(); - // Both mandatory extrinsics should have been discarded, therefore there are only 3 txs // in the block: 1 timestamp inherent + 1 normal extrinsic + 1 terminal assert_eq!(proposal.block.extrinsics().len(), 3); @@ -755,3 +751,228 @@ fn terminal_extrinsic_discarded_from_txpool() { let best_hash = client.info().best_hash; assert_eq!(best_hash, proposal.block.hash()); } + +#[test] +fn block_builder_cloned_ok() { + init_logger(); + + let client_builder = + TestClientBuilder::new().set_execution_strategy(ExecutionStrategy::NativeWhenPossible); + let backend = client_builder.backend(); + let client = Arc::new(client_builder.build()); + + let genesis_hash = + <[u8; 32]>::try_from(&client.info().best_hash[..]).expect("H256 is a 32 byte type"); + + let extrinsics = sign_extrinsics( + checked_extrinsics(5, bob(), 0, || CallBuilder::noop().build()), + VERSION.spec_version, + VERSION.transaction_version, + genesis_hash, + ); + + let mut block_builder = BlockBuilder::new( + client.as_ref(), + genesis_hash.into(), + 0_u32, + false.into(), + pre_digest(1, 0), + backend.as_ref(), + ) + .unwrap(); + + extrinsics.into_iter().for_each(|xt: OpaqueExtrinsic| { + assert_ok!(block_builder.push(xt)); + }); + + assert_eq!(block_builder.extrinsics().len(), 5); + + // At this point the overlay wrapped in the `Api` instance has some changes + let fresh_block_builder = BlockBuilder::new( + client.as_ref(), + genesis_hash.into(), + 0_u32, + false.into(), + pre_digest(1, 0), + backend.as_ref(), + ) + .unwrap(); + + let cloned_block_builder = block_builder.clone(); + + let (ext_1, api_1, ver_1, phash_1, bd_1, hsize_1) = block_builder.deconstruct(); + let (ext_2, api_2, ver_2, phash_2, bd_2, hsize_2) = cloned_block_builder.deconstruct(); + + // Assert that the components are equal but different + assert_eq!(ext_1, ext_2); + assert_ne!(ext_1.as_ptr(), ext_2.as_ptr()); + let api_1_ptr: *const >>::RuntimeApi = + api_1.deref(); + let api_2_ptr: *const >>::RuntimeApi = + api_2.deref(); + assert_ne!(api_1_ptr, api_2_ptr); + + // Reconstruct original block builders + let block_builder = BlockBuilder::<'_, _, Client<_, _, _, RA>, _>::from_parts( + ext_1, api_1, ver_1, phash_1, bd_1, hsize_1, + ); + let cloned_block_builder = BlockBuilder::<'_, _, Client<_, _, _, RA>, _>::from_parts( + ext_2, api_2, ver_2, phash_2, bd_2, hsize_2, + ); + + let changes_1 = block_builder.into_storage_changes().unwrap(); + let changes_2 = cloned_block_builder.into_storage_changes().unwrap(); + let changes_3 = fresh_block_builder.into_storage_changes().unwrap(); + + // Assert that the original and the cloned block builders produce same storage changes + assert_eq!( + changes_1.transaction_storage_root, + changes_2.transaction_storage_root + ); + // that are different from what builder created from scratch produces + assert_ne!( + changes_1.transaction_storage_root, + changes_3.transaction_storage_root + ); +} + +#[test] +fn proposal_timing_consistent() { + use sp_state_machine::IterArgs; + + init_logger(); + + init!(client, backend, txpool, spawner, genesis_hash); + + // Create an extrinsic that prefunds the bank account + let pre_fund_bank_xt = CheckedExtrinsic { + signed: Some((alice(), signed_extra(0))), + function: CallBuilder::deposit_to_bank().build(), + }; + let mut checked = vec![pre_fund_bank_xt]; + + // Creating a bunch of extrinsics to use up the quota for txpool processing + // so that about 100 time-consuming init messages should end up in the queue. + // It's possible though that not all of them make it into the block - it can depend on a + // number of factors (timer on the target machine, log level, etc). + checked.extend( + checked_extrinsics(100, bob(), 0, || { + // TODO: this is a "hand-wavy" workaround to have a long-running init message. + // Should be replaced with a more reliable solution (like zero-cost syscalls + // in init message that would guarantee incorrect gas estimation) + CallBuilder::long_init(500_u64).build() + }) + .into_iter(), + ); + let extrinsics = sign_extrinsics( + checked, + VERSION.spec_version, + VERSION.transaction_version, + genesis_hash, + ); + + let block_id = BlockId::number(0); + let timestamp = Timestamp::current(); + let max_gas = None; + // Simulate the situation when the `Gear::run()` takes longer time to execute than forecasted + // (for instance, if the gas metering is not quite precise etc.) by setting the deadline to a + // smaller value than in reality. On Vara the `max_duration` is 1.5s (which is then transformed + // into 1s inside the `Proposer` and corresponds to 10^12 `max_block` weight). + // Here we set it to 0.25s to try hit the timeout during the queue processing. + let max_duration = 250_u64; + + propose_block!( + client, + backend, + txpool, + spawner, + best_hash, + block_id, + extrinsics, + timestamp, + max_duration, + max_gas, + proposal, + { + let num_ready_0 = txpool.ready().count(); + }, + { + // Importing block #1 + block_on(client.import(BlockOrigin::Own, proposal.block.clone())).unwrap(); + + let state = backend.state_at(best_hash).unwrap(); + + // Check that the message queue has all messages pushed to it + let queue_entry_prefix = storage_prefix( + pallet_gear_messenger::Pallet::::name().as_bytes(), + "Dispatches".as_bytes(), + ); + let mut queue_entry_args = IterArgs::default(); + queue_entry_args.prefix = Some(&queue_entry_prefix); + + let queue_len = state.keys(queue_entry_args).unwrap().count(); + + // Draining tx pool in preparation for block #2 + let best_block_id = BlockId::Hash(best_hash); + block_on( + txpool.maintain(chain_event( + client + .header(client.block_hash_from_id(&best_block_id).unwrap().unwrap()) + .expect("header get error") + .expect("there should be header"), + )), + ); + + let num_ready_1 = txpool.ready().count(); + + // `-1` for the bank account pre-funding which did't put anything in the queue. + let num_messages = num_ready_0 - num_ready_1 - 1; + + // We expect the `Gear::run()` to have been dropped, hence the queue should + // still have all the messages originally pushed to it. + assert_eq!(queue_len, num_messages); + } + ); + + // Let the `Gear::run()` thread a little more time to finish + std::thread::sleep(time::Duration::from_millis(500)); + + // In the meantime make sure we can still keep creating blocks + let block_id = BlockId::Hash(best_hash); + let timestamp = Timestamp::new(timestamp.as_millis() + SLOT_DURATION); + // This time we set the deadline to a very high value to ensure that all messages go through. + let max_duration = 15_000_u64; + // No new extrinsics are added to the block + let extrinsics = vec![]; + + propose_block!( + client, + backend, + txpool, + spawner, + best_hash, + block_id, + extrinsics, + timestamp, + max_duration, + max_gas, + proposal, + {}, + { + // Importing block #2 + block_on(client.import(BlockOrigin::Own, proposal.block.clone())).unwrap(); + + let state = backend.state_at(best_hash).unwrap(); + + let queue_entry_prefix = storage_prefix( + pallet_gear_messenger::Pallet::::name().as_bytes(), + "Dispatches".as_bytes(), + ); + let mut queue_entry_args = IterArgs::default(); + queue_entry_args.prefix = Some(&queue_entry_prefix); + + let queue_len = state.keys(queue_entry_args).unwrap().count(); + assert_eq!(queue_len, 0); + } + ); +} diff --git a/node/service/src/lib.rs b/node/service/src/lib.rs index f2b34d07c4a..e6c9e69ee5b 100644 --- a/node/service/src/lib.rs +++ b/node/service/src/lib.rs @@ -191,8 +191,8 @@ where + Send + Sync + 'static, - RuntimeApi::RuntimeApi: - RuntimeApiCollection>, + RuntimeApi::RuntimeApi: RuntimeApiCollection> + + Clone, ExecutorDispatch: NativeExecutionDispatch + 'static, { if config.keystore_remote.is_some() { @@ -358,8 +358,8 @@ where + Send + Sync + 'static, - RuntimeApi::RuntimeApi: - RuntimeApiCollection>, + RuntimeApi::RuntimeApi: RuntimeApiCollection> + + Clone, ExecutorDispatch: NativeExecutionDispatch + 'static, { /// The task manager of the node. @@ -397,8 +397,9 @@ where + Send + Sync + 'static, - RuntimeApi::RuntimeApi: - RuntimeApiCollection>, + RuntimeApi::RuntimeApi: RuntimeApiCollection> + + Clone + + common::RuntimeApiExt>, ExecutorDispatch: NativeExecutionDispatch + 'static, { let hwbench = (!disable_hardware_benchmarks) @@ -471,7 +472,7 @@ where let rpc_handlers = sc_service::spawn_tasks(sc_service::SpawnTasksParams { config, - backend, + backend: backend.clone(), client: client.clone(), keystore: keystore_container.sync_keystore(), network: network.clone(), @@ -510,6 +511,7 @@ where let proposer = authorship::ProposerFactory::new( task_manager.spawn_handle(), client.clone(), + backend.clone(), transaction_pool.clone(), prometheus_registry.as_ref(), telemetry.as_ref().map(|x| x.handle()), diff --git a/runtime/gear/src/lib.rs b/runtime/gear/src/lib.rs index 9bedffb36e0..fc059c7df18 100644 --- a/runtime/gear/src/lib.rs +++ b/runtime/gear/src/lib.rs @@ -66,7 +66,11 @@ pub use runtime_common::{ pub use runtime_primitives::{AccountId, Signature}; use runtime_primitives::{Balance, BlockNumber, Hash, Index, Moment}; use sp_api::impl_runtime_apis; +#[cfg(any(feature = "std", test))] +use sp_api::{CallApiAt, OverlayedChanges, ProofRecorder, StateBackend, StorageTransactionCache}; use sp_core::{crypto::KeyTypeId, ConstBool, ConstU64, OpaqueMetadata, H256}; +#[cfg(any(feature = "std", test))] +use sp_runtime::traits::HashFor; use sp_runtime::{ create_runtime_str, generic, impl_opaque_keys, traits::{AccountIdLookup, BlakeTwo256, Block as BlockT, NumberFor, OpaqueKeys}, @@ -813,3 +817,40 @@ impl_runtime_apis_plus_common! { } } } + +#[cfg(any(feature = "std", test))] +impl Clone for RuntimeApiImpl +where + B: BlockT, + C: CallApiAt, + C::StateBackend: StateBackend>, + >>::Transaction: Clone, +{ + fn clone(&self) -> Self { + unimplemented!() + } +} + +#[cfg(any(feature = "std", test))] +impl common::RuntimeApiExt for RuntimeApiImpl +where + B: BlockT, + C: CallApiAt, + C::StateBackend: StateBackend>, + >>::Transaction: Clone, +{ + type Params = ( + bool, + OverlayedChanges, + StorageTransactionCache, + Option>, + ); + + fn deconstruct(self) -> (&'static C, Self::Params) { + unimplemented!() + } + + fn restore(_call: &C, _params: Self::Params) -> Self { + unimplemented!() + } +} diff --git a/runtime/vara/src/lib.rs b/runtime/vara/src/lib.rs index c15660bd521..9d998163b63 100644 --- a/runtime/vara/src/lib.rs +++ b/runtime/vara/src/lib.rs @@ -19,6 +19,7 @@ #![cfg_attr(not(feature = "std"), no_std)] // `construct_runtime!` does a lot of recursion and requires us to increase the limit to 256. #![recursion_limit = "256"] +#![allow(clippy::items_after_test_module)] // Make the WASM binary available. #[cfg(feature = "std")] @@ -76,7 +77,11 @@ pub use runtime_common::{ pub use runtime_primitives::{AccountId, Signature}; use runtime_primitives::{Balance, BlockNumber, Hash, Index, Moment}; use sp_api::impl_runtime_apis; +#[cfg(any(feature = "std", test))] +use sp_api::{CallApiAt, OverlayedChanges, ProofRecorder, StateBackend, StorageTransactionCache}; use sp_core::{crypto::KeyTypeId, ConstBool, ConstU64, OpaqueMetadata, H256}; +#[cfg(any(feature = "std", test))] +use sp_runtime::traits::HashFor; use sp_runtime::{ create_runtime_str, generic, impl_opaque_keys, traits::{AccountIdLookup, BlakeTwo256, Block as BlockT, ConvertInto, NumberFor, OpaqueKeys}, @@ -1389,3 +1394,60 @@ impl_runtime_apis_plus_common! { } } } + +#[cfg(any(feature = "std", test))] +impl Clone for RuntimeApiImpl +where + B: BlockT, + C: CallApiAt, + C::StateBackend: StateBackend>, + >>::Transaction: Clone, +{ + fn clone(&self) -> Self { + Self { + call: <&C>::clone(&self.call), + commit_on_success: self.commit_on_success.clone(), + changes: self.changes.clone(), + storage_transaction_cache: self.storage_transaction_cache.clone(), + recorder: self.recorder.clone(), + } + } +} + +#[cfg(any(feature = "std", test))] +impl common::RuntimeApiExt for RuntimeApiImpl +where + B: BlockT, + C: CallApiAt, + C::StateBackend: StateBackend>, + >>::Transaction: Clone, +{ + type Params = ( + bool, + OverlayedChanges, + StorageTransactionCache, + Option>, + ); + + fn deconstruct(self) -> (&'static C, Self::Params) { + ( + self.call, + ( + *core::cell::RefCell::borrow(&self.commit_on_success), + core::cell::RefCell::borrow(&self.changes).clone(), + core::cell::RefCell::borrow(&self.storage_transaction_cache).clone(), + self.recorder, + ), + ) + } + + fn restore(call: &C, params: Self::Params) -> Self { + Self { + call: unsafe { std::mem::transmute(call) }, + commit_on_success: params.0.into(), + changes: core::cell::RefCell::new(params.1), + storage_transaction_cache: core::cell::RefCell::new(params.2), + recorder: params.3, + } + } +}