From 7806893c7248746e7a5d09671382e154fb1c1f97 Mon Sep 17 00:00:00 2001 From: Tomasz Polaczyk Date: Thu, 29 Feb 2024 11:27:49 +0100 Subject: [PATCH 01/17] Implement pallet_xcm_core_buyer WIP Update polkadot-sdk, include cherry-pick DescribeAllTerminal --- Cargo.lock | 370 ++++++++-------- Cargo.toml | 3 + pallets/services-payment/src/lib.rs | 14 - pallets/services-payment/src/mock.rs | 14 - pallets/services-payment/src/tests.rs | 14 - pallets/xcm-core-buyer/Cargo.toml | 81 ++++ pallets/xcm-core-buyer/src/benchmarks.rs | 60 +++ pallets/xcm-core-buyer/src/lib.rs | 327 ++++++++++++++ pallets/xcm-core-buyer/src/mock.rs | 310 +++++++++++++ pallets/xcm-core-buyer/src/tests.rs | 57 +++ pallets/xcm-core-buyer/src/weights.rs | 103 +++++ runtime/dancebox/Cargo.toml | 13 +- runtime/dancebox/src/lib.rs | 1 + runtime/dancebox/src/xcm_config.rs | 147 +++++++ .../dancebox/tests/common/xcm/constants.rs | 93 ++++ .../dancebox/tests/common/xcm/core_buyer.rs | 410 ++++++++++++++++++ runtime/dancebox/tests/common/xcm/mocknets.rs | 124 +++++- runtime/dancebox/tests/common/xcm/mod.rs | 1 + 18 files changed, 1925 insertions(+), 217 deletions(-) create mode 100644 pallets/xcm-core-buyer/Cargo.toml create mode 100644 pallets/xcm-core-buyer/src/benchmarks.rs create mode 100644 pallets/xcm-core-buyer/src/lib.rs create mode 100644 pallets/xcm-core-buyer/src/mock.rs create mode 100644 pallets/xcm-core-buyer/src/tests.rs create mode 100644 pallets/xcm-core-buyer/src/weights.rs create mode 100644 runtime/dancebox/tests/common/xcm/core_buyer.rs diff --git a/Cargo.lock b/Cargo.lock index 5f9c037d1..d695a94e5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -433,7 +433,7 @@ checksum = "9b34d609dfbaf33d6889b2b7106d3ca345eacad44200913df5ba02bfd31d2ba9" [[package]] name = "asset-test-utils" version = "1.0.0" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "assets-common", "cumulus-pallet-parachain-system", @@ -468,7 +468,7 @@ dependencies = [ [[package]] name = "assets-common" version = "0.1.0" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "cumulus-primitives-core", "frame-support", @@ -788,7 +788,7 @@ dependencies = [ [[package]] name = "binary-merkle-tree" version = "4.0.0-dev" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "hash-db", "log", @@ -1013,7 +1013,7 @@ dependencies = [ [[package]] name = "bp-header-chain" version = "0.1.0" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "bp-runtime", "finality-grandpa", @@ -1030,7 +1030,7 @@ dependencies = [ [[package]] name = "bp-messages" version = "0.1.0" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "bp-header-chain", "bp-runtime", @@ -1045,7 +1045,7 @@ dependencies = [ [[package]] name = "bp-parachains" version = "0.1.0" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "bp-header-chain", "bp-polkadot-core", @@ -1062,7 +1062,7 @@ dependencies = [ [[package]] name = "bp-polkadot-core" version = "0.1.0" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "bp-messages", "bp-runtime", @@ -1080,7 +1080,7 @@ dependencies = [ [[package]] name = "bp-relayers" version = "0.1.0" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "bp-messages", "bp-runtime", @@ -1094,7 +1094,7 @@ dependencies = [ [[package]] name = "bp-runtime" version = "0.1.0" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "frame-support", "frame-system", @@ -1117,7 +1117,7 @@ dependencies = [ [[package]] name = "bp-test-utils" version = "0.1.0" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "bp-header-chain", "bp-parachains", @@ -1137,7 +1137,7 @@ dependencies = [ [[package]] name = "bp-xcm-bridge-hub" version = "0.1.0" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "sp-std", ] @@ -1145,7 +1145,7 @@ dependencies = [ [[package]] name = "bp-xcm-bridge-hub-router" version = "0.1.0" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "parity-scale-codec", "scale-info", @@ -1156,7 +1156,7 @@ dependencies = [ [[package]] name = "bridge-runtime-common" version = "0.1.0" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "bp-header-chain", "bp-messages", @@ -2297,7 +2297,7 @@ dependencies = [ [[package]] name = "cumulus-client-cli" version = "0.1.0" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "clap", "parity-scale-codec", @@ -2314,7 +2314,7 @@ dependencies = [ [[package]] name = "cumulus-client-collator" version = "0.1.0" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "cumulus-client-consensus-common", "cumulus-client-network", @@ -2337,7 +2337,7 @@ dependencies = [ [[package]] name = "cumulus-client-consensus-aura" version = "0.1.0" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "async-trait", "cumulus-client-collator", @@ -2379,7 +2379,7 @@ dependencies = [ [[package]] name = "cumulus-client-consensus-common" version = "0.1.0" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "async-trait", "cumulus-client-pov-recovery", @@ -2408,7 +2408,7 @@ dependencies = [ [[package]] name = "cumulus-client-consensus-proposer" version = "0.1.0" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "anyhow", "async-trait", @@ -2423,7 +2423,7 @@ dependencies = [ [[package]] name = "cumulus-client-network" version = "0.1.0" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "async-trait", "cumulus-relay-chain-interface", @@ -2446,7 +2446,7 @@ dependencies = [ [[package]] name = "cumulus-client-parachain-inherent" version = "0.1.0" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "async-trait", "cumulus-primitives-core", @@ -2470,7 +2470,7 @@ dependencies = [ [[package]] name = "cumulus-client-pov-recovery" version = "0.1.0" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "async-trait", "cumulus-primitives-core", @@ -2494,7 +2494,7 @@ dependencies = [ [[package]] name = "cumulus-client-service" version = "0.1.0" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "cumulus-client-cli", "cumulus-client-collator", @@ -2530,7 +2530,7 @@ dependencies = [ [[package]] name = "cumulus-pallet-dmp-queue" version = "0.1.0" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "cumulus-primitives-core", "frame-benchmarking", @@ -2593,7 +2593,7 @@ dependencies = [ [[package]] name = "cumulus-pallet-session-benchmarking" version = "3.0.0" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "frame-benchmarking", "frame-support", @@ -2607,7 +2607,7 @@ dependencies = [ [[package]] name = "cumulus-pallet-xcm" version = "0.1.0" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "cumulus-primitives-core", "frame-support", @@ -2623,7 +2623,7 @@ dependencies = [ [[package]] name = "cumulus-pallet-xcmp-queue" version = "0.1.0" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "bounded-collections", "bp-xcm-bridge-hub-router", @@ -2648,7 +2648,7 @@ dependencies = [ [[package]] name = "cumulus-primitives-aura" version = "0.1.0" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "parity-scale-codec", "polkadot-core-primitives", @@ -2704,7 +2704,7 @@ dependencies = [ [[package]] name = "cumulus-primitives-timestamp" version = "0.1.0" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "cumulus-primitives-core", "futures 0.3.30", @@ -2717,7 +2717,7 @@ dependencies = [ [[package]] name = "cumulus-primitives-utility" version = "0.1.0" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "cumulus-primitives-core", "frame-support", @@ -2737,7 +2737,7 @@ dependencies = [ [[package]] name = "cumulus-relay-chain-inprocess-interface" version = "0.1.0" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "async-trait", "cumulus-primitives-core", @@ -2779,7 +2779,7 @@ dependencies = [ [[package]] name = "cumulus-relay-chain-minimal-node" version = "0.1.0" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "array-bytes 6.2.2", "async-trait", @@ -2820,7 +2820,7 @@ dependencies = [ [[package]] name = "cumulus-relay-chain-rpc-interface" version = "0.1.0" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "async-trait", "cumulus-primitives-core", @@ -2859,7 +2859,7 @@ dependencies = [ [[package]] name = "cumulus-test-relay-sproof-builder" version = "0.1.0" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "cumulus-primitives-core", "parity-scale-codec", @@ -3052,12 +3052,15 @@ dependencies = [ "pallet-utility", "pallet-xcm", "pallet-xcm-benchmarks", + "pallet-xcm-core-buyer", "parachains-common", "parity-scale-codec", "polkadot-parachain-primitives", "polkadot-runtime-common", "polkadot-runtime-parachains", "polkadot-service", + "rococo-runtime", + "rococo-runtime-constants", "runtime-common", "sc-consensus-grandpa", "sc-service", @@ -3556,7 +3559,7 @@ dependencies = [ [[package]] name = "emulated-integration-tests-common" version = "1.0.0" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "asset-test-utils", "bp-messages", @@ -4503,7 +4506,7 @@ dependencies = [ [[package]] name = "frame-benchmarking-cli" version = "4.0.0-dev" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "Inflector", "array-bytes 6.2.2", @@ -4579,7 +4582,7 @@ dependencies = [ [[package]] name = "frame-executive" version = "4.0.0-dev" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "frame-support", "frame-system", @@ -4609,7 +4612,7 @@ dependencies = [ [[package]] name = "frame-remote-externalities" version = "0.10.0-dev" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "futures 0.3.30", "indicatif", @@ -4732,7 +4735,7 @@ dependencies = [ [[package]] name = "frame-system-benchmarking" version = "4.0.0-dev" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "frame-benchmarking", "frame-support", @@ -4747,7 +4750,7 @@ dependencies = [ [[package]] name = "frame-system-rpc-runtime-api" version = "4.0.0-dev" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "parity-scale-codec", "sp-api", @@ -4756,7 +4759,7 @@ dependencies = [ [[package]] name = "frame-try-runtime" version = "0.10.0-dev" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "frame-support", "parity-scale-codec", @@ -6775,7 +6778,7 @@ dependencies = [ [[package]] name = "mmr-gadget" version = "4.0.0-dev" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "futures 0.3.30", "log", @@ -6794,7 +6797,7 @@ dependencies = [ [[package]] name = "mmr-rpc" version = "4.0.0-dev" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "anyhow", "jsonrpsee", @@ -7571,7 +7574,7 @@ dependencies = [ [[package]] name = "pallet-asset-conversion" version = "4.0.0-dev" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "frame-benchmarking", "frame-support", @@ -7589,7 +7592,7 @@ dependencies = [ [[package]] name = "pallet-asset-rate" version = "4.0.0-dev" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "frame-benchmarking", "frame-support", @@ -7604,7 +7607,7 @@ dependencies = [ [[package]] name = "pallet-asset-tx-payment" version = "4.0.0-dev" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "frame-benchmarking", "frame-support", @@ -7622,7 +7625,7 @@ dependencies = [ [[package]] name = "pallet-assets" version = "4.0.0-dev" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "frame-benchmarking", "frame-support", @@ -7806,7 +7809,7 @@ dependencies = [ [[package]] name = "pallet-bags-list" version = "4.0.0-dev" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "aquamarine", "docify", @@ -7857,7 +7860,7 @@ dependencies = [ [[package]] name = "pallet-beefy" version = "4.0.0-dev" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "frame-support", "frame-system", @@ -7877,7 +7880,7 @@ dependencies = [ [[package]] name = "pallet-beefy-mmr" version = "4.0.0-dev" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "array-bytes 6.2.2", "binary-merkle-tree", @@ -7902,7 +7905,7 @@ dependencies = [ [[package]] name = "pallet-bounties" version = "4.0.0-dev" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "frame-benchmarking", "frame-support", @@ -7920,7 +7923,7 @@ dependencies = [ [[package]] name = "pallet-bridge-grandpa" version = "0.1.0" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "bp-header-chain", "bp-runtime", @@ -7941,7 +7944,7 @@ dependencies = [ [[package]] name = "pallet-bridge-messages" version = "0.1.0" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "bp-messages", "bp-runtime", @@ -7959,7 +7962,7 @@ dependencies = [ [[package]] name = "pallet-bridge-parachains" version = "0.1.0" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "bp-header-chain", "bp-parachains", @@ -7980,7 +7983,7 @@ dependencies = [ [[package]] name = "pallet-bridge-relayers" version = "0.1.0" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "bp-messages", "bp-relayers", @@ -8046,7 +8049,7 @@ dependencies = [ [[package]] name = "pallet-child-bounties" version = "4.0.0-dev" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "frame-benchmarking", "frame-support", @@ -8097,7 +8100,7 @@ dependencies = [ [[package]] name = "pallet-collator-selection" version = "3.0.0" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "frame-benchmarking", "frame-support", @@ -8116,7 +8119,7 @@ dependencies = [ [[package]] name = "pallet-collective" version = "4.0.0-dev" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "frame-benchmarking", "frame-support", @@ -8151,7 +8154,7 @@ dependencies = [ [[package]] name = "pallet-conviction-voting" version = "4.0.0-dev" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "assert_matches", "frame-benchmarking", @@ -8192,7 +8195,7 @@ dependencies = [ [[package]] name = "pallet-democracy" version = "4.0.0-dev" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "frame-benchmarking", "frame-support", @@ -8210,7 +8213,7 @@ dependencies = [ [[package]] name = "pallet-election-provider-multi-phase" version = "4.0.0-dev" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "frame-benchmarking", "frame-election-provider-support", @@ -8233,7 +8236,7 @@ dependencies = [ [[package]] name = "pallet-election-provider-support-benchmarking" version = "4.0.0-dev" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "frame-benchmarking", "frame-election-provider-support", @@ -8247,7 +8250,7 @@ dependencies = [ [[package]] name = "pallet-elections-phragmen" version = "5.0.0-dev" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "frame-benchmarking", "frame-support", @@ -8464,7 +8467,7 @@ dependencies = [ [[package]] name = "pallet-fast-unstake" version = "4.0.0-dev" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "docify", "frame-benchmarking", @@ -8502,7 +8505,7 @@ dependencies = [ [[package]] name = "pallet-grandpa" version = "4.0.0-dev" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "frame-benchmarking", "frame-support", @@ -8541,7 +8544,7 @@ dependencies = [ [[package]] name = "pallet-identity" version = "4.0.0-dev" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "enumflags2", "frame-benchmarking", @@ -8558,7 +8561,7 @@ dependencies = [ [[package]] name = "pallet-im-online" version = "4.0.0-dev" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "frame-benchmarking", "frame-support", @@ -8578,7 +8581,7 @@ dependencies = [ [[package]] name = "pallet-indices" version = "4.0.0-dev" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "frame-benchmarking", "frame-support", @@ -8671,7 +8674,7 @@ dependencies = [ [[package]] name = "pallet-membership" version = "4.0.0-dev" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "frame-benchmarking", "frame-support", @@ -8727,7 +8730,7 @@ dependencies = [ [[package]] name = "pallet-mmr" version = "4.0.0-dev" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "frame-benchmarking", "frame-support", @@ -8745,7 +8748,7 @@ dependencies = [ [[package]] name = "pallet-multisig" version = "4.0.0-dev" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "frame-benchmarking", "frame-support", @@ -8761,7 +8764,7 @@ dependencies = [ [[package]] name = "pallet-nis" version = "4.0.0-dev" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "frame-benchmarking", "frame-support", @@ -8777,7 +8780,7 @@ dependencies = [ [[package]] name = "pallet-nomination-pools" version = "1.0.0" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "frame-support", "frame-system", @@ -8796,7 +8799,7 @@ dependencies = [ [[package]] name = "pallet-nomination-pools-benchmarking" version = "1.0.0" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "frame-benchmarking", "frame-election-provider-support", @@ -8816,7 +8819,7 @@ dependencies = [ [[package]] name = "pallet-nomination-pools-runtime-api" version = "1.0.0-dev" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "pallet-nomination-pools", "parity-scale-codec", @@ -8827,7 +8830,7 @@ dependencies = [ [[package]] name = "pallet-offences" version = "4.0.0-dev" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "frame-support", "frame-system", @@ -8844,7 +8847,7 @@ dependencies = [ [[package]] name = "pallet-offences-benchmarking" version = "4.0.0-dev" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "frame-benchmarking", "frame-election-provider-support", @@ -8892,7 +8895,7 @@ dependencies = [ [[package]] name = "pallet-preimage" version = "4.0.0-dev" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "frame-benchmarking", "frame-support", @@ -8909,7 +8912,7 @@ dependencies = [ [[package]] name = "pallet-proxy" version = "4.0.0-dev" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "frame-benchmarking", "frame-support", @@ -8924,7 +8927,7 @@ dependencies = [ [[package]] name = "pallet-ranked-collective" version = "4.0.0-dev" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "frame-benchmarking", "frame-support", @@ -8942,7 +8945,7 @@ dependencies = [ [[package]] name = "pallet-recovery" version = "4.0.0-dev" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "frame-benchmarking", "frame-support", @@ -8957,7 +8960,7 @@ dependencies = [ [[package]] name = "pallet-referenda" version = "4.0.0-dev" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "assert_matches", "frame-benchmarking", @@ -9032,7 +9035,7 @@ dependencies = [ [[package]] name = "pallet-root-testing" version = "1.0.0-dev" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "frame-support", "frame-system", @@ -9047,7 +9050,7 @@ dependencies = [ [[package]] name = "pallet-scheduler" version = "4.0.0-dev" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "docify", "frame-benchmarking", @@ -9107,7 +9110,7 @@ dependencies = [ [[package]] name = "pallet-session-benchmarking" version = "4.0.0-dev" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "frame-benchmarking", "frame-support", @@ -9124,7 +9127,7 @@ dependencies = [ [[package]] name = "pallet-society" version = "4.0.0-dev" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "frame-benchmarking", "frame-support", @@ -9165,7 +9168,7 @@ dependencies = [ [[package]] name = "pallet-staking-reward-curve" version = "4.0.0-dev" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "proc-macro-crate 3.1.0", "proc-macro2", @@ -9176,7 +9179,7 @@ dependencies = [ [[package]] name = "pallet-staking-reward-fn" version = "4.0.0-dev" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "log", "sp-arithmetic", @@ -9185,7 +9188,7 @@ dependencies = [ [[package]] name = "pallet-staking-runtime-api" version = "4.0.0-dev" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "parity-scale-codec", "sp-api", @@ -9195,7 +9198,7 @@ dependencies = [ [[package]] name = "pallet-state-trie-migration" version = "4.0.0-dev" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "frame-benchmarking", "frame-support", @@ -9236,7 +9239,7 @@ dependencies = [ [[package]] name = "pallet-sudo" version = "4.0.0-dev" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "docify", "frame-benchmarking", @@ -9272,7 +9275,7 @@ dependencies = [ [[package]] name = "pallet-tips" version = "4.0.0-dev" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "frame-benchmarking", "frame-support", @@ -9291,7 +9294,7 @@ dependencies = [ [[package]] name = "pallet-transaction-payment" version = "4.0.0-dev" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "frame-support", "frame-system", @@ -9307,7 +9310,7 @@ dependencies = [ [[package]] name = "pallet-transaction-payment-rpc" version = "4.0.0-dev" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "jsonrpsee", "pallet-transaction-payment-rpc-runtime-api", @@ -9323,7 +9326,7 @@ dependencies = [ [[package]] name = "pallet-transaction-payment-rpc-runtime-api" version = "4.0.0-dev" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "pallet-transaction-payment", "parity-scale-codec", @@ -9335,7 +9338,7 @@ dependencies = [ [[package]] name = "pallet-treasury" version = "4.0.0-dev" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "docify", "frame-benchmarking", @@ -9354,7 +9357,7 @@ dependencies = [ [[package]] name = "pallet-tx-pause" version = "4.0.0-dev" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "docify", "frame-benchmarking", @@ -9372,7 +9375,7 @@ dependencies = [ [[package]] name = "pallet-utility" version = "4.0.0-dev" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "frame-benchmarking", "frame-support", @@ -9403,7 +9406,7 @@ dependencies = [ [[package]] name = "pallet-whitelist" version = "4.0.0-dev" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "frame-benchmarking", "frame-support", @@ -9418,7 +9421,7 @@ dependencies = [ [[package]] name = "pallet-xcm" version = "1.0.0" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "bounded-collections", "frame-benchmarking", @@ -9441,7 +9444,7 @@ dependencies = [ [[package]] name = "pallet-xcm-benchmarks" version = "1.0.0" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "frame-benchmarking", "frame-support", @@ -9460,7 +9463,7 @@ dependencies = [ [[package]] name = "pallet-xcm-bridge-hub-router" version = "0.1.0" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "bp-xcm-bridge-hub-router", "frame-benchmarking", @@ -9476,6 +9479,31 @@ dependencies = [ "staging-xcm-builder", ] +[[package]] +name = "pallet-xcm-core-buyer" +version = "0.1.0" +dependencies = [ + "bounded-collections", + "dp-core", + "frame-benchmarking", + "frame-support", + "frame-system", + "log", + "nimbus-primitives", + "num-traits", + "pallet-balances", + "parity-scale-codec", + "scale-info", + "serde", + "similar-asserts", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", + "staging-xcm", + "tp-traits", +] + [[package]] name = "pallet-xcm-executor-utils" version = "0.1.0" @@ -9497,7 +9525,7 @@ dependencies = [ [[package]] name = "parachains-common" version = "1.0.0" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "cumulus-primitives-core", "cumulus-primitives-utility", @@ -9534,7 +9562,7 @@ dependencies = [ [[package]] name = "parachains-runtimes-test-utils" version = "1.0.0" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "assets-common", "cumulus-pallet-parachain-system", @@ -9887,7 +9915,7 @@ checksum = "626dec3cac7cc0e1577a2ec3fc496277ec2baa084bebad95bb6fdbfae235f84c" [[package]] name = "polkadot-approval-distribution" version = "1.0.0" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "bitvec", "futures 0.3.30", @@ -9907,7 +9935,7 @@ dependencies = [ [[package]] name = "polkadot-availability-bitfield-distribution" version = "1.0.0" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "always-assert", "futures 0.3.30", @@ -9923,7 +9951,7 @@ dependencies = [ [[package]] name = "polkadot-availability-distribution" version = "1.0.0" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "derive_more", "fatality", @@ -9946,7 +9974,7 @@ dependencies = [ [[package]] name = "polkadot-availability-recovery" version = "1.0.0" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "async-trait", "fatality", @@ -9969,7 +9997,7 @@ dependencies = [ [[package]] name = "polkadot-cli" version = "1.1.0" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "cfg-if", "clap", @@ -9997,7 +10025,7 @@ dependencies = [ [[package]] name = "polkadot-collator-protocol" version = "1.0.0" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "bitvec", "fatality", @@ -10031,7 +10059,7 @@ dependencies = [ [[package]] name = "polkadot-dispute-distribution" version = "1.0.0" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "derive_more", "fatality", @@ -10056,7 +10084,7 @@ dependencies = [ [[package]] name = "polkadot-erasure-coding" version = "1.0.0" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "parity-scale-codec", "polkadot-node-primitives", @@ -10070,7 +10098,7 @@ dependencies = [ [[package]] name = "polkadot-gossip-support" version = "1.0.0" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "futures 0.3.30", "futures-timer", @@ -10091,7 +10119,7 @@ dependencies = [ [[package]] name = "polkadot-network-bridge" version = "1.0.0" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "always-assert", "async-trait", @@ -10114,7 +10142,7 @@ dependencies = [ [[package]] name = "polkadot-node-collation-generation" version = "1.0.0" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "futures 0.3.30", "parity-scale-codec", @@ -10132,7 +10160,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-approval-voting" version = "1.0.0" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "bitvec", "derive_more", @@ -10165,7 +10193,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-av-store" version = "1.0.0" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "bitvec", "futures 0.3.30", @@ -10187,7 +10215,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-backing" version = "1.0.0" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "bitvec", "fatality", @@ -10206,7 +10234,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-bitfield-signing" version = "1.0.0" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "futures 0.3.30", "polkadot-node-subsystem", @@ -10221,7 +10249,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-candidate-validation" version = "1.0.0" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "async-trait", "futures 0.3.30", @@ -10242,7 +10270,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-chain-api" version = "1.0.0" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "futures 0.3.30", "polkadot-node-metrics", @@ -10256,7 +10284,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-chain-selection" version = "1.0.0" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "futures 0.3.30", "futures-timer", @@ -10273,7 +10301,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-dispute-coordinator" version = "1.0.0" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "fatality", "futures 0.3.30", @@ -10292,7 +10320,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-parachains-inherent" version = "1.0.0" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "async-trait", "futures 0.3.30", @@ -10309,7 +10337,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-prospective-parachains" version = "1.0.0" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "bitvec", "fatality", @@ -10326,7 +10354,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-provisioner" version = "1.0.0" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "bitvec", "fatality", @@ -10343,7 +10371,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-pvf" version = "1.0.0" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "always-assert", "array-bytes 6.2.2", @@ -10376,7 +10404,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-pvf-checker" version = "1.0.0" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "futures 0.3.30", "polkadot-node-primitives", @@ -10392,7 +10420,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-pvf-common" version = "1.0.0" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "cfg-if", "cpu-time", @@ -10417,7 +10445,7 @@ dependencies = [ [[package]] name = "polkadot-node-core-runtime-api" version = "1.0.0" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "futures 0.3.30", "polkadot-node-metrics", @@ -10516,7 +10544,7 @@ dependencies = [ [[package]] name = "polkadot-node-subsystem" version = "1.0.0" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "polkadot-node-jaeger", "polkadot-node-subsystem-types", @@ -10554,7 +10582,7 @@ dependencies = [ [[package]] name = "polkadot-node-subsystem-util" version = "1.0.0" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "async-trait", "derive_more", @@ -10654,7 +10682,7 @@ dependencies = [ [[package]] name = "polkadot-rpc" version = "1.0.0" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "jsonrpsee", "mmr-rpc", @@ -10687,7 +10715,7 @@ dependencies = [ [[package]] name = "polkadot-runtime-common" version = "1.0.0" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "bitvec", "frame-benchmarking", @@ -10801,7 +10829,7 @@ dependencies = [ [[package]] name = "polkadot-service" version = "1.0.0" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "async-trait", "frame-benchmarking", @@ -10918,7 +10946,7 @@ dependencies = [ [[package]] name = "polkadot-statement-distribution" version = "1.0.0" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "arrayvec 0.7.4", "bitvec", @@ -11715,7 +11743,7 @@ dependencies = [ [[package]] name = "rococo-runtime" version = "1.0.0" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "binary-merkle-tree", "frame-benchmarking", @@ -11811,7 +11839,7 @@ dependencies = [ [[package]] name = "rococo-runtime-constants" version = "1.0.0" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "frame-support", "polkadot-primitives", @@ -12112,7 +12140,7 @@ dependencies = [ [[package]] name = "sc-basic-authorship" version = "0.10.0-dev" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "futures 0.3.30", "futures-timer", @@ -12307,7 +12335,7 @@ dependencies = [ [[package]] name = "sc-consensus-aura" version = "0.10.0-dev" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "async-trait", "futures 0.3.30", @@ -12336,7 +12364,7 @@ dependencies = [ [[package]] name = "sc-consensus-babe" version = "0.10.0-dev" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "async-trait", "fork-tree", @@ -12371,7 +12399,7 @@ dependencies = [ [[package]] name = "sc-consensus-babe-rpc" version = "0.10.0-dev" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "futures 0.3.30", "jsonrpsee", @@ -12393,7 +12421,7 @@ dependencies = [ [[package]] name = "sc-consensus-beefy" version = "4.0.0-dev" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "array-bytes 6.2.2", "async-channel 1.9.0", @@ -12428,7 +12456,7 @@ dependencies = [ [[package]] name = "sc-consensus-beefy-rpc" version = "4.0.0-dev" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "futures 0.3.30", "jsonrpsee", @@ -12447,7 +12475,7 @@ dependencies = [ [[package]] name = "sc-consensus-epochs" version = "0.10.0-dev" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "fork-tree", "parity-scale-codec", @@ -12460,7 +12488,7 @@ dependencies = [ [[package]] name = "sc-consensus-grandpa" version = "0.10.0-dev" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "ahash 0.8.8", "array-bytes 6.2.2", @@ -12502,7 +12530,7 @@ dependencies = [ [[package]] name = "sc-consensus-grandpa-rpc" version = "0.10.0-dev" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "finality-grandpa", "futures 0.3.30", @@ -12522,7 +12550,7 @@ dependencies = [ [[package]] name = "sc-consensus-manual-seal" version = "0.10.0-dev" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "assert_matches", "async-trait", @@ -12557,7 +12585,7 @@ dependencies = [ [[package]] name = "sc-consensus-slots" version = "0.10.0-dev" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "async-trait", "futures 0.3.30", @@ -12776,7 +12804,7 @@ dependencies = [ [[package]] name = "sc-network-gossip" version = "0.10.0-dev" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "ahash 0.8.8", "futures 0.3.30", @@ -12852,7 +12880,7 @@ dependencies = [ [[package]] name = "sc-network-test" version = "0.8.0" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "async-trait", "futures 0.3.30", @@ -12902,7 +12930,7 @@ dependencies = [ [[package]] name = "sc-offchain" version = "4.0.0-dev" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "array-bytes 6.2.2", "bytes", @@ -12936,7 +12964,7 @@ dependencies = [ [[package]] name = "sc-proposer-metrics" version = "0.10.0-dev" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "log", "substrate-prometheus-endpoint", @@ -13115,7 +13143,7 @@ dependencies = [ [[package]] name = "sc-storage-monitor" version = "0.1.0" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "clap", "fs4", @@ -13128,7 +13156,7 @@ dependencies = [ [[package]] name = "sc-sync-state-rpc" version = "0.10.0-dev" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "jsonrpsee", "parity-scale-codec", @@ -13724,7 +13752,7 @@ dependencies = [ [[package]] name = "slot-range-helper" version = "1.0.0" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "enumn", "parity-scale-codec", @@ -14073,7 +14101,7 @@ dependencies = [ [[package]] name = "sp-consensus-beefy" version = "4.0.0-dev" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "lazy_static", "parity-scale-codec", @@ -14323,7 +14351,7 @@ dependencies = [ [[package]] name = "sp-mmr-primitives" version = "4.0.0-dev" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "ckb-merkle-mountain-range", "log", @@ -14841,7 +14869,7 @@ checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" [[package]] name = "staging-parachain-info" version = "0.1.0" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "cumulus-primitives-core", "frame-support", @@ -14873,7 +14901,7 @@ dependencies = [ [[package]] name = "staging-xcm-builder" version = "1.0.0" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "frame-support", "frame-system", @@ -15023,12 +15051,12 @@ dependencies = [ [[package]] name = "substrate-build-script-utils" version = "3.0.0" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" [[package]] name = "substrate-frame-rpc-system" version = "4.0.0-dev" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "frame-system-rpc-runtime-api", "futures 0.3.30", @@ -15059,7 +15087,7 @@ dependencies = [ [[package]] name = "substrate-rpc-client" version = "0.10.0-dev" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "async-trait", "jsonrpsee", @@ -15072,7 +15100,7 @@ dependencies = [ [[package]] name = "substrate-state-trie-migration-rpc" version = "4.0.0-dev" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "jsonrpsee", "parity-scale-codec", @@ -15089,7 +15117,7 @@ dependencies = [ [[package]] name = "substrate-test-client" version = "2.0.1" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "array-bytes 6.2.2", "async-trait", @@ -15115,7 +15143,7 @@ dependencies = [ [[package]] name = "substrate-test-runtime" version = "2.0.0" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "array-bytes 6.2.2", "frame-executive", @@ -15156,7 +15184,7 @@ dependencies = [ [[package]] name = "substrate-test-runtime-client" version = "2.0.0" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "futures 0.3.30", "sc-block-builder", @@ -15174,7 +15202,7 @@ dependencies = [ [[package]] name = "substrate-wasm-builder" version = "5.0.0-dev" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "ansi_term", "build-helper", @@ -16081,7 +16109,7 @@ checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" [[package]] name = "try-runtime-cli" version = "0.10.0-dev" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "async-trait", "clap", @@ -16765,7 +16793,7 @@ checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" [[package]] name = "westend-runtime" version = "1.0.0" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "binary-merkle-tree", "bitvec", @@ -16871,7 +16899,7 @@ dependencies = [ [[package]] name = "westend-runtime-constants" version = "1.0.0" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "frame-support", "polkadot-primitives", @@ -17250,7 +17278,7 @@ dependencies = [ [[package]] name = "xcm-emulator" version = "0.1.0" -source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#fb422ea2572811a4d339dc100cb32d6aa63fe0c9" +source = "git+https://github.com/moondance-labs/polkadot-sdk?branch=tanssi-polkadot-v1.6.0#77c5b55315748c0c7922292d0c2c5a933441c920" dependencies = [ "cumulus-pallet-parachain-system", "cumulus-pallet-xcmp-queue", diff --git a/Cargo.toml b/Cargo.toml index afba7f4f1..4c14ee727 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -48,6 +48,7 @@ pallet-registrar = { path = "pallets/registrar", default-features = false } pallet-registrar-runtime-api = { path = "pallets/registrar/rpc/runtime-api", default-features = false } pallet-services-payment = { path = "pallets/services-payment", default-features = false } pallet-stream-payment = { path = "pallets/stream-payment", default-features = false } +pallet-xcm-core-buyer = { path = "pallets/xcm-core-buyer", default-features = false } container-chain-template-frontier-runtime = { path = "container-chains/templates/frontier/runtime", default-features = false } container-chain-template-simple-runtime = { path = "container-chains/templates/simple/runtime", default-features = false } @@ -200,6 +201,8 @@ polkadot-runtime-parachains = { git = "https://github.com/moondance-labs/polkado staging-xcm = { git = "https://github.com/moondance-labs/polkadot-sdk", branch = "tanssi-polkadot-v1.6.0", default-features = false } staging-xcm-builder = { git = "https://github.com/moondance-labs/polkadot-sdk", branch = "tanssi-polkadot-v1.6.0", default-features = false } staging-xcm-executor = { git = "https://github.com/moondance-labs/polkadot-sdk", branch = "tanssi-polkadot-v1.6.0", default-features = false } +rococo-runtime = { git = "https://github.com/moondance-labs/polkadot-sdk", branch = "tanssi-polkadot-v1.6.0", default-features = false } +rococo-runtime-constants = { git = "https://github.com/moondance-labs/polkadot-sdk", branch = "tanssi-polkadot-v1.6.0", default-features = false } westend-runtime = { git = "https://github.com/moondance-labs/polkadot-sdk", branch = "tanssi-polkadot-v1.6.0", default-features = false } westend-runtime-constants = { git = "https://github.com/moondance-labs/polkadot-sdk", branch = "tanssi-polkadot-v1.6.0", default-features = false } diff --git a/pallets/services-payment/src/lib.rs b/pallets/services-payment/src/lib.rs index 178d3ba81..4a3d1bdbc 100644 --- a/pallets/services-payment/src/lib.rs +++ b/pallets/services-payment/src/lib.rs @@ -14,20 +14,6 @@ // You should have received a copy of the GNU General Public License // along with Tanssi. If not, see -//! # Author Noting Pallet -//! -//! This pallet notes the author of the different containerChains that have registered: -//! -//! The set of container chains is retrieved thanks to the GetContainerChains trait -//! For each containerChain, we inspect the Header stored in the relayChain as -//! a generic header. This is the first requirement for containerChains. -//! -//! The second requirement is that an Aura digest with the slot number for the containerChains -//! needs to exist -//! -//! Using those two requirements we can select who the author was based on the collators assigned -//! to that containerChain, by simply assigning the slot position. - //! # Services Payment pallet //! //! This pallet allows for block creation services to be paid for by a diff --git a/pallets/services-payment/src/mock.rs b/pallets/services-payment/src/mock.rs index c8fb9fbd5..1fc1780cb 100644 --- a/pallets/services-payment/src/mock.rs +++ b/pallets/services-payment/src/mock.rs @@ -14,20 +14,6 @@ // You should have received a copy of the GNU General Public License // along with Tanssi. If not, see -//! # Author Noting Pallet -//! -//! This pallet notes the author of the different containerChains that have registered: -//! -//! The set of container chains is retrieved thanks to the GetContainerChains trait -//! For each containerChain, we inspect the Header stored in the relayChain as -//! a generic header. This is the first requirement for containerChains. -//! -//! The second requirement is that an Aura digest with the slot number for the containerChains -//! needs to exist -//! -//! Using those two requirements we can select who the author was based on the collators assigned -//! to that containerChain, by simply assigning the slot position. - use { crate::{ self as pallet_services_payment, ProvideBlockProductionCost, ProvideCollatorAssignmentCost, diff --git a/pallets/services-payment/src/tests.rs b/pallets/services-payment/src/tests.rs index 66d2dfa25..db2c77d14 100644 --- a/pallets/services-payment/src/tests.rs +++ b/pallets/services-payment/src/tests.rs @@ -14,20 +14,6 @@ // You should have received a copy of the GNU General Public License // along with Tanssi. If not, see -//! # Author Noting Pallet -//! -//! This pallet notes the author of the different containerChains that have registered: -//! -//! The set of container chains is retrieved thanks to the GetContainerChains trait -//! For each containerChain, we inspect the Header stored in the relayChain as -//! a generic header. This is the first requirement for containerChains. -//! -//! The second requirement is that an Aura digest with the slot number for the containerChains -//! needs to exist -//! -//! Using those two requirements we can select who the author was based on the collators assigned -//! to that containerChain, by simply assigning the slot position. - use { crate::{ mock::*, pallet as pallet_services_payment, BlockProductionCredits, diff --git a/pallets/xcm-core-buyer/Cargo.toml b/pallets/xcm-core-buyer/Cargo.toml new file mode 100644 index 000000000..14a54a149 --- /dev/null +++ b/pallets/xcm-core-buyer/Cargo.toml @@ -0,0 +1,81 @@ +[package] +name = "pallet-xcm-core-buyer" +authors = { workspace = true } +description = "Allows collators to buy parathread cores on demand" +edition = "2021" +license = "GPL-3.0-only" +version = "0.1.0" + +[package.metadata.docs.rs] +targets = [ "x86_64-unknown-linux-gnu" ] + +[dependencies] + +dp-core = { workspace = true } +log = { workspace = true } +serde = { workspace = true, optional = true } +tp-traits = { workspace = true } + +# Polkadot +staging-xcm = { workspace = true } + +# Substrate +frame-benchmarking = { workspace = true, optional = true } +frame-support = { workspace = true } +frame-system = { workspace = true } +parity-scale-codec = { workspace = true } +scale-info = { workspace = true } +sp-core = { workspace = true } +sp-io = { workspace = true } +sp-runtime = { workspace = true } +sp-std = { workspace = true } + +# Nimbus +nimbus-primitives = { workspace = true } + +[dev-dependencies] +bounded-collections = { workspace = true } +num-traits = { workspace = true } +pallet-balances = { workspace = true, features = [ "std" ] } +similar-asserts = { workspace = true } +sp-io = { workspace = true, features = [ "std" ] } + +[features] +default = [ "std" ] +std = [ + "bounded-collections/std", + "dp-core/std", + "frame-benchmarking/std", + "frame-support/std", + "frame-system/std", + "log/std", + "nimbus-primitives/std", + "pallet-balances/std", + "parity-scale-codec/std", + "scale-info/std", + "serde", + "serde?/std", + "sp-core/std", + "sp-io/std", + "sp-runtime/std", + "sp-std/std", + "tp-traits/std", + "staging-xcm/std" +] +runtime-benchmarks = [ + "frame-benchmarking", + "frame-benchmarking/runtime-benchmarks", + "frame-support/runtime-benchmarks", + "frame-system/runtime-benchmarks", + "nimbus-primitives/runtime-benchmarks", + "pallet-balances/runtime-benchmarks", + "sp-runtime/runtime-benchmarks", + "tp-traits/runtime-benchmarks", +] +try-runtime = [ + "frame-support/try-runtime", + "frame-system/try-runtime", + "nimbus-primitives/try-runtime", + "pallet-balances/try-runtime", + "sp-runtime/try-runtime", +] diff --git a/pallets/xcm-core-buyer/src/benchmarks.rs b/pallets/xcm-core-buyer/src/benchmarks.rs new file mode 100644 index 000000000..39ece281a --- /dev/null +++ b/pallets/xcm-core-buyer/src/benchmarks.rs @@ -0,0 +1,60 @@ +// Copyright (C) Moondance Labs Ltd. +// This file is part of Tanssi. + +// Tanssi is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Tanssi is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Tanssi. If not, see + +#![cfg(feature = "runtime-benchmarks")] + +//! Benchmarking +use { + crate::{Call, Config, Pallet}, + frame_benchmarking::v2::*, + frame_support::{ + traits::{EnsureOriginWithArg, OriginTrait}, + BoundedVec, + }, + frame_system::RawOrigin, + sp_std::vec, + tp_traits::ParaId, +}; + +#[benchmarks] +mod benchmarks { + use super::*; + + // TODO + #[benchmark] + fn set_boot_nodes(x: Linear<1, 200>, y: Linear<1, 10>) { + // x: url len, y: num boot_nodes + let boot_nodes = BoundedVec::try_from(vec![ + BoundedVec::try_from(vec![b'A'; x as usize]) + .unwrap(); + y as usize + ]) + .unwrap(); + let para_id = ParaId::from(2); + let origin = T::SetBootNodesOrigin::try_successful_origin(¶_id) + .expect("failed to create SetBootNodesOrigin"); + // Worst case is when caller is not root + let raw_origin = origin.as_system_ref(); + assert!(matches!(raw_origin, Some(RawOrigin::Signed(..)))); + + #[extrinsic_call] + Pallet::::set_boot_nodes(origin as T::RuntimeOrigin, para_id, boot_nodes.clone()); + + assert_eq!(Pallet::::boot_nodes(¶_id), boot_nodes); + } + + impl_benchmark_test_suite!(Pallet, crate::mock::new_test_ext(), crate::mock::Test); +} diff --git a/pallets/xcm-core-buyer/src/lib.rs b/pallets/xcm-core-buyer/src/lib.rs new file mode 100644 index 000000000..ceec6f485 --- /dev/null +++ b/pallets/xcm-core-buyer/src/lib.rs @@ -0,0 +1,327 @@ +// Copyright (C) Moondance Labs Ltd. +// This file is part of Tanssi. + +// Tanssi is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Tanssi is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Tanssi. If not, see + +//! # XCM Core Buyer Pallet +//! +//! This pallet allows collators to buy parathread cores on demand. + +#![cfg_attr(not(feature = "std"), no_std)] + +pub use pallet::*; + +#[cfg(test)] +mod mock; + +#[cfg(test)] +mod tests; + +#[cfg(any(test, feature = "runtime-benchmarks"))] +mod benchmarks; +pub mod weights; + +use { + crate::weights::WeightInfo, + dp_core::ParaId, + frame_support::{ + pallet_prelude::*, + traits::fungible::{Balanced, Inspect}, + }, + frame_system::pallet_prelude::*, + sp_io::hashing::blake2_256, + sp_runtime::traits::{Convert, Get}, + sp_std::vec, + sp_std::vec::Vec, + staging_xcm::prelude::*, + staging_xcm::v3::{InteriorMultiLocation, MultiAsset, MultiAssets, Xcm}, +}; + +#[frame_support::pallet] +pub mod pallet { + use super::*; + use sp_runtime::traits::TrailingZeroInput; + + /// Data preservers pallet. + #[pallet::pallet] + #[pallet::without_storage_info] + pub struct Pallet(core::marker::PhantomData); + + #[pallet::config] + pub trait Config: frame_system::Config { + /// Overarching event type. + type RuntimeEvent: From> + IsType<::RuntimeEvent>; + type Currency: Inspect + Balanced; + + type XcmBuyExecutionDot: Get; + type XcmSender: SendXcm; + type GetPurchaseCoretimeCall: GetPurchaseCoretimeCall; + type GetBlockNumber: Get; + // TODO: use AccountIdConversion trait here? + type AccountIdToArray32: Convert; + type SelfParaId: Get; + /// A configuration for base priority of unsigned transactions. + /// + /// This is exposed so that it can be tuned for particular runtime, when + /// multiple pallets send unsigned transactions. + #[pallet::constant] + type UnsignedPriority: Get; + + type WeightInfo: WeightInfo; + } + + #[pallet::event] + #[pallet::generate_deposit(pub(super) fn deposit_event)] + pub enum Event { + /// An XCM message to buy a core for this parathread has been sent to the relay chain. + CoretimeXcmSent { para_id: ParaId }, + } + + #[pallet::error] + pub enum Error { + NoAccountForParaId, + ErrorValidating, + ErrorDelivering, + } + + /// Proof that I am a collator, assigned to a para_id, and I can buy a core for that para_id + #[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo)] + pub struct BuyCoretimeCollatorProof { + // TODO + _signature: (), + } + + #[pallet::call] + impl Pallet { + /// Buy a core for this parathread id. + /// Collators should call this to indicate that they intend to produce a block, but they + /// cannot do it because this para id has no available cores. + /// The purchase is automatic using XCM, and collators do not need to do anything. + // Note that the collators that will be calling this function are parathread collators, not + // tanssi collators. So we cannot force them to provide a complex proof, e.g. against relay + // state. + #[pallet::call_index(0)] + // TODO: weight + #[pallet::weight(T::WeightInfo::set_boot_nodes(1, 1))] + pub fn buy_coretime( + origin: OriginFor, + para_id: ParaId, + // since signature verification is done in `validate_unsigned` + // we can skip doing it here again. + _proof: BuyCoretimeCollatorProof, + ) -> DispatchResult { + // Signature verification is done in `validate_unsigned`. + // We use `ensure_none` here because this can only be called by collators, and we do not + // want collators to pay fees. + ensure_none(origin)?; + + Self::on_collator_instantaneous_core_requested(para_id) + } + + /// Buy coretime for para id as root. Does not require any proof, useful in tests. + #[pallet::call_index(1)] + // TODO: weight + #[pallet::weight(T::WeightInfo::set_boot_nodes(1, 1))] + pub fn force_buy_coretime(origin: OriginFor, para_id: ParaId) -> DispatchResult { + ensure_root(origin)?; + + // TODO: check that the para_id is a parathread, and at least one collator could buy a + // core for it. Even though this extrinsic is called `force`, it should only be possible + // to use it when an equivalent non-force call can be created. + + Self::on_collator_instantaneous_core_requested(para_id) + } + } + + impl Pallet { + /// Derive a derivative account ID from the paraId to use as a DOT tank in the relay chain. + /// This is not the actual address, the actual address can be computed as a derivative of + /// the tanssi sovereign account and this address. + pub fn relay_parachain_tank_id(para_id: ParaId) -> T::AccountId { + // TODO: we could use the services_payment parachain tank account here, it could be + // easier to remember that it is the same account, but DANCE tokens are stored in + // tanssi and DOT tokens are stored in the relay chain + // TODO: and we could go a step further and set the tank address in tanssi + // equal to the relay chain, but not sure if that's a good idea + let entropy = (b"modlpy/buycoretim", para_id).using_encoded(blake2_256); + Decode::decode(&mut TrailingZeroInput::new(entropy.as_ref())) + .expect("infinite length input; no invalid inputs for type; qed") + } + + /// Returns the interior multilocation for this container chain para id. This is a relative + /// multilocation that can be used in the `descend_origin` XCM opcode. + pub fn interior_multilocation(para_id: ParaId) -> InteriorMultiLocation { + /* + // Not using this method in case another pallet also wants to use a derived account for + // a different purpose. + let interior_multilocation = + InteriorMultiLocation::X1(Junction::Parachain(para_id.into())); + */ + let container_chain_account = Self::relay_parachain_tank_id(para_id); + let account_junction = Junction::AccountId32 { + id: T::AccountIdToArray32::convert(container_chain_account), + network: None, + }; + + InteriorMultiLocation::X1(account_junction.clone()) + } + + /// Returns a multilocation that can be used in the `deposit_asset` XCM opcode. + /// The `interior_multilocation` can be obtained using `Self::interior_multilocation`. + pub fn absolute_multilocation( + interior_multilocation: InteriorMultiLocation, + ) -> MultiLocation { + let mut l = interior_multilocation; + l.push_front(Junction::Parachain(T::SelfParaId::get().into())) + .expect("multilocation too long"); + MultiLocation::from(l) + } + + fn on_collator_instantaneous_core_requested(para_id: ParaId) -> DispatchResult { + // TODO: the origin should have rights to create blocks for para_id + let withdraw_amount = T::XcmBuyExecutionDot::get(); + + // Send xcm to the relay + // Use a derivative account from the sovereign account based on the paraId + // Buy on-demand cores + // Any failure should return everything to the derivative account + + // Don't use utility::as_derivative because that will make the tanssi sovereign account + // pay for fees, instead use `DescendOrigin` to make the container chain sovereign account + // pay for fees. The container chain sovereign account is derived from the tanssi sovereign + // account. + // TODO: when coretime is implemented, buy coretime instead of buying on-demand cores + let origin = OriginKind::SovereignAccount; + // TODO: max_amount is the max price of a core that this parathread is willing to pay + // It should be defined in a storage item somewhere, contrallable by the container chain + // manager. + let max_amount = u128::MAX; + let (call, weight_at_most) = + T::GetPurchaseCoretimeCall::get_encoded(max_amount, para_id); + + // Assumption: derived account already has DOT + // The balance should be enough to cover + // TODO: we could make this be part of the proof, so collators cannot call this if the + // derived account does not have enough balance + // Although that would not be perfect, the relay state can change in the following block, + // and the xcm message will be executed in the block n+2, where n is the latest relay + // block number seen from the tanssi block that included this extrinsic. + let relay_asset_total: MultiAsset = (Here, withdraw_amount).into(); + let refund_asset_filter: MultiAssetFilter = + MultiAssetFilter::Wild(WildMultiAsset::AllCounted(1)); + // TODO: need better names for this methods. + // interior_multilocation is the one used in DescendOrigin + // absolute_multilocation is the one used in DepositAsset + // They can be easily converted from one another, the difference is that absolute_multilocation + // has an extra "Parachain" junction in the front, using SelfParaId::get() + let interior_multilocation = Self::interior_multilocation(para_id); + let derived_account = Self::absolute_multilocation(interior_multilocation); + + // Need to use `builder_unsafe` because safe `builder` does not allow `descend_origin` as first instruction + let message: Xcm<()> = Xcm::builder_unsafe() + .descend_origin(interior_multilocation) + .withdraw_asset(MultiAssets::from(vec![relay_asset_total.clone()])) + .buy_execution(relay_asset_total, Unlimited) + // Both in case of error and in case of success, we want to refund the unused weight + .set_appendix( + Xcm::builder_unsafe() + .refund_surplus() + .deposit_asset(refund_asset_filter, derived_account) + .build(), + ) + .transact(origin, weight_at_most, call.into()) + .build(); + + // Send to destination chain + let relay_chain = MultiLocation::parent(); + let (ticket, _price) = + T::XcmSender::validate(&mut Some(relay_chain), &mut Some(message)) + .map_err(|_| Error::::ErrorValidating)?; + T::XcmSender::deliver(ticket).map_err(|_| Error::::ErrorDelivering)?; + Self::deposit_event(Event::CoretimeXcmSent { para_id }); + + Ok(()) + } + } + + #[pallet::validate_unsigned] + impl ValidateUnsigned for Pallet { + type Call = Call; + + fn validate_unsigned(_source: TransactionSource, call: &Self::Call) -> TransactionValidity { + if let Call::buy_coretime { para_id, proof } = call { + /* + if >::is_online(heartbeat.authority_index) { + // we already received a heartbeat for this authority + return InvalidTransaction::Stale.into() + } + + // check if session index from heartbeat is recent + let current_session = T::ValidatorSet::session_index(); + if heartbeat.session_index != current_session { + return InvalidTransaction::Stale.into() + } + + // verify that the incoming (unverified) pubkey is actually an authority id + let keys = Keys::::get(); + if keys.len() as u32 != heartbeat.validators_len { + return InvalidTransaction::Custom(INVALID_VALIDATORS_LEN).into() + } + let authority_id = match keys.get(heartbeat.authority_index as usize) { + Some(id) => id, + None => return InvalidTransaction::BadProof.into(), + }; + + // check signature (this is expensive so we do it last). + let signature_valid = heartbeat.using_encoded(|encoded_heartbeat| { + authority_id.verify(&encoded_heartbeat, signature) + }); + + if !signature_valid { + return InvalidTransaction::BadProof.into() + } + */ + + // TODO: read session or block number + let block_number = T::GetBlockNumber::get(); + + // TODO: validate proof + let _ = proof; + + ValidTransaction::with_tag_prefix("BuyCoretime") + .priority(T::UnsignedPriority::get()) + // TODO: tags + .and_provides((block_number, para_id)) + //.and_provides((current_session, authority_id)) + //.longevity( + // TryInto::::try_into( + // T::NextSessionRotation::average_session_length() / 2u32.into(), + // ) + // .unwrap_or(64_u64), + //) + .longevity(64) + .propagate(true) + .build() + } else { + InvalidTransaction::Call.into() + } + } + } +} + +pub trait GetPurchaseCoretimeCall { + /// Get the encoded call to buy a core for this `para_id`, with this `max_amount`. + /// Returns the encoded call and its estimated weight. + fn get_encoded(max_amount: u128, para_id: ParaId) -> (Vec, Weight); +} diff --git a/pallets/xcm-core-buyer/src/mock.rs b/pallets/xcm-core-buyer/src/mock.rs new file mode 100644 index 000000000..bf321e2bb --- /dev/null +++ b/pallets/xcm-core-buyer/src/mock.rs @@ -0,0 +1,310 @@ +// Copyright (C) Moondance Labs Ltd. +// This file is part of Tanssi. + +// Tanssi is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Tanssi is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Tanssi. If not, see + +use crate::GetPurchaseCoretimeCall; +use bounded_collections::ConstU128; +use sp_runtime::traits::Convert; +use sp_runtime::BuildStorage; +use { + crate::{self as pallet_xcm_core_buyer}, + dp_core::ParaId, + frame_support::{ + pallet_prelude::*, + parameter_types, + traits::{ConstU64, EitherOfDiverse, EnsureOriginWithArg, Everything}, + }, + frame_system::{EnsureSigned, RawOrigin}, + sp_core::H256, + sp_runtime::{ + traits::{BlakeTwo256, IdentityLookup}, + Either, + }, + sp_std::collections::btree_map::BTreeMap, +}; + +type Block = frame_system::mocking::MockBlock; +pub type AccountId = u64; +pub type Balance = u128; + +// Configure a mock runtime to test the pallet. +frame_support::construct_runtime!( + pub enum Test + { + System: frame_system, + Balances: pallet_balances, + XcmCoreBuyer: pallet_xcm_core_buyer, + MockData: mock_data, + } +); + +impl frame_system::Config for Test { + type BaseCallFilter = Everything; + type Block = Block; + type BlockWeights = (); + type BlockLength = (); + type DbWeight = (); + type RuntimeOrigin = RuntimeOrigin; + type RuntimeCall = RuntimeCall; + type Nonce = u64; + type Hash = H256; + type Hashing = BlakeTwo256; + type AccountId = AccountId; + type Lookup = IdentityLookup; + type RuntimeEvent = RuntimeEvent; + type BlockHashCount = ConstU64<250>; + type Version = (); + type PalletInfo = PalletInfo; + type AccountData = pallet_balances::AccountData; + type OnNewAccount = (); + type OnKilledAccount = (); + type SystemWeightInfo = (); + type SS58Prefix = (); + type OnSetCode = (); + type MaxConsumers = ConstU32<16>; + type RuntimeTask = (); +} + +parameter_types! { + pub const ExistentialDeposit: u128 = 1; +} + +impl pallet_balances::Config for Test { + type MaxReserves = (); + type ReserveIdentifier = [u8; 4]; + type MaxLocks = (); + type Balance = Balance; + type RuntimeEvent = RuntimeEvent; + type DustRemoval = (); + type ExistentialDeposit = ExistentialDeposit; + type AccountStore = System; + type FreezeIdentifier = (); + type MaxFreezes = (); + type RuntimeHoldReason = (); + type RuntimeFreezeReason = (); + type MaxHolds = ConstU32<5>; + type WeightInfo = (); +} + +// Pallet to provide some mock data, used to test +#[frame_support::pallet] +pub mod mock_data { + use super::*; + + #[pallet::config] + pub trait Config: frame_system::Config {} + + #[pallet::call] + impl Pallet {} + + #[pallet::pallet] + #[pallet::without_storage_info] + pub struct Pallet(_); + + #[pallet::storage] + #[pallet::getter(fn mock)] + pub(super) type Mock = StorageValue<_, Mocks, ValueQuery>; + + impl Pallet { + pub fn get() -> Mocks { + Mock::::get() + } + pub fn mutate(f: F) -> R + where + F: FnOnce(&mut Mocks) -> R, + { + Mock::::mutate(f) + } + } +} + +impl mock_data::Config for Test {} + +#[derive(Clone, Encode, Decode, PartialEq, sp_core::RuntimeDebug, scale_info::TypeInfo)] +#[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))] +pub struct Mocks { + /// List of container chains, with the corresponding "manager" account. + /// In dancebox, the manager is the one who put the deposit in pallet_registrar. + /// The manager can be None if the chain was registered by root, or in genesis. + pub container_chain_managers: BTreeMap>, +} + +impl Default for Mocks { + fn default() -> Self { + Self { + container_chain_managers: BTreeMap::from_iter([(ParaId::from(1001), None)]), + } + } +} + +pub struct MockContainerChainManagerOrRootOrigin { + // Configurable root origin + container_chain_manager_origin: PhantomData, + _phantom: PhantomData, +} + +impl EnsureOriginWithArg + for MockContainerChainManagerOrRootOrigin +where + T: crate::Config, + RootOrigin: EnsureOriginWithArg, + O: From>, + Result, O>: From, + u64: From, + T::AccountId: From, + O: Clone, +{ + type Success = Either>::Success>; + + fn try_origin(o: O, para_id: &ParaId) -> Result { + let origin = EitherOfDiverse::, RootOrigin>::try_origin( + o.clone(), + para_id, + )?; + + if let Either::Left(signed_account) = &origin { + // This check will only pass if both are true: + // * The para_id has a deposit in pallet_registrar + // * The deposit creator is the signed_account + MockData::get() + .container_chain_managers + .get(para_id) + .and_then(|inner| *inner) + .and_then(|manager| { + if manager != u64::from(signed_account.clone()) { + None + } else { + Some(()) + } + }) + .ok_or(o)?; + } + + Ok(origin) + } + + #[cfg(feature = "runtime-benchmarks")] + fn try_successful_origin(para_id: &ParaId) -> Result { + // Return container chain manager, or register container chain as ALICE if it does not exist + MockData::mutate(|m| { + m.container_chain_managers + .entry(*para_id) + .or_insert_with(move || { + const ALICE: u64 = 1; + + Some(ALICE) + }); + }); + + // This panics if the container chain was registered by root (None) + let o = MockData::get() + .container_chain_managers + .get(para_id) + .unwrap() + .unwrap(); + + Ok(O::from(RawOrigin::Signed(o.into()))) + } +} + +parameter_types! { + pub const ParachainId: ParaId = ParaId::new(1000); +} + +impl pallet_xcm_core_buyer::Config for Test { + type RuntimeEvent = RuntimeEvent; + type Currency = Balances; + type XcmBuyExecutionDot = ConstU128<1_000>; + type XcmSender = (); + type GetPurchaseCoretimeCall = EncodedCallToBuyCoretime; + type GetBlockNumber = (); + type AccountIdToArray32 = AccountIdToArray32; + type SelfParaId = ParachainId; + type UnsignedPriority = (); + + type WeightInfo = (); +} + +pub struct GetBlockNumber; + +impl Get for GetBlockNumber { + fn get() -> u32 { + System::block_number() as u32 + } +} + +pub struct AccountIdToArray32; + +impl Convert for AccountIdToArray32 { + fn convert(a: u64) -> [u8; 32] { + let mut res = [0; 32]; + + res[..8].copy_from_slice(&a.to_le_bytes()); + + res + } +} + +pub struct EncodedCallToBuyCoretime; + +impl GetPurchaseCoretimeCall for EncodedCallToBuyCoretime { + fn get_encoded(_max_amount: u128, _para_id: ParaId) -> (Vec, Weight) { + let weight = Weight::from_parts(1_000_000_000, 100_000); + + let encoded_call = vec![]; + + (encoded_call, weight) + } +} + +#[derive(Default)] +pub struct ExtBuilder { + balances: Vec<(AccountId, Balance)>, +} + +impl ExtBuilder { + pub fn with_balances(mut self, balances: Vec<(AccountId, Balance)>) -> Self { + self.balances = balances; + self + } + + pub fn build(self) -> sp_io::TestExternalities { + let mut t = frame_system::GenesisConfig::::default() + .build_storage() + .unwrap(); + + pallet_balances::GenesisConfig:: { + balances: self.balances, + } + .assimilate_storage(&mut t) + .unwrap(); + + t.into() + } +} + +pub(crate) fn events() -> Vec> { + System::events() + .into_iter() + .map(|r| r.event) + .filter_map(|e| { + if let RuntimeEvent::XcmCoreBuyer(inner) = e { + Some(inner) + } else { + None + } + }) + .collect::>() +} diff --git a/pallets/xcm-core-buyer/src/tests.rs b/pallets/xcm-core-buyer/src/tests.rs new file mode 100644 index 000000000..68bd7b74d --- /dev/null +++ b/pallets/xcm-core-buyer/src/tests.rs @@ -0,0 +1,57 @@ +// Copyright (C) Moondance Labs Ltd. +// This file is part of Tanssi. + +// Tanssi is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Tanssi is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Tanssi. If not, see + +use { + crate::{mock::*, *}, + frame_support::{assert_noop, assert_ok}, + sp_runtime::traits::BadOrigin, +}; + +const ALICE: u64 = 1; + +#[test] +fn root_origin_can_force_send_xcm() { + ExtBuilder::default() + .with_balances([(ALICE, 1_000)].into()) + .build() + .execute_with(|| { + System::set_block_number(1); + let para_id = 3333.into(); + + assert_ok!(XcmCoreBuyer::force_buy_coretime( + RuntimeOrigin::root(), + para_id, + )); + + assert_eq!(events(), vec![Event::CoretimeXcmSent { para_id }]); + }); +} + +#[test] +fn signed_origin_cannot_force_send_xcm() { + ExtBuilder::default() + .with_balances([(ALICE, 1_000)].into()) + .build() + .execute_with(|| { + System::set_block_number(1); + let para_id = 3333.into(); + + assert_noop!( + XcmCoreBuyer::force_buy_coretime(RuntimeOrigin::signed(ALICE), para_id), + BadOrigin + ); + }); +} diff --git a/pallets/xcm-core-buyer/src/weights.rs b/pallets/xcm-core-buyer/src/weights.rs new file mode 100644 index 000000000..b93d57d1a --- /dev/null +++ b/pallets/xcm-core-buyer/src/weights.rs @@ -0,0 +1,103 @@ +// Copyright (C) Moondance Labs Ltd. +// This file is part of Tanssi. + +// Tanssi is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Tanssi is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Tanssi. If not, see + + +//! Autogenerated weights for pallet_data_preservers +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-12-11, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `tomasz-XPS-15-9520`, CPU: `12th Gen Intel(R) Core(TM) i7-12700H` +//! EXECUTION: , WASM-EXECUTION: Compiled, CHAIN: None, DB CACHE: 1024 + +// Executed Command: +// ./target/release/tanssi-node +// benchmark +// pallet +// --execution=wasm +// --wasm-execution=compiled +// --pallet +// pallet_data_preservers +// --extrinsic +// * +// --steps +// 50 +// --repeat +// 20 +// --template=./benchmarking/frame-weight-template.hbs +// --json-file +// raw.json +// --output +// weights.rs + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] + +use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; +use sp_std::marker::PhantomData; + +/// Weight functions needed for pallet_data_preservers. +pub trait WeightInfo { + fn set_boot_nodes(x: u32, y: u32, ) -> Weight; +} + +/// Weights for pallet_data_preservers using the Substrate node and recommended hardware. +pub struct SubstrateWeight(PhantomData); +impl WeightInfo for SubstrateWeight { + /// Storage: `Registrar::RegistrarDeposit` (r:1 w:0) + /// Proof: `Registrar::RegistrarDeposit` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `DataPreservers::BootNodes` (r:0 w:1) + /// Proof: `DataPreservers::BootNodes` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// The range of component `x` is `[1, 200]`. + /// The range of component `y` is `[1, 10]`. + fn set_boot_nodes(x: u32, y: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `195` + // Estimated: `3660` + // Minimum execution time: 10_703_000 picoseconds. + Weight::from_parts(9_788_229, 3660) + // Standard Error: 170 + .saturating_add(Weight::from_parts(7_964, 0).saturating_mul(x.into())) + // Standard Error: 3_552 + .saturating_add(Weight::from_parts(334_296, 0).saturating_mul(y.into())) + .saturating_add(T::DbWeight::get().reads(1_u64)) + .saturating_add(T::DbWeight::get().writes(1_u64)) + } +} + +// For backwards compatibility and tests +impl WeightInfo for () { + /// Storage: `Registrar::RegistrarDeposit` (r:1 w:0) + /// Proof: `Registrar::RegistrarDeposit` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `DataPreservers::BootNodes` (r:0 w:1) + /// Proof: `DataPreservers::BootNodes` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// The range of component `x` is `[1, 200]`. + /// The range of component `y` is `[1, 10]`. + fn set_boot_nodes(x: u32, y: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `195` + // Estimated: `3660` + // Minimum execution time: 10_703_000 picoseconds. + Weight::from_parts(9_788_229, 3660) + // Standard Error: 170 + .saturating_add(Weight::from_parts(7_964, 0).saturating_mul(x.into())) + // Standard Error: 3_552 + .saturating_add(Weight::from_parts(334_296, 0).saturating_mul(y.into())) + .saturating_add(RocksDbWeight::get().reads(1_u64)) + .saturating_add(RocksDbWeight::get().writes(1_u64)) + } +} diff --git a/runtime/dancebox/Cargo.toml b/runtime/dancebox/Cargo.toml index 9205d7951..7847636bc 100644 --- a/runtime/dancebox/Cargo.toml +++ b/runtime/dancebox/Cargo.toml @@ -27,6 +27,7 @@ pallet-author-noting = { workspace = true } pallet-author-noting-runtime-api = { workspace = true } pallet-authority-assignment = { workspace = true } pallet-authority-mapping = { workspace = true } +pallet-xcm-core-buyer = { workspace = true } pallet-collator-assignment = { workspace = true } pallet-collator-assignment-runtime-api = { workspace = true } pallet-configuration = { workspace = true } @@ -120,8 +121,6 @@ frame-system-benchmarking = { workspace = true, optional = true } frame-try-runtime = { workspace = true, optional = true } [dev-dependencies] -# Needed to force include the runtime-benchmark feature as emulated-integration-tests-common -# hasn't implemented that feature assets-common = { workspace = true } container-chain-template-frontier-runtime = { workspace = true, features = [ "std" ] } container-chain-template-simple-runtime = { workspace = true, features = [ "std" ] } @@ -131,13 +130,15 @@ emulated-integration-tests-common = { workspace = true } pallet-staking = { workspace = true, features = [ "std" ] } polkadot-runtime-parachains = { workspace = true, features = [ "std" ] } polkadot-service = { workspace = true } +rococo-runtime = { workspace = true } +rococo-runtime-constants = { workspace = true } sc-consensus-grandpa = { workspace = true } sc-service = { workspace = true } sp-consensus-babe = { workspace = true, features = [ "std" ] } sp-consensus-beefy = { workspace = true, features = [ "std" ] } sp-io = { workspace = true } test-relay-sproof-builder = { workspace = true } -westend-runtime = { workspace = true, features = [ "std" ] } +westend-runtime = { workspace = true } westend-runtime-constants = { workspace = true } xcm-emulator = { workspace = true } @@ -219,6 +220,7 @@ std = [ "polkadot-parachain-primitives/std", "polkadot-runtime-common/std", "polkadot-runtime-parachains/std", + "rococo-runtime/std", "runtime-common/std", "scale-info/std", "serde", @@ -253,6 +255,7 @@ std = [ "westend-runtime-constants/std", "westend-runtime/std", "xcm-primitives/std", + "pallet-xcm-core-buyer/std" ] # Allow to print logs details (no wasm:stripped) @@ -317,6 +320,8 @@ runtime-benchmarks = [ "tp-traits/runtime-benchmarks", "westend-runtime/runtime-benchmarks", "xcm-primitives/runtime-benchmarks", + "pallet-xcm-core-buyer/runtime-benchmarks", + "rococo-runtime/runtime-benchmarks" ] try-runtime = [ @@ -374,6 +379,8 @@ try-runtime = [ "runtime-common/try-runtime", "sp-runtime/try-runtime", "westend-runtime/try-runtime", + "pallet-xcm-core-buyer/try-runtime", + "rococo-runtime/try-runtime" ] fast-runtime = [] diff --git a/runtime/dancebox/src/lib.rs b/runtime/dancebox/src/lib.rs index a8bcd9652..af427f1f0 100644 --- a/runtime/dancebox/src/lib.rs +++ b/runtime/dancebox/src/lib.rs @@ -1638,6 +1638,7 @@ construct_runtime!( ForeignAssetsCreator: pallet_foreign_asset_creator::{Pallet, Call, Storage, Event} = 55, AssetRate: pallet_asset_rate::{Pallet, Call, Storage, Event} = 56, MessageQueue: pallet_message_queue::{Pallet, Call, Storage, Event} = 57, + BuyCoretime: pallet_xcm_core_buyer = 58, // More system support stuff RelayStorageRoots: pallet_relay_storage_roots = 60, diff --git a/runtime/dancebox/src/xcm_config.rs b/runtime/dancebox/src/xcm_config.rs index 5576fd219..384b099c3 100644 --- a/runtime/dancebox/src/xcm_config.rs +++ b/runtime/dancebox/src/xcm_config.rs @@ -14,6 +14,11 @@ // You should have received a copy of the GNU General Public License // along with Tanssi. If not, see +use frame_support::pallet_prelude::Get; +use parity_scale_codec::Encode; +use sp_runtime::traits::Convert; +use sp_runtime::transaction_validity::TransactionPriority; +use sp_std::vec::Vec; use { super::{ weights::xcm::XcmWeight as XcmGenericWeights, AccountId, AllPalletsWithSystem, AssetRate, @@ -339,6 +344,8 @@ impl pallet_asset_rate::Config for Runtime { type BenchmarkHelper = ForeignAssetBenchmarkHelper; } +use crate::System; +use pallet_xcm_core_buyer::GetPurchaseCoretimeCall; use { crate::ForeignAssets, staging_xcm_builder::{FungiblesAdapter, NoChecking}, @@ -456,3 +463,143 @@ impl pallet_message_queue::Config for Runtime { type MaxStale = sp_core::ConstU32<8>; type ServiceWeight = MessageQueueServiceWeight; } + +parameter_types! { + pub const ParasUnsignedPriority: TransactionPriority = TransactionPriority::MAX; + pub const XcmBuyExecutionDotRococo: u128 = XCM_BUY_EXECUTION_COST_ROCOCO; +} + +pub const XCM_BUY_EXECUTION_COST_ROCOCO: u128 = 50_000_000; + +impl pallet_xcm_core_buyer::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type Currency = Balances; + + // TODO: calculate weight and use rococo weight to fee + // /home/tomasz/.cargo/git/checkouts/polkadot-sdk-df3be1d6828443a1/77c5b55/polkadot/runtime/rococo/src/xcm_config.rs + /* + /// Returns weight of `weight_of_initiate_reserve_withdraw` call. + fn weight_of_initiate_reserve_withdraw() -> Weight { + let dest = MultiLocation::parent(); + + // We can use whatever asset here + let asset = MultiLocation::parent(); + + // Construct MultiAsset + let fee = MultiAsset { + id: Concrete(asset.clone()), + fun: Fungible(0), + }; + + let xcm: Xcm<()> = Xcm(vec![ + WithdrawAsset(fee.into()), + InitiateReserveWithdraw { + assets: MultiAssetFilter::Wild(All), + reserve: dest.clone(), + xcm: Xcm(vec![]), + }, + ]); + T::Weigher::weight(&mut xcm.into()).map_or(Weight::max_value(), |w| { + T::BaseXcmWeight::get().saturating_add(w) + }) + } + + */ + // TODO: this depends on the relay + type XcmBuyExecutionDot = XcmBuyExecutionDotRococo; + type XcmSender = XcmRouter; + type GetPurchaseCoretimeCall = EncodedCallToBuyCoretime; + type GetBlockNumber = GetBlockNumber; + type AccountIdToArray32 = AccountIdToArray32; + type SelfParaId = parachain_info::Pallet; + type UnsignedPriority = ParasUnsignedPriority; + + type WeightInfo = (); +} + +pub struct GetBlockNumber; + +impl Get for GetBlockNumber { + fn get() -> u32 { + System::block_number() + } +} + +pub struct AccountIdToArray32; + +impl Convert for AccountIdToArray32 { + fn convert(a: AccountId) -> [u8; 32] { + a.into() + } +} + +pub struct EncodedCallToBuyCoretime; + +impl GetPurchaseCoretimeCall for EncodedCallToBuyCoretime { + fn get_encoded(max_amount: u128, para_id: ParaId) -> (Vec, Weight) { + // TODO: this should use westend_runtime, but the polkadot 1.6.0 release does not have this pallet yet... + // TODO: this should depend on the relay chain defined in the chain spec, can we do that? + // probably the best solution would be to default to westend and use a storage item to override it + // so that we can set rococo for tests + // TODO: return weight of parachains_assigner_on_demand::Call::place_order_allow_death + let weight = Weight::from_parts(1_000_000_000, 100_000); + + // TODO: use place_order_keep_alive? + let call = rococo_calls::RelayCall::OnDemandAssignmentProvider( + rococo_calls::OnDemandAssignmentProviderCall::PlaceOrderAllowDeath { + max_amount, + para_id, + }, + ); + + (call.encode(), weight) + } +} + +// TODO: create a crate for rococo_calls +pub mod rococo_calls { + use super::*; + pub type Balance = u128; + + #[derive(Encode)] + pub enum RelayCall { + #[codec(index = 66u8)] + OnDemandAssignmentProvider(OnDemandAssignmentProviderCall), + } + + #[derive(Encode)] + pub enum OnDemandAssignmentProviderCall { + #[codec(index = 0u8)] + PlaceOrderAllowDeath { + max_amount: Balance, + para_id: ParaId, + }, + } + + #[cfg(test)] + mod tests { + use super::*; + use polkadot_runtime_parachains::assigner_on_demand as parachains_assigner_on_demand; + + #[test] + fn encode_place_order_allow_death() { + let max_amount = u128::MAX; + let para_id = u32::MAX.into(); + let call = rococo_runtime::RuntimeCall::OnDemandAssignmentProvider( + parachains_assigner_on_demand::Call::place_order_allow_death { + max_amount, + para_id, + }, + ); + let call2 = RelayCall::OnDemandAssignmentProvider( + OnDemandAssignmentProviderCall::PlaceOrderAllowDeath { + max_amount, + para_id, + }, + ); + + // If this fails check if indices changed + assert_eq!(call.encode(), call2.encode()); + } + } +} diff --git a/runtime/dancebox/tests/common/xcm/constants.rs b/runtime/dancebox/tests/common/xcm/constants.rs index 5acd6c0d3..e7619f2fc 100644 --- a/runtime/dancebox/tests/common/xcm/constants.rs +++ b/runtime/dancebox/tests/common/xcm/constants.rs @@ -199,6 +199,99 @@ pub mod westend { } } +// Rococo +pub mod rococo { + use polkadot_parachain_primitives::primitives::ValidationCode; + use polkadot_runtime_parachains::paras::{ParaGenesisArgs, ParaKind}; + use { + super::*, cumulus_primitives_core::relay_chain::BlockNumber, + polkadot_runtime_parachains::configuration::HostConfiguration, + rococo_runtime_constants::currency::UNITS as ROC, + }; + const ENDOWMENT: u128 = 1_000_000 * ROC; + + pub fn get_host_config() -> HostConfiguration { + HostConfiguration { + max_upward_queue_count: 10, + max_upward_queue_size: 51200, + max_upward_message_size: 51200, + max_upward_message_num_per_candidate: 10, + max_downward_message_size: 51200, + ..Default::default() + } + } + + fn session_keys( + babe: BabeId, + grandpa: GrandpaId, + para_validator: ValidatorId, + para_assignment: AssignmentId, + authority_discovery: AuthorityDiscoveryId, + beefy: BeefyId, + ) -> rococo_runtime::SessionKeys { + rococo_runtime::SessionKeys { + babe, + grandpa, + para_validator, + para_assignment, + authority_discovery, + beefy, + } + } + + pub fn genesis() -> Storage { + let genesis_config = rococo_runtime::RuntimeGenesisConfig { + balances: rococo_runtime::BalancesConfig { + balances: accounts::init_balances() + .iter() + .cloned() + .map(|k| (k, crate::common::xcm::constants::rococo::ENDOWMENT)) + .collect(), + }, + session: rococo_runtime::SessionConfig { + keys: validators::initial_authorities() + .iter() + .map(|x| { + ( + x.0.clone(), + x.0.clone(), + crate::common::xcm::constants::rococo::session_keys( + x.2.clone(), + x.3.clone(), + x.4.clone(), + x.5.clone(), + x.6.clone(), + get_from_seed::("Alice"), + ), + ) + }) + .collect::>(), + }, + babe: rococo_runtime::BabeConfig { + authorities: Default::default(), + epoch_config: Some(rococo_runtime::BABE_GENESIS_EPOCH_CONFIG), + ..Default::default() + }, + configuration: rococo_runtime::ConfigurationConfig { + config: crate::common::xcm::constants::rococo::get_host_config(), + }, + paras: rococo_runtime::ParasConfig { + _config: Default::default(), + paras: vec![( + 3333.into(), + ParaGenesisArgs { + genesis_head: Default::default(), + validation_code: ValidationCode(vec![1, 1, 2, 3, 4]), + para_kind: ParaKind::Parathread, + }, + )], + }, + ..Default::default() + }; + build_genesis_storage(&genesis_config, rococo_runtime::WASM_BINARY.unwrap()) + } +} + // Frontier template pub mod frontier_template { use { diff --git a/runtime/dancebox/tests/common/xcm/core_buyer.rs b/runtime/dancebox/tests/common/xcm/core_buyer.rs new file mode 100644 index 000000000..2c506e867 --- /dev/null +++ b/runtime/dancebox/tests/common/xcm/core_buyer.rs @@ -0,0 +1,410 @@ +// Copyright (C) Moondance Labs Ltd. +// This file is part of Tanssi. + +// Tanssi is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Tanssi is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Tanssi. If not, see + +use crate::common::xcm::mocknets::RococoSender; +use crate::common::xcm::*; +use dancebox_runtime::BuyCoretime; +use polkadot_runtime_parachains::assigner_on_demand as parachains_assigner_on_demand; +use sp_runtime::AccountId32; +use tp_traits::ParaId; +use xcm_emulator::RelayChain; +use { + crate::common::xcm::mocknets::{ + DanceboxRococoPara as Dancebox, RococoRelay as Rococo, RococoRelayPallet, + }, + frame_support::assert_ok, + staging_xcm_executor::traits::ConvertLocation, + xcm_emulator::Chain, +}; + +const PARATHREAD_ID: u32 = 3333; +const ROCOCO_ED: u128 = rococo_runtime_constants::currency::EXISTENTIAL_DEPOSIT; +const BUY_EXECUTION_COST: u128 = dancebox_runtime::xcm_config::XCM_BUY_EXECUTION_COST_ROCOCO; +// Difference between BUY_EXECUTION_COST and the actual cost that depends on the weight of the XCM +// message, gets refunded. +const BUY_EXECUTION_REFUND: u128 = 5115980; + +#[test] +fn constants() { + // If these constants change, some tests may break + assert_eq!(ROCOCO_ED, 100_000_000 / 3); + assert_eq!(BUY_EXECUTION_COST, 50_000_000); +} + +// TODO: modify tests to assert that the OnDemandOrderPlaced event was not emitted +// when it shouldn't + +/// The tests in this module all use this function to trigger an XCM message to buy a core. +/// +/// Each test has a different value of +/// * tank_account_balance: the balance of the parachain tank account in the relay chain +/// * spot_price: the price of a core +fn do_test(tank_account_balance: u128) { + // Get parathread tank address in relay chain. This is derived from the Dancebox para id and the + // parathread para id. + let parathread_tank_in_relay = Dancebox::execute_with(|| { + let parathread_tank_multilocation = BuyCoretime::absolute_multilocation( + BuyCoretime::interior_multilocation(PARATHREAD_ID.into()), + ); + let parathread_tank_in_relay = + ::SovereignAccountOf::convert_location( + ¶thread_tank_multilocation, + ) + .expect("probably this relay chain does not allow DescendOrigin"); + + parathread_tank_in_relay + }); + + // Pre-fund container chain tank in Relay Chain + Rococo::execute_with(|| { + let alice_origin = ::RuntimeOrigin::signed(RococoSender::get()); + let destination = sp_runtime::MultiAddress::Id(parathread_tank_in_relay.clone()); + let value = tank_account_balance; + + // Add funds to parathread tank account in relay + if value != 0 { + assert_ok!( + ::Balances::transfer_keep_alive( + alice_origin, + destination, + value + ) + ); + } + }); + + // If this test fails, uncomment this and try to debug the call without XCM first. + /* + Rococo::execute_with(|| { + let alice_origin = ::RuntimeOrigin::signed(RococoSender::get()); + let max_amount = u128::MAX; + let para_id = PARATHREAD_ID.into(); + assert_ok!( + ::OnDemandAssignmentProvider::place_order_allow_death( + alice_origin, + max_amount, + para_id, + ) + ); + }); + */ + + // Send XCM message from Dancebox pallet BuyCoretime + Dancebox::execute_with(|| { + let root_origin = ::RuntimeOrigin::root(); + assert_ok!(BuyCoretime::force_buy_coretime( + root_origin, + PARATHREAD_ID.into() + )); + + type RuntimeEvent = ::RuntimeEvent; + assert_expected_events!( + Dancebox, + vec![ + RuntimeEvent::BuyCoretime( + pallet_xcm_core_buyer::Event::CoretimeXcmSent { para_id } + ) => { + para_id: *para_id == ParaId::from(PARATHREAD_ID), + }, + ] + ); + }); +} + +fn assert_relay_order_event_not_emitted() { + type RuntimeEvent = ::RuntimeEvent; + + let events = ::events(); + for event in events { + match event { + RuntimeEvent::OnDemandAssignmentProvider( + parachains_assigner_on_demand::Event::OnDemandOrderPlaced { .. }, + ) => { + panic!("Event should not have been emitted: {:?}", event); + } + _ => (), + } + } + // OnDemandOrderPlaced +} + +fn get_parathread_tank_relay_address() -> AccountId32 { + let parathread_tank_in_relay = Dancebox::execute_with(|| { + let parathread_tank_multilocation = BuyCoretime::absolute_multilocation( + BuyCoretime::interior_multilocation(PARATHREAD_ID.into()), + ); + let parathread_tank_in_relay = + ::SovereignAccountOf::convert_location( + ¶thread_tank_multilocation, + ) + .expect("probably this relay chain does not allow DescendOrigin"); + + parathread_tank_in_relay + }); + parathread_tank_in_relay +} + +fn get_on_demand_base_fee() -> u128 { + Rococo::execute_with(|| { + let config = ::Configuration::config(); + + config.on_demand_base_fee + }) +} + +fn set_on_demand_base_fee(on_demand_base_fee: u128) { + Rococo::execute_with(|| { + let mut config = ::Configuration::config(); + config.on_demand_base_fee = on_demand_base_fee; + ::Configuration::force_set_active_config(config); + }); +} + +#[test] +fn xcm_core_buyer_zero_balance() { + let parathread_tank_in_relay = get_parathread_tank_relay_address(); + let balance_before = 0; + + // Invariant: if balance_before < BUY_EXECUTION_COST, then balance_after == balance_before + do_test(balance_before); + + // Receive XCM message in Relay Chain + Rococo::execute_with(|| { + type RuntimeEvent = ::RuntimeEvent; + let balance_after = + ::System::account(parathread_tank_in_relay.clone()) + .data + .free; + assert_expected_events!( + Rococo, + vec![ + RuntimeEvent::MessageQueue(pallet_message_queue::Event::Processed { success: false, .. }) => {}, + ] + ); + assert_relay_order_event_not_emitted(); + assert_eq!(balance_before, balance_after); + }); +} + +#[test] +fn xcm_core_buyer_only_enough_balance_for_buy_execution() { + let parathread_tank_in_relay = get_parathread_tank_relay_address(); + let balance_before = BUY_EXECUTION_COST; + + // Invariant: if balance_before >= BUY_EXECUTION_COST then balance_after <= (balance_before - BUY_EXECUTION_COST) + do_test(balance_before); + + // Receive XCM message in Relay Chain + Rococo::execute_with(|| { + type RuntimeEvent = ::RuntimeEvent; + let balance_after = + ::System::account(parathread_tank_in_relay.clone()) + .data + .free; + assert_expected_events!( + Rococo, + vec![ + RuntimeEvent::Balances( + pallet_balances::Event::Withdraw { + who, + amount: BUY_EXECUTION_COST, + } + ) => { + who: *who == parathread_tank_in_relay, + }, + RuntimeEvent::System( + frame_system::Event::KilledAccount { + account, + } + ) => { + account: *account == parathread_tank_in_relay, + }, + RuntimeEvent::MessageQueue(pallet_message_queue::Event::Processed { success: true, .. }) => {}, + ] + ); + assert_relay_order_event_not_emitted(); + assert_eq!(balance_after, 0); + }); +} + +#[test] +fn xcm_core_buyer_enough_balance_except_for_existential_deposit() { + let parathread_tank_in_relay = get_parathread_tank_relay_address(); + // Core price must be greater than existential deposit + let spot_price = ROCOCO_ED + 1; + set_on_demand_base_fee(spot_price); + let spot_price2 = spot_price; + let balance_before = BUY_EXECUTION_COST + spot_price; + + do_test(balance_before); + + // Receive XCM message in Relay Chain + Rococo::execute_with(|| { + type RuntimeEvent = ::RuntimeEvent; + + let balance_after = + ::System::account(parathread_tank_in_relay.clone()) + .data + .free; + assert_expected_events!( + Rococo, + vec![ + RuntimeEvent::Balances( + pallet_balances::Event::Withdraw { + who, + amount: BUY_EXECUTION_COST, + } + ) => { + who: *who == parathread_tank_in_relay, + }, + RuntimeEvent::Balances( + pallet_balances::Event::Withdraw { + who, + amount, + } + ) => { + who: *who == parathread_tank_in_relay, + amount: *amount == spot_price, + }, + RuntimeEvent::System( + frame_system::Event::KilledAccount { + account, + } + ) => { + account: *account == parathread_tank_in_relay, + }, + RuntimeEvent::OnDemandAssignmentProvider( + parachains_assigner_on_demand::Event::OnDemandOrderPlaced { + para_id, + spot_price, + } + ) => { + para_id: *para_id == ParaId::from(PARATHREAD_ID), + spot_price: *spot_price == spot_price2, + }, + RuntimeEvent::MessageQueue(pallet_message_queue::Event::Processed { success: true, .. }) => {}, + ] + ); + assert_eq!(balance_after, 0); + }); +} + +#[test] +fn xcm_core_buyer_enough_balance() { + let parathread_tank_in_relay = get_parathread_tank_relay_address(); + let spot_price = get_on_demand_base_fee(); + let spot_price2 = spot_price; + let balance_before = ROCOCO_ED + BUY_EXECUTION_COST + spot_price + 1; + + do_test(balance_before); + + // Receive XCM message in Relay Chain + Rococo::execute_with(|| { + type RuntimeEvent = ::RuntimeEvent; + + let balance_after = + ::System::account(parathread_tank_in_relay.clone()) + .data + .free; + assert_expected_events!( + Rococo, + vec![ + RuntimeEvent::Balances( + pallet_balances::Event::Withdraw { + who, + amount: BUY_EXECUTION_COST, + } + ) => { + who: *who == parathread_tank_in_relay, + }, + RuntimeEvent::Balances( + pallet_balances::Event::Withdraw { + who, + amount, + } + ) => { + who: *who == parathread_tank_in_relay, + amount: *amount == spot_price, + }, + RuntimeEvent::OnDemandAssignmentProvider( + parachains_assigner_on_demand::Event::OnDemandOrderPlaced { + para_id, + spot_price, + } + ) => { + para_id: *para_id == ParaId::from(PARATHREAD_ID), + spot_price: *spot_price == spot_price2, + }, + RuntimeEvent::Balances( + pallet_balances::Event::Deposit { + who, + amount: BUY_EXECUTION_REFUND, + } + ) => { + who: *who == parathread_tank_in_relay, + }, + RuntimeEvent::MessageQueue(pallet_message_queue::Event::Processed { success: true, .. }) => {}, + ] + ); + assert_eq!(balance_after, ROCOCO_ED + 1 + BUY_EXECUTION_REFUND); + }); +} + +#[test] +fn xcm_core_buyer_core_too_expensive() { + let parathread_tank_in_relay = get_parathread_tank_relay_address(); + let balance_before = ROCOCO_ED + BUY_EXECUTION_COST + 1; + set_on_demand_base_fee(balance_before * 2); + + do_test(balance_before); + + // Receive XCM message in Relay Chain + Rococo::execute_with(|| { + type RuntimeEvent = ::RuntimeEvent; + + let balance_after = + ::System::account(parathread_tank_in_relay.clone()) + .data + .free; + assert_expected_events!( + Rococo, + vec![ + RuntimeEvent::Balances( + pallet_balances::Event::Withdraw { + who, + amount: BUY_EXECUTION_COST, + } + ) => { + who: *who == parathread_tank_in_relay, + }, + RuntimeEvent::Balances( + pallet_balances::Event::Deposit { + who, + amount: BUY_EXECUTION_REFUND, + } + ) => { + who: *who == parathread_tank_in_relay, + }, + RuntimeEvent::MessageQueue(pallet_message_queue::Event::Processed { success: true, .. }) => {}, + ] + ); + assert_relay_order_event_not_emitted(); + assert_eq!( + balance_after, + balance_before + BUY_EXECUTION_REFUND - BUY_EXECUTION_COST + ); + }); +} diff --git a/runtime/dancebox/tests/common/xcm/mocknets.rs b/runtime/dancebox/tests/common/xcm/mocknets.rs index fd75be072..39f1b45b6 100644 --- a/runtime/dancebox/tests/common/xcm/mocknets.rs +++ b/runtime/dancebox/tests/common/xcm/mocknets.rs @@ -17,7 +17,7 @@ pub use sp_core::Get; use { super::constants::{ accounts::{ALICE, BOB, RANDOM}, - frontier_template, simple_template, westend, + frontier_template, rococo, simple_template, westend, }, emulated_integration_tests_common::{ impl_assert_events_helpers_for_parachain, xcm_emulator::decl_test_parachains, @@ -47,6 +47,26 @@ decl_test_relay_chains! { XcmPallet: westend_runtime::XcmPallet, Sudo: westend_runtime::Sudo, } + }, + #[api_version(10)] + pub struct Rococo { + genesis = rococo::genesis(), + on_init = (), + runtime = rococo_runtime, + core = { + SovereignAccountOf: rococo_runtime::xcm_config::LocationConverter, //TODO: rename to SovereignAccountOf, + }, + pallets = { + System: rococo_runtime::System, + Session: rococo_runtime::Session, + Configuration: rococo_runtime::Configuration, + Balances: rococo_runtime::Balances, + Registrar: rococo_runtime::Registrar, + ParasSudoWrapper: rococo_runtime::ParasSudoWrapper, + OnDemandAssignmentProvider: rococo_runtime::OnDemandAssignmentProvider, + XcmPallet: rococo_runtime::XcmPallet, + Sudo: rococo_runtime::Sudo, + } } } @@ -136,6 +156,93 @@ decl_test_parachains! { AssetRate: container_chain_template_simple_runtime::AssetRate, ForeignAssetsCreator: container_chain_template_simple_runtime::ForeignAssetsCreator, } + }, + + // Parachains + pub struct DanceboxRococo { + genesis = crate::ExtBuilder::default() + .with_balances(vec![ + // Alice gets 10k extra tokens for her mapping deposit + (crate::AccountId::from(crate::ALICE), 210_000 * crate::UNIT), + (crate::AccountId::from(crate::BOB), 100_000 * crate::UNIT), + // Give some balance to the relay chain account + (ParentIsPreset::::convert_location(&MultiLocation::parent()).unwrap(), 100_000 * crate::UNIT), + // And to sovereigns + ( + SiblingParachainConvertsVia::::convert_location( + &MultiLocation{ parents: 1, interior: X1(Parachain(2001u32))} + ).unwrap(), 100_000 * crate::UNIT + ), + ( + SiblingParachainConvertsVia::::convert_location( + &MultiLocation{ parents: 1, interior: X1(Parachain(2002u32))} + ).unwrap(), 100_000 * crate::UNIT + ), + + + ]) + .with_safe_xcm_version(3) + .with_own_para_id(2000u32.into()) + .build_storage(), + on_init = { + dancebox_runtime::System::deposit_log(DigestItem::PreRuntime(AURA_ENGINE_ID, 0u64.encode())); + }, + runtime = dancebox_runtime, + core = { + XcmpMessageHandler: dancebox_runtime::XcmpQueue, + LocationToAccountId: dancebox_runtime::xcm_config::LocationToAccountId, + ParachainInfo: dancebox_runtime::ParachainInfo, + MessageOrigin: cumulus_primitives_core::AggregateMessageOrigin, + }, + pallets = { + System: dancebox_runtime::System, + Balances: dancebox_runtime::Balances, + ParachainSystem: dancebox_runtime::ParachainSystem, + PolkadotXcm: dancebox_runtime::PolkadotXcm, + ForeignAssets: dancebox_runtime::ForeignAssets, + AssetRate: dancebox_runtime::AssetRate, + ForeignAssetsCreator: dancebox_runtime::ForeignAssetsCreator, + } + }, + pub struct FrontierTemplateRococo { + genesis = frontier_template::genesis(), + on_init = (), + runtime = container_chain_template_frontier_runtime, + core = { + XcmpMessageHandler: container_chain_template_frontier_runtime::XcmpQueue, + LocationToAccountId: container_chain_template_frontier_runtime::xcm_config::LocationToAccountId, + ParachainInfo: container_chain_template_frontier_runtime::ParachainInfo, + MessageOrigin: cumulus_primitives_core::AggregateMessageOrigin, + }, + pallets = { + System: container_chain_template_frontier_runtime::System, + Balances: container_chain_template_frontier_runtime::Balances, + ParachainSystem: container_chain_template_frontier_runtime::ParachainSystem, + PolkadotXcm: container_chain_template_frontier_runtime::PolkadotXcm, + ForeignAssets: container_chain_template_frontier_runtime::ForeignAssets, + AssetRate: container_chain_template_frontier_runtime::AssetRate, + ForeignAssetsCreator: container_chain_template_frontier_runtime::ForeignAssetsCreator, + } + }, + pub struct SimpleTemplateRococo { + genesis = simple_template::genesis(), + on_init = (), + runtime = container_chain_template_simple_runtime, + core = { + XcmpMessageHandler: container_chain_template_simple_runtime::XcmpQueue, + LocationToAccountId: container_chain_template_simple_runtime::xcm_config::LocationToAccountId, + ParachainInfo: container_chain_template_simple_runtime::ParachainInfo, + MessageOrigin: cumulus_primitives_core::AggregateMessageOrigin, + }, + pallets = { + System: container_chain_template_simple_runtime::System, + Balances: container_chain_template_simple_runtime::Balances, + ParachainSystem: container_chain_template_simple_runtime::ParachainSystem, + PolkadotXcm: container_chain_template_simple_runtime::PolkadotXcm, + ForeignAssets: container_chain_template_simple_runtime::ForeignAssets, + AssetRate: container_chain_template_simple_runtime::AssetRate, + ForeignAssetsCreator: container_chain_template_simple_runtime::ForeignAssetsCreator, + } } } @@ -152,6 +259,15 @@ decl_test_networks! { SimpleTemplate, ], bridge = () + }, + pub struct RococoMockNet { + relay_chain = Rococo, + parachains = vec![ + DanceboxRococo, + FrontierTemplateRococo, + SimpleTemplateRococo, + ], + bridge = () } } @@ -160,6 +276,12 @@ parameter_types! { pub WestendSender: cumulus_primitives_core::relay_chain::AccountId = WestendRelay::account_id_of(ALICE); pub WestendReceiver: cumulus_primitives_core::relay_chain::AccountId = WestendRelay::account_id_of(BOB); pub WestendEmptyReceiver: cumulus_primitives_core::relay_chain::AccountId = WestendRelay::account_id_of(RANDOM); + + // Rococo + pub RococoSender: cumulus_primitives_core::relay_chain::AccountId = RococoRelay::account_id_of(ALICE); + pub RococoReceiver: cumulus_primitives_core::relay_chain::AccountId = RococoRelay::account_id_of(BOB); + pub RococoEmptyReceiver: cumulus_primitives_core::relay_chain::AccountId = RococoRelay::account_id_of(RANDOM); + // Dancebox pub DanceboxSender: dancebox_runtime::AccountId = crate::AccountId::from(crate::ALICE); pub DanceboxReceiver: dancebox_runtime::AccountId = crate::AccountId::from(crate::BOB); diff --git a/runtime/dancebox/tests/common/xcm/mod.rs b/runtime/dancebox/tests/common/xcm/mod.rs index b39330064..c1e61a858 100644 --- a/runtime/dancebox/tests/common/xcm/mod.rs +++ b/runtime/dancebox/tests/common/xcm/mod.rs @@ -15,6 +15,7 @@ // along with Tanssi. If not, see mod constants; +mod core_buyer; mod foreign_signed_based_sovereign; mod foreign_sovereigns; mod mocknets; From 568562d2ead5a5bab8f0f7b61e16f4e173b9a887 Mon Sep 17 00:00:00 2001 From: Tomasz Polaczyk Date: Wed, 13 Mar 2024 14:40:57 +0100 Subject: [PATCH 02/17] Add more validations and more tests --- pallets/data-preservers/src/lib.rs | 2 +- pallets/inflation-rewards/src/lib.rs | 2 +- pallets/xcm-core-buyer/src/lib.rs | 130 ++++++++++++--- pallets/xcm-core-buyer/src/mock.rs | 157 ++++++++---------- pallets/xcm-core-buyer/src/tests.rs | 100 +++++++++-- runtime/dancebox/src/lib.rs | 2 +- runtime/dancebox/src/xcm_config.rs | 40 ++++- .../dancebox/tests/common/xcm/core_buyer.rs | 62 ++++--- runtime/dancebox/tests/common/xcm/mocknets.rs | 15 +- 9 files changed, 353 insertions(+), 157 deletions(-) diff --git a/pallets/data-preservers/src/lib.rs b/pallets/data-preservers/src/lib.rs index a3235cae9..af97830ec 100644 --- a/pallets/data-preservers/src/lib.rs +++ b/pallets/data-preservers/src/lib.rs @@ -89,7 +89,7 @@ pub mod pallet { /// Data preservers pallet. #[pallet::pallet] #[pallet::without_storage_info] - pub struct Pallet(core::marker::PhantomData); + pub struct Pallet(PhantomData); #[pallet::config] pub trait Config: frame_system::Config { diff --git a/pallets/inflation-rewards/src/lib.rs b/pallets/inflation-rewards/src/lib.rs index fb2456a9f..fdd5a4fcb 100644 --- a/pallets/inflation-rewards/src/lib.rs +++ b/pallets/inflation-rewards/src/lib.rs @@ -57,7 +57,7 @@ pub mod pallet { /// Inflation rewards pallet. #[pallet::pallet] #[pallet::without_storage_info] - pub struct Pallet(core::marker::PhantomData); + pub struct Pallet(PhantomData); #[pallet::hooks] impl Hooks> for Pallet { diff --git a/pallets/xcm-core-buyer/src/lib.rs b/pallets/xcm-core-buyer/src/lib.rs index ceec6f485..db1bd8493 100644 --- a/pallets/xcm-core-buyer/src/lib.rs +++ b/pallets/xcm-core-buyer/src/lib.rs @@ -52,11 +52,12 @@ use { pub mod pallet { use super::*; use sp_runtime::traits::TrailingZeroInput; + use tp_traits::ParathreadParams; /// Data preservers pallet. #[pallet::pallet] #[pallet::without_storage_info] - pub struct Pallet(core::marker::PhantomData); + pub struct Pallet(PhantomData); #[pallet::config] pub trait Config: frame_system::Config { @@ -66,11 +67,16 @@ pub mod pallet { type XcmBuyExecutionDot: Get; type XcmSender: SendXcm; - type GetPurchaseCoretimeCall: GetPurchaseCoretimeCall; + type GetPurchaseCoreCall: GetPurchaseCoreCall; type GetBlockNumber: Get; // TODO: use AccountIdConversion trait here? type AccountIdToArray32: Convert; type SelfParaId: Get; + type MaxParathreads: Get; + // TODO: do not abuse Get and Convert traits + type GetParathreadParams: Convert>; + // TODO: Self::CollatorId? + type GetAssignedCollators: Convert>; /// A configuration for base priority of unsigned transactions. /// /// This is exposed so that it can be tuned for particular runtime, when @@ -85,23 +91,44 @@ pub mod pallet { #[pallet::generate_deposit(pub(super) fn deposit_event)] pub enum Event { /// An XCM message to buy a core for this parathread has been sent to the relay chain. - CoretimeXcmSent { para_id: ParaId }, + BuyCoreXcmSent { para_id: ParaId }, } #[pallet::error] pub enum Error { - NoAccountForParaId, - ErrorValidating, - ErrorDelivering, + InvalidProof, + ErrorValidatingXCM, + ErrorDeliveringXCM, + /// An order for this para id already exists + OrderAlreadyExists, + /// The para id is not a parathread + NotAParathread, + /// There are too many in-flight orders, buying cores will not work until some of those + /// orders finish. + InFlightLimitReached, + /// There are no collators assigned to this parathread, so no point in buying a core + NoAssignedCollators, + /// This collator is not assigned to this parathread + CollatorNotAssigned, } /// Proof that I am a collator, assigned to a para_id, and I can buy a core for that para_id - #[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo)] - pub struct BuyCoretimeCollatorProof { + #[derive(Encode, Decode, CloneNoBound, PartialEq, Eq, DebugNoBound, TypeInfo)] + #[scale_info(skip_type_params(T))] + pub struct BuyCoreCollatorProof { + account: T::AccountId, // TODO _signature: (), } + /// Set of parathreads that have already sent an XCM message to buy a core recently. + /// Used to avoid 2 collators buying a core at the same time, because it is only possible to buy + /// 1 core in 1 relay block. + #[pallet::storage] + //pub type InFlightOrders = StorageMap<_, Blake2_128Concat, ParaId, (), OptionQuery>; + pub type InFlightOrders = + StorageValue<_, BoundedBTreeSet, ValueQuery>; + #[pallet::call] impl Pallet { /// Buy a core for this parathread id. @@ -114,31 +141,47 @@ pub mod pallet { #[pallet::call_index(0)] // TODO: weight #[pallet::weight(T::WeightInfo::set_boot_nodes(1, 1))] - pub fn buy_coretime( + pub fn buy_core( origin: OriginFor, para_id: ParaId, // since signature verification is done in `validate_unsigned` // we can skip doing it here again. - _proof: BuyCoretimeCollatorProof, + proof: BuyCoreCollatorProof, ) -> DispatchResult { // Signature verification is done in `validate_unsigned`. // We use `ensure_none` here because this can only be called by collators, and we do not // want collators to pay fees. ensure_none(origin)?; - Self::on_collator_instantaneous_core_requested(para_id) + let assigned_collators = T::GetAssignedCollators::convert(para_id); + if assigned_collators.is_empty() { + return Err(Error::::NoAssignedCollators.into()); + } + + if !assigned_collators.contains(&proof.account) { + return Err(Error::::CollatorNotAssigned.into()); + } + + // TODO: implement proof validation + return Err(Error::::InvalidProof.into()); + + //Self::on_collator_instantaneous_core_requested(para_id) } - /// Buy coretime for para id as root. Does not require any proof, useful in tests. + /// Buy core for para id as root. Does not require any proof, useful in tests. #[pallet::call_index(1)] // TODO: weight #[pallet::weight(T::WeightInfo::set_boot_nodes(1, 1))] - pub fn force_buy_coretime(origin: OriginFor, para_id: ParaId) -> DispatchResult { + pub fn force_buy_core(origin: OriginFor, para_id: ParaId) -> DispatchResult { ensure_root(origin)?; - // TODO: check that the para_id is a parathread, and at least one collator could buy a - // core for it. Even though this extrinsic is called `force`, it should only be possible + // Check that at least one collator could buy a core for this parathread. + // Even though this extrinsic is called `force`, it should only be possible // to use it when an equivalent non-force call can be created. + let assigned_collators = T::GetAssignedCollators::convert(para_id); + if assigned_collators.is_empty() { + return Err(Error::::NoAssignedCollators.into()); + } Self::on_collator_instantaneous_core_requested(para_id) } @@ -189,6 +232,20 @@ pub mod pallet { } fn on_collator_instantaneous_core_requested(para_id: ParaId) -> DispatchResult { + let mut in_flight_orders = InFlightOrders::::get(); + if in_flight_orders.contains(¶_id) { + return Err(Error::::OrderAlreadyExists.into()); + } + in_flight_orders + .try_insert(para_id) + .map_err(|_| Error::::InFlightLimitReached)?; + + // Check that the para id is a parathread + let parathread_params = T::GetParathreadParams::convert(para_id); + if parathread_params.is_none() { + return Err(Error::::NotAParathread.into()); + } + // TODO: the origin should have rights to create blocks for para_id let withdraw_amount = T::XcmBuyExecutionDot::get(); @@ -201,14 +258,13 @@ pub mod pallet { // pay for fees, instead use `DescendOrigin` to make the container chain sovereign account // pay for fees. The container chain sovereign account is derived from the tanssi sovereign // account. - // TODO: when coretime is implemented, buy coretime instead of buying on-demand cores + // TODO: when coretime is implemented, buy core there instead of buying on-demand cores let origin = OriginKind::SovereignAccount; // TODO: max_amount is the max price of a core that this parathread is willing to pay // It should be defined in a storage item somewhere, contrallable by the container chain // manager. let max_amount = u128::MAX; - let (call, weight_at_most) = - T::GetPurchaseCoretimeCall::get_encoded(max_amount, para_id); + let (call, weight_at_most) = T::GetPurchaseCoreCall::get_encoded(max_amount, para_id); // Assumption: derived account already has DOT // The balance should be enough to cover @@ -247,20 +303,46 @@ pub mod pallet { let relay_chain = MultiLocation::parent(); let (ticket, _price) = T::XcmSender::validate(&mut Some(relay_chain), &mut Some(message)) - .map_err(|_| Error::::ErrorValidating)?; - T::XcmSender::deliver(ticket).map_err(|_| Error::::ErrorDelivering)?; - Self::deposit_event(Event::CoretimeXcmSent { para_id }); + .map_err(|_| Error::::ErrorValidatingXCM)?; + T::XcmSender::deliver(ticket).map_err(|_| Error::::ErrorDeliveringXCM)?; + Self::deposit_event(Event::BuyCoreXcmSent { para_id }); + InFlightOrders::::put(in_flight_orders); Ok(()) } } + #[pallet::hooks] + impl Hooks> for Pallet { + fn on_initialize(_n: BlockNumberFor) -> Weight { + let mut weight = Weight::zero(); + + // 1 write in on_finalize + weight += T::DbWeight::get().writes(1); + + weight + } + + fn on_finalize(_: BlockNumberFor) { + // We clear this storage item because we only need it to prevent collators from buying + // more than one core in the same relay block + // TODO: with async backing, it is possible that two tanssi blocks are included in the + // same relay block, so this kill is not correct, should only kill the storage if the + // relay block number has changed + // TODO: this allows collators to send N consecutive messages to buy 1 core for the same + // parathread, as long as the parathread block is not included in pallet_author_noting. + // So a malicious collator could drain the parathread tank account by buying cores on + // every tanssi block but not actually producing any block. + InFlightOrders::::kill(); + } + } + #[pallet::validate_unsigned] impl ValidateUnsigned for Pallet { type Call = Call; fn validate_unsigned(_source: TransactionSource, call: &Self::Call) -> TransactionValidity { - if let Call::buy_coretime { para_id, proof } = call { + if let Call::buy_core { para_id, proof } = call { /* if >::is_online(heartbeat.authority_index) { // we already received a heartbeat for this authority @@ -299,7 +381,7 @@ pub mod pallet { // TODO: validate proof let _ = proof; - ValidTransaction::with_tag_prefix("BuyCoretime") + ValidTransaction::with_tag_prefix("XcmCoreBuyer") .priority(T::UnsignedPriority::get()) // TODO: tags .and_provides((block_number, para_id)) @@ -320,7 +402,7 @@ pub mod pallet { } } -pub trait GetPurchaseCoretimeCall { +pub trait GetPurchaseCoreCall { /// Get the encoded call to buy a core for this `para_id`, with this `max_amount`. /// Returns the encoded call and its estimated weight. fn get_encoded(max_amount: u128, para_id: ParaId) -> (Vec, Weight); diff --git a/pallets/xcm-core-buyer/src/mock.rs b/pallets/xcm-core-buyer/src/mock.rs index bf321e2bb..494e75cd8 100644 --- a/pallets/xcm-core-buyer/src/mock.rs +++ b/pallets/xcm-core-buyer/src/mock.rs @@ -14,24 +14,24 @@ // You should have received a copy of the GNU General Public License // along with Tanssi. If not, see -use crate::GetPurchaseCoretimeCall; +use crate::GetPurchaseCoreCall; use bounded_collections::ConstU128; use sp_runtime::traits::Convert; use sp_runtime::BuildStorage; +use staging_xcm::latest::{ + MultiAssets, MultiLocation, SendError, SendResult, SendXcm, Xcm, XcmHash, +}; +use tp_traits::{ParathreadParams, SlotFrequency}; use { crate::{self as pallet_xcm_core_buyer}, dp_core::ParaId, frame_support::{ pallet_prelude::*, parameter_types, - traits::{ConstU64, EitherOfDiverse, EnsureOriginWithArg, Everything}, + traits::{ConstU64, Everything}, }, - frame_system::{EnsureSigned, RawOrigin}, sp_core::H256, - sp_runtime::{ - traits::{BlakeTwo256, IdentityLookup}, - Either, - }, + sp_runtime::traits::{BlakeTwo256, IdentityLookup}, sp_std::collections::btree_map::BTreeMap, }; @@ -135,87 +135,14 @@ impl mock_data::Config for Test {} #[derive(Clone, Encode, Decode, PartialEq, sp_core::RuntimeDebug, scale_info::TypeInfo)] #[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))] pub struct Mocks { - /// List of container chains, with the corresponding "manager" account. - /// In dancebox, the manager is the one who put the deposit in pallet_registrar. - /// The manager can be None if the chain was registered by root, or in genesis. - pub container_chain_managers: BTreeMap>, + pub container_chain_collators: BTreeMap>, } impl Default for Mocks { fn default() -> Self { Self { - container_chain_managers: BTreeMap::from_iter([(ParaId::from(1001), None)]), - } - } -} - -pub struct MockContainerChainManagerOrRootOrigin { - // Configurable root origin - container_chain_manager_origin: PhantomData, - _phantom: PhantomData, -} - -impl EnsureOriginWithArg - for MockContainerChainManagerOrRootOrigin -where - T: crate::Config, - RootOrigin: EnsureOriginWithArg, - O: From>, - Result, O>: From, - u64: From, - T::AccountId: From, - O: Clone, -{ - type Success = Either>::Success>; - - fn try_origin(o: O, para_id: &ParaId) -> Result { - let origin = EitherOfDiverse::, RootOrigin>::try_origin( - o.clone(), - para_id, - )?; - - if let Either::Left(signed_account) = &origin { - // This check will only pass if both are true: - // * The para_id has a deposit in pallet_registrar - // * The deposit creator is the signed_account - MockData::get() - .container_chain_managers - .get(para_id) - .and_then(|inner| *inner) - .and_then(|manager| { - if manager != u64::from(signed_account.clone()) { - None - } else { - Some(()) - } - }) - .ok_or(o)?; + container_chain_collators: BTreeMap::from_iter([(ParaId::from(3333), vec![BOB])]), } - - Ok(origin) - } - - #[cfg(feature = "runtime-benchmarks")] - fn try_successful_origin(para_id: &ParaId) -> Result { - // Return container chain manager, or register container chain as ALICE if it does not exist - MockData::mutate(|m| { - m.container_chain_managers - .entry(*para_id) - .or_insert_with(move || { - const ALICE: u64 = 1; - - Some(ALICE) - }); - }); - - // This panics if the container chain was registered by root (None) - let o = MockData::get() - .container_chain_managers - .get(para_id) - .unwrap() - .unwrap(); - - Ok(O::from(RawOrigin::Signed(o.into()))) } } @@ -227,16 +154,56 @@ impl pallet_xcm_core_buyer::Config for Test { type RuntimeEvent = RuntimeEvent; type Currency = Balances; type XcmBuyExecutionDot = ConstU128<1_000>; - type XcmSender = (); - type GetPurchaseCoretimeCall = EncodedCallToBuyCoretime; + type XcmSender = DevNull; + type GetPurchaseCoreCall = EncodedCallToBuyCore; type GetBlockNumber = (); type AccountIdToArray32 = AccountIdToArray32; type SelfParaId = ParachainId; + type MaxParathreads = ConstU32<100>; + type GetParathreadParams = GetParathreadParams; + type GetAssignedCollators = GetAssignedCollators; type UnsignedPriority = (); type WeightInfo = (); } +pub struct DevNull; +impl SendXcm for DevNull { + type Ticket = (); + fn validate(_: &mut Option, _: &mut Option>) -> SendResult<()> { + Ok(((), MultiAssets::new())) + } + fn deliver(_: ()) -> Result { + Ok([0; 32]) + } +} + +pub struct GetParathreadParams; + +impl Convert> for GetParathreadParams { + fn convert(para_id: ParaId) -> Option { + if para_id == 3333.into() { + Some(ParathreadParams { + slot_frequency: SlotFrequency { min: 10, max: 10 }, + }) + } else { + None + } + } +} + +pub struct GetAssignedCollators; + +impl Convert> for GetAssignedCollators { + fn convert(para_id: ParaId) -> Vec { + MockData::mock() + .container_chain_collators + .get(¶_id) + .cloned() + .unwrap_or_default() + } +} + pub struct GetBlockNumber; impl Get for GetBlockNumber { @@ -257,9 +224,9 @@ impl Convert for AccountIdToArray32 { } } -pub struct EncodedCallToBuyCoretime; +pub struct EncodedCallToBuyCore; -impl GetPurchaseCoretimeCall for EncodedCallToBuyCoretime { +impl GetPurchaseCoreCall for EncodedCallToBuyCore { fn get_encoded(_max_amount: u128, _para_id: ParaId) -> (Vec, Weight) { let weight = Weight::from_parts(1_000_000_000, 100_000); @@ -308,3 +275,21 @@ pub(crate) fn events() -> Vec> { }) .collect::>() } + +pub fn run_to_block(n: u64) { + let old_block_number = System::block_number(); + + for x in (old_block_number + 1)..=n { + if x > 0 { + XcmCoreBuyer::on_finalize(x - 1); + System::on_finalize(x - 1); + } + System::reset_events(); + System::set_block_number(x); + System::on_initialize(x); + XcmCoreBuyer::on_initialize(x); + } +} + +pub const ALICE: u64 = 1; +pub const BOB: u64 = 2; diff --git a/pallets/xcm-core-buyer/src/tests.rs b/pallets/xcm-core-buyer/src/tests.rs index 68bd7b74d..707e71950 100644 --- a/pallets/xcm-core-buyer/src/tests.rs +++ b/pallets/xcm-core-buyer/src/tests.rs @@ -20,38 +20,114 @@ use { sp_runtime::traits::BadOrigin, }; -const ALICE: u64 = 1; - #[test] -fn root_origin_can_force_send_xcm() { +fn root_origin_can_force_buy_xcm() { ExtBuilder::default() .with_balances([(ALICE, 1_000)].into()) .build() .execute_with(|| { - System::set_block_number(1); + run_to_block(1); let para_id = 3333.into(); - assert_ok!(XcmCoreBuyer::force_buy_coretime( - RuntimeOrigin::root(), - para_id, - )); + assert_ok!(XcmCoreBuyer::force_buy_core(RuntimeOrigin::root(), para_id,)); - assert_eq!(events(), vec![Event::CoretimeXcmSent { para_id }]); + assert_eq!(events(), vec![Event::BuyCoreXcmSent { para_id }]); }); } #[test] -fn signed_origin_cannot_force_send_xcm() { +fn signed_origin_cannot_force_buy_xcm() { ExtBuilder::default() .with_balances([(ALICE, 1_000)].into()) .build() .execute_with(|| { - System::set_block_number(1); + run_to_block(1); let para_id = 3333.into(); assert_noop!( - XcmCoreBuyer::force_buy_coretime(RuntimeOrigin::signed(ALICE), para_id), + XcmCoreBuyer::force_buy_core(RuntimeOrigin::signed(ALICE), para_id), BadOrigin ); }); } + +#[test] +fn force_buy_two_messages_in_one_block_fails() { + ExtBuilder::default() + .with_balances([(ALICE, 1_000)].into()) + .build() + .execute_with(|| { + run_to_block(1); + let para_id = 3333.into(); + + assert_ok!(XcmCoreBuyer::force_buy_core(RuntimeOrigin::root(), para_id,)); + + assert_eq!(events(), vec![Event::BuyCoreXcmSent { para_id }]); + + assert_noop!( + XcmCoreBuyer::force_buy_core(RuntimeOrigin::root(), para_id), + Error::::OrderAlreadyExists + ); + }); +} + +#[test] +fn force_buy_two_messages_in_two_consecutive_blocks_works() { + ExtBuilder::default() + .with_balances([(ALICE, 1_000)].into()) + .build() + .execute_with(|| { + run_to_block(1); + let para_id = 3333.into(); + + assert_ok!(XcmCoreBuyer::force_buy_core(RuntimeOrigin::root(), para_id,)); + + assert_eq!(events(), vec![Event::BuyCoreXcmSent { para_id }]); + + run_to_block(2); + + assert_ok!(XcmCoreBuyer::force_buy_core(RuntimeOrigin::root(), para_id,)); + + assert_eq!(events(), vec![Event::BuyCoreXcmSent { para_id }]); + }); +} + +#[test] +fn cannot_force_buy_invalid_para_id() { + ExtBuilder::default() + .with_balances([(ALICE, 1_000)].into()) + .build() + .execute_with(|| { + run_to_block(1); + let para_id = 2000.into(); + + MockData::mutate(|m| { + // Mock para_id 2000 as a container chain with collators, but not a parathread + m.container_chain_collators.insert(2000.into(), vec![ALICE]); + }); + + assert_noop!( + XcmCoreBuyer::force_buy_core(RuntimeOrigin::root(), para_id), + Error::::NotAParathread + ); + }); +} + +#[test] +fn cannot_force_buy_para_id_with_no_collators() { + ExtBuilder::default() + .with_balances([(ALICE, 1_000)].into()) + .build() + .execute_with(|| { + run_to_block(1); + let para_id = 3333.into(); + MockData::mutate(|m| { + m.container_chain_collators = Default::default(); + }); + + assert_noop!( + XcmCoreBuyer::force_buy_core(RuntimeOrigin::root(), para_id), + Error::::NoAssignedCollators + ); + }); +} diff --git a/runtime/dancebox/src/lib.rs b/runtime/dancebox/src/lib.rs index af427f1f0..326baf6d8 100644 --- a/runtime/dancebox/src/lib.rs +++ b/runtime/dancebox/src/lib.rs @@ -1638,7 +1638,7 @@ construct_runtime!( ForeignAssetsCreator: pallet_foreign_asset_creator::{Pallet, Call, Storage, Event} = 55, AssetRate: pallet_asset_rate::{Pallet, Call, Storage, Event} = 56, MessageQueue: pallet_message_queue::{Pallet, Call, Storage, Event} = 57, - BuyCoretime: pallet_xcm_core_buyer = 58, + XcmCoreBuyer: pallet_xcm_core_buyer = 58, // More system support stuff RelayStorageRoots: pallet_relay_storage_roots = 60, diff --git a/runtime/dancebox/src/xcm_config.rs b/runtime/dancebox/src/xcm_config.rs index 384b099c3..07ce1b16e 100644 --- a/runtime/dancebox/src/xcm_config.rs +++ b/runtime/dancebox/src/xcm_config.rs @@ -23,8 +23,8 @@ use { super::{ weights::xcm::XcmWeight as XcmGenericWeights, AccountId, AllPalletsWithSystem, AssetRate, Balance, Balances, ForeignAssetsCreator, MaintenanceMode, MessageQueue, ParachainInfo, - ParachainSystem, PolkadotXcm, Runtime, RuntimeBlockWeights, RuntimeCall, RuntimeEvent, - RuntimeOrigin, WeightToFee, XcmpQueue, + ParachainSystem, PolkadotXcm, Registrar, Runtime, RuntimeBlockWeights, RuntimeCall, + RuntimeEvent, RuntimeOrigin, WeightToFee, XcmpQueue, }, cumulus_primitives_core::{AggregateMessageOrigin, ParaId}, frame_support::{ @@ -344,8 +344,9 @@ impl pallet_asset_rate::Config for Runtime { type BenchmarkHelper = ForeignAssetBenchmarkHelper; } -use crate::System; -use pallet_xcm_core_buyer::GetPurchaseCoretimeCall; +use crate::{CollatorAssignment, System}; +use pallet_xcm_core_buyer::GetPurchaseCoreCall; +use tp_traits::ParathreadParams; use { crate::ForeignAssets, staging_xcm_builder::{FungiblesAdapter, NoChecking}, @@ -508,10 +509,13 @@ impl pallet_xcm_core_buyer::Config for Runtime { // TODO: this depends on the relay type XcmBuyExecutionDot = XcmBuyExecutionDotRococo; type XcmSender = XcmRouter; - type GetPurchaseCoretimeCall = EncodedCallToBuyCoretime; + type GetPurchaseCoreCall = EncodedCallToBuyCore; type GetBlockNumber = GetBlockNumber; type AccountIdToArray32 = AccountIdToArray32; type SelfParaId = parachain_info::Pallet; + type MaxParathreads = ConstU32<100>; + type GetParathreadParams = GetParathreadParams; + type GetAssignedCollators = GetAssignedCollators; type UnsignedPriority = ParasUnsignedPriority; type WeightInfo = (); @@ -525,6 +529,28 @@ impl Get for GetBlockNumber { } } +pub struct GetParathreadParams; + +impl Convert> for GetParathreadParams { + fn convert(para_id: ParaId) -> Option { + Registrar::parathread_params(para_id) + } +} + +pub struct GetAssignedCollators; + +impl Convert> for GetAssignedCollators { + fn convert(para_id: ParaId) -> Vec { + // We do not need to check if the para_id is a valid parathread, + // because that is already being checked by `GetParathreadParams`. + CollatorAssignment::collator_container_chain() + .container_chains + .get(¶_id) + .cloned() + .unwrap_or_default() + } +} + pub struct AccountIdToArray32; impl Convert for AccountIdToArray32 { @@ -533,9 +559,9 @@ impl Convert for AccountIdToArray32 { } } -pub struct EncodedCallToBuyCoretime; +pub struct EncodedCallToBuyCore; -impl GetPurchaseCoretimeCall for EncodedCallToBuyCoretime { +impl GetPurchaseCoreCall for EncodedCallToBuyCore { fn get_encoded(max_amount: u128, para_id: ParaId) -> (Vec, Weight) { // TODO: this should use westend_runtime, but the polkadot 1.6.0 release does not have this pallet yet... // TODO: this should depend on the relay chain defined in the chain spec, can we do that? diff --git a/runtime/dancebox/tests/common/xcm/core_buyer.rs b/runtime/dancebox/tests/common/xcm/core_buyer.rs index 2c506e867..23582026f 100644 --- a/runtime/dancebox/tests/common/xcm/core_buyer.rs +++ b/runtime/dancebox/tests/common/xcm/core_buyer.rs @@ -14,12 +14,13 @@ // You should have received a copy of the GNU General Public License // along with Tanssi. If not, see -use crate::common::xcm::mocknets::RococoSender; +use crate::common::xcm::mocknets::{DanceboxSender, RococoSender}; use crate::common::xcm::*; -use dancebox_runtime::BuyCoretime; +use crate::common::{dummy_boot_nodes, empty_genesis_data, run_to_session}; +use dancebox_runtime::{DataPreservers, Registrar, XcmCoreBuyer}; use polkadot_runtime_parachains::assigner_on_demand as parachains_assigner_on_demand; use sp_runtime::AccountId32; -use tp_traits::ParaId; +use tp_traits::{ParaId, SlotFrequency}; use xcm_emulator::RelayChain; use { crate::common::xcm::mocknets::{ @@ -53,22 +54,32 @@ fn constants() { /// * tank_account_balance: the balance of the parachain tank account in the relay chain /// * spot_price: the price of a core fn do_test(tank_account_balance: u128) { - // Get parathread tank address in relay chain. This is derived from the Dancebox para id and the - // parathread para id. - let parathread_tank_in_relay = Dancebox::execute_with(|| { - let parathread_tank_multilocation = BuyCoretime::absolute_multilocation( - BuyCoretime::interior_multilocation(PARATHREAD_ID.into()), - ); - let parathread_tank_in_relay = - ::SovereignAccountOf::convert_location( - ¶thread_tank_multilocation, - ) - .expect("probably this relay chain does not allow DescendOrigin"); + Dancebox::execute_with(|| { + // Register parathread + let alice_origin = ::RuntimeOrigin::signed(DanceboxSender::get()); + assert_ok!(Registrar::register_parathread( + alice_origin.clone(), + PARATHREAD_ID.into(), + SlotFrequency { min: 1, max: 1 }, + empty_genesis_data() + )); + assert_ok!(DataPreservers::set_boot_nodes( + alice_origin, + PARATHREAD_ID.into(), + dummy_boot_nodes() + )); + let root_origin = ::RuntimeOrigin::root(); + assert_ok!(Registrar::mark_valid_for_collating( + root_origin, + PARATHREAD_ID.into() + )); - parathread_tank_in_relay + run_to_session(2); }); - // Pre-fund container chain tank in Relay Chain + let parathread_tank_in_relay = get_parathread_tank_relay_address(); + + // Pre-fund parathread tank in Relay Chain Rococo::execute_with(|| { let alice_origin = ::RuntimeOrigin::signed(RococoSender::get()); let destination = sp_runtime::MultiAddress::Id(parathread_tank_in_relay.clone()); @@ -102,10 +113,10 @@ fn do_test(tank_account_balance: u128) { }); */ - // Send XCM message from Dancebox pallet BuyCoretime + // Send XCM message from Dancebox pallet XcmCoreBuyer Dancebox::execute_with(|| { let root_origin = ::RuntimeOrigin::root(); - assert_ok!(BuyCoretime::force_buy_coretime( + assert_ok!(XcmCoreBuyer::force_buy_core( root_origin, PARATHREAD_ID.into() )); @@ -114,8 +125,8 @@ fn do_test(tank_account_balance: u128) { assert_expected_events!( Dancebox, vec![ - RuntimeEvent::BuyCoretime( - pallet_xcm_core_buyer::Event::CoretimeXcmSent { para_id } + RuntimeEvent::XcmCoreBuyer( + pallet_xcm_core_buyer::Event::BuyCoreXcmSent { para_id } ) => { para_id: *para_id == ParaId::from(PARATHREAD_ID), }, @@ -141,10 +152,12 @@ fn assert_relay_order_event_not_emitted() { // OnDemandOrderPlaced } +/// Get parathread tank address in relay chain. This is derived from the Dancebox para id and the +/// parathread para id. fn get_parathread_tank_relay_address() -> AccountId32 { let parathread_tank_in_relay = Dancebox::execute_with(|| { - let parathread_tank_multilocation = BuyCoretime::absolute_multilocation( - BuyCoretime::interior_multilocation(PARATHREAD_ID.into()), + let parathread_tank_multilocation = XcmCoreBuyer::absolute_multilocation( + XcmCoreBuyer::interior_multilocation(PARATHREAD_ID.into()), ); let parathread_tank_in_relay = ::SovereignAccountOf::convert_location( @@ -204,7 +217,10 @@ fn xcm_core_buyer_only_enough_balance_for_buy_execution() { let parathread_tank_in_relay = get_parathread_tank_relay_address(); let balance_before = BUY_EXECUTION_COST; - // Invariant: if balance_before >= BUY_EXECUTION_COST then balance_after <= (balance_before - BUY_EXECUTION_COST) + // Invariant: if balance_before >= BUY_EXECUTION_COST then + // balance_after <= (balance_before + BUY_EXECUTION_REFUND - BUY_EXECUTION_COST) + // In this case the balance_after is 0 because BUY_EXECUTION_REFUND < ROCOCO_ED, + // so the account gets the refund but it is immediatelly killed. do_test(balance_before); // Receive XCM message in Relay Chain diff --git a/runtime/dancebox/tests/common/xcm/mocknets.rs b/runtime/dancebox/tests/common/xcm/mocknets.rs index 39f1b45b6..b9c99d849 100644 --- a/runtime/dancebox/tests/common/xcm/mocknets.rs +++ b/runtime/dancebox/tests/common/xcm/mocknets.rs @@ -91,8 +91,6 @@ decl_test_parachains! { &MultiLocation{ parents: 1, interior: X1(Parachain(2002u32))} ).unwrap(), 100_000 * crate::UNIT ), - - ]) .with_safe_xcm_version(3) .with_own_para_id(2000u32.into()) @@ -181,6 +179,19 @@ decl_test_parachains! { ]) + .with_collators(vec![ + (crate::AccountId::from(crate::ALICE), 210 * crate::UNIT), + (crate::AccountId::from(crate::BOB), 100 * crate::UNIT), + ]) + .with_config(pallet_configuration::HostConfiguration { + max_collators: 100, + min_orchestrator_collators: 1, + max_orchestrator_collators: 1, + collators_per_container: 1, + collators_per_parathread: 1, + full_rotation_period: 0, + ..Default::default() + }) .with_safe_xcm_version(3) .with_own_para_id(2000u32.into()) .build_storage(), From f05db9bb08a09829c083e9c6835aba59010002a5 Mon Sep 17 00:00:00 2001 From: Tomasz Polaczyk Date: Wed, 13 Mar 2024 17:51:41 +0100 Subject: [PATCH 03/17] zepter & toml-maid --- Cargo.toml | 4 ++-- pallets/xcm-core-buyer/Cargo.toml | 2 +- runtime/dancebox/Cargo.toml | 13 +++++++------ 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 4c14ee727..f13924504 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -198,11 +198,11 @@ polkadot-node-primitives = { git = "https://github.com/moondance-labs/polkadot-s polkadot-parachain-primitives = { git = "https://github.com/moondance-labs/polkadot-sdk", branch = "tanssi-polkadot-v1.6.0", default-features = false } polkadot-runtime-common = { git = "https://github.com/moondance-labs/polkadot-sdk", branch = "tanssi-polkadot-v1.6.0", default-features = false } polkadot-runtime-parachains = { git = "https://github.com/moondance-labs/polkadot-sdk", branch = "tanssi-polkadot-v1.6.0", default-features = false } +rococo-runtime = { git = "https://github.com/moondance-labs/polkadot-sdk", branch = "tanssi-polkadot-v1.6.0", default-features = false } +rococo-runtime-constants = { git = "https://github.com/moondance-labs/polkadot-sdk", branch = "tanssi-polkadot-v1.6.0", default-features = false } staging-xcm = { git = "https://github.com/moondance-labs/polkadot-sdk", branch = "tanssi-polkadot-v1.6.0", default-features = false } staging-xcm-builder = { git = "https://github.com/moondance-labs/polkadot-sdk", branch = "tanssi-polkadot-v1.6.0", default-features = false } staging-xcm-executor = { git = "https://github.com/moondance-labs/polkadot-sdk", branch = "tanssi-polkadot-v1.6.0", default-features = false } -rococo-runtime = { git = "https://github.com/moondance-labs/polkadot-sdk", branch = "tanssi-polkadot-v1.6.0", default-features = false } -rococo-runtime-constants = { git = "https://github.com/moondance-labs/polkadot-sdk", branch = "tanssi-polkadot-v1.6.0", default-features = false } westend-runtime = { git = "https://github.com/moondance-labs/polkadot-sdk", branch = "tanssi-polkadot-v1.6.0", default-features = false } westend-runtime-constants = { git = "https://github.com/moondance-labs/polkadot-sdk", branch = "tanssi-polkadot-v1.6.0", default-features = false } diff --git a/pallets/xcm-core-buyer/Cargo.toml b/pallets/xcm-core-buyer/Cargo.toml index 14a54a149..fe4a69424 100644 --- a/pallets/xcm-core-buyer/Cargo.toml +++ b/pallets/xcm-core-buyer/Cargo.toml @@ -59,8 +59,8 @@ std = [ "sp-io/std", "sp-runtime/std", "sp-std/std", + "staging-xcm/std", "tp-traits/std", - "staging-xcm/std" ] runtime-benchmarks = [ "frame-benchmarking", diff --git a/runtime/dancebox/Cargo.toml b/runtime/dancebox/Cargo.toml index 7847636bc..a880160cb 100644 --- a/runtime/dancebox/Cargo.toml +++ b/runtime/dancebox/Cargo.toml @@ -27,7 +27,6 @@ pallet-author-noting = { workspace = true } pallet-author-noting-runtime-api = { workspace = true } pallet-authority-assignment = { workspace = true } pallet-authority-mapping = { workspace = true } -pallet-xcm-core-buyer = { workspace = true } pallet-collator-assignment = { workspace = true } pallet-collator-assignment-runtime-api = { workspace = true } pallet-configuration = { workspace = true } @@ -41,6 +40,7 @@ pallet-registrar-runtime-api = { workspace = true } pallet-relay-storage-roots = { workspace = true } pallet-services-payment = { workspace = true } pallet-stream-payment = { workspace = true } +pallet-xcm-core-buyer = { workspace = true } runtime-common = { workspace = true } # Moonkit @@ -213,6 +213,7 @@ std = [ "pallet-tx-pause/std", "pallet-utility/std", "pallet-xcm-benchmarks?/std", + "pallet-xcm-core-buyer/std", "pallet-xcm/std", "parachain-info/std", "parachains-common/std", @@ -220,6 +221,7 @@ std = [ "polkadot-parachain-primitives/std", "polkadot-runtime-common/std", "polkadot-runtime-parachains/std", + "rococo-runtime-constants/std", "rococo-runtime/std", "runtime-common/std", "scale-info/std", @@ -255,7 +257,6 @@ std = [ "westend-runtime-constants/std", "westend-runtime/std", "xcm-primitives/std", - "pallet-xcm-core-buyer/std" ] # Allow to print logs details (no wasm:stripped) @@ -306,12 +307,14 @@ runtime-benchmarks = [ "pallet-tx-pause/runtime-benchmarks", "pallet-utility/runtime-benchmarks", "pallet-xcm-benchmarks/runtime-benchmarks", + "pallet-xcm-core-buyer/runtime-benchmarks", "pallet-xcm/runtime-benchmarks", "parachains-common/runtime-benchmarks", "polkadot-parachain-primitives/runtime-benchmarks", "polkadot-runtime-common/runtime-benchmarks", "polkadot-runtime-parachains/runtime-benchmarks", "polkadot-service/runtime-benchmarks", + "rococo-runtime/runtime-benchmarks", "runtime-common/runtime-benchmarks", "sc-service/runtime-benchmarks", "sp-runtime/runtime-benchmarks", @@ -320,8 +323,6 @@ runtime-benchmarks = [ "tp-traits/runtime-benchmarks", "westend-runtime/runtime-benchmarks", "xcm-primitives/runtime-benchmarks", - "pallet-xcm-core-buyer/runtime-benchmarks", - "rococo-runtime/runtime-benchmarks" ] try-runtime = [ @@ -371,16 +372,16 @@ try-runtime = [ "pallet-treasury/try-runtime", "pallet-tx-pause/try-runtime", "pallet-utility/try-runtime", + "pallet-xcm-core-buyer/try-runtime", "pallet-xcm/try-runtime", "parachain-info/try-runtime", "polkadot-runtime-common/try-runtime", "polkadot-runtime-parachains/try-runtime", "polkadot-service/try-runtime", + "rococo-runtime/try-runtime", "runtime-common/try-runtime", "sp-runtime/try-runtime", "westend-runtime/try-runtime", - "pallet-xcm-core-buyer/try-runtime", - "rococo-runtime/try-runtime" ] fast-runtime = [] From 0aa4e38e07279dd08c30359f3d44c6dfe7d6ec5d Mon Sep 17 00:00:00 2001 From: Tomasz Polaczyk Date: Wed, 13 Mar 2024 18:32:28 +0100 Subject: [PATCH 04/17] Make benchmarks compile --- pallets/xcm-core-buyer/src/benchmarks.rs | 33 ++++++++---------------- pallets/xcm-core-buyer/src/lib.rs | 2 +- pallets/xcm-core-buyer/src/mock.rs | 9 +++++++ 3 files changed, 21 insertions(+), 23 deletions(-) diff --git a/pallets/xcm-core-buyer/src/benchmarks.rs b/pallets/xcm-core-buyer/src/benchmarks.rs index 39ece281a..bbbcc0df4 100644 --- a/pallets/xcm-core-buyer/src/benchmarks.rs +++ b/pallets/xcm-core-buyer/src/benchmarks.rs @@ -17,15 +17,12 @@ #![cfg(feature = "runtime-benchmarks")] //! Benchmarking +use crate::InFlightOrders; +use sp_std::collections::btree_set::BTreeSet; use { crate::{Call, Config, Pallet}, frame_benchmarking::v2::*, - frame_support::{ - traits::{EnsureOriginWithArg, OriginTrait}, - BoundedVec, - }, frame_system::RawOrigin, - sp_std::vec, tp_traits::ParaId, }; @@ -33,27 +30,19 @@ use { mod benchmarks { use super::*; - // TODO #[benchmark] - fn set_boot_nodes(x: Linear<1, 200>, y: Linear<1, 10>) { - // x: url len, y: num boot_nodes - let boot_nodes = BoundedVec::try_from(vec![ - BoundedVec::try_from(vec![b'A'; x as usize]) - .unwrap(); - y as usize - ]) - .unwrap(); - let para_id = ParaId::from(2); - let origin = T::SetBootNodesOrigin::try_successful_origin(¶_id) - .expect("failed to create SetBootNodesOrigin"); - // Worst case is when caller is not root - let raw_origin = origin.as_system_ref(); - assert!(matches!(raw_origin, Some(RawOrigin::Signed(..)))); + fn force_buy_core(x: Linear<1, 200>, y: Linear<1, 10>) { + let para_id = ParaId::from(3333); + assert_eq!(InFlightOrders::::get(), BTreeSet::new()); + + // TODO: need to add benchmark methods to config traits, to ensure that: + // * the para_id is a parathread + // * and to assign collators to that para_id #[extrinsic_call] - Pallet::::set_boot_nodes(origin as T::RuntimeOrigin, para_id, boot_nodes.clone()); + Pallet::::force_buy_core(RawOrigin::Root, para_id); - assert_eq!(Pallet::::boot_nodes(¶_id), boot_nodes); + assert_eq!(InFlightOrders::::get(), BTreeSet::from_iter([para_id])); } impl_benchmark_test_suite!(Pallet, crate::mock::new_test_ext(), crate::mock::Test); diff --git a/pallets/xcm-core-buyer/src/lib.rs b/pallets/xcm-core-buyer/src/lib.rs index db1bd8493..61ad86da4 100644 --- a/pallets/xcm-core-buyer/src/lib.rs +++ b/pallets/xcm-core-buyer/src/lib.rs @@ -217,7 +217,7 @@ pub mod pallet { network: None, }; - InteriorMultiLocation::X1(account_junction.clone()) + InteriorMultiLocation::X1(account_junction) } /// Returns a multilocation that can be used in the `deposit_asset` XCM opcode. diff --git a/pallets/xcm-core-buyer/src/mock.rs b/pallets/xcm-core-buyer/src/mock.rs index 494e75cd8..976952bc9 100644 --- a/pallets/xcm-core-buyer/src/mock.rs +++ b/pallets/xcm-core-buyer/src/mock.rs @@ -276,6 +276,15 @@ pub(crate) fn events() -> Vec> { .collect::>() } +// This function basically just builds a genesis storage key/value store according to +// our desired mockup. +pub fn new_test_ext() -> sp_io::TestExternalities { + frame_system::GenesisConfig::::default() + .build_storage() + .unwrap() + .into() +} + pub fn run_to_block(n: u64) { let old_block_number = System::block_number(); From fdc5f1e6d36fa10f70fdd900f4a41bfcbc5c3725 Mon Sep 17 00:00:00 2001 From: Tomasz Polaczyk Date: Thu, 14 Mar 2024 12:22:13 +0100 Subject: [PATCH 05/17] Implement and run benchmarks --- Cargo.lock | 1 + pallets/xcm-core-buyer/src/benchmarks.rs | 31 +++++-- pallets/xcm-core-buyer/src/lib.rs | 32 +++++-- pallets/xcm-core-buyer/src/mock.rs | 69 +++++++++------ pallets/xcm-core-buyer/src/weights.rs | 105 ++++++++++++++--------- primitives/traits/Cargo.toml | 3 + primitives/traits/src/lib.rs | 3 + runtime/dancebox/src/lib.rs | 1 + runtime/dancebox/src/xcm_config.rs | 69 ++++++++------- 9 files changed, 197 insertions(+), 117 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d695a94e5..43c6e526c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -15919,6 +15919,7 @@ dependencies = [ "impl-trait-for-tuples", "parity-scale-codec", "scale-info", + "serde", "sp-std", ] diff --git a/pallets/xcm-core-buyer/src/benchmarks.rs b/pallets/xcm-core-buyer/src/benchmarks.rs index bbbcc0df4..08d8be655 100644 --- a/pallets/xcm-core-buyer/src/benchmarks.rs +++ b/pallets/xcm-core-buyer/src/benchmarks.rs @@ -17,13 +17,13 @@ #![cfg(feature = "runtime-benchmarks")] //! Benchmarking -use crate::InFlightOrders; -use sp_std::collections::btree_set::BTreeSet; use { - crate::{Call, Config, Pallet}, - frame_benchmarking::v2::*, + crate::{Call, Config, GetParathreadCollators, GetParathreadParams, InFlightOrders, Pallet}, + frame_benchmarking::{account, v2::*}, + frame_support::BoundedBTreeSet, frame_system::RawOrigin, - tp_traits::ParaId, + sp_std::{collections::btree_set::BTreeSet, vec}, + tp_traits::{ParaId, ParathreadParams, SlotFrequency}, }; #[benchmarks] @@ -31,18 +31,33 @@ mod benchmarks { use super::*; #[benchmark] - fn force_buy_core(x: Linear<1, 200>, y: Linear<1, 10>) { - let para_id = ParaId::from(3333); + fn force_buy_core(x: Linear<1, 99>) { + let para_id = ParaId::from(x + 1); assert_eq!(InFlightOrders::::get(), BTreeSet::new()); + // Mock `x` xcm messages already sent in this block + let bbs: BoundedBTreeSet = BTreeSet::from_iter((0..x).map(ParaId::from)) + .try_into() + .expect("x is greater than MaxParathreads"); + InFlightOrders::::put(bbs); + assert!(!InFlightOrders::::get().contains(¶_id)); + // TODO: need to add benchmark methods to config traits, to ensure that: // * the para_id is a parathread // * and to assign collators to that para_id + T::GetParathreadParams::set_parathread_params( + para_id, + Some(ParathreadParams { + slot_frequency: SlotFrequency { min: 10, max: 10 }, + }), + ); + let author: T::AccountId = account("account id", 0u32, 0u32); + T::GetAssignedCollators::set_parathread_collators(para_id, vec![author]); #[extrinsic_call] Pallet::::force_buy_core(RawOrigin::Root, para_id); - assert_eq!(InFlightOrders::::get(), BTreeSet::from_iter([para_id])); + assert!(InFlightOrders::::get().contains(¶_id)); } impl_benchmark_test_suite!(Pallet, crate::mock::new_test_ext(), crate::mock::Test); diff --git a/pallets/xcm-core-buyer/src/lib.rs b/pallets/xcm-core-buyer/src/lib.rs index 61ad86da4..4d3aab9e9 100644 --- a/pallets/xcm-core-buyer/src/lib.rs +++ b/pallets/xcm-core-buyer/src/lib.rs @@ -32,6 +32,8 @@ mod tests; mod benchmarks; pub mod weights; +use sp_runtime::traits::TrailingZeroInput; +use tp_traits::ParathreadParams; use { crate::weights::WeightInfo, dp_core::ParaId, @@ -51,8 +53,6 @@ use { #[frame_support::pallet] pub mod pallet { use super::*; - use sp_runtime::traits::TrailingZeroInput; - use tp_traits::ParathreadParams; /// Data preservers pallet. #[pallet::pallet] @@ -74,9 +74,9 @@ pub mod pallet { type SelfParaId: Get; type MaxParathreads: Get; // TODO: do not abuse Get and Convert traits - type GetParathreadParams: Convert>; + type GetParathreadParams: GetParathreadParams; // TODO: Self::CollatorId? - type GetAssignedCollators: Convert>; + type GetAssignedCollators: GetParathreadCollators; /// A configuration for base priority of unsigned transactions. /// /// This is exposed so that it can be tuned for particular runtime, when @@ -140,7 +140,7 @@ pub mod pallet { // state. #[pallet::call_index(0)] // TODO: weight - #[pallet::weight(T::WeightInfo::set_boot_nodes(1, 1))] + #[pallet::weight(T::WeightInfo::force_buy_core(T::MaxParathreads::get()))] pub fn buy_core( origin: OriginFor, para_id: ParaId, @@ -153,7 +153,7 @@ pub mod pallet { // want collators to pay fees. ensure_none(origin)?; - let assigned_collators = T::GetAssignedCollators::convert(para_id); + let assigned_collators = T::GetAssignedCollators::get_parathread_collators(para_id); if assigned_collators.is_empty() { return Err(Error::::NoAssignedCollators.into()); } @@ -171,14 +171,14 @@ pub mod pallet { /// Buy core for para id as root. Does not require any proof, useful in tests. #[pallet::call_index(1)] // TODO: weight - #[pallet::weight(T::WeightInfo::set_boot_nodes(1, 1))] + #[pallet::weight(T::WeightInfo::force_buy_core(T::MaxParathreads::get()))] pub fn force_buy_core(origin: OriginFor, para_id: ParaId) -> DispatchResult { ensure_root(origin)?; // Check that at least one collator could buy a core for this parathread. // Even though this extrinsic is called `force`, it should only be possible // to use it when an equivalent non-force call can be created. - let assigned_collators = T::GetAssignedCollators::convert(para_id); + let assigned_collators = T::GetAssignedCollators::get_parathread_collators(para_id); if assigned_collators.is_empty() { return Err(Error::::NoAssignedCollators.into()); } @@ -241,7 +241,7 @@ pub mod pallet { .map_err(|_| Error::::InFlightLimitReached)?; // Check that the para id is a parathread - let parathread_params = T::GetParathreadParams::convert(para_id); + let parathread_params = T::GetParathreadParams::get_parathread_params(para_id); if parathread_params.is_none() { return Err(Error::::NotAParathread.into()); } @@ -407,3 +407,17 @@ pub trait GetPurchaseCoreCall { /// Returns the encoded call and its estimated weight. fn get_encoded(max_amount: u128, para_id: ParaId) -> (Vec, Weight); } + +pub trait GetParathreadCollators { + fn get_parathread_collators(para_id: ParaId) -> Vec; + + #[cfg(feature = "runtime-benchmarks")] + fn set_parathread_collators(para_id: ParaId, collators: Vec); +} + +pub trait GetParathreadParams { + fn get_parathread_params(para_id: ParaId) -> Option; + + #[cfg(feature = "runtime-benchmarks")] + fn set_parathread_params(para_id: ParaId, parathread_params: Option); +} diff --git a/pallets/xcm-core-buyer/src/mock.rs b/pallets/xcm-core-buyer/src/mock.rs index 976952bc9..9635de9d4 100644 --- a/pallets/xcm-core-buyer/src/mock.rs +++ b/pallets/xcm-core-buyer/src/mock.rs @@ -14,25 +14,22 @@ // You should have received a copy of the GNU General Public License // along with Tanssi. If not, see -use crate::GetPurchaseCoreCall; -use bounded_collections::ConstU128; -use sp_runtime::traits::Convert; -use sp_runtime::BuildStorage; -use staging_xcm::latest::{ - MultiAssets, MultiLocation, SendError, SendResult, SendXcm, Xcm, XcmHash, -}; -use tp_traits::{ParathreadParams, SlotFrequency}; use { - crate::{self as pallet_xcm_core_buyer}, + crate::{self as pallet_xcm_core_buyer, GetParathreadCollators, GetPurchaseCoreCall}, dp_core::ParaId, frame_support::{ pallet_prelude::*, parameter_types, - traits::{ConstU64, Everything}, + traits::{ConstU128, ConstU64, Everything}, }, sp_core::H256, sp_runtime::traits::{BlakeTwo256, IdentityLookup}, + sp_runtime::{traits::Convert, BuildStorage}, sp_std::collections::btree_map::BTreeMap, + staging_xcm::latest::{ + MultiAssets, MultiLocation, SendError, SendResult, SendXcm, Xcm, XcmHash, + }, + tp_traits::{ParathreadParams, SlotFrequency}, }; type Block = frame_system::mocking::MockBlock; @@ -136,12 +133,19 @@ impl mock_data::Config for Test {} #[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))] pub struct Mocks { pub container_chain_collators: BTreeMap>, + pub parathread_params: BTreeMap, } impl Default for Mocks { fn default() -> Self { Self { container_chain_collators: BTreeMap::from_iter([(ParaId::from(3333), vec![BOB])]), + parathread_params: BTreeMap::from_iter([( + ParaId::from(3333), + ParathreadParams { + slot_frequency: SlotFrequency { min: 10, max: 10 }, + }, + )]), } } } @@ -160,8 +164,8 @@ impl pallet_xcm_core_buyer::Config for Test { type AccountIdToArray32 = AccountIdToArray32; type SelfParaId = ParachainId; type MaxParathreads = ConstU32<100>; - type GetParathreadParams = GetParathreadParams; - type GetAssignedCollators = GetAssignedCollators; + type GetParathreadParams = GetParathreadParamsImpl; + type GetAssignedCollators = GetAssignedCollatorsImpl; type UnsignedPriority = (); type WeightInfo = (); @@ -178,30 +182,42 @@ impl SendXcm for DevNull { } } -pub struct GetParathreadParams; +pub struct GetParathreadParamsImpl; -impl Convert> for GetParathreadParams { - fn convert(para_id: ParaId) -> Option { - if para_id == 3333.into() { - Some(ParathreadParams { - slot_frequency: SlotFrequency { min: 10, max: 10 }, - }) - } else { - None - } +impl crate::GetParathreadParams for GetParathreadParamsImpl { + fn get_parathread_params(para_id: ParaId) -> Option { + MockData::mock().parathread_params.get(¶_id).cloned() + } + + #[cfg(feature = "runtime-benchmarks")] + fn set_parathread_params(para_id: ParaId, parathread_params: Option) { + MockData::mutate(|m| { + if let Some(parathread_params) = parathread_params { + m.parathread_params.insert(para_id, parathread_params); + } else { + m.parathread_params.remove(¶_id); + } + }); } } -pub struct GetAssignedCollators; +pub struct GetAssignedCollatorsImpl; -impl Convert> for GetAssignedCollators { - fn convert(para_id: ParaId) -> Vec { +impl GetParathreadCollators for GetAssignedCollatorsImpl { + fn get_parathread_collators(para_id: ParaId) -> Vec { MockData::mock() .container_chain_collators .get(¶_id) .cloned() .unwrap_or_default() } + + #[cfg(feature = "runtime-benchmarks")] + fn set_parathread_collators(para_id: ParaId, collators: Vec) { + MockData::mutate(|m| { + m.container_chain_collators.insert(para_id, collators); + }) + } } pub struct GetBlockNumber; @@ -276,8 +292,7 @@ pub(crate) fn events() -> Vec> { .collect::>() } -// This function basically just builds a genesis storage key/value store according to -// our desired mockup. +#[cfg(feature = "runtime-benchmarks")] pub fn new_test_ext() -> sp_io::TestExternalities { frame_system::GenesisConfig::::default() .build_storage() diff --git a/pallets/xcm-core-buyer/src/weights.rs b/pallets/xcm-core-buyer/src/weights.rs index b93d57d1a..2b453123d 100644 --- a/pallets/xcm-core-buyer/src/weights.rs +++ b/pallets/xcm-core-buyer/src/weights.rs @@ -15,13 +15,13 @@ // along with Tanssi. If not, see -//! Autogenerated weights for pallet_data_preservers +//! Autogenerated weights for pallet_xcm_core_buyer //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-12-11, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2024-03-14, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` //! HOSTNAME: `tomasz-XPS-15-9520`, CPU: `12th Gen Intel(R) Core(TM) i7-12700H` -//! EXECUTION: , WASM-EXECUTION: Compiled, CHAIN: None, DB CACHE: 1024 +//! EXECUTION: , WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024 // Executed Command: // ./target/release/tanssi-node @@ -30,9 +30,10 @@ // --execution=wasm // --wasm-execution=compiled // --pallet -// pallet_data_preservers +// pallet_xcm_core_buyer // --extrinsic // * +// --chain=dev // --steps // 50 // --repeat @@ -41,7 +42,7 @@ // --json-file // raw.json // --output -// weights.rs +// tmp/pallet_xcm_core_buyer.rs #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -50,54 +51,74 @@ use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; use sp_std::marker::PhantomData; -/// Weight functions needed for pallet_data_preservers. +/// Weight functions needed for pallet_xcm_core_buyer. pub trait WeightInfo { - fn set_boot_nodes(x: u32, y: u32, ) -> Weight; + fn force_buy_core(x: u32, ) -> Weight; } -/// Weights for pallet_data_preservers using the Substrate node and recommended hardware. +/// Weights for pallet_xcm_core_buyer using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); impl WeightInfo for SubstrateWeight { - /// Storage: `Registrar::RegistrarDeposit` (r:1 w:0) - /// Proof: `Registrar::RegistrarDeposit` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `DataPreservers::BootNodes` (r:0 w:1) - /// Proof: `DataPreservers::BootNodes` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// The range of component `x` is `[1, 200]`. - /// The range of component `y` is `[1, 10]`. - fn set_boot_nodes(x: u32, y: u32, ) -> Weight { + /// Storage: `CollatorAssignment::CollatorContainerChain` (r:1 w:0) + /// Proof: `CollatorAssignment::CollatorContainerChain` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `XcmCoreBuyer::InFlightOrders` (r:1 w:1) + /// Proof: `XcmCoreBuyer::InFlightOrders` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Registrar::ParathreadParams` (r:1 w:0) + /// Proof: `Registrar::ParathreadParams` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `PolkadotXcm::SupportedVersion` (r:1 w:0) + /// Proof: `PolkadotXcm::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `PolkadotXcm::VersionDiscoveryQueue` (r:1 w:1) + /// Proof: `PolkadotXcm::VersionDiscoveryQueue` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `PolkadotXcm::SafeXcmVersion` (r:1 w:0) + /// Proof: `PolkadotXcm::SafeXcmVersion` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ParachainSystem::HostConfiguration` (r:1 w:0) + /// Proof: `ParachainSystem::HostConfiguration` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ParachainSystem::PendingUpwardMessages` (r:1 w:1) + /// Proof: `ParachainSystem::PendingUpwardMessages` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// The range of component `x` is `[1, 99]`. + fn force_buy_core(x: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `195` - // Estimated: `3660` - // Minimum execution time: 10_703_000 picoseconds. - Weight::from_parts(9_788_229, 3660) - // Standard Error: 170 - .saturating_add(Weight::from_parts(7_964, 0).saturating_mul(x.into())) - // Standard Error: 3_552 - .saturating_add(Weight::from_parts(334_296, 0).saturating_mul(y.into())) - .saturating_add(T::DbWeight::get().reads(1_u64)) - .saturating_add(T::DbWeight::get().writes(1_u64)) + // Measured: `618 + x * (4 ±0)` + // Estimated: `4082 + x * (4 ±0)` + // Minimum execution time: 26_557_000 picoseconds. + Weight::from_parts(31_565_282, 4082) + // Standard Error: 1_405 + .saturating_add(Weight::from_parts(33_647, 0).saturating_mul(x.into())) + .saturating_add(T::DbWeight::get().reads(8_u64)) + .saturating_add(T::DbWeight::get().writes(3_u64)) + .saturating_add(Weight::from_parts(0, 4).saturating_mul(x.into())) } } // For backwards compatibility and tests impl WeightInfo for () { - /// Storage: `Registrar::RegistrarDeposit` (r:1 w:0) - /// Proof: `Registrar::RegistrarDeposit` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `DataPreservers::BootNodes` (r:0 w:1) - /// Proof: `DataPreservers::BootNodes` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// The range of component `x` is `[1, 200]`. - /// The range of component `y` is `[1, 10]`. - fn set_boot_nodes(x: u32, y: u32, ) -> Weight { + /// Storage: `CollatorAssignment::CollatorContainerChain` (r:1 w:0) + /// Proof: `CollatorAssignment::CollatorContainerChain` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `XcmCoreBuyer::InFlightOrders` (r:1 w:1) + /// Proof: `XcmCoreBuyer::InFlightOrders` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Registrar::ParathreadParams` (r:1 w:0) + /// Proof: `Registrar::ParathreadParams` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `PolkadotXcm::SupportedVersion` (r:1 w:0) + /// Proof: `PolkadotXcm::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `PolkadotXcm::VersionDiscoveryQueue` (r:1 w:1) + /// Proof: `PolkadotXcm::VersionDiscoveryQueue` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `PolkadotXcm::SafeXcmVersion` (r:1 w:0) + /// Proof: `PolkadotXcm::SafeXcmVersion` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ParachainSystem::HostConfiguration` (r:1 w:0) + /// Proof: `ParachainSystem::HostConfiguration` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ParachainSystem::PendingUpwardMessages` (r:1 w:1) + /// Proof: `ParachainSystem::PendingUpwardMessages` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// The range of component `x` is `[1, 99]`. + fn force_buy_core(x: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `195` - // Estimated: `3660` - // Minimum execution time: 10_703_000 picoseconds. - Weight::from_parts(9_788_229, 3660) - // Standard Error: 170 - .saturating_add(Weight::from_parts(7_964, 0).saturating_mul(x.into())) - // Standard Error: 3_552 - .saturating_add(Weight::from_parts(334_296, 0).saturating_mul(y.into())) - .saturating_add(RocksDbWeight::get().reads(1_u64)) - .saturating_add(RocksDbWeight::get().writes(1_u64)) + // Measured: `618 + x * (4 ±0)` + // Estimated: `4082 + x * (4 ±0)` + // Minimum execution time: 26_557_000 picoseconds. + Weight::from_parts(31_565_282, 4082) + // Standard Error: 1_405 + .saturating_add(Weight::from_parts(33_647, 0).saturating_mul(x.into())) + .saturating_add(RocksDbWeight::get().reads(8_u64)) + .saturating_add(RocksDbWeight::get().writes(3_u64)) + .saturating_add(Weight::from_parts(0, 4).saturating_mul(x.into())) } } diff --git a/primitives/traits/Cargo.toml b/primitives/traits/Cargo.toml index b944fc200..63b24f682 100644 --- a/primitives/traits/Cargo.toml +++ b/primitives/traits/Cargo.toml @@ -14,6 +14,7 @@ frame-support = { workspace = true } impl-trait-for-tuples = { workspace = true } parity-scale-codec = { workspace = true } scale-info = { workspace = true } +serde = { workspace = true, optional = true } sp-std = { workspace = true } # Cumulus @@ -27,6 +28,8 @@ std = [ "parity-scale-codec/std", "scale-info/std", "sp-std/std", + "serde", + "serde/std", ] runtime-benchmarks = [ "cumulus-primitives-core/runtime-benchmarks", diff --git a/primitives/traits/src/lib.rs b/primitives/traits/src/lib.rs index 881f144bd..15f96bed7 100644 --- a/primitives/traits/src/lib.rs +++ b/primitives/traits/src/lib.rs @@ -23,6 +23,7 @@ pub use cumulus_primitives_core::{ relay_chain::{BlockNumber, Slot}, ParaId, }; +use frame_support::__private::serde; use { frame_support::{ pallet_prelude::{Decode, DispatchResultWithPostInfo, Encode, Get, Weight}, @@ -93,6 +94,7 @@ pub trait GetCurrentContainerChains { /// tanssi slot time, 12 seconds by default. // TODO: this is currently ignored #[derive(Clone, Debug, Encode, Decode, scale_info::TypeInfo, PartialEq, Eq)] +#[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))] pub struct SlotFrequency { /// The parathread will produce at most 1 block every x slots. min=10 means that collators can produce 1 block /// every `x >= 10` slots, but they are not enforced to. If collators produce a block after less than 10 @@ -111,6 +113,7 @@ impl Default for SlotFrequency { } #[derive(Clone, Debug, Encode, Decode, scale_info::TypeInfo, PartialEq, Eq)] +#[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))] pub struct ParathreadParams { pub slot_frequency: SlotFrequency, } diff --git a/runtime/dancebox/src/lib.rs b/runtime/dancebox/src/lib.rs index 326baf6d8..0a7ec1702 100644 --- a/runtime/dancebox/src/lib.rs +++ b/runtime/dancebox/src/lib.rs @@ -1674,6 +1674,7 @@ mod benches { [cumulus_pallet_xcmp_queue, XcmpQueue] [pallet_xcm, PalletXcmExtrinsicsBenchmark::] [pallet_xcm_benchmarks::generic, pallet_xcm_benchmarks::generic::Pallet::] + [pallet_xcm_core_buyer, XcmCoreBuyer] [pallet_stream_payment, StreamPayment] [pallet_relay_storage_roots, RelayStorageRoots] [pallet_assets, ForeignAssets] diff --git a/runtime/dancebox/src/xcm_config.rs b/runtime/dancebox/src/xcm_config.rs index 07ce1b16e..7e0c1b0cc 100644 --- a/runtime/dancebox/src/xcm_config.rs +++ b/runtime/dancebox/src/xcm_config.rs @@ -14,40 +14,41 @@ // You should have received a copy of the GNU General Public License // along with Tanssi. If not, see -use frame_support::pallet_prelude::Get; -use parity_scale_codec::Encode; -use sp_runtime::traits::Convert; -use sp_runtime::transaction_validity::TransactionPriority; -use sp_std::vec::Vec; use { super::{ weights::xcm::XcmWeight as XcmGenericWeights, AccountId, AllPalletsWithSystem, AssetRate, - Balance, Balances, ForeignAssetsCreator, MaintenanceMode, MessageQueue, ParachainInfo, - ParachainSystem, PolkadotXcm, Registrar, Runtime, RuntimeBlockWeights, RuntimeCall, - RuntimeEvent, RuntimeOrigin, WeightToFee, XcmpQueue, + Balance, Balances, CollatorAssignment, ForeignAssets, ForeignAssetsCreator, + MaintenanceMode, MessageQueue, ParachainInfo, ParachainSystem, PolkadotXcm, Registrar, + Runtime, RuntimeBlockWeights, RuntimeCall, RuntimeEvent, RuntimeOrigin, System, + WeightToFee, XcmpQueue, }, cumulus_primitives_core::{AggregateMessageOrigin, ParaId}, frame_support::{ + pallet_prelude::Get, parameter_types, traits::{Everything, Nothing, PalletInfoAccess, TransformOrigin}, weights::Weight, }, frame_system::EnsureRoot, pallet_xcm::XcmPassthrough, + pallet_xcm_core_buyer::{GetParathreadCollators, GetParathreadParams, GetPurchaseCoreCall}, parachains_common::message_queue::{NarrowOriginToSibling, ParaIdToSibling}, + parity_scale_codec::Encode, polkadot_runtime_common::xcm_sender::NoPriceForMessageDelivery, sp_core::ConstU32, - sp_runtime::Perbill, + sp_runtime::{traits::Convert, transaction_validity::TransactionPriority, Perbill}, + sp_std::vec::Vec, staging_xcm::latest::prelude::*, staging_xcm_builder::{ AccountId32Aliases, AllowKnownQueryResponses, AllowSubscriptionsFrom, AllowTopLevelPaidExecutionFrom, ConvertedConcreteId, EnsureXcmOrigin, FungibleAdapter, - IsConcrete, ParentIsPreset, RelayChainAsNative, SiblingParachainAsNative, - SiblingParachainConvertsVia, SignedAccountId32AsNative, SignedToAccountId32, - SovereignSignedViaLocation, TakeWeightCredit, UsingComponents, WeightInfoBounds, - WithComputedOrigin, + FungiblesAdapter, IsConcrete, NoChecking, ParentIsPreset, RelayChainAsNative, + SiblingParachainAsNative, SiblingParachainConvertsVia, SignedAccountId32AsNative, + SignedToAccountId32, SovereignSignedViaLocation, TakeWeightCredit, UsingComponents, + WeightInfoBounds, WithComputedOrigin, }, - staging_xcm_executor::XcmExecutor, + staging_xcm_executor::{traits::JustTry, XcmExecutor}, + tp_traits::ParathreadParams, }; parameter_types! { @@ -344,15 +345,6 @@ impl pallet_asset_rate::Config for Runtime { type BenchmarkHelper = ForeignAssetBenchmarkHelper; } -use crate::{CollatorAssignment, System}; -use pallet_xcm_core_buyer::GetPurchaseCoreCall; -use tp_traits::ParathreadParams; -use { - crate::ForeignAssets, - staging_xcm_builder::{FungiblesAdapter, NoChecking}, - staging_xcm_executor::traits::JustTry, -}; - /// Means for transacting foreign assets from different global consensus. pub type ForeignFungiblesTransactor = FungiblesAdapter< // Use this fungibles implementation: @@ -514,8 +506,8 @@ impl pallet_xcm_core_buyer::Config for Runtime { type AccountIdToArray32 = AccountIdToArray32; type SelfParaId = parachain_info::Pallet; type MaxParathreads = ConstU32<100>; - type GetParathreadParams = GetParathreadParams; - type GetAssignedCollators = GetAssignedCollators; + type GetParathreadParams = GetParathreadParamsImpl; + type GetAssignedCollators = GetAssignedCollatorsImpl; type UnsignedPriority = ParasUnsignedPriority; type WeightInfo = (); @@ -529,18 +521,27 @@ impl Get for GetBlockNumber { } } -pub struct GetParathreadParams; +pub struct GetParathreadParamsImpl; -impl Convert> for GetParathreadParams { - fn convert(para_id: ParaId) -> Option { +impl GetParathreadParams for GetParathreadParamsImpl { + fn get_parathread_params(para_id: ParaId) -> Option { Registrar::parathread_params(para_id) } + + #[cfg(feature = "runtime-benchmarks")] + fn set_parathread_params(para_id: ParaId, parathread_params: Option) { + if let Some(parathread_params) = parathread_params { + pallet_registrar::ParathreadParams::::insert(para_id, parathread_params); + } else { + pallet_registrar::ParathreadParams::::remove(para_id); + } + } } -pub struct GetAssignedCollators; +pub struct GetAssignedCollatorsImpl; -impl Convert> for GetAssignedCollators { - fn convert(para_id: ParaId) -> Vec { +impl GetParathreadCollators for GetAssignedCollatorsImpl { + fn get_parathread_collators(para_id: ParaId) -> Vec { // We do not need to check if the para_id is a valid parathread, // because that is already being checked by `GetParathreadParams`. CollatorAssignment::collator_container_chain() @@ -549,6 +550,12 @@ impl Convert> for GetAssignedCollators { .cloned() .unwrap_or_default() } + + #[cfg(feature = "runtime-benchmarks")] + fn set_parathread_collators(para_id: ParaId, collators: Vec) { + use tp_traits::GetContainerChainAuthor; + CollatorAssignment::set_authors_for_para_id(para_id, collators); + } } pub struct AccountIdToArray32; From 824ab4ce44e607cd0bfd7a88259c1ab95c1b6cd0 Mon Sep 17 00:00:00 2001 From: Tomasz Polaczyk Date: Thu, 14 Mar 2024 14:54:55 +0100 Subject: [PATCH 06/17] Change account derivation and store XCM weights in pallet storage --- pallets/xcm-core-buyer/src/benchmarks.rs | 4 +- pallets/xcm-core-buyer/src/lib.rs | 87 +++++++++++-------- pallets/xcm-core-buyer/src/mock.rs | 62 +++++++++---- pallets/xcm-core-buyer/src/tests.rs | 18 ++++ runtime/dancebox/src/xcm_config.rs | 53 +++-------- .../dancebox/tests/common/xcm/core_buyer.rs | 35 +++++--- 6 files changed, 151 insertions(+), 108 deletions(-) diff --git a/pallets/xcm-core-buyer/src/benchmarks.rs b/pallets/xcm-core-buyer/src/benchmarks.rs index 08d8be655..5b5f0989f 100644 --- a/pallets/xcm-core-buyer/src/benchmarks.rs +++ b/pallets/xcm-core-buyer/src/benchmarks.rs @@ -42,9 +42,9 @@ mod benchmarks { InFlightOrders::::put(bbs); assert!(!InFlightOrders::::get().contains(¶_id)); - // TODO: need to add benchmark methods to config traits, to ensure that: + // For the extrinsic to succeed, we need to ensure that: // * the para_id is a parathread - // * and to assign collators to that para_id + // * it has assigned collators T::GetParathreadParams::set_parathread_params( para_id, Some(ParathreadParams { diff --git a/pallets/xcm-core-buyer/src/lib.rs b/pallets/xcm-core-buyer/src/lib.rs index 4d3aab9e9..7dc536f62 100644 --- a/pallets/xcm-core-buyer/src/lib.rs +++ b/pallets/xcm-core-buyer/src/lib.rs @@ -32,8 +32,6 @@ mod tests; mod benchmarks; pub mod weights; -use sp_runtime::traits::TrailingZeroInput; -use tp_traits::ParathreadParams; use { crate::weights::WeightInfo, dp_core::ParaId, @@ -42,12 +40,12 @@ use { traits::fungible::{Balanced, Inspect}, }, frame_system::pallet_prelude::*, - sp_io::hashing::blake2_256, sp_runtime::traits::{Convert, Get}, sp_std::vec, sp_std::vec::Vec, staging_xcm::prelude::*, staging_xcm::v3::{InteriorMultiLocation, MultiAsset, MultiAssets, Xcm}, + tp_traits::ParathreadParams, }; #[frame_support::pallet] @@ -65,17 +63,13 @@ pub mod pallet { type RuntimeEvent: From> + IsType<::RuntimeEvent>; type Currency: Inspect + Balanced; - type XcmBuyExecutionDot: Get; type XcmSender: SendXcm; type GetPurchaseCoreCall: GetPurchaseCoreCall; type GetBlockNumber: Get; - // TODO: use AccountIdConversion trait here? - type AccountIdToArray32: Convert; + type GetParathreadAccountId: Convert; type SelfParaId: Get; type MaxParathreads: Get; - // TODO: do not abuse Get and Convert traits type GetParathreadParams: GetParathreadParams; - // TODO: Self::CollatorId? type GetAssignedCollators: GetParathreadCollators; /// A configuration for base priority of unsigned transactions. /// @@ -110,6 +104,9 @@ pub mod pallet { NoAssignedCollators, /// This collator is not assigned to this parathread CollatorNotAssigned, + /// The `XcmWeights` storage has not been set. This must have been set by root with the + /// value of the relay chain xcm call weight and extrinsic weight + XcmWeightStorageNotSet, } /// Proof that I am a collator, assigned to a para_id, and I can buy a core for that para_id @@ -129,6 +126,20 @@ pub mod pallet { pub type InFlightOrders = StorageValue<_, BoundedBTreeSet, ValueQuery>; + /// This must be set by root with the value of the relay chain xcm call weight and extrinsic + /// weight limit. This is a storage item because relay chain weights can change, so we need to + /// be able to adjust them without doing a runtime upgrade. + #[pallet::storage] + pub type XcmWeights = StorageValue<_, XcmWeightsTy, OptionQuery>; + + #[derive(Encode, Decode, CloneNoBound, PartialEq, Eq, DebugNoBound, TypeInfo)] + #[scale_info(skip_type_params(T))] + pub struct XcmWeightsTy { + pub buy_execution_cost: u128, + pub weight_at_most: Weight, + pub _phantom: PhantomData, + } + #[pallet::call] impl Pallet { /// Buy a core for this parathread id. @@ -170,7 +181,6 @@ pub mod pallet { /// Buy core for para id as root. Does not require any proof, useful in tests. #[pallet::call_index(1)] - // TODO: weight #[pallet::weight(T::WeightInfo::force_buy_core(T::MaxParathreads::get()))] pub fn force_buy_core(origin: OriginFor, para_id: ParaId) -> DispatchResult { ensure_root(origin)?; @@ -185,35 +195,33 @@ pub mod pallet { Self::on_collator_instantaneous_core_requested(para_id) } - } - impl Pallet { - /// Derive a derivative account ID from the paraId to use as a DOT tank in the relay chain. - /// This is not the actual address, the actual address can be computed as a derivative of - /// the tanssi sovereign account and this address. - pub fn relay_parachain_tank_id(para_id: ParaId) -> T::AccountId { - // TODO: we could use the services_payment parachain tank account here, it could be - // easier to remember that it is the same account, but DANCE tokens are stored in - // tanssi and DOT tokens are stored in the relay chain - // TODO: and we could go a step further and set the tank address in tanssi - // equal to the relay chain, but not sure if that's a good idea - let entropy = (b"modlpy/buycoretim", para_id).using_encoded(blake2_256); - Decode::decode(&mut TrailingZeroInput::new(entropy.as_ref())) - .expect("infinite length input; no invalid inputs for type; qed") + #[pallet::call_index(2)] + // TODO: weight + #[pallet::weight(T::WeightInfo::force_buy_core(T::MaxParathreads::get()))] + pub fn set_xcm_weights( + origin: OriginFor, + xcm_weights: Option>, + ) -> DispatchResult { + ensure_root(origin)?; + + if let Some(xcm_weights) = xcm_weights { + XcmWeights::::put(xcm_weights); + } else { + XcmWeights::::kill(); + } + + Ok(()) } + } + impl Pallet { /// Returns the interior multilocation for this container chain para id. This is a relative /// multilocation that can be used in the `descend_origin` XCM opcode. pub fn interior_multilocation(para_id: ParaId) -> InteriorMultiLocation { - /* - // Not using this method in case another pallet also wants to use a derived account for - // a different purpose. - let interior_multilocation = - InteriorMultiLocation::X1(Junction::Parachain(para_id.into())); - */ - let container_chain_account = Self::relay_parachain_tank_id(para_id); + let container_chain_account = T::GetParathreadAccountId::convert(para_id); let account_junction = Junction::AccountId32 { - id: T::AccountIdToArray32::convert(container_chain_account), + id: container_chain_account, network: None, }; @@ -246,8 +254,12 @@ pub mod pallet { return Err(Error::::NotAParathread.into()); } - // TODO: the origin should have rights to create blocks for para_id - let withdraw_amount = T::XcmBuyExecutionDot::get(); + // TODO: also compare the latest slot from pallet_author_noting with parathread_params.slot_frequency + + let xcm_weights_storage = + XcmWeights::::get().ok_or(Error::::XcmWeightStorageNotSet)?; + + let withdraw_amount = xcm_weights_storage.buy_execution_cost; // Send xcm to the relay // Use a derivative account from the sovereign account based on the paraId @@ -261,10 +273,11 @@ pub mod pallet { // TODO: when coretime is implemented, buy core there instead of buying on-demand cores let origin = OriginKind::SovereignAccount; // TODO: max_amount is the max price of a core that this parathread is willing to pay - // It should be defined in a storage item somewhere, contrallable by the container chain + // It should be defined in a storage item somewhere, controllable by the container chain // manager. let max_amount = u128::MAX; - let (call, weight_at_most) = T::GetPurchaseCoreCall::get_encoded(max_amount, para_id); + let call = T::GetPurchaseCoreCall::get_encoded(max_amount, para_id); + let weight_at_most = xcm_weights_storage.weight_at_most; // Assumption: derived account already has DOT // The balance should be enough to cover @@ -325,7 +338,7 @@ pub mod pallet { fn on_finalize(_: BlockNumberFor) { // We clear this storage item because we only need it to prevent collators from buying - // more than one core in the same relay block + // more than one core for the same parathread in the same relay block // TODO: with async backing, it is possible that two tanssi blocks are included in the // same relay block, so this kill is not correct, should only kill the storage if the // relay block number has changed @@ -405,7 +418,7 @@ pub mod pallet { pub trait GetPurchaseCoreCall { /// Get the encoded call to buy a core for this `para_id`, with this `max_amount`. /// Returns the encoded call and its estimated weight. - fn get_encoded(max_amount: u128, para_id: ParaId) -> (Vec, Weight); + fn get_encoded(max_amount: u128, para_id: ParaId) -> Vec; } pub trait GetParathreadCollators { diff --git a/pallets/xcm-core-buyer/src/mock.rs b/pallets/xcm-core-buyer/src/mock.rs index 9635de9d4..ea4706445 100644 --- a/pallets/xcm-core-buyer/src/mock.rs +++ b/pallets/xcm-core-buyer/src/mock.rs @@ -15,14 +15,18 @@ // along with Tanssi. If not, see use { - crate::{self as pallet_xcm_core_buyer, GetParathreadCollators, GetPurchaseCoreCall}, + crate::{ + self as pallet_xcm_core_buyer, GetParathreadCollators, GetPurchaseCoreCall, XcmWeightsTy, + }, dp_core::ParaId, frame_support::{ + assert_ok, pallet_prelude::*, parameter_types, - traits::{ConstU128, ConstU64, Everything}, + traits::{ConstU64, Everything}, }, sp_core::H256, + sp_io::TestExternalities, sp_runtime::traits::{BlakeTwo256, IdentityLookup}, sp_runtime::{traits::Convert, BuildStorage}, sp_std::collections::btree_map::BTreeMap, @@ -157,11 +161,10 @@ parameter_types! { impl pallet_xcm_core_buyer::Config for Test { type RuntimeEvent = RuntimeEvent; type Currency = Balances; - type XcmBuyExecutionDot = ConstU128<1_000>; type XcmSender = DevNull; type GetPurchaseCoreCall = EncodedCallToBuyCore; type GetBlockNumber = (); - type AccountIdToArray32 = AccountIdToArray32; + type GetParathreadAccountId = ParaIdToAccount32; type SelfParaId = ParachainId; type MaxParathreads = ConstU32<100>; type GetParathreadParams = GetParathreadParamsImpl; @@ -228,13 +231,13 @@ impl Get for GetBlockNumber { } } -pub struct AccountIdToArray32; +pub struct ParaIdToAccount32; -impl Convert for AccountIdToArray32 { - fn convert(a: u64) -> [u8; 32] { +impl Convert for ParaIdToAccount32 { + fn convert(para_id: ParaId) -> [u8; 32] { let mut res = [0; 32]; - res[..8].copy_from_slice(&a.to_le_bytes()); + res[..4].copy_from_slice(&u32::from(para_id).to_le_bytes()); res } @@ -243,15 +246,14 @@ impl Convert for AccountIdToArray32 { pub struct EncodedCallToBuyCore; impl GetPurchaseCoreCall for EncodedCallToBuyCore { - fn get_encoded(_max_amount: u128, _para_id: ParaId) -> (Vec, Weight) { - let weight = Weight::from_parts(1_000_000_000, 100_000); - - let encoded_call = vec![]; - - (encoded_call, weight) + fn get_encoded(_max_amount: u128, _para_id: ParaId) -> Vec { + vec![] } } +pub const BUY_EXECUTION_COST: u128 = 50_000_000; +pub const PLACE_ORDER_WEIGHT_AT_MOST: Weight = Weight::from_parts(1_000_000_000, 100_000); + #[derive(Default)] pub struct ExtBuilder { balances: Vec<(AccountId, Balance)>, @@ -274,7 +276,20 @@ impl ExtBuilder { .assimilate_storage(&mut t) .unwrap(); - t.into() + let mut ext: TestExternalities = t.into(); + + ext.execute_with(|| { + assert_ok!(XcmCoreBuyer::set_xcm_weights( + RuntimeOrigin::root(), + Some(XcmWeightsTy { + buy_execution_cost: BUY_EXECUTION_COST, + weight_at_most: PLACE_ORDER_WEIGHT_AT_MOST, + _phantom: PhantomData, + }), + )); + }); + + ext } } @@ -294,10 +309,23 @@ pub(crate) fn events() -> Vec> { #[cfg(feature = "runtime-benchmarks")] pub fn new_test_ext() -> sp_io::TestExternalities { - frame_system::GenesisConfig::::default() + let mut ext: TestExternalities = frame_system::GenesisConfig::::default() .build_storage() .unwrap() - .into() + .into(); + + ext.execute_with(|| { + assert_ok!(XcmCoreBuyer::set_xcm_weights( + RuntimeOrigin::root(), + Some(XcmWeightsTy { + buy_execution_cost: BUY_EXECUTION_COST, + weight_at_most: PLACE_ORDER_WEIGHT_AT_MOST, + _phantom: PhantomData, + }), + )); + }); + + ext } pub fn run_to_block(n: u64) { diff --git a/pallets/xcm-core-buyer/src/tests.rs b/pallets/xcm-core-buyer/src/tests.rs index 707e71950..90694ce31 100644 --- a/pallets/xcm-core-buyer/src/tests.rs +++ b/pallets/xcm-core-buyer/src/tests.rs @@ -131,3 +131,21 @@ fn cannot_force_buy_para_id_with_no_collators() { ); }); } + +#[test] +fn cannot_buy_if_no_weights_storage_set() { + ExtBuilder::default() + .with_balances([(ALICE, 1_000)].into()) + .build() + .execute_with(|| { + run_to_block(1); + assert_ok!(XcmCoreBuyer::set_xcm_weights(RuntimeOrigin::root(), None)); + + let para_id = 3333.into(); + + assert_noop!( + XcmCoreBuyer::force_buy_core(RuntimeOrigin::root(), para_id), + Error::::XcmWeightStorageNotSet + ); + }); +} diff --git a/runtime/dancebox/src/xcm_config.rs b/runtime/dancebox/src/xcm_config.rs index 7e0c1b0cc..16b3b378d 100644 --- a/runtime/dancebox/src/xcm_config.rs +++ b/runtime/dancebox/src/xcm_config.rs @@ -14,6 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Tanssi. If not, see +use sp_runtime::traits::AccountIdConversion; use { super::{ weights::xcm::XcmWeight as XcmGenericWeights, AccountId, AllPalletsWithSystem, AssetRate, @@ -468,42 +469,10 @@ impl pallet_xcm_core_buyer::Config for Runtime { type RuntimeEvent = RuntimeEvent; type Currency = Balances; - // TODO: calculate weight and use rococo weight to fee - // /home/tomasz/.cargo/git/checkouts/polkadot-sdk-df3be1d6828443a1/77c5b55/polkadot/runtime/rococo/src/xcm_config.rs - /* - /// Returns weight of `weight_of_initiate_reserve_withdraw` call. - fn weight_of_initiate_reserve_withdraw() -> Weight { - let dest = MultiLocation::parent(); - - // We can use whatever asset here - let asset = MultiLocation::parent(); - - // Construct MultiAsset - let fee = MultiAsset { - id: Concrete(asset.clone()), - fun: Fungible(0), - }; - - let xcm: Xcm<()> = Xcm(vec![ - WithdrawAsset(fee.into()), - InitiateReserveWithdraw { - assets: MultiAssetFilter::Wild(All), - reserve: dest.clone(), - xcm: Xcm(vec![]), - }, - ]); - T::Weigher::weight(&mut xcm.into()).map_or(Weight::max_value(), |w| { - T::BaseXcmWeight::get().saturating_add(w) - }) - } - - */ - // TODO: this depends on the relay - type XcmBuyExecutionDot = XcmBuyExecutionDotRococo; type XcmSender = XcmRouter; type GetPurchaseCoreCall = EncodedCallToBuyCore; type GetBlockNumber = GetBlockNumber; - type AccountIdToArray32 = AccountIdToArray32; + type GetParathreadAccountId = ParaIdToAccount32; type SelfParaId = parachain_info::Pallet; type MaxParathreads = ConstU32<100>; type GetParathreadParams = GetParathreadParamsImpl; @@ -558,24 +527,26 @@ impl GetParathreadCollators for GetAssignedCollatorsImpl { } } -pub struct AccountIdToArray32; +pub struct ParaIdToAccount32; -impl Convert for AccountIdToArray32 { - fn convert(a: AccountId) -> [u8; 32] { - a.into() +impl Convert for ParaIdToAccount32 { + fn convert(para_id: ParaId) -> [u8; 32] { + // Derive a 32 byte account id for a parathread. Note that this is not the address of + // the relay chain parathread tank, but that address is derived from this. + let account: AccountId = para_id.into_account_truncating(); + + account.into() } } pub struct EncodedCallToBuyCore; impl GetPurchaseCoreCall for EncodedCallToBuyCore { - fn get_encoded(max_amount: u128, para_id: ParaId) -> (Vec, Weight) { + fn get_encoded(max_amount: u128, para_id: ParaId) -> Vec { // TODO: this should use westend_runtime, but the polkadot 1.6.0 release does not have this pallet yet... // TODO: this should depend on the relay chain defined in the chain spec, can we do that? // probably the best solution would be to default to westend and use a storage item to override it // so that we can set rococo for tests - // TODO: return weight of parachains_assigner_on_demand::Call::place_order_allow_death - let weight = Weight::from_parts(1_000_000_000, 100_000); // TODO: use place_order_keep_alive? let call = rococo_calls::RelayCall::OnDemandAssignmentProvider( @@ -585,7 +556,7 @@ impl GetPurchaseCoreCall for EncodedCallToBuyCore { }, ); - (call.encode(), weight) + call.encode() } } diff --git a/runtime/dancebox/tests/common/xcm/core_buyer.rs b/runtime/dancebox/tests/common/xcm/core_buyer.rs index 23582026f..a7c4c1ca6 100644 --- a/runtime/dancebox/tests/common/xcm/core_buyer.rs +++ b/runtime/dancebox/tests/common/xcm/core_buyer.rs @@ -14,21 +14,25 @@ // You should have received a copy of the GNU General Public License // along with Tanssi. If not, see -use crate::common::xcm::mocknets::{DanceboxSender, RococoSender}; -use crate::common::xcm::*; -use crate::common::{dummy_boot_nodes, empty_genesis_data, run_to_session}; -use dancebox_runtime::{DataPreservers, Registrar, XcmCoreBuyer}; -use polkadot_runtime_parachains::assigner_on_demand as parachains_assigner_on_demand; -use sp_runtime::AccountId32; -use tp_traits::{ParaId, SlotFrequency}; -use xcm_emulator::RelayChain; use { - crate::common::xcm::mocknets::{ - DanceboxRococoPara as Dancebox, RococoRelay as Rococo, RococoRelayPallet, + crate::common::{ + dummy_boot_nodes, empty_genesis_data, run_to_session, + xcm::mocknets::{ + DanceboxRococoPara as Dancebox, DanceboxSender, RococoRelay as Rococo, + RococoRelayPallet, RococoSender, + }, + xcm::*, }, + core::marker::PhantomData, + cumulus_primitives_core::Weight, + dancebox_runtime::{DataPreservers, Registrar, XcmCoreBuyer}, frame_support::assert_ok, + pallet_xcm_core_buyer::XcmWeightsTy, + polkadot_runtime_parachains::assigner_on_demand as parachains_assigner_on_demand, + sp_runtime::AccountId32, staging_xcm_executor::traits::ConvertLocation, - xcm_emulator::Chain, + tp_traits::{ParaId, SlotFrequency}, + xcm_emulator::{Chain, RelayChain}, }; const PARATHREAD_ID: u32 = 3333; @@ -37,6 +41,7 @@ const BUY_EXECUTION_COST: u128 = dancebox_runtime::xcm_config::XCM_BUY_EXECUTION // Difference between BUY_EXECUTION_COST and the actual cost that depends on the weight of the XCM // message, gets refunded. const BUY_EXECUTION_REFUND: u128 = 5115980; +const PLACE_ORDER_WEIGHT_AT_MOST: Weight = Weight::from_parts(1_000_000_000, 100_000); #[test] fn constants() { @@ -116,6 +121,14 @@ fn do_test(tank_account_balance: u128) { // Send XCM message from Dancebox pallet XcmCoreBuyer Dancebox::execute_with(|| { let root_origin = ::RuntimeOrigin::root(); + assert_ok!(XcmCoreBuyer::set_xcm_weights( + root_origin.clone(), + Some(XcmWeightsTy { + buy_execution_cost: BUY_EXECUTION_COST, + weight_at_most: PLACE_ORDER_WEIGHT_AT_MOST, + _phantom: PhantomData, + }), + )); assert_ok!(XcmCoreBuyer::force_buy_core( root_origin, PARATHREAD_ID.into() From dd5f5cedc27ffe0308aa96a4fb0832ebbd5a8ed4 Mon Sep 17 00:00:00 2001 From: Tomasz Polaczyk Date: Fri, 15 Mar 2024 15:15:14 +0100 Subject: [PATCH 07/17] Add set_xcm_weights benchmark --- pallets/xcm-core-buyer/src/benchmarks.rs | 34 ++++++++++++++- pallets/xcm-core-buyer/src/lib.rs | 3 +- pallets/xcm-core-buyer/src/weights.rs | 55 +++++++++++++++++------- primitives/traits/src/lib.rs | 1 - 4 files changed, 73 insertions(+), 20 deletions(-) diff --git a/pallets/xcm-core-buyer/src/benchmarks.rs b/pallets/xcm-core-buyer/src/benchmarks.rs index 5b5f0989f..40b5de666 100644 --- a/pallets/xcm-core-buyer/src/benchmarks.rs +++ b/pallets/xcm-core-buyer/src/benchmarks.rs @@ -18,20 +18,36 @@ //! Benchmarking use { - crate::{Call, Config, GetParathreadCollators, GetParathreadParams, InFlightOrders, Pallet}, + crate::{ + Call, Config, GetParathreadCollators, GetParathreadParams, InFlightOrders, Pallet, + XcmWeights, XcmWeightsTy, + }, + core::marker::PhantomData, frame_benchmarking::{account, v2::*}, - frame_support::BoundedBTreeSet, + frame_support::{assert_ok, pallet_prelude::Weight, BoundedBTreeSet}, frame_system::RawOrigin, sp_std::{collections::btree_set::BTreeSet, vec}, tp_traits::{ParaId, ParathreadParams, SlotFrequency}, }; +pub const BUY_EXECUTION_COST: u128 = 50_000_000; +pub const PLACE_ORDER_WEIGHT_AT_MOST: Weight = Weight::from_parts(1_000_000_000, 100_000); + #[benchmarks] mod benchmarks { use super::*; #[benchmark] fn force_buy_core(x: Linear<1, 99>) { + assert_ok!(Pallet::::set_xcm_weights( + RawOrigin::Root.into(), + Some(XcmWeightsTy { + buy_execution_cost: BUY_EXECUTION_COST, + weight_at_most: PLACE_ORDER_WEIGHT_AT_MOST, + _phantom: PhantomData, + }), + )); + let para_id = ParaId::from(x + 1); assert_eq!(InFlightOrders::::get(), BTreeSet::new()); @@ -60,5 +76,19 @@ mod benchmarks { assert!(InFlightOrders::::get().contains(¶_id)); } + #[benchmark] + fn set_xcm_weights() { + let xcm_weights = XcmWeightsTy { + buy_execution_cost: BUY_EXECUTION_COST, + weight_at_most: PLACE_ORDER_WEIGHT_AT_MOST, + _phantom: PhantomData, + }; + + #[extrinsic_call] + Pallet::::set_xcm_weights(RawOrigin::Root, Some(xcm_weights.clone())); + + assert_eq!(XcmWeights::::get(), Some(xcm_weights)); + } + impl_benchmark_test_suite!(Pallet, crate::mock::new_test_ext(), crate::mock::Test); } diff --git a/pallets/xcm-core-buyer/src/lib.rs b/pallets/xcm-core-buyer/src/lib.rs index 7dc536f62..534af0c9a 100644 --- a/pallets/xcm-core-buyer/src/lib.rs +++ b/pallets/xcm-core-buyer/src/lib.rs @@ -197,8 +197,7 @@ pub mod pallet { } #[pallet::call_index(2)] - // TODO: weight - #[pallet::weight(T::WeightInfo::force_buy_core(T::MaxParathreads::get()))] + #[pallet::weight(T::WeightInfo::set_xcm_weights())] pub fn set_xcm_weights( origin: OriginFor, xcm_weights: Option>, diff --git a/pallets/xcm-core-buyer/src/weights.rs b/pallets/xcm-core-buyer/src/weights.rs index 2b453123d..5bc631512 100644 --- a/pallets/xcm-core-buyer/src/weights.rs +++ b/pallets/xcm-core-buyer/src/weights.rs @@ -18,7 +18,7 @@ //! Autogenerated weights for pallet_xcm_core_buyer //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2024-03-14, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2024-03-15, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` //! HOSTNAME: `tomasz-XPS-15-9520`, CPU: `12th Gen Intel(R) Core(TM) i7-12700H` //! EXECUTION: , WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024 @@ -54,6 +54,7 @@ use sp_std::marker::PhantomData; /// Weight functions needed for pallet_xcm_core_buyer. pub trait WeightInfo { fn force_buy_core(x: u32, ) -> Weight; + fn set_xcm_weights() -> Weight; } /// Weights for pallet_xcm_core_buyer using the Substrate node and recommended hardware. @@ -65,6 +66,8 @@ impl WeightInfo for SubstrateWeight { /// Proof: `XcmCoreBuyer::InFlightOrders` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) /// Storage: `Registrar::ParathreadParams` (r:1 w:0) /// Proof: `Registrar::ParathreadParams` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `XcmCoreBuyer::XcmWeights` (r:1 w:0) + /// Proof: `XcmCoreBuyer::XcmWeights` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) /// Storage: `PolkadotXcm::SupportedVersion` (r:1 w:0) /// Proof: `PolkadotXcm::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `PolkadotXcm::VersionDiscoveryQueue` (r:1 w:1) @@ -78,16 +81,26 @@ impl WeightInfo for SubstrateWeight { /// The range of component `x` is `[1, 99]`. fn force_buy_core(x: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `618 + x * (4 ±0)` - // Estimated: `4082 + x * (4 ±0)` - // Minimum execution time: 26_557_000 picoseconds. - Weight::from_parts(31_565_282, 4082) - // Standard Error: 1_405 - .saturating_add(Weight::from_parts(33_647, 0).saturating_mul(x.into())) - .saturating_add(T::DbWeight::get().reads(8_u64)) + // Measured: `665 + x * (4 ±0)` + // Estimated: `4129 + x * (4 ±0)` + // Minimum execution time: 30_726_000 picoseconds. + Weight::from_parts(33_061_964, 4129) + // Standard Error: 1_369 + .saturating_add(Weight::from_parts(28_154, 0).saturating_mul(x.into())) + .saturating_add(T::DbWeight::get().reads(9_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 4).saturating_mul(x.into())) } + /// Storage: `XcmCoreBuyer::XcmWeights` (r:0 w:1) + /// Proof: `XcmCoreBuyer::XcmWeights` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + fn set_xcm_weights() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 1_740_000 picoseconds. + Weight::from_parts(1_959_000, 0) + .saturating_add(T::DbWeight::get().writes(1_u64)) + } } // For backwards compatibility and tests @@ -98,6 +111,8 @@ impl WeightInfo for () { /// Proof: `XcmCoreBuyer::InFlightOrders` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) /// Storage: `Registrar::ParathreadParams` (r:1 w:0) /// Proof: `Registrar::ParathreadParams` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `XcmCoreBuyer::XcmWeights` (r:1 w:0) + /// Proof: `XcmCoreBuyer::XcmWeights` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) /// Storage: `PolkadotXcm::SupportedVersion` (r:1 w:0) /// Proof: `PolkadotXcm::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `PolkadotXcm::VersionDiscoveryQueue` (r:1 w:1) @@ -111,14 +126,24 @@ impl WeightInfo for () { /// The range of component `x` is `[1, 99]`. fn force_buy_core(x: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `618 + x * (4 ±0)` - // Estimated: `4082 + x * (4 ±0)` - // Minimum execution time: 26_557_000 picoseconds. - Weight::from_parts(31_565_282, 4082) - // Standard Error: 1_405 - .saturating_add(Weight::from_parts(33_647, 0).saturating_mul(x.into())) - .saturating_add(RocksDbWeight::get().reads(8_u64)) + // Measured: `665 + x * (4 ±0)` + // Estimated: `4129 + x * (4 ±0)` + // Minimum execution time: 30_726_000 picoseconds. + Weight::from_parts(33_061_964, 4129) + // Standard Error: 1_369 + .saturating_add(Weight::from_parts(28_154, 0).saturating_mul(x.into())) + .saturating_add(RocksDbWeight::get().reads(9_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 4).saturating_mul(x.into())) } + /// Storage: `XcmCoreBuyer::XcmWeights` (r:0 w:1) + /// Proof: `XcmCoreBuyer::XcmWeights` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + fn set_xcm_weights() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 1_740_000 picoseconds. + Weight::from_parts(1_959_000, 0) + .saturating_add(RocksDbWeight::get().writes(1_u64)) + } } diff --git a/primitives/traits/src/lib.rs b/primitives/traits/src/lib.rs index 15f96bed7..0fd0084d5 100644 --- a/primitives/traits/src/lib.rs +++ b/primitives/traits/src/lib.rs @@ -23,7 +23,6 @@ pub use cumulus_primitives_core::{ relay_chain::{BlockNumber, Slot}, ParaId, }; -use frame_support::__private::serde; use { frame_support::{ pallet_prelude::{Decode, DispatchResultWithPostInfo, Encode, Get, Weight}, From 396b791785717b1f9b2222eb29b09c3d339d4818 Mon Sep 17 00:00:00 2001 From: Tomasz Polaczyk Date: Fri, 15 Mar 2024 15:19:45 +0100 Subject: [PATCH 08/17] typescript-api --- .../dancebox/interfaces/augment-api-consts.ts | 10 + .../dancebox/interfaces/augment-api-errors.ts | 22 + .../dancebox/interfaces/augment-api-events.ts | 6 + .../dancebox/interfaces/augment-api-query.ts | 18 + .../src/dancebox/interfaces/augment-api-tx.ts | 36 ++ .../src/dancebox/interfaces/lookup.ts | 413 +++++++++-------- .../src/dancebox/interfaces/registry.ts | 10 + .../src/dancebox/interfaces/types-lookup.ts | 428 ++++++++++-------- 8 files changed, 577 insertions(+), 366 deletions(-) diff --git a/typescript-api/src/dancebox/interfaces/augment-api-consts.ts b/typescript-api/src/dancebox/interfaces/augment-api-consts.ts index 764c02f70..c3e2c02a2 100644 --- a/typescript-api/src/dancebox/interfaces/augment-api-consts.ts +++ b/typescript-api/src/dancebox/interfaces/augment-api-consts.ts @@ -288,6 +288,16 @@ declare module "@polkadot/api-base/types/consts" { /** Generic const */ [key: string]: Codec; }; + xcmCoreBuyer: { + /** + * A configuration for base priority of unsigned transactions. + * + * This is exposed so that it can be tuned for particular runtime, when multiple pallets send unsigned transactions. + */ + unsignedPriority: u64 & AugmentedConst; + /** Generic const */ + [key: string]: Codec; + }; xcmpQueue: { /** * The maximum number of inbound XCMP channels that can be suspended simultaneously. diff --git a/typescript-api/src/dancebox/interfaces/augment-api-errors.ts b/typescript-api/src/dancebox/interfaces/augment-api-errors.ts index a697b8297..3a9847594 100644 --- a/typescript-api/src/dancebox/interfaces/augment-api-errors.ts +++ b/typescript-api/src/dancebox/interfaces/augment-api-errors.ts @@ -540,6 +540,28 @@ declare module "@polkadot/api-base/types/errors" { /** Generic error */ [key: string]: AugmentedError; }; + xcmCoreBuyer: { + /** This collator is not assigned to this parathread */ + CollatorNotAssigned: AugmentedError; + ErrorDeliveringXCM: AugmentedError; + ErrorValidatingXCM: AugmentedError; + /** There are too many in-flight orders, buying cores will not work until some of those orders finish. */ + InFlightLimitReached: AugmentedError; + InvalidProof: AugmentedError; + /** There are no collators assigned to this parathread, so no point in buying a core */ + NoAssignedCollators: AugmentedError; + /** The para id is not a parathread */ + NotAParathread: AugmentedError; + /** An order for this para id already exists */ + OrderAlreadyExists: AugmentedError; + /** + * The `XcmWeights` storage has not been set. This must have been set by root with the value of the relay chain + * xcm call weight and extrinsic weight + */ + XcmWeightStorageNotSet: AugmentedError; + /** Generic error */ + [key: string]: AugmentedError; + }; xcmpQueue: { /** The execution is already resumed. */ AlreadyResumed: AugmentedError; diff --git a/typescript-api/src/dancebox/interfaces/augment-api-events.ts b/typescript-api/src/dancebox/interfaces/augment-api-events.ts index 9316ac505..4e5b66103 100644 --- a/typescript-api/src/dancebox/interfaces/augment-api-events.ts +++ b/typescript-api/src/dancebox/interfaces/augment-api-events.ts @@ -1291,6 +1291,12 @@ declare module "@polkadot/api-base/types/events" { /** Generic event */ [key: string]: AugmentedEvent; }; + xcmCoreBuyer: { + /** An XCM message to buy a core for this parathread has been sent to the relay chain. */ + BuyCoreXcmSent: AugmentedEvent; + /** Generic event */ + [key: string]: AugmentedEvent; + }; xcmpQueue: { /** An HRMP message was sent to a sibling parachain. */ XcmpMessageSent: AugmentedEvent; diff --git a/typescript-api/src/dancebox/interfaces/augment-api-query.ts b/typescript-api/src/dancebox/interfaces/augment-api-query.ts index 55d7b5bf0..0a39be6b1 100644 --- a/typescript-api/src/dancebox/interfaces/augment-api-query.ts +++ b/typescript-api/src/dancebox/interfaces/augment-api-query.ts @@ -69,6 +69,7 @@ import type { PalletTransactionPaymentReleases, PalletTreasuryProposal, PalletTreasurySpendStatus, + PalletXcmCoreBuyerXcmWeightsTy, PalletXcmQueryStatus, PalletXcmRemoteLockedFungibleRecord, PalletXcmVersionMigrationStage, @@ -1255,6 +1256,23 @@ declare module "@polkadot/api-base/types/storage" { /** Generic query */ [key: string]: QueryableStorageEntry; }; + xcmCoreBuyer: { + /** + * Set of parathreads that have already sent an XCM message to buy a core recently. Used to avoid 2 collators + * buying a core at the same time, because it is only possible to buy 1 core in 1 relay block. + */ + inFlightOrders: AugmentedQuery Observable>, []> & + QueryableStorageEntry; + /** + * This must be set by root with the value of the relay chain xcm call weight and extrinsic weight limit. This is + * a storage item because relay chain weights can change, so we need to be able to adjust them without doing a + * runtime upgrade. + */ + xcmWeights: AugmentedQuery Observable>, []> & + QueryableStorageEntry; + /** Generic query */ + [key: string]: QueryableStorageEntry; + }; xcmpQueue: { /** The factor to multiply the base delivery fee by. */ deliveryFeeFactor: AugmentedQuery Observable, [u32]> & diff --git a/typescript-api/src/dancebox/interfaces/augment-api-tx.ts b/typescript-api/src/dancebox/interfaces/augment-api-tx.ts index 46eb1956c..5b506d202 100644 --- a/typescript-api/src/dancebox/interfaces/augment-api-tx.ts +++ b/typescript-api/src/dancebox/interfaces/augment-api-tx.ts @@ -32,6 +32,8 @@ import type { PalletStreamPaymentChangeKind, PalletStreamPaymentDepositChange, PalletStreamPaymentStreamConfig, + PalletXcmCoreBuyerBuyCoreCollatorProof, + PalletXcmCoreBuyerXcmWeightsTy, SpRuntimeMultiSignature, SpWeightsWeightV2Weight, StagingXcmV3MultiLocation, @@ -2154,6 +2156,40 @@ declare module "@polkadot/api-base/types/submittable" { /** Generic tx */ [key: string]: SubmittableExtrinsicFunction; }; + xcmCoreBuyer: { + /** See [`Pallet::buy_core`]. */ + buyCore: AugmentedSubmittable< + ( + paraId: u32 | AnyNumber | Uint8Array, + proof: + | PalletXcmCoreBuyerBuyCoreCollatorProof + | { account?: any; signature?: any } + | string + | Uint8Array + ) => SubmittableExtrinsic, + [u32, PalletXcmCoreBuyerBuyCoreCollatorProof] + >; + /** See [`Pallet::force_buy_core`]. */ + forceBuyCore: AugmentedSubmittable< + (paraId: u32 | AnyNumber | Uint8Array) => SubmittableExtrinsic, + [u32] + >; + /** See [`Pallet::set_xcm_weights`]. */ + setXcmWeights: AugmentedSubmittable< + ( + xcmWeights: + | Option + | null + | Uint8Array + | PalletXcmCoreBuyerXcmWeightsTy + | { buyExecutionCost?: any; weightAtMost?: any } + | string + ) => SubmittableExtrinsic, + [Option] + >; + /** Generic tx */ + [key: string]: SubmittableExtrinsicFunction; + }; xcmpQueue: { /** See [`Pallet::resume_xcm_execution`]. */ resumeXcmExecution: AugmentedSubmittable<() => SubmittableExtrinsic, []>; diff --git a/typescript-api/src/dancebox/interfaces/lookup.ts b/typescript-api/src/dancebox/interfaces/lookup.ts index b4ad01967..96c9a990d 100644 --- a/typescript-api/src/dancebox/interfaces/lookup.ts +++ b/typescript-api/src/dancebox/interfaces/lookup.ts @@ -1748,11 +1748,19 @@ export default { Yield: "Null", }, }, - /** Lookup140: pallet_root_testing::pallet::Event */ + /** Lookup140: pallet_xcm_core_buyer::pallet::Event */ + PalletXcmCoreBuyerEvent: { + _enum: { + BuyCoreXcmSent: { + paraId: "u32", + }, + }, + }, + /** Lookup141: pallet_root_testing::pallet::Event */ PalletRootTestingEvent: { _enum: ["DefensiveTestCall"], }, - /** Lookup141: frame_system::Phase */ + /** Lookup142: frame_system::Phase */ FrameSystemPhase: { _enum: { ApplyExtrinsic: "u32", @@ -1760,17 +1768,17 @@ export default { Initialization: "Null", }, }, - /** Lookup145: frame_system::LastRuntimeUpgradeInfo */ + /** Lookup146: frame_system::LastRuntimeUpgradeInfo */ FrameSystemLastRuntimeUpgradeInfo: { specVersion: "Compact", specName: "Text", }, - /** Lookup147: frame_system::CodeUpgradeAuthorization */ + /** Lookup148: frame_system::CodeUpgradeAuthorization */ FrameSystemCodeUpgradeAuthorization: { codeHash: "H256", checkVersion: "bool", }, - /** Lookup148: frame_system::pallet::Call */ + /** Lookup149: frame_system::pallet::Call */ FrameSystemCall: { _enum: { remark: { @@ -1813,41 +1821,41 @@ export default { }, }, }, - /** Lookup152: frame_system::limits::BlockWeights */ + /** Lookup153: frame_system::limits::BlockWeights */ FrameSystemLimitsBlockWeights: { baseBlock: "SpWeightsWeightV2Weight", maxBlock: "SpWeightsWeightV2Weight", perClass: "FrameSupportDispatchPerDispatchClassWeightsPerClass", }, - /** Lookup153: frame_support::dispatch::PerDispatchClass */ + /** Lookup154: frame_support::dispatch::PerDispatchClass */ FrameSupportDispatchPerDispatchClassWeightsPerClass: { normal: "FrameSystemLimitsWeightsPerClass", operational: "FrameSystemLimitsWeightsPerClass", mandatory: "FrameSystemLimitsWeightsPerClass", }, - /** Lookup154: frame_system::limits::WeightsPerClass */ + /** Lookup155: frame_system::limits::WeightsPerClass */ FrameSystemLimitsWeightsPerClass: { baseExtrinsic: "SpWeightsWeightV2Weight", maxExtrinsic: "Option", maxTotal: "Option", reserved: "Option", }, - /** Lookup156: frame_system::limits::BlockLength */ + /** Lookup157: frame_system::limits::BlockLength */ FrameSystemLimitsBlockLength: { max: "FrameSupportDispatchPerDispatchClassU32", }, - /** Lookup157: frame_support::dispatch::PerDispatchClass */ + /** Lookup158: frame_support::dispatch::PerDispatchClass */ FrameSupportDispatchPerDispatchClassU32: { normal: "u32", operational: "u32", mandatory: "u32", }, - /** Lookup158: sp_weights::RuntimeDbWeight */ + /** Lookup159: sp_weights::RuntimeDbWeight */ SpWeightsRuntimeDbWeight: { read: "u64", write: "u64", }, - /** Lookup159: sp_version::RuntimeVersion */ + /** Lookup160: sp_version::RuntimeVersion */ SpVersionRuntimeVersion: { specName: "Text", implName: "Text", @@ -1858,7 +1866,7 @@ export default { transactionVersion: "u32", stateVersion: "u8", }, - /** Lookup163: frame_system::pallet::Error */ + /** Lookup164: frame_system::pallet::Error */ FrameSystemError: { _enum: [ "InvalidSpecName", @@ -1871,49 +1879,49 @@ export default { "Unauthorized", ], }, - /** Lookup165: cumulus_pallet_parachain_system::unincluded_segment::Ancestor */ + /** Lookup166: cumulus_pallet_parachain_system::unincluded_segment::Ancestor */ CumulusPalletParachainSystemUnincludedSegmentAncestor: { usedBandwidth: "CumulusPalletParachainSystemUnincludedSegmentUsedBandwidth", paraHeadHash: "Option", consumedGoAheadSignal: "Option", }, - /** Lookup166: cumulus_pallet_parachain_system::unincluded_segment::UsedBandwidth */ + /** Lookup167: cumulus_pallet_parachain_system::unincluded_segment::UsedBandwidth */ CumulusPalletParachainSystemUnincludedSegmentUsedBandwidth: { umpMsgCount: "u32", umpTotalBytes: "u32", hrmpOutgoing: "BTreeMap", }, - /** Lookup168: cumulus_pallet_parachain_system::unincluded_segment::HrmpChannelUpdate */ + /** Lookup169: cumulus_pallet_parachain_system::unincluded_segment::HrmpChannelUpdate */ CumulusPalletParachainSystemUnincludedSegmentHrmpChannelUpdate: { msgCount: "u32", totalBytes: "u32", }, - /** Lookup173: polkadot_primitives::v6::UpgradeGoAhead */ + /** Lookup174: polkadot_primitives::v6::UpgradeGoAhead */ PolkadotPrimitivesV6UpgradeGoAhead: { _enum: ["Abort", "GoAhead"], }, - /** Lookup174: cumulus_pallet_parachain_system::unincluded_segment::SegmentTracker */ + /** Lookup175: cumulus_pallet_parachain_system::unincluded_segment::SegmentTracker */ CumulusPalletParachainSystemUnincludedSegmentSegmentTracker: { usedBandwidth: "CumulusPalletParachainSystemUnincludedSegmentUsedBandwidth", hrmpWatermark: "Option", consumedGoAheadSignal: "Option", }, - /** Lookup175: polkadot_primitives::v6::PersistedValidationData */ + /** Lookup176: polkadot_primitives::v6::PersistedValidationData */ PolkadotPrimitivesV6PersistedValidationData: { parentHead: "Bytes", relayParentNumber: "u32", relayParentStorageRoot: "H256", maxPovSize: "u32", }, - /** Lookup178: polkadot_primitives::v6::UpgradeRestriction */ + /** Lookup179: polkadot_primitives::v6::UpgradeRestriction */ PolkadotPrimitivesV6UpgradeRestriction: { _enum: ["Present"], }, - /** Lookup179: sp_trie::storage_proof::StorageProof */ + /** Lookup180: sp_trie::storage_proof::StorageProof */ SpTrieStorageProof: { trieNodes: "BTreeSet", }, - /** Lookup181: cumulus_pallet_parachain_system::relay_state_snapshot::MessagingStateSnapshot */ + /** Lookup182: cumulus_pallet_parachain_system::relay_state_snapshot::MessagingStateSnapshot */ CumulusPalletParachainSystemRelayStateSnapshotMessagingStateSnapshot: { dmqMqcHead: "H256", relayDispatchQueueRemainingCapacity: @@ -1921,12 +1929,12 @@ export default { ingressChannels: "Vec<(u32,PolkadotPrimitivesV6AbridgedHrmpChannel)>", egressChannels: "Vec<(u32,PolkadotPrimitivesV6AbridgedHrmpChannel)>", }, - /** Lookup182: cumulus_pallet_parachain_system::relay_state_snapshot::RelayDispatchQueueRemainingCapacity */ + /** Lookup183: cumulus_pallet_parachain_system::relay_state_snapshot::RelayDispatchQueueRemainingCapacity */ CumulusPalletParachainSystemRelayStateSnapshotRelayDispatchQueueRemainingCapacity: { remainingCount: "u32", remainingSize: "u32", }, - /** Lookup185: polkadot_primitives::v6::AbridgedHrmpChannel */ + /** Lookup186: polkadot_primitives::v6::AbridgedHrmpChannel */ PolkadotPrimitivesV6AbridgedHrmpChannel: { maxCapacity: "u32", maxTotalSize: "u32", @@ -1935,7 +1943,7 @@ export default { totalSize: "u32", mqcHead: "Option", }, - /** Lookup186: polkadot_primitives::v6::AbridgedHostConfiguration */ + /** Lookup187: polkadot_primitives::v6::AbridgedHostConfiguration */ PolkadotPrimitivesV6AbridgedHostConfiguration: { maxCodeSize: "u32", maxHeadDataSize: "u32", @@ -1948,17 +1956,17 @@ export default { validationUpgradeDelay: "u32", asyncBackingParams: "PolkadotPrimitivesV6AsyncBackingAsyncBackingParams", }, - /** Lookup187: polkadot_primitives::v6::async_backing::AsyncBackingParams */ + /** Lookup188: polkadot_primitives::v6::async_backing::AsyncBackingParams */ PolkadotPrimitivesV6AsyncBackingAsyncBackingParams: { maxCandidateDepth: "u32", allowedAncestryLen: "u32", }, - /** Lookup193: polkadot_core_primitives::OutboundHrmpMessage */ + /** Lookup194: polkadot_core_primitives::OutboundHrmpMessage */ PolkadotCorePrimitivesOutboundHrmpMessage: { recipient: "u32", data: "Bytes", }, - /** Lookup194: cumulus_pallet_parachain_system::pallet::Call */ + /** Lookup195: cumulus_pallet_parachain_system::pallet::Call */ CumulusPalletParachainSystemCall: { _enum: { set_validation_data: { @@ -1976,24 +1984,24 @@ export default { }, }, }, - /** Lookup195: cumulus_primitives_parachain_inherent::ParachainInherentData */ + /** Lookup196: cumulus_primitives_parachain_inherent::ParachainInherentData */ CumulusPrimitivesParachainInherentParachainInherentData: { validationData: "PolkadotPrimitivesV6PersistedValidationData", relayChainState: "SpTrieStorageProof", downwardMessages: "Vec", horizontalMessages: "BTreeMap>", }, - /** Lookup197: polkadot_core_primitives::InboundDownwardMessage */ + /** Lookup198: polkadot_core_primitives::InboundDownwardMessage */ PolkadotCorePrimitivesInboundDownwardMessage: { sentAt: "u32", msg: "Bytes", }, - /** Lookup200: polkadot_core_primitives::InboundHrmpMessage */ + /** Lookup201: polkadot_core_primitives::InboundHrmpMessage */ PolkadotCorePrimitivesInboundHrmpMessage: { sentAt: "u32", data: "Bytes", }, - /** Lookup203: cumulus_pallet_parachain_system::pallet::Error */ + /** Lookup204: cumulus_pallet_parachain_system::pallet::Error */ CumulusPalletParachainSystemError: { _enum: [ "OverlappingUpgrades", @@ -2006,7 +2014,7 @@ export default { "Unauthorized", ], }, - /** Lookup204: pallet_timestamp::pallet::Call */ + /** Lookup205: pallet_timestamp::pallet::Call */ PalletTimestampCall: { _enum: { set: { @@ -2014,9 +2022,9 @@ export default { }, }, }, - /** Lookup205: staging_parachain_info::pallet::Call */ + /** Lookup206: staging_parachain_info::pallet::Call */ StagingParachainInfoCall: "Null", - /** Lookup206: pallet_sudo::pallet::Call */ + /** Lookup207: pallet_sudo::pallet::Call */ PalletSudoCall: { _enum: { sudo: { @@ -2039,7 +2047,7 @@ export default { remove_key: "Null", }, }, - /** Lookup208: pallet_utility::pallet::Call */ + /** Lookup209: pallet_utility::pallet::Call */ PalletUtilityCall: { _enum: { batch: { @@ -2065,7 +2073,7 @@ export default { }, }, }, - /** Lookup210: dancebox_runtime::OriginCaller */ + /** Lookup211: dancebox_runtime::OriginCaller */ DanceboxRuntimeOriginCaller: { _enum: { system: "FrameSupportDispatchRawOrigin", @@ -2124,7 +2132,7 @@ export default { PolkadotXcm: "PalletXcmOrigin", }, }, - /** Lookup211: frame_support::dispatch::RawOrigin */ + /** Lookup212: frame_support::dispatch::RawOrigin */ FrameSupportDispatchRawOrigin: { _enum: { Root: "Null", @@ -2132,23 +2140,23 @@ export default { None: "Null", }, }, - /** Lookup212: cumulus_pallet_xcm::pallet::Origin */ + /** Lookup213: cumulus_pallet_xcm::pallet::Origin */ CumulusPalletXcmOrigin: { _enum: { Relay: "Null", SiblingParachain: "u32", }, }, - /** Lookup213: pallet_xcm::pallet::Origin */ + /** Lookup214: pallet_xcm::pallet::Origin */ PalletXcmOrigin: { _enum: { Xcm: "StagingXcmV3MultiLocation", Response: "StagingXcmV3MultiLocation", }, }, - /** Lookup214: sp_core::Void */ + /** Lookup215: sp_core::Void */ SpCoreVoid: "Null", - /** Lookup215: pallet_proxy::pallet::Call */ + /** Lookup216: pallet_proxy::pallet::Call */ PalletProxyCall: { _enum: { proxy: { @@ -2199,11 +2207,11 @@ export default { }, }, }, - /** Lookup219: pallet_maintenance_mode::pallet::Call */ + /** Lookup220: pallet_maintenance_mode::pallet::Call */ PalletMaintenanceModeCall: { _enum: ["enter_maintenance_mode", "resume_normal_operation"], }, - /** Lookup220: pallet_tx_pause::pallet::Call */ + /** Lookup221: pallet_tx_pause::pallet::Call */ PalletTxPauseCall: { _enum: { pause: { @@ -2214,7 +2222,7 @@ export default { }, }, }, - /** Lookup221: pallet_balances::pallet::Call */ + /** Lookup222: pallet_balances::pallet::Call */ PalletBalancesCall: { _enum: { transfer_allow_death: { @@ -2249,7 +2257,7 @@ export default { }, }, }, - /** Lookup222: pallet_stream_payment::pallet::Call */ + /** Lookup223: pallet_stream_payment::pallet::Call */ PalletStreamPaymentCall: { _enum: { open_stream: { @@ -2284,7 +2292,7 @@ export default { }, }, }, - /** Lookup223: pallet_stream_payment::pallet::ChangeKind