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>,
+