Skip to content

Commit 4af6519

Browse files
bkonturacatangiusvyatonikserban300
committed
Extended Kusama/Polkadot BridgeHub with dynamic fees and congestion support
Add congestion detection to the Bridge Hub runtimes and report congestion status to the sending chain. Bridge Hub's `ExportMessage` handling is extended with check if outbound message queue is congested, if so then `CongestedMessage` signal is sent to the sending chain's relevant `pallet-xcm-bridge-hub-router` pallet instance, where dynamic fees factor is processed. When then same Bridge Hub receives message delivery confirmation, there is a another check is outbound queue is still congested, if not then `UncongestedMessage` signal is sent to the sending chain's relevant `pallet-xcm-bridge-hub-router` pallet instance. `pallet-bridge-messages`'s `receive_messages_proof` does another check for congestion or back-preassure with checking status of underlaying XCMP queue (`cumulus_pallet_xcmp_queue::bridging::OutboundXcmpChannelCongestionStatusProvider`). If we cannot deliver a message to the target, then `receive_messages_proof` returns error and Bridge Hub does not allow to receive new bridged messages. More about congestion detection [here](paritytech/parity-bridges-common#2318). Signed-off-by: Branislav Kontur <[email protected]> Signed-off-by: Adrian Catangiu <[email protected]> Signed-off-by: Svyatoslav Nikolsky <[email protected]> Signed-off-by: Serban Iorga <[email protected]> Co-authored-by: Adrian Catangiu <[email protected]> Co-authored-by: Svyatoslav Nikolsky <[email protected]> Co-authored-by: Serban Iorga <[email protected]>
1 parent 945ea7f commit 4af6519

File tree

15 files changed

+299
-53
lines changed

15 files changed

+299
-53
lines changed

Cargo.lock

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

cumulus/pallets/xcmp-queue/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ cumulus-pallet-parachain-system = { path = "../parachain-system" }
4646
[features]
4747
default = [ "std" ]
4848
std = [
49-
"bp-xcm-bridge-hub-router/std",
49+
"bp-xcm-bridge-hub-router?/std",
5050
"codec/std",
5151
"cumulus-primitives-core/std",
5252
"frame-benchmarking?/std",

cumulus/parachains/runtimes/bridge-hubs/bridge-hub-kusama/Cargo.toml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,14 +64,15 @@ cumulus-pallet-dmp-queue = { path = "../../../../pallets/dmp-queue", default-fea
6464
cumulus-pallet-parachain-system = { path = "../../../../pallets/parachain-system", default-features = false, features = ["parameterized-consensus-hook",] }
6565
cumulus-pallet-session-benchmarking = { path = "../../../../pallets/session-benchmarking", default-features = false}
6666
cumulus-pallet-xcm = { path = "../../../../pallets/xcm", default-features = false }
67-
cumulus-pallet-xcmp-queue = { path = "../../../../pallets/xcmp-queue", default-features = false }
67+
cumulus-pallet-xcmp-queue = { path = "../../../../pallets/xcmp-queue", default-features = false, features = ["bridging"] }
6868
cumulus-primitives-core = { path = "../../../../primitives/core", default-features = false }
6969
cumulus-primitives-utility = { path = "../../../../primitives/utility", default-features = false }
7070
pallet-collator-selection = { path = "../../../../pallets/collator-selection", default-features = false }
7171
parachain-info = { path = "../../../pallets/parachain-info", default-features = false }
7272
parachains-common = { path = "../../../common", default-features = false }
7373

7474
# Bridges
75+
bp-asset-hub-kusama = { path = "../../../../bridges/primitives/chain-asset-hub-kusama", default-features = false }
7576
bp-bridge-hub-kusama = { path = "../../../../bridges/primitives/chain-bridge-hub-kusama", default-features = false }
7677
bp-bridge-hub-polkadot = { path = "../../../../bridges/primitives/chain-bridge-hub-polkadot", default-features = false }
7778
bp-header-chain = { path = "../../../../bridges/primitives/header-chain", default-features = false }
@@ -97,6 +98,7 @@ sp-keyring = { path = "../../../../../substrate/primitives/keyring" }
9798
[features]
9899
default = [ "std" ]
99100
std = [
101+
"bp-asset-hub-kusama/std",
100102
"bp-bridge-hub-kusama/std",
101103
"bp-bridge-hub-polkadot/std",
102104
"bp-header-chain/std",

cumulus/parachains/runtimes/bridge-hubs/bridge-hub-kusama/src/bridge_hub_config.rs

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ use bridge_runtime_common::{
3333
RefundableParachain,
3434
},
3535
};
36+
use codec::Encode;
3637
use frame_support::{parameter_types, traits::PalletInfoAccess};
3738
use sp_runtime::RuntimeDebug;
3839
use xcm::{latest::prelude::*, prelude::NetworkId};
@@ -55,6 +56,28 @@ parameter_types! {
5556
ParentThen(X1(Parachain(AssetHubKusamaParaId::get().into()))).into(),
5657
ASSET_HUB_KUSAMA_TO_ASSET_HUB_POLKADOT_LANE_ID,
5758
);
59+
60+
pub CongestedMessage: Xcm<()> = sp_std::vec![Transact {
61+
origin_kind: OriginKind::Xcm,
62+
require_weight_at_most: bp_asset_hub_kusama::XcmBridgeHubRouterTransactCallMaxWeight::get(),
63+
call: bp_asset_hub_kusama::Call::ToPolkadotXcmRouter(
64+
bp_asset_hub_kusama::XcmBridgeHubRouterCall::report_bridge_status {
65+
bridge_id: Default::default(),
66+
is_congested: true,
67+
}
68+
).encode().into(),
69+
}].into();
70+
71+
pub UncongestedMessage: Xcm<()> = sp_std::vec![Transact {
72+
origin_kind: OriginKind::Xcm,
73+
require_weight_at_most: bp_asset_hub_kusama::XcmBridgeHubRouterTransactCallMaxWeight::get(),
74+
call: bp_asset_hub_kusama::Call::ToPolkadotXcmRouter(
75+
bp_asset_hub_kusama::XcmBridgeHubRouterCall::report_bridge_status {
76+
bridge_id: Default::default(),
77+
is_congested: false,
78+
}
79+
).encode().into(),
80+
}].into();
5881
}
5982

6083
/// Proof of messages, coming from BridgeHubPolkadot.
@@ -81,10 +104,13 @@ impl XcmBlobHauler for ToBridgeHubPolkadotXcmBlobHauler {
81104
type SenderAndLane = FromAssetHubKusamaToAssetHubPolkadotRoute;
82105

83106
type ToSourceChainSender = crate::XcmRouter;
84-
type CongestedMessage = ();
85-
type UncongestedMessage = ();
107+
type CongestedMessage = CongestedMessage;
108+
type UncongestedMessage = UncongestedMessage;
86109
}
87110

111+
/// On messages delivered callback.
112+
pub type OnMessagesDelivered = XcmBlobHaulerAdapter<ToBridgeHubPolkadotXcmBlobHauler>;
113+
88114
/// Messaging Bridge configuration for ThisChain -> BridgeHubPolkadot
89115
pub struct WithBridgeHubPolkadotMessageBridge;
90116
impl MessageBridge for WithBridgeHubPolkadotMessageBridge {

cumulus/parachains/runtimes/bridge-hubs/bridge-hub-kusama/src/lib.rs

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -493,9 +493,15 @@ impl pallet_bridge_messages::Config<WithBridgeHubPolkadotMessagesInstance> for R
493493
DeliveryRewardInBalance,
494494
>;
495495
type SourceHeaderChain = SourceHeaderChainAdapter<WithBridgeHubPolkadotMessageBridge>;
496-
type MessageDispatch =
497-
XcmBlobMessageDispatch<OnThisChainBlobDispatcher<UniversalLocation>, Self::WeightInfo, ()>;
498-
type OnMessagesDelivered = ();
496+
type MessageDispatch = XcmBlobMessageDispatch<
497+
OnThisChainBlobDispatcher<UniversalLocation>,
498+
Self::WeightInfo,
499+
cumulus_pallet_xcmp_queue::bridging::OutboundXcmpChannelCongestionStatusProvider<
500+
bridge_hub_config::AssetHubKusamaParaId,
501+
Runtime,
502+
>,
503+
>;
504+
type OnMessagesDelivered = bridge_hub_config::OnMessagesDelivered;
499505
}
500506

501507
/// Allows collect and claim rewards for relayers
@@ -942,7 +948,11 @@ impl_runtime_apis! {
942948
type XcmBalances = pallet_xcm_benchmarks::fungible::Pallet::<Runtime>;
943949
type XcmGeneric = pallet_xcm_benchmarks::generic::Pallet::<Runtime>;
944950

945-
use bridge_runtime_common::messages_benchmarking::{prepare_message_delivery_proof_from_parachain, prepare_message_proof_from_parachain};
951+
use bridge_runtime_common::messages_benchmarking::{
952+
generate_xcm_builder_bridge_message_sample,
953+
prepare_message_delivery_proof_from_parachain,
954+
prepare_message_proof_from_parachain
955+
};
946956
use pallet_bridge_messages::benchmarking::{
947957
Config as BridgeMessagesConfig,
948958
Pallet as BridgeMessagesBench,
@@ -972,7 +982,7 @@ impl_runtime_apis! {
972982
Runtime,
973983
BridgeGrandpaPolkadotInstance,
974984
bridge_hub_config::WithBridgeHubPolkadotMessageBridge,
975-
>(params, X2(GlobalConsensus(xcm_config::RelayNetwork::get().unwrap()), Parachain(42)))
985+
>(params, generate_xcm_builder_bridge_message_sample(X2(GlobalConsensus(xcm_config::RelayNetwork::get().unwrap()), Parachain(42))))
976986
}
977987
fn prepare_message_delivery_proof(
978988
params: MessageDeliveryProofParams<AccountId>,

cumulus/parachains/runtimes/bridge-hubs/bridge-hub-kusama/src/xcm_config.rs

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -112,12 +112,6 @@ match_types! {
112112
MultiLocation { parents: 1, interior: Here } |
113113
MultiLocation { parents: 1, interior: X1(_) }
114114
};
115-
// TODO:check-parameter - (https://github.com/paritytech/parity-bridges-common/issues/2084)
116-
// remove this and extend `AllowExplicitUnpaidExecutionFrom` with "or SystemParachains" once merged https://github.com/paritytech/polkadot/pull/7005
117-
pub type SystemParachains: impl Contains<MultiLocation> = {
118-
// Statemine
119-
MultiLocation { parents: 1, interior: X1(Parachain(1000)) }
120-
};
121115
}
122116

123117
/// A call filter for the XCM Transact instruction. This is a temporary measure until we properly
@@ -191,9 +185,8 @@ pub type Barrier = TrailingSetTopicAsId<
191185
// If the message is one that immediately attemps to pay for execution, then
192186
// allow it.
193187
AllowTopLevelPaidExecutionFrom<Everything>,
194-
// Parent, its pluralities (i.e. governance bodies) and system parachains get
195-
// free execution.
196-
AllowExplicitUnpaidExecutionFrom<(ParentOrParentsPlurality, SystemParachains)>,
188+
// Parent and its pluralities (i.e. governance bodies) get free execution.
189+
AllowExplicitUnpaidExecutionFrom<(ParentOrParentsPlurality,)>,
197190
// Subscriptions for version tracking are OK.
198191
AllowSubscriptionsFrom<ParentOrSiblings>,
199192
),

cumulus/parachains/runtimes/bridge-hubs/bridge-hub-kusama/tests/tests.rs

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
use bp_polkadot_core::Signature;
1818
pub use bridge_hub_kusama_runtime::{
1919
bridge_hub_config,
20-
xcm_config::{RelayNetwork, XcmConfig},
20+
xcm_config::{KsmRelayLocation, RelayNetwork, XcmConfig},
2121
AllPalletsWithoutSystem, Balances, BridgeGrandpaPolkadotInstance,
2222
BridgeRejectObsoleteHeadersAndMessages, ExistentialDeposit, ParachainSystem, PolkadotXcm,
2323
Runtime, RuntimeCall, RuntimeEvent, SessionKeys, WithBridgeHubPolkadotMessagesInstance,
@@ -183,7 +183,10 @@ fn handle_export_message_from_system_parachain_add_to_outbound_queue_works() {
183183
}
184184
}),
185185
|| ExportMessage { network: Polkadot, destination: X1(Parachain(1234)), xcm: Xcm(vec![]) },
186-
bridge_hub_config::ASSET_HUB_KUSAMA_TO_ASSET_HUB_POLKADOT_LANE_ID
186+
bridge_hub_config::ASSET_HUB_KUSAMA_TO_ASSET_HUB_POLKADOT_LANE_ID,
187+
Some((KsmRelayLocation::get(), ExistentialDeposit::get()).into()),
188+
// value should be >= than value generated by `can_calculate_weight_for_paid_export_message_with_reserve_transfer`
189+
Some((KsmRelayLocation::get(), bp_asset_hub_kusama::BridgeHubKusamaBaseFeeInDots::get()).into()),
187190
)
188191
}
189192

@@ -262,3 +265,21 @@ pub fn complex_relay_extrinsic_works() {
262265
construct_and_apply_extrinsic,
263266
);
264267
}
268+
269+
#[test]
270+
pub fn can_calculate_weight_for_paid_export_message_with_reserve_transfer() {
271+
let estimated = bridge_hub_test_utils::test_cases::can_calculate_weight_for_paid_export_message_with_reserve_transfer::<
272+
Runtime,
273+
XcmConfig,
274+
WeightToFee,
275+
>();
276+
277+
// check if estimated value is sane
278+
let max_expected = bp_asset_hub_kusama::BridgeHubKusamaBaseFeeInDots::get();
279+
assert!(
280+
estimated <= max_expected,
281+
"calculated: {:?}, max_expected: {:?}, please adjust `bp_asset_hub_kusama::BridgeHubKusamaBaseFeeInDots` value",
282+
estimated,
283+
max_expected
284+
);
285+
}

cumulus/parachains/runtimes/bridge-hubs/bridge-hub-polkadot/Cargo.toml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,14 +64,15 @@ cumulus-pallet-dmp-queue = { path = "../../../../pallets/dmp-queue", default-fea
6464
cumulus-pallet-parachain-system = { path = "../../../../pallets/parachain-system", default-features = false, features = ["parameterized-consensus-hook",] }
6565
cumulus-pallet-session-benchmarking = { path = "../../../../pallets/session-benchmarking", default-features = false}
6666
cumulus-pallet-xcm = { path = "../../../../pallets/xcm", default-features = false }
67-
cumulus-pallet-xcmp-queue = { path = "../../../../pallets/xcmp-queue", default-features = false }
67+
cumulus-pallet-xcmp-queue = { path = "../../../../pallets/xcmp-queue", default-features = false, features = ["bridging"] }
6868
cumulus-primitives-core = { path = "../../../../primitives/core", default-features = false }
6969
cumulus-primitives-utility = { path = "../../../../primitives/utility", default-features = false }
7070
pallet-collator-selection = { path = "../../../../pallets/collator-selection", default-features = false }
7171
parachain-info = { path = "../../../pallets/parachain-info", default-features = false }
7272
parachains-common = { path = "../../../common", default-features = false }
7373

7474
# Bridges
75+
bp-asset-hub-polkadot = { path = "../../../../bridges/primitives/chain-asset-hub-polkadot", default-features = false }
7576
bp-bridge-hub-kusama = { path = "../../../../bridges/primitives/chain-bridge-hub-kusama", default-features = false }
7677
bp-bridge-hub-polkadot = { path = "../../../../bridges/primitives/chain-bridge-hub-polkadot", default-features = false }
7778
bp-header-chain = { path = "../../../../bridges/primitives/header-chain", default-features = false }
@@ -97,6 +98,7 @@ sp-keyring = { path = "../../../../../substrate/primitives/keyring" }
9798
[features]
9899
default = [ "std" ]
99100
std = [
101+
"bp-asset-hub-polkadot/std",
100102
"bp-bridge-hub-kusama/std",
101103
"bp-bridge-hub-polkadot/std",
102104
"bp-header-chain/std",

cumulus/parachains/runtimes/bridge-hubs/bridge-hub-polkadot/src/bridge_hub_config.rs

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ use bridge_runtime_common::{
3333
RefundableParachain,
3434
},
3535
};
36+
use codec::Encode;
3637
use frame_support::{parameter_types, traits::PalletInfoAccess};
3738
use sp_runtime::RuntimeDebug;
3839
use xcm::{latest::prelude::*, prelude::NetworkId};
@@ -55,6 +56,28 @@ parameter_types! {
5556
ParentThen(X1(Parachain(AssetHubPolkadotParaId::get().into()))).into(),
5657
ASSET_HUB_POLKADOT_TO_ASSET_HUB_KUSAMA_LANE_ID,
5758
);
59+
60+
pub CongestedMessage: Xcm<()> = sp_std::vec![Transact {
61+
origin_kind: OriginKind::Xcm,
62+
require_weight_at_most: bp_asset_hub_polkadot::XcmBridgeHubRouterTransactCallMaxWeight::get(),
63+
call: bp_asset_hub_polkadot::Call::ToKusamaXcmRouter(
64+
bp_asset_hub_polkadot::XcmBridgeHubRouterCall::report_bridge_status {
65+
bridge_id: Default::default(),
66+
is_congested: true,
67+
}
68+
).encode().into(),
69+
}].into();
70+
71+
pub UncongestedMessage: Xcm<()> = sp_std::vec![Transact {
72+
origin_kind: OriginKind::Xcm,
73+
require_weight_at_most: bp_asset_hub_polkadot::XcmBridgeHubRouterTransactCallMaxWeight::get(),
74+
call: bp_asset_hub_polkadot::Call::ToKusamaXcmRouter(
75+
bp_asset_hub_polkadot::XcmBridgeHubRouterCall::report_bridge_status {
76+
bridge_id: Default::default(),
77+
is_congested: false,
78+
}
79+
).encode().into(),
80+
}].into();
5881
}
5982

6083
/// Proof of messages, coming from BridgeHubKusama.
@@ -81,10 +104,13 @@ impl XcmBlobHauler for ToBridgeHubKusamaXcmBlobHauler {
81104
type SenderAndLane = FromAssetHubPolkadotToAssetHubKusamaRoute;
82105

83106
type ToSourceChainSender = crate::XcmRouter;
84-
type CongestedMessage = ();
85-
type UncongestedMessage = ();
107+
type CongestedMessage = CongestedMessage;
108+
type UncongestedMessage = UncongestedMessage;
86109
}
87110

111+
/// On messages delivered callback.
112+
pub type OnMessagesDelivered = XcmBlobHaulerAdapter<ToBridgeHubKusamaXcmBlobHauler>;
113+
88114
/// Messaging Bridge configuration for ThisChain -> BridgeHubKusama
89115
pub struct WithBridgeHubKusamaMessageBridge;
90116
impl MessageBridge for WithBridgeHubKusamaMessageBridge {

cumulus/parachains/runtimes/bridge-hubs/bridge-hub-polkadot/src/lib.rs

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -494,9 +494,15 @@ impl pallet_bridge_messages::Config<WithBridgeHubKusamaMessagesInstance> for Run
494494
DeliveryRewardInBalance,
495495
>;
496496
type SourceHeaderChain = SourceHeaderChainAdapter<WithBridgeHubKusamaMessageBridge>;
497-
type MessageDispatch =
498-
XcmBlobMessageDispatch<OnThisChainBlobDispatcher<UniversalLocation>, Self::WeightInfo, ()>;
499-
type OnMessagesDelivered = ();
497+
type MessageDispatch = XcmBlobMessageDispatch<
498+
OnThisChainBlobDispatcher<UniversalLocation>,
499+
Self::WeightInfo,
500+
cumulus_pallet_xcmp_queue::bridging::OutboundXcmpChannelCongestionStatusProvider<
501+
bridge_hub_config::AssetHubPolkadotParaId,
502+
Runtime,
503+
>,
504+
>;
505+
type OnMessagesDelivered = bridge_hub_config::OnMessagesDelivered;
500506
}
501507

502508
/// Allows collect and claim rewards for relayers
@@ -943,7 +949,11 @@ impl_runtime_apis! {
943949
type XcmBalances = pallet_xcm_benchmarks::fungible::Pallet::<Runtime>;
944950
type XcmGeneric = pallet_xcm_benchmarks::generic::Pallet::<Runtime>;
945951

946-
use bridge_runtime_common::messages_benchmarking::{prepare_message_delivery_proof_from_parachain, prepare_message_proof_from_parachain};
952+
use bridge_runtime_common::messages_benchmarking::{
953+
generate_xcm_builder_bridge_message_sample,
954+
prepare_message_delivery_proof_from_parachain,
955+
prepare_message_proof_from_parachain
956+
};
947957
use pallet_bridge_messages::benchmarking::{
948958
Config as BridgeMessagesConfig,
949959
Pallet as BridgeMessagesBench,
@@ -973,7 +983,7 @@ impl_runtime_apis! {
973983
Runtime,
974984
BridgeGrandpaKusamaInstance,
975985
bridge_hub_config::WithBridgeHubKusamaMessageBridge,
976-
>(params, X2(GlobalConsensus(xcm_config::RelayNetwork::get().unwrap()), Parachain(42)))
986+
>(params, generate_xcm_builder_bridge_message_sample(X2(GlobalConsensus(xcm_config::RelayNetwork::get().unwrap()), Parachain(42))))
977987
}
978988
fn prepare_message_delivery_proof(
979989
params: MessageDeliveryProofParams<AccountId>,

cumulus/parachains/runtimes/bridge-hubs/bridge-hub-polkadot/src/xcm_config.rs

Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -115,14 +115,6 @@ match_types! {
115115
pub type FellowsPlurality: impl Contains<MultiLocation> = {
116116
MultiLocation { parents: 1, interior: X2(Parachain(1001), Plurality { id: BodyId::Technical, ..}) }
117117
};
118-
// TODO:check-parameter - (https://github.com/paritytech/parity-bridges-common/issues/2084)
119-
// remove this and extend `AllowExplicitUnpaidExecutionFrom` with "or SystemParachains" once merged https://github.com/paritytech/polkadot/pull/7005
120-
pub type SystemParachains: impl Contains<MultiLocation> = {
121-
// Statemint
122-
MultiLocation { parents: 1, interior: X1(Parachain(1000)) } |
123-
// Collectives
124-
MultiLocation { parents: 1, interior: X1(Parachain(1001)) }
125-
};
126118
}
127119

128120
/// A call filter for the XCM Transact instruction. This is a temporary measure until we properly
@@ -196,13 +188,9 @@ pub type Barrier = TrailingSetTopicAsId<
196188
// If the message is one that immediately attemps to pay for execution, then
197189
// allow it.
198190
AllowTopLevelPaidExecutionFrom<Everything>,
199-
// Parent, its pluralities (i.e. governance bodies), the Fellows plurality
200-
// and system parachains get free execution.
201-
AllowExplicitUnpaidExecutionFrom<(
202-
ParentOrParentsPlurality,
203-
FellowsPlurality,
204-
SystemParachains,
205-
)>,
191+
// Parent, its pluralities (i.e. governance bodies) and the Fellows plurality
192+
// get free execution.
193+
AllowExplicitUnpaidExecutionFrom<(ParentOrParentsPlurality, FellowsPlurality)>,
206194
// Subscriptions for version tracking are OK.
207195
AllowSubscriptionsFrom<ParentOrSiblings>,
208196
),

0 commit comments

Comments
 (0)