From 98872cb5cdcc65369a0d48c6b2bab95d1be5d286 Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Mon, 8 Jan 2024 19:22:02 +0300 Subject: [PATCH] Added Polkadot <> Kusama bridge configuration (#108) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR adds bridge configuration to allow exchanging assets between Polkadot and Kusama Asset Hubs. So far we only support sending KSM from Kusama Asset Hub to Polkadot Asset Hub as wKSM + DOT from Polkadot Asset Hub to Kusama Asset Hub as wDOT. Other assets may be added later. The opposite direction is also supported, though it'll need dependencies upgrade to >= v1.4. --- Similar Rococo <> Westend bridge is also active on live chains. You may read docs on how to play with it here: https://github.com/paritytech/polkadot-sdk/blob/master/cumulus/parachains/runtimes/bridge-hubs/README.md For Polkadot <> Kusama bridge we have a dedicated branch for local zombienet tests: https://github.com/svyatonik/runtimes/tree/sv-pk-bridge-with-zombienet-tests. You may run autotests (exchanging assets) there - see https://github.com/svyatonik/runtimes/blob/sv-pk-bridge-with-zombienet-tests/system-parachains/bridge-hubs/zombienet/README.md for details. You may do manual tests by spawning local chains using those scripts and use https://github.com/svyatonik/runtimes/blob/sv-pk-bridge-with-zombienet-tests/system-parachains/bridge-hubs/zombienet/scripts/bridges_kusama_polkadot.sh script to run various commands - i.e. send assets manually. Polkadot js apps is also supported. --------- Co-authored-by: Branislav Kontur Co-authored-by: Bastian Köcher --- CHANGELOG.md | 1 + Cargo.lock | 215 +++++- Cargo.toml | 4 + .../src/tests/reserve_transfer.rs | 2 +- .../src/tests/reserve_transfer.rs | 2 +- .../emulated/common/src/impls.rs | 8 +- .../asset-hubs/asset-hub-kusama/Cargo.toml | 24 +- .../asset-hub-kusama/primitives/Cargo.toml | 33 + .../asset-hub-kusama/primitives/src/lib.rs | 68 ++ .../asset-hubs/asset-hub-kusama/src/lib.rs | 72 +- .../asset-hub-kusama/src/weights/mod.rs | 1 + .../weights/pallet_xcm_bridge_hub_router.rs | 110 +++ .../asset-hub-kusama/src/weights/xcm/mod.rs | 2 +- .../xcm/pallet_xcm_benchmarks_fungible.rs | 14 +- .../xcm/pallet_xcm_benchmarks_generic.rs | 225 ++++--- .../asset-hub-kusama/src/xcm_config.rs | 213 +++++- .../asset-hub-kusama/tests/tests.rs | 626 +++++++++++++++++- .../asset-hubs/asset-hub-polkadot/Cargo.toml | 28 +- .../asset-hub-polkadot/primitives/Cargo.toml | 33 + .../asset-hub-polkadot/primitives/src/lib.rs | 68 ++ .../asset-hubs/asset-hub-polkadot/src/lib.rs | 72 +- .../asset-hub-polkadot/src/weights/mod.rs | 1 + .../weights/pallet_xcm_bridge_hub_router.rs | 110 +++ .../asset-hub-polkadot/src/weights/xcm/mod.rs | 2 +- .../xcm/pallet_xcm_benchmarks_fungible.rs | 14 +- .../xcm/pallet_xcm_benchmarks_generic.rs | 221 ++++--- .../asset-hub-polkadot/src/xcm_config.rs | 209 +++++- .../asset-hub-polkadot/tests/tests.rs | 625 ++++++++++++++++- .../bridge-hubs/bridge-hub-kusama/Cargo.toml | 55 +- .../bridge-hub-kusama/primitives/Cargo.toml | 39 ++ .../bridge-hub-kusama/primitives/src/lib.rs | 153 +++++ .../src/bridge_to_polkadot_config.rs | 404 +++++++++++ .../bridge-hubs/bridge-hub-kusama/src/lib.rs | 186 +++++- .../bridge-hub-kusama/src/weights/mod.rs | 31 + .../src/weights/pallet_bridge_grandpa.rs | 63 ++ .../src/weights/pallet_bridge_messages.rs | 226 +++++++ .../src/weights/pallet_bridge_parachains.rs | 98 +++ .../src/weights/pallet_bridge_relayers.rs | 107 +++ .../bridge-hub-kusama/src/weights/xcm/mod.rs | 6 +- .../xcm/pallet_xcm_benchmarks_generic.rs | 233 ++++--- .../bridge-hub-kusama/src/xcm_config.rs | 38 +- .../bridge-hub-kusama/tests/tests.rs | 266 +++++++- .../bridge-hub-polkadot/Cargo.toml | 54 +- .../bridge-hub-polkadot/primitives/Cargo.toml | 39 ++ .../bridge-hub-polkadot/primitives/src/lib.rs | 146 ++++ .../src/bridge_to_kusama_config.rs | 400 +++++++++++ .../bridge-hub-polkadot/src/lib.rs | 186 +++++- .../bridge-hub-polkadot/src/weights/mod.rs | 31 + .../src/weights/pallet_bridge_grandpa.rs | 63 ++ .../src/weights/pallet_bridge_messages.rs | 226 +++++++ .../src/weights/pallet_bridge_parachains.rs | 96 +++ .../src/weights/pallet_bridge_relayers.rs | 107 +++ .../src/weights/xcm/mod.rs | 6 +- .../xcm/pallet_xcm_benchmarks_generic.rs | 233 ++++--- .../bridge-hub-polkadot/src/xcm_config.rs | 38 +- .../bridge-hub-polkadot/tests/tests.rs | 266 +++++++- 56 files changed, 6228 insertions(+), 571 deletions(-) create mode 100644 system-parachains/asset-hubs/asset-hub-kusama/primitives/Cargo.toml create mode 100644 system-parachains/asset-hubs/asset-hub-kusama/primitives/src/lib.rs create mode 100644 system-parachains/asset-hubs/asset-hub-kusama/src/weights/pallet_xcm_bridge_hub_router.rs create mode 100644 system-parachains/asset-hubs/asset-hub-polkadot/primitives/Cargo.toml create mode 100644 system-parachains/asset-hubs/asset-hub-polkadot/primitives/src/lib.rs create mode 100644 system-parachains/asset-hubs/asset-hub-polkadot/src/weights/pallet_xcm_bridge_hub_router.rs create mode 100644 system-parachains/bridge-hubs/bridge-hub-kusama/primitives/Cargo.toml create mode 100644 system-parachains/bridge-hubs/bridge-hub-kusama/primitives/src/lib.rs create mode 100644 system-parachains/bridge-hubs/bridge-hub-kusama/src/bridge_to_polkadot_config.rs create mode 100644 system-parachains/bridge-hubs/bridge-hub-kusama/src/weights/pallet_bridge_grandpa.rs create mode 100644 system-parachains/bridge-hubs/bridge-hub-kusama/src/weights/pallet_bridge_messages.rs create mode 100644 system-parachains/bridge-hubs/bridge-hub-kusama/src/weights/pallet_bridge_parachains.rs create mode 100644 system-parachains/bridge-hubs/bridge-hub-kusama/src/weights/pallet_bridge_relayers.rs create mode 100644 system-parachains/bridge-hubs/bridge-hub-polkadot/primitives/Cargo.toml create mode 100644 system-parachains/bridge-hubs/bridge-hub-polkadot/primitives/src/lib.rs create mode 100644 system-parachains/bridge-hubs/bridge-hub-polkadot/src/bridge_to_kusama_config.rs create mode 100644 system-parachains/bridge-hubs/bridge-hub-polkadot/src/weights/pallet_bridge_grandpa.rs create mode 100644 system-parachains/bridge-hubs/bridge-hub-polkadot/src/weights/pallet_bridge_messages.rs create mode 100644 system-parachains/bridge-hubs/bridge-hub-polkadot/src/weights/pallet_bridge_parachains.rs create mode 100644 system-parachains/bridge-hubs/bridge-hub-polkadot/src/weights/pallet_bridge_relayers.rs diff --git a/CHANGELOG.md b/CHANGELOG.md index 29bbe8c280..141c966da4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -27,6 +27,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - Treasury is able to spend various asset kinds ([polkadot-fellows/runtimes#87](https://github.com/polkadot-fellows/runtimes/pull/87)) - Add BEEFY to Polkadot ([polkadot-fellows/runtimes#65](https://github.com/polkadot-fellows/runtimes/pull/65)) - Fellowship Treasury pallet on Polkadot Collectives ([polkadot-fellows/runtimes#109](https://github.com/polkadot-fellows/runtimes/pull/109)) +- Added Polkadot <> Kusama bridge to support asset transfers between Asset Hubs ([polkadot-fellows/runtimes#108](https://github.com/polkadot-fellows/runtimes/pull/108)) ### Fixed diff --git a/Cargo.lock b/Cargo.lock index 046fe1d689..9069eaf411 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -553,6 +553,10 @@ version = "1.0.0" dependencies = [ "asset-test-utils", "assets-common", + "bp-asset-hub-kusama", + "bp-asset-hub-polkadot", + "bp-bridge-hub-kusama", + "bp-bridge-hub-polkadot", "cumulus-pallet-aura-ext", "cumulus-pallet-dmp-queue", "cumulus-pallet-parachain-system", @@ -592,11 +596,14 @@ dependencies = [ "pallet-utility", "pallet-xcm", "pallet-xcm-benchmarks", + "pallet-xcm-bridge-hub-router", "parachains-common", + "parachains-runtimes-test-utils", "parity-scale-codec", "polkadot-core-primitives", "polkadot-parachain-primitives", "polkadot-runtime-common", + "polkadot-runtime-constants", "primitive-types", "scale-info", "smallvec", @@ -606,6 +613,7 @@ dependencies = [ "sp-core", "sp-genesis-builder", "sp-inherents", + "sp-io", "sp-offchain", "sp-runtime", "sp-session", @@ -649,6 +657,10 @@ version = "1.0.0" dependencies = [ "asset-test-utils", "assets-common", + "bp-asset-hub-kusama", + "bp-asset-hub-polkadot", + "bp-bridge-hub-kusama", + "bp-bridge-hub-polkadot", "cumulus-pallet-aura-ext", "cumulus-pallet-dmp-queue", "cumulus-pallet-parachain-system", @@ -665,6 +677,7 @@ dependencies = [ "frame-system-rpc-runtime-api", "frame-try-runtime", "hex-literal", + "kusama-runtime-constants", "log", "pallet-asset-tx-payment", "pallet-assets", @@ -684,7 +697,9 @@ dependencies = [ "pallet-utility", "pallet-xcm", "pallet-xcm-benchmarks", + "pallet-xcm-bridge-hub-router", "parachains-common", + "parachains-runtimes-test-utils", "parity-scale-codec", "polkadot-core-primitives", "polkadot-parachain-primitives", @@ -698,6 +713,7 @@ dependencies = [ "sp-core", "sp-genesis-builder", "sp-inherents", + "sp-io", "sp-offchain", "sp-runtime", "sp-session", @@ -1120,6 +1136,30 @@ dependencies = [ "thiserror", ] +[[package]] +name = "bp-asset-hub-kusama" +version = "1.0.0" +dependencies = [ + "bp-xcm-bridge-hub-router", + "frame-support", + "parity-scale-codec", + "scale-info", + "sp-std", + "staging-xcm", +] + +[[package]] +name = "bp-asset-hub-polkadot" +version = "1.0.0" +dependencies = [ + "bp-xcm-bridge-hub-router", + "frame-support", + "parity-scale-codec", + "scale-info", + "sp-std", + "staging-xcm", +] + [[package]] name = "bp-bridge-hub-cumulus" version = "0.4.0" @@ -1136,6 +1176,36 @@ dependencies = [ "sp-std", ] +[[package]] +name = "bp-bridge-hub-kusama" +version = "1.0.0" +dependencies = [ + "bp-bridge-hub-cumulus", + "bp-messages", + "bp-runtime", + "frame-support", + "kusama-runtime-constants", + "polkadot-runtime-constants", + "sp-api", + "sp-runtime", + "sp-std", +] + +[[package]] +name = "bp-bridge-hub-polkadot" +version = "1.0.0" +dependencies = [ + "bp-bridge-hub-cumulus", + "bp-messages", + "bp-runtime", + "frame-support", + "kusama-runtime-constants", + "polkadot-runtime-constants", + "sp-api", + "sp-runtime", + "sp-std", +] + [[package]] name = "bp-bridge-hub-rococo" version = "0.4.0" @@ -1184,6 +1254,20 @@ dependencies = [ "sp-std", ] +[[package]] +name = "bp-kusama" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d69f61df356df3dbedf2dfbfec65ce673ff80121ad7eb319b84a093ebc24aaf9" +dependencies = [ + "bp-header-chain", + "bp-polkadot-core", + "bp-runtime", + "frame-support", + "sp-api", + "sp-std", +] + [[package]] name = "bp-messages" version = "0.4.0" @@ -1218,6 +1302,20 @@ dependencies = [ "sp-std", ] +[[package]] +name = "bp-polkadot" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2643dd8c1c9f82517cb0f438bb66533e8f0b54d8c4b063d24f835aa620e4034" +dependencies = [ + "bp-header-chain", + "bp-polkadot-core", + "bp-runtime", + "frame-support", + "sp-api", + "sp-std", +] + [[package]] name = "bp-polkadot-core" version = "0.4.0" @@ -1313,7 +1411,20 @@ dependencies = [ name = "bridge-hub-kusama-runtime" version = "1.0.0" dependencies = [ + "bp-asset-hub-kusama", + "bp-asset-hub-polkadot", + "bp-bridge-hub-kusama", + "bp-bridge-hub-polkadot", + "bp-header-chain", + "bp-kusama", + "bp-messages", + "bp-parachains", + "bp-polkadot", + "bp-polkadot-core", + "bp-relayers", + "bp-runtime", "bridge-hub-test-utils", + "bridge-runtime-common", "cumulus-pallet-aura-ext", "cumulus-pallet-dmp-queue", "cumulus-pallet-parachain-system", @@ -1335,6 +1446,10 @@ dependencies = [ "pallet-aura", "pallet-authorship", "pallet-balances", + "pallet-bridge-grandpa", + "pallet-bridge-messages", + "pallet-bridge-parachains", + "pallet-bridge-relayers", "pallet-collator-selection", "pallet-multisig", "pallet-session", @@ -1359,6 +1474,7 @@ dependencies = [ "sp-genesis-builder", "sp-inherents", "sp-io", + "sp-keyring", "sp-offchain", "sp-runtime", "sp-session", @@ -1370,6 +1486,7 @@ dependencies = [ "staging-xcm", "staging-xcm-builder", "staging-xcm-executor", + "static_assertions", "substrate-wasm-builder", "system-parachains-constants", ] @@ -1378,7 +1495,20 @@ dependencies = [ name = "bridge-hub-polkadot-runtime" version = "1.0.0" dependencies = [ + "bp-asset-hub-kusama", + "bp-asset-hub-polkadot", + "bp-bridge-hub-kusama", + "bp-bridge-hub-polkadot", + "bp-header-chain", + "bp-kusama", + "bp-messages", + "bp-parachains", + "bp-polkadot", + "bp-polkadot-core", + "bp-relayers", + "bp-runtime", "bridge-hub-test-utils", + "bridge-runtime-common", "cumulus-pallet-aura-ext", "cumulus-pallet-dmp-queue", "cumulus-pallet-parachain-system", @@ -1399,6 +1529,10 @@ dependencies = [ "pallet-aura", "pallet-authorship", "pallet-balances", + "pallet-bridge-grandpa", + "pallet-bridge-messages", + "pallet-bridge-parachains", + "pallet-bridge-relayers", "pallet-collator-selection", "pallet-multisig", "pallet-session", @@ -1424,6 +1558,7 @@ dependencies = [ "sp-genesis-builder", "sp-inherents", "sp-io", + "sp-keyring", "sp-offchain", "sp-runtime", "sp-session", @@ -1435,6 +1570,7 @@ dependencies = [ "staging-xcm", "staging-xcm-builder", "staging-xcm-executor", + "static_assertions", "substrate-wasm-builder", "system-parachains-constants", ] @@ -1521,6 +1657,7 @@ dependencies = [ "sp-trie", "staging-xcm", "staging-xcm-builder", + "static_assertions", ] [[package]] @@ -2411,7 +2548,7 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "84baea20d10325b2501b6fa06d4a7902a43d6a6c62c71b5309e75c3ad8ae1441" dependencies = [ - "proc-macro-crate", + "proc-macro-crate 1.3.1", "proc-macro2", "quote", "syn 2.0.38", @@ -3324,7 +3461,7 @@ checksum = "f5aa1e3ae159e592ad222dc90c5acbad632b527779ba88486abe92782ab268bd" dependencies = [ "expander 0.0.4", "indexmap 1.9.3", - "proc-macro-crate", + "proc-macro-crate 1.3.1", "proc-macro2", "quote", "syn 1.0.109", @@ -3504,7 +3641,7 @@ version = "12.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "03911cf3675af64252a6de7b4f383eafa80d5ea5830184e7a0739aeb0b95272d" dependencies = [ - "proc-macro-crate", + "proc-macro-crate 1.3.1", "proc-macro2", "quote", "syn 2.0.38", @@ -3649,7 +3786,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b3ac1266522a8c9a2d2d26d205ec3028b88582d5f3cd5cbc75d0ec8271d197b7" dependencies = [ "frame-support-procedural-tools-derive", - "proc-macro-crate", + "proc-macro-crate 1.3.1", "proc-macro2", "quote", "syn 2.0.38", @@ -4746,7 +4883,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "44e8ab85614a08792b9bff6c8feee23be78c98d0182d4c622c05256ab553892a" dependencies = [ "heck", - "proc-macro-crate", + "proc-macro-crate 1.3.1", "proc-macro2", "quote", "syn 1.0.109", @@ -5851,7 +5988,7 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc076939022111618a5026d3be019fd8b366e76314538ff9a1b59ffbcbf98bcd" dependencies = [ - "proc-macro-crate", + "proc-macro-crate 1.3.1", "proc-macro-error", "proc-macro2", "quote", @@ -6194,7 +6331,7 @@ dependencies = [ "indexmap 2.0.0", "itertools 0.11.0", "petgraph", - "proc-macro-crate", + "proc-macro-crate 1.3.1", "proc-macro2", "quote", "syn 1.0.109", @@ -7349,7 +7486,7 @@ version = "10.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df8878e29f3d001ac1b1b714621f462e41a9d1fa8f385657f955e8a1ec0684d7" dependencies = [ - "proc-macro-crate", + "proc-macro-crate 1.3.1", "proc-macro2", "quote", "syn 2.0.38", @@ -7720,9 +7857,9 @@ dependencies = [ [[package]] name = "parity-scale-codec" -version = "3.6.4" +version = "3.6.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8e946cc0cc711189c0b0249fb8b599cbeeab9784d83c415719368bb8d4ac64" +checksum = "881331e34fa842a2fb61cc2db9643a8fedc615e47cfcc52597d1af0db9a7e8fe" dependencies = [ "arrayvec 0.7.4", "bitvec", @@ -7735,11 +7872,11 @@ dependencies = [ [[package]] name = "parity-scale-codec-derive" -version = "3.6.4" +version = "3.6.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a296c3079b5fefbc499e1de58dc26c09b1b9a5952d26694ee89f04a43ebbb3e" +checksum = "be30eaf4b0a9fba5336683b38de57bb86d179a35862ba6bfcf57625d006bde5b" dependencies = [ - "proc-macro-crate", + "proc-macro-crate 2.0.0", "proc-macro2", "quote", "syn 1.0.109", @@ -8638,7 +8775,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" dependencies = [ "once_cell", - "toml_edit", + "toml_edit 0.19.14", +] + +[[package]] +name = "proc-macro-crate" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e8366a6159044a37876a2b9817124296703c586a5c92e2c53751fa06d8d43e8" +dependencies = [ + "toml_edit 0.20.2", ] [[package]] @@ -8684,9 +8830,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.69" +version = "1.0.70" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +checksum = "39278fbbf5fb4f646ce651690877f89d1c5811a3d4acb27700c1cb3cdb78fd3b" dependencies = [ "unicode-ident", ] @@ -9533,7 +9679,7 @@ version = "10.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1f25158f791eb48715da9322375598b541cadd1f193674e8a4d77c79ffa3d95d" dependencies = [ - "proc-macro-crate", + "proc-macro-crate 1.3.1", "proc-macro2", "quote", "syn 2.0.38", @@ -10187,7 +10333,7 @@ version = "10.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c4ae9e4f957d7274ac6b59d667b66262caf6482dbb1b63f1c370528626b1272" dependencies = [ - "proc-macro-crate", + "proc-macro-crate 1.3.1", "proc-macro2", "quote", "syn 2.0.38", @@ -10273,7 +10419,7 @@ version = "2.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "abf2c68b89cafb3b8d918dd07b42be0da66ff202cf1155c5739a4e0c1ea0dc19" dependencies = [ - "proc-macro-crate", + "proc-macro-crate 1.3.1", "proc-macro2", "quote", "syn 1.0.109", @@ -10471,18 +10617,18 @@ checksum = "f97841a747eef040fcd2e7b3b9a220a7205926e60488e673d9e4926d27772ce5" [[package]] name = "serde" -version = "1.0.188" +version = "1.0.193" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf9e0fcba69a370eed61bcf2b728575f726b50b55cba78064753d708ddc7549e" +checksum = "25dd9975e68d0cb5aa1120c288333fc98731bd1dd12f561e468ea4728c042b89" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.188" +version = "1.0.193" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2" +checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3" dependencies = [ "proc-macro2", "quote", @@ -10672,9 +10818,9 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.11.0" +version = "1.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62bb4feee49fdd9f707ef802e22365a35de4b7b299de4763d44bfea899442ff9" +checksum = "4dccd0940a2dcdf68d092b8cbab7dc0ad8fa938bf95787e1b916b0e3d0e8e970" [[package]] name = "snap" @@ -10767,7 +10913,7 @@ dependencies = [ "Inflector", "blake2 0.10.6", "expander 2.0.0", - "proc-macro-crate", + "proc-macro-crate 1.3.1", "proc-macro2", "quote", "syn 2.0.38", @@ -11286,7 +11432,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b2afcbd1bd18d323371111b66b7ac2870bdc1c86c3d7b0dae67b112ca52b4d8" dependencies = [ "Inflector", - "proc-macro-crate", + "proc-macro-crate 1.3.1", "proc-macro2", "quote", "syn 2.0.38", @@ -12309,7 +12455,7 @@ dependencies = [ "serde", "serde_spanned", "toml_datetime", - "toml_edit", + "toml_edit 0.19.14", ] [[package]] @@ -12334,6 +12480,17 @@ dependencies = [ "winnow", ] +[[package]] +name = "toml_edit" +version = "0.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "396e4d48bbb2b7554c944bde63101b5ae446cff6ec4a24227428f15eb72ef338" +dependencies = [ + "indexmap 2.0.0", + "toml_datetime", + "winnow", +] + [[package]] name = "tower" version = "0.4.13" @@ -12439,7 +12596,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "35756d8c1a227ec525853a1080bf890d03d939deb2bc50d4d43c96516c795d0d" dependencies = [ "expander 2.0.0", - "proc-macro-crate", + "proc-macro-crate 1.3.1", "proc-macro2", "quote", "syn 2.0.38", diff --git a/Cargo.toml b/Cargo.toml index 8baf12752c..60818e781e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,9 +14,13 @@ members = [ "relay/polkadot", "relay/polkadot/constants", "system-parachains/asset-hubs/asset-hub-kusama", + "system-parachains/asset-hubs/asset-hub-kusama/primitives", "system-parachains/asset-hubs/asset-hub-polkadot", + "system-parachains/asset-hubs/asset-hub-polkadot/primitives", "system-parachains/bridge-hubs/bridge-hub-kusama", + "system-parachains/bridge-hubs/bridge-hub-kusama/primitives", "system-parachains/bridge-hubs/bridge-hub-polkadot", + "system-parachains/bridge-hubs/bridge-hub-polkadot/primitives", "system-parachains/collectives/collectives-polkadot", "system-parachains/constants", "system-parachains/gluttons/glutton-kusama", diff --git a/integration-tests/emulated/assets/asset-hub-kusama/src/tests/reserve_transfer.rs b/integration-tests/emulated/assets/asset-hub-kusama/src/tests/reserve_transfer.rs index 8792a14f6c..cc2e7a66b3 100644 --- a/integration-tests/emulated/assets/asset-hub-kusama/src/tests/reserve_transfer.rs +++ b/integration-tests/emulated/assets/asset-hub-kusama/src/tests/reserve_transfer.rs @@ -36,7 +36,7 @@ fn relay_origin_assertions(t: RelayToSystemParaTest) { } fn system_para_dest_assertions_incomplete(_t: RelayToSystemParaTest) { - AssetHubKusama::assert_dmp_queue_incomplete(Some(Error::WeightNotComputable)); + AssetHubKusama::assert_dmp_queue_incomplete(None, Some(Error::UntrustedReserveLocation)); } fn system_para_to_relay_assertions(_t: SystemParaToRelayTest) { diff --git a/integration-tests/emulated/assets/asset-hub-polkadot/src/tests/reserve_transfer.rs b/integration-tests/emulated/assets/asset-hub-polkadot/src/tests/reserve_transfer.rs index 5fe9d6b1f0..96c4358abd 100644 --- a/integration-tests/emulated/assets/asset-hub-polkadot/src/tests/reserve_transfer.rs +++ b/integration-tests/emulated/assets/asset-hub-polkadot/src/tests/reserve_transfer.rs @@ -36,7 +36,7 @@ fn relay_origin_assertions(t: RelayToSystemParaTest) { } fn system_para_dest_assertions_incomplete(_t: RelayToSystemParaTest) { - AssetHubPolkadot::assert_dmp_queue_incomplete(Some(Error::WeightNotComputable)); + AssetHubPolkadot::assert_dmp_queue_incomplete(None, Some(Error::UntrustedReserveLocation)); } fn system_para_to_relay_assertions(_t: SystemParaToRelayTest) { diff --git a/integration-tests/emulated/common/src/impls.rs b/integration-tests/emulated/common/src/impls.rs index e55f1bbe9c..5969b8ac84 100644 --- a/integration-tests/emulated/common/src/impls.rs +++ b/integration-tests/emulated/common/src/impls.rs @@ -474,14 +474,20 @@ macro_rules! impl_assert_events_helpers_for_parachain { /// Asserts a XCM from Relay Chain is incompletely executed pub fn assert_dmp_queue_incomplete( + expected_weight: Option<$crate::impls::Weight>, expected_error: Option<$crate::impls::Error>, ) { $crate::impls::assert_expected_events!( Self, vec![ [<$chain RuntimeEvent>]::DmpQueue($crate::impls::cumulus_pallet_dmp_queue::Event::ExecutedDownward { - outcome: $crate::impls::Outcome::Error(error), .. + outcome: $crate::impls::Outcome::Incomplete(weight, error), .. }) => { + weight: $crate::impls::weight_within_threshold( + ($crate::impls::REF_TIME_THRESHOLD, $crate::impls::PROOF_SIZE_THRESHOLD), + expected_weight.unwrap_or(*weight), + *weight + ), error: *error == expected_error.unwrap_or(*error), }, ] diff --git a/system-parachains/asset-hubs/asset-hub-kusama/Cargo.toml b/system-parachains/asset-hubs/asset-hub-kusama/Cargo.toml index b5e514e71f..bd3da40fe6 100644 --- a/system-parachains/asset-hubs/asset-hub-kusama/Cargo.toml +++ b/system-parachains/asset-hubs/asset-hub-kusama/Cargo.toml @@ -15,6 +15,14 @@ log = { version = "0.4.20", default-features = false } scale-info = { version = "2.9.0", default-features = false, features = ["derive"] } smallvec = "1.11.0" +# Local +bp-asset-hub-kusama = { path = "./primitives", default-features = false} +bp-asset-hub-polkadot = { path = "../asset-hub-polkadot/primitives", default-features = false} +bp-bridge-hub-kusama = { path = "../../bridge-hubs/bridge-hub-kusama/primitives", default-features = false} +bp-bridge-hub-polkadot = { path = "../../bridge-hubs/bridge-hub-polkadot/primitives", default-features = false} +kusama-runtime-constants = { path = "../../../relay/kusama/constants", default-features = false} +polkadot-runtime-constants = { path = "../../../relay/polkadot/constants", default-features = false} + # Substrate frame-benchmarking = { default-features = false, optional = true, version = "25.0.0" } frame-executive = { default-features = false, version = "25.0.0" } @@ -59,7 +67,6 @@ sp-weights = { default-features = false, version = "24.0.0" } primitive-types = { version = "0.12.2", default-features = false, features = ["codec", "scale-info", "num-traits"] } # Polkadot -kusama-runtime-constants = { path = "../../../relay/kusama/constants", default-features = false} pallet-xcm = { default-features = false, version = "4.0.0" } pallet-xcm-benchmarks = { default-features = false, optional = true , version = "4.0.0" } polkadot-core-primitives = { default-features = false, version = "4.0.0" } @@ -75,7 +82,7 @@ cumulus-pallet-dmp-queue = { default-features = false , version = "0.4.0" } cumulus-pallet-parachain-system = { default-features = false, features = ["parameterized-consensus-hook",] , version = "0.4.0" } cumulus-pallet-session-benchmarking = { default-features = false, version = "6.0.0" } cumulus-pallet-xcm = { default-features = false , version = "0.4.0" } -cumulus-pallet-xcmp-queue = { default-features = false , version = "0.4.0" } +cumulus-pallet-xcmp-queue = { default-features = false , features = ["bridging"] , version = "0.4.0" } cumulus-primitives-core = { default-features = false , version = "0.4.0" } cumulus-primitives-utility = { default-features = false , version = "0.4.0" } pallet-collator-selection = { default-features = false , version = "6.0.0" } @@ -84,8 +91,13 @@ parachains-common = { default-features = false , version = "4.0.0" } system-parachains-constants = { path = "../../constants", default-features = false } assets-common = { default-features = false , version = "0.4.0" } +# Bridges +pallet-xcm-bridge-hub-router = { default-features = false , version = "0.2.0" } + [dev-dependencies] asset-test-utils = { version = "4.0.0" } +parachains-runtimes-test-utils = { version = "4.0.0" } +sp-io = { version = "27.0.0" } [build-dependencies] substrate-wasm-builder = { optional = true , version = "14.0.0" } @@ -123,6 +135,7 @@ runtime-benchmarks = [ "pallet-uniques/runtime-benchmarks", "pallet-utility/runtime-benchmarks", "pallet-xcm-benchmarks/runtime-benchmarks", + "pallet-xcm-bridge-hub-router/runtime-benchmarks", "pallet-xcm/runtime-benchmarks", "polkadot-parachain-primitives/runtime-benchmarks", "polkadot-runtime-common/runtime-benchmarks", @@ -157,6 +170,7 @@ try-runtime = [ "pallet-transaction-payment/try-runtime", "pallet-uniques/try-runtime", "pallet-utility/try-runtime", + "pallet-xcm-bridge-hub-router/try-runtime", "pallet-xcm/try-runtime", "parachain-info/try-runtime", "polkadot-runtime-common/try-runtime", @@ -164,6 +178,10 @@ try-runtime = [ ] std = [ "assets-common/std", + "bp-asset-hub-kusama/std", + "bp-bridge-hub-kusama/std", + "bp-asset-hub-polkadot/std", + "bp-bridge-hub-polkadot/std", "codec/std", "cumulus-pallet-aura-ext/std", "cumulus-pallet-dmp-queue/std", @@ -202,12 +220,14 @@ std = [ "pallet-uniques/std", "pallet-utility/std", "pallet-xcm-benchmarks?/std", + "pallet-xcm-bridge-hub-router/std", "pallet-xcm/std", "parachain-info/std", "parachains-common/std", "polkadot-core-primitives/std", "polkadot-parachain-primitives/std", "polkadot-runtime-common/std", + "polkadot-runtime-constants/std", "scale-info/std", "sp-api/std", "sp-block-builder/std", diff --git a/system-parachains/asset-hubs/asset-hub-kusama/primitives/Cargo.toml b/system-parachains/asset-hubs/asset-hub-kusama/primitives/Cargo.toml new file mode 100644 index 0000000000..b8eab108b7 --- /dev/null +++ b/system-parachains/asset-hubs/asset-hub-kusama/primitives/Cargo.toml @@ -0,0 +1,33 @@ +[package] +name = "bp-asset-hub-kusama" +description = "Primitives of AssetHubKusama parachain runtime." +repository.workspace = true +version.workspace = true +authors.workspace = true +edition.workspace = true +license.workspace = true + +[dependencies] +codec = { package = "parity-scale-codec", version = "3.0.0", default-features = false, features = ["derive", "max-encoded-len"] } +scale-info = { version = "2.9.0", default-features = false, features = ["derive"] } + +# Bridge Dependencies +bp-xcm-bridge-hub-router = { default-features = false , version = "0.3.0" } + +# Substrate Based Dependencies +frame-support = { default-features = false, version = "25.0.0" } +sp-std = { default-features = false, version = "12.0.0" } + +# Polkadot +xcm = { package = "staging-xcm", default-features = false, version = "4.0.0" } + +[features] +default = [ "std" ] +std = [ + "bp-xcm-bridge-hub-router/std", + "codec/std", + "frame-support/std", + "scale-info/std", + "sp-std/std", + "xcm/std" +] diff --git a/system-parachains/asset-hubs/asset-hub-kusama/primitives/src/lib.rs b/system-parachains/asset-hubs/asset-hub-kusama/primitives/src/lib.rs new file mode 100644 index 0000000000..18f8efbf6f --- /dev/null +++ b/system-parachains/asset-hubs/asset-hub-kusama/primitives/src/lib.rs @@ -0,0 +1,68 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Polkadot is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Polkadot. If not, see . + +//! Module with configuration which reflects AssetHubKusama runtime setup. + +#![cfg_attr(not(feature = "std"), no_std)] + +use codec::{Decode, Encode}; +use frame_support::weights::Weight; +use scale_info::TypeInfo; +use xcm::prelude::*; + +pub use bp_xcm_bridge_hub_router::XcmBridgeHubRouterCall; + +/// `AssetHubKusama` Runtime `Call` enum. +/// +/// The enum represents a subset of possible `Call`s we can send to `AssetHubKusama` chain. +/// Ideally this code would be auto-generated from metadata, because we want to +/// avoid depending directly on the ENTIRE runtime just to get the encoding of `Dispatchable`s. +/// +/// All entries here (like pretty much in the entire file) must be kept in sync with +/// `AssetHubKusama` `construct_runtime`, so that we maintain SCALE-compatibility. +#[allow(clippy::large_enum_variant)] +#[derive(Encode, Decode, Debug, PartialEq, Eq, Clone, TypeInfo)] +pub enum Call { + /// `ToPolkadotXcmRouter` bridge pallet. + #[codec(index = 34)] + ToPolkadotXcmRouter(XcmBridgeHubRouterCall), +} + +frame_support::parameter_types! { + /// Some sane weight to execute `xcm::Transact(pallet-xcm-bridge-hub-router::Call::report_bridge_status)`. + pub const XcmBridgeHubRouterTransactCallMaxWeight: Weight = Weight::from_parts(200_000_000, 6144); + + /// Message that is sent to the sibling Kusama Asset Hub when the with-Polkadot bridge becomes congested. + pub CongestedMessage: Xcm<()> = build_congestion_message(true).into(); + /// Message that is sent to the sibling Kusama Asset Hub when the with-Polkadot bridge becomes uncongested. + pub UncongestedMessage: Xcm<()> = build_congestion_message(false).into(); +} + +fn build_congestion_message(is_congested: bool) -> sp_std::vec::Vec> { + sp_std::vec![ + UnpaidExecution { weight_limit: Unlimited, check_origin: None }, + Transact { + origin_kind: OriginKind::Xcm, + require_weight_at_most: XcmBridgeHubRouterTransactCallMaxWeight::get(), + call: Call::ToPolkadotXcmRouter(XcmBridgeHubRouterCall::report_bridge_status { + bridge_id: Default::default(), + is_congested, + }) + .encode() + .into(), + } + ] +} diff --git a/system-parachains/asset-hubs/asset-hub-kusama/src/lib.rs b/system-parachains/asset-hubs/asset-hub-kusama/src/lib.rs index 5c93017890..92ba0a9641 100644 --- a/system-parachains/asset-hubs/asset-hub-kusama/src/lib.rs +++ b/system-parachains/asset-hubs/asset-hub-kusama/src/lib.rs @@ -56,7 +56,7 @@ use frame_support::{ ord_parameter_types, parameter_types, traits::{ AsEnsureOriginWithArg, ConstBool, ConstU128, ConstU32, ConstU64, ConstU8, EitherOfDiverse, - InstanceFilter, + Equals, InstanceFilter, }, weights::{ConstantMultiplier, Weight}, BoundedVec, PalletId, @@ -836,6 +836,37 @@ impl pallet_nfts::Config for Runtime { type Helper = (); } +/// XCM router instance to BridgeHub with bridging capabilities for `Polkadot` global +/// consensus with dynamic fees and back-pressure. +pub type ToPolkadotXcmRouterInstance = pallet_xcm_bridge_hub_router::Instance1; +impl pallet_xcm_bridge_hub_router::Config for Runtime { + type WeightInfo = weights::pallet_xcm_bridge_hub_router::WeightInfo; + + type UniversalLocation = xcm_config::UniversalLocation; + type BridgedNetworkId = xcm_config::bridging::to_polkadot::PolkadotNetwork; + type Bridges = xcm_config::bridging::NetworkExportTable; + + #[cfg(not(feature = "runtime-benchmarks"))] + type BridgeHubOrigin = EnsureXcm>; + #[cfg(feature = "runtime-benchmarks")] + type BridgeHubOrigin = frame_support::traits::EitherOfDiverse< + // for running benchmarks + EnsureRoot, + // for running tests with `--feature runtime-benchmarks` + EnsureXcm>, + >; + + type ToBridgeHubSender = XcmpQueue; + type WithBridgeHubChannel = + cumulus_pallet_xcmp_queue::bridging::InAndOutXcmpChannelStatusProvider< + xcm_config::bridging::SiblingBridgeHubParaId, + Runtime, + >; + + type ByteFee = xcm_config::bridging::XcmBridgeHubRouterByteFee; + type FeeAsset = xcm_config::bridging::XcmBridgeHubRouterFeeAssetId; +} + // Create the runtime by composing the FRAME pallets that were previously configured. construct_runtime!( pub enum Runtime @@ -866,6 +897,7 @@ construct_runtime!( PolkadotXcm: pallet_xcm::{Pallet, Call, Storage, Event, Origin, Config} = 31, CumulusXcm: cumulus_pallet_xcm::{Pallet, Event, Origin} = 32, DmpQueue: cumulus_pallet_dmp_queue::{Pallet, Call, Storage, Event} = 33, + ToPolkadotXcmRouter: pallet_xcm_bridge_hub_router::::{Pallet, Storage, Call} = 34, // Handy utilities. Utility: pallet_utility::{Pallet, Call, Event} = 40, @@ -947,6 +979,8 @@ mod benches { [cumulus_pallet_xcmp_queue, XcmpQueue] // XCM [pallet_xcm, PolkadotXcm] + // Bridges + [pallet_xcm_bridge_hub_router, ToPolkadot] // NOTE: Make sure you point to the individual modules below. [pallet_xcm_benchmarks::fungible, XcmBalances] [pallet_xcm_benchmarks::generic, XcmGeneric] @@ -1194,6 +1228,7 @@ impl_runtime_apis! { use frame_support::traits::StorageInfoTrait; use frame_system_benchmarking::Pallet as SystemBench; use cumulus_pallet_session_benchmarking::Pallet as SessionBench; + use pallet_xcm_bridge_hub_router::benchmarking::Pallet as XcmBridgeHubRouterBench; // This is defined once again in dispatch_benchmark, because list_benchmarks! // and add_benchmarks! are macros exported by define_benchmarks! macros and those types @@ -1209,6 +1244,8 @@ impl_runtime_apis! { type Foreign = pallet_assets::Pallet::; type Pool = pallet_assets::Pallet::; + type ToPolkadot = XcmBridgeHubRouterBench; + let mut list = Vec::::new(); list_benchmarks!(list, extra); @@ -1292,7 +1329,13 @@ impl_runtime_apis! { MultiAsset { fun: Fungible(UNITS), id: Concrete(KsmLocation::get()) }, )); pub const CheckedAccount: Option<(AccountId, xcm_builder::MintLocation)> = None; - pub const TrustedReserve: Option<(MultiLocation, MultiAsset)> = None; + // AssetHubKusama trusts AssetHubPolkadot as reserve for DOTs + pub TrustedReserve: Option<(MultiLocation, MultiAsset)> = Some( + ( + xcm_config::bridging::to_polkadot::AssetHubPolkadot::get(), + MultiAsset::from((xcm_config::bridging::to_polkadot::DotLocation::get(), 1000000000000 as u128)) + ) + ); } impl pallet_xcm_benchmarks::fungible::Config for Runtime { @@ -1323,7 +1366,8 @@ impl_runtime_apis! { } fn universal_alias() -> Result<(MultiLocation, Junction), BenchmarkError> { - Err(BenchmarkError::Skip) + xcm_config::bridging::BridgingBenchmarksHelper::prepare_universal_alias() + .ok_or(BenchmarkError::Skip) } fn transact_origin_and_runtime_call() -> Result<(MultiLocation, RuntimeCall), BenchmarkError> { @@ -1355,6 +1399,26 @@ impl_runtime_apis! { } } + use pallet_xcm_bridge_hub_router::benchmarking::{ + Pallet as XcmBridgeHubRouterBench, + Config as XcmBridgeHubRouterConfig, + }; + + impl XcmBridgeHubRouterConfig for Runtime { + fn make_congested() { + cumulus_pallet_xcmp_queue::bridging::suspend_channel_for_benchmarks::( + xcm_config::bridging::SiblingBridgeHubParaId::get().into() + ); + } + + fn ensure_bridged_target_destination() -> MultiLocation { + ParachainSystem::open_outbound_hrmp_channel_for_benchmarks_or_tests( + xcm_config::bridging::SiblingBridgeHubParaId::get().into() + ); + xcm_config::bridging::to_polkadot::AssetHubPolkadot::get() + } + } + type XcmBalances = pallet_xcm_benchmarks::fungible::Pallet::; type XcmGeneric = pallet_xcm_benchmarks::generic::Pallet::; @@ -1362,6 +1426,8 @@ impl_runtime_apis! { type Foreign = pallet_assets::Pallet::; type Pool = pallet_assets::Pallet::; + type ToPolkadot = XcmBridgeHubRouterBench; + let whitelist: Vec = vec![ // Block Number hex_literal::hex!("26aa394eea5630e07c48ae0c9558cef702a5c1b19ab7a04f536c519aca4983ac").to_vec().into(), diff --git a/system-parachains/asset-hubs/asset-hub-kusama/src/weights/mod.rs b/system-parachains/asset-hubs/asset-hub-kusama/src/weights/mod.rs index 9d92330275..0295549956 100644 --- a/system-parachains/asset-hubs/asset-hub-kusama/src/weights/mod.rs +++ b/system-parachains/asset-hubs/asset-hub-kusama/src/weights/mod.rs @@ -33,6 +33,7 @@ pub mod pallet_timestamp; pub mod pallet_uniques; pub mod pallet_utility; pub mod pallet_xcm; +pub mod pallet_xcm_bridge_hub_router; pub mod paritydb_weights; pub mod rocksdb_weights; pub mod xcm; diff --git a/system-parachains/asset-hubs/asset-hub-kusama/src/weights/pallet_xcm_bridge_hub_router.rs b/system-parachains/asset-hubs/asset-hub-kusama/src/weights/pallet_xcm_bridge_hub_router.rs new file mode 100644 index 0000000000..714722f94a --- /dev/null +++ b/system-parachains/asset-hubs/asset-hub-kusama/src/weights/pallet_xcm_bridge_hub_router.rs @@ -0,0 +1,110 @@ + +//! Autogenerated weights for `pallet_xcm_bridge_hub_router` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-12-05, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `svyatonik-benchmarking`, CPU: `Intel(R) Xeon(R) CPU @ 2.80GHz` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("ah-kusama-local-raw.json")`, DB CACHE: 1024 + +// Executed Command: +// ../polkadot-sdk/target/production/polkadot-parachain-benchmarks +// benchmark +// pallet +// --chain +// ah-kusama-local-raw.json +// --pallet +// pallet-xcm-bridge-hub-router +// --extrinsic +// * +// --output=system-parachains/asset-hubs/asset-hub-kusama/src/weights +// --no-median-slopes +// --no-min-squares + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_xcm_bridge_hub_router`. +pub struct WeightInfo(PhantomData); +impl pallet_xcm_bridge_hub_router::WeightInfo for WeightInfo { + /// Storage: `XcmpQueue::InboundXcmpStatus` (r:1 w:0) + /// Proof: `XcmpQueue::InboundXcmpStatus` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `XcmpQueue::OutboundXcmpStatus` (r:1 w:0) + /// Proof: `XcmpQueue::OutboundXcmpStatus` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ToPolkadotXcmRouter::Bridge` (r:1 w:1) + /// Proof: `ToPolkadotXcmRouter::Bridge` (`max_values`: Some(1), `max_size`: Some(17), added: 512, mode: `MaxEncodedLen`) + fn on_initialize_when_non_congested() -> Weight { + // Proof Size summary in bytes: + // Measured: `159` + // Estimated: `1644` + // Minimum execution time: 10_642_000 picoseconds. + Weight::from_parts(11_071_000, 0) + .saturating_add(Weight::from_parts(0, 1644)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: `XcmpQueue::InboundXcmpStatus` (r:1 w:0) + /// Proof: `XcmpQueue::InboundXcmpStatus` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `XcmpQueue::OutboundXcmpStatus` (r:1 w:0) + /// Proof: `XcmpQueue::OutboundXcmpStatus` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + fn on_initialize_when_congested() -> Weight { + // Proof Size summary in bytes: + // Measured: `111` + // Estimated: `1596` + // Minimum execution time: 5_037_000 picoseconds. + Weight::from_parts(5_209_000, 0) + .saturating_add(Weight::from_parts(0, 1596)) + .saturating_add(T::DbWeight::get().reads(2)) + } + /// Storage: `ToPolkadotXcmRouter::Bridge` (r:1 w:1) + /// Proof: `ToPolkadotXcmRouter::Bridge` (`max_values`: Some(1), `max_size`: Some(17), added: 512, mode: `MaxEncodedLen`) + fn report_bridge_status() -> Weight { + // Proof Size summary in bytes: + // Measured: `83` + // Estimated: `1502` + // Minimum execution time: 13_006_000 picoseconds. + Weight::from_parts(13_656_000, 0) + .saturating_add(Weight::from_parts(0, 1502)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: `ParachainInfo::ParachainId` (r:1 w:0) + /// Proof: `ParachainInfo::ParachainId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: UNKNOWN KEY `0x3302afcb67e838a3f960251b417b9a4f` (r:1 w:0) + /// Proof: UNKNOWN KEY `0x3302afcb67e838a3f960251b417b9a4f` (r:1 w:0) + /// Storage: UNKNOWN KEY `0x0973fe64c85043ba1c965cbc38eb63c7` (r:1 w:0) + /// Proof: UNKNOWN KEY `0x0973fe64c85043ba1c965cbc38eb63c7` (r:1 w:0) + /// Storage: `ToPolkadotXcmRouter::Bridge` (r:1 w:1) + /// Proof: `ToPolkadotXcmRouter::Bridge` (`max_values`: Some(1), `max_size`: Some(17), added: 512, mode: `MaxEncodedLen`) + /// Storage: `XcmpQueue::DeliveryFeeFactor` (r:1 w:0) + /// Proof: `XcmpQueue::DeliveryFeeFactor` (`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::RelevantMessagingState` (r:1 w:0) + /// Proof: `ParachainSystem::RelevantMessagingState` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `XcmpQueue::OutboundXcmpStatus` (r:1 w:1) + /// Proof: `XcmpQueue::OutboundXcmpStatus` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `XcmpQueue::InboundXcmpStatus` (r:1 w:0) + /// Proof: `XcmpQueue::InboundXcmpStatus` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `XcmpQueue::OutboundXcmpMessages` (r:0 w:1) + /// Proof: `XcmpQueue::OutboundXcmpMessages` (`max_values`: None, `max_size`: None, mode: `Measured`) + fn send_message() -> Weight { + // Proof Size summary in bytes: + // Measured: `392` + // Estimated: `3857` + // Minimum execution time: 63_791_000 picoseconds. + Weight::from_parts(68_199_000, 0) + .saturating_add(Weight::from_parts(0, 3857)) + .saturating_add(T::DbWeight::get().reads(11)) + .saturating_add(T::DbWeight::get().writes(4)) + } +} diff --git a/system-parachains/asset-hubs/asset-hub-kusama/src/weights/xcm/mod.rs b/system-parachains/asset-hubs/asset-hub-kusama/src/weights/xcm/mod.rs index ce6e920651..ffae9fb6c3 100644 --- a/system-parachains/asset-hubs/asset-hub-kusama/src/weights/xcm/mod.rs +++ b/system-parachains/asset-hubs/asset-hub-kusama/src/weights/xcm/mod.rs @@ -209,7 +209,7 @@ impl XcmWeightInfo for AssetHubKusamaXcmWeight { XcmGeneric::::clear_transact_status() } fn universal_origin(_: &Junction) -> Weight { - Weight::MAX + XcmGeneric::::universal_origin() } fn export_message(_: &NetworkId, _: &Junctions, _: &Xcm<()>) -> Weight { Weight::MAX diff --git a/system-parachains/asset-hubs/asset-hub-kusama/src/weights/xcm/pallet_xcm_benchmarks_fungible.rs b/system-parachains/asset-hubs/asset-hub-kusama/src/weights/xcm/pallet_xcm_benchmarks_fungible.rs index d8344feeb2..f7bf0a5808 100644 --- a/system-parachains/asset-hubs/asset-hub-kusama/src/weights/xcm/pallet_xcm_benchmarks_fungible.rs +++ b/system-parachains/asset-hubs/asset-hub-kusama/src/weights/xcm/pallet_xcm_benchmarks_fungible.rs @@ -97,15 +97,15 @@ impl WeightInfo { .saturating_add(T::DbWeight::get().reads(10)) .saturating_add(T::DbWeight::get().writes(5)) } - /// Storage: `Benchmark::Override` (r:0 w:0) - /// Proof: `Benchmark::Override` (`max_values`: None, `max_size`: None, mode: `Measured`) - pub(crate) fn reserve_asset_deposited() -> Weight { + // Storage: `ParachainInfo::ParachainId` (r:1 w:0) + // Proof: `ParachainInfo::ParachainId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + pub fn reserve_asset_deposited() -> Weight { // Proof Size summary in bytes: // Measured: `0` - // Estimated: `0` - // Minimum execution time: 18_446_744_073_709_551_000 picoseconds. - Weight::from_parts(18_446_744_073_709_551_000, 0) - .saturating_add(Weight::from_parts(0, 0)) + // Estimated: `1489` + // Minimum execution time: 7_855_000 picoseconds. + Weight::from_parts(8_015_000, 1489) + .saturating_add(T::DbWeight::get().reads(1)) } /// Storage: `ParachainInfo::ParachainId` (r:1 w:0) /// Proof: `ParachainInfo::ParachainId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) diff --git a/system-parachains/asset-hubs/asset-hub-kusama/src/weights/xcm/pallet_xcm_benchmarks_generic.rs b/system-parachains/asset-hubs/asset-hub-kusama/src/weights/xcm/pallet_xcm_benchmarks_generic.rs index 625549ecfc..a5603c41c9 100644 --- a/system-parachains/asset-hubs/asset-hub-kusama/src/weights/xcm/pallet_xcm_benchmarks_generic.rs +++ b/system-parachains/asset-hubs/asset-hub-kusama/src/weights/xcm/pallet_xcm_benchmarks_generic.rs @@ -1,44 +1,26 @@ -// Copyright (C) Parity Technologies (UK) Ltd. -// This file is part of Cumulus. - -// Cumulus is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Cumulus is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Cumulus. If not, see . //! Autogenerated weights for `pallet_xcm_benchmarks::generic` //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-07-31, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2023-12-05, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-ynta1nyy-project-238-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! EXECUTION: , WASM-EXECUTION: Compiled, CHAIN: Some("asset-hub-kusama-dev"), DB CACHE: 1024 +//! HOSTNAME: `svyatonik-benchmarking`, CPU: `Intel(R) Xeon(R) CPU @ 2.80GHz` +//! WASM-EXECUTION: Compiled, CHAIN: Some("ah-kusama-local-raw.json"), DB CACHE: 1024 // Executed Command: -// ./target/production/polkadot-parachain +// ../polkadot-sdk/target/production/polkadot-parachain-benchmarks // benchmark // pallet -// --template=./templates/xcm-bench-template.hbs -// --chain=asset-hub-kusama-dev -// --wasm-execution=compiled -// --pallet=pallet_xcm_benchmarks::generic -// --no-storage-info +// --chain +// ah-kusama-local-raw.json +// --pallet +// pallet-xcm-benchmarks::generic +// --extrinsic +// report_holding,buy_execution,query_response,transact,refund_surplus,set_error_handler,set_appendix,clear_error,descend_origin,clear_origin,report_error,claim_asset,trap,subscribe_version,unsubscribe_version,burn_asset,expect_asset,expect_origin,expect_error,expect_transact_status,query_pallet,report_transact_status,clear_transact_status,set_topic,clear_topic,export_message,set_fees_mode,unpaid_execution,universal_origin +// --template=../polkadot-sdk/cumulus/templates/xcm-bench-template.hbs +// --output=system-parachains/asset-hubs/asset-hub-kusama/src/weights/xcm // --no-median-slopes // --no-min-squares -// --extrinsic=* -// --steps=50 -// --repeat=20 -// --json -// --header=./file_header.txt -// --output=./parachains/runtimes/assets/asset-hub-kusama/src/weights/xcm/pallet_xcm_benchmarks_generic.rs #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -52,31 +34,35 @@ pub struct WeightInfo(PhantomData); impl WeightInfo { // Storage: `ParachainInfo::ParachainId` (r:1 w:0) // Proof: `ParachainInfo::ParachainId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + // Storage: `ParachainSystem::UpwardDeliveryFeeFactor` (r:1 w:0) + // Proof: `ParachainSystem::UpwardDeliveryFeeFactor` (`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) // 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: `System::Account` (r:2 w:2) + // Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) // 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`) pub fn report_holding() -> Weight { // Proof Size summary in bytes: - // Measured: `109` - // Estimated: `3574` - // Minimum execution time: 432_196_000 picoseconds. - Weight::from_parts(438_017_000, 3574) - .saturating_add(T::DbWeight::get().reads(6)) - .saturating_add(T::DbWeight::get().writes(2)) + // Measured: `246` + // Estimated: `6196` + // Minimum execution time: 491_370_000 picoseconds. + Weight::from_parts(499_900_000, 6196) + .saturating_add(T::DbWeight::get().reads(9)) + .saturating_add(T::DbWeight::get().writes(4)) } pub fn buy_execution() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 4_223_000 picoseconds. - Weight::from_parts(4_412_000, 0) + // Minimum execution time: 3_604_000 picoseconds. + Weight::from_parts(3_809_000, 0) } // Storage: `PolkadotXcm::Queries` (r:1 w:0) // Proof: `PolkadotXcm::Queries` (`max_values`: None, `max_size`: None, mode: `Measured`) @@ -84,79 +70,83 @@ impl WeightInfo { // Proof Size summary in bytes: // Measured: `103` // Estimated: `3568` - // Minimum execution time: 11_582_000 picoseconds. - Weight::from_parts(11_830_000, 3568) + // Minimum execution time: 11_038_000 picoseconds. + Weight::from_parts(11_599_000, 3568) .saturating_add(T::DbWeight::get().reads(1)) } pub fn transact() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 13_955_000 picoseconds. - Weight::from_parts(14_320_000, 0) + // Minimum execution time: 12_310_000 picoseconds. + Weight::from_parts(12_701_000, 0) } pub fn refund_surplus() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 4_423_000 picoseconds. - Weight::from_parts(4_709_000, 0) + // Minimum execution time: 3_835_000 picoseconds. + Weight::from_parts(4_027_000, 0) } pub fn set_error_handler() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 3_028_000 picoseconds. - Weight::from_parts(3_151_000, 0) + // Minimum execution time: 2_374_000 picoseconds. + Weight::from_parts(2_462_000, 0) } pub fn set_appendix() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_966_000 picoseconds. - Weight::from_parts(3_076_000, 0) + // Minimum execution time: 2_338_000 picoseconds. + Weight::from_parts(2_426_000, 0) } pub fn clear_error() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_971_000 picoseconds. - Weight::from_parts(3_119_000, 0) + // Minimum execution time: 2_334_000 picoseconds. + Weight::from_parts(2_430_000, 0) } pub fn descend_origin() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 3_772_000 picoseconds. - Weight::from_parts(3_853_000, 0) + // Minimum execution time: 3_333_000 picoseconds. + Weight::from_parts(3_403_000, 0) } pub fn clear_origin() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_940_000 picoseconds. - Weight::from_parts(3_050_000, 0) + // Minimum execution time: 2_330_000 picoseconds. + Weight::from_parts(2_401_000, 0) } // Storage: `ParachainInfo::ParachainId` (r:1 w:0) // Proof: `ParachainInfo::ParachainId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + // Storage: `ParachainSystem::UpwardDeliveryFeeFactor` (r:1 w:0) + // Proof: `ParachainSystem::UpwardDeliveryFeeFactor` (`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) // 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: `System::Account` (r:2 w:2) + // Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) // 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`) pub fn report_error() -> Weight { // Proof Size summary in bytes: - // Measured: `109` - // Estimated: `3574` - // Minimum execution time: 27_734_000 picoseconds. - Weight::from_parts(28_351_000, 3574) - .saturating_add(T::DbWeight::get().reads(6)) - .saturating_add(T::DbWeight::get().writes(2)) + // Measured: `246` + // Estimated: `6196` + // Minimum execution time: 67_780_000 picoseconds. + Weight::from_parts(69_179_000, 6196) + .saturating_add(T::DbWeight::get().reads(9)) + .saturating_add(T::DbWeight::get().writes(4)) } // Storage: `PolkadotXcm::AssetTraps` (r:1 w:1) // Proof: `PolkadotXcm::AssetTraps` (`max_values`: None, `max_size`: None, mode: `Measured`) @@ -164,8 +154,8 @@ impl WeightInfo { // Proof Size summary in bytes: // Measured: `160` // Estimated: `3625` - // Minimum execution time: 16_456_000 picoseconds. - Weight::from_parts(16_846_000, 3625) + // Minimum execution time: 15_239_000 picoseconds. + Weight::from_parts(15_551_000, 3625) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } @@ -173,11 +163,13 @@ impl WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_974_000 picoseconds. - Weight::from_parts(3_108_000, 0) + // Minimum execution time: 2_407_000 picoseconds. + Weight::from_parts(2_476_000, 0) } // Storage: `PolkadotXcm::VersionNotifyTargets` (r:1 w:1) // Proof: `PolkadotXcm::VersionNotifyTargets` (`max_values`: None, `max_size`: None, mode: `Measured`) + // Storage: `ParachainSystem::UpwardDeliveryFeeFactor` (r:1 w:0) + // Proof: `ParachainSystem::UpwardDeliveryFeeFactor` (`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) @@ -190,11 +182,11 @@ impl WeightInfo { // Proof: `ParachainSystem::PendingUpwardMessages` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) pub fn subscribe_version() -> Weight { // Proof Size summary in bytes: - // Measured: `109` - // Estimated: `3574` - // Minimum execution time: 29_823_000 picoseconds. - Weight::from_parts(30_776_000, 3574) - .saturating_add(T::DbWeight::get().reads(6)) + // Measured: `145` + // Estimated: `3610` + // Minimum execution time: 30_637_000 picoseconds. + Weight::from_parts(31_296_000, 3610) + .saturating_add(T::DbWeight::get().reads(7)) .saturating_add(T::DbWeight::get().writes(3)) } // Storage: `PolkadotXcm::VersionNotifyTargets` (r:0 w:1) @@ -203,127 +195,140 @@ impl WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 4_966_000 picoseconds. - Weight::from_parts(5_157_000, 0) + // Minimum execution time: 4_863_000 picoseconds. + Weight::from_parts(5_051_000, 0) .saturating_add(T::DbWeight::get().writes(1)) } pub fn burn_asset() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 141_875_000 picoseconds. - Weight::from_parts(144_925_000, 0) + // Minimum execution time: 145_285_000 picoseconds. + Weight::from_parts(145_935_000, 0) } pub fn expect_asset() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 13_147_000 picoseconds. - Weight::from_parts(13_420_000, 0) + // Minimum execution time: 14_934_000 picoseconds. + Weight::from_parts(15_299_000, 0) } pub fn expect_origin() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 3_050_000 picoseconds. - Weight::from_parts(3_161_000, 0) + // Minimum execution time: 2_482_000 picoseconds. + Weight::from_parts(2_556_000, 0) } pub fn expect_error() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_930_000 picoseconds. - Weight::from_parts(3_077_000, 0) + // Minimum execution time: 2_374_000 picoseconds. + Weight::from_parts(2_442_000, 0) } pub fn expect_transact_status() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 3_188_000 picoseconds. - Weight::from_parts(3_299_000, 0) + // Minimum execution time: 2_660_000 picoseconds. + Weight::from_parts(2_762_000, 0) } // Storage: `ParachainInfo::ParachainId` (r:1 w:0) // Proof: `ParachainInfo::ParachainId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + // Storage: `ParachainSystem::UpwardDeliveryFeeFactor` (r:1 w:0) + // Proof: `ParachainSystem::UpwardDeliveryFeeFactor` (`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) // 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: `System::Account` (r:2 w:2) + // Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) // 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`) pub fn query_pallet() -> Weight { // Proof Size summary in bytes: - // Measured: `109` - // Estimated: `3574` - // Minimum execution time: 31_678_000 picoseconds. - Weight::from_parts(32_462_000, 3574) - .saturating_add(T::DbWeight::get().reads(6)) - .saturating_add(T::DbWeight::get().writes(2)) - } - pub fn expect_pallet() -> Weight { - // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 5_638_000 picoseconds. - Weight::from_parts(5_756_000, 0) + // Measured: `246` + // Estimated: `6196` + // Minimum execution time: 72_570_000 picoseconds. + Weight::from_parts(74_250_000, 6196) + .saturating_add(T::DbWeight::get().reads(9)) + .saturating_add(T::DbWeight::get().writes(4)) } // Storage: `ParachainInfo::ParachainId` (r:1 w:0) // Proof: `ParachainInfo::ParachainId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + // Storage: `ParachainSystem::UpwardDeliveryFeeFactor` (r:1 w:0) + // Proof: `ParachainSystem::UpwardDeliveryFeeFactor` (`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) // 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: `System::Account` (r:2 w:2) + // Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) // 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`) pub fn report_transact_status() -> Weight { // Proof Size summary in bytes: - // Measured: `109` - // Estimated: `3574` - // Minimum execution time: 27_556_000 picoseconds. - Weight::from_parts(28_240_000, 3574) - .saturating_add(T::DbWeight::get().reads(6)) - .saturating_add(T::DbWeight::get().writes(2)) + // Measured: `246` + // Estimated: `6196` + // Minimum execution time: 67_731_000 picoseconds. + Weight::from_parts(68_921_000, 6196) + .saturating_add(T::DbWeight::get().reads(9)) + .saturating_add(T::DbWeight::get().writes(4)) } pub fn clear_transact_status() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_932_000 picoseconds. - Weight::from_parts(3_097_000, 0) + // Minimum execution time: 2_417_000 picoseconds. + Weight::from_parts(2_480_000, 0) } pub fn set_topic() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_860_000 picoseconds. - Weight::from_parts(2_957_000, 0) + // Minimum execution time: 2_331_000 picoseconds. + Weight::from_parts(2_439_000, 0) } pub fn clear_topic() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_886_000 picoseconds. - Weight::from_parts(3_015_000, 0) + // Minimum execution time: 2_336_000 picoseconds. + Weight::from_parts(2_402_000, 0) + } + // Storage: `ParachainInfo::ParachainId` (r:1 w:0) + // Proof: `ParachainInfo::ParachainId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + pub fn universal_origin() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `1489` + // Minimum execution time: 4_903_000 picoseconds. + Weight::from_parts(5_042_000, 1489) + .saturating_add(T::DbWeight::get().reads(1)) } pub fn set_fees_mode() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_874_000 picoseconds. - Weight::from_parts(3_060_000, 0) + // Minimum execution time: 2_338_000 picoseconds. + Weight::from_parts(2_436_000, 0) } pub fn unpaid_execution() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 3_029_000 picoseconds. - Weight::from_parts(3_158_000, 0) + // Minimum execution time: 2_545_000 picoseconds. + Weight::from_parts(2_605_000, 0) } } + +impl WeightInfo { pub fn expect_pallet() -> Weight { Weight::from_parts(5_756_000, 0) } } diff --git a/system-parachains/asset-hubs/asset-hub-kusama/src/xcm_config.rs b/system-parachains/asset-hubs/asset-hub-kusama/src/xcm_config.rs index 1f9eb0acad..489e38458a 100644 --- a/system-parachains/asset-hubs/asset-hub-kusama/src/xcm_config.rs +++ b/system-parachains/asset-hubs/asset-hub-kusama/src/xcm_config.rs @@ -16,9 +16,10 @@ use super::{ AccountId, AllPalletsWithSystem, Assets, Authorship, Balance, Balances, ParachainInfo, ParachainSystem, PolkadotXcm, PoolAssets, PriceForParentDelivery, Runtime, RuntimeCall, - RuntimeEvent, RuntimeOrigin, TrustBackedAssetsInstance, WeightToFee, XcmpQueue, + RuntimeEvent, RuntimeOrigin, ToPolkadotXcmRouter, TransactionByteFee, + TrustBackedAssetsInstance, WeightToFee, XcmpQueue, }; -use crate::ForeignAssets; +use crate::{ForeignAssets, ForeignAssetsInstance}; use assets_common::{ local_and_foreign_assets::MatchesLocalAndForeignAssetsMultiLocation, matching::{FromSiblingParachain, IsForeignConcreteAsset}, @@ -45,12 +46,12 @@ use xcm_builder::{ AccountId32Aliases, AllowExplicitUnpaidExecutionFrom, AllowKnownQueryResponses, AllowSubscriptionsFrom, AllowTopLevelPaidExecutionFrom, CurrencyAdapter, DenyReserveTransferToRelayChain, DenyThenTry, DescribeAllTerminal, DescribeFamily, - EnsureXcmOrigin, FungiblesAdapter, HashedDescription, IsConcrete, LocalMint, NoChecking, - ParentAsSuperuser, ParentIsPreset, RelayChainAsNative, SiblingParachainAsNative, - SiblingParachainConvertsVia, SignedAccountId32AsNative, SignedToAccountId32, - SovereignSignedViaLocation, StartsWith, StartsWithExplicitGlobalConsensus, TakeWeightCredit, - TrailingSetTopicAsId, UsingComponents, WeightInfoBounds, WithComputedOrigin, WithUniqueTopic, - XcmFeesToAccount, + EnsureXcmOrigin, FungiblesAdapter, GlobalConsensusParachainConvertsFor, HashedDescription, + IsConcrete, LocalMint, NoChecking, ParentAsSuperuser, ParentIsPreset, RelayChainAsNative, + SiblingParachainAsNative, SiblingParachainConvertsVia, SignedAccountId32AsNative, + SignedToAccountId32, SovereignSignedViaLocation, StartsWith, StartsWithExplicitGlobalConsensus, + TakeWeightCredit, TrailingSetTopicAsId, UsingComponents, WeightInfoBounds, WithComputedOrigin, + WithUniqueTopic, XcmFeesToAccount, }; use xcm_executor::{traits::WithOriginFilter, XcmExecutor}; @@ -89,6 +90,9 @@ pub type LocationToAccountId = ( AccountId32Aliases, // Foreign locations alias into accounts according to a hash of their standard description. HashedDescription>, + // Different global consensus parachain sovereign account. + // (Used for over-bridge transfers and reserve processing) + GlobalConsensusParachainConvertsFor, ); /// Means for transacting the native currency on this chain. @@ -258,6 +262,17 @@ impl Contains for SafeCallFilter { } } + // Allow to change dedicated storage items (called by governance-like) + match call { + RuntimeCall::System(frame_system::Call::set_storage { items }) + if items.iter().all(|(k, _)| { + k.eq(&bridging::XcmBridgeHubRouterBaseFee::key()) || + k.eq(&bridging::XcmBridgeHubRouterByteFee::key()) + }) => + return true, + _ => (), + }; + matches!( call, RuntimeCall::PolkadotXcm( @@ -444,6 +459,8 @@ impl Contains for SafeCallFilter { pallet_uniques::Call::set_collection_max_supply { .. } | pallet_uniques::Call::set_price { .. } | pallet_uniques::Call::buy_item { .. } + ) | RuntimeCall::ToPolkadotXcmRouter( + pallet_xcm_bridge_hub_router::Call::report_bridge_status { .. } ) ) } @@ -462,11 +479,12 @@ pub type Barrier = TrailingSetTopicAsId< // If the message is one that immediately attempts to pay for execution, then // allow it. AllowTopLevelPaidExecutionFrom, - // Parent, its pluralities (i.e. governance bodies) and parent's treasury - // pallet get free execution. + // Parent, its pluralities (i.e. governance bodies), parent's treasury and + // sibling bridge hub get free execution. AllowExplicitUnpaidExecutionFrom<( ParentOrParentsPlurality, Equals, + Equals, )>, // Subscriptions for version tracking are OK. AllowSubscriptionsFrom, @@ -512,16 +530,26 @@ pub type TrustedTeleporters = ( IsForeignConcreteAsset>>, ); +/// Multiplier used for dedicated `TakeFirstAssetTrader` with `ForeignAssets` instance. +pub type ForeignAssetFeeAsExistentialDepositMultiplierFeeCharger = + AssetFeeAsExistentialDepositMultiplier< + Runtime, + WeightToFee, + pallet_assets::BalanceToAssetBalance, + ForeignAssetsInstance, + >; + pub struct XcmConfig; impl xcm_executor::Config for XcmConfig { type RuntimeCall = RuntimeCall; type XcmSender = XcmRouter; type AssetTransactor = AssetTransactors; type OriginConverter = XcmOriginToTransactDispatchOrigin; - // Asset Hub Kusama does not recognize a reserve location for any asset. This does not prevent - // Asset Hub acting _as_ a reserve location for KSM and assets created under `pallet-assets`. - // For KSM, users must use teleport where allowed (e.g. with the Relay Chain). - type IsReserve = (); + // Asset Hub trusts only particular, pre-configured bridged locations from a different consensus + // as reserve locations (we trust the Bridge Hub to relay the message that a reserve is being + // held). Asset Hub may _act_ as a reserve location for KSM and assets created + // under `pallet-assets`. Users must use teleport where allowed (e.g. KSM with the Relay Chain). + type IsReserve = (bridging::to_polkadot::IsTrustedBridgedReserveLocationForConcreteAsset,); type IsTeleporter = TrustedTeleporters; type UniversalLocation = UniversalLocation; type Barrier = Barrier; @@ -532,6 +560,8 @@ impl xcm_executor::Config for XcmConfig { >; type Trader = ( UsingComponents>, + // This trader allows to pay with `is_sufficient=true` "Trust Backed" assets from dedicated + // `pallet_assets` instance - `Assets`. cumulus_primitives_utility::TakeFirstAssetTrader< AccountId, AssetFeeAsExistentialDepositMultiplierFeeCharger, @@ -543,6 +573,19 @@ impl xcm_executor::Config for XcmConfig { XcmAssetFeesReceiver, >, >, + // This trader allows to pay with `is_sufficient=true` "Foreign" assets from dedicated + // `pallet_assets` instance - `ForeignAssets`. + cumulus_primitives_utility::TakeFirstAssetTrader< + AccountId, + ForeignAssetFeeAsExistentialDepositMultiplierFeeCharger, + ForeignAssetsConvertedConcreteId, + ForeignAssets, + cumulus_primitives_utility::XcmFeesTo32ByteAccount< + ForeignFungiblesTransactor, + AccountId, + XcmAssetFeesReceiver, + >, + >, ); type ResponseHandler = PolkadotXcm; type AssetTrap = PolkadotXcm; @@ -554,7 +597,7 @@ impl xcm_executor::Config for XcmConfig { type AssetExchanger = (); type FeeManager = XcmFeesToAccount; type MessageExporter = (); - type UniversalAliases = Nothing; + type UniversalAliases = bridging::to_polkadot::UniversalAliases; type CallDispatcher = WithOriginFilter; type SafeCallFilter = SafeCallFilter; type Aliasers = Nothing; @@ -564,13 +607,23 @@ impl xcm_executor::Config for XcmConfig { /// Forms the basis for local origins sending/executing XCMs. pub type LocalOriginToLocation = SignedToAccountId32; -/// The means for routing XCM messages which are not for local execution into the right message -/// queues. -pub type XcmRouter = WithUniqueTopic<( +/// For routing XCM messages which do not cross local consensus boundary. +type LocalXcmRouter = ( // Two routers - use UMP to communicate with the relay chain: cumulus_primitives_utility::ParentAsUmp, // ..and XCMP to communicate with the sibling chains. XcmpQueue, +); + +/// The means for routing XCM messages which are not for local execution into the right message +/// queues. +pub type XcmRouter = WithUniqueTopic<( + // The means for routing XCM messages which are not for local execution into the right message + // queues. + LocalXcmRouter, + // Router which wraps and sends xcm to BridgeHub to be delivered to the Polkadot + // GlobalConsensus + ToPolkadotXcmRouter, )>; #[cfg(feature = "runtime-benchmarks")] @@ -660,3 +713,127 @@ where sp_std::boxed::Box::new(Self::asset_id(asset_id)) } } + +/// All configuration related to bridging +pub mod bridging { + use super::*; + use assets_common::matching; + use sp_std::collections::btree_set::BTreeSet; + use xcm_builder::NetworkExportTableItem; + + parameter_types! { + /// Base price of every Kusama -> Polkadot message. Can be adjusted via + /// governance `set_storage` call. + pub storage XcmBridgeHubRouterBaseFee: Balance = bp_bridge_hub_kusama::estimate_kusama_to_polkadot_message_fee( + bp_bridge_hub_polkadot::BridgeHubPolkadotBaseDeliveryFeeInDots::get() + ); + /// Price of every byte of the Kusama -> Polkadot message. Can be adjusted via + /// governance `set_storage` call. + pub storage XcmBridgeHubRouterByteFee: Balance = TransactionByteFee::get(); + + pub SiblingBridgeHubParaId: u32 = bp_bridge_hub_kusama::BRIDGE_HUB_KUSAMA_PARACHAIN_ID; + pub SiblingBridgeHub: MultiLocation = MultiLocation::new(1, X1(Parachain(SiblingBridgeHubParaId::get()))); + /// Router expects payment with this `AssetId`. + /// (`AssetId` has to be aligned with `BridgeTable`) + pub XcmBridgeHubRouterFeeAssetId: AssetId = KsmLocation::get().into(); + + pub BridgeTable: sp_std::vec::Vec = + sp_std::vec::Vec::new().into_iter() + .chain(to_polkadot::BridgeTable::get()) + .collect(); + } + + pub type NetworkExportTable = xcm_builder::NetworkExportTable; + + pub mod to_polkadot { + use super::*; + + parameter_types! { + pub SiblingBridgeHubWithBridgeHubPolkadotInstance: MultiLocation = MultiLocation::new( + 1, + X2( + Parachain(SiblingBridgeHubParaId::get()), + PalletInstance(bp_bridge_hub_kusama::WITH_BRIDGE_KUSAMA_TO_POLKADOT_MESSAGES_PALLET_INDEX), + ) + ); + + pub const PolkadotNetwork: NetworkId = NetworkId::Polkadot; + pub AssetHubPolkadot: MultiLocation = MultiLocation::new( + 2, + X2( + GlobalConsensus(PolkadotNetwork::get()), + Parachain(polkadot_runtime_constants::system_parachain::ASSET_HUB_ID), + ), + ); + pub DotLocation: MultiLocation = MultiLocation::new(2, X1(GlobalConsensus(PolkadotNetwork::get()))); + + pub DotFromAssetHubPolkadot: (MultiAssetFilter, MultiLocation) = ( + Wild(AllOf { fun: WildFungible, id: Concrete(DotLocation::get()) }), + AssetHubPolkadot::get() + ); + + /// Set up exporters configuration. + /// `Option` represents static "base fee" which is used for total delivery fee calculation. + pub BridgeTable: sp_std::vec::Vec = sp_std::vec![ + NetworkExportTableItem::new( + PolkadotNetwork::get(), + Some(sp_std::vec![ + AssetHubPolkadot::get().interior.split_global().expect("invalid configuration for AssetHubKusama").1, + ]), + SiblingBridgeHub::get(), + // base delivery fee to local `BridgeHub` + Some(( + XcmBridgeHubRouterFeeAssetId::get(), + XcmBridgeHubRouterBaseFee::get(), + ).into()) + ) + ]; + + /// Universal aliases + pub UniversalAliases: BTreeSet<(MultiLocation, Junction)> = BTreeSet::from_iter( + sp_std::vec![ + (SiblingBridgeHubWithBridgeHubPolkadotInstance::get(), GlobalConsensus(PolkadotNetwork::get())) + ] + ); + } + + impl Contains<(MultiLocation, Junction)> for UniversalAliases { + fn contains(alias: &(MultiLocation, Junction)) -> bool { + UniversalAliases::get().contains(alias) + } + } + + /// Reserve locations filter for `xcm_executor::Config::IsReserve`. + /// Locations from which the runtime accepts reserved assets. + pub type IsTrustedBridgedReserveLocationForConcreteAsset = + matching::IsTrustedBridgedReserveLocationForConcreteAsset< + UniversalLocation, + ( + // allow receive DOT from AssetHubPolkadot + xcm_builder::Case, + // and nothing else + ), + >; + } + + /// Benchmarks helper for bridging configuration. + #[cfg(feature = "runtime-benchmarks")] + pub struct BridgingBenchmarksHelper; + + #[cfg(feature = "runtime-benchmarks")] + impl BridgingBenchmarksHelper { + pub fn prepare_universal_alias() -> Option<(MultiLocation, Junction)> { + let alias = to_polkadot::UniversalAliases::get().into_iter().find_map( + |(location, junction)| { + match to_polkadot::SiblingBridgeHubWithBridgeHubPolkadotInstance::get() + .eq(&location) + { + true => Some((location, junction)), + false => None, + } + }, + ); + Some(alias.expect("we expect here BridgeHubKusama to Polkadot mapping at least")) + } + } +} diff --git a/system-parachains/asset-hubs/asset-hub-kusama/tests/tests.rs b/system-parachains/asset-hubs/asset-hub-kusama/tests/tests.rs index f207fb83de..a70901b5b4 100644 --- a/system-parachains/asset-hubs/asset-hub-kusama/tests/tests.rs +++ b/system-parachains/asset-hubs/asset-hub-kusama/tests/tests.rs @@ -17,16 +17,21 @@ //! Tests for the Kusama Asset Hub (previously known as Statemine) chain. -use asset_hub_kusama_runtime::xcm_config::{ - AssetFeeAsExistentialDepositMultiplierFeeCharger, KsmLocation, TrustBackedAssetsPalletLocation, -}; -pub use asset_hub_kusama_runtime::{ - xcm_config::{CheckingAccount, ForeignCreatorsSovereignAccountOf, XcmConfig}, +use asset_hub_kusama_runtime::{ + xcm_config::{ + bridging::{self, XcmBridgeHubRouterFeeAssetId}, + AssetFeeAsExistentialDepositMultiplierFeeCharger, CheckingAccount, + ForeignCreatorsSovereignAccountOf, KsmLocation, LocationToAccountId, TreasuryAccount, + TrustBackedAssetsPalletLocation, XcmConfig, + }, AllPalletsWithoutSystem, AssetDeposit, Assets, Balances, ExistentialDeposit, ForeignAssets, ForeignAssetsInstance, MetadataDepositBase, MetadataDepositPerByte, ParachainSystem, Runtime, - RuntimeCall, RuntimeEvent, SessionKeys, System, TrustBackedAssetsInstance, + RuntimeCall, RuntimeEvent, SessionKeys, ToPolkadotXcmRouterInstance, TrustBackedAssetsInstance, + XcmpQueue, +}; +use asset_test_utils::{ + test_cases_over_bridge::TestBridgingConfig, CollatorSessionKey, CollatorSessionKeys, ExtBuilder, }; -use asset_test_utils::{CollatorSessionKeys, ExtBuilder}; use codec::{Decode, Encode}; use cumulus_primitives_utility::ChargeWeightInFungibles; use frame_support::{ @@ -48,6 +53,14 @@ type AssetIdForTrustBackedAssetsConvert = type RuntimeHelper = asset_test_utils::RuntimeHelper; +fn collator_session_key(account: [u8; 32]) -> CollatorSessionKey { + CollatorSessionKey::new( + AccountId::from(account), + AccountId::from(account), + SessionKeys { aura: AuraId::from(sp_core::sr25519::Public::from_raw(account)) }, + ) +} + fn collator_session_keys() -> CollatorSessionKeys { CollatorSessionKeys::new( AccountId::from(ALICE), @@ -631,3 +644,602 @@ asset_test_utils::include_create_and_manage_foreign_assets_for_local_consensus_p assert_eq!(ForeignAssets::asset_ids().collect::>().len(), 1); }) ); + +fn bridging_to_asset_hub_polkadot() -> TestBridgingConfig { + TestBridgingConfig { + bridged_network: bridging::to_polkadot::PolkadotNetwork::get(), + local_bridge_hub_para_id: bridging::SiblingBridgeHubParaId::get(), + local_bridge_hub_location: bridging::SiblingBridgeHub::get(), + bridged_target_location: bridging::to_polkadot::AssetHubPolkadot::get(), + } +} + +#[test] +fn limited_reserve_transfer_assets_for_native_asset_to_asset_hub_polkadot_works() { + missing_asset_test_utils_test_cases_over_bridge::limited_reserve_transfer_assets_for_native_asset_works::< + Runtime, + AllPalletsWithoutSystem, + XcmConfig, + ParachainSystem, + XcmpQueue, + LocationToAccountId, + >( + collator_session_keys(), + ExistentialDeposit::get(), + AccountId::from(ALICE), + Box::new(|runtime_event_encoded: Vec| { + match RuntimeEvent::decode(&mut &runtime_event_encoded[..]) { + Ok(RuntimeEvent::PolkadotXcm(event)) => Some(event), + _ => None, + } + }), + Box::new(|runtime_event_encoded: Vec| { + match RuntimeEvent::decode(&mut &runtime_event_encoded[..]) { + Ok(RuntimeEvent::XcmpQueue(event)) => Some(event), + _ => None, + } + }), + bridging_to_asset_hub_polkadot, + WeightLimit::Unlimited, + Some(XcmBridgeHubRouterFeeAssetId::get()), + TreasuryAccount::get(), + ) +} + +#[test] +fn receive_reserve_asset_deposited_roc_from_asset_hub_polkadot_works() { + const BLOCK_AUTHOR_ACCOUNT: [u8; 32] = [13; 32]; + asset_test_utils::test_cases_over_bridge::receive_reserve_asset_deposited_from_different_consensus_works::< + Runtime, + AllPalletsWithoutSystem, + XcmConfig, + LocationToAccountId, + ForeignAssetsInstance, + >( + collator_session_keys().add(collator_session_key(BLOCK_AUTHOR_ACCOUNT)), + ExistentialDeposit::get(), + AccountId::from([73; 32]), + AccountId::from(BLOCK_AUTHOR_ACCOUNT), + // receiving ROCs + (MultiLocation { parents: 2, interior: X1(GlobalConsensus(Polkadot)) }, 1000000000000, 1_000_000_000), + bridging_to_asset_hub_polkadot, + ( + X1(PalletInstance(bp_bridge_hub_kusama::WITH_BRIDGE_KUSAMA_TO_POLKADOT_MESSAGES_PALLET_INDEX)), + GlobalConsensus(Polkadot), + X1(Parachain(1000)) + ) + ) +} + +#[test] +fn report_bridge_status_from_xcm_bridge_router_for_polkadot_works() { + missing_asset_test_utils_test_cases_over_bridge::report_bridge_status_from_xcm_bridge_router_works::< + Runtime, + AllPalletsWithoutSystem, + XcmConfig, + LocationToAccountId, + ToPolkadotXcmRouterInstance, + >( + collator_session_keys(), + bridging_to_asset_hub_polkadot, + || Decode::decode(&mut &bp_asset_hub_kusama::CongestedMessage::get().encode()[..]).unwrap(), + || { + Decode::decode(&mut &bp_asset_hub_kusama::UncongestedMessage::get().encode()[..]) + .unwrap() + }, + ) +} + +#[test] +fn test_report_bridge_status_call_compatibility() { + // if this test fails, make sure `bp_asset_hub_polkadot` has valid encoding + assert_eq!( + RuntimeCall::ToPolkadotXcmRouter( + pallet_xcm_bridge_hub_router::Call::report_bridge_status { + bridge_id: Default::default(), + is_congested: true, + } + ) + .encode(), + bp_asset_hub_kusama::Call::ToPolkadotXcmRouter( + bp_asset_hub_kusama::XcmBridgeHubRouterCall::report_bridge_status { + bridge_id: Default::default(), + is_congested: true, + } + ) + .encode() + ) +} + +#[test] +fn check_sane_weight_report_bridge_status() { + use pallet_xcm_bridge_hub_router::WeightInfo; + let actual = >::WeightInfo::report_bridge_status(); + let max_weight = bp_asset_hub_kusama::XcmBridgeHubRouterTransactCallMaxWeight::get(); + assert!( + actual.all_lte(max_weight), + "max_weight: {:?} should be adjusted to actual {:?}", + max_weight, + actual + ); +} + +#[test] +fn change_xcm_bridge_hub_router_byte_fee_by_governance_works() { + asset_test_utils::test_cases::change_storage_constant_by_governance_works::< + Runtime, + bridging::XcmBridgeHubRouterByteFee, + Balance, + >( + collator_session_keys(), + 1000, + Box::new(|call| RuntimeCall::System(call).encode()), + || { + ( + bridging::XcmBridgeHubRouterByteFee::key().to_vec(), + bridging::XcmBridgeHubRouterByteFee::get(), + ) + }, + |old_value| { + if let Some(new_value) = old_value.checked_add(1) { + new_value + } else { + old_value.checked_sub(1).unwrap() + } + }, + ) +} + +// missing stuff from asset_test_utils::test_cases_over_bridge +// TODO: replace me with direct usages of `asset_test_utils` after deps are bumped to (at least) 1.4 +mod missing_asset_test_utils_test_cases_over_bridge { + use asset_test_utils::test_cases_over_bridge::TestBridgingConfig; + use codec::Encode; + use cumulus_primitives_core::XcmpMessageSource; + use frame_support::{ + assert_ok, + traits::{Currency, Get, OnFinalize, OnInitialize, OriginTrait, ProcessMessageError}, + }; + use frame_system::pallet_prelude::BlockNumberFor; + use parachains_common::{AccountId, Balance}; + use parachains_runtimes_test_utils::{ + mock_open_hrmp_channel, AccountIdOf, BalanceOf, CollatorSessionKeys, ExtBuilder, + RuntimeHelper, ValidatorIdOf, XcmReceivedFrom, + }; + use sp_runtime::{traits::StaticLookup, Saturating}; + use xcm::{latest::prelude::*, VersionedMultiAssets}; + use xcm_builder::{CreateMatcher, MatchXcm}; + use xcm_executor::{ + traits::{ConvertLocation, TransactAsset}, + XcmExecutor, + }; + + /// Helper function to verify `xcm` contains all relevant instructions expected on destination + /// chain as part of a reserve-asset-transfer. + fn assert_matches_reserve_asset_deposited_instructions( + xcm: &mut Xcm, + expected_reserve_assets_deposited: &MultiAssets, + expected_beneficiary: &MultiLocation, + ) { + let _ = xcm + .0 + .matcher() + .skip_inst_while(|inst| !matches!(inst, ReserveAssetDeposited(..))) + .expect("no instruction ReserveAssetDeposited?") + .match_next_inst(|instr| match instr { + ReserveAssetDeposited(reserve_assets) => { + assert_eq!(reserve_assets, expected_reserve_assets_deposited); + Ok(()) + }, + _ => Err(ProcessMessageError::BadFormat), + }) + .expect("expected instruction ReserveAssetDeposited") + .match_next_inst(|instr| match instr { + ClearOrigin => Ok(()), + _ => Err(ProcessMessageError::BadFormat), + }) + .expect("expected instruction ClearOrigin") + .match_next_inst(|instr| match instr { + BuyExecution { .. } => Ok(()), + _ => Err(ProcessMessageError::BadFormat), + }) + .expect("expected instruction BuyExecution") + .match_next_inst(|instr| match instr { + DepositAsset { assets: _, beneficiary } if beneficiary == expected_beneficiary => + Ok(()), + _ => Err(ProcessMessageError::BadFormat), + }) + .expect("expected instruction DepositAsset"); + } + + pub fn limited_reserve_transfer_assets_for_native_asset_works< + Runtime, + AllPalletsWithoutSystem, + XcmConfig, + HrmpChannelOpener, + HrmpChannelSource, + LocationToAccountId, + >( + collator_session_keys: CollatorSessionKeys, + existential_deposit: BalanceOf, + alice_account: AccountIdOf, + unwrap_pallet_xcm_event: Box) -> Option>>, + unwrap_xcmp_queue_event: Box< + dyn Fn(Vec) -> Option>, + >, + prepare_configuration: fn() -> TestBridgingConfig, + weight_limit: WeightLimit, + maybe_paid_export_message: Option, + delivery_fees_account: Option>, + ) where + Runtime: frame_system::Config + + pallet_balances::Config + + pallet_session::Config + + pallet_xcm::Config + + parachain_info::Config + + pallet_collator_selection::Config + + cumulus_pallet_parachain_system::Config + + cumulus_pallet_xcmp_queue::Config, + AllPalletsWithoutSystem: + OnInitialize> + OnFinalize>, + AccountIdOf: Into<[u8; 32]>, + ValidatorIdOf: From>, + BalanceOf: From, + ::Balance: From + Into, + XcmConfig: xcm_executor::Config, + LocationToAccountId: ConvertLocation>, + ::AccountId: + Into<<::RuntimeOrigin as OriginTrait>::AccountId>, + <::Lookup as StaticLookup>::Source: + From<::AccountId>, + ::AccountId: From, + HrmpChannelOpener: frame_support::inherent::ProvideInherent< + Call = cumulus_pallet_parachain_system::Call, + >, + HrmpChannelSource: XcmpMessageSource, + { + let runtime_para_id = 1000; + ExtBuilder::::default() + .with_collators(collator_session_keys.collators()) + .with_session_keys(collator_session_keys.session_keys()) + .with_tracing() + .with_safe_xcm_version(3) + .with_para_id(runtime_para_id.into()) + .build() + .execute_with(|| { + let mut alice = [0u8; 32]; + alice[0] = 1; + let included_head = RuntimeHelper::::run_to_block( + 2, + AccountId::from(alice).into(), + ); + + // prepare bridge config + let TestBridgingConfig { + bridged_network, + local_bridge_hub_para_id, + bridged_target_location: target_location_from_different_consensus, + .. + } = prepare_configuration(); + + let reserve_account = LocationToAccountId::convert_location( + &target_location_from_different_consensus, + ) + .expect("Sovereign account for reserves"); + let balance_to_transfer = 1_000_000_000_000_u128; + let native_asset = MultiLocation::parent(); + + // open HRMP to bridge hub + mock_open_hrmp_channel::( + runtime_para_id.into(), + local_bridge_hub_para_id.into(), + included_head, + &alice, + ); + + // drip ED to account + let alice_account_init_balance = existential_deposit + balance_to_transfer.into(); + let _ = >::deposit_creating( + &alice_account, + alice_account_init_balance, + ); + // SA of target location needs to have at least ED, otherwise making reserve fails + let _ = >::deposit_creating( + &reserve_account, + existential_deposit, + ); + + // we just check here, that user retains enough balance after withdrawal + // and also we check if `balance_to_transfer` is more than `existential_deposit`, + assert!( + (>::free_balance(&alice_account) - + balance_to_transfer.into()) >= + existential_deposit + ); + // SA has just ED + assert_eq!( + >::free_balance(&reserve_account), + existential_deposit + ); + + let delivery_fees_account_balance_before = delivery_fees_account + .as_ref() + .map(|dfa| >::free_balance(dfa)) + .unwrap_or(0.into()); + + // local native asset (pallet_balances) + let asset_to_transfer = MultiAsset { + fun: Fungible(balance_to_transfer.into()), + id: Concrete(native_asset), + }; + + // destination is (some) account relative to the destination different consensus + let target_destination_account = MultiLocation { + parents: 0, + interior: X1(AccountId32 { + network: Some(bridged_network), + id: sp_runtime::AccountId32::new([3; 32]).into(), + }), + }; + + let assets_to_transfer = MultiAssets::from(asset_to_transfer); + let mut expected_assets = assets_to_transfer.clone(); + let context = XcmConfig::UniversalLocation::get(); + expected_assets + .reanchor(&target_location_from_different_consensus, context) + .unwrap(); + + let expected_beneficiary = target_destination_account; + + // Make sure sender has enough funds for paying delivery fees + let handling_delivery_fees = { + // Probable XCM with `ReserveAssetDeposited`. + let mut expected_reserve_asset_deposited_message = Xcm(vec![ + ReserveAssetDeposited(MultiAssets::from(expected_assets.clone())), + ClearOrigin, + BuyExecution { + fees: MultiAsset { + id: Concrete(Default::default()), + fun: Fungible(balance_to_transfer), + }, + weight_limit: Unlimited, + }, + DepositAsset { + assets: Wild(AllCounted(1)), + beneficiary: expected_beneficiary, + }, + SetTopic([ + 220, 188, 144, 32, 213, 83, 111, 175, 44, 210, 111, 19, 90, 165, 191, + 112, 140, 247, 192, 124, 42, 17, 153, 141, 114, 34, 189, 20, 83, 69, + 237, 173, + ]), + ]); + assert_matches_reserve_asset_deposited_instructions( + &mut expected_reserve_asset_deposited_message, + &expected_assets, + &expected_beneficiary, + ); + + // Call `SendXcm::validate` to get delivery fees. + let (_, delivery_fees): (_, MultiAssets) = XcmConfig::XcmSender::validate( + &mut Some(target_location_from_different_consensus), + &mut Some(expected_reserve_asset_deposited_message), + ) + .expect("validate passes"); + // Drip delivery fee to Alice account. + let mut delivery_fees_added = false; + for delivery_fee in delivery_fees.inner() { + assert_ok!(::deposit_asset( + &delivery_fee, + &MultiLocation { + parents: 0, + interior: X1(AccountId32 { + network: None, + id: alice_account.clone().into(), + }), + }, + None, + )); + delivery_fees_added = true; + } + delivery_fees_added + }; + + // do pallet_xcm call reserve transfer + assert_ok!(>::limited_reserve_transfer_assets( + RuntimeHelper::::origin_of( + alice_account.clone() + ), + Box::new(target_location_from_different_consensus.into_versioned()), + Box::new(target_destination_account.into_versioned()), + Box::new(VersionedMultiAssets::from(assets_to_transfer)), + 0, + weight_limit, + )); + + // check events + // check pallet_xcm attempted + RuntimeHelper::::assert_pallet_xcm_event_outcome( + &unwrap_pallet_xcm_event, + |outcome| { + assert_ok!(outcome.ensure_complete()); + }, + ); + + // check that xcm was sent + let xcm_sent_message_hash = >::events() + .into_iter() + .filter_map(|e| unwrap_xcmp_queue_event(e.event.encode())) + .find_map(|e| match e { + cumulus_pallet_xcmp_queue::Event::XcmpMessageSent { message_hash } => + Some(message_hash), + _ => None, + }); + + // read xcm + let xcm_sent = + RuntimeHelper::::take_xcm( + local_bridge_hub_para_id.into(), + ) + .unwrap(); + assert_eq!( + xcm_sent_message_hash, + Some(xcm_sent.using_encoded(sp_io::hashing::blake2_256)) + ); + let mut xcm_sent: Xcm<()> = xcm_sent.try_into().expect("versioned xcm"); + + // check sent XCM ExportMessage to BridgeHub + + // 1. check paid or unpaid + if let Some(expected_fee_asset_id) = maybe_paid_export_message { + xcm_sent + .0 + .matcher() + .match_next_inst(|instr| match instr { + WithdrawAsset(_) => Ok(()), + _ => Err(ProcessMessageError::BadFormat), + }) + .expect("contains WithdrawAsset") + .match_next_inst(|instr| match instr { + BuyExecution { fees, .. } if fees.id.eq(&expected_fee_asset_id) => + Ok(()), + _ => Err(ProcessMessageError::BadFormat), + }) + .expect("contains BuyExecution") + } else { + xcm_sent + .0 + .matcher() + .match_next_inst(|instr| match instr { + // first instruction could be UnpaidExecution (because we could have + // explicit unpaid execution on BridgeHub) + UnpaidExecution { weight_limit, check_origin } + if weight_limit == &Unlimited && check_origin.is_none() => + Ok(()), + _ => Err(ProcessMessageError::BadFormat), + }) + .expect("contains UnpaidExecution") + } + // 2. check ExportMessage + .match_next_inst(|instr| match instr { + // next instruction is ExportMessage + ExportMessage { network, destination, xcm: inner_xcm } => { + assert_eq!(network, &bridged_network); + let (_, target_location_junctions_without_global_consensus) = + target_location_from_different_consensus + .interior + .split_global() + .expect("split works"); + assert_eq!( + destination, + &target_location_junctions_without_global_consensus + ); + assert_matches_reserve_asset_deposited_instructions( + inner_xcm, + &expected_assets, + &expected_beneficiary, + ); + Ok(()) + }, + _ => Err(ProcessMessageError::BadFormat), + }) + .expect("contains ExportMessage"); + + // check alice account decreased by balance_to_transfer + assert_eq!( + >::free_balance(&alice_account), + alice_account_init_balance + .saturating_sub(existential_deposit) + .saturating_sub(balance_to_transfer.into()) + ); + + // check reserve account increased by balance_to_transfer + assert_eq!( + >::free_balance(&reserve_account), + existential_deposit + balance_to_transfer.into() + ); + + // check dedicated account increased by delivery fees (if configured) + if handling_delivery_fees { + if let Some(delivery_fees_account) = delivery_fees_account { + let delivery_fees_account_balance_after = + >::free_balance( + &delivery_fees_account, + ); + assert!( + delivery_fees_account_balance_after > + delivery_fees_account_balance_before + ); + } + } + }) + } + + pub fn report_bridge_status_from_xcm_bridge_router_works< + Runtime, + AllPalletsWithoutSystem, + XcmConfig, + LocationToAccountId, + XcmBridgeHubRouterInstance, + >( + collator_session_keys: CollatorSessionKeys, + prepare_configuration: fn() -> TestBridgingConfig, + congested_message: fn() -> Xcm, + uncongested_message: fn() -> Xcm, + ) where + Runtime: frame_system::Config + + pallet_balances::Config + + pallet_session::Config + + pallet_xcm::Config + + parachain_info::Config + + pallet_collator_selection::Config + + cumulus_pallet_parachain_system::Config + + cumulus_pallet_xcmp_queue::Config + + pallet_xcm_bridge_hub_router::Config, + AllPalletsWithoutSystem: + OnInitialize> + OnFinalize>, + AccountIdOf: Into<[u8; 32]>, + ValidatorIdOf: From>, + BalanceOf: From, + ::Balance: From + Into, + XcmConfig: xcm_executor::Config, + LocationToAccountId: ConvertLocation>, + ::AccountId: + Into<<::RuntimeOrigin as OriginTrait>::AccountId>, + <::Lookup as StaticLookup>::Source: + From<::AccountId>, + ::AccountId: From, + XcmBridgeHubRouterInstance: 'static, + { + ExtBuilder::::default() + .with_collators(collator_session_keys.collators()) + .with_session_keys(collator_session_keys.session_keys()) + .with_tracing() + .build() + .execute_with(|| { + let report_bridge_status = |is_congested: bool| { + // prepare bridge config + let TestBridgingConfig { local_bridge_hub_location, .. } = prepare_configuration(); + + // Call received XCM execution + let xcm = if is_congested { congested_message() } else { uncongested_message() }; + let hash = xcm.using_encoded(sp_io::hashing::blake2_256); + + // execute xcm as XcmpQueue would do + let outcome = XcmExecutor::::execute_xcm( + local_bridge_hub_location, + xcm, + hash, + RuntimeHelper::::xcm_max_weight(XcmReceivedFrom::Sibling), + ); + assert_eq!(outcome.ensure_complete(), Ok(())); + assert_eq!(is_congested, pallet_xcm_bridge_hub_router::Pallet::::bridge().is_congested); + }; + + report_bridge_status(true); + report_bridge_status(false); + }) + } +} diff --git a/system-parachains/asset-hubs/asset-hub-polkadot/Cargo.toml b/system-parachains/asset-hubs/asset-hub-polkadot/Cargo.toml index 0b626126ed..649e1f6513 100644 --- a/system-parachains/asset-hubs/asset-hub-polkadot/Cargo.toml +++ b/system-parachains/asset-hubs/asset-hub-polkadot/Cargo.toml @@ -12,8 +12,16 @@ version.workspace = true codec = { package = "parity-scale-codec", version = "3.0.0", default-features = false, features = ["derive", "max-encoded-len"] } hex-literal = { version = "0.4.1", optional = true } log = { version = "0.4.20", default-features = false } -scale-info = { version = "2.9.0", default-features = false, features = ["derive"] } -smallvec = "1.11.0" +scale-info = { version = "2.10.0", default-features = false, features = ["derive"] } +smallvec = "1.11.1" + +# Local +bp-asset-hub-kusama = { path = "../asset-hub-kusama/primitives", default-features = false} +bp-asset-hub-polkadot = { path = "./primitives", default-features = false} +bp-bridge-hub-kusama = { path = "../../bridge-hubs/bridge-hub-kusama/primitives", default-features = false} +bp-bridge-hub-polkadot = { path = "../../bridge-hubs/bridge-hub-polkadot/primitives", default-features = false} +kusama-runtime-constants = { path = "../../../relay/kusama/constants", default-features = false} +polkadot-runtime-constants = { path = "../../../relay/polkadot/constants", default-features = false} # Substrate frame-benchmarking = { default-features = false, optional = true, version = "25.0.0" } @@ -59,7 +67,6 @@ pallet-xcm-benchmarks = { default-features = false, optional = true , version = polkadot-core-primitives = { default-features = false, version = "4.0.0" } polkadot-parachain-primitives = { default-features = false, version = "3.0.0" } polkadot-runtime-common = { default-features = false, version = "4.0.0" } -polkadot-runtime-constants = { path = "../../../relay/polkadot/constants", default-features = false} xcm = { package = "staging-xcm", default-features = false, version = "4.0.0" } xcm-builder = { package = "staging-xcm-builder", default-features = false, version = "4.0.0" } xcm-executor = { package = "staging-xcm-executor", default-features = false, version = "4.0.0" } @@ -70,7 +77,7 @@ cumulus-pallet-dmp-queue = { default-features = false , version = "0.4.0" } cumulus-pallet-parachain-system = { default-features = false, features = ["parameterized-consensus-hook",] , version = "0.4.0" } cumulus-pallet-session-benchmarking = { default-features = false, version = "6.0.0" } cumulus-pallet-xcm = { default-features = false , version = "0.4.0" } -cumulus-pallet-xcmp-queue = { default-features = false , version = "0.4.0" } +cumulus-pallet-xcmp-queue = { default-features = false , features = ["bridging"] , version = "0.4.0" } cumulus-primitives-core = { default-features = false , version = "0.4.0" } cumulus-primitives-utility = { default-features = false , version = "0.4.0" } pallet-collator-selection = { default-features = false , version = "6.0.0" } @@ -79,9 +86,14 @@ parachains-common = { default-features = false , version = "4.0.0" } system-parachains-constants = { path = "../../constants", default-features = false } assets-common = { default-features = false , version = "0.4.0" } +# Bridges +pallet-xcm-bridge-hub-router = { default-features = false , version = "0.2.0" } + [dev-dependencies] hex-literal = "0.4.1" asset-test-utils = { version = "4.0.0" } +parachains-runtimes-test-utils = { version = "4.0.0" } +sp-io = { version = "27.0.0" } [build-dependencies] substrate-wasm-builder = { optional = true , version = "14.0.0" } @@ -110,6 +122,7 @@ runtime-benchmarks = [ "pallet-uniques/runtime-benchmarks", "pallet-utility/runtime-benchmarks", "pallet-xcm-benchmarks/runtime-benchmarks", + "pallet-xcm-bridge-hub-router/runtime-benchmarks", "pallet-xcm/runtime-benchmarks", "polkadot-parachain-primitives/runtime-benchmarks", "polkadot-runtime-common/runtime-benchmarks", @@ -141,6 +154,7 @@ try-runtime = [ "pallet-transaction-payment/try-runtime", "pallet-uniques/try-runtime", "pallet-utility/try-runtime", + "pallet-xcm-bridge-hub-router/try-runtime", "pallet-xcm/try-runtime", "parachain-info/try-runtime", "polkadot-runtime-common/try-runtime", @@ -148,6 +162,10 @@ try-runtime = [ ] std = [ "assets-common/std", + "bp-asset-hub-kusama/std", + "bp-asset-hub-polkadot/std", + "bp-bridge-hub-kusama/std", + "bp-bridge-hub-polkadot/std", "codec/std", "cumulus-pallet-aura-ext/std", "cumulus-pallet-dmp-queue/std", @@ -164,6 +182,7 @@ std = [ "frame-system-rpc-runtime-api/std", "frame-system/std", "frame-try-runtime?/std", + "kusama-runtime-constants/std", "log/std", "pallet-asset-tx-payment/std", "pallet-assets/std", @@ -182,6 +201,7 @@ std = [ "pallet-uniques/std", "pallet-utility/std", "pallet-xcm-benchmarks?/std", + "pallet-xcm-bridge-hub-router/std", "pallet-xcm/std", "parachain-info/std", "parachains-common/std", diff --git a/system-parachains/asset-hubs/asset-hub-polkadot/primitives/Cargo.toml b/system-parachains/asset-hubs/asset-hub-polkadot/primitives/Cargo.toml new file mode 100644 index 0000000000..939fb36e34 --- /dev/null +++ b/system-parachains/asset-hubs/asset-hub-polkadot/primitives/Cargo.toml @@ -0,0 +1,33 @@ +[package] +name = "bp-asset-hub-polkadot" +description = "Primitives of AssetHubPolkadot parachain runtime." +repository.workspace = true +version.workspace = true +authors.workspace = true +edition.workspace = true +license.workspace = true + +[dependencies] +codec = { package = "parity-scale-codec", version = "3.0.0", default-features = false, features = ["derive", "max-encoded-len"] } +scale-info = { version = "2.9.0", default-features = false, features = ["derive"] } + +# Bridge Dependencies +bp-xcm-bridge-hub-router = { default-features = false , version = "0.3.0" } + +# Substrate Based Dependencies +frame-support = { default-features = false, version = "25.0.0" } +sp-std = { default-features = false, version = "12.0.0" } + +# Polkadot +xcm = { package = "staging-xcm", default-features = false, version = "4.0.0" } + +[features] +default = [ "std" ] +std = [ + "bp-xcm-bridge-hub-router/std", + "codec/std", + "frame-support/std", + "scale-info/std", + "sp-std/std", + "xcm/std" +] diff --git a/system-parachains/asset-hubs/asset-hub-polkadot/primitives/src/lib.rs b/system-parachains/asset-hubs/asset-hub-polkadot/primitives/src/lib.rs new file mode 100644 index 0000000000..c16da851dd --- /dev/null +++ b/system-parachains/asset-hubs/asset-hub-polkadot/primitives/src/lib.rs @@ -0,0 +1,68 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Polkadot is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Polkadot. If not, see . + +//! Module with configuration which reflects AssetHubPolkadot runtime setup. + +#![cfg_attr(not(feature = "std"), no_std)] + +use codec::{Decode, Encode}; +use frame_support::weights::Weight; +use scale_info::TypeInfo; +use xcm::prelude::*; + +pub use bp_xcm_bridge_hub_router::XcmBridgeHubRouterCall; + +/// `AssetHubPolkadot` Runtime `Call` enum. +/// +/// The enum represents a subset of possible `Call`s we can send to `AssetHubPolkadot` chain. +/// Ideally this code would be auto-generated from metadata, because we want to +/// avoid depending directly on the ENTIRE runtime just to get the encoding of `Dispatchable`s. +/// +/// All entries here (like pretty much in the entire file) must be kept in sync with +/// `AssetHubPolkadot` `construct_runtime`, so that we maintain SCALE-compatibility. +#[allow(clippy::large_enum_variant)] +#[derive(Encode, Decode, Debug, PartialEq, Eq, Clone, TypeInfo)] +pub enum Call { + /// `ToKusamaXcmRouter` bridge pallet. + #[codec(index = 34)] + ToKusamaXcmRouter(XcmBridgeHubRouterCall), +} + +frame_support::parameter_types! { + /// Some sane weight to execute `xcm::Transact(pallet-xcm-bridge-hub-router::Call::report_bridge_status)`. + pub const XcmBridgeHubRouterTransactCallMaxWeight: Weight = Weight::from_parts(200_000_000, 6144); + + /// Message that is sent to the sibling Kusama Asset Hub when the with-Polkadot bridge becomes congested. + pub CongestedMessage: Xcm<()> = build_congestion_message(true).into(); + /// Message that is sent to the sibling Kusama Asset Hub when the with-Polkadot bridge becomes uncongested. + pub UncongestedMessage: Xcm<()> = build_congestion_message(false).into(); +} + +fn build_congestion_message(is_congested: bool) -> sp_std::vec::Vec> { + sp_std::vec![ + UnpaidExecution { weight_limit: Unlimited, check_origin: None }, + Transact { + origin_kind: OriginKind::Xcm, + require_weight_at_most: XcmBridgeHubRouterTransactCallMaxWeight::get(), + call: Call::ToKusamaXcmRouter(XcmBridgeHubRouterCall::report_bridge_status { + bridge_id: Default::default(), + is_congested, + }) + .encode() + .into(), + } + ] +} diff --git a/system-parachains/asset-hubs/asset-hub-polkadot/src/lib.rs b/system-parachains/asset-hubs/asset-hub-polkadot/src/lib.rs index 7bdffa19bb..87ec19b53b 100644 --- a/system-parachains/asset-hubs/asset-hub-polkadot/src/lib.rs +++ b/system-parachains/asset-hubs/asset-hub-polkadot/src/lib.rs @@ -87,7 +87,7 @@ use frame_support::{ genesis_builder_helper::{build_config, create_default_config}, parameter_types, traits::{ - AsEnsureOriginWithArg, ConstBool, ConstU32, ConstU64, ConstU8, EitherOfDiverse, + AsEnsureOriginWithArg, ConstBool, ConstU32, ConstU64, ConstU8, EitherOfDiverse, Equals, InstanceFilter, OnRuntimeUpgrade, }, weights::{ConstantMultiplier, Weight}, @@ -752,6 +752,37 @@ impl pallet_nfts::Config for Runtime { type Helper = (); } +/// XCM router instance to BridgeHub with bridging capabilities for `Kusama` global +/// consensus with dynamic fees and back-pressure. +pub type ToKusamaXcmRouterInstance = pallet_xcm_bridge_hub_router::Instance1; +impl pallet_xcm_bridge_hub_router::Config for Runtime { + type WeightInfo = weights::pallet_xcm_bridge_hub_router::WeightInfo; + + type UniversalLocation = xcm_config::UniversalLocation; + type BridgedNetworkId = xcm_config::bridging::to_kusama::KusamaNetwork; + type Bridges = xcm_config::bridging::NetworkExportTable; + + #[cfg(not(feature = "runtime-benchmarks"))] + type BridgeHubOrigin = EnsureXcm>; + #[cfg(feature = "runtime-benchmarks")] + type BridgeHubOrigin = frame_support::traits::EitherOfDiverse< + // for running benchmarks + EnsureRoot, + // for running tests with `--feature runtime-benchmarks` + EnsureXcm>, + >; + + type ToBridgeHubSender = XcmpQueue; + type WithBridgeHubChannel = + cumulus_pallet_xcmp_queue::bridging::InAndOutXcmpChannelStatusProvider< + xcm_config::bridging::SiblingBridgeHubParaId, + Runtime, + >; + + type ByteFee = xcm_config::bridging::XcmBridgeHubRouterByteFee; + type FeeAsset = xcm_config::bridging::XcmBridgeHubRouterFeeAssetId; +} + // Create the runtime by composing the FRAME pallets that were previously configured. construct_runtime!( pub enum Runtime @@ -782,6 +813,7 @@ construct_runtime!( PolkadotXcm: pallet_xcm::{Pallet, Call, Storage, Event, Origin, Config} = 31, CumulusXcm: cumulus_pallet_xcm::{Pallet, Event, Origin} = 32, DmpQueue: cumulus_pallet_dmp_queue::{Pallet, Call, Storage, Event} = 33, + ToKusamaXcmRouter: pallet_xcm_bridge_hub_router::::{Pallet, Storage, Call} = 34, // Handy utilities. Utility: pallet_utility::{Pallet, Call, Event} = 40, @@ -863,6 +895,8 @@ mod benches { [cumulus_pallet_xcmp_queue, XcmpQueue] // XCM [pallet_xcm, PolkadotXcm] + // Bridges + [pallet_xcm_bridge_hub_router, ToKusama] // NOTE: Make sure you point to the individual modules below. [pallet_xcm_benchmarks::fungible, XcmBalances] [pallet_xcm_benchmarks::generic, XcmGeneric] @@ -1086,6 +1120,7 @@ impl_runtime_apis! { use frame_support::traits::StorageInfoTrait; use frame_system_benchmarking::Pallet as SystemBench; use cumulus_pallet_session_benchmarking::Pallet as SessionBench; + use pallet_xcm_bridge_hub_router::benchmarking::Pallet as XcmBridgeHubRouterBench; // This is defined once again in dispatch_benchmark, because list_benchmarks! // and add_benchmarks! are macros exported by define_benchmarks! macros and those types @@ -1100,6 +1135,8 @@ impl_runtime_apis! { type Local = pallet_assets::Pallet::; type Foreign = pallet_assets::Pallet::; + type ToKusama = XcmBridgeHubRouterBench; + let mut list = Vec::::new(); list_benchmarks!(list, extra); @@ -1183,7 +1220,13 @@ impl_runtime_apis! { MultiAsset { fun: Fungible(UNITS), id: Concrete(DotLocation::get()) }, )); pub const CheckedAccount: Option<(AccountId, xcm_builder::MintLocation)> = None; - pub const TrustedReserve: Option<(MultiLocation, MultiAsset)> = None; + // AssetHubPolkadot trusts AssetHubKusama as reserve for KSMs + pub TrustedReserve: Option<(MultiLocation, MultiAsset)> = Some( + ( + xcm_config::bridging::to_kusama::AssetHubKusama::get(), + MultiAsset::from((xcm_config::bridging::to_kusama::KsmLocation::get(), 1000000000000 as u128)) + ) + ); } impl pallet_xcm_benchmarks::fungible::Config for Runtime { @@ -1214,7 +1257,8 @@ impl_runtime_apis! { } fn universal_alias() -> Result<(MultiLocation, Junction), BenchmarkError> { - Err(BenchmarkError::Skip) + xcm_config::bridging::BridgingBenchmarksHelper::prepare_universal_alias() + .ok_or(BenchmarkError::Skip) } fn transact_origin_and_runtime_call() -> Result<(MultiLocation, RuntimeCall), BenchmarkError> { @@ -1246,12 +1290,34 @@ impl_runtime_apis! { } } + use pallet_xcm_bridge_hub_router::benchmarking::{ + Pallet as XcmBridgeHubRouterBench, + Config as XcmBridgeHubRouterConfig, + }; + + impl XcmBridgeHubRouterConfig for Runtime { + fn make_congested() { + cumulus_pallet_xcmp_queue::bridging::suspend_channel_for_benchmarks::( + xcm_config::bridging::SiblingBridgeHubParaId::get().into() + ); + } + + fn ensure_bridged_target_destination() -> MultiLocation { + ParachainSystem::open_outbound_hrmp_channel_for_benchmarks_or_tests( + xcm_config::bridging::SiblingBridgeHubParaId::get().into() + ); + xcm_config::bridging::to_kusama::AssetHubKusama::get() + } + } + type XcmBalances = pallet_xcm_benchmarks::fungible::Pallet::; type XcmGeneric = pallet_xcm_benchmarks::generic::Pallet::; type Local = pallet_assets::Pallet::; type Foreign = pallet_assets::Pallet::; + type ToKusama = XcmBridgeHubRouterBench; + let whitelist: Vec = vec![ // Block Number hex_literal::hex!("26aa394eea5630e07c48ae0c9558cef702a5c1b19ab7a04f536c519aca4983ac").to_vec().into(), diff --git a/system-parachains/asset-hubs/asset-hub-polkadot/src/weights/mod.rs b/system-parachains/asset-hubs/asset-hub-polkadot/src/weights/mod.rs index d3408c738d..ae08c4f1f4 100644 --- a/system-parachains/asset-hubs/asset-hub-polkadot/src/weights/mod.rs +++ b/system-parachains/asset-hubs/asset-hub-polkadot/src/weights/mod.rs @@ -30,6 +30,7 @@ pub mod pallet_timestamp; pub mod pallet_uniques; pub mod pallet_utility; pub mod pallet_xcm; +pub mod pallet_xcm_bridge_hub_router; pub mod paritydb_weights; pub mod rocksdb_weights; pub mod xcm; diff --git a/system-parachains/asset-hubs/asset-hub-polkadot/src/weights/pallet_xcm_bridge_hub_router.rs b/system-parachains/asset-hubs/asset-hub-polkadot/src/weights/pallet_xcm_bridge_hub_router.rs new file mode 100644 index 0000000000..744a6a3111 --- /dev/null +++ b/system-parachains/asset-hubs/asset-hub-polkadot/src/weights/pallet_xcm_bridge_hub_router.rs @@ -0,0 +1,110 @@ + +//! Autogenerated weights for `pallet_xcm_bridge_hub_router` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-12-05, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `svyatonik-benchmarking`, CPU: `Intel(R) Xeon(R) CPU @ 2.80GHz` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("ah-polkadot-local-raw.json")`, DB CACHE: 1024 + +// Executed Command: +// ../polkadot-sdk/target/production/polkadot-parachain-benchmarks +// benchmark +// pallet +// --chain +// ah-polkadot-local-raw.json +// --pallet +// pallet-xcm-bridge-hub-router +// --extrinsic +// * +// --output=system-parachains/asset-hubs/asset-hub-polkadot/src/weights +// --no-median-slopes +// --no-min-squares + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_xcm_bridge_hub_router`. +pub struct WeightInfo(PhantomData); +impl pallet_xcm_bridge_hub_router::WeightInfo for WeightInfo { + /// Storage: `XcmpQueue::InboundXcmpStatus` (r:1 w:0) + /// Proof: `XcmpQueue::InboundXcmpStatus` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `XcmpQueue::OutboundXcmpStatus` (r:1 w:0) + /// Proof: `XcmpQueue::OutboundXcmpStatus` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `ToKusamaXcmRouter::Bridge` (r:1 w:1) + /// Proof: `ToKusamaXcmRouter::Bridge` (`max_values`: Some(1), `max_size`: Some(17), added: 512, mode: `MaxEncodedLen`) + fn on_initialize_when_non_congested() -> Weight { + // Proof Size summary in bytes: + // Measured: `193` + // Estimated: `1678` + // Minimum execution time: 10_726_000 picoseconds. + Weight::from_parts(11_346_000, 0) + .saturating_add(Weight::from_parts(0, 1678)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: `XcmpQueue::InboundXcmpStatus` (r:1 w:0) + /// Proof: `XcmpQueue::InboundXcmpStatus` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `XcmpQueue::OutboundXcmpStatus` (r:1 w:0) + /// Proof: `XcmpQueue::OutboundXcmpStatus` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + fn on_initialize_when_congested() -> Weight { + // Proof Size summary in bytes: + // Measured: `111` + // Estimated: `1596` + // Minimum execution time: 4_975_000 picoseconds. + Weight::from_parts(5_197_000, 0) + .saturating_add(Weight::from_parts(0, 1596)) + .saturating_add(T::DbWeight::get().reads(2)) + } + /// Storage: `ToKusamaXcmRouter::Bridge` (r:1 w:1) + /// Proof: `ToKusamaXcmRouter::Bridge` (`max_values`: Some(1), `max_size`: Some(17), added: 512, mode: `MaxEncodedLen`) + fn report_bridge_status() -> Weight { + // Proof Size summary in bytes: + // Measured: `117` + // Estimated: `1502` + // Minimum execution time: 13_131_000 picoseconds. + Weight::from_parts(13_897_000, 0) + .saturating_add(Weight::from_parts(0, 1502)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: `ParachainInfo::ParachainId` (r:1 w:0) + /// Proof: `ParachainInfo::ParachainId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: UNKNOWN KEY `0x3302afcb67e838a3f960251b417b9a4f` (r:1 w:0) + /// Proof: UNKNOWN KEY `0x3302afcb67e838a3f960251b417b9a4f` (r:1 w:0) + /// Storage: UNKNOWN KEY `0x0973fe64c85043ba1c965cbc38eb63c7` (r:1 w:0) + /// Proof: UNKNOWN KEY `0x0973fe64c85043ba1c965cbc38eb63c7` (r:1 w:0) + /// Storage: `ToKusamaXcmRouter::Bridge` (r:1 w:1) + /// Proof: `ToKusamaXcmRouter::Bridge` (`max_values`: Some(1), `max_size`: Some(17), added: 512, mode: `MaxEncodedLen`) + /// Storage: `XcmpQueue::DeliveryFeeFactor` (r:1 w:0) + /// Proof: `XcmpQueue::DeliveryFeeFactor` (`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::RelevantMessagingState` (r:1 w:0) + /// Proof: `ParachainSystem::RelevantMessagingState` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `XcmpQueue::OutboundXcmpStatus` (r:1 w:1) + /// Proof: `XcmpQueue::OutboundXcmpStatus` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `XcmpQueue::InboundXcmpStatus` (r:1 w:0) + /// Proof: `XcmpQueue::InboundXcmpStatus` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `XcmpQueue::OutboundXcmpMessages` (r:0 w:1) + /// Proof: `XcmpQueue::OutboundXcmpMessages` (`max_values`: None, `max_size`: None, mode: `Measured`) + fn send_message() -> Weight { + // Proof Size summary in bytes: + // Measured: `355` + // Estimated: `3820` + // Minimum execution time: 66_293_000 picoseconds. + Weight::from_parts(68_872_000, 0) + .saturating_add(Weight::from_parts(0, 3820)) + .saturating_add(T::DbWeight::get().reads(11)) + .saturating_add(T::DbWeight::get().writes(4)) + } +} diff --git a/system-parachains/asset-hubs/asset-hub-polkadot/src/weights/xcm/mod.rs b/system-parachains/asset-hubs/asset-hub-polkadot/src/weights/xcm/mod.rs index eb140c4bf3..b34f4ed16c 100644 --- a/system-parachains/asset-hubs/asset-hub-polkadot/src/weights/xcm/mod.rs +++ b/system-parachains/asset-hubs/asset-hub-polkadot/src/weights/xcm/mod.rs @@ -209,7 +209,7 @@ impl XcmWeightInfo for AssetHubPolkadotXcmWeight { XcmGeneric::::clear_transact_status() } fn universal_origin(_: &Junction) -> Weight { - Weight::MAX + XcmGeneric::::universal_origin() } fn export_message(_: &NetworkId, _: &Junctions, _: &Xcm<()>) -> Weight { Weight::MAX diff --git a/system-parachains/asset-hubs/asset-hub-polkadot/src/weights/xcm/pallet_xcm_benchmarks_fungible.rs b/system-parachains/asset-hubs/asset-hub-polkadot/src/weights/xcm/pallet_xcm_benchmarks_fungible.rs index 2120b3ddcf..82eed68ead 100644 --- a/system-parachains/asset-hubs/asset-hub-polkadot/src/weights/xcm/pallet_xcm_benchmarks_fungible.rs +++ b/system-parachains/asset-hubs/asset-hub-polkadot/src/weights/xcm/pallet_xcm_benchmarks_fungible.rs @@ -97,15 +97,15 @@ impl WeightInfo { .saturating_add(T::DbWeight::get().reads(10)) .saturating_add(T::DbWeight::get().writes(4)) } - /// Storage: `Benchmark::Override` (r:0 w:0) - /// Proof: `Benchmark::Override` (`max_values`: None, `max_size`: None, mode: `Measured`) - pub(crate) fn reserve_asset_deposited() -> Weight { + // Storage: `ParachainInfo::ParachainId` (r:1 w:0) + // Proof: `ParachainInfo::ParachainId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + pub fn reserve_asset_deposited() -> Weight { // Proof Size summary in bytes: // Measured: `0` - // Estimated: `0` - // Minimum execution time: 18_446_744_073_709_551_000 picoseconds. - Weight::from_parts(18_446_744_073_709_551_000, 0) - .saturating_add(Weight::from_parts(0, 0)) + // Estimated: `1489` + // Minimum execution time: 9_365_000 picoseconds. + Weight::from_parts(9_576_000, 1489) + .saturating_add(T::DbWeight::get().reads(1)) } /// Storage: `ParachainInfo::ParachainId` (r:1 w:0) /// Proof: `ParachainInfo::ParachainId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) diff --git a/system-parachains/asset-hubs/asset-hub-polkadot/src/weights/xcm/pallet_xcm_benchmarks_generic.rs b/system-parachains/asset-hubs/asset-hub-polkadot/src/weights/xcm/pallet_xcm_benchmarks_generic.rs index 061992691a..cfb68a99d2 100644 --- a/system-parachains/asset-hubs/asset-hub-polkadot/src/weights/xcm/pallet_xcm_benchmarks_generic.rs +++ b/system-parachains/asset-hubs/asset-hub-polkadot/src/weights/xcm/pallet_xcm_benchmarks_generic.rs @@ -1,44 +1,26 @@ -// Copyright (C) Parity Technologies (UK) Ltd. -// This file is part of Cumulus. - -// Cumulus is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Cumulus is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Cumulus. If not, see . //! Autogenerated weights for `pallet_xcm_benchmarks::generic` //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-07-31, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2023-12-05, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-ynta1nyy-project-238-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! EXECUTION: , WASM-EXECUTION: Compiled, CHAIN: Some("asset-hub-polkadot-dev"), DB CACHE: 1024 +//! HOSTNAME: `svyatonik-benchmarking`, CPU: `Intel(R) Xeon(R) CPU @ 2.80GHz` +//! WASM-EXECUTION: Compiled, CHAIN: Some("ah-polkadot-local-raw.json"), DB CACHE: 1024 // Executed Command: -// ./target/production/polkadot-parachain +// ../polkadot-sdk/target/production/polkadot-parachain-benchmarks // benchmark // pallet -// --template=./templates/xcm-bench-template.hbs -// --chain=asset-hub-polkadot-dev -// --wasm-execution=compiled -// --pallet=pallet_xcm_benchmarks::generic -// --no-storage-info +// --chain +// ah-polkadot-local-raw.json +// --pallet +// pallet-xcm-benchmarks::generic +// --extrinsic +// report_holding,buy_execution,query_response,transact,refund_surplus,set_error_handler,set_appendix,clear_error,descend_origin,clear_origin,report_error,claim_asset,trap,subscribe_version,unsubscribe_version,burn_asset,expect_asset,expect_origin,expect_error,expect_transact_status,query_pallet,report_transact_status,clear_transact_status,set_topic,clear_topic,export_message,set_fees_mode,unpaid_execution,universal_origin +// --template=../polkadot-sdk/cumulus/templates/xcm-bench-template.hbs +// --output=system-parachains/asset-hubs/asset-hub-polkadot/src/weights/xcm // --no-median-slopes // --no-min-squares -// --extrinsic=* -// --steps=50 -// --repeat=20 -// --json -// --header=./file_header.txt -// --output=./parachains/runtimes/assets/asset-hub-polkadot/src/weights/xcm/pallet_xcm_benchmarks_generic.rs #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -52,31 +34,35 @@ pub struct WeightInfo(PhantomData); impl WeightInfo { // Storage: `ParachainInfo::ParachainId` (r:1 w:0) // Proof: `ParachainInfo::ParachainId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + // Storage: `ParachainSystem::UpwardDeliveryFeeFactor` (r:1 w:0) + // Proof: `ParachainSystem::UpwardDeliveryFeeFactor` (`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) // 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: `System::Account` (r:2 w:1) + // Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) // 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`) pub fn report_holding() -> Weight { // Proof Size summary in bytes: - // Measured: `75` - // Estimated: `3540` - // Minimum execution time: 425_235_000 picoseconds. - Weight::from_parts(432_935_000, 3540) - .saturating_add(T::DbWeight::get().reads(6)) - .saturating_add(T::DbWeight::get().writes(2)) + // Measured: `176` + // Estimated: `6196` + // Minimum execution time: 611_886_000 picoseconds. + Weight::from_parts(620_695_000, 6196) + .saturating_add(T::DbWeight::get().reads(9)) + .saturating_add(T::DbWeight::get().writes(3)) } pub fn buy_execution() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 4_070_000 picoseconds. - Weight::from_parts(4_329_000, 0) + // Minimum execution time: 4_383_000 picoseconds. + Weight::from_parts(4_500_000, 0) } // Storage: `PolkadotXcm::Queries` (r:1 w:0) // Proof: `PolkadotXcm::Queries` (`max_values`: None, `max_size`: None, mode: `Measured`) @@ -84,79 +70,83 @@ impl WeightInfo { // Proof Size summary in bytes: // Measured: `69` // Estimated: `3534` - // Minimum execution time: 11_464_000 picoseconds. - Weight::from_parts(11_829_000, 3534) + // Minimum execution time: 12_188_000 picoseconds. + Weight::from_parts(12_476_000, 3534) .saturating_add(T::DbWeight::get().reads(1)) } pub fn transact() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 13_574_000 picoseconds. - Weight::from_parts(14_021_000, 0) + // Minimum execution time: 14_331_000 picoseconds. + Weight::from_parts(14_711_000, 0) } pub fn refund_surplus() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 4_276_000 picoseconds. - Weight::from_parts(4_479_000, 0) + // Minimum execution time: 4_530_000 picoseconds. + Weight::from_parts(4_631_000, 0) } pub fn set_error_handler() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_833_000 picoseconds. - Weight::from_parts(2_939_000, 0) + // Minimum execution time: 2_991_000 picoseconds. + Weight::from_parts(3_066_000, 0) } pub fn set_appendix() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_797_000 picoseconds. - Weight::from_parts(2_901_000, 0) + // Minimum execution time: 2_973_000 picoseconds. + Weight::from_parts(3_078_000, 0) } pub fn clear_error() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_855_000 picoseconds. - Weight::from_parts(2_961_000, 0) + // Minimum execution time: 2_949_000 picoseconds. + Weight::from_parts(3_045_000, 0) } pub fn descend_origin() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 3_589_000 picoseconds. - Weight::from_parts(3_720_000, 0) + // Minimum execution time: 4_213_000 picoseconds. + Weight::from_parts(4_293_000, 0) } pub fn clear_origin() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_786_000 picoseconds. - Weight::from_parts(2_889_000, 0) + // Minimum execution time: 2_955_000 picoseconds. + Weight::from_parts(3_007_000, 0) } // Storage: `ParachainInfo::ParachainId` (r:1 w:0) // Proof: `ParachainInfo::ParachainId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + // Storage: `ParachainSystem::UpwardDeliveryFeeFactor` (r:1 w:0) + // Proof: `ParachainSystem::UpwardDeliveryFeeFactor` (`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) // 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: `System::Account` (r:2 w:1) + // Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) // 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`) pub fn report_error() -> Weight { // Proof Size summary in bytes: - // Measured: `75` - // Estimated: `3540` - // Minimum execution time: 25_740_000 picoseconds. - Weight::from_parts(26_355_000, 3540) - .saturating_add(T::DbWeight::get().reads(6)) - .saturating_add(T::DbWeight::get().writes(2)) + // Measured: `176` + // Estimated: `6196` + // Minimum execution time: 57_532_000 picoseconds. + Weight::from_parts(58_060_000, 6196) + .saturating_add(T::DbWeight::get().reads(9)) + .saturating_add(T::DbWeight::get().writes(3)) } // Storage: `PolkadotXcm::AssetTraps` (r:1 w:1) // Proof: `PolkadotXcm::AssetTraps` (`max_values`: None, `max_size`: None, mode: `Measured`) @@ -164,8 +154,8 @@ impl WeightInfo { // Proof Size summary in bytes: // Measured: `126` // Estimated: `3591` - // Minimum execution time: 16_206_000 picoseconds. - Weight::from_parts(16_651_000, 3591) + // Minimum execution time: 16_409_000 picoseconds. + Weight::from_parts(16_751_000, 3591) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } @@ -173,11 +163,13 @@ impl WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_819_000 picoseconds. - Weight::from_parts(2_944_000, 0) + // Minimum execution time: 2_957_000 picoseconds. + Weight::from_parts(3_020_000, 0) } // Storage: `PolkadotXcm::VersionNotifyTargets` (r:1 w:1) // Proof: `PolkadotXcm::VersionNotifyTargets` (`max_values`: None, `max_size`: None, mode: `Measured`) + // Storage: `ParachainSystem::UpwardDeliveryFeeFactor` (r:1 w:0) + // Proof: `ParachainSystem::UpwardDeliveryFeeFactor` (`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) @@ -192,9 +184,9 @@ impl WeightInfo { // Proof Size summary in bytes: // Measured: `75` // Estimated: `3540` - // Minimum execution time: 28_216_000 picoseconds. - Weight::from_parts(28_878_000, 3540) - .saturating_add(T::DbWeight::get().reads(6)) + // Minimum execution time: 31_366_000 picoseconds. + Weight::from_parts(32_271_000, 3540) + .saturating_add(T::DbWeight::get().reads(7)) .saturating_add(T::DbWeight::get().writes(3)) } // Storage: `PolkadotXcm::VersionNotifyTargets` (r:0 w:1) @@ -203,127 +195,140 @@ impl WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 4_795_000 picoseconds. - Weight::from_parts(5_008_000, 0) + // Minimum execution time: 5_330_000 picoseconds. + Weight::from_parts(5_528_000, 0) .saturating_add(T::DbWeight::get().writes(1)) } pub fn burn_asset() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 135_205_000 picoseconds. - Weight::from_parts(140_623_000, 0) + // Minimum execution time: 201_668_000 picoseconds. + Weight::from_parts(202_392_000, 0) } pub fn expect_asset() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 12_791_000 picoseconds. - Weight::from_parts(13_114_000, 0) + // Minimum execution time: 17_274_000 picoseconds. + Weight::from_parts(17_475_000, 0) } pub fn expect_origin() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 3_000_000 picoseconds. - Weight::from_parts(3_091_000, 0) + // Minimum execution time: 3_156_000 picoseconds. + Weight::from_parts(3_215_000, 0) } pub fn expect_error() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_828_000 picoseconds. - Weight::from_parts(2_947_000, 0) + // Minimum execution time: 2_975_000 picoseconds. + Weight::from_parts(3_048_000, 0) } pub fn expect_transact_status() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_980_000 picoseconds. - Weight::from_parts(3_123_000, 0) + // Minimum execution time: 3_194_000 picoseconds. + Weight::from_parts(3_274_000, 0) } // Storage: `ParachainInfo::ParachainId` (r:1 w:0) // Proof: `ParachainInfo::ParachainId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + // Storage: `ParachainSystem::UpwardDeliveryFeeFactor` (r:1 w:0) + // Proof: `ParachainSystem::UpwardDeliveryFeeFactor` (`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) // 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: `System::Account` (r:2 w:1) + // Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) // 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`) pub fn query_pallet() -> Weight { // Proof Size summary in bytes: - // Measured: `75` - // Estimated: `3540` - // Minimum execution time: 29_672_000 picoseconds. - Weight::from_parts(30_318_000, 3540) - .saturating_add(T::DbWeight::get().reads(6)) - .saturating_add(T::DbWeight::get().writes(2)) - } - pub fn expect_pallet() -> Weight { - // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 5_421_000 picoseconds. - Weight::from_parts(5_614_000, 0) + // Measured: `176` + // Estimated: `6196` + // Minimum execution time: 62_377_000 picoseconds. + Weight::from_parts(63_285_000, 6196) + .saturating_add(T::DbWeight::get().reads(9)) + .saturating_add(T::DbWeight::get().writes(3)) } // Storage: `ParachainInfo::ParachainId` (r:1 w:0) // Proof: `ParachainInfo::ParachainId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + // Storage: `ParachainSystem::UpwardDeliveryFeeFactor` (r:1 w:0) + // Proof: `ParachainSystem::UpwardDeliveryFeeFactor` (`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) // 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: `System::Account` (r:2 w:1) + // Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) // 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`) pub fn report_transact_status() -> Weight { // Proof Size summary in bytes: - // Measured: `75` - // Estimated: `3540` - // Minimum execution time: 25_621_000 picoseconds. - Weight::from_parts(26_486_000, 3540) - .saturating_add(T::DbWeight::get().reads(6)) - .saturating_add(T::DbWeight::get().writes(2)) + // Measured: `176` + // Estimated: `6196` + // Minimum execution time: 57_515_000 picoseconds. + Weight::from_parts(58_410_000, 6196) + .saturating_add(T::DbWeight::get().reads(9)) + .saturating_add(T::DbWeight::get().writes(3)) } pub fn clear_transact_status() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_873_000 picoseconds. - Weight::from_parts(2_973_000, 0) + // Minimum execution time: 3_026_000 picoseconds. + Weight::from_parts(3_100_000, 0) } pub fn set_topic() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_861_000 picoseconds. - Weight::from_parts(2_923_000, 0) + // Minimum execution time: 2_991_000 picoseconds. + Weight::from_parts(3_057_000, 0) } pub fn clear_topic() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_845_000 picoseconds. - Weight::from_parts(2_970_000, 0) + // Minimum execution time: 2_895_000 picoseconds. + Weight::from_parts(3_036_000, 0) + } + // Storage: `ParachainInfo::ParachainId` (r:1 w:0) + // Proof: `ParachainInfo::ParachainId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + pub fn universal_origin() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `1489` + // Minimum execution time: 5_985_000 picoseconds. + Weight::from_parts(6_133_000, 1489) + .saturating_add(T::DbWeight::get().reads(1)) } pub fn set_fees_mode() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_773_000 picoseconds. - Weight::from_parts(2_922_000, 0) + // Minimum execution time: 2_940_000 picoseconds. + Weight::from_parts(3_043_000, 0) } pub fn unpaid_execution() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_980_000 picoseconds. - Weight::from_parts(3_095_000, 0) + // Minimum execution time: 3_194_000 picoseconds. + Weight::from_parts(3_245_000, 0) } } + +impl WeightInfo { pub fn expect_pallet() -> Weight { Weight::from_parts(5_756_000, 0) } } diff --git a/system-parachains/asset-hubs/asset-hub-polkadot/src/xcm_config.rs b/system-parachains/asset-hubs/asset-hub-polkadot/src/xcm_config.rs index 8d5b6339b7..4f6393a35f 100644 --- a/system-parachains/asset-hubs/asset-hub-polkadot/src/xcm_config.rs +++ b/system-parachains/asset-hubs/asset-hub-polkadot/src/xcm_config.rs @@ -16,8 +16,10 @@ use super::{ AccountId, AllPalletsWithSystem, Assets, Authorship, Balance, Balances, ForeignAssets, ParachainInfo, ParachainSystem, PolkadotXcm, PriceForParentDelivery, Runtime, RuntimeCall, - RuntimeEvent, RuntimeOrigin, TrustBackedAssetsInstance, WeightToFee, XcmpQueue, + RuntimeEvent, RuntimeOrigin, ToKusamaXcmRouter, TransactionByteFee, TrustBackedAssetsInstance, + WeightToFee, XcmpQueue, }; +use crate::ForeignAssetsInstance; use assets_common::matching::{FromSiblingParachain, IsForeignConcreteAsset}; use frame_support::{ match_types, parameter_types, @@ -41,12 +43,12 @@ use xcm_builder::{ AccountId32Aliases, AllowExplicitUnpaidExecutionFrom, AllowKnownQueryResponses, AllowSubscriptionsFrom, AllowTopLevelPaidExecutionFrom, CurrencyAdapter, DenyReserveTransferToRelayChain, DenyThenTry, DescribeAllTerminal, DescribeFamily, - EnsureXcmOrigin, FungiblesAdapter, HashedDescription, IsConcrete, LocalMint, NoChecking, - ParentAsSuperuser, ParentIsPreset, RelayChainAsNative, SiblingParachainAsNative, - SiblingParachainConvertsVia, SignedAccountId32AsNative, SignedToAccountId32, - SovereignSignedViaLocation, StartsWith, StartsWithExplicitGlobalConsensus, TakeWeightCredit, - TrailingSetTopicAsId, UsingComponents, WeightInfoBounds, WithComputedOrigin, WithUniqueTopic, - XcmFeesToAccount, + EnsureXcmOrigin, FungiblesAdapter, GlobalConsensusParachainConvertsFor, HashedDescription, + IsConcrete, LocalMint, NoChecking, ParentAsSuperuser, ParentIsPreset, RelayChainAsNative, + SiblingParachainAsNative, SiblingParachainConvertsVia, SignedAccountId32AsNative, + SignedToAccountId32, SovereignSignedViaLocation, StartsWith, StartsWithExplicitGlobalConsensus, + TakeWeightCredit, TrailingSetTopicAsId, UsingComponents, WeightInfoBounds, WithComputedOrigin, + WithUniqueTopic, XcmFeesToAccount, }; use xcm_executor::{traits::WithOriginFilter, XcmExecutor}; @@ -78,6 +80,9 @@ pub type LocationToAccountId = ( AccountId32Aliases, // Foreign locations alias into accounts according to a hash of their standard description. HashedDescription>, + // Different global consensus parachain sovereign account. + // (Used for over-bridge transfers and reserve processing) + GlobalConsensusParachainConvertsFor, ); /// Means for transacting the native currency on this chain. @@ -215,6 +220,17 @@ impl Contains for SafeCallFilter { } } + // Allow to change dedicated storage items (called by governance-like) + match call { + RuntimeCall::System(frame_system::Call::set_storage { items }) + if items.iter().all(|(k, _)| { + k.eq(&bridging::XcmBridgeHubRouterBaseFee::key()) || + k.eq(&bridging::XcmBridgeHubRouterByteFee::key()) + }) => + return true, + _ => (), + }; + matches!( call, RuntimeCall::PolkadotXcm( @@ -360,6 +376,8 @@ impl Contains for SafeCallFilter { pallet_uniques::Call::set_collection_max_supply { .. } | pallet_uniques::Call::set_price { .. } | pallet_uniques::Call::buy_item { .. } + ) | RuntimeCall::ToKusamaXcmRouter( + pallet_xcm_bridge_hub_router::Call::report_bridge_status { .. } ) ) } @@ -379,10 +397,13 @@ pub type Barrier = TrailingSetTopicAsId< // allow it. AllowTopLevelPaidExecutionFrom, // The locations listed below get free execution. + // Parent, its pluralities (i.e. governance bodies), the Fellows plurality and + // sibling bridge hub get free execution. AllowExplicitUnpaidExecutionFrom<( ParentOrParentsPlurality, FellowshipEntities, Equals, + Equals, )>, // Subscriptions for version tracking are OK. AllowSubscriptionsFrom, @@ -431,16 +452,26 @@ pub type TrustedTeleporters = ( IsForeignConcreteAsset>>, ); +/// Multiplier used for dedicated `TakeFirstAssetTrader` with `ForeignAssets` instance. +pub type ForeignAssetFeeAsExistentialDepositMultiplierFeeCharger = + AssetFeeAsExistentialDepositMultiplier< + Runtime, + WeightToFee, + pallet_assets::BalanceToAssetBalance, + ForeignAssetsInstance, + >; + pub struct XcmConfig; impl xcm_executor::Config for XcmConfig { type RuntimeCall = RuntimeCall; type XcmSender = XcmRouter; type AssetTransactor = AssetTransactors; type OriginConverter = XcmOriginToTransactDispatchOrigin; - // Asset Hub Polkadot does not recognize a reserve location for any asset. This does not prevent - // Asset Hub acting _as_ a reserve location for DOT and assets created under `pallet-assets`. - // For DOT, users must use teleport where allowed (e.g. with the Relay Chain). - type IsReserve = (); + // Asset Hub trusts only particular, pre-configured bridged locations from a different consensus + // as reserve locations (we trust the Bridge Hub to relay the message that a reserve is being + // held). Asset Hub may _act_ as a reserve location for DOT and assets created + // under `pallet-assets`. Users must use teleport where allowed (e.g. DOT with the Relay Chain). + type IsReserve = (bridging::to_kusama::IsTrustedBridgedReserveLocationForConcreteAsset,); type IsTeleporter = TrustedTeleporters; type UniversalLocation = UniversalLocation; type Barrier = Barrier; @@ -451,6 +482,8 @@ impl xcm_executor::Config for XcmConfig { >; type Trader = ( UsingComponents>, + // This trader allows to pay with `is_sufficient=true` "Trust Backed" assets from dedicated + // `pallet_assets` instance - `Assets`. cumulus_primitives_utility::TakeFirstAssetTrader< AccountId, AssetFeeAsExistentialDepositMultiplierFeeCharger, @@ -462,6 +495,19 @@ impl xcm_executor::Config for XcmConfig { XcmAssetFeesReceiver, >, >, + // This trader allows to pay with `is_sufficient=true` "Foreign" assets from dedicated + // `pallet_assets` instance - `ForeignAssets`. + cumulus_primitives_utility::TakeFirstAssetTrader< + AccountId, + ForeignAssetFeeAsExistentialDepositMultiplierFeeCharger, + ForeignAssetsConvertedConcreteId, + ForeignAssets, + cumulus_primitives_utility::XcmFeesTo32ByteAccount< + ForeignFungiblesTransactor, + AccountId, + XcmAssetFeesReceiver, + >, + >, ); type ResponseHandler = PolkadotXcm; type AssetTrap = PolkadotXcm; @@ -473,7 +519,7 @@ impl xcm_executor::Config for XcmConfig { type AssetExchanger = (); type FeeManager = XcmFeesToAccount; type MessageExporter = (); - type UniversalAliases = Nothing; + type UniversalAliases = bridging::to_kusama::UniversalAliases; type CallDispatcher = WithOriginFilter; type SafeCallFilter = SafeCallFilter; type Aliasers = Nothing; @@ -483,13 +529,23 @@ impl xcm_executor::Config for XcmConfig { /// Forms the basis for local origins sending/executing XCMs. pub type LocalOriginToLocation = SignedToAccountId32; -/// The means for routing XCM messages which are not for local execution into the right message -/// queues. -pub type XcmRouter = WithUniqueTopic<( +/// For routing XCM messages which do not cross local consensus boundary. +type LocalXcmRouter = ( // Two routers - use UMP to communicate with the relay chain: cumulus_primitives_utility::ParentAsUmp, // ..and XCMP to communicate with the sibling chains. XcmpQueue, +); + +/// The means for routing XCM messages which are not for local execution into the right message +/// queues. +pub type XcmRouter = WithUniqueTopic<( + // The means for routing XCM messages which are not for local execution into the right message + // queues. + LocalXcmRouter, + // Router which wraps and sends xcm to BridgeHub to be delivered to the Kusama + // GlobalConsensus + ToKusamaXcmRouter, )>; #[cfg(feature = "runtime-benchmarks")] @@ -553,6 +609,129 @@ impl pallet_assets::BenchmarkHelper for XcmBenchmarkHelper { } } +/// All configuration related to bridging +pub mod bridging { + use super::*; + use assets_common::matching; + use sp_std::collections::btree_set::BTreeSet; + use xcm_builder::NetworkExportTableItem; + + parameter_types! { + /// Base price of every Polkadot -> Kusama message. Can be adjusted via + /// governance `set_storage` call. + pub storage XcmBridgeHubRouterBaseFee: Balance = bp_bridge_hub_polkadot::estimate_polkadot_to_kusama_message_fee( + bp_bridge_hub_kusama::BridgeHubKusamaBaseDeliveryFeeInKsms::get() + ); + /// Price of every byte of the Polkadot -> Kusama message. Can be adjusted via + /// governance `set_storage` call. + pub storage XcmBridgeHubRouterByteFee: Balance = TransactionByteFee::get(); + + pub SiblingBridgeHubParaId: u32 = bp_bridge_hub_polkadot::BRIDGE_HUB_POLKADOT_PARACHAIN_ID; + pub SiblingBridgeHub: MultiLocation = MultiLocation::new(1, X1(Parachain(SiblingBridgeHubParaId::get()))); + /// Router expects payment with this `AssetId`. + /// (`AssetId` has to be aligned with `BridgeTable`) + pub XcmBridgeHubRouterFeeAssetId: AssetId = DotLocation::get().into(); + + pub BridgeTable: sp_std::vec::Vec = + sp_std::vec::Vec::new().into_iter() + .chain(to_kusama::BridgeTable::get()) + .collect(); + } + + pub type NetworkExportTable = xcm_builder::NetworkExportTable; + + pub mod to_kusama { + use super::*; + + parameter_types! { + pub SiblingBridgeHubWithBridgeHubKusamaInstance: MultiLocation = MultiLocation::new( + 1, + X2( + Parachain(SiblingBridgeHubParaId::get()), + PalletInstance(bp_bridge_hub_polkadot::WITH_BRIDGE_POLKADOT_TO_KUSAMA_MESSAGES_PALLET_INDEX), + ) + ); + + pub const KusamaNetwork: NetworkId = NetworkId::Kusama; + pub AssetHubKusama: MultiLocation = MultiLocation::new( + 2, + X2( + GlobalConsensus(KusamaNetwork::get()), + Parachain(kusama_runtime_constants::system_parachain::ASSET_HUB_ID), + ), + ); + pub KsmLocation: MultiLocation = MultiLocation::new(2, X1(GlobalConsensus(KusamaNetwork::get()))); + + pub KsmFromAssetHubKusama: (MultiAssetFilter, MultiLocation) = ( + Wild(AllOf { fun: WildFungible, id: Concrete(KsmLocation::get()) }), + AssetHubKusama::get() + ); + + /// Set up exporters configuration. + /// `Option` represents static "base fee" which is used for total delivery fee calculation. + pub BridgeTable: sp_std::vec::Vec = sp_std::vec![ + NetworkExportTableItem::new( + KusamaNetwork::get(), + Some(sp_std::vec![ + AssetHubKusama::get().interior.split_global().expect("invalid configuration for AssetHubPolkadot").1, + ]), + SiblingBridgeHub::get(), + // base delivery fee to local `BridgeHub` + Some(( + XcmBridgeHubRouterFeeAssetId::get(), + XcmBridgeHubRouterBaseFee::get(), + ).into()) + ) + ]; + + /// Universal aliases + pub UniversalAliases: BTreeSet<(MultiLocation, Junction)> = BTreeSet::from_iter( + sp_std::vec![ + (SiblingBridgeHubWithBridgeHubKusamaInstance::get(), GlobalConsensus(KusamaNetwork::get())) + ] + ); + } + + impl Contains<(MultiLocation, Junction)> for UniversalAliases { + fn contains(alias: &(MultiLocation, Junction)) -> bool { + UniversalAliases::get().contains(alias) + } + } + + /// Reserve locations filter for `xcm_executor::Config::IsReserve`. + /// Locations from which the runtime accepts reserved assets. + pub type IsTrustedBridgedReserveLocationForConcreteAsset = + matching::IsTrustedBridgedReserveLocationForConcreteAsset< + UniversalLocation, + ( + // allow receive KSM from AssetHubKusama + xcm_builder::Case, + // and nothing else + ), + >; + } + + /// Benchmarks helper for bridging configuration. + #[cfg(feature = "runtime-benchmarks")] + pub struct BridgingBenchmarksHelper; + + #[cfg(feature = "runtime-benchmarks")] + impl BridgingBenchmarksHelper { + pub fn prepare_universal_alias() -> Option<(MultiLocation, Junction)> { + let alias = + to_kusama::UniversalAliases::get().into_iter().find_map(|(location, junction)| { + match to_kusama::SiblingBridgeHubWithBridgeHubKusamaInstance::get() + .eq(&location) + { + true => Some((location, junction)), + false => None, + } + }); + Some(alias.expect("we expect here BridgeHubPolkadot to Kusama mapping at least")) + } + } +} + #[test] fn foreign_pallet_has_correct_local_account() { use sp_core::crypto::{Ss58AddressFormat, Ss58Codec}; diff --git a/system-parachains/asset-hubs/asset-hub-polkadot/tests/tests.rs b/system-parachains/asset-hubs/asset-hub-polkadot/tests/tests.rs index c56381e099..e5c53f39b2 100644 --- a/system-parachains/asset-hubs/asset-hub-polkadot/tests/tests.rs +++ b/system-parachains/asset-hubs/asset-hub-polkadot/tests/tests.rs @@ -17,16 +17,21 @@ //! Tests for the Polkadot Asset Hub (previously known as Statemint) chain. -use asset_hub_polkadot_runtime::xcm_config::{ - AssetFeeAsExistentialDepositMultiplierFeeCharger, CheckingAccount, DotLocation, - ForeignCreatorsSovereignAccountOf, TrustBackedAssetsPalletLocation, XcmConfig, -}; -pub use asset_hub_polkadot_runtime::{ +use asset_hub_polkadot_runtime::{ + xcm_config::{ + bridging::{self, XcmBridgeHubRouterFeeAssetId}, + AssetFeeAsExistentialDepositMultiplierFeeCharger, CheckingAccount, DotLocation, + ForeignCreatorsSovereignAccountOf, LocationToAccountId, TreasuryAccount, + TrustBackedAssetsPalletLocation, XcmConfig, + }, AllPalletsWithoutSystem, AssetDeposit, Assets, Balances, ExistentialDeposit, ForeignAssets, ForeignAssetsInstance, MetadataDepositBase, MetadataDepositPerByte, ParachainSystem, Runtime, - RuntimeCall, RuntimeEvent, SessionKeys, System, TrustBackedAssetsInstance, + RuntimeCall, RuntimeEvent, SessionKeys, ToKusamaXcmRouterInstance, TrustBackedAssetsInstance, + XcmpQueue, +}; +use asset_test_utils::{ + test_cases_over_bridge::TestBridgingConfig, CollatorSessionKey, CollatorSessionKeys, ExtBuilder, }; -use asset_test_utils::{CollatorSessionKeys, ExtBuilder}; use codec::{Decode, Encode}; use cumulus_primitives_utility::ChargeWeightInFungibles; use frame_support::{ @@ -50,6 +55,14 @@ type AssetIdForTrustBackedAssetsConvert = type RuntimeHelper = asset_test_utils::RuntimeHelper; +fn collator_session_key(account: [u8; 32]) -> CollatorSessionKey { + CollatorSessionKey::new( + AccountId::from(account), + AccountId::from(account), + SessionKeys { aura: AuraId::from(sp_core::ed25519::Public::from_raw(account)) }, + ) +} + fn collator_session_keys() -> CollatorSessionKeys { CollatorSessionKeys::new( AccountId::from(ALICE), @@ -657,3 +670,601 @@ asset_test_utils::include_create_and_manage_foreign_assets_for_local_consensus_p assert_eq!(ForeignAssets::asset_ids().collect::>().len(), 1); }) ); + +fn bridging_to_asset_hub_kusama() -> TestBridgingConfig { + TestBridgingConfig { + bridged_network: bridging::to_kusama::KusamaNetwork::get(), + local_bridge_hub_para_id: bridging::SiblingBridgeHubParaId::get(), + local_bridge_hub_location: bridging::SiblingBridgeHub::get(), + bridged_target_location: bridging::to_kusama::AssetHubKusama::get(), + } +} + +#[test] +fn limited_reserve_transfer_assets_for_native_asset_to_asset_hub_kusama_works() { + missing_asset_test_utils_test_cases_over_bridge::limited_reserve_transfer_assets_for_native_asset_works::< + Runtime, + AllPalletsWithoutSystem, + XcmConfig, + ParachainSystem, + XcmpQueue, + LocationToAccountId, + >( + collator_session_keys(), + ExistentialDeposit::get(), + AccountId::from(ALICE), + Box::new(|runtime_event_encoded: Vec| { + match RuntimeEvent::decode(&mut &runtime_event_encoded[..]) { + Ok(RuntimeEvent::PolkadotXcm(event)) => Some(event), + _ => None, + } + }), + Box::new(|runtime_event_encoded: Vec| { + match RuntimeEvent::decode(&mut &runtime_event_encoded[..]) { + Ok(RuntimeEvent::XcmpQueue(event)) => Some(event), + _ => None, + } + }), + bridging_to_asset_hub_kusama, + WeightLimit::Unlimited, + Some(XcmBridgeHubRouterFeeAssetId::get()), + TreasuryAccount::get(), + ) +} +#[test] +fn receive_reserve_asset_deposited_roc_from_asset_hub_kusama_works() { + const BLOCK_AUTHOR_ACCOUNT: [u8; 32] = [13; 32]; + asset_test_utils::test_cases_over_bridge::receive_reserve_asset_deposited_from_different_consensus_works::< + Runtime, + AllPalletsWithoutSystem, + XcmConfig, + LocationToAccountId, + ForeignAssetsInstance, + >( + collator_session_keys().add(collator_session_key(BLOCK_AUTHOR_ACCOUNT)), + ExistentialDeposit::get(), + AccountId::from([73; 32]), + AccountId::from(BLOCK_AUTHOR_ACCOUNT), + // receiving ROCs + (MultiLocation { parents: 2, interior: X1(GlobalConsensus(Kusama)) }, 1000000000000, 1_000_000_000), + bridging_to_asset_hub_kusama, + ( + X1(PalletInstance(bp_bridge_hub_polkadot::WITH_BRIDGE_POLKADOT_TO_KUSAMA_MESSAGES_PALLET_INDEX)), + GlobalConsensus(Kusama), + X1(Parachain(1000)) + ) + ) +} +#[test] +fn report_bridge_status_from_xcm_bridge_router_for_kusama_works() { + missing_asset_test_utils_test_cases_over_bridge::report_bridge_status_from_xcm_bridge_router_works::< + Runtime, + AllPalletsWithoutSystem, + XcmConfig, + LocationToAccountId, + ToKusamaXcmRouterInstance, + >( + collator_session_keys(), + bridging_to_asset_hub_kusama, + || { + Decode::decode(&mut &bp_asset_hub_polkadot::CongestedMessage::get().encode()[..]) + .unwrap() + }, + || { + Decode::decode(&mut &bp_asset_hub_polkadot::UncongestedMessage::get().encode()[..]) + .unwrap() + }, + ) +} + +#[test] +fn test_report_bridge_status_call_compatibility() { + // if this test fails, make sure `bp_asset_hub_kusama` has valid encoding + assert_eq!( + RuntimeCall::ToKusamaXcmRouter(pallet_xcm_bridge_hub_router::Call::report_bridge_status { + bridge_id: Default::default(), + is_congested: true, + }) + .encode(), + bp_asset_hub_polkadot::Call::ToKusamaXcmRouter( + bp_asset_hub_polkadot::XcmBridgeHubRouterCall::report_bridge_status { + bridge_id: Default::default(), + is_congested: true, + } + ) + .encode() + ) +} + +#[test] +fn check_sane_weight_report_bridge_status() { + use pallet_xcm_bridge_hub_router::WeightInfo; + let actual = >::WeightInfo::report_bridge_status(); + let max_weight = bp_asset_hub_polkadot::XcmBridgeHubRouterTransactCallMaxWeight::get(); + assert!( + actual.all_lte(max_weight), + "max_weight: {:?} should be adjusted to actual {:?}", + max_weight, + actual + ); +} + +#[test] +fn change_xcm_bridge_hub_router_byte_fee_by_governance_works() { + asset_test_utils::test_cases::change_storage_constant_by_governance_works::< + Runtime, + bridging::XcmBridgeHubRouterByteFee, + Balance, + >( + collator_session_keys(), + 1000, + Box::new(|call| RuntimeCall::System(call).encode()), + || { + ( + bridging::XcmBridgeHubRouterByteFee::key().to_vec(), + bridging::XcmBridgeHubRouterByteFee::get(), + ) + }, + |old_value| { + if let Some(new_value) = old_value.checked_add(1) { + new_value + } else { + old_value.checked_sub(1).unwrap() + } + }, + ) +} + +// missing stuff from asset_test_utils::test_cases_over_bridge +// TODO: replace me with direct usages of `asset_test_utils` after deps are bumped to (at least) 1.4 +mod missing_asset_test_utils_test_cases_over_bridge { + use asset_test_utils::test_cases_over_bridge::TestBridgingConfig; + use codec::Encode; + use cumulus_primitives_core::XcmpMessageSource; + use frame_support::{ + assert_ok, + traits::{Currency, Get, OnFinalize, OnInitialize, OriginTrait, ProcessMessageError}, + }; + use frame_system::pallet_prelude::BlockNumberFor; + use parachains_common::{AccountId, Balance}; + use parachains_runtimes_test_utils::{ + mock_open_hrmp_channel, AccountIdOf, BalanceOf, CollatorSessionKeys, ExtBuilder, + RuntimeHelper, ValidatorIdOf, XcmReceivedFrom, + }; + use sp_runtime::{traits::StaticLookup, Saturating}; + use xcm::{latest::prelude::*, VersionedMultiAssets}; + use xcm_builder::{CreateMatcher, MatchXcm}; + use xcm_executor::{ + traits::{ConvertLocation, TransactAsset}, + XcmExecutor, + }; + + /// Helper function to verify `xcm` contains all relevant instructions expected on destination + /// chain as part of a reserve-asset-transfer. + fn assert_matches_reserve_asset_deposited_instructions( + xcm: &mut Xcm, + expected_reserve_assets_deposited: &MultiAssets, + expected_beneficiary: &MultiLocation, + ) { + let _ = xcm + .0 + .matcher() + .skip_inst_while(|inst| !matches!(inst, ReserveAssetDeposited(..))) + .expect("no instruction ReserveAssetDeposited?") + .match_next_inst(|instr| match instr { + ReserveAssetDeposited(reserve_assets) => { + assert_eq!(reserve_assets, expected_reserve_assets_deposited); + Ok(()) + }, + _ => Err(ProcessMessageError::BadFormat), + }) + .expect("expected instruction ReserveAssetDeposited") + .match_next_inst(|instr| match instr { + ClearOrigin => Ok(()), + _ => Err(ProcessMessageError::BadFormat), + }) + .expect("expected instruction ClearOrigin") + .match_next_inst(|instr| match instr { + BuyExecution { .. } => Ok(()), + _ => Err(ProcessMessageError::BadFormat), + }) + .expect("expected instruction BuyExecution") + .match_next_inst(|instr| match instr { + DepositAsset { assets: _, beneficiary } if beneficiary == expected_beneficiary => + Ok(()), + _ => Err(ProcessMessageError::BadFormat), + }) + .expect("expected instruction DepositAsset"); + } + + pub fn limited_reserve_transfer_assets_for_native_asset_works< + Runtime, + AllPalletsWithoutSystem, + XcmConfig, + HrmpChannelOpener, + HrmpChannelSource, + LocationToAccountId, + >( + collator_session_keys: CollatorSessionKeys, + existential_deposit: BalanceOf, + alice_account: AccountIdOf, + unwrap_pallet_xcm_event: Box) -> Option>>, + unwrap_xcmp_queue_event: Box< + dyn Fn(Vec) -> Option>, + >, + prepare_configuration: fn() -> TestBridgingConfig, + weight_limit: WeightLimit, + maybe_paid_export_message: Option, + delivery_fees_account: Option>, + ) where + Runtime: frame_system::Config + + pallet_balances::Config + + pallet_session::Config + + pallet_xcm::Config + + parachain_info::Config + + pallet_collator_selection::Config + + cumulus_pallet_parachain_system::Config + + cumulus_pallet_xcmp_queue::Config, + AllPalletsWithoutSystem: + OnInitialize> + OnFinalize>, + AccountIdOf: Into<[u8; 32]>, + ValidatorIdOf: From>, + BalanceOf: From, + ::Balance: From + Into, + XcmConfig: xcm_executor::Config, + LocationToAccountId: ConvertLocation>, + ::AccountId: + Into<<::RuntimeOrigin as OriginTrait>::AccountId>, + <::Lookup as StaticLookup>::Source: + From<::AccountId>, + ::AccountId: From, + HrmpChannelOpener: frame_support::inherent::ProvideInherent< + Call = cumulus_pallet_parachain_system::Call, + >, + HrmpChannelSource: XcmpMessageSource, + { + let runtime_para_id = 1000; + ExtBuilder::::default() + .with_collators(collator_session_keys.collators()) + .with_session_keys(collator_session_keys.session_keys()) + .with_tracing() + .with_safe_xcm_version(3) + .with_para_id(runtime_para_id.into()) + .build() + .execute_with(|| { + let mut alice = [0u8; 32]; + alice[0] = 1; + let included_head = RuntimeHelper::::run_to_block( + 2, + AccountId::from(alice).into(), + ); + + // prepare bridge config + let TestBridgingConfig { + bridged_network, + local_bridge_hub_para_id, + bridged_target_location: target_location_from_different_consensus, + .. + } = prepare_configuration(); + + let reserve_account = LocationToAccountId::convert_location( + &target_location_from_different_consensus, + ) + .expect("Sovereign account for reserves"); + let balance_to_transfer = 1_000_000_000_000_u128; + let native_asset = MultiLocation::parent(); + + // open HRMP to bridge hub + mock_open_hrmp_channel::( + runtime_para_id.into(), + local_bridge_hub_para_id.into(), + included_head, + &alice, + ); + + // drip ED to account + let alice_account_init_balance = existential_deposit + balance_to_transfer.into(); + let _ = >::deposit_creating( + &alice_account, + alice_account_init_balance, + ); + // SA of target location needs to have at least ED, otherwise making reserve fails + let _ = >::deposit_creating( + &reserve_account, + existential_deposit, + ); + + // we just check here, that user retains enough balance after withdrawal + // and also we check if `balance_to_transfer` is more than `existential_deposit`, + assert!( + (>::free_balance(&alice_account) - + balance_to_transfer.into()) >= + existential_deposit + ); + // SA has just ED + assert_eq!( + >::free_balance(&reserve_account), + existential_deposit + ); + + let delivery_fees_account_balance_before = delivery_fees_account + .as_ref() + .map(|dfa| >::free_balance(dfa)) + .unwrap_or(0.into()); + + // local native asset (pallet_balances) + let asset_to_transfer = MultiAsset { + fun: Fungible(balance_to_transfer.into()), + id: Concrete(native_asset), + }; + + // destination is (some) account relative to the destination different consensus + let target_destination_account = MultiLocation { + parents: 0, + interior: X1(AccountId32 { + network: Some(bridged_network), + id: sp_runtime::AccountId32::new([3; 32]).into(), + }), + }; + + let assets_to_transfer = MultiAssets::from(asset_to_transfer); + let mut expected_assets = assets_to_transfer.clone(); + let context = XcmConfig::UniversalLocation::get(); + expected_assets + .reanchor(&target_location_from_different_consensus, context) + .unwrap(); + + let expected_beneficiary = target_destination_account; + + // Make sure sender has enough funds for paying delivery fees + let handling_delivery_fees = { + // Probable XCM with `ReserveAssetDeposited`. + let mut expected_reserve_asset_deposited_message = Xcm(vec![ + ReserveAssetDeposited(MultiAssets::from(expected_assets.clone())), + ClearOrigin, + BuyExecution { + fees: MultiAsset { + id: Concrete(Default::default()), + fun: Fungible(balance_to_transfer), + }, + weight_limit: Unlimited, + }, + DepositAsset { + assets: Wild(AllCounted(1)), + beneficiary: expected_beneficiary, + }, + SetTopic([ + 220, 188, 144, 32, 213, 83, 111, 175, 44, 210, 111, 19, 90, 165, 191, + 112, 140, 247, 192, 124, 42, 17, 153, 141, 114, 34, 189, 20, 83, 69, + 237, 173, + ]), + ]); + assert_matches_reserve_asset_deposited_instructions( + &mut expected_reserve_asset_deposited_message, + &expected_assets, + &expected_beneficiary, + ); + + // Call `SendXcm::validate` to get delivery fees. + let (_, delivery_fees): (_, MultiAssets) = XcmConfig::XcmSender::validate( + &mut Some(target_location_from_different_consensus), + &mut Some(expected_reserve_asset_deposited_message), + ) + .expect("validate passes"); + // Drip delivery fee to Alice account. + let mut delivery_fees_added = false; + for delivery_fee in delivery_fees.inner() { + assert_ok!(::deposit_asset( + &delivery_fee, + &MultiLocation { + parents: 0, + interior: X1(AccountId32 { + network: None, + id: alice_account.clone().into(), + }), + }, + None, + )); + delivery_fees_added = true; + } + delivery_fees_added + }; + + // do pallet_xcm call reserve transfer + assert_ok!(>::limited_reserve_transfer_assets( + RuntimeHelper::::origin_of( + alice_account.clone() + ), + Box::new(target_location_from_different_consensus.into_versioned()), + Box::new(target_destination_account.into_versioned()), + Box::new(VersionedMultiAssets::from(assets_to_transfer)), + 0, + weight_limit, + )); + + // check events + // check pallet_xcm attempted + RuntimeHelper::::assert_pallet_xcm_event_outcome( + &unwrap_pallet_xcm_event, + |outcome| { + assert_ok!(outcome.ensure_complete()); + }, + ); + + // check that xcm was sent + let xcm_sent_message_hash = >::events() + .into_iter() + .filter_map(|e| unwrap_xcmp_queue_event(e.event.encode())) + .find_map(|e| match e { + cumulus_pallet_xcmp_queue::Event::XcmpMessageSent { message_hash } => + Some(message_hash), + _ => None, + }); + + // read xcm + let xcm_sent = + RuntimeHelper::::take_xcm( + local_bridge_hub_para_id.into(), + ) + .unwrap(); + assert_eq!( + xcm_sent_message_hash, + Some(xcm_sent.using_encoded(sp_io::hashing::blake2_256)) + ); + let mut xcm_sent: Xcm<()> = xcm_sent.try_into().expect("versioned xcm"); + + // check sent XCM ExportMessage to BridgeHub + + // 1. check paid or unpaid + if let Some(expected_fee_asset_id) = maybe_paid_export_message { + xcm_sent + .0 + .matcher() + .match_next_inst(|instr| match instr { + WithdrawAsset(_) => Ok(()), + _ => Err(ProcessMessageError::BadFormat), + }) + .expect("contains WithdrawAsset") + .match_next_inst(|instr| match instr { + BuyExecution { fees, .. } if fees.id.eq(&expected_fee_asset_id) => + Ok(()), + _ => Err(ProcessMessageError::BadFormat), + }) + .expect("contains BuyExecution") + } else { + xcm_sent + .0 + .matcher() + .match_next_inst(|instr| match instr { + // first instruction could be UnpaidExecution (because we could have + // explicit unpaid execution on BridgeHub) + UnpaidExecution { weight_limit, check_origin } + if weight_limit == &Unlimited && check_origin.is_none() => + Ok(()), + _ => Err(ProcessMessageError::BadFormat), + }) + .expect("contains UnpaidExecution") + } + // 2. check ExportMessage + .match_next_inst(|instr| match instr { + // next instruction is ExportMessage + ExportMessage { network, destination, xcm: inner_xcm } => { + assert_eq!(network, &bridged_network); + let (_, target_location_junctions_without_global_consensus) = + target_location_from_different_consensus + .interior + .split_global() + .expect("split works"); + assert_eq!( + destination, + &target_location_junctions_without_global_consensus + ); + assert_matches_reserve_asset_deposited_instructions( + inner_xcm, + &expected_assets, + &expected_beneficiary, + ); + Ok(()) + }, + _ => Err(ProcessMessageError::BadFormat), + }) + .expect("contains ExportMessage"); + + // check alice account decreased by balance_to_transfer + assert_eq!( + >::free_balance(&alice_account), + alice_account_init_balance + .saturating_sub(existential_deposit) + .saturating_sub(balance_to_transfer.into()) + ); + + // check reserve account increased by balance_to_transfer + assert_eq!( + >::free_balance(&reserve_account), + existential_deposit + balance_to_transfer.into() + ); + + // check dedicated account increased by delivery fees (if configured) + if handling_delivery_fees { + if let Some(delivery_fees_account) = delivery_fees_account { + let delivery_fees_account_balance_after = + >::free_balance( + &delivery_fees_account, + ); + assert!( + delivery_fees_account_balance_after > + delivery_fees_account_balance_before + ); + } + } + }) + } + + pub fn report_bridge_status_from_xcm_bridge_router_works< + Runtime, + AllPalletsWithoutSystem, + XcmConfig, + LocationToAccountId, + XcmBridgeHubRouterInstance, + >( + collator_session_keys: CollatorSessionKeys, + prepare_configuration: fn() -> TestBridgingConfig, + congested_message: fn() -> Xcm, + uncongested_message: fn() -> Xcm, + ) where + Runtime: frame_system::Config + + pallet_balances::Config + + pallet_session::Config + + pallet_xcm::Config + + parachain_info::Config + + pallet_collator_selection::Config + + cumulus_pallet_parachain_system::Config + + cumulus_pallet_xcmp_queue::Config + + pallet_xcm_bridge_hub_router::Config, + AllPalletsWithoutSystem: + OnInitialize> + OnFinalize>, + AccountIdOf: Into<[u8; 32]>, + ValidatorIdOf: From>, + BalanceOf: From, + ::Balance: From + Into, + XcmConfig: xcm_executor::Config, + LocationToAccountId: ConvertLocation>, + ::AccountId: + Into<<::RuntimeOrigin as OriginTrait>::AccountId>, + <::Lookup as StaticLookup>::Source: + From<::AccountId>, + ::AccountId: From, + XcmBridgeHubRouterInstance: 'static, + { + ExtBuilder::::default() + .with_collators(collator_session_keys.collators()) + .with_session_keys(collator_session_keys.session_keys()) + .with_tracing() + .build() + .execute_with(|| { + let report_bridge_status = |is_congested: bool| { + // prepare bridge config + let TestBridgingConfig { local_bridge_hub_location, .. } = prepare_configuration(); + + // Call received XCM execution + let xcm = if is_congested { congested_message() } else { uncongested_message() }; + let hash = xcm.using_encoded(sp_io::hashing::blake2_256); + + // execute xcm as XcmpQueue would do + let outcome = XcmExecutor::::execute_xcm( + local_bridge_hub_location, + xcm, + hash, + RuntimeHelper::::xcm_max_weight(XcmReceivedFrom::Sibling), + ); + assert_eq!(outcome.ensure_complete(), Ok(())); + assert_eq!(is_congested, pallet_xcm_bridge_hub_router::Pallet::::bridge().is_congested); + }; + + report_bridge_status(true); + report_bridge_status(false); + }) + } +} diff --git a/system-parachains/bridge-hubs/bridge-hub-kusama/Cargo.toml b/system-parachains/bridge-hubs/bridge-hub-kusama/Cargo.toml index cecd47bb88..2825bb4e11 100644 --- a/system-parachains/bridge-hubs/bridge-hub-kusama/Cargo.toml +++ b/system-parachains/bridge-hubs/bridge-hub-kusama/Cargo.toml @@ -19,6 +19,13 @@ scale-info = { version = "2.9.0", default-features = false, features = ["derive" serde = { version = "1.0.188", optional = true, features = ["derive"] } smallvec = "1.11.0" +# Local +bp-asset-hub-kusama = { path = "../../asset-hubs/asset-hub-kusama/primitives", default-features = false} +bp-asset-hub-polkadot = { path = "../../asset-hubs/asset-hub-polkadot/primitives", default-features = false} +bp-bridge-hub-kusama = { path = "./primitives", default-features = false} +bp-bridge-hub-polkadot = { path = "../bridge-hub-polkadot/primitives", default-features = false} +kusama-runtime-constants = { path = "../../../relay/kusama/constants", default-features = false} + # Substrate frame-benchmarking = { default-features = false, optional = true, version = "25.0.0" } frame-executive = { default-features = false, version = "25.0.0" } @@ -52,7 +59,6 @@ sp-transaction-pool = { default-features = false, version = "23.0.0" } sp-version = { default-features = false, version = "26.0.0" } # Polkadot -kusama-runtime-constants = { path = "../../../relay/kusama/constants", default-features = false} pallet-xcm = { default-features = false, version = "4.0.0" } pallet-xcm-benchmarks = { default-features = false, optional = true , version = "4.0.0" } polkadot-core-primitives = { default-features = false, version = "4.0.0" } @@ -68,7 +74,7 @@ cumulus-pallet-dmp-queue = { default-features = false , version = "0.4.0" } cumulus-pallet-parachain-system = { default-features = false, features = ["parameterized-consensus-hook",] , version = "0.4.0" } cumulus-pallet-session-benchmarking = { default-features = false, version = "6.0.0" } cumulus-pallet-xcm = { default-features = false , version = "0.4.0" } -cumulus-pallet-xcmp-queue = { default-features = false , version = "0.4.0" } +cumulus-pallet-xcmp-queue = { default-features = false , features = ["bridging"] , version = "0.4.0" } cumulus-primitives-core = { default-features = false , version = "0.4.0" } cumulus-primitives-utility = { default-features = false , version = "0.4.0" } pallet-collator-selection = { default-features = false , version = "6.0.0" } @@ -76,12 +82,43 @@ parachain-info = { package = "staging-parachain-info", default-features = false parachains-common = { default-features = false , version = "4.0.0" } system-parachains-constants = { path = "../../constants", default-features = false } +# Bridges +bp-header-chain = { default-features = false , version = "0.4.0" } +bp-messages = { default-features = false , version = "0.4.0" } +bp-parachains = { default-features = false , version = "0.4.0" } +bp-polkadot-core = { default-features = false , version = "0.4.0" } +bp-relayers = { default-features = false , version = "0.4.0" } +bp-runtime = { default-features = false , version = "0.4.0" } +bp-kusama = { default-features = false , version = "0.2.0" } +bp-polkadot = { default-features = false , version = "0.2.0" } +bridge-runtime-common = { default-features = false , version = "0.4.0" } +pallet-bridge-grandpa = { default-features = false , version = "0.4.0" } +pallet-bridge-messages = { default-features = false , version = "0.4.0" } +pallet-bridge-parachains = { default-features = false , version = "0.4.0" } +pallet-bridge-relayers = { default-features = false , version = "0.4.0" } + [dev-dependencies] bridge-hub-test-utils = { version = "0.4.0" } +bridge-runtime-common = { version = "0.4.0", features = ["integrity-test"] } +sp-keyring = { version = "28.0.0" } +static_assertions = { version = "1.1.0" } [features] default = [ "std" ] std = [ + "bp-asset-hub-kusama/std", + "bp-asset-hub-polkadot/std", + "bp-bridge-hub-kusama/std", + "bp-bridge-hub-polkadot/std", + "bp-header-chain/std", + "bp-messages/std", + "bp-parachains/std", + "bp-polkadot-core/std", + "bp-relayers/std", + "bp-runtime/std", + "bp-kusama/std", + "bp-polkadot/std", + "bridge-runtime-common/std", "codec/std", "cumulus-pallet-aura-ext/std", "cumulus-pallet-dmp-queue/std", @@ -103,6 +140,10 @@ std = [ "pallet-aura/std", "pallet-authorship/std", "pallet-balances/std", + "pallet-bridge-grandpa/std", + "pallet-bridge-messages/std", + "pallet-bridge-parachains/std", + "pallet-bridge-relayers/std", "pallet-collator-selection/std", "pallet-multisig/std", "pallet-session/std", @@ -141,6 +182,7 @@ std = [ ] runtime-benchmarks = [ + "bridge-runtime-common/runtime-benchmarks", "cumulus-pallet-parachain-system/runtime-benchmarks", "cumulus-pallet-session-benchmarking/runtime-benchmarks", "cumulus-pallet-xcmp-queue/runtime-benchmarks", @@ -150,12 +192,17 @@ runtime-benchmarks = [ "frame-system-benchmarking/runtime-benchmarks", "frame-system/runtime-benchmarks", "pallet-balances/runtime-benchmarks", + "pallet-bridge-grandpa/runtime-benchmarks", + "pallet-bridge-messages/runtime-benchmarks", + "pallet-bridge-parachains/runtime-benchmarks", + "pallet-bridge-relayers/runtime-benchmarks", "pallet-collator-selection/runtime-benchmarks", "pallet-multisig/runtime-benchmarks", "pallet-timestamp/runtime-benchmarks", "pallet-utility/runtime-benchmarks", "pallet-xcm-benchmarks/runtime-benchmarks", "pallet-xcm/runtime-benchmarks", + "parachains-common/runtime-benchmarks", "polkadot-parachain-primitives/runtime-benchmarks", "polkadot-runtime-common/runtime-benchmarks", "sp-runtime/runtime-benchmarks", @@ -176,6 +223,10 @@ try-runtime = [ "pallet-aura/try-runtime", "pallet-authorship/try-runtime", "pallet-balances/try-runtime", + "pallet-bridge-grandpa/try-runtime", + "pallet-bridge-messages/try-runtime", + "pallet-bridge-parachains/try-runtime", + "pallet-bridge-relayers/try-runtime", "pallet-collator-selection/try-runtime", "pallet-multisig/try-runtime", "pallet-session/try-runtime", diff --git a/system-parachains/bridge-hubs/bridge-hub-kusama/primitives/Cargo.toml b/system-parachains/bridge-hubs/bridge-hub-kusama/primitives/Cargo.toml new file mode 100644 index 0000000000..3f53e6c7f0 --- /dev/null +++ b/system-parachains/bridge-hubs/bridge-hub-kusama/primitives/Cargo.toml @@ -0,0 +1,39 @@ +[package] +name = "bp-bridge-hub-kusama" +description = "Primitives of BridgeHubKusama parachain runtime." +repository.workspace = true +version.workspace = true +authors.workspace = true +edition.workspace = true +license.workspace = true + +[dependencies] + +# Local +kusama-runtime-constants = { path = "../../../../relay/kusama/constants", default-features = false} +polkadot-runtime-constants = { path = "../../../../relay/polkadot/constants", default-features = false} + +# Bridge Dependencies +bp-bridge-hub-cumulus = { default-features = false , version = "0.4.0" } +bp-runtime = { default-features = false , version = "0.4.0" } +bp-messages = { default-features = false , version = "0.4.0" } + +# Substrate Based Dependencies +frame-support = { default-features = false, version = "25.0.0" } +sp-api = { default-features = false, version = "23.0.0" } +sp-runtime = { default-features = false, version = "28.0.0" } +sp-std = { default-features = false , version = "12.0.0" } + +[features] +default = [ "std" ] +std = [ + "bp-bridge-hub-cumulus/std", + "bp-messages/std", + "bp-runtime/std", + "frame-support/std", + "kusama-runtime-constants/std", + "polkadot-runtime-constants/std", + "sp-api/std", + "sp-runtime/std", + "sp-std/std", +] diff --git a/system-parachains/bridge-hubs/bridge-hub-kusama/primitives/src/lib.rs b/system-parachains/bridge-hubs/bridge-hub-kusama/primitives/src/lib.rs new file mode 100644 index 0000000000..a746c2e022 --- /dev/null +++ b/system-parachains/bridge-hubs/bridge-hub-kusama/primitives/src/lib.rs @@ -0,0 +1,153 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Polkadot is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Polkadot. If not, see . + +//! Module with configuration which reflects BridgeHubKusama runtime setup (AccountId, Headers, +//! Hashes...) + +#![cfg_attr(not(feature = "std"), no_std)] + +pub use bp_bridge_hub_cumulus::*; +use bp_messages::*; +use bp_runtime::{ + decl_bridge_finality_runtime_apis, decl_bridge_messages_runtime_apis, Chain, Parachain, +}; +use frame_support::{ + dispatch::DispatchClass, + sp_runtime::{MultiAddress, MultiSigner}, +}; +use sp_runtime::{FixedPointNumber, FixedU128, RuntimeDebug, Saturating}; + +/// BridgeHubKusama parachain. +#[derive(RuntimeDebug)] +pub struct BridgeHubKusama; + +impl Chain for BridgeHubKusama { + type BlockNumber = BlockNumber; + type Hash = Hash; + type Hasher = Hasher; + type Header = Header; + + type AccountId = AccountId; + type Balance = Balance; + type Nonce = Nonce; + type Signature = Signature; + + fn max_extrinsic_size() -> u32 { + *BlockLength::get().max.get(DispatchClass::Normal) + } + + fn max_extrinsic_weight() -> Weight { + BlockWeights::get() + .get(DispatchClass::Normal) + .max_extrinsic + .unwrap_or(Weight::MAX) + } +} + +impl Parachain for BridgeHubKusama { + const PARACHAIN_ID: u32 = BRIDGE_HUB_KUSAMA_PARACHAIN_ID; +} + +/// Public key of the chain account that may be used to verify signatures. +pub type AccountSigner = MultiSigner; + +/// The address format for describing accounts. +pub type Address = MultiAddress; + +/// Identifier of BridgeHubKusama in the Kusama relay chain. +pub const BRIDGE_HUB_KUSAMA_PARACHAIN_ID: u32 = 1002; + +/// Name of the With-BridgeHubKusama messages pallet instance that is deployed at bridged chains. +pub const WITH_BRIDGE_HUB_KUSAMA_MESSAGES_PALLET_NAME: &str = "BridgeKusamaMessages"; + +/// Name of the With-BridgeHubKusama bridge-relayers pallet instance that is deployed at bridged +/// chains. +pub const WITH_BRIDGE_HUB_KUSAMA_RELAYERS_PALLET_NAME: &str = "BridgeRelayers"; + +/// Pallet index of `BridgePolkadotMessages: pallet_bridge_messages::`. +pub const WITH_BRIDGE_KUSAMA_TO_POLKADOT_MESSAGES_PALLET_INDEX: u8 = 53; + +decl_bridge_finality_runtime_apis!(bridge_hub_kusama); +decl_bridge_messages_runtime_apis!(bridge_hub_kusama); + +frame_support::parameter_types! { + /// The XCM fee that is paid for executing XCM program (with `ExportMessage` instruction) at the Kusama + /// BridgeHub. + /// (initially was calculated by test `BridgeHubKusama::can_calculate_weight_for_paid_export_message_with_reserve_transfer` + `33%`) + pub const BridgeHubKusamaBaseXcmFeeInKsms: u128 = 16_196_533_317; + + /// Transaction fee that is paid at the Kusama BridgeHub for delivering single inbound message. + /// (initially was calculated by test `BridgeHubKusama::can_calculate_fee_for_complex_message_delivery_transaction` + `33%`) + pub const BridgeHubKusamaBaseDeliveryFeeInKsms: u128 = 56_516_280_489; + + /// Transaction fee that is paid at the Kusama BridgeHub for delivering single outbound message confirmation. + /// (initially was calculated by test `BridgeHubKusama::can_calculate_fee_for_complex_message_confirmation_transaction` + `33%`) + pub const BridgeHubKusamaBaseConfirmationFeeInKsms: u128 = 53_943_614_276; +} + +/// Compute the total estimated fee that needs to be paid in KSMs by the sender when sending +/// message from Kusama Bridge Hub to Polkadot Bridge Hub. +pub fn estimate_kusama_to_polkadot_message_fee( + bridge_hub_polkadot_base_delivery_fee_in_udots: Balance, +) -> Balance { + // Sender must pay: + // + // 1) an approximate cost of XCM execution (`ExportMessage` and surroundings) at Kusama bridge + // Hub; + // + // 2) the approximate cost of Kusama -> Polkadot message delivery transaction on Polkadot Bridge + // Hub, converted into KSMs using 1:5 conversion rate; + // + // 3) the approximate cost of Kusama -> Polkadot message confirmation transaction on Kusama + // Bridge Hub. + BridgeHubKusamaBaseXcmFeeInKsms::get() + .saturating_add(convert_from_udot_to_uksm(bridge_hub_polkadot_base_delivery_fee_in_udots)) + .saturating_add(BridgeHubKusamaBaseConfirmationFeeInKsms::get()) +} + +/// Convert from uDOTs to uKSMs. +fn convert_from_udot_to_uksm(price_in_udot: Balance) -> Balance { + // assuming exchange rate is 5 DOTs for 1 KSM + let ksm_to_dot_economic_rate = FixedU128::from_rational(1, 5); + // tokens have different nominals and we need to take that into account + let nominal_ratio = FixedU128::from_rational( + kusama_runtime_constants::currency::UNITS, + polkadot_runtime_constants::currency::UNITS, + ); + + ksm_to_dot_economic_rate + .saturating_mul(nominal_ratio) + .saturating_mul(FixedU128::saturating_from_integer(price_in_udot)) + .into_inner() / + FixedU128::DIV +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn convert_from_udot_to_uksm_works() { + let price_in_udot = 77 * polkadot_runtime_constants::currency::UNITS; + let same_price_in_uksm = convert_from_udot_to_uksm(price_in_udot); + + let price_in_dot = + FixedU128::from_rational(price_in_udot, polkadot_runtime_constants::currency::UNITS); + let price_in_ksm = + FixedU128::from_rational(same_price_in_uksm, kusama_runtime_constants::currency::UNITS); + assert_eq!(price_in_dot / FixedU128::saturating_from_integer(5), price_in_ksm); + } +} diff --git a/system-parachains/bridge-hubs/bridge-hub-kusama/src/bridge_to_polkadot_config.rs b/system-parachains/bridge-hubs/bridge-hub-kusama/src/bridge_to_polkadot_config.rs new file mode 100644 index 0000000000..7379898b60 --- /dev/null +++ b/system-parachains/bridge-hubs/bridge-hub-kusama/src/bridge_to_polkadot_config.rs @@ -0,0 +1,404 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Cumulus. + +// Cumulus is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Cumulus is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Cumulus. If not, see . + +//! Bridge definitions used for bridging with Polkadot Bridge Hub. + +use crate::{ + weights, + xcm_config::{UniversalLocation, XcmRouter}, + AccountId, Balance, Balances, BlockNumber, BridgePolkadotMessages, Runtime, RuntimeEvent, + RuntimeOrigin, +}; +use bp_messages::LaneId; +use bp_parachains::SingleParaStoredHeaderDataBuilder; +use bridge_runtime_common::{ + messages, + messages::{ + source::{FromBridgedChainMessagesDeliveryProof, TargetHeaderChainAdapter}, + target::{FromBridgedChainMessagesProof, SourceHeaderChainAdapter}, + MessageBridge, ThisChainWithMessages, UnderlyingChainProvider, + }, + messages_xcm_extension::{ + SenderAndLane, XcmAsPlainPayload, XcmBlobHauler, XcmBlobHaulerAdapter, + XcmBlobMessageDispatch, + }, + refund_relayer_extension::{ + ActualFeeRefund, RefundBridgedParachainMessages, RefundSignedExtensionAdapter, + RefundableMessagesLane, RefundableParachain, + }, +}; +use cumulus_primitives_core::ParentThen; +use frame_support::{parameter_types, traits::PalletInfoAccess}; +use kusama_runtime_constants as constants; +use sp_runtime::{traits::ConstU32, RuntimeDebug}; +use xcm::{ + latest::prelude::*, + prelude::{InteriorMultiLocation, NetworkId}, +}; +use xcm_builder::{BridgeBlobDispatcher, HaulBlobExporter}; + +/// Lane identifier, used to connect Kusama Asset Hub and Polkadot Asset Hub. +pub const XCM_LANE_FOR_ASSET_HUB_KUSAMA_TO_ASSET_HUB_POLKADOT: LaneId = LaneId([0, 0, 0, 1]); + +// Parameters that may be changed by the governance. +parameter_types! { + /// Reward that is paid (by the Kusama Asset Hub) to relayers for delivering a single + /// Kusama -> Polkadot bridge message. + /// + /// This payment is tracked by the `pallet_bridge_relayers` pallet at the Kusama + /// Bridge Hub. + pub storage DeliveryRewardInBalance: Balance = constants::currency::UNITS / 10_000; + + /// Registered relayer stake. + /// + /// Any relayer may reserve this amount on his account and get a priority boost for his + /// message delivery transactions. In exchange, he risks losing his stake if he would + /// submit an invalid transaction. The set of such (registered) relayers is tracked + /// by the `pallet_bridge_relayers` pallet at the Kusama Bridge Hub. + pub storage RequiredStakeForStakeAndSlash: Balance = 100 * constants::currency::UNITS; +} + +// Parameters, used by both XCM and bridge code. +parameter_types! { + /// Polkadot Network identifier. + pub PolkadotGlobalConsensusNetwork: NetworkId = NetworkId::Polkadot; + /// Interior location (relative to this runtime) of the with-Polkadot messages pallet. + pub BridgeKusamaToPolkadotMessagesPalletInstance: InteriorMultiLocation = X1( + PalletInstance(::index() as u8), + ); + + /// Identifier of the sibling Kusama Asset Hub parachain. + pub AssetHubKusamaParaId: cumulus_primitives_core::ParaId = kusama_runtime_constants::system_parachain::ASSET_HUB_ID.into(); + /// A route (XCM location and bridge lane) that the Kusama Asset Hub -> Polkadot Asset Hub + /// message is following. + pub FromAssetHubKusamaToAssetHubPolkadotRoute: SenderAndLane = SenderAndLane::new( + ParentThen(X1(Parachain(AssetHubKusamaParaId::get().into()))).into(), + XCM_LANE_FOR_ASSET_HUB_KUSAMA_TO_ASSET_HUB_POLKADOT, + ); +} + +// Parameters, used by bridge transport code. +parameter_types! { + /// Number of Polkadot headers to keep in the runtime storage. + /// + /// Note that we are keeping only required header information, not the whole header itself. Roughly, it + /// is the 2 hours of real time (assuming that every header is submitted). + pub const RelayChainHeadersToKeep: u32 = 1_200; + /// Number of Polkadot Bridge Hub headers to keep in the runtime storage. + /// + /// Note that we are keeping only required header information, not the whole header itself. Roughly, it + /// is the 2 hours of real time (assuming that every header is submitted). + pub const ParachainHeadsToKeep: u32 = 600; + /// Maximal size of Polkadot Bridge Hub header **part** that we are storing in the runtime storage. + pub const MaxParaHeadDataSize: u32 = bp_polkadot::MAX_NESTED_PARACHAIN_HEAD_DATA_SIZE; + + /// Bridge specific chain (network) identifier of the Polkadot Bridge Hub. + pub const BridgeHubPolkadotChainId: bp_runtime::ChainId = bp_runtime::BRIDGE_HUB_POLKADOT_CHAIN_ID; + /// Name of the `paras` pallet at Polkadot that tracks all parachain heads. + pub const ParachainPalletNameAtPolkadot: &'static str = bp_polkadot::PARAS_PALLET_NAME; + + /// Maximal number of entries in the unrewarded relayers vector at the Kusama Bridge Hub. It matches the + /// maximal number of unrewarded relayers that the single confirmation transaction at Polkadot Bridge + /// Hub may process. + pub const MaxUnrewardedRelayerEntriesAtInboundLane: bp_messages::MessageNonce = + bp_bridge_hub_polkadot::MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX; + /// Maximal number of unconfirmed messages at the Kusama Bridge Hub. It matches the maximal number of + /// uncinfirmed messages that the single confirmation transaction at Polkadot Bridge Hub may process. + pub const MaxUnconfirmedMessagesAtInboundLane: bp_messages::MessageNonce = + bp_bridge_hub_polkadot::MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX; + + /// Lane identifier, used to connect Kusama Asset Hub and Polkadot Asset Hub. + pub const AssetHubKusamaToAssetHubPolkadotMessagesLane: bp_messages::LaneId + = XCM_LANE_FOR_ASSET_HUB_KUSAMA_TO_ASSET_HUB_POLKADOT; + /// All active lanes that the current bridge supports. + pub ActiveOutboundLanesToBridgeHubPolkadot: &'static [bp_messages::LaneId] + = &[XCM_LANE_FOR_ASSET_HUB_KUSAMA_TO_ASSET_HUB_POLKADOT]; + + /// Reserve identifier, used by the `pallet_bridge_relayers` to hold funds of registered relayer. + pub const RelayerStakeReserveId: [u8; 8] = *b"brdgrlrs"; + /// Minimal period of relayer registration. Roughly, it is the 1 hour of real time. + pub const RelayerStakeLease: u32 = 300; + /// Priority boost that the registered relayer receives for every additional message in the message + /// delivery transaction. + /// + /// It is determined semi-automatically - see `FEE_BOOST_PER_MESSAGE` constant to get the + /// meaning of this value + pub PriorityBoostPerMessage: u64 = 182_044_444_444_444; +} + +/// Add GRANDPA bridge pallet to track Polkadot relay chain. +pub type BridgeGrandpaPolkadotInstance = pallet_bridge_grandpa::Instance1; +impl pallet_bridge_grandpa::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type BridgedChain = bp_polkadot::Polkadot; + type MaxFreeMandatoryHeadersPerBlock = ConstU32<4>; + type HeadersToKeep = RelayChainHeadersToKeep; + type WeightInfo = weights::pallet_bridge_grandpa::WeightInfo; +} + +/// Add parachain bridge pallet to track Polkadot BridgeHub parachain. +pub type BridgeParachainPolkadotInstance = pallet_bridge_parachains::Instance1; +impl pallet_bridge_parachains::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type WeightInfo = weights::pallet_bridge_parachains::WeightInfo; + type BridgesGrandpaPalletInstance = BridgeGrandpaPolkadotInstance; + type ParasPalletName = ParachainPalletNameAtPolkadot; + type ParaStoredHeaderDataBuilder = + SingleParaStoredHeaderDataBuilder; + type HeadsToKeep = ParachainHeadsToKeep; + type MaxParaHeadDataSize = MaxParaHeadDataSize; +} + +/// Allows collect and claim rewards for relayers. +impl pallet_bridge_relayers::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type Reward = Balance; + type PaymentProcedure = + bp_relayers::PayRewardFromAccount, AccountId>; + type StakeAndSlash = pallet_bridge_relayers::StakeAndSlashNamed< + AccountId, + BlockNumber, + Balances, + RelayerStakeReserveId, + RequiredStakeForStakeAndSlash, + RelayerStakeLease, + >; + type WeightInfo = weights::pallet_bridge_relayers::WeightInfo; +} + +/// Add XCM messages support for exchanging messages with BridgeHubPolkadot. +pub type WithBridgeHubPolkadotMessagesInstance = pallet_bridge_messages::Instance1; +impl pallet_bridge_messages::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type WeightInfo = weights::pallet_bridge_messages::WeightInfo; + type BridgedChainId = BridgeHubPolkadotChainId; + type ActiveOutboundLanes = ActiveOutboundLanesToBridgeHubPolkadot; + type MaxUnrewardedRelayerEntriesAtInboundLane = MaxUnrewardedRelayerEntriesAtInboundLane; + type MaxUnconfirmedMessagesAtInboundLane = MaxUnconfirmedMessagesAtInboundLane; + + type MaximalOutboundPayloadSize = ToBridgeHubPolkadotMaximalOutboundPayloadSize; + type OutboundPayload = XcmAsPlainPayload; + + type InboundPayload = XcmAsPlainPayload; + type InboundRelayer = AccountId; + type DeliveryPayments = (); + + type TargetHeaderChain = TargetHeaderChainAdapter; + type LaneMessageVerifier = ToBridgeHubPolkadotMessageVerifier; + type DeliveryConfirmationPayments = pallet_bridge_relayers::DeliveryConfirmationPaymentsAdapter< + Runtime, + WithBridgeHubPolkadotMessagesInstance, + DeliveryRewardInBalance, + >; + + type SourceHeaderChain = SourceHeaderChainAdapter; + type MessageDispatch = XcmBlobMessageDispatch< + FromPolkadotMessageBlobDispatcher, + Self::WeightInfo, + cumulus_pallet_xcmp_queue::bridging::OutXcmpChannelStatusProvider< + AssetHubKusamaParaId, + Runtime, + >, + >; + type OnMessagesDelivered = OnMessagesDeliveredFromPolkadot; +} + +/// Proof of messages, coming from Polkadot. +pub type FromPolkadotBridgeHubMessagesProof = + FromBridgedChainMessagesProof; +/// Messages delivery proof for Kusama Bridge Hub -> Polkadot Bridge Hub messages. +pub type ToPolkadotBridgeHubMessagesDeliveryProof = + FromBridgedChainMessagesDeliveryProof; + +/// Dispatches received XCM messages from Polkadot BridgeHub. +type FromPolkadotMessageBlobDispatcher = BridgeBlobDispatcher< + XcmRouter, + UniversalLocation, + BridgeKusamaToPolkadotMessagesPalletInstance, +>; + +/// Export XCM messages to be relayed to the other side +pub type ToBridgeHubPolkadotHaulBlobExporter = HaulBlobExporter< + XcmBlobHaulerAdapter, + PolkadotGlobalConsensusNetwork, + (), +>; +pub struct ToBridgeHubPolkadotXcmBlobHauler; +impl XcmBlobHauler for ToBridgeHubPolkadotXcmBlobHauler { + type Runtime = Runtime; + type MessagesInstance = WithBridgeHubPolkadotMessagesInstance; + type SenderAndLane = FromAssetHubKusamaToAssetHubPolkadotRoute; + + type ToSourceChainSender = XcmRouter; + type CongestedMessage = bp_asset_hub_kusama::CongestedMessage; + type UncongestedMessage = bp_asset_hub_kusama::UncongestedMessage; +} + +/// On messages delivered callback. +type OnMessagesDeliveredFromPolkadot = XcmBlobHaulerAdapter; + +/// Messaging Bridge configuration for BridgeHubKusama -> BridgeHubPolkadot +pub struct WithBridgeHubPolkadotMessageBridge; +impl MessageBridge for WithBridgeHubPolkadotMessageBridge { + const BRIDGED_MESSAGES_PALLET_NAME: &'static str = + bp_bridge_hub_kusama::WITH_BRIDGE_HUB_KUSAMA_MESSAGES_PALLET_NAME; + type ThisChain = BridgeHubKusama; + type BridgedChain = BridgeHubPolkadot; + type BridgedHeaderChain = pallet_bridge_parachains::ParachainHeaders< + Runtime, + BridgeParachainPolkadotInstance, + bp_bridge_hub_polkadot::BridgeHubPolkadot, + >; +} + +/// Message verifier for BridgeHubPolkadot messages sent from BridgeHubKusama +pub type ToBridgeHubPolkadotMessageVerifier = + messages::source::FromThisChainMessageVerifier; + +/// Maximal outbound payload size of BridgeHubKusama -> BridgeHubPolkadot messages. +pub type ToBridgeHubPolkadotMaximalOutboundPayloadSize = + messages::source::FromThisChainMaximalOutboundPayloadSize; + +/// BridgeHubPolkadot chain from message lane point of view. +#[derive(RuntimeDebug, Clone, Copy)] +pub struct BridgeHubPolkadot; + +impl UnderlyingChainProvider for BridgeHubPolkadot { + type Chain = bp_bridge_hub_polkadot::BridgeHubPolkadot; +} + +impl messages::BridgedChainWithMessages for BridgeHubPolkadot {} + +/// BridgeHubKusama chain from message lane point of view. +#[derive(RuntimeDebug, Clone, Copy)] +pub struct BridgeHubKusama; + +impl UnderlyingChainProvider for BridgeHubKusama { + type Chain = bp_bridge_hub_kusama::BridgeHubKusama; +} + +impl ThisChainWithMessages for BridgeHubKusama { + type RuntimeOrigin = RuntimeOrigin; +} + +/// Signed extension that refunds relayers that are delivering messages from the Polkadot parachain. +pub type RefundBridgeHubPolkadotMessages = RefundSignedExtensionAdapter< + RefundBridgedParachainMessages< + Runtime, + RefundableParachain< + BridgeParachainPolkadotInstance, + bp_bridge_hub_polkadot::BridgeHubPolkadot, + >, + RefundableMessagesLane< + WithBridgeHubPolkadotMessagesInstance, + AssetHubKusamaToAssetHubPolkadotMessagesLane, + >, + ActualFeeRefund, + PriorityBoostPerMessage, + StrRefundBridgeHubPolkadotMessages, + >, +>; +bp_runtime::generate_static_str_provider!(RefundBridgeHubPolkadotMessages); + +#[cfg(test)] +mod tests { + use super::*; + use bridge_runtime_common::{ + assert_complete_bridge_types, + integrity::{ + assert_complete_bridge_constants, check_message_lane_weights, + AssertBridgeMessagesPalletConstants, AssertBridgePalletNames, AssertChainConstants, + AssertCompleteBridgeConstants, + }, + }; + + /// Every additional message in the message delivery transaction boosts its priority. + /// So the priority of transaction with `N+1` messages is larger than priority of + /// transaction with `N` messages by the `PriorityBoostPerMessage`. + /// + /// Economically, it is an equivalent of adding tip to the transaction with `N` messages. + /// The `FEE_BOOST_PER_MESSAGE` constant is the value of this tip. + /// + /// We want this tip to be large enough (delivery transactions with more messages = less + /// operational costs and a faster bridge), so this value should be significant. + const FEE_BOOST_PER_MESSAGE: Balance = 2 * constants::currency::UNITS; + + #[test] + fn ensure_bridge_hub_kusama_message_lane_weights_are_correct() { + check_message_lane_weights::< + bp_bridge_hub_kusama::BridgeHubKusama, + Runtime, + WithBridgeHubPolkadotMessagesInstance, + >( + bp_bridge_hub_polkadot::EXTRA_STORAGE_PROOF_SIZE, + bp_bridge_hub_kusama::MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX, + bp_bridge_hub_kusama::MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX, + true, + ); + } + + #[test] + fn ensure_bridge_integrity() { + assert_complete_bridge_types!( + runtime: Runtime, + with_bridged_chain_grandpa_instance: BridgeGrandpaPolkadotInstance, + with_bridged_chain_messages_instance: WithBridgeHubPolkadotMessagesInstance, + bridge: WithBridgeHubPolkadotMessageBridge, + this_chain: bp_kusama::Kusama, + bridged_chain: bp_polkadot::Polkadot, + ); + + assert_complete_bridge_constants::< + Runtime, + BridgeGrandpaPolkadotInstance, + WithBridgeHubPolkadotMessagesInstance, + WithBridgeHubPolkadotMessageBridge, + >(AssertCompleteBridgeConstants { + this_chain_constants: AssertChainConstants { + block_length: bp_bridge_hub_kusama::BlockLength::get(), + block_weights: bp_bridge_hub_kusama::BlockWeights::get(), + }, + messages_pallet_constants: AssertBridgeMessagesPalletConstants { + max_unrewarded_relayers_in_bridged_confirmation_tx: + bp_bridge_hub_polkadot::MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX, + max_unconfirmed_messages_in_bridged_confirmation_tx: + bp_bridge_hub_polkadot::MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX, + bridged_chain_id: bp_runtime::BRIDGE_HUB_POLKADOT_CHAIN_ID, + }, + pallet_names: AssertBridgePalletNames { + with_this_chain_messages_pallet_name: + bp_bridge_hub_kusama::WITH_BRIDGE_HUB_KUSAMA_MESSAGES_PALLET_NAME, + with_bridged_chain_grandpa_pallet_name: + bp_polkadot::WITH_POLKADOT_GRANDPA_PALLET_NAME, + with_bridged_chain_messages_pallet_name: + bp_bridge_hub_polkadot::WITH_BRIDGE_HUB_POLKADOT_MESSAGES_PALLET_NAME, + }, + }); + + bridge_runtime_common::priority_calculator::ensure_priority_boost_is_sane::< + Runtime, + WithBridgeHubPolkadotMessagesInstance, + PriorityBoostPerMessage, + >(FEE_BOOST_PER_MESSAGE); + + assert_eq!( + BridgeKusamaToPolkadotMessagesPalletInstance::get(), + X1(PalletInstance( + bp_bridge_hub_kusama::WITH_BRIDGE_KUSAMA_TO_POLKADOT_MESSAGES_PALLET_INDEX + )) + ); + } +} diff --git a/system-parachains/bridge-hubs/bridge-hub-kusama/src/lib.rs b/system-parachains/bridge-hubs/bridge-hub-kusama/src/lib.rs index 5e5f7e9e0e..8aa92ce9ed 100644 --- a/system-parachains/bridge-hubs/bridge-hub-kusama/src/lib.rs +++ b/system-parachains/bridge-hubs/bridge-hub-kusama/src/lib.rs @@ -22,6 +22,7 @@ #[cfg(feature = "std")] include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs")); +pub mod bridge_to_polkadot_config; mod weights; pub mod xcm_config; @@ -101,8 +102,20 @@ pub type SignedExtra = ( frame_system::CheckNonce, frame_system::CheckWeight, pallet_transaction_payment::ChargeTransactionPayment, + BridgeRejectObsoleteHeadersAndMessages, + bridge_to_polkadot_config::RefundBridgeHubPolkadotMessages, ); +bridge_runtime_common::generate_bridge_reject_obsolete_headers_and_messages! { + RuntimeCall, AccountId, + // Grandpa + BridgePolkadotGrandpa, + // Parachains + BridgePolkadotParachains, + // Messages + BridgePolkadotMessages +} + /// Unchecked extrinsic type as expected by this runtime. pub type UncheckedExtrinsic = generic::UncheckedExtrinsic; @@ -454,6 +467,14 @@ construct_runtime!( // Handy utilities. Utility: pallet_utility::{Pallet, Call, Event} = 40, Multisig: pallet_multisig::{Pallet, Call, Storage, Event} = 41, + + // Pallets that may be used by all bridges. + BridgeRelayers: pallet_bridge_relayers::{Pallet, Call, Storage, Event} = 50, + + // Polkadot bridge pallets. + BridgePolkadotGrandpa: pallet_bridge_grandpa::::{Pallet, Call, Storage, Event, Config} = 51, + BridgePolkadotParachains: pallet_bridge_parachains::::{Pallet, Call, Storage, Event} = 52, + BridgePolkadotMessages: pallet_bridge_messages::::{Pallet, Call, Storage, Event, Config} = 53, } ); @@ -477,6 +498,12 @@ mod benches { // NOTE: Make sure you point to the individual modules below. [pallet_xcm_benchmarks::fungible, XcmBalances] [pallet_xcm_benchmarks::generic, XcmGeneric] + // Shared bridge pallets + [pallet_bridge_relayers, BridgeRelayersBench::] + // Polkadot bridge pallets. + [pallet_bridge_grandpa, PolkadotFinality] + [pallet_bridge_parachains, PolkadotParachains] + [pallet_bridge_messages, PolkadotMessages] ); } @@ -634,6 +661,50 @@ impl_runtime_apis! { } } + impl bp_polkadot::PolkadotFinalityApi for Runtime { + fn best_finalized() -> Option> { + BridgePolkadotGrandpa::best_finalized() + } + + fn synced_headers_grandpa_info( + ) -> Vec> { + BridgePolkadotGrandpa::synced_headers_grandpa_info() + } + } + + impl bp_bridge_hub_polkadot::BridgeHubPolkadotFinalityApi for Runtime { + fn best_finalized() -> Option> { + BridgePolkadotParachains::best_parachain_head_id::< + bp_bridge_hub_polkadot::BridgeHubPolkadot + >().unwrap_or(None) + } + } + + impl bp_bridge_hub_polkadot::FromBridgeHubPolkadotInboundLaneApi for Runtime { + fn message_details( + lane: bp_messages::LaneId, + messages: Vec<(bp_messages::MessagePayload, bp_messages::OutboundMessageDetails)>, + ) -> Vec { + bridge_runtime_common::messages_api::inbound_message_details::< + Runtime, + bridge_to_polkadot_config::WithBridgeHubPolkadotMessagesInstance, + >(lane, messages) + } + } + + impl bp_bridge_hub_polkadot::ToBridgeHubPolkadotOutboundLaneApi for Runtime { + fn message_details( + lane: bp_messages::LaneId, + begin: bp_messages::MessageNonce, + end: bp_messages::MessageNonce, + ) -> Vec { + bridge_runtime_common::messages_api::outbound_message_details::< + Runtime, + bridge_to_polkadot_config::WithBridgeHubPolkadotMessagesInstance, + >(lane, begin, end) + } + } + #[cfg(feature = "try-runtime")] impl frame_try_runtime::TryRuntime for Runtime { fn on_runtime_upgrade(checks: frame_try_runtime::UpgradeCheckSelect) -> (Weight, Weight) { @@ -670,6 +741,11 @@ impl_runtime_apis! { type XcmBalances = pallet_xcm_benchmarks::fungible::Pallet::; type XcmGeneric = pallet_xcm_benchmarks::generic::Pallet::; + use pallet_bridge_relayers::benchmarking::Pallet as BridgeRelayersBench; + type PolkadotFinality = BridgePolkadotGrandpa; + type PolkadotParachains = pallet_bridge_parachains::benchmarking::Pallet::; + type PolkadotMessages = pallet_bridge_messages::benchmarking::Pallet::; + let mut list = Vec::::new(); list_benchmarks!(list, extra); @@ -792,7 +868,7 @@ impl_runtime_apis! { fn export_message_origin_and_destination( ) -> Result<(MultiLocation, NetworkId, InteriorMultiLocation), BenchmarkError> { - Err(BenchmarkError::Skip) + Ok((KsmRelayLocation::get(), NetworkId::Polkadot, X1(Parachain(1000)))) } fn alias_origin() -> Result<(MultiLocation, MultiLocation), BenchmarkError> { @@ -803,6 +879,114 @@ impl_runtime_apis! { type XcmBalances = pallet_xcm_benchmarks::fungible::Pallet::; type XcmGeneric = pallet_xcm_benchmarks::generic::Pallet::; + type PolkadotFinality = BridgePolkadotGrandpa; + type PolkadotParachains = pallet_bridge_parachains::benchmarking::Pallet::; + type PolkadotMessages = pallet_bridge_messages::benchmarking::Pallet::; + + use pallet_bridge_relayers::benchmarking::{ + Pallet as BridgeRelayersBench, + Config as BridgeRelayersConfig, + }; + + impl BridgeRelayersConfig for Runtime { + fn prepare_rewards_account( + account_params: bp_relayers::RewardsAccountParams, + reward: Balance, + ) { + let rewards_account = bp_relayers::PayRewardFromAccount::< + Balances, + AccountId + >::rewards_account(account_params); + Self::deposit_account(rewards_account, reward); + } + + fn deposit_account(account: AccountId, balance: Balance) { + use frame_support::traits::fungible::Mutate; + Balances::mint_into(&account, balance.saturating_add(ExistentialDeposit::get())).unwrap(); + } + } + + use bridge_runtime_common::parachains_benchmarking::prepare_parachain_heads_proof; + use pallet_bridge_parachains::benchmarking::Config as BridgeParachainsConfig; + + impl BridgeParachainsConfig for Runtime { + fn parachains() -> Vec { + use bp_runtime::Parachain; + vec![bp_polkadot_core::parachains::ParaId(bp_bridge_hub_polkadot::BridgeHubPolkadot::PARACHAIN_ID)] + } + + fn prepare_parachain_heads_proof( + parachains: &[bp_polkadot_core::parachains::ParaId], + parachain_head_size: u32, + proof_size: bp_runtime::StorageProofSize, + ) -> ( + pallet_bridge_parachains::RelayBlockNumber, + pallet_bridge_parachains::RelayBlockHash, + bp_polkadot_core::parachains::ParaHeadsProof, + Vec<(bp_polkadot_core::parachains::ParaId, bp_polkadot_core::parachains::ParaHash)>, + ) { + prepare_parachain_heads_proof::( + parachains, + parachain_head_size, + proof_size, + ) + } + } + + use bridge_runtime_common::messages_benchmarking::{ + prepare_message_delivery_proof_from_parachain, + prepare_message_proof_from_parachain, + generate_xcm_builder_bridge_message_sample, + }; + use pallet_bridge_messages::benchmarking::{ + Config as BridgeMessagesConfig, + MessageDeliveryProofParams, + MessageProofParams, + }; + + impl BridgeMessagesConfig for Runtime { + fn is_relayer_rewarded(relayer: &Self::AccountId) -> bool { + let bench_lane_id = >::bench_lane_id(); + let bridged_chain_id = bp_runtime::BRIDGE_HUB_POLKADOT_CHAIN_ID; + pallet_bridge_relayers::Pallet::::relayer_reward( + relayer, + bp_relayers::RewardsAccountParams::new( + bench_lane_id, + bridged_chain_id, + bp_relayers::RewardsAccountOwner::BridgedChain + ) + ).is_some() + } + + fn prepare_message_proof( + params: MessageProofParams, + ) -> (bridge_to_polkadot_config::FromPolkadotBridgeHubMessagesProof, Weight) { + use cumulus_primitives_core::XcmpMessageSource; + assert!(XcmpQueue::take_outbound_messages(usize::MAX).is_empty()); + ParachainSystem::open_outbound_hrmp_channel_for_benchmarks_or_tests(42.into()); + prepare_message_proof_from_parachain::< + Runtime, + bridge_to_polkadot_config::BridgeGrandpaPolkadotInstance, + bridge_to_polkadot_config::WithBridgeHubPolkadotMessageBridge, + >(params, generate_xcm_builder_bridge_message_sample(X2(GlobalConsensus(Kusama), Parachain(42)))) + } + + fn prepare_message_delivery_proof( + params: MessageDeliveryProofParams, + ) -> bridge_to_polkadot_config::ToPolkadotBridgeHubMessagesDeliveryProof { + prepare_message_delivery_proof_from_parachain::< + Runtime, + bridge_to_polkadot_config::BridgeGrandpaPolkadotInstance, + bridge_to_polkadot_config::WithBridgeHubPolkadotMessageBridge, + >(params) + } + + fn is_message_successfully_dispatched(_nonce: bp_messages::MessageNonce) -> bool { + use cumulus_primitives_core::XcmpMessageSource; + !XcmpQueue::take_outbound_messages(usize::MAX).is_empty() + } + } + let whitelist: Vec = vec![ // Block Number hex_literal::hex!("26aa394eea5630e07c48ae0c9558cef702a5c1b19ab7a04f536c519aca4983ac").to_vec().into(), diff --git a/system-parachains/bridge-hubs/bridge-hub-kusama/src/weights/mod.rs b/system-parachains/bridge-hubs/bridge-hub-kusama/src/weights/mod.rs index 60dfbea8db..a65be4f0d7 100644 --- a/system-parachains/bridge-hubs/bridge-hub-kusama/src/weights/mod.rs +++ b/system-parachains/bridge-hubs/bridge-hub-kusama/src/weights/mod.rs @@ -17,11 +17,21 @@ //! Expose the auto generated weight files. +use crate::Runtime; +use ::pallet_bridge_messages::WeightInfoExt as MessagesWeightInfoExt; +use ::pallet_bridge_parachains::WeightInfoExt as ParachainsWeightInfoExt; +use ::pallet_bridge_relayers::WeightInfoExt as _; +use frame_support::weights::Weight; + pub mod block_weights; pub mod cumulus_pallet_xcmp_queue; pub mod extrinsic_weights; pub mod frame_system; pub mod pallet_balances; +pub mod pallet_bridge_grandpa; +pub mod pallet_bridge_messages; +pub mod pallet_bridge_parachains; +pub mod pallet_bridge_relayers; pub mod pallet_collator_selection; pub mod pallet_multisig; pub mod pallet_session; @@ -35,3 +45,24 @@ pub mod xcm; pub use block_weights::constants::BlockExecutionWeight; pub use extrinsic_weights::constants::ExtrinsicBaseWeight; pub use rocksdb_weights::constants::RocksDbWeight; + +impl MessagesWeightInfoExt for pallet_bridge_messages::WeightInfo { + fn expected_extra_storage_proof_size() -> u32 { + bp_bridge_hub_polkadot::EXTRA_STORAGE_PROOF_SIZE + } + + fn receive_messages_proof_overhead_from_runtime() -> Weight { + pallet_bridge_relayers::WeightInfo::::receive_messages_proof_overhead_from_runtime( + ) + } + + fn receive_messages_delivery_proof_overhead_from_runtime() -> Weight { + pallet_bridge_relayers::WeightInfo::::receive_messages_delivery_proof_overhead_from_runtime() + } +} + +impl ParachainsWeightInfoExt for pallet_bridge_parachains::WeightInfo { + fn expected_extra_storage_proof_size() -> u32 { + bp_bridge_hub_polkadot::EXTRA_STORAGE_PROOF_SIZE + } +} diff --git a/system-parachains/bridge-hubs/bridge-hub-kusama/src/weights/pallet_bridge_grandpa.rs b/system-parachains/bridge-hubs/bridge-hub-kusama/src/weights/pallet_bridge_grandpa.rs new file mode 100644 index 0000000000..9998670c35 --- /dev/null +++ b/system-parachains/bridge-hubs/bridge-hub-kusama/src/weights/pallet_bridge_grandpa.rs @@ -0,0 +1,63 @@ + +//! Autogenerated weights for `pallet_bridge_grandpa` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-12-05, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `svyatonik-benchmarking`, CPU: `Intel(R) Xeon(R) CPU @ 2.80GHz` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("bh-kusama-local-raw.json")`, DB CACHE: 1024 + +// Executed Command: +// ../polkadot-sdk/target/production/polkadot-parachain-benchmarks +// benchmark +// pallet +// --chain +// bh-kusama-local-raw.json +// --pallet +// pallet-bridge-grandpa +// --extrinsic +// * +// --output=system-parachains/bridge-hubs/bridge-hub-kusama/src/weights +// --no-median-slopes +// --no-min-squares + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_bridge_grandpa`. +pub struct WeightInfo(PhantomData); +impl pallet_bridge_grandpa::WeightInfo for WeightInfo { + /// Storage: `BridgePolkadotGrandpa::PalletOperatingMode` (r:1 w:0) + /// Proof: `BridgePolkadotGrandpa::PalletOperatingMode` (`max_values`: Some(1), `max_size`: Some(1), added: 496, mode: `MaxEncodedLen`) + /// Storage: `BridgePolkadotGrandpa::BestFinalized` (r:1 w:1) + /// Proof: `BridgePolkadotGrandpa::BestFinalized` (`max_values`: Some(1), `max_size`: Some(36), added: 531, mode: `MaxEncodedLen`) + /// Storage: `BridgePolkadotGrandpa::CurrentAuthoritySet` (r:1 w:0) + /// Proof: `BridgePolkadotGrandpa::CurrentAuthoritySet` (`max_values`: Some(1), `max_size`: Some(50250), added: 50745, mode: `MaxEncodedLen`) + /// Storage: `BridgePolkadotGrandpa::ImportedHashesPointer` (r:1 w:1) + /// Proof: `BridgePolkadotGrandpa::ImportedHashesPointer` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `BridgePolkadotGrandpa::ImportedHashes` (r:1 w:1) + /// Proof: `BridgePolkadotGrandpa::ImportedHashes` (`max_values`: Some(1200), `max_size`: Some(36), added: 1521, mode: `MaxEncodedLen`) + /// Storage: `BridgePolkadotGrandpa::ImportedHeaders` (r:0 w:2) + /// Proof: `BridgePolkadotGrandpa::ImportedHeaders` (`max_values`: Some(1200), `max_size`: Some(68), added: 1553, mode: `MaxEncodedLen`) + /// The range of component `p` is `[1, 838]`. + /// The range of component `v` is `[50, 100]`. + fn submit_finality_proof(p: u32, v: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `231 + p * (60 ±0)` + // Estimated: `51735` + // Minimum execution time: 368_161_000 picoseconds. + Weight::from_parts(76_463_974, 0) + .saturating_add(Weight::from_parts(0, 51735)) + // Standard Error: 7_393 + .saturating_add(Weight::from_parts(61_698_143, 0).saturating_mul(p.into())) + // Standard Error: 123_310 + .saturating_add(Weight::from_parts(3_056_651, 0).saturating_mul(v.into())) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().writes(5)) + } +} diff --git a/system-parachains/bridge-hubs/bridge-hub-kusama/src/weights/pallet_bridge_messages.rs b/system-parachains/bridge-hubs/bridge-hub-kusama/src/weights/pallet_bridge_messages.rs new file mode 100644 index 0000000000..799bc357c6 --- /dev/null +++ b/system-parachains/bridge-hubs/bridge-hub-kusama/src/weights/pallet_bridge_messages.rs @@ -0,0 +1,226 @@ + +//! Autogenerated weights for `pallet_bridge_messages` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-12-05, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `svyatonik-benchmarking`, CPU: `Intel(R) Xeon(R) CPU @ 2.80GHz` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("bh-kusama-local-raw.json")`, DB CACHE: 1024 + +// Executed Command: +// ../polkadot-sdk/target/production/polkadot-parachain-benchmarks +// benchmark +// pallet +// --chain +// bh-kusama-local-raw.json +// --pallet +// pallet-bridge-messages +// --extrinsic +// * +// --output=system-parachains/bridge-hubs/bridge-hub-kusama/src/weights +// --no-median-slopes +// --no-min-squares + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_bridge_messages`. +pub struct WeightInfo(PhantomData); +impl pallet_bridge_messages::WeightInfo for WeightInfo { + /// Storage: `BridgePolkadotMessages::PalletOperatingMode` (r:1 w:0) + /// Proof: `BridgePolkadotMessages::PalletOperatingMode` (`max_values`: Some(1), `max_size`: Some(2), added: 497, mode: `MaxEncodedLen`) + /// Storage: `XcmpQueue::OutboundXcmpStatus` (r:1 w:0) + /// Proof: `XcmpQueue::OutboundXcmpStatus` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `BridgePolkadotParachains::ImportedParaHeads` (r:1 w:0) + /// Proof: `BridgePolkadotParachains::ImportedParaHeads` (`max_values`: Some(600), `max_size`: Some(196), added: 1681, mode: `MaxEncodedLen`) + /// Storage: `BridgePolkadotMessages::InboundLanes` (r:1 w:1) + /// Proof: `BridgePolkadotMessages::InboundLanes` (`max_values`: None, `max_size`: Some(49180), added: 51655, mode: `MaxEncodedLen`) + /// Storage: `ParachainInfo::ParachainId` (r:1 w:0) + /// Proof: `ParachainInfo::ParachainId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + fn receive_single_message_proof() -> Weight { + // Proof Size summary in bytes: + // Measured: `470` + // Estimated: `52645` + // Minimum execution time: 73_258_000 picoseconds. + Weight::from_parts(75_198_000, 0) + .saturating_add(Weight::from_parts(0, 52645)) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: `BridgePolkadotMessages::PalletOperatingMode` (r:1 w:0) + /// Proof: `BridgePolkadotMessages::PalletOperatingMode` (`max_values`: Some(1), `max_size`: Some(2), added: 497, mode: `MaxEncodedLen`) + /// Storage: `XcmpQueue::OutboundXcmpStatus` (r:1 w:0) + /// Proof: `XcmpQueue::OutboundXcmpStatus` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `BridgePolkadotParachains::ImportedParaHeads` (r:1 w:0) + /// Proof: `BridgePolkadotParachains::ImportedParaHeads` (`max_values`: Some(600), `max_size`: Some(196), added: 1681, mode: `MaxEncodedLen`) + /// Storage: `BridgePolkadotMessages::InboundLanes` (r:1 w:1) + /// Proof: `BridgePolkadotMessages::InboundLanes` (`max_values`: None, `max_size`: Some(49180), added: 51655, mode: `MaxEncodedLen`) + /// Storage: `ParachainInfo::ParachainId` (r:1 w:0) + /// Proof: `ParachainInfo::ParachainId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + fn receive_two_messages_proof() -> Weight { + // Proof Size summary in bytes: + // Measured: `470` + // Estimated: `52645` + // Minimum execution time: 92_110_000 picoseconds. + Weight::from_parts(94_813_000, 0) + .saturating_add(Weight::from_parts(0, 52645)) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: `BridgePolkadotMessages::PalletOperatingMode` (r:1 w:0) + /// Proof: `BridgePolkadotMessages::PalletOperatingMode` (`max_values`: Some(1), `max_size`: Some(2), added: 497, mode: `MaxEncodedLen`) + /// Storage: `XcmpQueue::OutboundXcmpStatus` (r:1 w:0) + /// Proof: `XcmpQueue::OutboundXcmpStatus` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `BridgePolkadotParachains::ImportedParaHeads` (r:1 w:0) + /// Proof: `BridgePolkadotParachains::ImportedParaHeads` (`max_values`: Some(600), `max_size`: Some(196), added: 1681, mode: `MaxEncodedLen`) + /// Storage: `BridgePolkadotMessages::InboundLanes` (r:1 w:1) + /// Proof: `BridgePolkadotMessages::InboundLanes` (`max_values`: None, `max_size`: Some(49180), added: 51655, mode: `MaxEncodedLen`) + /// Storage: `ParachainInfo::ParachainId` (r:1 w:0) + /// Proof: `ParachainInfo::ParachainId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + fn receive_single_message_proof_with_outbound_lane_state() -> Weight { + // Proof Size summary in bytes: + // Measured: `470` + // Estimated: `52645` + // Minimum execution time: 81_696_000 picoseconds. + Weight::from_parts(84_047_000, 0) + .saturating_add(Weight::from_parts(0, 52645)) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: `BridgePolkadotMessages::PalletOperatingMode` (r:1 w:0) + /// Proof: `BridgePolkadotMessages::PalletOperatingMode` (`max_values`: Some(1), `max_size`: Some(2), added: 497, mode: `MaxEncodedLen`) + /// Storage: `XcmpQueue::OutboundXcmpStatus` (r:1 w:0) + /// Proof: `XcmpQueue::OutboundXcmpStatus` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `BridgePolkadotParachains::ImportedParaHeads` (r:1 w:0) + /// Proof: `BridgePolkadotParachains::ImportedParaHeads` (`max_values`: Some(600), `max_size`: Some(196), added: 1681, mode: `MaxEncodedLen`) + /// Storage: `BridgePolkadotMessages::InboundLanes` (r:1 w:1) + /// Proof: `BridgePolkadotMessages::InboundLanes` (`max_values`: None, `max_size`: Some(49180), added: 51655, mode: `MaxEncodedLen`) + fn receive_single_message_proof_1_kb() -> Weight { + // Proof Size summary in bytes: + // Measured: `438` + // Estimated: `52645` + // Minimum execution time: 71_530_000 picoseconds. + Weight::from_parts(73_127_000, 0) + .saturating_add(Weight::from_parts(0, 52645)) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: `BridgePolkadotMessages::PalletOperatingMode` (r:1 w:0) + /// Proof: `BridgePolkadotMessages::PalletOperatingMode` (`max_values`: Some(1), `max_size`: Some(2), added: 497, mode: `MaxEncodedLen`) + /// Storage: `XcmpQueue::OutboundXcmpStatus` (r:1 w:0) + /// Proof: `XcmpQueue::OutboundXcmpStatus` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `BridgePolkadotParachains::ImportedParaHeads` (r:1 w:0) + /// Proof: `BridgePolkadotParachains::ImportedParaHeads` (`max_values`: Some(600), `max_size`: Some(196), added: 1681, mode: `MaxEncodedLen`) + /// Storage: `BridgePolkadotMessages::InboundLanes` (r:1 w:1) + /// Proof: `BridgePolkadotMessages::InboundLanes` (`max_values`: None, `max_size`: Some(49180), added: 51655, mode: `MaxEncodedLen`) + fn receive_single_message_proof_16_kb() -> Weight { + // Proof Size summary in bytes: + // Measured: `438` + // Estimated: `52645` + // Minimum execution time: 112_482_000 picoseconds. + Weight::from_parts(115_496_000, 0) + .saturating_add(Weight::from_parts(0, 52645)) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: `BridgePolkadotMessages::PalletOperatingMode` (r:1 w:0) + /// Proof: `BridgePolkadotMessages::PalletOperatingMode` (`max_values`: Some(1), `max_size`: Some(2), added: 497, mode: `MaxEncodedLen`) + /// Storage: `BridgePolkadotParachains::ImportedParaHeads` (r:1 w:0) + /// Proof: `BridgePolkadotParachains::ImportedParaHeads` (`max_values`: Some(600), `max_size`: Some(196), added: 1681, mode: `MaxEncodedLen`) + /// Storage: `BridgePolkadotMessages::OutboundLanes` (r:1 w:1) + /// Proof: `BridgePolkadotMessages::OutboundLanes` (`max_values`: Some(1), `max_size`: Some(44), added: 539, mode: `MaxEncodedLen`) + /// Storage: UNKNOWN KEY `0x6e0a18b62a1de81c5f519181cc611e18` (r:1 w:0) + /// Proof: UNKNOWN KEY `0x6e0a18b62a1de81c5f519181cc611e18` (r:1 w:0) + /// Storage: `BridgeRelayers::RelayerRewards` (r:1 w:1) + /// Proof: `BridgeRelayers::RelayerRewards` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) + fn receive_delivery_proof_for_single_message() -> Weight { + // Proof Size summary in bytes: + // Measured: `343` + // Estimated: `3808` + // Minimum execution time: 40_730_000 picoseconds. + Weight::from_parts(41_879_000, 0) + .saturating_add(Weight::from_parts(0, 3808)) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: `BridgePolkadotMessages::PalletOperatingMode` (r:1 w:0) + /// Proof: `BridgePolkadotMessages::PalletOperatingMode` (`max_values`: Some(1), `max_size`: Some(2), added: 497, mode: `MaxEncodedLen`) + /// Storage: `BridgePolkadotParachains::ImportedParaHeads` (r:1 w:0) + /// Proof: `BridgePolkadotParachains::ImportedParaHeads` (`max_values`: Some(600), `max_size`: Some(196), added: 1681, mode: `MaxEncodedLen`) + /// Storage: `BridgePolkadotMessages::OutboundLanes` (r:1 w:1) + /// Proof: `BridgePolkadotMessages::OutboundLanes` (`max_values`: Some(1), `max_size`: Some(44), added: 539, mode: `MaxEncodedLen`) + /// Storage: UNKNOWN KEY `0x6e0a18b62a1de81c5f519181cc611e18` (r:1 w:0) + /// Proof: UNKNOWN KEY `0x6e0a18b62a1de81c5f519181cc611e18` (r:1 w:0) + /// Storage: `BridgeRelayers::RelayerRewards` (r:1 w:1) + /// Proof: `BridgeRelayers::RelayerRewards` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) + fn receive_delivery_proof_for_two_messages_by_single_relayer() -> Weight { + // Proof Size summary in bytes: + // Measured: `343` + // Estimated: `3808` + // Minimum execution time: 40_765_000 picoseconds. + Weight::from_parts(41_895_000, 0) + .saturating_add(Weight::from_parts(0, 3808)) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: `BridgePolkadotMessages::PalletOperatingMode` (r:1 w:0) + /// Proof: `BridgePolkadotMessages::PalletOperatingMode` (`max_values`: Some(1), `max_size`: Some(2), added: 497, mode: `MaxEncodedLen`) + /// Storage: `BridgePolkadotParachains::ImportedParaHeads` (r:1 w:0) + /// Proof: `BridgePolkadotParachains::ImportedParaHeads` (`max_values`: Some(600), `max_size`: Some(196), added: 1681, mode: `MaxEncodedLen`) + /// Storage: `BridgePolkadotMessages::OutboundLanes` (r:1 w:1) + /// Proof: `BridgePolkadotMessages::OutboundLanes` (`max_values`: Some(1), `max_size`: Some(44), added: 539, mode: `MaxEncodedLen`) + /// Storage: UNKNOWN KEY `0x6e0a18b62a1de81c5f519181cc611e18` (r:1 w:0) + /// Proof: UNKNOWN KEY `0x6e0a18b62a1de81c5f519181cc611e18` (r:1 w:0) + /// Storage: `BridgeRelayers::RelayerRewards` (r:2 w:2) + /// Proof: `BridgeRelayers::RelayerRewards` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) + fn receive_delivery_proof_for_two_messages_by_two_relayers() -> Weight { + // Proof Size summary in bytes: + // Measured: `343` + // Estimated: `6086` + // Minimum execution time: 44_120_000 picoseconds. + Weight::from_parts(44_844_000, 0) + .saturating_add(Weight::from_parts(0, 6086)) + .saturating_add(T::DbWeight::get().reads(6)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: `BridgePolkadotMessages::PalletOperatingMode` (r:1 w:0) + /// Proof: `BridgePolkadotMessages::PalletOperatingMode` (`max_values`: Some(1), `max_size`: Some(2), added: 497, mode: `MaxEncodedLen`) + /// Storage: `XcmpQueue::OutboundXcmpStatus` (r:1 w:1) + /// Proof: `XcmpQueue::OutboundXcmpStatus` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `BridgePolkadotParachains::ImportedParaHeads` (r:1 w:0) + /// Proof: `BridgePolkadotParachains::ImportedParaHeads` (`max_values`: Some(600), `max_size`: Some(196), added: 1681, mode: `MaxEncodedLen`) + /// Storage: `BridgePolkadotMessages::InboundLanes` (r:1 w:1) + /// Proof: `BridgePolkadotMessages::InboundLanes` (`max_values`: None, `max_size`: Some(49180), added: 51655, mode: `MaxEncodedLen`) + /// Storage: `ParachainInfo::ParachainId` (r:1 w:0) + /// Proof: `ParachainInfo::ParachainId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `XcmpQueue::DeliveryFeeFactor` (r:1 w:0) + /// Proof: `XcmpQueue::DeliveryFeeFactor` (`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::RelevantMessagingState` (r:1 w:0) + /// Proof: `ParachainSystem::RelevantMessagingState` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `XcmpQueue::OutboundXcmpMessages` (r:0 w:1) + /// Proof: `XcmpQueue::OutboundXcmpMessages` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// The range of component `i` is `[128, 2048]`. + fn receive_single_message_proof_with_dispatch(i: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `601` + // Estimated: `52645` + // Minimum execution time: 86_315_000 picoseconds. + Weight::from_parts(87_602_840, 0) + .saturating_add(Weight::from_parts(0, 52645)) + // Standard Error: 123 + .saturating_add(Weight::from_parts(7_611, 0).saturating_mul(i.into())) + .saturating_add(T::DbWeight::get().reads(10)) + .saturating_add(T::DbWeight::get().writes(4)) + } +} diff --git a/system-parachains/bridge-hubs/bridge-hub-kusama/src/weights/pallet_bridge_parachains.rs b/system-parachains/bridge-hubs/bridge-hub-kusama/src/weights/pallet_bridge_parachains.rs new file mode 100644 index 0000000000..6e1e10a097 --- /dev/null +++ b/system-parachains/bridge-hubs/bridge-hub-kusama/src/weights/pallet_bridge_parachains.rs @@ -0,0 +1,98 @@ + +//! Autogenerated weights for `pallet_bridge_parachains` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-12-05, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `svyatonik-benchmarking`, CPU: `Intel(R) Xeon(R) CPU @ 2.80GHz` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("bh-kusama-local-raw.json")`, DB CACHE: 1024 + +// Executed Command: +// ../polkadot-sdk/target/production/polkadot-parachain-benchmarks +// benchmark +// pallet +// --chain +// bh-kusama-local-raw.json +// --pallet +// pallet-bridge-parachains +// --extrinsic +// * +// --output=system-parachains/bridge-hubs/bridge-hub-kusama/src/weights +// --no-median-slopes +// --no-min-squares + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_bridge_parachains`. +pub struct WeightInfo(PhantomData); +impl pallet_bridge_parachains::WeightInfo for WeightInfo { + /// Storage: `BridgePolkadotParachains::PalletOperatingMode` (r:1 w:0) + /// Proof: `BridgePolkadotParachains::PalletOperatingMode` (`max_values`: Some(1), `max_size`: Some(1), added: 496, mode: `MaxEncodedLen`) + /// Storage: `BridgePolkadotGrandpa::ImportedHeaders` (r:1 w:0) + /// Proof: `BridgePolkadotGrandpa::ImportedHeaders` (`max_values`: Some(1200), `max_size`: Some(68), added: 1553, mode: `MaxEncodedLen`) + /// Storage: `BridgePolkadotParachains::ParasInfo` (r:1 w:1) + /// Proof: `BridgePolkadotParachains::ParasInfo` (`max_values`: Some(1), `max_size`: Some(60), added: 555, mode: `MaxEncodedLen`) + /// Storage: `BridgePolkadotParachains::ImportedParaHashes` (r:1 w:1) + /// Proof: `BridgePolkadotParachains::ImportedParaHashes` (`max_values`: Some(600), `max_size`: Some(64), added: 1549, mode: `MaxEncodedLen`) + /// Storage: `BridgePolkadotParachains::ImportedParaHeads` (r:0 w:1) + /// Proof: `BridgePolkadotParachains::ImportedParaHeads` (`max_values`: Some(600), `max_size`: Some(196), added: 1681, mode: `MaxEncodedLen`) + /// The range of component `p` is `[1, 2]`. + fn submit_parachain_heads_with_n_parachains(p: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `293` + // Estimated: `2543` + // Minimum execution time: 41_740_000 picoseconds. + Weight::from_parts(43_231_089, 0) + .saturating_add(Weight::from_parts(0, 2543)) + // Standard Error: 174_898 + .saturating_add(Weight::from_parts(50_055, 0).saturating_mul(p.into())) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: `BridgePolkadotParachains::PalletOperatingMode` (r:1 w:0) + /// Proof: `BridgePolkadotParachains::PalletOperatingMode` (`max_values`: Some(1), `max_size`: Some(1), added: 496, mode: `MaxEncodedLen`) + /// Storage: `BridgePolkadotGrandpa::ImportedHeaders` (r:1 w:0) + /// Proof: `BridgePolkadotGrandpa::ImportedHeaders` (`max_values`: Some(1200), `max_size`: Some(68), added: 1553, mode: `MaxEncodedLen`) + /// Storage: `BridgePolkadotParachains::ParasInfo` (r:1 w:1) + /// Proof: `BridgePolkadotParachains::ParasInfo` (`max_values`: Some(1), `max_size`: Some(60), added: 555, mode: `MaxEncodedLen`) + /// Storage: `BridgePolkadotParachains::ImportedParaHashes` (r:1 w:1) + /// Proof: `BridgePolkadotParachains::ImportedParaHashes` (`max_values`: Some(600), `max_size`: Some(64), added: 1549, mode: `MaxEncodedLen`) + /// Storage: `BridgePolkadotParachains::ImportedParaHeads` (r:0 w:1) + /// Proof: `BridgePolkadotParachains::ImportedParaHeads` (`max_values`: Some(600), `max_size`: Some(196), added: 1681, mode: `MaxEncodedLen`) + fn submit_parachain_heads_with_1kb_proof() -> Weight { + // Proof Size summary in bytes: + // Measured: `293` + // Estimated: `2543` + // Minimum execution time: 43_838_000 picoseconds. + Weight::from_parts(44_567_000, 0) + .saturating_add(Weight::from_parts(0, 2543)) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: `BridgePolkadotParachains::PalletOperatingMode` (r:1 w:0) + /// Proof: `BridgePolkadotParachains::PalletOperatingMode` (`max_values`: Some(1), `max_size`: Some(1), added: 496, mode: `MaxEncodedLen`) + /// Storage: `BridgePolkadotGrandpa::ImportedHeaders` (r:1 w:0) + /// Proof: `BridgePolkadotGrandpa::ImportedHeaders` (`max_values`: Some(1200), `max_size`: Some(68), added: 1553, mode: `MaxEncodedLen`) + /// Storage: `BridgePolkadotParachains::ParasInfo` (r:1 w:1) + /// Proof: `BridgePolkadotParachains::ParasInfo` (`max_values`: Some(1), `max_size`: Some(60), added: 555, mode: `MaxEncodedLen`) + /// Storage: `BridgePolkadotParachains::ImportedParaHashes` (r:1 w:1) + /// Proof: `BridgePolkadotParachains::ImportedParaHashes` (`max_values`: Some(600), `max_size`: Some(64), added: 1549, mode: `MaxEncodedLen`) + /// Storage: `BridgePolkadotParachains::ImportedParaHeads` (r:0 w:1) + /// Proof: `BridgePolkadotParachains::ImportedParaHeads` (`max_values`: Some(600), `max_size`: Some(196), added: 1681, mode: `MaxEncodedLen`) + fn submit_parachain_heads_with_16kb_proof() -> Weight { + // Proof Size summary in bytes: + // Measured: `293` + // Estimated: `2543` + // Minimum execution time: 83_675_000 picoseconds. + Weight::from_parts(84_895_000, 0) + .saturating_add(Weight::from_parts(0, 2543)) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(3)) + } +} diff --git a/system-parachains/bridge-hubs/bridge-hub-kusama/src/weights/pallet_bridge_relayers.rs b/system-parachains/bridge-hubs/bridge-hub-kusama/src/weights/pallet_bridge_relayers.rs new file mode 100644 index 0000000000..a3e48207a9 --- /dev/null +++ b/system-parachains/bridge-hubs/bridge-hub-kusama/src/weights/pallet_bridge_relayers.rs @@ -0,0 +1,107 @@ + +//! Autogenerated weights for `pallet_bridge_relayers` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-11-13, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `MusXroom`, CPU: `13th Gen Intel(R) Core(TM) i7-13650HX` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("bh-kusama-local-raw.json")`, DB CACHE: 1024 + +// Executed Command: +// ../polkadot-sdk/target/release/polkadot-parachain-benchmarks +// benchmark +// pallet +// --chain +// bh-kusama-local-raw.json +// --pallet +// pallet-bridge-relayers +// --extrinsic +// * +// --output=system-parachains/bridge-hubs/bridge-hub-kusama/src/weights +// --no-median-slopes +// --no-min-squares + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_bridge_relayers`. +pub struct WeightInfo(PhantomData); +impl pallet_bridge_relayers::WeightInfo for WeightInfo { + /// Storage: `BridgeRelayers::RelayerRewards` (r:1 w:1) + /// Proof: `BridgeRelayers::RelayerRewards` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + fn claim_rewards() -> Weight { + // Proof Size summary in bytes: + // Measured: `207` + // Estimated: `3593` + // Minimum execution time: 37_502_000 picoseconds. + Weight::from_parts(38_049_000, 0) + .saturating_add(Weight::from_parts(0, 3593)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: `BridgeRelayers::RegisteredRelayers` (r:1 w:1) + /// Proof: `BridgeRelayers::RegisteredRelayers` (`max_values`: None, `max_size`: Some(68), added: 2543, mode: `MaxEncodedLen`) + /// Storage: UNKNOWN KEY `0x1e8445dc201eeb8560e5579a5dd54655` (r:1 w:0) + /// Proof: UNKNOWN KEY `0x1e8445dc201eeb8560e5579a5dd54655` (r:1 w:0) + /// Storage: `Balances::Reserves` (r:1 w:1) + /// Proof: `Balances::Reserves` (`max_values`: None, `max_size`: Some(1249), added: 3724, mode: `MaxEncodedLen`) + fn register() -> Weight { + // Proof Size summary in bytes: + // Measured: `61` + // Estimated: `4714` + // Minimum execution time: 18_683_000 picoseconds. + Weight::from_parts(19_228_000, 0) + .saturating_add(Weight::from_parts(0, 4714)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: `BridgeRelayers::RegisteredRelayers` (r:1 w:1) + /// Proof: `BridgeRelayers::RegisteredRelayers` (`max_values`: None, `max_size`: Some(68), added: 2543, mode: `MaxEncodedLen`) + /// Storage: `Balances::Reserves` (r:1 w:1) + /// Proof: `Balances::Reserves` (`max_values`: None, `max_size`: Some(1249), added: 3724, mode: `MaxEncodedLen`) + fn deregister() -> Weight { + // Proof Size summary in bytes: + // Measured: `160` + // Estimated: `4714` + // Minimum execution time: 20_191_000 picoseconds. + Weight::from_parts(20_529_000, 0) + .saturating_add(Weight::from_parts(0, 4714)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: `BridgeRelayers::RegisteredRelayers` (r:1 w:1) + /// Proof: `BridgeRelayers::RegisteredRelayers` (`max_values`: None, `max_size`: Some(68), added: 2543, mode: `MaxEncodedLen`) + /// Storage: `Balances::Reserves` (r:1 w:1) + /// Proof: `Balances::Reserves` (`max_values`: None, `max_size`: Some(1249), added: 3724, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + fn slash_and_deregister() -> Weight { + // Proof Size summary in bytes: + // Measured: `263` + // Estimated: `4714` + // Minimum execution time: 22_360_000 picoseconds. + Weight::from_parts(22_935_000, 0) + .saturating_add(Weight::from_parts(0, 4714)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: `BridgeRelayers::RelayerRewards` (r:1 w:1) + /// Proof: `BridgeRelayers::RelayerRewards` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) + fn register_relayer_reward() -> Weight { + // Proof Size summary in bytes: + // Measured: `6` + // Estimated: `3538` + // Minimum execution time: 2_303_000 picoseconds. + Weight::from_parts(2_411_000, 0) + .saturating_add(Weight::from_parts(0, 3538)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } +} diff --git a/system-parachains/bridge-hubs/bridge-hub-kusama/src/weights/xcm/mod.rs b/system-parachains/bridge-hubs/bridge-hub-kusama/src/weights/xcm/mod.rs index ded5dc6702..dce4cc9c4a 100644 --- a/system-parachains/bridge-hubs/bridge-hub-kusama/src/weights/xcm/mod.rs +++ b/system-parachains/bridge-hubs/bridge-hub-kusama/src/weights/xcm/mod.rs @@ -18,6 +18,7 @@ mod pallet_xcm_benchmarks_fungible; mod pallet_xcm_benchmarks_generic; use crate::{xcm_config::MaxAssetsIntoHolding, Runtime}; +use codec::Encode; use frame_support::weights::Weight; use pallet_xcm_benchmarks_fungible::WeightInfo as XcmFungibleWeight; use pallet_xcm_benchmarks_generic::WeightInfo as XcmGeneric; @@ -211,8 +212,9 @@ impl XcmWeightInfo for BridgeHubKusamaXcmWeight { fn universal_origin(_: &Junction) -> Weight { Weight::MAX } - fn export_message(_: &NetworkId, _: &Junctions, _: &Xcm<()>) -> Weight { - Weight::MAX + fn export_message(_: &NetworkId, _: &Junctions, inner: &Xcm<()>) -> Weight { + let inner_encoded_len = inner.encode().len() as u32; + XcmGeneric::::export_message(inner_encoded_len) } fn lock_asset(_: &MultiAsset, _: &MultiLocation) -> Weight { Weight::MAX diff --git a/system-parachains/bridge-hubs/bridge-hub-kusama/src/weights/xcm/pallet_xcm_benchmarks_generic.rs b/system-parachains/bridge-hubs/bridge-hub-kusama/src/weights/xcm/pallet_xcm_benchmarks_generic.rs index b1e8107b30..c127fc7c0e 100644 --- a/system-parachains/bridge-hubs/bridge-hub-kusama/src/weights/xcm/pallet_xcm_benchmarks_generic.rs +++ b/system-parachains/bridge-hubs/bridge-hub-kusama/src/weights/xcm/pallet_xcm_benchmarks_generic.rs @@ -1,44 +1,26 @@ -// Copyright (C) Parity Technologies (UK) Ltd. -// This file is part of Cumulus. - -// Cumulus is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Cumulus is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Cumulus. If not, see . //! Autogenerated weights for `pallet_xcm_benchmarks::generic` //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-07-31, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2023-12-05, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-ynta1nyy-project-238-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! EXECUTION: , WASM-EXECUTION: Compiled, CHAIN: Some("bridge-hub-kusama-dev"), DB CACHE: 1024 +//! HOSTNAME: `svyatonik-benchmarking`, CPU: `Intel(R) Xeon(R) CPU @ 2.80GHz` +//! WASM-EXECUTION: Compiled, CHAIN: Some("bh-kusama-local-raw.json"), DB CACHE: 1024 // Executed Command: -// ./target/production/polkadot-parachain +// ../polkadot-sdk/target/production/polkadot-parachain-benchmarks // benchmark // pallet -// --template=./templates/xcm-bench-template.hbs -// --chain=bridge-hub-kusama-dev -// --wasm-execution=compiled -// --pallet=pallet_xcm_benchmarks::generic -// --no-storage-info +// --chain +// bh-kusama-local-raw.json +// --pallet +// pallet-xcm-benchmarks::generic +// --extrinsic +// report_holding,buy_execution,query_response,transact,refund_surplus,set_error_handler,set_appendix,clear_error,descend_origin,clear_origin,report_error,claim_asset,trap,subscribe_version,unsubscribe_version,burn_asset,expect_asset,expect_origin,expect_error,expect_transact_status,query_pallet,report_transact_status,clear_transact_status,set_topic,clear_topic,export_message,set_fees_mode,unpaid_execution,universal_origin +// --template=../polkadot-sdk/cumulus/templates/xcm-bench-template.hbs +// --output=system-parachains/bridge-hubs/bridge-hub-kusama/src/weights/xcm // --no-median-slopes // --no-min-squares -// --extrinsic=* -// --steps=50 -// --repeat=20 -// --json -// --header=./file_header.txt -// --output=./parachains/runtimes/bridge-hubs/bridge-hub-kusama/src/weights/xcm/pallet_xcm_benchmarks_generic.rs #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -52,31 +34,35 @@ pub struct WeightInfo(PhantomData); impl WeightInfo { // Storage: `ParachainInfo::ParachainId` (r:1 w:0) // Proof: `ParachainInfo::ParachainId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + // Storage: `ParachainSystem::UpwardDeliveryFeeFactor` (r:1 w:0) + // Proof: `ParachainSystem::UpwardDeliveryFeeFactor` (`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) // 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: `System::Account` (r:2 w:2) + // Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) // 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`) pub fn report_holding() -> Weight { // Proof Size summary in bytes: - // Measured: `70` - // Estimated: `3535` - // Minimum execution time: 33_141_000 picoseconds. - Weight::from_parts(34_380_000, 3535) - .saturating_add(T::DbWeight::get().reads(6)) - .saturating_add(T::DbWeight::get().writes(2)) + // Measured: `171` + // Estimated: `6196` + // Minimum execution time: 80_031_000 picoseconds. + Weight::from_parts(82_416_000, 6196) + .saturating_add(T::DbWeight::get().reads(9)) + .saturating_add(T::DbWeight::get().writes(4)) } pub fn buy_execution() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_803_000 picoseconds. - Weight::from_parts(2_904_000, 0) + // Minimum execution time: 2_768_000 picoseconds. + Weight::from_parts(2_842_000, 0) } // Storage: `PolkadotXcm::Queries` (r:1 w:0) // Proof: `PolkadotXcm::Queries` (`max_values`: None, `max_size`: None, mode: `Measured`) @@ -84,79 +70,83 @@ impl WeightInfo { // Proof Size summary in bytes: // Measured: `32` // Estimated: `3497` - // Minimum execution time: 10_308_000 picoseconds. - Weight::from_parts(10_753_000, 3497) + // Minimum execution time: 10_522_000 picoseconds. + Weight::from_parts(10_768_000, 3497) .saturating_add(T::DbWeight::get().reads(1)) } pub fn transact() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 11_499_000 picoseconds. - Weight::from_parts(11_786_000, 0) + // Minimum execution time: 11_838_000 picoseconds. + Weight::from_parts(12_192_000, 0) } pub fn refund_surplus() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 3_102_000 picoseconds. - Weight::from_parts(3_161_000, 0) + // Minimum execution time: 3_038_000 picoseconds. + Weight::from_parts(3_121_000, 0) } pub fn set_error_handler() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_678_000 picoseconds. - Weight::from_parts(2_795_000, 0) + // Minimum execution time: 2_599_000 picoseconds. + Weight::from_parts(2_695_000, 0) } pub fn set_appendix() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_685_000 picoseconds. - Weight::from_parts(2_758_000, 0) + // Minimum execution time: 2_663_000 picoseconds. + Weight::from_parts(2_719_000, 0) } pub fn clear_error() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_590_000 picoseconds. - Weight::from_parts(2_754_000, 0) + // Minimum execution time: 2_627_000 picoseconds. + Weight::from_parts(2_688_000, 0) } pub fn descend_origin() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 3_297_000 picoseconds. - Weight::from_parts(3_419_000, 0) + // Minimum execution time: 3_017_000 picoseconds. + Weight::from_parts(3_257_000, 0) } pub fn clear_origin() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_606_000 picoseconds. - Weight::from_parts(2_717_000, 0) + // Minimum execution time: 2_215_000 picoseconds. + Weight::from_parts(2_367_000, 0) } // Storage: `ParachainInfo::ParachainId` (r:1 w:0) // Proof: `ParachainInfo::ParachainId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + // Storage: `ParachainSystem::UpwardDeliveryFeeFactor` (r:1 w:0) + // Proof: `ParachainSystem::UpwardDeliveryFeeFactor` (`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) // 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: `System::Account` (r:2 w:2) + // Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) // 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`) pub fn report_error() -> Weight { // Proof Size summary in bytes: - // Measured: `70` - // Estimated: `3535` - // Minimum execution time: 26_242_000 picoseconds. - Weight::from_parts(29_220_000, 3535) - .saturating_add(T::DbWeight::get().reads(6)) - .saturating_add(T::DbWeight::get().writes(2)) + // Measured: `171` + // Estimated: `6196` + // Minimum execution time: 66_737_000 picoseconds. + Weight::from_parts(67_960_000, 6196) + .saturating_add(T::DbWeight::get().reads(9)) + .saturating_add(T::DbWeight::get().writes(4)) } // Storage: `PolkadotXcm::AssetTraps` (r:1 w:1) // Proof: `PolkadotXcm::AssetTraps` (`max_values`: None, `max_size`: None, mode: `Measured`) @@ -164,8 +154,8 @@ impl WeightInfo { // Proof Size summary in bytes: // Measured: `90` // Estimated: `3555` - // Minimum execution time: 14_106_000 picoseconds. - Weight::from_parts(14_535_000, 3555) + // Minimum execution time: 13_230_000 picoseconds. + Weight::from_parts(13_672_000, 3555) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } @@ -173,11 +163,13 @@ impl WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_634_000 picoseconds. - Weight::from_parts(2_763_000, 0) + // Minimum execution time: 2_255_000 picoseconds. + Weight::from_parts(2_361_000, 0) } // Storage: `PolkadotXcm::VersionNotifyTargets` (r:1 w:1) // Proof: `PolkadotXcm::VersionNotifyTargets` (`max_values`: None, `max_size`: None, mode: `Measured`) + // Storage: `ParachainSystem::UpwardDeliveryFeeFactor` (r:1 w:0) + // Proof: `ParachainSystem::UpwardDeliveryFeeFactor` (`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) @@ -192,9 +184,9 @@ impl WeightInfo { // Proof Size summary in bytes: // Measured: `38` // Estimated: `3503` - // Minimum execution time: 27_802_000 picoseconds. - Weight::from_parts(28_495_000, 3503) - .saturating_add(T::DbWeight::get().reads(6)) + // Minimum execution time: 27_396_000 picoseconds. + Weight::from_parts(28_037_000, 3503) + .saturating_add(T::DbWeight::get().reads(7)) .saturating_add(T::DbWeight::get().writes(3)) } // Storage: `PolkadotXcm::VersionNotifyTargets` (r:0 w:1) @@ -203,127 +195,152 @@ impl WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 4_683_000 picoseconds. - Weight::from_parts(4_907_000, 0) + // Minimum execution time: 4_662_000 picoseconds. + Weight::from_parts(5_035_000, 0) .saturating_add(T::DbWeight::get().writes(1)) } pub fn burn_asset() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 3_941_000 picoseconds. - Weight::from_parts(4_080_000, 0) + // Minimum execution time: 3_694_000 picoseconds. + Weight::from_parts(3_930_000, 0) } pub fn expect_asset() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_775_000 picoseconds. - Weight::from_parts(2_908_000, 0) + // Minimum execution time: 2_403_000 picoseconds. + Weight::from_parts(2_519_000, 0) } pub fn expect_origin() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_743_000 picoseconds. - Weight::from_parts(2_863_000, 0) + // Minimum execution time: 2_302_000 picoseconds. + Weight::from_parts(2_422_000, 0) } pub fn expect_error() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_641_000 picoseconds. - Weight::from_parts(2_771_000, 0) + // Minimum execution time: 2_250_000 picoseconds. + Weight::from_parts(2_293_000, 0) } pub fn expect_transact_status() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_838_000 picoseconds. - Weight::from_parts(2_950_000, 0) + // Minimum execution time: 2_504_000 picoseconds. + Weight::from_parts(2_632_000, 0) } // Storage: `ParachainInfo::ParachainId` (r:1 w:0) // Proof: `ParachainInfo::ParachainId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + // Storage: `ParachainSystem::UpwardDeliveryFeeFactor` (r:1 w:0) + // Proof: `ParachainSystem::UpwardDeliveryFeeFactor` (`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) // 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: `System::Account` (r:2 w:2) + // Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) // 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`) pub fn query_pallet() -> Weight { // Proof Size summary in bytes: - // Measured: `70` - // Estimated: `3535` - // Minimum execution time: 29_284_000 picoseconds. - Weight::from_parts(29_867_000, 3535) - .saturating_add(T::DbWeight::get().reads(6)) - .saturating_add(T::DbWeight::get().writes(2)) - } - pub fn expect_pallet() -> Weight { - // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 4_734_000 picoseconds. - Weight::from_parts(4_876_000, 0) + // Measured: `171` + // Estimated: `6196` + // Minimum execution time: 71_517_000 picoseconds. + Weight::from_parts(73_518_000, 6196) + .saturating_add(T::DbWeight::get().reads(9)) + .saturating_add(T::DbWeight::get().writes(4)) } // Storage: `ParachainInfo::ParachainId` (r:1 w:0) // Proof: `ParachainInfo::ParachainId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + // Storage: `ParachainSystem::UpwardDeliveryFeeFactor` (r:1 w:0) + // Proof: `ParachainSystem::UpwardDeliveryFeeFactor` (`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) // 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: `System::Account` (r:2 w:2) + // Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) // 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`) pub fn report_transact_status() -> Weight { // Proof Size summary in bytes: - // Measured: `70` - // Estimated: `3535` - // Minimum execution time: 26_154_000 picoseconds. - Weight::from_parts(26_851_000, 3535) - .saturating_add(T::DbWeight::get().reads(6)) - .saturating_add(T::DbWeight::get().writes(2)) + // Measured: `171` + // Estimated: `6196` + // Minimum execution time: 67_403_000 picoseconds. + Weight::from_parts(69_255_000, 6196) + .saturating_add(T::DbWeight::get().reads(9)) + .saturating_add(T::DbWeight::get().writes(4)) } pub fn clear_transact_status() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_678_000 picoseconds. - Weight::from_parts(2_748_000, 0) + // Minimum execution time: 2_293_000 picoseconds. + Weight::from_parts(2_403_000, 0) } pub fn set_topic() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_585_000 picoseconds. - Weight::from_parts(2_697_000, 0) + // Minimum execution time: 2_295_000 picoseconds. + Weight::from_parts(2_339_000, 0) } pub fn clear_topic() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_576_000 picoseconds. - Weight::from_parts(2_701_000, 0) + // Minimum execution time: 2_227_000 picoseconds. + Weight::from_parts(2_293_000, 0) + } + // Storage: `ParachainInfo::ParachainId` (r:1 w:0) + // Proof: `ParachainInfo::ParachainId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + // Storage: `BridgePolkadotMessages::PalletOperatingMode` (r:1 w:0) + // Proof: `BridgePolkadotMessages::PalletOperatingMode` (`max_values`: Some(1), `max_size`: Some(2), added: 497, mode: `MaxEncodedLen`) + // Storage: `BridgePolkadotMessages::OutboundLanes` (r:1 w:1) + // Proof: `BridgePolkadotMessages::OutboundLanes` (`max_values`: Some(1), `max_size`: Some(44), added: 539, mode: `MaxEncodedLen`) + // Storage: `BridgePolkadotMessages::OutboundLanesCongestedSignals` (r:1 w:0) + // Proof: `BridgePolkadotMessages::OutboundLanesCongestedSignals` (`max_values`: Some(1), `max_size`: Some(21), added: 516, mode: `MaxEncodedLen`) + // Storage: `BridgePolkadotMessages::OutboundMessages` (r:0 w:1) + // Proof: `BridgePolkadotMessages::OutboundMessages` (`max_values`: None, `max_size`: Some(2621472), added: 2623947, mode: `MaxEncodedLen`) + /// The range of component `x` is `[1, 1000]`. + pub fn export_message(x: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `61` + // Estimated: `1529` + // Minimum execution time: 30_606_000 picoseconds. + Weight::from_parts(33_048_888, 1529) + // Standard Error: 705 + .saturating_add(Weight::from_parts(409_990, 0).saturating_mul(x.into())) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(2)) } pub fn set_fees_mode() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_597_000 picoseconds. - Weight::from_parts(2_735_000, 0) + // Minimum execution time: 2_218_000 picoseconds. + Weight::from_parts(2_277_000, 0) } pub fn unpaid_execution() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_744_000 picoseconds. - Weight::from_parts(2_809_000, 0) + // Minimum execution time: 2_299_000 picoseconds. + Weight::from_parts(2_431_000, 0) } } + +impl WeightInfo { pub fn expect_pallet() -> Weight { Weight::from_parts(5_756_000, 0) } } diff --git a/system-parachains/bridge-hubs/bridge-hub-kusama/src/xcm_config.rs b/system-parachains/bridge-hubs/bridge-hub-kusama/src/xcm_config.rs index a448ffeadc..023ddc7e4a 100644 --- a/system-parachains/bridge-hubs/bridge-hub-kusama/src/xcm_config.rs +++ b/system-parachains/bridge-hubs/bridge-hub-kusama/src/xcm_config.rs @@ -15,6 +15,9 @@ // along with Cumulus. If not, see . use super::{ + bridge_to_polkadot_config::{ + DeliveryRewardInBalance, RequiredStakeForStakeAndSlash, ToBridgeHubPolkadotHaulBlobExporter, + }, AccountId, AllPalletsWithSystem, Balances, ParachainInfo, ParachainSystem, PolkadotXcm, PriceForParentDelivery, Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin, WeightToFee, XcmpQueue, @@ -48,10 +51,10 @@ use xcm_executor::{traits::WithOriginFilter, XcmExecutor}; parameter_types! { pub const KsmRelayLocation: MultiLocation = MultiLocation::parent(); - pub const RelayNetwork: Option = Some(NetworkId::Kusama); + pub const RelayNetwork: NetworkId = NetworkId::Kusama; pub RelayChainOrigin: RuntimeOrigin = cumulus_pallet_xcm::Origin::Relay.into(); pub UniversalLocation: InteriorMultiLocation = - X2(GlobalConsensus(RelayNetwork::get().unwrap()), Parachain(ParachainInfo::parachain_id().into())); + X2(GlobalConsensus(RelayNetwork::get()), Parachain(ParachainInfo::parachain_id().into())); pub const MaxInstructions: u32 = 100; pub const MaxAssetsIntoHolding: u32 = 64; pub const GovernanceLocation: MultiLocation = MultiLocation::parent(); @@ -139,6 +142,17 @@ impl Contains for SafeCallFilter { } } + // Allow to change dedicated storage items (called by governance-like) + match call { + RuntimeCall::System(frame_system::Call::set_storage { items }) + if items.iter().all(|(k, _)| { + k.eq(&DeliveryRewardInBalance::key()) || + k.eq(&RequiredStakeForStakeAndSlash::key()) + }) => + return true, + _ => (), + }; + matches!( call, RuntimeCall::PolkadotXcm( @@ -162,7 +176,23 @@ impl Contains for SafeCallFilter { pallet_collator_selection::Call::remove_invulnerable { .. }, ) | RuntimeCall::Session(pallet_session::Call::purge_keys { .. }) | RuntimeCall::XcmpQueue(..) | - RuntimeCall::DmpQueue(..) + RuntimeCall::DmpQueue(..) | + RuntimeCall::BridgePolkadotGrandpa(pallet_bridge_grandpa::Call::< + Runtime, + crate::bridge_to_polkadot_config::BridgeGrandpaPolkadotInstance, + >::initialize { .. }) | + RuntimeCall::BridgePolkadotGrandpa(pallet_bridge_grandpa::Call::< + Runtime, + crate::bridge_to_polkadot_config::BridgeGrandpaPolkadotInstance, + >::set_operating_mode { .. }) | + RuntimeCall::BridgePolkadotParachains(pallet_bridge_parachains::Call::< + Runtime, + crate::bridge_to_polkadot_config::BridgeParachainPolkadotInstance, + >::set_operating_mode { .. }) | + RuntimeCall::BridgePolkadotMessages(pallet_bridge_messages::Call::< + Runtime, + crate::bridge_to_polkadot_config::WithBridgeHubPolkadotMessagesInstance, + >::set_operating_mode { .. }) ) } } @@ -246,7 +276,7 @@ impl xcm_executor::Config for XcmConfig { type AssetLocker = (); type AssetExchanger = (); type FeeManager = XcmFeesToAccount; - type MessageExporter = (); + type MessageExporter = ToBridgeHubPolkadotHaulBlobExporter; type UniversalAliases = Nothing; type CallDispatcher = WithOriginFilter; type SafeCallFilter = SafeCallFilter; diff --git a/system-parachains/bridge-hubs/bridge-hub-kusama/tests/tests.rs b/system-parachains/bridge-hubs/bridge-hub-kusama/tests/tests.rs index 54ebc96a7a..54a4192851 100644 --- a/system-parachains/bridge-hubs/bridge-hub-kusama/tests/tests.rs +++ b/system-parachains/bridge-hubs/bridge-hub-kusama/tests/tests.rs @@ -14,21 +14,87 @@ // You should have received a copy of the GNU General Public License // along with Cumulus. If not, see . -pub use bridge_hub_kusama_runtime::{ - xcm_config::XcmConfig, AllPalletsWithoutSystem, Balances, ExistentialDeposit, ParachainSystem, - PolkadotXcm, Runtime, RuntimeEvent, SessionKeys, +use bp_polkadot_core::Signature; +use bridge_hub_kusama_runtime::{ + bridge_to_polkadot_config::{ + BridgeGrandpaPolkadotInstance, BridgeHubPolkadotChainId, BridgeParachainPolkadotInstance, + DeliveryRewardInBalance, PolkadotGlobalConsensusNetwork, RefundBridgeHubPolkadotMessages, + RequiredStakeForStakeAndSlash, WithBridgeHubPolkadotMessageBridge, + WithBridgeHubPolkadotMessagesInstance, XCM_LANE_FOR_ASSET_HUB_KUSAMA_TO_ASSET_HUB_POLKADOT, + }, + xcm_config::{KsmRelayLocation, RelayNetwork, XcmConfig}, + AllPalletsWithoutSystem, BridgeRejectObsoleteHeadersAndMessages, Executive, ExistentialDeposit, + ParachainSystem, PolkadotXcm, Runtime, RuntimeCall, RuntimeEvent, SessionKeys, SignedExtra, + UncheckedExtrinsic, }; -use codec::Decode; +use codec::{Decode, Encode}; use frame_support::parameter_types; -use parachains_common::{AccountId, AuraId}; -use system_parachains_constants::kusama::fee::WeightToFee; +use frame_system::pallet_prelude::HeaderFor; +use parachains_common::{kusama::fee::WeightToFee, AccountId, AuraId, Balance}; +use sp_keyring::AccountKeyring::Alice; +use sp_runtime::{ + generic::{Era, SignedPayload}, + AccountId32, +}; +use xcm::latest::prelude::*; const ALICE: [u8; 32] = [1u8; 32]; +// Para id of sibling chain used in tests. +pub const SIBLING_PARACHAIN_ID: u32 = 1000; + parameter_types! { pub CheckingAccount: AccountId = PolkadotXcm::check_account(); } +fn construct_extrinsic( + sender: sp_keyring::AccountKeyring, + call: RuntimeCall, +) -> UncheckedExtrinsic { + let extra: SignedExtra = ( + frame_system::CheckNonZeroSender::::new(), + frame_system::CheckSpecVersion::::new(), + frame_system::CheckTxVersion::::new(), + frame_system::CheckGenesis::::new(), + frame_system::CheckEra::::from(Era::immortal()), + frame_system::CheckNonce::::from(0), + frame_system::CheckWeight::::new(), + pallet_transaction_payment::ChargeTransactionPayment::::from(0), + BridgeRejectObsoleteHeadersAndMessages, + (RefundBridgeHubPolkadotMessages::default()), + ); + let payload = SignedPayload::new(call.clone(), extra.clone()).unwrap(); + let signature = payload.using_encoded(|e| sender.sign(e)); + UncheckedExtrinsic::new_signed( + call, + AccountId32::from(sender.public()).into(), + Signature::Sr25519(signature.clone()), + extra, + ) +} + +fn construct_and_apply_extrinsic( + relayer_at_target: sp_keyring::AccountKeyring, + batch: pallet_utility::Call, +) -> sp_runtime::DispatchOutcome { + let batch_call = RuntimeCall::Utility(batch); + let xt = construct_extrinsic(relayer_at_target, batch_call); + let r = Executive::apply_extrinsic(xt); + r.unwrap() +} + +fn executive_init_block(header: &HeaderFor) { + Executive::initialize_block(header) +} + +fn collator_session_keys() -> bridge_hub_test_utils::CollatorSessionKeys { + bridge_hub_test_utils::CollatorSessionKeys::new( + AccountId::from(Alice), + AccountId::from(Alice), + SessionKeys { aura: AuraId::from(Alice.public()) }, + ) +} + bridge_hub_test_utils::test_cases::include_teleports_for_native_asset_works!( Runtime, AllPalletsWithoutSystem, @@ -56,3 +122,191 @@ bridge_hub_test_utils::test_cases::include_teleports_for_native_asset_works!( }), 1002 ); + +#[test] +fn initialize_bridge_by_governance_works() { + bridge_hub_test_utils::test_cases::initialize_bridge_by_governance_works::< + Runtime, + BridgeGrandpaPolkadotInstance, + >( + collator_session_keys(), + bp_bridge_hub_kusama::BRIDGE_HUB_KUSAMA_PARACHAIN_ID, + Box::new(|call| RuntimeCall::BridgePolkadotGrandpa(call).encode()), + ) +} + +#[test] +fn change_delivery_reward_by_governance_works() { + bridge_hub_test_utils::test_cases::change_storage_constant_by_governance_works::< + Runtime, + DeliveryRewardInBalance, + Balance, + >( + collator_session_keys(), + bp_bridge_hub_kusama::BRIDGE_HUB_KUSAMA_PARACHAIN_ID, + Box::new(|call| RuntimeCall::System(call).encode()), + || (DeliveryRewardInBalance::key().to_vec(), DeliveryRewardInBalance::get()), + |old_value| old_value.checked_mul(2).unwrap(), + ) +} + +#[test] +fn change_required_stake_by_governance_works() { + bridge_hub_test_utils::test_cases::change_storage_constant_by_governance_works::< + Runtime, + RequiredStakeForStakeAndSlash, + Balance, + >( + collator_session_keys(), + bp_bridge_hub_kusama::BRIDGE_HUB_KUSAMA_PARACHAIN_ID, + Box::new(|call| RuntimeCall::System(call).encode()), + || (RequiredStakeForStakeAndSlash::key().to_vec(), RequiredStakeForStakeAndSlash::get()), + |old_value| old_value.checked_mul(2).unwrap(), + ) +} + +#[test] +fn handle_export_message_from_system_parachain_add_to_outbound_queue_works() { + bridge_hub_test_utils::test_cases::handle_export_message_from_system_parachain_to_outbound_queue_works::< + Runtime, + XcmConfig, + WithBridgeHubPolkadotMessagesInstance, + >( + collator_session_keys(), + bp_bridge_hub_kusama::BRIDGE_HUB_KUSAMA_PARACHAIN_ID, + SIBLING_PARACHAIN_ID, + Box::new(|runtime_event_encoded: Vec| { + match RuntimeEvent::decode(&mut &runtime_event_encoded[..]) { + Ok(RuntimeEvent::BridgePolkadotMessages(event)) => Some(event), + _ => None, + } + }), + || ExportMessage { network: Polkadot, destination: X1(Parachain(4321)), xcm: Xcm(vec![]) }, + XCM_LANE_FOR_ASSET_HUB_KUSAMA_TO_ASSET_HUB_POLKADOT, + Some((KsmRelayLocation::get(), ExistentialDeposit::get()).into()), + // value should be >= than value generated by `can_calculate_weight_for_paid_export_message_with_reserve_transfer` + Some((KsmRelayLocation::get(), bp_bridge_hub_kusama::BridgeHubKusamaBaseXcmFeeInKsms::get()).into()), + || (), + ) +} + +#[test] +fn message_dispatch_routing_works() { + bridge_hub_test_utils::test_cases::message_dispatch_routing_works::< + Runtime, + AllPalletsWithoutSystem, + XcmConfig, + ParachainSystem, + WithBridgeHubPolkadotMessagesInstance, + RelayNetwork, + PolkadotGlobalConsensusNetwork, + >( + collator_session_keys(), + bp_bridge_hub_kusama::BRIDGE_HUB_KUSAMA_PARACHAIN_ID, + SIBLING_PARACHAIN_ID, + Box::new(|runtime_event_encoded: Vec| { + match RuntimeEvent::decode(&mut &runtime_event_encoded[..]) { + Ok(RuntimeEvent::ParachainSystem(event)) => Some(event), + _ => None, + } + }), + Box::new(|runtime_event_encoded: Vec| { + match RuntimeEvent::decode(&mut &runtime_event_encoded[..]) { + Ok(RuntimeEvent::XcmpQueue(event)) => Some(event), + _ => None, + } + }), + XCM_LANE_FOR_ASSET_HUB_KUSAMA_TO_ASSET_HUB_POLKADOT, + || (), + ) +} + +#[test] +fn relayed_incoming_message_works() { + bridge_hub_test_utils::test_cases::relayed_incoming_message_works::< + Runtime, + AllPalletsWithoutSystem, + XcmConfig, + ParachainSystem, + BridgeGrandpaPolkadotInstance, + BridgeParachainPolkadotInstance, + WithBridgeHubPolkadotMessagesInstance, + WithBridgeHubPolkadotMessageBridge, + >( + collator_session_keys(), + bp_bridge_hub_kusama::BRIDGE_HUB_KUSAMA_PARACHAIN_ID, + bp_bridge_hub_polkadot::BRIDGE_HUB_POLKADOT_PARACHAIN_ID, + SIBLING_PARACHAIN_ID, + Kusama, + XCM_LANE_FOR_ASSET_HUB_KUSAMA_TO_ASSET_HUB_POLKADOT, + || (), + ) +} + +#[test] +pub fn complex_relay_extrinsic_works() { + bridge_hub_test_utils::test_cases::complex_relay_extrinsic_works::< + Runtime, + AllPalletsWithoutSystem, + XcmConfig, + ParachainSystem, + BridgeGrandpaPolkadotInstance, + BridgeParachainPolkadotInstance, + WithBridgeHubPolkadotMessagesInstance, + WithBridgeHubPolkadotMessageBridge, + >( + collator_session_keys(), + bp_bridge_hub_kusama::BRIDGE_HUB_KUSAMA_PARACHAIN_ID, + bp_bridge_hub_polkadot::BRIDGE_HUB_POLKADOT_PARACHAIN_ID, + SIBLING_PARACHAIN_ID, + BridgeHubPolkadotChainId::get(), + Kusama, + XCM_LANE_FOR_ASSET_HUB_KUSAMA_TO_ASSET_HUB_POLKADOT, + ExistentialDeposit::get(), + executive_init_block, + construct_and_apply_extrinsic, + || (), + ); +} + +#[test] +pub fn can_calculate_weight_for_paid_export_message_with_reserve_transfer() { + let estimated = bridge_hub_test_utils::test_cases::can_calculate_weight_for_paid_export_message_with_reserve_transfer::< + Runtime, + XcmConfig, + WeightToFee, + >(); + + // check if estimated value is sane + let max_expected = bp_bridge_hub_kusama::BridgeHubKusamaBaseXcmFeeInKsms::get(); + assert!( + estimated <= max_expected, + "calculated: {:?}, max_expected: {:?}, please adjust `bp_bridge_hub_kusama::BridgeHubKusamaBaseXcmFeeInKsms` value", + estimated, + max_expected + ); +} + +// TODO: replace me with direct usages of `bridge_hub_test_utils` after deps are bumped to (at +// least) 1.4 +// +// Following two tests have to be implemented properly after upgrade to 1.6. +// See https://github.com/paritytech/polkadot-sdk/pull/2139/ and https://github.com/paritytech/parity-bridges-common/pull/2728 +// for impl details +// +// Until that, anyone can run it manually by doing following: +// +// 1) cargo vendor ../vendored-dependencies +// 2) apply relevant changes from above PRs +// 3) change workspace Cargo.toml: +// [patch.crates-io] +// bp-polkadot-core = { path = "../vendored-dependencies/bp-polkadot-core" } +// bridge-hub-test-utils = { path = "../vendored-dependencies/bridge-hub-test-utils" } +// bridge-runtime-common = { path = "../vendored-dependencies/bridge-runtime-common" } +// 4) add actual tests code and do `cargo test -p bridge-hub-polkadot-runtime` + +#[test] +pub fn can_calculate_fee_for_complex_message_delivery_transaction() {} + +#[test] +pub fn can_calculate_fee_for_complex_message_confirmation_transaction() {} diff --git a/system-parachains/bridge-hubs/bridge-hub-polkadot/Cargo.toml b/system-parachains/bridge-hubs/bridge-hub-polkadot/Cargo.toml index 46aef5b926..110f33c676 100644 --- a/system-parachains/bridge-hubs/bridge-hub-polkadot/Cargo.toml +++ b/system-parachains/bridge-hubs/bridge-hub-polkadot/Cargo.toml @@ -19,6 +19,13 @@ scale-info = { version = "2.9.0", default-features = false, features = ["derive" serde = { version = "1.0.188", optional = true, features = ["derive"] } smallvec = "1.11.0" +# Local +bp-asset-hub-kusama = { path = "../../asset-hubs/asset-hub-kusama/primitives", default-features = false} +bp-asset-hub-polkadot = { path = "../../asset-hubs/asset-hub-polkadot/primitives", default-features = false} +bp-bridge-hub-kusama = { path = "../bridge-hub-kusama/primitives", default-features = false} +bp-bridge-hub-polkadot = { path = "../bridge-hub-polkadot/primitives", default-features = false} +polkadot-runtime-constants = { path = "../../../relay/polkadot/constants", default-features = false} + # Substrate frame-benchmarking = { default-features = false, optional = true, version = "25.0.0" } frame-executive = { default-features = false, version = "25.0.0" } @@ -52,7 +59,6 @@ sp-transaction-pool = { default-features = false, version = "23.0.0" } sp-version = { default-features = false, version = "26.0.0" } # Polkadot -polkadot-runtime-constants = { path = "../../../relay/polkadot/constants", default-features = false} pallet-xcm = { default-features = false, version = "4.0.0" } pallet-xcm-benchmarks = { default-features = false, optional = true , version = "4.0.0" } polkadot-core-primitives = { default-features = false, version = "4.0.0" } @@ -68,7 +74,7 @@ cumulus-pallet-dmp-queue = { default-features = false , version = "0.4.0" } cumulus-pallet-parachain-system = { default-features = false, features = ["parameterized-consensus-hook",] , version = "0.4.0" } cumulus-pallet-session-benchmarking = { default-features = false, version = "6.0.0" } cumulus-pallet-xcm = { default-features = false , version = "0.4.0" } -cumulus-pallet-xcmp-queue = { default-features = false , version = "0.4.0" } +cumulus-pallet-xcmp-queue = { default-features = false , features = ["bridging"] , version = "0.4.0" } cumulus-primitives-core = { default-features = false , version = "0.4.0" } cumulus-primitives-utility = { default-features = false , version = "0.4.0" } pallet-collator-selection = { default-features = false , version = "6.0.0" } @@ -76,12 +82,43 @@ parachain-info = { package = "staging-parachain-info", default-features = false parachains-common = { default-features = false , version = "4.0.0" } system-parachains-constants = { path = "../../constants", default-features = false } +# Bridges +bp-header-chain = { default-features = false , version = "0.4.0" } +bp-messages = { default-features = false , version = "0.4.0" } +bp-parachains = { default-features = false , version = "0.4.0" } +bp-polkadot-core = { default-features = false , version = "0.4.0" } +bp-relayers = { default-features = false , version = "0.4.0" } +bp-runtime = { default-features = false , version = "0.4.0" } +bp-kusama = { default-features = false , version = "0.2.0" } +bp-polkadot = { default-features = false , version = "0.2.0" } +bridge-runtime-common = { default-features = false , version = "0.4.0" } +pallet-bridge-grandpa = { default-features = false , version = "0.4.0" } +pallet-bridge-messages = { default-features = false , version = "0.4.0" } +pallet-bridge-parachains = { default-features = false , version = "0.4.0" } +pallet-bridge-relayers = { default-features = false , version = "0.4.0" } + [dev-dependencies] bridge-hub-test-utils = { version = "0.4.0" } +bridge-runtime-common = { version = "0.4.0", features = ["integrity-test"] } +sp-keyring = { version = "28.0.0" } +static_assertions = { version = "1.1.0" } [features] default = [ "std" ] std = [ + "bp-asset-hub-kusama/std", + "bp-asset-hub-polkadot/std", + "bp-bridge-hub-kusama/std", + "bp-bridge-hub-polkadot/std", + "bp-header-chain/std", + "bp-messages/std", + "bp-parachains/std", + "bp-polkadot-core/std", + "bp-relayers/std", + "bp-runtime/std", + "bp-kusama/std", + "bp-polkadot/std", + "bridge-runtime-common/std", "codec/std", "cumulus-pallet-aura-ext/std", "cumulus-pallet-dmp-queue/std", @@ -102,6 +139,10 @@ std = [ "pallet-aura/std", "pallet-authorship/std", "pallet-balances/std", + "pallet-bridge-grandpa/std", + "pallet-bridge-messages/std", + "pallet-bridge-parachains/std", + "pallet-bridge-relayers/std", "pallet-collator-selection/std", "pallet-multisig/std", "pallet-session/std", @@ -141,6 +182,7 @@ std = [ ] runtime-benchmarks = [ + "bridge-runtime-common/runtime-benchmarks", "cumulus-pallet-parachain-system/runtime-benchmarks", "cumulus-pallet-session-benchmarking/runtime-benchmarks", "cumulus-pallet-xcmp-queue/runtime-benchmarks", @@ -150,6 +192,10 @@ runtime-benchmarks = [ "frame-system-benchmarking/runtime-benchmarks", "frame-system/runtime-benchmarks", "pallet-balances/runtime-benchmarks", + "pallet-bridge-grandpa/runtime-benchmarks", + "pallet-bridge-messages/runtime-benchmarks", + "pallet-bridge-parachains/runtime-benchmarks", + "pallet-bridge-relayers/runtime-benchmarks", "pallet-collator-selection/runtime-benchmarks", "pallet-multisig/runtime-benchmarks", "pallet-timestamp/runtime-benchmarks", @@ -176,6 +222,10 @@ try-runtime = [ "pallet-aura/try-runtime", "pallet-authorship/try-runtime", "pallet-balances/try-runtime", + "pallet-bridge-grandpa/try-runtime", + "pallet-bridge-messages/try-runtime", + "pallet-bridge-parachains/try-runtime", + "pallet-bridge-relayers/try-runtime", "pallet-collator-selection/try-runtime", "pallet-multisig/try-runtime", "pallet-session/try-runtime", diff --git a/system-parachains/bridge-hubs/bridge-hub-polkadot/primitives/Cargo.toml b/system-parachains/bridge-hubs/bridge-hub-polkadot/primitives/Cargo.toml new file mode 100644 index 0000000000..614216ff78 --- /dev/null +++ b/system-parachains/bridge-hubs/bridge-hub-polkadot/primitives/Cargo.toml @@ -0,0 +1,39 @@ +[package] +name = "bp-bridge-hub-polkadot" +description = "Primitives of BridgeHubPolkadot parachain runtime." +repository.workspace = true +version.workspace = true +authors.workspace = true +edition.workspace = true +license.workspace = true + +[dependencies] + +# Local +kusama-runtime-constants = { path = "../../../../relay/kusama/constants", default-features = false} +polkadot-runtime-constants = { path = "../../../../relay/polkadot/constants", default-features = false} + +# Bridge Dependencies +bp-bridge-hub-cumulus = { default-features = false , version = "0.4.0" } +bp-runtime = { default-features = false , version = "0.4.0" } +bp-messages = { default-features = false , version = "0.4.0" } + +# Substrate Based Dependencies +frame-support = { default-features = false, version = "25.0.0" } +sp-api = { default-features = false, version = "23.0.0" } +sp-runtime = { default-features = false, version = "28.0.0" } +sp-std = { default-features = false , version = "12.0.0" } + +[features] +default = [ "std" ] +std = [ + "bp-bridge-hub-cumulus/std", + "bp-messages/std", + "bp-runtime/std", + "frame-support/std", + "kusama-runtime-constants/std", + "polkadot-runtime-constants/std", + "sp-api/std", + "sp-runtime/std", + "sp-std/std", +] diff --git a/system-parachains/bridge-hubs/bridge-hub-polkadot/primitives/src/lib.rs b/system-parachains/bridge-hubs/bridge-hub-polkadot/primitives/src/lib.rs new file mode 100644 index 0000000000..b02f6107d6 --- /dev/null +++ b/system-parachains/bridge-hubs/bridge-hub-polkadot/primitives/src/lib.rs @@ -0,0 +1,146 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Polkadot is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Polkadot. If not, see . + +//! Module with configuration which reflects BridgeHubPolkadot runtime setup +//! (AccountId, Headers, Hashes...) + +#![cfg_attr(not(feature = "std"), no_std)] + +pub use bp_bridge_hub_cumulus::*; +use bp_messages::*; +use bp_runtime::{ + decl_bridge_finality_runtime_apis, decl_bridge_messages_runtime_apis, Chain, Parachain, +}; +use frame_support::dispatch::DispatchClass; +use sp_runtime::{FixedPointNumber, FixedU128, RuntimeDebug, Saturating}; + +/// BridgeHubPolkadot parachain. +#[derive(RuntimeDebug)] +pub struct BridgeHubPolkadot; + +impl Chain for BridgeHubPolkadot { + type BlockNumber = BlockNumber; + type Hash = Hash; + type Hasher = Hasher; + type Header = Header; + + type AccountId = AccountId; + type Balance = Balance; + type Nonce = Nonce; + type Signature = Signature; + + fn max_extrinsic_size() -> u32 { + *BlockLength::get().max.get(DispatchClass::Normal) + } + + fn max_extrinsic_weight() -> Weight { + BlockWeights::get() + .get(DispatchClass::Normal) + .max_extrinsic + .unwrap_or(Weight::MAX) + } +} + +impl Parachain for BridgeHubPolkadot { + const PARACHAIN_ID: u32 = BRIDGE_HUB_POLKADOT_PARACHAIN_ID; +} + +/// Identifier of BridgeHubPolkadot in the Polkadot relay chain. +pub const BRIDGE_HUB_POLKADOT_PARACHAIN_ID: u32 = 1002; + +/// Name of the With-BridgeHubPolkadot messages pallet instance that is deployed at bridged chains. +pub const WITH_BRIDGE_HUB_POLKADOT_MESSAGES_PALLET_NAME: &str = "BridgePolkadotMessages"; + +/// Name of the With-BridgeHubPolkadot bridge-relayers pallet instance that is deployed at bridged +/// chains. +pub const WITH_BRIDGE_HUB_POLKADOT_RELAYERS_PALLET_NAME: &str = "BridgeRelayers"; + +/// Pallet index of `BridgeKusamaMessages: pallet_bridge_messages::`. +pub const WITH_BRIDGE_POLKADOT_TO_KUSAMA_MESSAGES_PALLET_INDEX: u8 = 53; + +decl_bridge_finality_runtime_apis!(bridge_hub_polkadot); +decl_bridge_messages_runtime_apis!(bridge_hub_polkadot); + +frame_support::parameter_types! { + /// The XCM fee that is paid for executing XCM program (with `ExportMessage` instruction) at the Polkadot + /// BridgeHub. + /// (initially was calculated by test `BridgeHubPolkadot::can_calculate_weight_for_paid_export_message_with_reserve_transfer` + `33%`) + pub const BridgeHubPolkadotBaseXcmFeeInDots: Balance = 4_858_960_000; + + /// Transaction fee that is paid at the Polkadot BridgeHub for delivering single inbound message. + /// (initially was calculated by test `BridgeHubPolkadot::can_calculate_fee_for_complex_message_delivery_transaction` + `33%`) + pub const BridgeHubPolkadotBaseDeliveryFeeInDots: Balance = 16_954_899_613; + + /// Transaction fee that is paid at the Polkadot BridgeHub for delivering single outbound message confirmation. + /// (initially was calculated by test `BridgeHubPolkadot::can_calculate_fee_for_complex_message_confirmation_transaction` + `33%`) + pub const BridgeHubPolkadotBaseConfirmationFeeInDots: Balance = 16_183_099_613; +} + +/// Compute the total estimated fee that needs to be paid in DOTs by the sender when sending +/// message from Polkadot Bridge Hub to Kusama Bridge Hub. +pub fn estimate_polkadot_to_kusama_message_fee( + bridge_hub_kusama_base_delivery_fee_in_uksms: Balance, +) -> Balance { + // Sender must pay: + // + // 1) an approximate cost of XCM execution (`ExportMessage` and surroundings) at Polkadot bridge + // Hub; + // + // 2) the approximate cost of Polkadot -> Kusama message delivery transaction on Kusama Bridge + // Hub, converted into KSMs using 1:5 conversion rate; + // + // 3) the approximate cost of Polkadot -> Kusama message confirmation transaction on Polkadot + // Bridge Hub. + BridgeHubPolkadotBaseXcmFeeInDots::get() + .saturating_add(convert_from_uksm_to_udot(bridge_hub_kusama_base_delivery_fee_in_uksms)) + .saturating_add(BridgeHubPolkadotBaseConfirmationFeeInDots::get()) +} + +/// Convert from uKSMs to uDOTs. +fn convert_from_uksm_to_udot(price_in_uksm: Balance) -> Balance { + // assuming exchange rate is 5 DOTs for 1 KSM + let dot_to_ksm_economic_rate = FixedU128::from_rational(5, 1); + // tokens have different nominals and we need to take that into account + let nominal_ratio = FixedU128::from_rational( + polkadot_runtime_constants::currency::UNITS, + kusama_runtime_constants::currency::UNITS, + ); + + dot_to_ksm_economic_rate + .saturating_mul(nominal_ratio) + .saturating_mul(FixedU128::saturating_from_integer(price_in_uksm)) + .into_inner() / + FixedU128::DIV +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn convert_from_uksm_to_udot_works() { + let price_in_uksm = 77 * kusama_runtime_constants::currency::UNITS; + let same_price_in_udot = convert_from_uksm_to_udot(price_in_uksm); + + let price_in_ksm = + FixedU128::from_rational(price_in_uksm, kusama_runtime_constants::currency::UNITS); + let price_in_dot = FixedU128::from_rational( + same_price_in_udot, + polkadot_runtime_constants::currency::UNITS, + ); + assert_eq!(price_in_dot / FixedU128::saturating_from_integer(5), price_in_ksm); + } +} diff --git a/system-parachains/bridge-hubs/bridge-hub-polkadot/src/bridge_to_kusama_config.rs b/system-parachains/bridge-hubs/bridge-hub-polkadot/src/bridge_to_kusama_config.rs new file mode 100644 index 0000000000..4911e3444f --- /dev/null +++ b/system-parachains/bridge-hubs/bridge-hub-polkadot/src/bridge_to_kusama_config.rs @@ -0,0 +1,400 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Cumulus. + +// Cumulus is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Cumulus is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Cumulus. If not, see . + +//! Bridge definitions used for bridging with Kusama Bridge Hub. + +use crate::{ + weights, + xcm_config::{UniversalLocation, XcmRouter}, + AccountId, Balance, Balances, BlockNumber, BridgeKusamaMessages, Runtime, RuntimeEvent, + RuntimeOrigin, +}; +use bp_messages::LaneId; +use bp_parachains::SingleParaStoredHeaderDataBuilder; +use bridge_runtime_common::{ + messages, + messages::{ + source::{FromBridgedChainMessagesDeliveryProof, TargetHeaderChainAdapter}, + target::{FromBridgedChainMessagesProof, SourceHeaderChainAdapter}, + MessageBridge, ThisChainWithMessages, UnderlyingChainProvider, + }, + messages_xcm_extension::{ + SenderAndLane, XcmAsPlainPayload, XcmBlobHauler, XcmBlobHaulerAdapter, + XcmBlobMessageDispatch, + }, + refund_relayer_extension::{ + ActualFeeRefund, RefundBridgedParachainMessages, RefundSignedExtensionAdapter, + RefundableMessagesLane, RefundableParachain, + }, +}; +use cumulus_primitives_core::ParentThen; +use frame_support::{parameter_types, traits::PalletInfoAccess}; +use polkadot_runtime_constants as constants; +use sp_runtime::{traits::ConstU32, RuntimeDebug}; +use xcm::{ + latest::prelude::*, + prelude::{InteriorMultiLocation, NetworkId}, +}; +use xcm_builder::{BridgeBlobDispatcher, HaulBlobExporter}; + +/// Lane identifier, used to connect Polkadot Asset Hub and Kusama Asset Hub. +pub const XCM_LANE_FOR_ASSET_HUB_POLKADOT_TO_ASSET_HUB_KUSAMA: LaneId = LaneId([0, 0, 0, 1]); + +// Parameters that may be changed by the governance. +parameter_types! { + /// Reward that is paid (by the Polkadot Asset Hub) to relayers for delivering a single + /// Polkadot -> Kusama bridge message. + /// + /// This payment is tracked by the `pallet_bridge_relayers` pallet at the Polkadot + /// Bridge Hub. + pub storage DeliveryRewardInBalance: Balance = constants::currency::UNITS / 2_000; + + /// Registered relayer stake. + /// + /// Any relayer may reserve this amount on his account and get a priority boost for his + /// message delivery transactions. In exchange, he risks losing his stake if he would + /// submit an invalid transaction. The set of such (registered) relayers is tracked + /// by the `pallet_bridge_relayers` pallet at the Polkadot Bridge Hub. + pub storage RequiredStakeForStakeAndSlash: Balance = 500 * constants::currency::UNITS; +} + +// Parameters, used by both XCM and bridge code. +parameter_types! { + /// Kusama Network identifier. + pub KusamaGlobalConsensusNetwork: NetworkId = NetworkId::Kusama; + /// Interior location (relative to this runtime) of the with-Kusama messages pallet. + pub BridgePolkadotToKusamaMessagesPalletInstance: InteriorMultiLocation = X1( + PalletInstance(::index() as u8), + ); + + /// Identifier of the sibling Polkadot Asset Hub parachain. + pub AssetHubPolkadotParaId: cumulus_primitives_core::ParaId = polkadot_runtime_constants::system_parachain::ASSET_HUB_ID.into(); + /// A route (XCM location and bridge lane) that the Polkadot Asset Hub -> Kusama Asset Hub + /// message is following. + pub FromAssetHubPolkadotToAssetHubKusamaRoute: SenderAndLane = SenderAndLane::new( + ParentThen(X1(Parachain(AssetHubPolkadotParaId::get().into()))).into(), + XCM_LANE_FOR_ASSET_HUB_POLKADOT_TO_ASSET_HUB_KUSAMA, + ); +} + +// Parameters, used by bridge transport code. +parameter_types! { + /// Number of Kusama headers to keep in the runtime storage. + /// + /// Note that we are keeping only required header information, not the whole header itself. Roughly, it + /// is the 2 hours of real time (assuming that every header is submitted). + pub const RelayChainHeadersToKeep: u32 = 1_200; + /// Number of Kusama Bridge Hub headers to keep in the runtime storage. + /// + /// Note that we are keeping only required header information, not the whole header itself. Roughly, it + /// is the 2 hours of real time (assuming that every header is submitted). + pub const ParachainHeadsToKeep: u32 = 600; + /// Maximal size of Kusama Bridge Hub header **part** that we are storing in the runtime storage. + pub const MaxParaHeadDataSize: u32 = bp_kusama::MAX_NESTED_PARACHAIN_HEAD_DATA_SIZE; + + /// Bridge specific chain (network) identifier of the Kusama Bridge Hub. + pub const BridgeHubKusamaChainId: bp_runtime::ChainId = bp_runtime::BRIDGE_HUB_KUSAMA_CHAIN_ID; + /// Name of the `paras` pallet at Kusama that tracks all parachain heads. + pub const ParachainPalletNameAtKusama: &'static str = bp_kusama::PARAS_PALLET_NAME; + + /// Maximal number of entries in the unrewarded relayers vector at the Polkadot Bridge Hub. It matches the + /// maximal number of unrewarded relayers that the single confirmation transaction at Kusama Bridge + /// Hub may process. + pub const MaxUnrewardedRelayerEntriesAtInboundLane: bp_messages::MessageNonce = + bp_bridge_hub_kusama::MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX; + /// Maximal number of unconfirmed messages at the Polkadot Bridge Hub. It matches the maximal number of + /// uncinfirmed messages that the single confirmation transaction at Kusama Bridge Hub may process. + pub const MaxUnconfirmedMessagesAtInboundLane: bp_messages::MessageNonce = + bp_bridge_hub_kusama::MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX; + + /// Lane identifier, used to connect Polkadot Asset Hub and Kusama Asset Hub. + pub const AssetHubPolkadotToAssetHubKusamaMessagesLane: bp_messages::LaneId + = XCM_LANE_FOR_ASSET_HUB_POLKADOT_TO_ASSET_HUB_KUSAMA; + /// All active lanes that the current bridge supports. + pub ActiveOutboundLanesToBridgeHubKusama: &'static [bp_messages::LaneId] + = &[XCM_LANE_FOR_ASSET_HUB_POLKADOT_TO_ASSET_HUB_KUSAMA]; + + /// Reserve identifier, used by the `pallet_bridge_relayers` to hold funds of registered relayer. + pub const RelayerStakeReserveId: [u8; 8] = *b"brdgrlrs"; + /// Minimal period of relayer registration. Roughly, it is the 1 hour of real time. + pub const RelayerStakeLease: u32 = 300; + /// Priority boost that the registered relayer receives for every additional message in the message + /// delivery transaction. + /// + /// It is determined semi-automatically - see `FEE_BOOST_PER_MESSAGE` constant to get the + /// meaning of this value + pub PriorityBoostPerMessage: u64 = 1_820_444_444_444; +} + +/// Add GRANDPA bridge pallet to track Kusama relay chain. +pub type BridgeGrandpaKusamaInstance = pallet_bridge_grandpa::Instance1; +impl pallet_bridge_grandpa::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type BridgedChain = bp_kusama::Kusama; + type MaxFreeMandatoryHeadersPerBlock = ConstU32<4>; + type HeadersToKeep = RelayChainHeadersToKeep; + type WeightInfo = weights::pallet_bridge_grandpa::WeightInfo; +} + +/// Add parachain bridge pallet to track Kusama BridgeHub parachain. +pub type BridgeParachainKusamaInstance = pallet_bridge_parachains::Instance1; +impl pallet_bridge_parachains::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type WeightInfo = weights::pallet_bridge_parachains::WeightInfo; + type BridgesGrandpaPalletInstance = BridgeGrandpaKusamaInstance; + type ParasPalletName = ParachainPalletNameAtKusama; + type ParaStoredHeaderDataBuilder = + SingleParaStoredHeaderDataBuilder; + type HeadsToKeep = ParachainHeadsToKeep; + type MaxParaHeadDataSize = MaxParaHeadDataSize; +} + +/// Allows collect and claim rewards for relayers. +impl pallet_bridge_relayers::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type Reward = Balance; + type PaymentProcedure = + bp_relayers::PayRewardFromAccount, AccountId>; + type StakeAndSlash = pallet_bridge_relayers::StakeAndSlashNamed< + AccountId, + BlockNumber, + Balances, + RelayerStakeReserveId, + RequiredStakeForStakeAndSlash, + RelayerStakeLease, + >; + type WeightInfo = weights::pallet_bridge_relayers::WeightInfo; +} + +/// Add XCM messages support for exchanging messages with BridgeHubKusama. +pub type WithBridgeHubKusamaMessagesInstance = pallet_bridge_messages::Instance1; +impl pallet_bridge_messages::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type WeightInfo = weights::pallet_bridge_messages::WeightInfo; + type BridgedChainId = BridgeHubKusamaChainId; + type ActiveOutboundLanes = ActiveOutboundLanesToBridgeHubKusama; + type MaxUnrewardedRelayerEntriesAtInboundLane = MaxUnrewardedRelayerEntriesAtInboundLane; + type MaxUnconfirmedMessagesAtInboundLane = MaxUnconfirmedMessagesAtInboundLane; + + type MaximalOutboundPayloadSize = ToBridgeHubKusamaMaximalOutboundPayloadSize; + type OutboundPayload = XcmAsPlainPayload; + + type InboundPayload = XcmAsPlainPayload; + type InboundRelayer = AccountId; + type DeliveryPayments = (); + + type TargetHeaderChain = TargetHeaderChainAdapter; + type LaneMessageVerifier = ToBridgeHubKusamaMessageVerifier; + type DeliveryConfirmationPayments = pallet_bridge_relayers::DeliveryConfirmationPaymentsAdapter< + Runtime, + WithBridgeHubKusamaMessagesInstance, + DeliveryRewardInBalance, + >; + + type SourceHeaderChain = SourceHeaderChainAdapter; + type MessageDispatch = XcmBlobMessageDispatch< + FromKusamaMessageBlobDispatcher, + Self::WeightInfo, + cumulus_pallet_xcmp_queue::bridging::OutXcmpChannelStatusProvider< + AssetHubPolkadotParaId, + Runtime, + >, + >; + type OnMessagesDelivered = OnMessagesDeliveredFromKusama; +} + +/// Proof of messages, coming from Kusama. +pub type FromKusamaBridgeHubMessagesProof = + FromBridgedChainMessagesProof; +/// Messages delivery proof for Polkadot Bridge Hub -> Kusama Bridge Hub messages. +pub type ToKusamaBridgeHubMessagesDeliveryProof = + FromBridgedChainMessagesDeliveryProof; + +/// Dispatches received XCM messages from Kusama BridgeHub. +type FromKusamaMessageBlobDispatcher = BridgeBlobDispatcher< + XcmRouter, + UniversalLocation, + BridgePolkadotToKusamaMessagesPalletInstance, +>; + +/// Export XCM messages to be relayed to the other side +pub type ToBridgeHubKusamaHaulBlobExporter = HaulBlobExporter< + XcmBlobHaulerAdapter, + KusamaGlobalConsensusNetwork, + (), +>; +pub struct ToBridgeHubKusamaXcmBlobHauler; +impl XcmBlobHauler for ToBridgeHubKusamaXcmBlobHauler { + type Runtime = Runtime; + type MessagesInstance = WithBridgeHubKusamaMessagesInstance; + type SenderAndLane = FromAssetHubPolkadotToAssetHubKusamaRoute; + + type ToSourceChainSender = XcmRouter; + type CongestedMessage = bp_asset_hub_polkadot::CongestedMessage; + type UncongestedMessage = bp_asset_hub_polkadot::UncongestedMessage; +} + +/// On messages delivered callback. +type OnMessagesDeliveredFromKusama = XcmBlobHaulerAdapter; + +/// Messaging Bridge configuration for BridgeHubPolkadot -> BridgeHubKusama +pub struct WithBridgeHubKusamaMessageBridge; +impl MessageBridge for WithBridgeHubKusamaMessageBridge { + const BRIDGED_MESSAGES_PALLET_NAME: &'static str = + bp_bridge_hub_polkadot::WITH_BRIDGE_HUB_POLKADOT_MESSAGES_PALLET_NAME; + type ThisChain = BridgeHubPolkadot; + type BridgedChain = BridgeHubKusama; + type BridgedHeaderChain = pallet_bridge_parachains::ParachainHeaders< + Runtime, + BridgeParachainKusamaInstance, + bp_bridge_hub_kusama::BridgeHubKusama, + >; +} + +/// Message verifier for BridgeHubKusama messages sent from BridgeHubPolkadot +pub type ToBridgeHubKusamaMessageVerifier = + messages::source::FromThisChainMessageVerifier; + +/// Maximal outbound payload size of BridgeHubPolkadot -> BridgeHubKusama messages. +pub type ToBridgeHubKusamaMaximalOutboundPayloadSize = + messages::source::FromThisChainMaximalOutboundPayloadSize; + +/// BridgeHubKusama chain from message lane point of view. +#[derive(RuntimeDebug, Clone, Copy)] +pub struct BridgeHubKusama; + +impl UnderlyingChainProvider for BridgeHubKusama { + type Chain = bp_bridge_hub_kusama::BridgeHubKusama; +} + +impl messages::BridgedChainWithMessages for BridgeHubKusama {} + +/// BridgeHubPolkadot chain from message lane point of view. +#[derive(RuntimeDebug, Clone, Copy)] +pub struct BridgeHubPolkadot; + +impl UnderlyingChainProvider for BridgeHubPolkadot { + type Chain = bp_bridge_hub_polkadot::BridgeHubPolkadot; +} + +impl ThisChainWithMessages for BridgeHubPolkadot { + type RuntimeOrigin = RuntimeOrigin; +} + +/// Signed extension that refunds relayers that are delivering messages from the Kusama parachain. +pub type RefundBridgeHubKusamaMessages = RefundSignedExtensionAdapter< + RefundBridgedParachainMessages< + Runtime, + RefundableParachain, + RefundableMessagesLane< + WithBridgeHubKusamaMessagesInstance, + AssetHubPolkadotToAssetHubKusamaMessagesLane, + >, + ActualFeeRefund, + PriorityBoostPerMessage, + StrRefundBridgeHubKusamaMessages, + >, +>; +bp_runtime::generate_static_str_provider!(RefundBridgeHubKusamaMessages); + +#[cfg(test)] +mod tests { + use super::*; + use bridge_runtime_common::{ + assert_complete_bridge_types, + integrity::{ + assert_complete_bridge_constants, check_message_lane_weights, + AssertBridgeMessagesPalletConstants, AssertBridgePalletNames, AssertChainConstants, + AssertCompleteBridgeConstants, + }, + }; + + /// Every additional message in the message delivery transaction boosts its priority. + /// So the priority of transaction with `N+1` messages is larger than priority of + /// transaction with `N` messages by the `PriorityBoostPerMessage`. + /// + /// Economically, it is an equivalent of adding tip to the transaction with `N` messages. + /// The `FEE_BOOST_PER_MESSAGE` constant is the value of this tip. + /// + /// We want this tip to be large enough (delivery transactions with more messages = less + /// operational costs and a faster bridge), so this value should be significant. + const FEE_BOOST_PER_MESSAGE: Balance = 2 * constants::currency::UNITS; + + #[test] + fn ensure_bridge_hub_polkadot_message_lane_weights_are_correct() { + check_message_lane_weights::< + bp_bridge_hub_polkadot::BridgeHubPolkadot, + Runtime, + WithBridgeHubKusamaMessagesInstance, + >( + bp_bridge_hub_kusama::EXTRA_STORAGE_PROOF_SIZE, + bp_bridge_hub_polkadot::MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX, + bp_bridge_hub_polkadot::MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX, + true, + ); + } + + #[test] + fn ensure_bridge_integrity() { + assert_complete_bridge_types!( + runtime: Runtime, + with_bridged_chain_grandpa_instance: BridgeGrandpaKusamaInstance, + with_bridged_chain_messages_instance: WithBridgeHubKusamaMessagesInstance, + bridge: WithBridgeHubKusamaMessageBridge, + this_chain: bp_polkadot::Polkadot, + bridged_chain: bp_kusama::Kusama, + ); + + assert_complete_bridge_constants::< + Runtime, + BridgeGrandpaKusamaInstance, + WithBridgeHubKusamaMessagesInstance, + WithBridgeHubKusamaMessageBridge, + >(AssertCompleteBridgeConstants { + this_chain_constants: AssertChainConstants { + block_length: bp_bridge_hub_polkadot::BlockLength::get(), + block_weights: bp_bridge_hub_polkadot::BlockWeights::get(), + }, + messages_pallet_constants: AssertBridgeMessagesPalletConstants { + max_unrewarded_relayers_in_bridged_confirmation_tx: + bp_bridge_hub_kusama::MAX_UNREWARDED_RELAYERS_IN_CONFIRMATION_TX, + max_unconfirmed_messages_in_bridged_confirmation_tx: + bp_bridge_hub_kusama::MAX_UNCONFIRMED_MESSAGES_IN_CONFIRMATION_TX, + bridged_chain_id: bp_runtime::BRIDGE_HUB_KUSAMA_CHAIN_ID, + }, + pallet_names: AssertBridgePalletNames { + with_this_chain_messages_pallet_name: + bp_bridge_hub_polkadot::WITH_BRIDGE_HUB_POLKADOT_MESSAGES_PALLET_NAME, + with_bridged_chain_grandpa_pallet_name: bp_kusama::WITH_KUSAMA_GRANDPA_PALLET_NAME, + with_bridged_chain_messages_pallet_name: + bp_bridge_hub_kusama::WITH_BRIDGE_HUB_KUSAMA_MESSAGES_PALLET_NAME, + }, + }); + + bridge_runtime_common::priority_calculator::ensure_priority_boost_is_sane::< + Runtime, + WithBridgeHubKusamaMessagesInstance, + PriorityBoostPerMessage, + >(FEE_BOOST_PER_MESSAGE); + + assert_eq!( + BridgePolkadotToKusamaMessagesPalletInstance::get(), + X1(PalletInstance( + bp_bridge_hub_polkadot::WITH_BRIDGE_POLKADOT_TO_KUSAMA_MESSAGES_PALLET_INDEX + )) + ); + } +} diff --git a/system-parachains/bridge-hubs/bridge-hub-polkadot/src/lib.rs b/system-parachains/bridge-hubs/bridge-hub-polkadot/src/lib.rs index c18dcc3d2f..126a5dd407 100644 --- a/system-parachains/bridge-hubs/bridge-hub-polkadot/src/lib.rs +++ b/system-parachains/bridge-hubs/bridge-hub-polkadot/src/lib.rs @@ -22,6 +22,7 @@ #[cfg(feature = "std")] include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs")); +pub mod bridge_to_kusama_config; mod weights; pub mod xcm_config; @@ -101,8 +102,20 @@ pub type SignedExtra = ( frame_system::CheckNonce, frame_system::CheckWeight, pallet_transaction_payment::ChargeTransactionPayment, + BridgeRejectObsoleteHeadersAndMessages, + bridge_to_kusama_config::RefundBridgeHubKusamaMessages, ); +bridge_runtime_common::generate_bridge_reject_obsolete_headers_and_messages! { + RuntimeCall, AccountId, + // Grandpa + BridgeKusamaGrandpa, + // Parachains + BridgeKusamaParachains, + // Messages + BridgeKusamaMessages +} + /// Unchecked extrinsic type as expected by this runtime. pub type UncheckedExtrinsic = generic::UncheckedExtrinsic; @@ -454,6 +467,14 @@ construct_runtime!( // Handy utilities. Utility: pallet_utility::{Pallet, Call, Event} = 40, Multisig: pallet_multisig::{Pallet, Call, Storage, Event} = 41, + + // Pallets that may be used by all bridges. + BridgeRelayers: pallet_bridge_relayers::{Pallet, Call, Storage, Event} = 50, + + // Kusama bridge pallets. + BridgeKusamaGrandpa: pallet_bridge_grandpa::::{Pallet, Call, Storage, Event, Config} = 51, + BridgeKusamaParachains: pallet_bridge_parachains::::{Pallet, Call, Storage, Event} = 52, + BridgeKusamaMessages: pallet_bridge_messages::::{Pallet, Call, Storage, Event, Config} = 53, } ); @@ -477,6 +498,12 @@ mod benches { // NOTE: Make sure you point to the individual modules below. [pallet_xcm_benchmarks::fungible, XcmBalances] [pallet_xcm_benchmarks::generic, XcmGeneric] + // Shared bridge pallets + [pallet_bridge_relayers, BridgeRelayersBench::] + // Polkadot bridge pallets. + [pallet_bridge_grandpa, KusamaFinality] + [pallet_bridge_parachains, KusamaParachains] + [pallet_bridge_messages, KusamaMessages] ); } @@ -634,6 +661,50 @@ impl_runtime_apis! { } } + impl bp_kusama::KusamaFinalityApi for Runtime { + fn best_finalized() -> Option> { + BridgeKusamaGrandpa::best_finalized() + } + + fn synced_headers_grandpa_info( + ) -> Vec> { + BridgeKusamaGrandpa::synced_headers_grandpa_info() + } + } + + impl bp_bridge_hub_kusama::BridgeHubKusamaFinalityApi for Runtime { + fn best_finalized() -> Option> { + BridgeKusamaParachains::best_parachain_head_id::< + bp_bridge_hub_kusama::BridgeHubKusama + >().unwrap_or(None) + } + } + + impl bp_bridge_hub_kusama::FromBridgeHubKusamaInboundLaneApi for Runtime { + fn message_details( + lane: bp_messages::LaneId, + messages: Vec<(bp_messages::MessagePayload, bp_messages::OutboundMessageDetails)>, + ) -> Vec { + bridge_runtime_common::messages_api::inbound_message_details::< + Runtime, + bridge_to_kusama_config::WithBridgeHubKusamaMessagesInstance, + >(lane, messages) + } + } + + impl bp_bridge_hub_kusama::ToBridgeHubKusamaOutboundLaneApi for Runtime { + fn message_details( + lane: bp_messages::LaneId, + begin: bp_messages::MessageNonce, + end: bp_messages::MessageNonce, + ) -> Vec { + bridge_runtime_common::messages_api::outbound_message_details::< + Runtime, + bridge_to_kusama_config::WithBridgeHubKusamaMessagesInstance, + >(lane, begin, end) + } + } + #[cfg(feature = "try-runtime")] impl frame_try_runtime::TryRuntime for Runtime { fn on_runtime_upgrade(checks: frame_try_runtime::UpgradeCheckSelect) -> (Weight, Weight) { @@ -670,6 +741,11 @@ impl_runtime_apis! { type XcmBalances = pallet_xcm_benchmarks::fungible::Pallet::; type XcmGeneric = pallet_xcm_benchmarks::generic::Pallet::; + use pallet_bridge_relayers::benchmarking::Pallet as BridgeRelayersBench; + type KusamaFinality = BridgeKusamaGrandpa; + type KusamaParachains = pallet_bridge_parachains::benchmarking::Pallet::; + type KusamaMessages = pallet_bridge_messages::benchmarking::Pallet::; + let mut list = Vec::::new(); list_benchmarks!(list, extra); @@ -792,7 +868,7 @@ impl_runtime_apis! { fn export_message_origin_and_destination( ) -> Result<(MultiLocation, NetworkId, InteriorMultiLocation), BenchmarkError> { - Err(BenchmarkError::Skip) + Ok((DotRelayLocation::get(), NetworkId::Kusama, X1(Parachain(1000)))) } fn alias_origin() -> Result<(MultiLocation, MultiLocation), BenchmarkError> { @@ -803,6 +879,114 @@ impl_runtime_apis! { type XcmBalances = pallet_xcm_benchmarks::fungible::Pallet::; type XcmGeneric = pallet_xcm_benchmarks::generic::Pallet::; + type KusamaFinality = BridgeKusamaGrandpa; + type KusamaParachains = pallet_bridge_parachains::benchmarking::Pallet::; + type KusamaMessages = pallet_bridge_messages::benchmarking::Pallet::; + + use pallet_bridge_relayers::benchmarking::{ + Pallet as BridgeRelayersBench, + Config as BridgeRelayersConfig, + }; + + impl BridgeRelayersConfig for Runtime { + fn prepare_rewards_account( + account_params: bp_relayers::RewardsAccountParams, + reward: Balance, + ) { + let rewards_account = bp_relayers::PayRewardFromAccount::< + Balances, + AccountId + >::rewards_account(account_params); + Self::deposit_account(rewards_account, reward); + } + + fn deposit_account(account: AccountId, balance: Balance) { + use frame_support::traits::fungible::Mutate; + Balances::mint_into(&account, balance.saturating_add(ExistentialDeposit::get())).unwrap(); + } + } + + use bridge_runtime_common::parachains_benchmarking::prepare_parachain_heads_proof; + use pallet_bridge_parachains::benchmarking::Config as BridgeParachainsConfig; + + impl BridgeParachainsConfig for Runtime { + fn parachains() -> Vec { + use bp_runtime::Parachain; + vec![bp_polkadot_core::parachains::ParaId(bp_bridge_hub_kusama::BridgeHubKusama::PARACHAIN_ID)] + } + + fn prepare_parachain_heads_proof( + parachains: &[bp_polkadot_core::parachains::ParaId], + parachain_head_size: u32, + proof_size: bp_runtime::StorageProofSize, + ) -> ( + pallet_bridge_parachains::RelayBlockNumber, + pallet_bridge_parachains::RelayBlockHash, + bp_polkadot_core::parachains::ParaHeadsProof, + Vec<(bp_polkadot_core::parachains::ParaId, bp_polkadot_core::parachains::ParaHash)>, + ) { + prepare_parachain_heads_proof::( + parachains, + parachain_head_size, + proof_size, + ) + } + } + + use bridge_runtime_common::messages_benchmarking::{ + prepare_message_delivery_proof_from_parachain, + prepare_message_proof_from_parachain, + generate_xcm_builder_bridge_message_sample, + }; + use pallet_bridge_messages::benchmarking::{ + Config as BridgeMessagesConfig, + MessageDeliveryProofParams, + MessageProofParams, + }; + + impl BridgeMessagesConfig for Runtime { + fn is_relayer_rewarded(relayer: &Self::AccountId) -> bool { + let bench_lane_id = >::bench_lane_id(); + let bridged_chain_id = bp_runtime::BRIDGE_HUB_KUSAMA_CHAIN_ID; + pallet_bridge_relayers::Pallet::::relayer_reward( + relayer, + bp_relayers::RewardsAccountParams::new( + bench_lane_id, + bridged_chain_id, + bp_relayers::RewardsAccountOwner::BridgedChain + ) + ).is_some() + } + + fn prepare_message_proof( + params: MessageProofParams, + ) -> (bridge_to_kusama_config::FromKusamaBridgeHubMessagesProof, Weight) { + use cumulus_primitives_core::XcmpMessageSource; + assert!(XcmpQueue::take_outbound_messages(usize::MAX).is_empty()); + ParachainSystem::open_outbound_hrmp_channel_for_benchmarks_or_tests(42.into()); + prepare_message_proof_from_parachain::< + Runtime, + bridge_to_kusama_config::BridgeGrandpaKusamaInstance, + bridge_to_kusama_config::WithBridgeHubKusamaMessageBridge, + >(params, generate_xcm_builder_bridge_message_sample(X2(GlobalConsensus(Polkadot), Parachain(42)))) + } + + fn prepare_message_delivery_proof( + params: MessageDeliveryProofParams, + ) -> bridge_to_kusama_config::ToKusamaBridgeHubMessagesDeliveryProof { + prepare_message_delivery_proof_from_parachain::< + Runtime, + bridge_to_kusama_config::BridgeGrandpaKusamaInstance, + bridge_to_kusama_config::WithBridgeHubKusamaMessageBridge, + >(params) + } + + fn is_message_successfully_dispatched(_nonce: bp_messages::MessageNonce) -> bool { + use cumulus_primitives_core::XcmpMessageSource; + !XcmpQueue::take_outbound_messages(usize::MAX).is_empty() + } + } + let whitelist: Vec = vec![ // Block Number hex_literal::hex!("26aa394eea5630e07c48ae0c9558cef702a5c1b19ab7a04f536c519aca4983ac").to_vec().into(), diff --git a/system-parachains/bridge-hubs/bridge-hub-polkadot/src/weights/mod.rs b/system-parachains/bridge-hubs/bridge-hub-polkadot/src/weights/mod.rs index 60dfbea8db..951cab5546 100644 --- a/system-parachains/bridge-hubs/bridge-hub-polkadot/src/weights/mod.rs +++ b/system-parachains/bridge-hubs/bridge-hub-polkadot/src/weights/mod.rs @@ -17,11 +17,21 @@ //! Expose the auto generated weight files. +use crate::Runtime; +use ::pallet_bridge_messages::WeightInfoExt as MessagesWeightInfoExt; +use ::pallet_bridge_parachains::WeightInfoExt as ParachainsWeightInfoExt; +use ::pallet_bridge_relayers::WeightInfoExt as _; +use frame_support::weights::Weight; + pub mod block_weights; pub mod cumulus_pallet_xcmp_queue; pub mod extrinsic_weights; pub mod frame_system; pub mod pallet_balances; +pub mod pallet_bridge_grandpa; +pub mod pallet_bridge_messages; +pub mod pallet_bridge_parachains; +pub mod pallet_bridge_relayers; pub mod pallet_collator_selection; pub mod pallet_multisig; pub mod pallet_session; @@ -35,3 +45,24 @@ pub mod xcm; pub use block_weights::constants::BlockExecutionWeight; pub use extrinsic_weights::constants::ExtrinsicBaseWeight; pub use rocksdb_weights::constants::RocksDbWeight; + +impl MessagesWeightInfoExt for pallet_bridge_messages::WeightInfo { + fn expected_extra_storage_proof_size() -> u32 { + bp_bridge_hub_kusama::EXTRA_STORAGE_PROOF_SIZE + } + + fn receive_messages_proof_overhead_from_runtime() -> Weight { + pallet_bridge_relayers::WeightInfo::::receive_messages_proof_overhead_from_runtime( + ) + } + + fn receive_messages_delivery_proof_overhead_from_runtime() -> Weight { + pallet_bridge_relayers::WeightInfo::::receive_messages_delivery_proof_overhead_from_runtime() + } +} + +impl ParachainsWeightInfoExt for pallet_bridge_parachains::WeightInfo { + fn expected_extra_storage_proof_size() -> u32 { + bp_bridge_hub_kusama::EXTRA_STORAGE_PROOF_SIZE + } +} diff --git a/system-parachains/bridge-hubs/bridge-hub-polkadot/src/weights/pallet_bridge_grandpa.rs b/system-parachains/bridge-hubs/bridge-hub-polkadot/src/weights/pallet_bridge_grandpa.rs new file mode 100644 index 0000000000..197f112806 --- /dev/null +++ b/system-parachains/bridge-hubs/bridge-hub-polkadot/src/weights/pallet_bridge_grandpa.rs @@ -0,0 +1,63 @@ + +//! Autogenerated weights for `pallet_bridge_grandpa` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-12-05, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `svyatonik-benchmarking`, CPU: `Intel(R) Xeon(R) CPU @ 2.80GHz` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("bh-polkadot-local-raw.json")`, DB CACHE: 1024 + +// Executed Command: +// ../polkadot-sdk/target/production/polkadot-parachain-benchmarks +// benchmark +// pallet +// --chain +// bh-polkadot-local-raw.json +// --pallet +// pallet-bridge-grandpa +// --extrinsic +// * +// --output=system-parachains/bridge-hubs/bridge-hub-polkadot/src/weights +// --no-median-slopes +// --no-min-squares + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_bridge_grandpa`. +pub struct WeightInfo(PhantomData); +impl pallet_bridge_grandpa::WeightInfo for WeightInfo { + /// Storage: `BridgeKusamaGrandpa::PalletOperatingMode` (r:1 w:0) + /// Proof: `BridgeKusamaGrandpa::PalletOperatingMode` (`max_values`: Some(1), `max_size`: Some(1), added: 496, mode: `MaxEncodedLen`) + /// Storage: `BridgeKusamaGrandpa::BestFinalized` (r:1 w:1) + /// Proof: `BridgeKusamaGrandpa::BestFinalized` (`max_values`: Some(1), `max_size`: Some(36), added: 531, mode: `MaxEncodedLen`) + /// Storage: `BridgeKusamaGrandpa::CurrentAuthoritySet` (r:1 w:0) + /// Proof: `BridgeKusamaGrandpa::CurrentAuthoritySet` (`max_values`: Some(1), `max_size`: Some(50250), added: 50745, mode: `MaxEncodedLen`) + /// Storage: `BridgeKusamaGrandpa::ImportedHashesPointer` (r:1 w:1) + /// Proof: `BridgeKusamaGrandpa::ImportedHashesPointer` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `BridgeKusamaGrandpa::ImportedHashes` (r:1 w:1) + /// Proof: `BridgeKusamaGrandpa::ImportedHashes` (`max_values`: Some(1200), `max_size`: Some(36), added: 1521, mode: `MaxEncodedLen`) + /// Storage: `BridgeKusamaGrandpa::ImportedHeaders` (r:0 w:2) + /// Proof: `BridgeKusamaGrandpa::ImportedHeaders` (`max_values`: Some(1200), `max_size`: Some(68), added: 1553, mode: `MaxEncodedLen`) + /// The range of component `p` is `[1, 838]`. + /// The range of component `v` is `[50, 100]`. + fn submit_finality_proof(p: u32, v: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `302 + p * (60 ±0)` + // Estimated: `51735` + // Minimum execution time: 375_137_000 picoseconds. + Weight::from_parts(60_927_772, 0) + .saturating_add(Weight::from_parts(0, 51735)) + // Standard Error: 8_595 + .saturating_add(Weight::from_parts(61_673_711, 0).saturating_mul(p.into())) + // Standard Error: 143_360 + .saturating_add(Weight::from_parts(3_269_140, 0).saturating_mul(v.into())) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().writes(5)) + } +} diff --git a/system-parachains/bridge-hubs/bridge-hub-polkadot/src/weights/pallet_bridge_messages.rs b/system-parachains/bridge-hubs/bridge-hub-polkadot/src/weights/pallet_bridge_messages.rs new file mode 100644 index 0000000000..fb7f0e1895 --- /dev/null +++ b/system-parachains/bridge-hubs/bridge-hub-polkadot/src/weights/pallet_bridge_messages.rs @@ -0,0 +1,226 @@ + +//! Autogenerated weights for `pallet_bridge_messages` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-12-05, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `svyatonik-benchmarking`, CPU: `Intel(R) Xeon(R) CPU @ 2.80GHz` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("bh-polkadot-local-raw.json")`, DB CACHE: 1024 + +// Executed Command: +// ../polkadot-sdk/target/production/polkadot-parachain-benchmarks +// benchmark +// pallet +// --chain +// bh-polkadot-local-raw.json +// --pallet +// pallet-bridge-messages +// --extrinsic +// * +// --output=system-parachains/bridge-hubs/bridge-hub-polkadot/src/weights +// --no-median-slopes +// --no-min-squares + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_bridge_messages`. +pub struct WeightInfo(PhantomData); +impl pallet_bridge_messages::WeightInfo for WeightInfo { + /// Storage: `BridgeKusamaMessages::PalletOperatingMode` (r:1 w:0) + /// Proof: `BridgeKusamaMessages::PalletOperatingMode` (`max_values`: Some(1), `max_size`: Some(2), added: 497, mode: `MaxEncodedLen`) + /// Storage: `XcmpQueue::OutboundXcmpStatus` (r:1 w:0) + /// Proof: `XcmpQueue::OutboundXcmpStatus` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `BridgeKusamaParachains::ImportedParaHeads` (r:1 w:0) + /// Proof: `BridgeKusamaParachains::ImportedParaHeads` (`max_values`: Some(600), `max_size`: Some(196), added: 1681, mode: `MaxEncodedLen`) + /// Storage: `BridgeKusamaMessages::InboundLanes` (r:1 w:1) + /// Proof: `BridgeKusamaMessages::InboundLanes` (`max_values`: None, `max_size`: Some(49180), added: 51655, mode: `MaxEncodedLen`) + /// Storage: `ParachainInfo::ParachainId` (r:1 w:0) + /// Proof: `ParachainInfo::ParachainId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + fn receive_single_message_proof() -> Weight { + // Proof Size summary in bytes: + // Measured: `542` + // Estimated: `52645` + // Minimum execution time: 71_852_000 picoseconds. + Weight::from_parts(74_164_000, 0) + .saturating_add(Weight::from_parts(0, 52645)) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: `BridgeKusamaMessages::PalletOperatingMode` (r:1 w:0) + /// Proof: `BridgeKusamaMessages::PalletOperatingMode` (`max_values`: Some(1), `max_size`: Some(2), added: 497, mode: `MaxEncodedLen`) + /// Storage: `XcmpQueue::OutboundXcmpStatus` (r:1 w:0) + /// Proof: `XcmpQueue::OutboundXcmpStatus` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `BridgeKusamaParachains::ImportedParaHeads` (r:1 w:0) + /// Proof: `BridgeKusamaParachains::ImportedParaHeads` (`max_values`: Some(600), `max_size`: Some(196), added: 1681, mode: `MaxEncodedLen`) + /// Storage: `BridgeKusamaMessages::InboundLanes` (r:1 w:1) + /// Proof: `BridgeKusamaMessages::InboundLanes` (`max_values`: None, `max_size`: Some(49180), added: 51655, mode: `MaxEncodedLen`) + /// Storage: `ParachainInfo::ParachainId` (r:1 w:0) + /// Proof: `ParachainInfo::ParachainId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + fn receive_two_messages_proof() -> Weight { + // Proof Size summary in bytes: + // Measured: `542` + // Estimated: `52645` + // Minimum execution time: 90_722_000 picoseconds. + Weight::from_parts(99_839_000, 0) + .saturating_add(Weight::from_parts(0, 52645)) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: `BridgeKusamaMessages::PalletOperatingMode` (r:1 w:0) + /// Proof: `BridgeKusamaMessages::PalletOperatingMode` (`max_values`: Some(1), `max_size`: Some(2), added: 497, mode: `MaxEncodedLen`) + /// Storage: `XcmpQueue::OutboundXcmpStatus` (r:1 w:0) + /// Proof: `XcmpQueue::OutboundXcmpStatus` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `BridgeKusamaParachains::ImportedParaHeads` (r:1 w:0) + /// Proof: `BridgeKusamaParachains::ImportedParaHeads` (`max_values`: Some(600), `max_size`: Some(196), added: 1681, mode: `MaxEncodedLen`) + /// Storage: `BridgeKusamaMessages::InboundLanes` (r:1 w:1) + /// Proof: `BridgeKusamaMessages::InboundLanes` (`max_values`: None, `max_size`: Some(49180), added: 51655, mode: `MaxEncodedLen`) + /// Storage: `ParachainInfo::ParachainId` (r:1 w:0) + /// Proof: `ParachainInfo::ParachainId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + fn receive_single_message_proof_with_outbound_lane_state() -> Weight { + // Proof Size summary in bytes: + // Measured: `542` + // Estimated: `52645` + // Minimum execution time: 78_537_000 picoseconds. + Weight::from_parts(80_528_000, 0) + .saturating_add(Weight::from_parts(0, 52645)) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: `BridgeKusamaMessages::PalletOperatingMode` (r:1 w:0) + /// Proof: `BridgeKusamaMessages::PalletOperatingMode` (`max_values`: Some(1), `max_size`: Some(2), added: 497, mode: `MaxEncodedLen`) + /// Storage: `XcmpQueue::OutboundXcmpStatus` (r:1 w:0) + /// Proof: `XcmpQueue::OutboundXcmpStatus` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `BridgeKusamaParachains::ImportedParaHeads` (r:1 w:0) + /// Proof: `BridgeKusamaParachains::ImportedParaHeads` (`max_values`: Some(600), `max_size`: Some(196), added: 1681, mode: `MaxEncodedLen`) + /// Storage: `BridgeKusamaMessages::InboundLanes` (r:1 w:1) + /// Proof: `BridgeKusamaMessages::InboundLanes` (`max_values`: None, `max_size`: Some(49180), added: 51655, mode: `MaxEncodedLen`) + fn receive_single_message_proof_1_kb() -> Weight { + // Proof Size summary in bytes: + // Measured: `510` + // Estimated: `52645` + // Minimum execution time: 68_804_000 picoseconds. + Weight::from_parts(71_705_000, 0) + .saturating_add(Weight::from_parts(0, 52645)) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: `BridgeKusamaMessages::PalletOperatingMode` (r:1 w:0) + /// Proof: `BridgeKusamaMessages::PalletOperatingMode` (`max_values`: Some(1), `max_size`: Some(2), added: 497, mode: `MaxEncodedLen`) + /// Storage: `XcmpQueue::OutboundXcmpStatus` (r:1 w:0) + /// Proof: `XcmpQueue::OutboundXcmpStatus` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `BridgeKusamaParachains::ImportedParaHeads` (r:1 w:0) + /// Proof: `BridgeKusamaParachains::ImportedParaHeads` (`max_values`: Some(600), `max_size`: Some(196), added: 1681, mode: `MaxEncodedLen`) + /// Storage: `BridgeKusamaMessages::InboundLanes` (r:1 w:1) + /// Proof: `BridgeKusamaMessages::InboundLanes` (`max_values`: None, `max_size`: Some(49180), added: 51655, mode: `MaxEncodedLen`) + fn receive_single_message_proof_16_kb() -> Weight { + // Proof Size summary in bytes: + // Measured: `510` + // Estimated: `52645` + // Minimum execution time: 104_741_000 picoseconds. + Weight::from_parts(106_847_000, 0) + .saturating_add(Weight::from_parts(0, 52645)) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: `BridgeKusamaMessages::PalletOperatingMode` (r:1 w:0) + /// Proof: `BridgeKusamaMessages::PalletOperatingMode` (`max_values`: Some(1), `max_size`: Some(2), added: 497, mode: `MaxEncodedLen`) + /// Storage: `BridgeKusamaParachains::ImportedParaHeads` (r:1 w:0) + /// Proof: `BridgeKusamaParachains::ImportedParaHeads` (`max_values`: Some(600), `max_size`: Some(196), added: 1681, mode: `MaxEncodedLen`) + /// Storage: `BridgeKusamaMessages::OutboundLanes` (r:1 w:1) + /// Proof: `BridgeKusamaMessages::OutboundLanes` (`max_values`: Some(1), `max_size`: Some(44), added: 539, mode: `MaxEncodedLen`) + /// Storage: UNKNOWN KEY `0x6e0a18b62a1de81c5f519181cc611e18` (r:1 w:0) + /// Proof: UNKNOWN KEY `0x6e0a18b62a1de81c5f519181cc611e18` (r:1 w:0) + /// Storage: `BridgeRelayers::RelayerRewards` (r:1 w:1) + /// Proof: `BridgeRelayers::RelayerRewards` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) + fn receive_delivery_proof_for_single_message() -> Weight { + // Proof Size summary in bytes: + // Measured: `412` + // Estimated: `3877` + // Minimum execution time: 40_971_000 picoseconds. + Weight::from_parts(42_095_000, 0) + .saturating_add(Weight::from_parts(0, 3877)) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: `BridgeKusamaMessages::PalletOperatingMode` (r:1 w:0) + /// Proof: `BridgeKusamaMessages::PalletOperatingMode` (`max_values`: Some(1), `max_size`: Some(2), added: 497, mode: `MaxEncodedLen`) + /// Storage: `BridgeKusamaParachains::ImportedParaHeads` (r:1 w:0) + /// Proof: `BridgeKusamaParachains::ImportedParaHeads` (`max_values`: Some(600), `max_size`: Some(196), added: 1681, mode: `MaxEncodedLen`) + /// Storage: `BridgeKusamaMessages::OutboundLanes` (r:1 w:1) + /// Proof: `BridgeKusamaMessages::OutboundLanes` (`max_values`: Some(1), `max_size`: Some(44), added: 539, mode: `MaxEncodedLen`) + /// Storage: UNKNOWN KEY `0x6e0a18b62a1de81c5f519181cc611e18` (r:1 w:0) + /// Proof: UNKNOWN KEY `0x6e0a18b62a1de81c5f519181cc611e18` (r:1 w:0) + /// Storage: `BridgeRelayers::RelayerRewards` (r:1 w:1) + /// Proof: `BridgeRelayers::RelayerRewards` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) + fn receive_delivery_proof_for_two_messages_by_single_relayer() -> Weight { + // Proof Size summary in bytes: + // Measured: `412` + // Estimated: `3877` + // Minimum execution time: 41_175_000 picoseconds. + Weight::from_parts(42_223_000, 0) + .saturating_add(Weight::from_parts(0, 3877)) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: `BridgeKusamaMessages::PalletOperatingMode` (r:1 w:0) + /// Proof: `BridgeKusamaMessages::PalletOperatingMode` (`max_values`: Some(1), `max_size`: Some(2), added: 497, mode: `MaxEncodedLen`) + /// Storage: `BridgeKusamaParachains::ImportedParaHeads` (r:1 w:0) + /// Proof: `BridgeKusamaParachains::ImportedParaHeads` (`max_values`: Some(600), `max_size`: Some(196), added: 1681, mode: `MaxEncodedLen`) + /// Storage: `BridgeKusamaMessages::OutboundLanes` (r:1 w:1) + /// Proof: `BridgeKusamaMessages::OutboundLanes` (`max_values`: Some(1), `max_size`: Some(44), added: 539, mode: `MaxEncodedLen`) + /// Storage: UNKNOWN KEY `0x6e0a18b62a1de81c5f519181cc611e18` (r:1 w:0) + /// Proof: UNKNOWN KEY `0x6e0a18b62a1de81c5f519181cc611e18` (r:1 w:0) + /// Storage: `BridgeRelayers::RelayerRewards` (r:2 w:2) + /// Proof: `BridgeRelayers::RelayerRewards` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) + fn receive_delivery_proof_for_two_messages_by_two_relayers() -> Weight { + // Proof Size summary in bytes: + // Measured: `412` + // Estimated: `6086` + // Minimum execution time: 44_446_000 picoseconds. + Weight::from_parts(45_490_000, 0) + .saturating_add(Weight::from_parts(0, 6086)) + .saturating_add(T::DbWeight::get().reads(6)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: `BridgeKusamaMessages::PalletOperatingMode` (r:1 w:0) + /// Proof: `BridgeKusamaMessages::PalletOperatingMode` (`max_values`: Some(1), `max_size`: Some(2), added: 497, mode: `MaxEncodedLen`) + /// Storage: `XcmpQueue::OutboundXcmpStatus` (r:1 w:1) + /// Proof: `XcmpQueue::OutboundXcmpStatus` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `BridgeKusamaParachains::ImportedParaHeads` (r:1 w:0) + /// Proof: `BridgeKusamaParachains::ImportedParaHeads` (`max_values`: Some(600), `max_size`: Some(196), added: 1681, mode: `MaxEncodedLen`) + /// Storage: `BridgeKusamaMessages::InboundLanes` (r:1 w:1) + /// Proof: `BridgeKusamaMessages::InboundLanes` (`max_values`: None, `max_size`: Some(49180), added: 51655, mode: `MaxEncodedLen`) + /// Storage: `ParachainInfo::ParachainId` (r:1 w:0) + /// Proof: `ParachainInfo::ParachainId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `XcmpQueue::DeliveryFeeFactor` (r:1 w:0) + /// Proof: `XcmpQueue::DeliveryFeeFactor` (`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::RelevantMessagingState` (r:1 w:0) + /// Proof: `ParachainSystem::RelevantMessagingState` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `XcmpQueue::OutboundXcmpMessages` (r:0 w:1) + /// Proof: `XcmpQueue::OutboundXcmpMessages` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// The range of component `i` is `[128, 2048]`. + fn receive_single_message_proof_with_dispatch(i: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `673` + // Estimated: `52645` + // Minimum execution time: 84_817_000 picoseconds. + Weight::from_parts(85_877_544, 0) + .saturating_add(Weight::from_parts(0, 52645)) + // Standard Error: 96 + .saturating_add(Weight::from_parts(7_374, 0).saturating_mul(i.into())) + .saturating_add(T::DbWeight::get().reads(10)) + .saturating_add(T::DbWeight::get().writes(4)) + } +} diff --git a/system-parachains/bridge-hubs/bridge-hub-polkadot/src/weights/pallet_bridge_parachains.rs b/system-parachains/bridge-hubs/bridge-hub-polkadot/src/weights/pallet_bridge_parachains.rs new file mode 100644 index 0000000000..8cf2ee96c2 --- /dev/null +++ b/system-parachains/bridge-hubs/bridge-hub-polkadot/src/weights/pallet_bridge_parachains.rs @@ -0,0 +1,96 @@ + +//! Autogenerated weights for `pallet_bridge_parachains` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-12-05, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `svyatonik-benchmarking`, CPU: `Intel(R) Xeon(R) CPU @ 2.80GHz` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("bh-polkadot-local-raw.json")`, DB CACHE: 1024 + +// Executed Command: +// ../polkadot-sdk/target/production/polkadot-parachain-benchmarks +// benchmark +// pallet +// --chain +// bh-polkadot-local-raw.json +// --pallet +// pallet-bridge-parachains +// --extrinsic +// * +// --output=system-parachains/bridge-hubs/bridge-hub-polkadot/src/weights +// --no-median-slopes +// --no-min-squares + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_bridge_parachains`. +pub struct WeightInfo(PhantomData); +impl pallet_bridge_parachains::WeightInfo for WeightInfo { + /// Storage: `BridgeKusamaParachains::PalletOperatingMode` (r:1 w:0) + /// Proof: `BridgeKusamaParachains::PalletOperatingMode` (`max_values`: Some(1), `max_size`: Some(1), added: 496, mode: `MaxEncodedLen`) + /// Storage: `BridgeKusamaGrandpa::ImportedHeaders` (r:1 w:0) + /// Proof: `BridgeKusamaGrandpa::ImportedHeaders` (`max_values`: Some(1200), `max_size`: Some(68), added: 1553, mode: `MaxEncodedLen`) + /// Storage: `BridgeKusamaParachains::ParasInfo` (r:1 w:1) + /// Proof: `BridgeKusamaParachains::ParasInfo` (`max_values`: Some(1), `max_size`: Some(60), added: 555, mode: `MaxEncodedLen`) + /// Storage: `BridgeKusamaParachains::ImportedParaHashes` (r:1 w:1) + /// Proof: `BridgeKusamaParachains::ImportedParaHashes` (`max_values`: Some(600), `max_size`: Some(64), added: 1549, mode: `MaxEncodedLen`) + /// Storage: `BridgeKusamaParachains::ImportedParaHeads` (r:0 w:1) + /// Proof: `BridgeKusamaParachains::ImportedParaHeads` (`max_values`: Some(600), `max_size`: Some(196), added: 1681, mode: `MaxEncodedLen`) + /// The range of component `p` is `[1, 2]`. + fn submit_parachain_heads_with_n_parachains(_p: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `364` + // Estimated: `2543` + // Minimum execution time: 41_520_000 picoseconds. + Weight::from_parts(42_862_371, 0) + .saturating_add(Weight::from_parts(0, 2543)) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: `BridgeKusamaParachains::PalletOperatingMode` (r:1 w:0) + /// Proof: `BridgeKusamaParachains::PalletOperatingMode` (`max_values`: Some(1), `max_size`: Some(1), added: 496, mode: `MaxEncodedLen`) + /// Storage: `BridgeKusamaGrandpa::ImportedHeaders` (r:1 w:0) + /// Proof: `BridgeKusamaGrandpa::ImportedHeaders` (`max_values`: Some(1200), `max_size`: Some(68), added: 1553, mode: `MaxEncodedLen`) + /// Storage: `BridgeKusamaParachains::ParasInfo` (r:1 w:1) + /// Proof: `BridgeKusamaParachains::ParasInfo` (`max_values`: Some(1), `max_size`: Some(60), added: 555, mode: `MaxEncodedLen`) + /// Storage: `BridgeKusamaParachains::ImportedParaHashes` (r:1 w:1) + /// Proof: `BridgeKusamaParachains::ImportedParaHashes` (`max_values`: Some(600), `max_size`: Some(64), added: 1549, mode: `MaxEncodedLen`) + /// Storage: `BridgeKusamaParachains::ImportedParaHeads` (r:0 w:1) + /// Proof: `BridgeKusamaParachains::ImportedParaHeads` (`max_values`: Some(600), `max_size`: Some(196), added: 1681, mode: `MaxEncodedLen`) + fn submit_parachain_heads_with_1kb_proof() -> Weight { + // Proof Size summary in bytes: + // Measured: `364` + // Estimated: `2543` + // Minimum execution time: 43_116_000 picoseconds. + Weight::from_parts(43_611_000, 0) + .saturating_add(Weight::from_parts(0, 2543)) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: `BridgeKusamaParachains::PalletOperatingMode` (r:1 w:0) + /// Proof: `BridgeKusamaParachains::PalletOperatingMode` (`max_values`: Some(1), `max_size`: Some(1), added: 496, mode: `MaxEncodedLen`) + /// Storage: `BridgeKusamaGrandpa::ImportedHeaders` (r:1 w:0) + /// Proof: `BridgeKusamaGrandpa::ImportedHeaders` (`max_values`: Some(1200), `max_size`: Some(68), added: 1553, mode: `MaxEncodedLen`) + /// Storage: `BridgeKusamaParachains::ParasInfo` (r:1 w:1) + /// Proof: `BridgeKusamaParachains::ParasInfo` (`max_values`: Some(1), `max_size`: Some(60), added: 555, mode: `MaxEncodedLen`) + /// Storage: `BridgeKusamaParachains::ImportedParaHashes` (r:1 w:1) + /// Proof: `BridgeKusamaParachains::ImportedParaHashes` (`max_values`: Some(600), `max_size`: Some(64), added: 1549, mode: `MaxEncodedLen`) + /// Storage: `BridgeKusamaParachains::ImportedParaHeads` (r:0 w:1) + /// Proof: `BridgeKusamaParachains::ImportedParaHeads` (`max_values`: Some(600), `max_size`: Some(196), added: 1681, mode: `MaxEncodedLen`) + fn submit_parachain_heads_with_16kb_proof() -> Weight { + // Proof Size summary in bytes: + // Measured: `364` + // Estimated: `2543` + // Minimum execution time: 77_877_000 picoseconds. + Weight::from_parts(79_034_000, 0) + .saturating_add(Weight::from_parts(0, 2543)) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(3)) + } +} diff --git a/system-parachains/bridge-hubs/bridge-hub-polkadot/src/weights/pallet_bridge_relayers.rs b/system-parachains/bridge-hubs/bridge-hub-polkadot/src/weights/pallet_bridge_relayers.rs new file mode 100644 index 0000000000..636b5b5b4f --- /dev/null +++ b/system-parachains/bridge-hubs/bridge-hub-polkadot/src/weights/pallet_bridge_relayers.rs @@ -0,0 +1,107 @@ + +//! Autogenerated weights for `pallet_bridge_relayers` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-11-13, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `MusXroom`, CPU: `13th Gen Intel(R) Core(TM) i7-13650HX` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("bh-polkadot-local-raw.json")`, DB CACHE: 1024 + +// Executed Command: +// ../polkadot-sdk/target/release/polkadot-parachain-benchmarks +// benchmark +// pallet +// --chain +// bh-polkadot-local-raw.json +// --pallet +// pallet-bridge-relayers +// --extrinsic +// * +// --output=system-parachains/bridge-hubs/bridge-hub-polkadot/src/weights +// --no-median-slopes +// --no-min-squares + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_bridge_relayers`. +pub struct WeightInfo(PhantomData); +impl pallet_bridge_relayers::WeightInfo for WeightInfo { + /// Storage: `BridgeRelayers::RelayerRewards` (r:1 w:1) + /// Proof: `BridgeRelayers::RelayerRewards` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + fn claim_rewards() -> Weight { + // Proof Size summary in bytes: + // Measured: `278` + // Estimated: `3593` + // Minimum execution time: 37_582_000 picoseconds. + Weight::from_parts(38_046_000, 0) + .saturating_add(Weight::from_parts(0, 3593)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: `BridgeRelayers::RegisteredRelayers` (r:1 w:1) + /// Proof: `BridgeRelayers::RegisteredRelayers` (`max_values`: None, `max_size`: Some(68), added: 2543, mode: `MaxEncodedLen`) + /// Storage: UNKNOWN KEY `0x1e8445dc201eeb8560e5579a5dd54655` (r:1 w:0) + /// Proof: UNKNOWN KEY `0x1e8445dc201eeb8560e5579a5dd54655` (r:1 w:0) + /// Storage: `Balances::Reserves` (r:1 w:1) + /// Proof: `Balances::Reserves` (`max_values`: None, `max_size`: Some(1249), added: 3724, mode: `MaxEncodedLen`) + fn register() -> Weight { + // Proof Size summary in bytes: + // Measured: `115` + // Estimated: `4714` + // Minimum execution time: 18_758_000 picoseconds. + Weight::from_parts(19_298_000, 0) + .saturating_add(Weight::from_parts(0, 4714)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: `BridgeRelayers::RegisteredRelayers` (r:1 w:1) + /// Proof: `BridgeRelayers::RegisteredRelayers` (`max_values`: None, `max_size`: Some(68), added: 2543, mode: `MaxEncodedLen`) + /// Storage: `Balances::Reserves` (r:1 w:1) + /// Proof: `Balances::Reserves` (`max_values`: None, `max_size`: Some(1249), added: 3724, mode: `MaxEncodedLen`) + fn deregister() -> Weight { + // Proof Size summary in bytes: + // Measured: `231` + // Estimated: `4714` + // Minimum execution time: 20_507_000 picoseconds. + Weight::from_parts(20_944_000, 0) + .saturating_add(Weight::from_parts(0, 4714)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: `BridgeRelayers::RegisteredRelayers` (r:1 w:1) + /// Proof: `BridgeRelayers::RegisteredRelayers` (`max_values`: None, `max_size`: Some(68), added: 2543, mode: `MaxEncodedLen`) + /// Storage: `Balances::Reserves` (r:1 w:1) + /// Proof: `Balances::Reserves` (`max_values`: None, `max_size`: Some(1249), added: 3724, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + fn slash_and_deregister() -> Weight { + // Proof Size summary in bytes: + // Measured: `334` + // Estimated: `4714` + // Minimum execution time: 22_634_000 picoseconds. + Weight::from_parts(23_065_000, 0) + .saturating_add(Weight::from_parts(0, 4714)) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: `BridgeRelayers::RelayerRewards` (r:1 w:1) + /// Proof: `BridgeRelayers::RelayerRewards` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) + fn register_relayer_reward() -> Weight { + // Proof Size summary in bytes: + // Measured: `76` + // Estimated: `3538` + // Minimum execution time: 2_718_000 picoseconds. + Weight::from_parts(2_840_000, 0) + .saturating_add(Weight::from_parts(0, 3538)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } +} diff --git a/system-parachains/bridge-hubs/bridge-hub-polkadot/src/weights/xcm/mod.rs b/system-parachains/bridge-hubs/bridge-hub-polkadot/src/weights/xcm/mod.rs index 7e9f218427..3a07ef123f 100644 --- a/system-parachains/bridge-hubs/bridge-hub-polkadot/src/weights/xcm/mod.rs +++ b/system-parachains/bridge-hubs/bridge-hub-polkadot/src/weights/xcm/mod.rs @@ -18,6 +18,7 @@ mod pallet_xcm_benchmarks_fungible; mod pallet_xcm_benchmarks_generic; use crate::{xcm_config::MaxAssetsIntoHolding, Runtime}; +use codec::Encode; use frame_support::weights::Weight; use pallet_xcm_benchmarks_fungible::WeightInfo as XcmFungibleWeight; use pallet_xcm_benchmarks_generic::WeightInfo as XcmGeneric; @@ -211,8 +212,9 @@ impl XcmWeightInfo for BridgeHubPolkadotXcmWeight { fn universal_origin(_: &Junction) -> Weight { Weight::MAX } - fn export_message(_: &NetworkId, _: &Junctions, _: &Xcm<()>) -> Weight { - Weight::MAX + fn export_message(_: &NetworkId, _: &Junctions, inner: &Xcm<()>) -> Weight { + let inner_encoded_len = inner.encode().len() as u32; + XcmGeneric::::export_message(inner_encoded_len) } fn lock_asset(_: &MultiAsset, _: &MultiLocation) -> Weight { Weight::MAX diff --git a/system-parachains/bridge-hubs/bridge-hub-polkadot/src/weights/xcm/pallet_xcm_benchmarks_generic.rs b/system-parachains/bridge-hubs/bridge-hub-polkadot/src/weights/xcm/pallet_xcm_benchmarks_generic.rs index 7968649d14..c42cdccb1e 100644 --- a/system-parachains/bridge-hubs/bridge-hub-polkadot/src/weights/xcm/pallet_xcm_benchmarks_generic.rs +++ b/system-parachains/bridge-hubs/bridge-hub-polkadot/src/weights/xcm/pallet_xcm_benchmarks_generic.rs @@ -1,44 +1,26 @@ -// Copyright (C) Parity Technologies (UK) Ltd. -// This file is part of Cumulus. - -// Cumulus is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Cumulus is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Cumulus. If not, see . //! Autogenerated weights for `pallet_xcm_benchmarks::generic` //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-07-31, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2023-12-05, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-ynta1nyy-project-238-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` -//! EXECUTION: , WASM-EXECUTION: Compiled, CHAIN: Some("bridge-hub-polkadot-dev"), DB CACHE: 1024 +//! HOSTNAME: `svyatonik-benchmarking`, CPU: `Intel(R) Xeon(R) CPU @ 2.80GHz` +//! WASM-EXECUTION: Compiled, CHAIN: Some("bh-polkadot-local-raw.json"), DB CACHE: 1024 // Executed Command: -// ./target/production/polkadot-parachain +// ../polkadot-sdk/target/production/polkadot-parachain-benchmarks // benchmark // pallet -// --template=./templates/xcm-bench-template.hbs -// --chain=bridge-hub-polkadot-dev -// --wasm-execution=compiled -// --pallet=pallet_xcm_benchmarks::generic -// --no-storage-info +// --chain +// bh-polkadot-local-raw.json +// --pallet +// pallet-xcm-benchmarks::generic +// --extrinsic +// report_holding,buy_execution,query_response,transact,refund_surplus,set_error_handler,set_appendix,clear_error,descend_origin,clear_origin,report_error,claim_asset,trap,subscribe_version,unsubscribe_version,burn_asset,expect_asset,expect_origin,expect_error,expect_transact_status,query_pallet,report_transact_status,clear_transact_status,set_topic,clear_topic,export_message,set_fees_mode,unpaid_execution,universal_origin +// --template=../polkadot-sdk/cumulus/templates/xcm-bench-template.hbs +// --output=system-parachains/bridge-hubs/bridge-hub-polkadot/src/weights/xcm // --no-median-slopes // --no-min-squares -// --extrinsic=* -// --steps=50 -// --repeat=20 -// --json -// --header=./file_header.txt -// --output=./parachains/runtimes/bridge-hubs/bridge-hub-polkadot/src/weights/xcm/pallet_xcm_benchmarks_generic.rs #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -52,31 +34,35 @@ pub struct WeightInfo(PhantomData); impl WeightInfo { // Storage: `ParachainInfo::ParachainId` (r:1 w:0) // Proof: `ParachainInfo::ParachainId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + // Storage: `ParachainSystem::UpwardDeliveryFeeFactor` (r:1 w:0) + // Proof: `ParachainSystem::UpwardDeliveryFeeFactor` (`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) // 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: `System::Account` (r:2 w:1) + // Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) // 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`) pub fn report_holding() -> Weight { // Proof Size summary in bytes: - // Measured: `70` - // Estimated: `3535` - // Minimum execution time: 30_923_000 picoseconds. - Weight::from_parts(31_653_000, 3535) - .saturating_add(T::DbWeight::get().reads(6)) - .saturating_add(T::DbWeight::get().writes(2)) + // Measured: `171` + // Estimated: `6196` + // Minimum execution time: 62_849_000 picoseconds. + Weight::from_parts(63_913_000, 6196) + .saturating_add(T::DbWeight::get().reads(9)) + .saturating_add(T::DbWeight::get().writes(3)) } pub fn buy_execution() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_837_000 picoseconds. - Weight::from_parts(2_932_000, 0) + // Minimum execution time: 2_513_000 picoseconds. + Weight::from_parts(2_619_000, 0) } // Storage: `PolkadotXcm::Queries` (r:1 w:0) // Proof: `PolkadotXcm::Queries` (`max_values`: None, `max_size`: None, mode: `Measured`) @@ -84,79 +70,83 @@ impl WeightInfo { // Proof Size summary in bytes: // Measured: `32` // Estimated: `3497` - // Minimum execution time: 10_319_000 picoseconds. - Weight::from_parts(10_614_000, 3497) + // Minimum execution time: 9_382_000 picoseconds. + Weight::from_parts(9_570_000, 3497) .saturating_add(T::DbWeight::get().reads(1)) } pub fn transact() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 11_466_000 picoseconds. - Weight::from_parts(12_005_000, 0) + // Minimum execution time: 10_783_000 picoseconds. + Weight::from_parts(11_041_000, 0) } pub fn refund_surplus() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 3_039_000 picoseconds. - Weight::from_parts(3_125_000, 0) + // Minimum execution time: 2_732_000 picoseconds. + Weight::from_parts(2_800_000, 0) } pub fn set_error_handler() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_655_000 picoseconds. - Weight::from_parts(2_717_000, 0) + // Minimum execution time: 2_347_000 picoseconds. + Weight::from_parts(2_420_000, 0) } pub fn set_appendix() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_655_000 picoseconds. - Weight::from_parts(2_695_000, 0) + // Minimum execution time: 2_357_000 picoseconds. + Weight::from_parts(2_393_000, 0) } pub fn clear_error() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_612_000 picoseconds. - Weight::from_parts(2_685_000, 0) + // Minimum execution time: 2_339_000 picoseconds. + Weight::from_parts(2_417_000, 0) } pub fn descend_origin() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 3_286_000 picoseconds. - Weight::from_parts(3_425_000, 0) + // Minimum execution time: 3_165_000 picoseconds. + Weight::from_parts(3_241_000, 0) } pub fn clear_origin() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_613_000 picoseconds. - Weight::from_parts(2_699_000, 0) + // Minimum execution time: 2_338_000 picoseconds. + Weight::from_parts(2_403_000, 0) } // Storage: `ParachainInfo::ParachainId` (r:1 w:0) // Proof: `ParachainInfo::ParachainId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + // Storage: `ParachainSystem::UpwardDeliveryFeeFactor` (r:1 w:0) + // Proof: `ParachainSystem::UpwardDeliveryFeeFactor` (`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) // 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: `System::Account` (r:2 w:1) + // Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) // 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`) pub fn report_error() -> Weight { // Proof Size summary in bytes: - // Measured: `70` - // Estimated: `3535` - // Minimum execution time: 24_616_000 picoseconds. - Weight::from_parts(25_147_000, 3535) - .saturating_add(T::DbWeight::get().reads(6)) - .saturating_add(T::DbWeight::get().writes(2)) + // Measured: `171` + // Estimated: `6196` + // Minimum execution time: 54_827_000 picoseconds. + Weight::from_parts(55_517_000, 6196) + .saturating_add(T::DbWeight::get().reads(9)) + .saturating_add(T::DbWeight::get().writes(3)) } // Storage: `PolkadotXcm::AssetTraps` (r:1 w:1) // Proof: `PolkadotXcm::AssetTraps` (`max_values`: None, `max_size`: None, mode: `Measured`) @@ -164,8 +154,8 @@ impl WeightInfo { // Proof Size summary in bytes: // Measured: `90` // Estimated: `3555` - // Minimum execution time: 14_511_000 picoseconds. - Weight::from_parts(14_831_000, 3555) + // Minimum execution time: 13_690_000 picoseconds. + Weight::from_parts(13_900_000, 3555) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } @@ -173,11 +163,13 @@ impl WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_640_000 picoseconds. - Weight::from_parts(2_702_000, 0) + // Minimum execution time: 2_324_000 picoseconds. + Weight::from_parts(2_397_000, 0) } // Storage: `PolkadotXcm::VersionNotifyTargets` (r:1 w:1) // Proof: `PolkadotXcm::VersionNotifyTargets` (`max_values`: None, `max_size`: None, mode: `Measured`) + // Storage: `ParachainSystem::UpwardDeliveryFeeFactor` (r:1 w:0) + // Proof: `ParachainSystem::UpwardDeliveryFeeFactor` (`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) @@ -192,9 +184,9 @@ impl WeightInfo { // Proof Size summary in bytes: // Measured: `38` // Estimated: `3503` - // Minimum execution time: 26_044_000 picoseconds. - Weight::from_parts(26_561_000, 3503) - .saturating_add(T::DbWeight::get().reads(6)) + // Minimum execution time: 27_827_000 picoseconds. + Weight::from_parts(28_423_000, 3503) + .saturating_add(T::DbWeight::get().reads(7)) .saturating_add(T::DbWeight::get().writes(3)) } // Storage: `PolkadotXcm::VersionNotifyTargets` (r:0 w:1) @@ -203,127 +195,152 @@ impl WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 4_568_000 picoseconds. - Weight::from_parts(4_764_000, 0) + // Minimum execution time: 4_665_000 picoseconds. + Weight::from_parts(4_827_000, 0) .saturating_add(T::DbWeight::get().writes(1)) } pub fn burn_asset() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 3_953_000 picoseconds. - Weight::from_parts(4_079_000, 0) + // Minimum execution time: 3_898_000 picoseconds. + Weight::from_parts(3_979_000, 0) } pub fn expect_asset() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_793_000 picoseconds. - Weight::from_parts(2_914_000, 0) + // Minimum execution time: 2_550_000 picoseconds. + Weight::from_parts(2_622_000, 0) } pub fn expect_origin() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_719_000 picoseconds. - Weight::from_parts(2_829_000, 0) + // Minimum execution time: 2_472_000 picoseconds. + Weight::from_parts(2_541_000, 0) } pub fn expect_error() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_710_000 picoseconds. - Weight::from_parts(2_824_000, 0) + // Minimum execution time: 2_366_000 picoseconds. + Weight::from_parts(2_420_000, 0) } pub fn expect_transact_status() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_941_000 picoseconds. - Weight::from_parts(3_201_000, 0) + // Minimum execution time: 2_621_000 picoseconds. + Weight::from_parts(2_724_000, 0) } // Storage: `ParachainInfo::ParachainId` (r:1 w:0) // Proof: `ParachainInfo::ParachainId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + // Storage: `ParachainSystem::UpwardDeliveryFeeFactor` (r:1 w:0) + // Proof: `ParachainSystem::UpwardDeliveryFeeFactor` (`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) // 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: `System::Account` (r:2 w:1) + // Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) // 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`) pub fn query_pallet() -> Weight { // Proof Size summary in bytes: - // Measured: `70` - // Estimated: `3535` - // Minimum execution time: 28_080_000 picoseconds. - Weight::from_parts(28_920_000, 3535) - .saturating_add(T::DbWeight::get().reads(6)) - .saturating_add(T::DbWeight::get().writes(2)) - } - pub fn expect_pallet() -> Weight { - // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 4_752_000 picoseconds. - Weight::from_parts(4_982_000, 0) + // Measured: `171` + // Estimated: `6196` + // Minimum execution time: 58_965_000 picoseconds. + Weight::from_parts(60_095_000, 6196) + .saturating_add(T::DbWeight::get().reads(9)) + .saturating_add(T::DbWeight::get().writes(3)) } // Storage: `ParachainInfo::ParachainId` (r:1 w:0) // Proof: `ParachainInfo::ParachainId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + // Storage: `ParachainSystem::UpwardDeliveryFeeFactor` (r:1 w:0) + // Proof: `ParachainSystem::UpwardDeliveryFeeFactor` (`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) // 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: `System::Account` (r:2 w:1) + // Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) // 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`) pub fn report_transact_status() -> Weight { // Proof Size summary in bytes: - // Measured: `70` - // Estimated: `3535` - // Minimum execution time: 24_810_000 picoseconds. - Weight::from_parts(25_270_000, 3535) - .saturating_add(T::DbWeight::get().reads(6)) - .saturating_add(T::DbWeight::get().writes(2)) + // Measured: `171` + // Estimated: `6196` + // Minimum execution time: 54_594_000 picoseconds. + Weight::from_parts(56_039_000, 6196) + .saturating_add(T::DbWeight::get().reads(9)) + .saturating_add(T::DbWeight::get().writes(3)) } pub fn clear_transact_status() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_676_000 picoseconds. - Weight::from_parts(2_780_000, 0) + // Minimum execution time: 2_393_000 picoseconds. + Weight::from_parts(2_465_000, 0) } pub fn set_topic() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_624_000 picoseconds. - Weight::from_parts(2_710_000, 0) + // Minimum execution time: 2_356_000 picoseconds. + Weight::from_parts(2_406_000, 0) } pub fn clear_topic() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_611_000 picoseconds. - Weight::from_parts(2_707_000, 0) + // Minimum execution time: 2_305_000 picoseconds. + Weight::from_parts(2_375_000, 0) + } + // Storage: `ParachainInfo::ParachainId` (r:1 w:0) + // Proof: `ParachainInfo::ParachainId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + // Storage: `BridgeKusamaMessages::PalletOperatingMode` (r:1 w:0) + // Proof: `BridgeKusamaMessages::PalletOperatingMode` (`max_values`: Some(1), `max_size`: Some(2), added: 497, mode: `MaxEncodedLen`) + // Storage: `BridgeKusamaMessages::OutboundLanes` (r:1 w:1) + // Proof: `BridgeKusamaMessages::OutboundLanes` (`max_values`: Some(1), `max_size`: Some(44), added: 539, mode: `MaxEncodedLen`) + // Storage: `BridgeKusamaMessages::OutboundLanesCongestedSignals` (r:1 w:0) + // Proof: `BridgeKusamaMessages::OutboundLanesCongestedSignals` (`max_values`: Some(1), `max_size`: Some(21), added: 516, mode: `MaxEncodedLen`) + // Storage: `BridgeKusamaMessages::OutboundMessages` (r:0 w:1) + // Proof: `BridgeKusamaMessages::OutboundMessages` (`max_values`: None, `max_size`: Some(2621472), added: 2623947, mode: `MaxEncodedLen`) + /// The range of component `x` is `[1, 1000]`. + pub fn export_message(x: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `133` + // Estimated: `1529` + // Minimum execution time: 31_422_000 picoseconds. + Weight::from_parts(33_165_507, 1529) + // Standard Error: 568 + .saturating_add(Weight::from_parts(433_830, 0).saturating_mul(x.into())) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(2)) } pub fn set_fees_mode() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_653_000 picoseconds. - Weight::from_parts(2_740_000, 0) + // Minimum execution time: 2_695_000 picoseconds. + Weight::from_parts(2_770_000, 0) } pub fn unpaid_execution() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_821_000 picoseconds. - Weight::from_parts(2_874_000, 0) + // Minimum execution time: 2_833_000 picoseconds. + Weight::from_parts(2_970_000, 0) } } + +impl WeightInfo { pub fn expect_pallet() -> Weight { Weight::from_parts(5_756_000, 0) } } diff --git a/system-parachains/bridge-hubs/bridge-hub-polkadot/src/xcm_config.rs b/system-parachains/bridge-hubs/bridge-hub-polkadot/src/xcm_config.rs index 472eba4ce7..59a3890e02 100644 --- a/system-parachains/bridge-hubs/bridge-hub-polkadot/src/xcm_config.rs +++ b/system-parachains/bridge-hubs/bridge-hub-polkadot/src/xcm_config.rs @@ -15,6 +15,9 @@ // along with Cumulus. If not, see . use super::{ + bridge_to_kusama_config::{ + DeliveryRewardInBalance, RequiredStakeForStakeAndSlash, ToBridgeHubKusamaHaulBlobExporter, + }, AccountId, AllPalletsWithSystem, Balances, ParachainInfo, ParachainSystem, PolkadotXcm, PriceForParentDelivery, Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin, WeightToFee, XcmpQueue, @@ -48,10 +51,10 @@ use xcm_executor::{traits::WithOriginFilter, XcmExecutor}; parameter_types! { pub const DotRelayLocation: MultiLocation = MultiLocation::parent(); - pub const RelayNetwork: Option = Some(NetworkId::Polkadot); + pub const RelayNetwork: NetworkId = NetworkId::Polkadot; pub RelayChainOrigin: RuntimeOrigin = cumulus_pallet_xcm::Origin::Relay.into(); pub UniversalLocation: InteriorMultiLocation = - X2(GlobalConsensus(RelayNetwork::get().unwrap()), Parachain(ParachainInfo::parachain_id().into())); + X2(GlobalConsensus(RelayNetwork::get()), Parachain(ParachainInfo::parachain_id().into())); pub const MaxInstructions: u32 = 100; pub const MaxAssetsIntoHolding: u32 = 64; pub FellowshipLocation: MultiLocation = MultiLocation::new(1, Parachain(1001)); @@ -142,6 +145,17 @@ impl Contains for SafeCallFilter { } } + // Allow to change dedicated storage items (called by governance-like) + match call { + RuntimeCall::System(frame_system::Call::set_storage { items }) + if items.iter().all(|(k, _)| { + k.eq(&DeliveryRewardInBalance::key()) || + k.eq(&RequiredStakeForStakeAndSlash::key()) + }) => + return true, + _ => (), + }; + matches!( call, RuntimeCall::PolkadotXcm( @@ -165,7 +179,23 @@ impl Contains for SafeCallFilter { pallet_collator_selection::Call::remove_invulnerable { .. }, ) | RuntimeCall::Session(pallet_session::Call::purge_keys { .. }) | RuntimeCall::XcmpQueue(..) | - RuntimeCall::DmpQueue(..) + RuntimeCall::DmpQueue(..) | + RuntimeCall::BridgeKusamaGrandpa(pallet_bridge_grandpa::Call::< + Runtime, + crate::bridge_to_kusama_config::BridgeGrandpaKusamaInstance, + >::initialize { .. }) | + RuntimeCall::BridgeKusamaGrandpa(pallet_bridge_grandpa::Call::< + Runtime, + crate::bridge_to_kusama_config::BridgeGrandpaKusamaInstance, + >::set_operating_mode { .. }) | + RuntimeCall::BridgeKusamaParachains(pallet_bridge_parachains::Call::< + Runtime, + crate::bridge_to_kusama_config::BridgeParachainKusamaInstance, + >::set_operating_mode { .. }) | + RuntimeCall::BridgeKusamaMessages(pallet_bridge_messages::Call::< + Runtime, + crate::bridge_to_kusama_config::WithBridgeHubKusamaMessagesInstance, + >::set_operating_mode { .. }) ) } } @@ -253,7 +283,7 @@ impl xcm_executor::Config for XcmConfig { type AssetLocker = (); type AssetExchanger = (); type FeeManager = XcmFeesToAccount; - type MessageExporter = (); + type MessageExporter = ToBridgeHubKusamaHaulBlobExporter; type UniversalAliases = Nothing; type CallDispatcher = WithOriginFilter; type SafeCallFilter = SafeCallFilter; diff --git a/system-parachains/bridge-hubs/bridge-hub-polkadot/tests/tests.rs b/system-parachains/bridge-hubs/bridge-hub-polkadot/tests/tests.rs index 1529f77025..b5682ec790 100644 --- a/system-parachains/bridge-hubs/bridge-hub-polkadot/tests/tests.rs +++ b/system-parachains/bridge-hubs/bridge-hub-polkadot/tests/tests.rs @@ -14,21 +14,87 @@ // You should have received a copy of the GNU General Public License // along with Cumulus. If not, see . -pub use bridge_hub_polkadot_runtime::{ - xcm_config::XcmConfig, AllPalletsWithoutSystem, Balances, ExistentialDeposit, ParachainSystem, - PolkadotXcm, Runtime, RuntimeEvent, SessionKeys, +use bp_polkadot_core::Signature; +use bridge_hub_polkadot_runtime::{ + bridge_to_kusama_config::{ + BridgeGrandpaKusamaInstance, BridgeHubKusamaChainId, BridgeParachainKusamaInstance, + DeliveryRewardInBalance, KusamaGlobalConsensusNetwork, RefundBridgeHubKusamaMessages, + RequiredStakeForStakeAndSlash, WithBridgeHubKusamaMessageBridge, + WithBridgeHubKusamaMessagesInstance, XCM_LANE_FOR_ASSET_HUB_POLKADOT_TO_ASSET_HUB_KUSAMA, + }, + xcm_config::{DotRelayLocation, RelayNetwork, XcmConfig}, + AllPalletsWithoutSystem, BridgeRejectObsoleteHeadersAndMessages, Executive, ExistentialDeposit, + ParachainSystem, PolkadotXcm, Runtime, RuntimeCall, RuntimeEvent, SessionKeys, SignedExtra, + UncheckedExtrinsic, }; -use codec::Decode; +use codec::{Decode, Encode}; use frame_support::parameter_types; -use parachains_common::{AccountId, AuraId}; -use system_parachains_constants::polkadot::fee::WeightToFee; +use frame_system::pallet_prelude::HeaderFor; +use parachains_common::{polkadot::fee::WeightToFee, AccountId, AuraId, Balance}; +use sp_keyring::AccountKeyring::Alice; +use sp_runtime::{ + generic::{Era, SignedPayload}, + AccountId32, +}; +use xcm::latest::prelude::*; const ALICE: [u8; 32] = [1u8; 32]; +// Para id of sibling chain used in tests. +pub const SIBLING_PARACHAIN_ID: u32 = 1000; + parameter_types! { pub CheckingAccount: AccountId = PolkadotXcm::check_account(); } +fn construct_extrinsic( + sender: sp_keyring::AccountKeyring, + call: RuntimeCall, +) -> UncheckedExtrinsic { + let extra: SignedExtra = ( + frame_system::CheckNonZeroSender::::new(), + frame_system::CheckSpecVersion::::new(), + frame_system::CheckTxVersion::::new(), + frame_system::CheckGenesis::::new(), + frame_system::CheckEra::::from(Era::immortal()), + frame_system::CheckNonce::::from(0), + frame_system::CheckWeight::::new(), + pallet_transaction_payment::ChargeTransactionPayment::::from(0), + BridgeRejectObsoleteHeadersAndMessages, + (RefundBridgeHubKusamaMessages::default()), + ); + let payload = SignedPayload::new(call.clone(), extra.clone()).unwrap(); + let signature = payload.using_encoded(|e| sender.sign(e)); + UncheckedExtrinsic::new_signed( + call, + AccountId32::from(sender.public()).into(), + Signature::Sr25519(signature.clone()), + extra, + ) +} + +fn construct_and_apply_extrinsic( + relayer_at_target: sp_keyring::AccountKeyring, + batch: pallet_utility::Call, +) -> sp_runtime::DispatchOutcome { + let batch_call = RuntimeCall::Utility(batch); + let xt = construct_extrinsic(relayer_at_target, batch_call); + let r = Executive::apply_extrinsic(xt); + r.unwrap() +} + +fn executive_init_block(header: &HeaderFor) { + Executive::initialize_block(header) +} + +fn collator_session_keys() -> bridge_hub_test_utils::CollatorSessionKeys { + bridge_hub_test_utils::CollatorSessionKeys::new( + AccountId::from(Alice), + AccountId::from(Alice), + SessionKeys { aura: AuraId::from(Alice.public()) }, + ) +} + bridge_hub_test_utils::test_cases::include_teleports_for_native_asset_works!( Runtime, AllPalletsWithoutSystem, @@ -56,3 +122,191 @@ bridge_hub_test_utils::test_cases::include_teleports_for_native_asset_works!( }), 1002 ); + +#[test] +fn initialize_bridge_by_governance_works() { + bridge_hub_test_utils::test_cases::initialize_bridge_by_governance_works::< + Runtime, + BridgeGrandpaKusamaInstance, + >( + collator_session_keys(), + bp_bridge_hub_polkadot::BRIDGE_HUB_POLKADOT_PARACHAIN_ID, + Box::new(|call| RuntimeCall::BridgeKusamaGrandpa(call).encode()), + ) +} + +#[test] +fn change_delivery_reward_by_governance_works() { + bridge_hub_test_utils::test_cases::change_storage_constant_by_governance_works::< + Runtime, + DeliveryRewardInBalance, + Balance, + >( + collator_session_keys(), + bp_bridge_hub_polkadot::BRIDGE_HUB_POLKADOT_PARACHAIN_ID, + Box::new(|call| RuntimeCall::System(call).encode()), + || (DeliveryRewardInBalance::key().to_vec(), DeliveryRewardInBalance::get()), + |old_value| old_value.checked_mul(2).unwrap(), + ) +} + +#[test] +fn change_required_stake_by_governance_works() { + bridge_hub_test_utils::test_cases::change_storage_constant_by_governance_works::< + Runtime, + RequiredStakeForStakeAndSlash, + Balance, + >( + collator_session_keys(), + bp_bridge_hub_polkadot::BRIDGE_HUB_POLKADOT_PARACHAIN_ID, + Box::new(|call| RuntimeCall::System(call).encode()), + || (RequiredStakeForStakeAndSlash::key().to_vec(), RequiredStakeForStakeAndSlash::get()), + |old_value| old_value.checked_mul(2).unwrap(), + ) +} + +#[test] +fn handle_export_message_from_system_parachain_add_to_outbound_queue_works() { + bridge_hub_test_utils::test_cases::handle_export_message_from_system_parachain_to_outbound_queue_works::< + Runtime, + XcmConfig, + WithBridgeHubKusamaMessagesInstance, + >( + collator_session_keys(), + bp_bridge_hub_polkadot::BRIDGE_HUB_POLKADOT_PARACHAIN_ID, + SIBLING_PARACHAIN_ID, + Box::new(|runtime_event_encoded: Vec| { + match RuntimeEvent::decode(&mut &runtime_event_encoded[..]) { + Ok(RuntimeEvent::BridgeKusamaMessages(event)) => Some(event), + _ => None, + } + }), + || ExportMessage { network: Kusama, destination: X1(Parachain(4321)), xcm: Xcm(vec![]) }, + XCM_LANE_FOR_ASSET_HUB_POLKADOT_TO_ASSET_HUB_KUSAMA, + Some((DotRelayLocation::get(), ExistentialDeposit::get()).into()), + // value should be >= than value generated by `can_calculate_weight_for_paid_export_message_with_reserve_transfer` + Some((DotRelayLocation::get(), bp_bridge_hub_polkadot::BridgeHubPolkadotBaseXcmFeeInDots::get()).into()), + || (), + ) +} + +#[test] +fn message_dispatch_routing_works() { + bridge_hub_test_utils::test_cases::message_dispatch_routing_works::< + Runtime, + AllPalletsWithoutSystem, + XcmConfig, + ParachainSystem, + WithBridgeHubKusamaMessagesInstance, + RelayNetwork, + KusamaGlobalConsensusNetwork, + >( + collator_session_keys(), + bp_bridge_hub_polkadot::BRIDGE_HUB_POLKADOT_PARACHAIN_ID, + SIBLING_PARACHAIN_ID, + Box::new(|runtime_event_encoded: Vec| { + match RuntimeEvent::decode(&mut &runtime_event_encoded[..]) { + Ok(RuntimeEvent::ParachainSystem(event)) => Some(event), + _ => None, + } + }), + Box::new(|runtime_event_encoded: Vec| { + match RuntimeEvent::decode(&mut &runtime_event_encoded[..]) { + Ok(RuntimeEvent::XcmpQueue(event)) => Some(event), + _ => None, + } + }), + XCM_LANE_FOR_ASSET_HUB_POLKADOT_TO_ASSET_HUB_KUSAMA, + || (), + ) +} + +#[test] +fn relayed_incoming_message_works() { + bridge_hub_test_utils::test_cases::relayed_incoming_message_works::< + Runtime, + AllPalletsWithoutSystem, + XcmConfig, + ParachainSystem, + BridgeGrandpaKusamaInstance, + BridgeParachainKusamaInstance, + WithBridgeHubKusamaMessagesInstance, + WithBridgeHubKusamaMessageBridge, + >( + collator_session_keys(), + bp_bridge_hub_polkadot::BRIDGE_HUB_POLKADOT_PARACHAIN_ID, + bp_bridge_hub_kusama::BRIDGE_HUB_KUSAMA_PARACHAIN_ID, + SIBLING_PARACHAIN_ID, + Polkadot, + XCM_LANE_FOR_ASSET_HUB_POLKADOT_TO_ASSET_HUB_KUSAMA, + || (), + ) +} + +#[test] +pub fn complex_relay_extrinsic_works() { + bridge_hub_test_utils::test_cases::complex_relay_extrinsic_works::< + Runtime, + AllPalletsWithoutSystem, + XcmConfig, + ParachainSystem, + BridgeGrandpaKusamaInstance, + BridgeParachainKusamaInstance, + WithBridgeHubKusamaMessagesInstance, + WithBridgeHubKusamaMessageBridge, + >( + collator_session_keys(), + bp_bridge_hub_polkadot::BRIDGE_HUB_POLKADOT_PARACHAIN_ID, + bp_bridge_hub_kusama::BRIDGE_HUB_KUSAMA_PARACHAIN_ID, + SIBLING_PARACHAIN_ID, + BridgeHubKusamaChainId::get(), + Polkadot, + XCM_LANE_FOR_ASSET_HUB_POLKADOT_TO_ASSET_HUB_KUSAMA, + ExistentialDeposit::get(), + executive_init_block, + construct_and_apply_extrinsic, + || (), + ); +} + +#[test] +pub fn can_calculate_weight_for_paid_export_message_with_reserve_transfer() { + let estimated = bridge_hub_test_utils::test_cases::can_calculate_weight_for_paid_export_message_with_reserve_transfer::< + Runtime, + XcmConfig, + WeightToFee, + >(); + + // check if estimated value is sane + let max_expected = bp_bridge_hub_polkadot::BridgeHubPolkadotBaseXcmFeeInDots::get(); + assert!( + estimated <= max_expected, + "calculated: {:?}, max_expected: {:?}, please adjust `bp_bridge_hub_polkadot::BridgeHubPolkadotBaseXcmFeeInDots` value", + estimated, + max_expected + ); +} + +// TODO: replace me with direct usages of `bridge_hub_test_utils` after deps are bumped to (at +// least) 1.4 +// +// Following two tests have to be implemented properly after upgrade to 1.6. +// See https://github.com/paritytech/polkadot-sdk/pull/2139/ and https://github.com/paritytech/parity-bridges-common/pull/2728 +// for impl details +// +// Until that, anyone can run it manually by doing following: +// +// 1) cargo vendor ../vendored-dependencies +// 2) apply relevant changes from above PRs +// 3) change workspace Cargo.toml: +// [patch.crates-io] +// bp-polkadot-core = { path = "../vendored-dependencies/bp-polkadot-core" } +// bridge-hub-test-utils = { path = "../vendored-dependencies/bridge-hub-test-utils" } +// bridge-runtime-common = { path = "../vendored-dependencies/bridge-runtime-common" } +// 4) add actual tests code and do `cargo test -p bridge-hub-polkadot-runtime` + +#[test] +pub fn can_calculate_fee_for_complex_message_delivery_transaction() {} + +#[test] +pub fn can_calculate_fee_for_complex_message_confirmation_transaction() {}