Skip to content

Commit

Permalink
Adapt testnet runtimes to latest congestion changes
Browse files Browse the repository at this point in the history
  • Loading branch information
bkontur committed Nov 5, 2024
1 parent f415d55 commit 152389a
Show file tree
Hide file tree
Showing 20 changed files with 384 additions and 131 deletions.
1 change: 0 additions & 1 deletion Cargo.lock

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

104 changes: 103 additions & 1 deletion bridges/modules/xcm-bridge-hub-router/src/impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

//! Various implementations supporting easier configuration of the pallet.
use crate::{Config, Pallet, Bridges, BridgeIdOf, LOG_TARGET};
use xcm_builder::ExporterFor;
use xcm_builder::{ensure_is_remote, ExporterFor};
use bp_xcm_bridge_hub_router::ResolveBridgeId;
use codec::Encode;
use frame_support::pallet_prelude::PhantomData;
Expand Down Expand Up @@ -164,3 +164,105 @@ where
Some((bridge_hub_location, fees))
}
}

/// Implementation of `ResolveBridgeId` returning `bp_xcm_bridge_hub::BridgeId` based on the configured `UniversalLocation` and remote universal location.
pub struct EnsureIsRemoteBridgeIdResolver<UniversalLocation>(PhantomData<UniversalLocation>);
impl<UniversalLocation: Get<InteriorLocation>> ResolveBridgeId for EnsureIsRemoteBridgeIdResolver<UniversalLocation> {
type BridgeId = bp_xcm_bridge_hub::BridgeId;

fn resolve_for_dest(dest: &Location) -> Option<Self::BridgeId> {
let Ok((remote_network, remote_dest)) = ensure_is_remote(UniversalLocation::get(), dest.clone()) else {
log::trace!(
target: LOG_TARGET,
"EnsureIsRemoteBridgeIdResolver - does not recognize a remote destination for: {dest:?}!"
);
return None
};
Self::resolve_for(&remote_network, &remote_dest)
}

fn resolve_for(bridged_network: &NetworkId, bridged_dest: &InteriorLocation) -> Option<Self::BridgeId> {
let bridged_universal_location = if let Ok(network) = bridged_dest.global_consensus() {
if network.ne(bridged_network) {
log::error!(
target: LOG_TARGET,
"EnsureIsRemoteBridgeIdResolver - bridged_dest: {bridged_dest:?} contains invalid network: {network:?}, expected bridged_network: {bridged_network:?}!"
);
return None
} else {
bridged_dest.clone()
}
} else {
// if `bridged_dest` does not contain `GlobalConsensus`, let's prepend one
match bridged_dest.clone().pushed_front_with(bridged_network.clone()) {
Ok(bridged_universal_location) => bridged_universal_location,
Err((original, prepend_with)) => {
log::error!(
target: LOG_TARGET,
"EnsureIsRemoteBridgeIdResolver - bridged_dest: {original:?} cannot be prepended with: {prepend_with:?}!"
);
return None
}
}
};

match (UniversalLocation::get().global_consensus(), bridged_universal_location.global_consensus()) {
(Ok(local), Ok(remote)) if local != remote => (),
(local, remote) => {
log::error!(
target: LOG_TARGET,
"EnsureIsRemoteBridgeIdResolver - local: {local:?} and remote: {remote:?} must be different!"
);
return None
}
}

// calculate `BridgeId` from universal locations
Some(Self::BridgeId::new(&UniversalLocation::get(), &bridged_universal_location))
}
}

#[cfg(test)]
mod tests {
use frame_support::__private::sp_tracing;
use super::*;

#[test]
fn ensure_is_remote_bridge_id_resolver_works() {
sp_tracing::try_init_simple();
frame_support::parameter_types! {
pub ThisNetwork: NetworkId = NetworkId::ByGenesis([0; 32]);
pub BridgedNetwork: NetworkId = NetworkId::ByGenesis([1; 32]);
pub UniversalLocation: InteriorLocation = [GlobalConsensus(ThisNetwork::get()), Parachain(1000)].into();
}
assert_ne!(ThisNetwork::get(), BridgedNetwork::get());

type Resolver = EnsureIsRemoteBridgeIdResolver<UniversalLocation>;

// not remote dest
assert!(Resolver::resolve_for_dest(&Location::new(1, Here)).is_none());
// not a valid remote dest
assert!(Resolver::resolve_for_dest(&Location::new(2, Here)).is_none());
// the same network for remote dest
assert!(Resolver::resolve_for_dest(&Location::new(2, GlobalConsensus(ThisNetwork::get()))).is_none());
assert!(Resolver::resolve_for(&ThisNetwork::get(), &Here.into()).is_none());

// ok
assert!(Resolver::resolve_for_dest(&Location::new(2, GlobalConsensus(BridgedNetwork::get()))).is_some());
assert!(Resolver::resolve_for_dest(&Location::new(2, [GlobalConsensus(BridgedNetwork::get()), Parachain(2013)])).is_some());

// ok - resolves the same
assert_eq!(
Resolver::resolve_for_dest(&Location::new(2, GlobalConsensus(BridgedNetwork::get()))),
Resolver::resolve_for(&BridgedNetwork::get(), &Here.into()),
);
assert_eq!(
Resolver::resolve_for_dest(&Location::new(2, [GlobalConsensus(BridgedNetwork::get()), Parachain(2013)])),
Resolver::resolve_for(&BridgedNetwork::get(), &Parachain(2013).into()),
);
assert_eq!(
Resolver::resolve_for_dest(&Location::new(2, [GlobalConsensus(BridgedNetwork::get()), Parachain(2013)])),
Resolver::resolve_for(&BridgedNetwork::get(), &[GlobalConsensus(BridgedNetwork::get()), Parachain(2013)].into()),
);
}
}
4 changes: 2 additions & 2 deletions bridges/modules/xcm-bridge-hub-router/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
#![cfg_attr(not(feature = "std"), no_std)]

use bp_xcm_bridge_hub_router::{BridgeState, ResolveBridgeId};
pub use bp_xcm_bridge_hub_router::{BridgeState, ResolveBridgeId};
use codec::Encode;
use frame_support::traits::{EnsureOriginWithArg, Get};
use sp_runtime::{FixedPointNumber, FixedU128, Saturating};
Expand Down Expand Up @@ -732,7 +732,7 @@ mod tests {
fn report_bridge_status_works() {
run_test(|| {
let dest = Location::new(2, [GlobalConsensus(BridgedNetworkId::get()), Parachain(1000)]);
let bridge_id = ();
let bridge_id = bp_xcm_bridge_hub::BridgeId::new(&UniversalLocation::get(), dest.interior());
let report_bridge_status = |bridge_id, is_congested| {
let call = RuntimeCall::XcmBridgeHubRouter(Call::report_bridge_status {
bridge_id,
Expand Down
3 changes: 2 additions & 1 deletion bridges/modules/xcm-bridge-hub-router/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ use xcm::prelude::*;
use xcm_builder::{
InspectMessageQueues, NetworkExportTable, NetworkExportTableItem, SovereignPaidRemoteExporter,
};
use crate::impls::EnsureIsRemoteBridgeIdResolver;

type Block = frame_system::mocking::MockBlock<TestRuntime>;

Expand Down Expand Up @@ -104,7 +105,7 @@ impl pallet_xcm_bridge_hub_router::Config<()> for TestRuntime {
UniversalLocation,
>;

type BridgeIdResolver = EveryDestinationToSameBridgeIdResolver;
type BridgeIdResolver = EnsureIsRemoteBridgeIdResolver<UniversalLocation>;
type BridgeHubOrigin = EnsureRoot<u64>;

type ByteFee = ConstU128<BYTE_FEE>;
Expand Down
1 change: 0 additions & 1 deletion bridges/modules/xcm-bridge-hub/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ pallet-balances = { workspace = true }
sp-io = { workspace = true }
bp-runtime = { workspace = true }
bp-header-chain = { workspace = true }
bp-xcm-bridge-hub-router = { workspace = true }
pallet-xcm-bridge-hub-router = { workspace = true }
polkadot-parachain-primitives = { workspace = true }

Expand Down
4 changes: 2 additions & 2 deletions bridges/modules/xcm-bridge-hub/src/exporter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -365,7 +365,7 @@ mod tests {

use bp_runtime::RangeInclusiveExt;
use bp_xcm_bridge_hub::{Bridge, BridgeLocations, BridgeState, Receiver};
use bp_xcm_bridge_hub_router::ResolveBridgeId;
use pallet_xcm_bridge_hub_router::ResolveBridgeId;
use frame_support::{
assert_ok,
traits::{Contains, EnsureOrigin},
Expand Down Expand Up @@ -828,7 +828,7 @@ mod tests {
// valid routable destination
let dest = Location::new(2, BridgedUniversalDestination::get());

fn router_bridge_state<T: pallet_xcm_bridge_hub_router::Config<I>, I: 'static>(dest: &Location) -> Option<bp_xcm_bridge_hub_router::BridgeState> {
fn router_bridge_state<T: pallet_xcm_bridge_hub_router::Config<I>, I: 'static>(dest: &Location) -> Option<pallet_xcm_bridge_hub_router::BridgeState> {
let bridge_id = <T::BridgeIdResolver as ResolveBridgeId>::resolve_for_dest(dest).unwrap();
pallet_xcm_bridge_hub_router::Bridges::<T, I>::get(&bridge_id)
}
Expand Down
23 changes: 3 additions & 20 deletions bridges/modules/xcm-bridge-hub/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ use bp_messages::{
use bp_runtime::{messages::MessageDispatchResult, Chain, ChainId, HashOf};
use bp_xcm_bridge_hub::{BridgeId, BridgeLocations, LocalXcmChannelManager};
use codec::Encode;
use bp_xcm_bridge_hub_router::ResolveBridgeId;
use frame_support::{
assert_ok, derive_impl, parameter_types,
traits::{fungible::Mutate, EitherOf, EnsureOrigin, Equals, Everything, OriginTrait},
Expand All @@ -47,7 +46,7 @@ use xcm::prelude::*;
use xcm_builder::{
AllowUnpaidExecutionFrom, DispatchBlob, DispatchBlobError, FixedWeightBounds,
InspectMessageQueues, NetworkExportTable, NetworkExportTableItem, ParentIsPreset,
SiblingParachainConvertsVia, SovereignPaidRemoteExporter, UnpaidLocalExporter, ensure_is_remote,
SiblingParachainConvertsVia, SovereignPaidRemoteExporter, UnpaidLocalExporter,
};
use xcm_executor::{traits::{ConvertLocation, ConvertOrigin}, XcmExecutor};
use crate::congestion::BlobDispatcherWithChannelStatus;
Expand Down Expand Up @@ -258,7 +257,7 @@ impl pallet_xcm_bridge_hub_router::Config<()> for TestRuntime {
ExportMessageOriginUniversalLocation,
>;

type BridgeIdResolver = EnsureIsRemoteBridgeIdResolver<ExportMessageOriginUniversalLocation>;
type BridgeIdResolver = pallet_xcm_bridge_hub_router::impls::EnsureIsRemoteBridgeIdResolver<ExportMessageOriginUniversalLocation>;
// We convert to root here `BridgeHubLocationXcmOriginAsRoot`
type BridgeHubOrigin = EnsureRoot<AccountId>;
}
Expand All @@ -272,27 +271,11 @@ impl pallet_xcm_bridge_hub_router::Config<XcmOverBridgeByExportXcmRouterInstance
// trigger directly `pallet_xcm_bridge_hub` as exporter.
type ToBridgeHubSender = UnpaidLocalExporter<XcmOverBridge, UniversalLocation>;

type BridgeIdResolver = EnsureIsRemoteBridgeIdResolver<UniversalLocation>;
type BridgeIdResolver = pallet_xcm_bridge_hub_router::impls::EnsureIsRemoteBridgeIdResolver<UniversalLocation>;
// We don't need to support here `report_bridge_status`.
type BridgeHubOrigin = EnsureNever<()>;
}

/// Implementation of `ResolveBridgeId` returning `BridgeId` based on the configured `UniversalLocation`.
pub struct EnsureIsRemoteBridgeIdResolver<UniversalLocation>(PhantomData<UniversalLocation>);
impl<UniversalLocation: Get<InteriorLocation>> ResolveBridgeId for EnsureIsRemoteBridgeIdResolver<UniversalLocation> {
type BridgeId = BridgeId;

fn resolve_for_dest(dest: &Location) -> Option<Self::BridgeId> {
let (remote_network, remote_dest) = ensure_is_remote(UniversalLocation::get(), dest.clone()).unwrap();
Self::resolve_for(&remote_network, &remote_dest)
}

fn resolve_for(bridged_network: &NetworkId, bridged_dest: &InteriorLocation) -> Option<Self::BridgeId> {
let bridged_universal_location = bridged_dest.clone().pushed_front_with(bridged_network.clone()).unwrap();
Some(BridgeId::new(&UniversalLocation::get(), &bridged_universal_location))
}
}

/// A dynamic way to set different universal location for the origin which sends `ExportMessage`.
pub struct ExportMessageOriginUniversalLocation;
impl ExportMessageOriginUniversalLocation {
Expand Down
28 changes: 0 additions & 28 deletions cumulus/pallets/xcmp-queue/src/bridging.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,34 +17,6 @@ use crate::{pallet, OutboundState};
use cumulus_primitives_core::ParaId;
use xcm::latest::prelude::*;

/// Adapter implementation for `bp_xcm_bridge_hub::ChannelStatusProvider` which checks
/// both `OutboundXcmpStatus` and `InboundXcmpStatus` for defined `Location` if any of those is
/// suspended.
pub struct InAndOutXcmpChannelStatusProvider<Runtime>(core::marker::PhantomData<Runtime>);
impl<Runtime: crate::Config> bp_xcm_bridge_hub::ChannelStatusProvider
for InAndOutXcmpChannelStatusProvider<Runtime>
{
fn is_congested(with: &Location) -> bool {
// handle congestion only for a sibling parachain locations.
let sibling_para_id: ParaId = match with.unpack() {
(_, [Parachain(para_id)]) => (*para_id).into(),
_ => return false,
};

// if the inbound channel with recipient is suspended, it means that we are unable to
// receive congestion reports from the `with` location. So we assume the pipeline is
// congested too.
if pallet::Pallet::<Runtime>::is_inbound_channel_suspended(sibling_para_id) {
return true
}

// if the outbound channel with recipient is suspended, it means that one of further
// queues (e.g. bridge queue between two bridge hubs) is overloaded, so we shall
// take larger fee for our outbound messages
OutXcmpChannelStatusProvider::<Runtime>::is_congested(with)
}
}

/// Adapter implementation for `bp_xcm_bridge_hub::ChannelStatusProvider` which checks
/// only `OutboundXcmpStatus` for defined `SiblingParaId` if is suspended.
pub struct OutXcmpChannelStatusProvider<Runtime>(core::marker::PhantomData<Runtime>);
Expand Down
5 changes: 0 additions & 5 deletions cumulus/pallets/xcmp-queue/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -691,11 +691,6 @@ impl<T: Config> Pallet<T> {
.max(<T as crate::Config>::WeightInfo::on_idle_large_msg())
}

#[cfg(feature = "bridging")]
fn is_inbound_channel_suspended(sender: ParaId) -> bool {
<InboundXcmpSuspended<T>>::get().iter().any(|c| c == &sender)
}

#[cfg(feature = "bridging")]
/// Returns tuple of `OutboundState` and number of queued pages.
fn outbound_channel_state(target: ParaId) -> Option<(OutboundState, u16)> {
Expand Down
26 changes: 18 additions & 8 deletions cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ use frame_support::{
weights::{ConstantMultiplier, Weight, WeightToFee as _},
BoundedVec, PalletId,
};
use frame_support::traits::Equals;
use frame_system::{
limits::{BlockLength, BlockWeights},
EnsureRoot, EnsureSigned, EnsureSignedBy,
Expand Down Expand Up @@ -111,7 +112,7 @@ use xcm_runtime_apis::{
};

use weights::{BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight};
use xcm_builder::SovereignPaidRemoteExporter;
use xcm_builder::{NetworkExportTable, SovereignPaidRemoteExporter};

impl_opaque_keys! {
pub struct SessionKeys {
Expand Down Expand Up @@ -928,22 +929,31 @@ impl pallet_xcm_bridge_hub_router::Config<ToWestendXcmRouterInstance> for Runtim
type RuntimeEvent = RuntimeEvent;
type WeightInfo = weights::pallet_xcm_bridge_hub_router::WeightInfo<Runtime>;

type UniversalLocation = xcm_config::UniversalLocation;
type SiblingBridgeHubLocation = xcm_config::bridging::SiblingBridgeHub;
type BridgedNetworkId = xcm_config::bridging::to_westend::WestendNetwork;
type DestinationVersion = PolkadotXcm;

// Let's use `SovereignPaidRemoteExporter`, which sends `ExportMessage` over HRMP to the sibling
// BridgeHub.
type ToBridgeHubSender = SovereignPaidRemoteExporter<
xcm_builder::NetworkExportTable<xcm_config::bridging::to_westend::BridgeTable>,
// `ExporterFor` wrapper handling dynamic fees for congestion.
pallet_xcm_bridge_hub_router::impls::ViaRemoteBridgeHubExporter<
Runtime,
ToWestendXcmRouterInstance,
NetworkExportTable<xcm_config::bridging::to_westend::BridgeTable>,
xcm_config::bridging::to_westend::WestendNetwork,
xcm_config::bridging::SiblingBridgeHub
>,
XcmpQueue,
Self::UniversalLocation
xcm_config::UniversalLocation,
>;
type LocalXcmChannelManager =
cumulus_pallet_xcmp_queue::bridging::InAndOutXcmpChannelStatusProvider<Runtime>;

// For congestion - resolves `BridgeId` using the same algorithm as `pallet_xcm_bridge_hub` on the BH.
type BridgeIdResolver = pallet_xcm_bridge_hub_router::impls::EnsureIsRemoteBridgeIdResolver<xcm_config::UniversalLocation>;
// For congestion - allow only calls from BH.
type BridgeHubOrigin = AsEnsureOriginWithArg<EnsureXcm<Equals<xcm_config::bridging::SiblingBridgeHub>>>;

// For adding message size fees
type ByteFee = xcm_config::bridging::XcmBridgeHubRouterByteFee;
// For adding message size fees
type FeeAsset = xcm_config::bridging::XcmBridgeHubRouterFeeAssetId;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,20 @@

use frame_support::{traits::Get, weights::Weight};
use core::marker::PhantomData;
use frame_support::weights::constants::RocksDbWeight;

/// Weight functions for `pallet_xcm_bridge_hub_router`.
pub struct WeightInfo<T>(PhantomData<T>);
impl<T: frame_system::Config> pallet_xcm_bridge_hub_router::WeightInfo for WeightInfo<T> {
// TODO: FAIL-CI
fn on_initialize_when_bridge_state_removed() -> Weight {
RocksDbWeight::get().writes(1)
}

// TODO: FAIL-CI
fn on_initialize_when_bridge_state_updated() -> Weight {
RocksDbWeight::get().writes(1)
}
/// Storage: `XcmpQueue::InboundXcmpSuspended` (r:1 w:0)
/// Proof: `XcmpQueue::InboundXcmpSuspended` (`max_values`: Some(1), `max_size`: Some(4002), added: 4497, mode: `MaxEncodedLen`)
/// Storage: `XcmpQueue::OutboundXcmpStatus` (r:1 w:0)
Expand Down Expand Up @@ -77,4 +87,14 @@ impl<T: frame_system::Config> pallet_xcm_bridge_hub_router::WeightInfo for Weigh
.saturating_add(Weight::from_parts(0, 5487))
.saturating_add(T::DbWeight::get().reads(2))
}
// TODO: FAIL-CI
fn report_bridge_status() -> Weight {
// Proof Size summary in bytes:
// Measured: `53`
// Estimated: `1502`
// Minimum execution time: 10_427 nanoseconds.
Weight::from_parts(10_682_000, 1502)
.saturating_add(T::DbWeight::get().reads(1_u64))
.saturating_add(T::DbWeight::get().writes(1_u64))
}
}
Loading

0 comments on commit 152389a

Please sign in to comment.