Skip to content
This repository has been archived by the owner on Nov 15, 2023. It is now read-only.

Commit

Permalink
Adding paid xcm bridge hub router to AssetHubPolkadot
Browse files Browse the repository at this point in the history
  • Loading branch information
bkontur committed Aug 14, 2023
1 parent 025f109 commit af0a0c3
Show file tree
Hide file tree
Showing 6 changed files with 85 additions and 10 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -482,7 +482,7 @@ type LocalXcmRouter = (
/// queues.
pub type XcmRouter = WithUniqueTopic<(
LocalXcmRouter,
// Router, which wraps and sends xcm to BridgeHub to be delivered to the Polkadot GlobalConsensus
// Router which wraps and sends xcm to BridgeHub to be delivered to the Polkadot GlobalConsensus
ToPolkadotXcmRouter,
)>;

Expand Down
8 changes: 7 additions & 1 deletion parachains/runtimes/assets/asset-hub-polkadot/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ cumulus-pallet-dmp-queue = { path = "../../../../pallets/dmp-queue", default-fea
cumulus-pallet-parachain-system = { path = "../../../../pallets/parachain-system", default-features = false }
cumulus-pallet-session-benchmarking = { path = "../../../../pallets/session-benchmarking", default-features = false, version = "3.0.0" }
cumulus-pallet-xcm = { path = "../../../../pallets/xcm", default-features = false }
cumulus-pallet-xcmp-queue = { path = "../../../../pallets/xcmp-queue", default-features = false }
cumulus-pallet-xcmp-queue = { path = "../../../../pallets/xcmp-queue", default-features = false, features = ["bridging"] }
cumulus-primitives-core = { path = "../../../../primitives/core", default-features = false }
cumulus-primitives-timestamp = { path = "../../../../primitives/timestamp", default-features = false }
cumulus-primitives-utility = { path = "../../../../primitives/utility", default-features = false }
Expand All @@ -74,6 +74,9 @@ parachain-info = { path = "../../../pallets/parachain-info", default-features =
parachains-common = { path = "../../../common", default-features = false }
assets-common = { path = "../common", default-features = false }

# Bridges
pallet-xcm-bridge-hub-router = { path = "../../../../bridges/modules/xcm-bridge-hub-router", default-features = false }

[dev-dependencies]
hex-literal = "0.4.1"
asset-test-utils = { path = "../test-utils"}
Expand Down Expand Up @@ -107,6 +110,7 @@ runtime-benchmarks = [
"cumulus-pallet-xcmp-queue/runtime-benchmarks",
"pallet-xcm-benchmarks/runtime-benchmarks",
"assets-common/runtime-benchmarks",
"pallet-xcm-bridge-hub-router/runtime-benchmarks",
]
try-runtime = [
"cumulus-pallet-aura-ext/try-runtime",
Expand All @@ -133,6 +137,7 @@ try-runtime = [
"pallet-utility/try-runtime",
"pallet-xcm/try-runtime",
"parachain-info/try-runtime",
"pallet-xcm-bridge-hub-router/try-runtime",
]
std = [
"codec/std",
Expand Down Expand Up @@ -188,5 +193,6 @@ std = [
"parachain-info/std",
"parachains-common/std",
"assets-common/std",
"pallet-xcm-bridge-hub-router/std",
"substrate-wasm-builder",
]
24 changes: 24 additions & 0 deletions parachains/runtimes/assets/asset-hub-polkadot/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -720,6 +720,27 @@ 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_assets::Instance1;
impl pallet_xcm_bridge_hub_router::Config<ToKusamaXcmRouterInstance> for Runtime {
type WeightInfo = (); // TODO: proper weights

type UniversalLocation = xcm_config::UniversalLocation;
type BridgedNetworkId = xcm_config::bridging::KusamaNetwork;
type Bridges = xcm_config::bridging::FilteredNetworkExportTable;

type BridgeHubOrigin = EnsureXcm<Equals<xcm_config::bridging::BridgeHubPolkadot>>;
type ToBridgeHubSender = XcmpQueue;
type WithBridgeHubChannel =
cumulus_pallet_xcmp_queue::bridging::InboundAndOutboundXcmpChannelCongestionStatusProvider<
xcm_config::bridging::BridgeHubPolkadotParaId,
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
Expand Down Expand Up @@ -756,6 +777,9 @@ construct_runtime!(
Multisig: pallet_multisig::{Pallet, Call, Storage, Event<T>} = 41,
Proxy: pallet_proxy::{Pallet, Call, Storage, Event<T>} = 42,

// Bridge utilities.
ToPolkadotXcmRouter: pallet_xcm_bridge_hub_router::<Instance1>::{Pallet, Storage, Call} = 43,

// The main stage.
Assets: pallet_assets::<Instance1>::{Pallet, Call, Storage, Event<T>} = 50,
Uniques: pallet_uniques::{Pallet, Call, Storage, Event<T>} = 51,
Expand Down
32 changes: 25 additions & 7 deletions parachains/runtimes/assets/asset-hub-polkadot/src/xcm_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
use super::{
AccountId, AllPalletsWithSystem, Assets, Authorship, Balance, Balances, ForeignAssets,
ParachainInfo, ParachainSystem, PolkadotXcm, Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin,
TrustBackedAssetsInstance, WeightToFee, XcmpQueue,
ToKusamaXcmRouter, TransactionByteFee, TrustBackedAssetsInstance, WeightToFee, XcmpQueue,
};
use crate::ForeignAssetsInstance;
use assets_common::matching::{
Expand Down Expand Up @@ -207,6 +207,14 @@ impl Contains<RuntimeCall> 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().any(|(k, _)| k.eq(&bridging::XcmBridgeHubRouterByteFee::key())) =>
return true,
_ => (),
};

matches!(
call,
RuntimeCall::PolkadotXcm(pallet_xcm::Call::force_xcm_version { .. }) |
Expand Down Expand Up @@ -460,6 +468,7 @@ impl xcm_executor::Config for XcmConfig {
type MaxAssetsIntoHolding = MaxAssetsIntoHolding;
type AssetLocker = ();
type AssetExchanger = ();
// TODO:check-parameter: change and assert in tests when (https://github.com/paritytech/polkadot/pull/7005) merged
type FeeManager = ();
type MessageExporter = ();
type UniversalAliases = bridging::UniversalAliases;
Expand All @@ -482,7 +491,11 @@ type LocalXcmRouter = (

/// The means for routing XCM messages which are not for local execution into the right message
/// queues.
pub type XcmRouter = WithUniqueTopic<(LocalXcmRouter, bridging::BridgingXcmRouter)>;
pub type XcmRouter = WithUniqueTopic<(
LocalXcmRouter,
// Router which wraps and sends XCM to BridgeHub to be delivered to the Kusama GlobalConsensus
ToKusamaXcmRouter,
)>;

#[cfg(feature = "runtime-benchmarks")]
parameter_types! {
Expand Down Expand Up @@ -577,7 +590,14 @@ pub mod bridging {
pub AssetHubKusama: MultiLocation = MultiLocation::new(2, X2(GlobalConsensus(KusamaNetwork::get()), Parachain(1000)));
pub KsmLocation: MultiLocation = MultiLocation::new(2, X1(GlobalConsensus(KusamaNetwork::get())));

/// Router expects payment with this `AssetId`.
/// (`AssetId` has to be aligned with `BridgeTable`)
pub XcmBridgeHubRouterFeeAssetId: AssetId = DotLocation::get().into();
/// Price per byte - can be adjusted via governance `set_storage` call.
pub storage XcmBridgeHubRouterByteFee: Balance = TransactionByteFee::get();

/// Set up exporters configuration.
/// `Option<MultiAsset>` represents static "base fee" which is used for total delivery fee calculation.
pub BridgeTable: sp_std::vec::Vec<(NetworkId, LocationFilter<InteriorMultiLocation>, MultiLocation, Option<MultiAsset>)> = sp_std::vec![
(
KusamaNetwork::get(),
Expand All @@ -586,7 +606,9 @@ pub mod bridging {
.add_equals(AssetHubKusama::get().interior.split_global().expect("invalid configuration for AssetHubKusama").1),
// and nothing else
BridgeHubPolkadot::get(),
None
// base delivery fee to local `BridgeHub`
// (initially was calculated `51220000` + 10% by test `BridgeHubPolkadot::can_calculate_weight_for_paid_export_message_with_reserve_transfer`)
Some((XcmBridgeHubRouterFeeAssetId::get(), 56342000).into())
)
];

Expand Down Expand Up @@ -637,10 +659,6 @@ pub mod bridging {
pub type FilteredNetworkExportTable =
parachains_common::xcm_config::FilteredNetworkExportTable<BridgeTable>;

/// Bridge router, which wraps and sends xcm to BridgeHub to be delivered to the different GlobalConsensus
pub type BridgingXcmRouter =
UnpaidRemoteExporter<FilteredNetworkExportTable, LocalXcmRouter, UniversalLocation>;

/// Reserve locations filter for `xcm_executor::Config::IsReserve`.
pub type IsTrustedBridgedReserveLocationForConcreteAsset =
matching::IsTrustedBridgedReserveLocationForConcreteAsset<
Expand Down
28 changes: 27 additions & 1 deletion parachains/runtimes/assets/asset-hub-polkadot/tests/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -692,7 +692,7 @@ fn limited_reserve_transfer_assets_for_native_asset_over_bridge_works() {
}),
bridging_to_asset_hub_kusama,
WeightLimit::Unlimited,
None,
Some(xcm_config::bridging::XcmBridgeHubRouterFeeAssetId::get()),
)
}

Expand Down Expand Up @@ -799,3 +799,29 @@ fn xcm_reserve_transfer_filter_works() {
}
})
}

#[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()
}
},
)
}

0 comments on commit af0a0c3

Please sign in to comment.