From ad0931c1912dedbfa0914a2928b14aa267352fa3 Mon Sep 17 00:00:00 2001 From: Branislav Kontur Date: Fri, 25 Oct 2024 10:05:25 +0200 Subject: [PATCH 01/72] Nits --- .../modules/xcm-bridge-hub-router/src/lib.rs | 2 +- .../modules/xcm-bridge-hub/src/exporter.rs | 8 +++--- bridges/modules/xcm-bridge-hub/src/mock.rs | 27 ++++++++----------- .../xcm-bridge-hub-router/src/lib.rs | 2 +- 4 files changed, 17 insertions(+), 22 deletions(-) diff --git a/bridges/modules/xcm-bridge-hub-router/src/lib.rs b/bridges/modules/xcm-bridge-hub-router/src/lib.rs index fe8f5a2efdfb..a751fbeb8692 100644 --- a/bridges/modules/xcm-bridge-hub-router/src/lib.rs +++ b/bridges/modules/xcm-bridge-hub-router/src/lib.rs @@ -67,7 +67,7 @@ pub const HARD_MESSAGE_SIZE_LIMIT: u32 = 32 * 1024; /// pallet has significant differences with those pallets. The main one is that is intended to /// be deployed at sending chains. Other bridge pallets are likely to be deployed at the separate /// bridge hub parachain. -pub const LOG_TARGET: &str = "xcm::bridge-hub-router"; +pub const LOG_TARGET: &str = "runtime::bridge-xcm-router"; #[frame_support::pallet] pub mod pallet { diff --git a/bridges/modules/xcm-bridge-hub/src/exporter.rs b/bridges/modules/xcm-bridge-hub/src/exporter.rs index 5afb9f36bc94..f67ccdde9686 100644 --- a/bridges/modules/xcm-bridge-hub/src/exporter.rs +++ b/bridges/modules/xcm-bridge-hub/src/exporter.rs @@ -287,7 +287,7 @@ impl, I: 'static> Pallet { _ => { // if there is no bridge or it has been closed, then we don't need to send resume // signal to the local origin - it has closed bridge itself, so it should have - // alrady pruned everything else + // already pruned everything else return }, }; @@ -662,17 +662,17 @@ mod tests { ); // send `ExportMessage(message)` by `UnpaidRemoteExporter`. - TestExportXcmWithXcmOverBridge::set_origin_for_execute(SiblingLocation::get()); + ExecuteXcmOverSendXcm::set_origin_for_execute(SiblingLocation::get()); assert_ok!(send_xcm::< UnpaidRemoteExporter< NetworkExportTable, - TestExportXcmWithXcmOverBridge, + ExecuteXcmOverSendXcm, UniversalLocation, >, >(dest.clone(), Xcm::<()>::default())); // send `ExportMessage(message)` by `pallet_xcm_bridge_hub_router`. - TestExportXcmWithXcmOverBridge::set_origin_for_execute(SiblingLocation::get()); + ExecuteXcmOverSendXcm::set_origin_for_execute(SiblingLocation::get()); assert_ok!(send_xcm::(dest.clone(), Xcm::<()>::default())); // check after - a message ready to be relayed diff --git a/bridges/modules/xcm-bridge-hub/src/mock.rs b/bridges/modules/xcm-bridge-hub/src/mock.rs index 9f06b99ef6d5..113d2ec2f1db 100644 --- a/bridges/modules/xcm-bridge-hub/src/mock.rs +++ b/bridges/modules/xcm-bridge-hub/src/mock.rs @@ -59,11 +59,11 @@ pub const BRIDGED_ASSET_HUB_ID: u32 = 1001; frame_support::construct_runtime! { pub enum TestRuntime { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - Balances: pallet_balances::{Pallet, Event}, - Messages: pallet_bridge_messages::{Pallet, Call, Event}, - XcmOverBridge: pallet_xcm_bridge_hub::{Pallet, Call, HoldReason, Event}, - XcmOverBridgeRouter: pallet_xcm_bridge_hub_router, + System: frame_system, + Balances: pallet_balances, + Messages: pallet_bridge_messages, + XcmOverBridge: pallet_xcm_bridge_hub, + XcmOverBridgeRouter: pallet_xcm_bridge_hub_router = 57, } } @@ -208,6 +208,7 @@ impl pallet_xcm_bridge_hub::Config for TestRuntime { type BlobDispatcher = TestBlobDispatcher; } +/// A router instance simulates a scenario where the router is deployed on a different chain than the `MessageExporter`. This means that the router sends an `ExportMessage`. impl pallet_xcm_bridge_hub_router::Config<()> for TestRuntime { type RuntimeEvent = RuntimeEvent; type WeightInfo = (); @@ -218,7 +219,7 @@ impl pallet_xcm_bridge_hub_router::Config<()> for TestRuntime { type Bridges = NetworkExportTable; type DestinationVersion = AlwaysLatest; - type ToBridgeHubSender = TestExportXcmWithXcmOverBridge; + type ToBridgeHubSender = ExecuteXcmOverSendXcm; type LocalXcmChannelManager = TestLocalXcmChannelManager; type ByteFee = ConstU128<0>; @@ -264,14 +265,8 @@ thread_local! { } /// The `SendXcm` implementation directly executes XCM using `XcmExecutor`. -/// -/// We ensure that the `ExportMessage` produced by `pallet_xcm_bridge_hub_router` is compatible with -/// the `ExportXcm` implementation of `pallet_xcm_bridge_hub`. -/// -/// Note: The crucial part is that `ExportMessage` is processed by `XcmExecutor`, which calls the -/// `ExportXcm` implementation of `pallet_xcm_bridge_hub` as `MessageExporter`. -pub struct TestExportXcmWithXcmOverBridge; -impl SendXcm for TestExportXcmWithXcmOverBridge { +pub struct ExecuteXcmOverSendXcm; +impl SendXcm for ExecuteXcmOverSendXcm { type Ticket = Xcm<()>; fn validate( @@ -298,7 +293,7 @@ impl SendXcm for TestExportXcmWithXcmOverBridge { Ok(hash) } } -impl InspectMessageQueues for TestExportXcmWithXcmOverBridge { +impl InspectMessageQueues for ExecuteXcmOverSendXcm { fn clear_messages() { todo!() } @@ -307,7 +302,7 @@ impl InspectMessageQueues for TestExportXcmWithXcmOverBridge { todo!() } } -impl TestExportXcmWithXcmOverBridge { +impl ExecuteXcmOverSendXcm { pub fn set_origin_for_execute(origin: Location) { EXECUTE_XCM_ORIGIN.with(|o| *o.borrow_mut() = Some(origin)); } diff --git a/bridges/primitives/xcm-bridge-hub-router/src/lib.rs b/bridges/primitives/xcm-bridge-hub-router/src/lib.rs index 89123b51ef2f..5e7511bb3ece 100644 --- a/bridges/primitives/xcm-bridge-hub-router/src/lib.rs +++ b/bridges/primitives/xcm-bridge-hub-router/src/lib.rs @@ -29,7 +29,7 @@ pub const MINIMAL_DELIVERY_FEE_FACTOR: FixedU128 = FixedU128::from_u32(1); /// XCM channel status provider that may report whether it is congested or not. /// -/// By channel we mean the physical channel that is used to deliver messages of one +/// By the channel we mean the physical channel that is used to deliver messages of one /// of the bridge queues. pub trait XcmChannelStatusProvider { /// Returns true if the channel is currently congested. From efce0e7490ec9a6304d37cbe4ba1def1ce0e83d2 Mon Sep 17 00:00:00 2001 From: Branislav Kontur Date: Fri, 25 Oct 2024 10:47:01 +0200 Subject: [PATCH 02/72] Remove internal `ViaBridgeHubExporter/SovereignPaidRemoteExporter` and allow to externalize it with `ToBridgeHubSender`. --- .../modules/xcm-bridge-hub-router/src/lib.rs | 49 ++++++++----------- .../modules/xcm-bridge-hub-router/src/mock.rs | 9 +++- bridges/modules/xcm-bridge-hub/src/mock.rs | 10 +++- .../assets/asset-hub-rococo/src/lib.rs | 8 ++- .../assets/asset-hub-westend/src/lib.rs | 8 ++- 5 files changed, 50 insertions(+), 34 deletions(-) diff --git a/bridges/modules/xcm-bridge-hub-router/src/lib.rs b/bridges/modules/xcm-bridge-hub-router/src/lib.rs index a751fbeb8692..bfaead8814e0 100644 --- a/bridges/modules/xcm-bridge-hub-router/src/lib.rs +++ b/bridges/modules/xcm-bridge-hub-router/src/lib.rs @@ -14,19 +14,17 @@ // You should have received a copy of the GNU General Public License // along with Parity Bridges Common. If not, see . -//! Pallet that may be used instead of `SovereignPaidRemoteExporter` in the XCM router -//! configuration. The main thing that the pallet offers is the dynamic message fee, -//! that is computed based on the bridge queues state. It starts exponentially increasing -//! if the queue between this chain and the sibling/child bridge hub is congested. +//! A pallet that can be used instead of `SovereignPaidRemoteExporter` (or others) in the XCM router +//! configuration. The main feature this pallet offers is a dynamic message fee, +//! which is computed based on the state of the bridge queues. The fee increases exponentially +//! if the queue between this chain and the sibling or child bridge hub becomes congested. //! -//! All other bridge hub queues offer some backpressure mechanisms. So if at least one -//! of all queues is congested, it will eventually lead to the growth of the queue at -//! this chain. +//! All other bridge hub queues offer backpressure mechanisms, so if any of these +//! queues are congested, it will eventually lead to increased queuing on this chain. //! -//! **A note on terminology**: when we mention the bridge hub here, we mean the chain that -//! has the messages pallet deployed (`pallet-bridge-grandpa`, `pallet-bridge-messages`, -//! `pallet-xcm-bridge-hub`, ...). It may be the system bridge hub parachain or any other -//! chain. +//! **Note on Terminology**: When we refer to the bridge hub here, we mean the chain that +//! has the `pallet-bridge-messages` with an `ExportXcm` implementation deployed, e.g., provided by `pallet-xcm-bridge-hub`. +//! Depending on the deployment setup, `T::ToBridgeHubSender` can be configured accordingly - see `T::ToBridgeHubSender` for more documentation. #![cfg_attr(not(feature = "std"), no_std)] @@ -36,7 +34,7 @@ use frame_support::traits::Get; use sp_runtime::{FixedPointNumber, FixedU128, Saturating}; use sp_std::vec::Vec; use xcm::prelude::*; -use xcm_builder::{ExporterFor, InspectMessageQueues, SovereignPaidRemoteExporter}; +use xcm_builder::{ExporterFor, InspectMessageQueues}; pub use pallet::*; pub use weights::WeightInfo; @@ -98,7 +96,9 @@ pub mod pallet { /// Checks the XCM version for the destination. type DestinationVersion: GetVersion; - /// Actual message sender (`HRMP` or `DMP`) to the sibling bridge hub location. + //! The bridge hub may be: + //! - A system (sibling) bridge hub parachain (or another chain), in which case we need an implementation for `T::ToBridgeHubSender` that sends `ExportMessage`, e.g., `SovereignPaidRemoteExporter`. + //! - The local chain, in which case we need an implementation for `T::ToBridgeHubSender` that does not use `ExportMessage` but instead directly calls the `ExportXcm` implementation. type ToBridgeHubSender: SendXcm; /// Local XCM channel manager. type LocalXcmChannelManager: XcmChannelStatusProvider; @@ -229,13 +229,6 @@ pub mod pallet { } } -/// We'll be using `SovereignPaidRemoteExporter` to send remote messages over the sibling/child -/// bridge hub. -type ViaBridgeHubExporter = SovereignPaidRemoteExporter< - Pallet, - >::ToBridgeHubSender, - >::UniversalLocation, ->; // This pallet acts as the `ExporterFor` for the `SovereignPaidRemoteExporter` to compute // message fee using fee factor. @@ -340,7 +333,7 @@ impl, I: 'static> SendXcm for Pallet { ) -> SendResult { log::trace!(target: LOG_TARGET, "validate - msg: {xcm:?}, destination: {dest:?}"); - // In case of success, the `ViaBridgeHubExporter` can modify XCM instructions and consume + // In case of success, the `T::ToBridgeHubSender` can modify XCM instructions and consume // `dest` / `xcm`, so we retain the clone of original message and the destination for later // `DestinationVersion` validation. let xcm_to_dest_clone = xcm.clone(); @@ -352,7 +345,7 @@ impl, I: 'static> SendXcm for Pallet { // include both the cost of (1) delivery to the sibling bridge hub (returned by // `Config::ToBridgeHubSender`) and (2) delivery to the bridged bridge hub (returned by // `Self::exporter_for`). - match ViaBridgeHubExporter::::validate(dest, xcm) { + match T::ToBridgeHubSender::validate(dest, xcm) { Ok((ticket, cost)) => { // If the ticket is ok, it means we are routing with this router, so we need to // apply more validations to the cloned `dest` and `xcm`, which are required here. @@ -361,7 +354,7 @@ impl, I: 'static> SendXcm for Pallet { // We won't have access to `dest` and `xcm` in the `deliver` method, so we need to // precompute everything required here. However, `dest` and `xcm` were consumed by - // `ViaBridgeHubExporter`, so we need to use their clones. + // `T::ToBridgeHubSender`, so we need to use their clones. let message_size = xcm_to_dest_clone.encoded_size() as _; // The bridge doesn't support oversized or overweight messages. Therefore, it's @@ -373,7 +366,7 @@ impl, I: 'static> SendXcm for Pallet { // We need to ensure that the known `dest`'s XCM version can comprehend the current // `xcm` program. This may seem like an additional, unnecessary check, but it is - // not. A similar check is probably performed by the `ViaBridgeHubExporter`, which + // not. A similar check is probably performed by the `T::ToBridgeHubSender`, which // attempts to send a versioned message to the sibling bridge hub. However, the // local bridge hub may have a higher XCM version than the remote `dest`. Once // again, it is better to discard such messages here than at the bridge hub (e.g., @@ -387,7 +380,7 @@ impl, I: 'static> SendXcm for Pallet { Ok(((message_size, ticket), cost)) }, Err(e) => { - log::trace!(target: LOG_TARGET, "validate - ViaBridgeHubExporter - error: {e:?}"); + log::trace!(target: LOG_TARGET, "`T::ToBridgeHubSender` validates for dest: {dest_clone:?} with error: {e:?}"); Err(e) }, } @@ -397,7 +390,7 @@ impl, I: 'static> SendXcm for Pallet { // use router to enqueue message to the sibling/child bridge hub. This also should handle // payment for passing through this queue. let (message_size, ticket) = ticket; - let xcm_hash = ViaBridgeHubExporter::::deliver(ticket)?; + let xcm_hash = T::ToBridgeHubSender::deliver(ticket)?; // increase delivery fee factor if required Self::on_message_sent_to_bridge(message_size); @@ -510,7 +503,7 @@ mod tests { let xcm: Xcm<()> = vec![ClearOrigin; HARD_MESSAGE_SIZE_LIMIT as usize].into(); // dest is routable with the inner router - assert_ok!(ViaBridgeHubExporter::::validate( + assert_ok!(>::ToBridgeHubSender::validate( &mut Some(dest.clone()), &mut Some(xcm.clone()) )); @@ -540,7 +533,7 @@ mod tests { let xcm: Xcm<()> = vec![ClearOrigin].into(); // dest is routable with the inner router - assert_ok!(ViaBridgeHubExporter::::validate( + assert_ok!(>::ToBridgeHubSender::validate( &mut Some(dest.clone()), &mut Some(xcm.clone()) )); diff --git a/bridges/modules/xcm-bridge-hub-router/src/mock.rs b/bridges/modules/xcm-bridge-hub-router/src/mock.rs index 095572883920..aae488e65185 100644 --- a/bridges/modules/xcm-bridge-hub-router/src/mock.rs +++ b/bridges/modules/xcm-bridge-hub-router/src/mock.rs @@ -27,7 +27,7 @@ use frame_support::{ use sp_runtime::{traits::ConstU128, BuildStorage}; use sp_std::cell::RefCell; use xcm::prelude::*; -use xcm_builder::{InspectMessageQueues, NetworkExportTable, NetworkExportTableItem}; +use xcm_builder::{InspectMessageQueues, NetworkExportTable, NetworkExportTableItem, SovereignPaidRemoteExporter}; type Block = frame_system::mocking::MockBlock; @@ -80,7 +80,12 @@ impl pallet_xcm_bridge_hub_router::Config<()> for TestRuntime { type DestinationVersion = LatestOrNoneForLocationVersionChecker>; - type ToBridgeHubSender = TestToBridgeHubSender; + type ToBridgeHubSender = SovereignPaidRemoteExporter< + // use pallet itself as `ExportFor` provider. + XcmBridgeHubRouter, + TestToBridgeHubSender, + Self::UniversalLocation, + >; type LocalXcmChannelManager = TestLocalXcmChannelManager; type ByteFee = ConstU128; diff --git a/bridges/modules/xcm-bridge-hub/src/mock.rs b/bridges/modules/xcm-bridge-hub/src/mock.rs index 113d2ec2f1db..3037a88a2b1d 100644 --- a/bridges/modules/xcm-bridge-hub/src/mock.rs +++ b/bridges/modules/xcm-bridge-hub/src/mock.rs @@ -42,7 +42,7 @@ use xcm::{latest::ROCOCO_GENESIS_HASH, prelude::*}; use xcm_builder::{ AllowUnpaidExecutionFrom, DispatchBlob, DispatchBlobError, FixedWeightBounds, InspectMessageQueues, NetworkExportTable, NetworkExportTableItem, ParentIsPreset, - SiblingParachainConvertsVia, + SiblingParachainConvertsVia, SovereignPaidRemoteExporter, }; use xcm_executor::XcmExecutor; @@ -219,7 +219,13 @@ impl pallet_xcm_bridge_hub_router::Config<()> for TestRuntime { type Bridges = NetworkExportTable; type DestinationVersion = AlwaysLatest; - type ToBridgeHubSender = ExecuteXcmOverSendXcm; + // We use `SovereignPaidRemoteExporter` here to test and ensure that the `ExportMessage` produced by `pallet_xcm_bridge_hub_router` is compatible with the `ExportXcm` implementation of `pallet_xcm_bridge_hub`. + type ToBridgeHubSender = SovereignPaidRemoteExporter< + XcmOverBridgeRouter, + // **Note**: The crucial part is that `ExportMessage` is processed by `XcmExecutor`, which calls the `ExportXcm` implementation of `pallet_xcm_bridge_hub` as the `MessageExporter`. + ExecuteXcmOverSendXcm, + Self::UniversalLocation, + >; type LocalXcmChannelManager = TestLocalXcmChannelManager; type ByteFee = ConstU128<0>; diff --git a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs index 2f9d83bd9d0b..891a283ef127 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs @@ -111,6 +111,7 @@ use xcm_runtime_apis::{ }; use weights::{BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight}; +use xcm_builder::SovereignPaidRemoteExporter; impl_opaque_keys! { pub struct SessionKeys { @@ -933,7 +934,12 @@ impl pallet_xcm_bridge_hub_router::Config for Runtim type Bridges = xcm_config::bridging::NetworkExportTable; type DestinationVersion = PolkadotXcm; - type ToBridgeHubSender = XcmpQueue; + // Let's use `SovereignPaidRemoteExporter`, which sends `ExportMessage` over HRMP to the sibling BridgeHub. + type ToBridgeHubSender = SovereignPaidRemoteExporter< + ToWestendXcmRouter, + XcmpQueue, + Self::UniversalLocation, + >; type LocalXcmChannelManager = cumulus_pallet_xcmp_queue::bridging::InAndOutXcmpChannelStatusProvider; diff --git a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs index 63175222cc26..05bd38fdc327 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs @@ -112,6 +112,7 @@ use xcm_runtime_apis::{ }; use weights::{BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight}; +use xcm_builder::SovereignPaidRemoteExporter; impl_opaque_keys! { pub struct SessionKeys { @@ -930,7 +931,12 @@ impl pallet_xcm_bridge_hub_router::Config for Runtime type Bridges = xcm_config::bridging::NetworkExportTable; type DestinationVersion = PolkadotXcm; - type ToBridgeHubSender = XcmpQueue; + // Let's use `SovereignPaidRemoteExporter`, which sends `ExportMessage` over HRMP to the sibling BridgeHub. + type ToBridgeHubSender = SovereignPaidRemoteExporter< + ToRococoXcmRouter, + XcmpQueue, + Self::UniversalLocation, + >; type LocalXcmChannelManager = cumulus_pallet_xcmp_queue::bridging::InAndOutXcmpChannelStatusProvider; From 28a19f872f1083fa73cd6ca85bd2e69e96f3e543 Mon Sep 17 00:00:00 2001 From: Branislav Kontur Date: Fri, 25 Oct 2024 11:09:29 +0200 Subject: [PATCH 03/72] doc --- bridges/modules/xcm-bridge-hub-router/src/lib.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/bridges/modules/xcm-bridge-hub-router/src/lib.rs b/bridges/modules/xcm-bridge-hub-router/src/lib.rs index bfaead8814e0..69cd63512547 100644 --- a/bridges/modules/xcm-bridge-hub-router/src/lib.rs +++ b/bridges/modules/xcm-bridge-hub-router/src/lib.rs @@ -96,9 +96,9 @@ pub mod pallet { /// Checks the XCM version for the destination. type DestinationVersion: GetVersion; - //! The bridge hub may be: - //! - A system (sibling) bridge hub parachain (or another chain), in which case we need an implementation for `T::ToBridgeHubSender` that sends `ExportMessage`, e.g., `SovereignPaidRemoteExporter`. - //! - The local chain, in which case we need an implementation for `T::ToBridgeHubSender` that does not use `ExportMessage` but instead directly calls the `ExportXcm` implementation. + /// The bridge hub may be: + /// - A system (sibling) bridge hub parachain (or another chain), in which case we need an implementation for `T::ToBridgeHubSender` that sends `ExportMessage`, e.g., `SovereignPaidRemoteExporter`. + /// - The local chain, in which case we need an implementation for `T::ToBridgeHubSender` that does not use `ExportMessage` but instead directly calls the `ExportXcm` implementation. type ToBridgeHubSender: SendXcm; /// Local XCM channel manager. type LocalXcmChannelManager: XcmChannelStatusProvider; From 725f66730fea5e885df0809ab49456074b556bc1 Mon Sep 17 00:00:00 2001 From: command-bot <> Date: Fri, 25 Oct 2024 11:26:16 +0000 Subject: [PATCH 04/72] ".git/.scripts/commands/fmt/fmt.sh" --- bridges/modules/xcm-bridge-hub-router/src/lib.rs | 14 +++++++++----- bridges/modules/xcm-bridge-hub-router/src/mock.rs | 4 +++- bridges/modules/xcm-bridge-hub/src/mock.rs | 11 ++++++++--- .../runtimes/assets/asset-hub-rococo/src/lib.rs | 10 ++++------ .../runtimes/assets/asset-hub-westend/src/lib.rs | 10 ++++------ 5 files changed, 28 insertions(+), 21 deletions(-) diff --git a/bridges/modules/xcm-bridge-hub-router/src/lib.rs b/bridges/modules/xcm-bridge-hub-router/src/lib.rs index 69cd63512547..1826d1528efb 100644 --- a/bridges/modules/xcm-bridge-hub-router/src/lib.rs +++ b/bridges/modules/xcm-bridge-hub-router/src/lib.rs @@ -23,8 +23,9 @@ //! queues are congested, it will eventually lead to increased queuing on this chain. //! //! **Note on Terminology**: When we refer to the bridge hub here, we mean the chain that -//! has the `pallet-bridge-messages` with an `ExportXcm` implementation deployed, e.g., provided by `pallet-xcm-bridge-hub`. -//! Depending on the deployment setup, `T::ToBridgeHubSender` can be configured accordingly - see `T::ToBridgeHubSender` for more documentation. +//! has the `pallet-bridge-messages` with an `ExportXcm` implementation deployed, e.g., provided by +//! `pallet-xcm-bridge-hub`. Depending on the deployment setup, `T::ToBridgeHubSender` can be +//! configured accordingly - see `T::ToBridgeHubSender` for more documentation. #![cfg_attr(not(feature = "std"), no_std)] @@ -97,8 +98,12 @@ pub mod pallet { type DestinationVersion: GetVersion; /// The bridge hub may be: - /// - A system (sibling) bridge hub parachain (or another chain), in which case we need an implementation for `T::ToBridgeHubSender` that sends `ExportMessage`, e.g., `SovereignPaidRemoteExporter`. - /// - The local chain, in which case we need an implementation for `T::ToBridgeHubSender` that does not use `ExportMessage` but instead directly calls the `ExportXcm` implementation. + /// - A system (sibling) bridge hub parachain (or another chain), in which case we need an + /// implementation for `T::ToBridgeHubSender` that sends `ExportMessage`, e.g., + /// `SovereignPaidRemoteExporter`. + /// - The local chain, in which case we need an implementation for `T::ToBridgeHubSender` + /// that does not use `ExportMessage` but instead directly calls the `ExportXcm` + /// implementation. type ToBridgeHubSender: SendXcm; /// Local XCM channel manager. type LocalXcmChannelManager: XcmChannelStatusProvider; @@ -229,7 +234,6 @@ pub mod pallet { } } - // This pallet acts as the `ExporterFor` for the `SovereignPaidRemoteExporter` to compute // message fee using fee factor. impl, I: 'static> ExporterFor for Pallet { diff --git a/bridges/modules/xcm-bridge-hub-router/src/mock.rs b/bridges/modules/xcm-bridge-hub-router/src/mock.rs index aae488e65185..e234c01bc3e5 100644 --- a/bridges/modules/xcm-bridge-hub-router/src/mock.rs +++ b/bridges/modules/xcm-bridge-hub-router/src/mock.rs @@ -27,7 +27,9 @@ use frame_support::{ use sp_runtime::{traits::ConstU128, BuildStorage}; use sp_std::cell::RefCell; use xcm::prelude::*; -use xcm_builder::{InspectMessageQueues, NetworkExportTable, NetworkExportTableItem, SovereignPaidRemoteExporter}; +use xcm_builder::{ + InspectMessageQueues, NetworkExportTable, NetworkExportTableItem, SovereignPaidRemoteExporter, +}; type Block = frame_system::mocking::MockBlock; diff --git a/bridges/modules/xcm-bridge-hub/src/mock.rs b/bridges/modules/xcm-bridge-hub/src/mock.rs index 3037a88a2b1d..0ea3a7194921 100644 --- a/bridges/modules/xcm-bridge-hub/src/mock.rs +++ b/bridges/modules/xcm-bridge-hub/src/mock.rs @@ -208,7 +208,8 @@ impl pallet_xcm_bridge_hub::Config for TestRuntime { type BlobDispatcher = TestBlobDispatcher; } -/// A router instance simulates a scenario where the router is deployed on a different chain than the `MessageExporter`. This means that the router sends an `ExportMessage`. +/// A router instance simulates a scenario where the router is deployed on a different chain than +/// the `MessageExporter`. This means that the router sends an `ExportMessage`. impl pallet_xcm_bridge_hub_router::Config<()> for TestRuntime { type RuntimeEvent = RuntimeEvent; type WeightInfo = (); @@ -219,10 +220,14 @@ impl pallet_xcm_bridge_hub_router::Config<()> for TestRuntime { type Bridges = NetworkExportTable; type DestinationVersion = AlwaysLatest; - // We use `SovereignPaidRemoteExporter` here to test and ensure that the `ExportMessage` produced by `pallet_xcm_bridge_hub_router` is compatible with the `ExportXcm` implementation of `pallet_xcm_bridge_hub`. + // We use `SovereignPaidRemoteExporter` here to test and ensure that the `ExportMessage` + // produced by `pallet_xcm_bridge_hub_router` is compatible with the `ExportXcm` implementation + // of `pallet_xcm_bridge_hub`. type ToBridgeHubSender = SovereignPaidRemoteExporter< XcmOverBridgeRouter, - // **Note**: The crucial part is that `ExportMessage` is processed by `XcmExecutor`, which calls the `ExportXcm` implementation of `pallet_xcm_bridge_hub` as the `MessageExporter`. + // **Note**: The crucial part is that `ExportMessage` is processed by `XcmExecutor`, which + // calls the `ExportXcm` implementation of `pallet_xcm_bridge_hub` as the + // `MessageExporter`. ExecuteXcmOverSendXcm, Self::UniversalLocation, >; diff --git a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs index 891a283ef127..01fd0198cc6b 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs @@ -934,12 +934,10 @@ impl pallet_xcm_bridge_hub_router::Config for Runtim type Bridges = xcm_config::bridging::NetworkExportTable; type DestinationVersion = PolkadotXcm; - // Let's use `SovereignPaidRemoteExporter`, which sends `ExportMessage` over HRMP to the sibling BridgeHub. - type ToBridgeHubSender = SovereignPaidRemoteExporter< - ToWestendXcmRouter, - XcmpQueue, - Self::UniversalLocation, - >; + // Let's use `SovereignPaidRemoteExporter`, which sends `ExportMessage` over HRMP to the sibling + // BridgeHub. + type ToBridgeHubSender = + SovereignPaidRemoteExporter; type LocalXcmChannelManager = cumulus_pallet_xcmp_queue::bridging::InAndOutXcmpChannelStatusProvider; diff --git a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs index 05bd38fdc327..29ca45b36991 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs @@ -931,12 +931,10 @@ impl pallet_xcm_bridge_hub_router::Config for Runtime type Bridges = xcm_config::bridging::NetworkExportTable; type DestinationVersion = PolkadotXcm; - // Let's use `SovereignPaidRemoteExporter`, which sends `ExportMessage` over HRMP to the sibling BridgeHub. - type ToBridgeHubSender = SovereignPaidRemoteExporter< - ToRococoXcmRouter, - XcmpQueue, - Self::UniversalLocation, - >; + // Let's use `SovereignPaidRemoteExporter`, which sends `ExportMessage` over HRMP to the sibling + // BridgeHub. + type ToBridgeHubSender = + SovereignPaidRemoteExporter; type LocalXcmChannelManager = cumulus_pallet_xcmp_queue::bridging::InAndOutXcmpChannelStatusProvider; From 63a1fd6fcd2b00095ab612dd030eb0a65005ad7f Mon Sep 17 00:00:00 2001 From: GitHub Action Date: Fri, 25 Oct 2024 11:53:36 +0000 Subject: [PATCH 05/72] Update from bkontur running command 'prdoc --audience runtime_dev --bump patch --force' --- prdoc/pr_6231.prdoc | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 prdoc/pr_6231.prdoc diff --git a/prdoc/pr_6231.prdoc b/prdoc/pr_6231.prdoc new file mode 100644 index 000000000000..d246843e61fd --- /dev/null +++ b/prdoc/pr_6231.prdoc @@ -0,0 +1,22 @@ +title: Bridges - revert-back and improve congestion +doc: +- audience: Runtime Dev + description: |- + Closes: https://github.com/paritytech/polkadot-sdk/issues/5551 + + ## Description + TBD: + + ## TODO + - [ ] backport to the stable-2024-09-3 till 11.Nov +crates: +- name: pallet-xcm-bridge-hub-router + bump: patch +- name: pallet-xcm-bridge-hub + bump: patch +- name: bp-xcm-bridge-hub-router + bump: patch +- name: asset-hub-rococo-runtime + bump: patch +- name: asset-hub-westend-runtime + bump: patch From a9db6f563e463d044240ee663f8727c14fccc0fa Mon Sep 17 00:00:00 2001 From: Branislav Kontur Date: Fri, 25 Oct 2024 23:10:34 +0200 Subject: [PATCH 06/72] Simplification: Merge `bridge_owner_account` / `deposit` to optional `Deposit` struct (we will need because we don't want/have `Location::Here` converter) --- .../modules/xcm-bridge-hub/src/dispatcher.rs | 7 +- .../modules/xcm-bridge-hub/src/exporter.rs | 11 +- bridges/modules/xcm-bridge-hub/src/lib.rs | 179 +++++++++--------- .../modules/xcm-bridge-hub/src/migration.rs | 101 +++++++++- bridges/primitives/xcm-bridge-hub/src/lib.rs | 30 ++- 5 files changed, 222 insertions(+), 106 deletions(-) diff --git a/bridges/modules/xcm-bridge-hub/src/dispatcher.rs b/bridges/modules/xcm-bridge-hub/src/dispatcher.rs index dd855c7069aa..daa49ed415d3 100644 --- a/bridges/modules/xcm-bridge-hub/src/dispatcher.rs +++ b/bridges/modules/xcm-bridge-hub/src/dispatcher.rs @@ -127,7 +127,6 @@ mod tests { use bp_xcm_bridge_hub::{Bridge, BridgeLocations, BridgeState}; use frame_support::assert_ok; use pallet_bridge_messages::InboundLaneStorage; - use xcm_executor::traits::ConvertLocation; fn bridge() -> (Box, TestLaneIdType) { let origin = OpenBridgeOrigin::sibling_parachain_origin(); @@ -157,11 +156,7 @@ mod tests { bridge.bridge_destination_universal_location().clone().into(), ), state: BridgeState::Opened, - bridge_owner_account: LocationToAccountId::convert_location( - bridge.bridge_origin_relative_location(), - ) - .expect("valid accountId"), - deposit: 0, + deposit: None, lane_id, }, ); diff --git a/bridges/modules/xcm-bridge-hub/src/exporter.rs b/bridges/modules/xcm-bridge-hub/src/exporter.rs index f67ccdde9686..0dcd3a8fccdc 100644 --- a/bridges/modules/xcm-bridge-hub/src/exporter.rs +++ b/bridges/modules/xcm-bridge-hub/src/exporter.rs @@ -367,7 +367,7 @@ mod tests { use frame_support::assert_ok; use pallet_bridge_messages::InboundLaneStorage; use xcm_builder::{NetworkExportTable, UnpaidRemoteExporter}; - use xcm_executor::traits::{export_xcm, ConvertLocation}; + use xcm_executor::traits::export_xcm; fn universal_source() -> InteriorLocation { SiblingUniversalLocation::get() @@ -402,11 +402,7 @@ mod tests { locations.bridge_destination_universal_location().clone().into(), ), state: BridgeState::Opened, - bridge_owner_account: LocationToAccountId::convert_location( - locations.bridge_origin_relative_location(), - ) - .expect("valid accountId"), - deposit: 0, + deposit: None, lane_id, }, ); @@ -618,8 +614,7 @@ mod tests { locations.bridge_destination_universal_location().clone().into(), ), state: BridgeState::Opened, - bridge_owner_account: [0u8; 32].into(), - deposit: 0, + deposit: None, lane_id: expected_lane_id, }, ); diff --git a/bridges/modules/xcm-bridge-hub/src/lib.rs b/bridges/modules/xcm-bridge-hub/src/lib.rs index 1b2536598a20..aa3c755bd348 100644 --- a/bridges/modules/xcm-bridge-hub/src/lib.rs +++ b/bridges/modules/xcm-bridge-hub/src/lib.rs @@ -146,11 +146,10 @@ use bp_messages::{LaneState, MessageNonce}; use bp_runtime::{AccountIdOf, BalanceOf, RangeInclusiveExt}; pub use bp_xcm_bridge_hub::{Bridge, BridgeId, BridgeState}; -use bp_xcm_bridge_hub::{BridgeLocations, BridgeLocationsError, LocalXcmChannelManager}; +use bp_xcm_bridge_hub::{BridgeLocations, BridgeLocationsError, LocalXcmChannelManager, DepositOf, Deposit}; use frame_support::{traits::fungible::MutateHold, DefaultNoBound}; use frame_system::Config as SystemConfig; use pallet_bridge_messages::{Config as BridgeMessagesConfig, LanesManagerError}; -use sp_runtime::traits::Zero; use sp_std::{boxed::Box, vec::Vec}; use xcm::prelude::*; use xcm_builder::DispatchBlob; @@ -409,23 +408,27 @@ pub mod pallet { LaneToBridge::::remove(bridge.lane_id); // return deposit - let released_deposit = T::Currency::release( - &HoldReason::BridgeDeposit.into(), - &bridge.bridge_owner_account, - bridge.deposit, - Precision::BestEffort, - ) - .inspect_err(|e| { - // we can't do anything here - looks like funds have been (partially) unreserved - // before by someone else. Let's not fail, though - it'll be worse for the caller - log::error!( - target: LOG_TARGET, - "Failed to unreserve during the bridge {:?} closure with error: {e:?}", - locations.bridge_id(), - ); - }) - .ok() - .unwrap_or(BalanceOf::>::zero()); + let released_deposit = if let Some(deposit) = bridge.deposit { + T::Currency::release( + &HoldReason::BridgeDeposit.into(), + &deposit.account, + deposit.amount, + Precision::BestEffort, + ) + .inspect_err(|e| { + // we can't do anything here - looks like funds have been (partially) unreserved + // before by someone else. Let's not fail, though - it'll be worse for the caller + log::error!( + target: LOG_TARGET, + "Failed to unreserve during the bridge {:?} closure with error: {e:?}", + locations.bridge_id(), + ); + }) + .map(|released| Deposit::new(deposit.account, released)) + .ok() + } else { + None + }; // write something to log log::trace!( @@ -456,16 +459,17 @@ pub mod pallet { lane_id: T::LaneId, create_lanes: bool, ) -> Result<(), DispatchError> { - // reserve balance on the origin's sovereign account (if needed) - let bridge_owner_account = T::BridgeOriginAccountIdConverter::convert_location( - locations.bridge_origin_relative_location(), - ) - .ok_or(Error::::InvalidBridgeOriginAccount)?; + // reserve balance (if needed) let deposit = if T::AllowWithoutBridgeDeposit::contains( locations.bridge_origin_relative_location(), ) { - BalanceOf::>::zero() + None } else { + // get origin's sovereign account + let bridge_owner_account = T::BridgeOriginAccountIdConverter::convert_location( + locations.bridge_origin_relative_location(), + ).ok_or(Error::::InvalidBridgeOriginAccount)?; + let deposit = T::BridgeDeposit::get(); T::Currency::hold( &HoldReason::BridgeDeposit.into(), @@ -482,7 +486,7 @@ pub mod pallet { ); Error::::FailedToReserveBridgeDeposit })?; - deposit + Some(Deposit::new(bridge_owner_account, deposit)) }; // save bridge metadata @@ -500,8 +504,7 @@ pub mod pallet { locations.bridge_destination_universal_location().clone().into(), ), state: BridgeState::Opened, - bridge_owner_account, - deposit, + deposit: deposit.clone(), lane_id, }); Ok(()) @@ -680,10 +683,12 @@ pub mod pallet { ); // check bridge account owner - ensure!( - T::BridgeOriginAccountIdConverter::convert_location(bridge_origin_relative_location_as_latest) == Some(bridge.bridge_owner_account), - "`bridge.bridge_owner_account` is different than calculated from `bridge.bridge_origin_relative_location`, needs migration!" - ); + if let Some(deposit) = bridge.deposit { + ensure!( + T::BridgeOriginAccountIdConverter::convert_location(bridge_origin_relative_location_as_latest) == Some(deposit.account), + "`bridge.deposit.account` is different than calculated from `bridge.bridge_origin_relative_location`, needs migration!" + ); + } Ok(bridge.lane_id) } @@ -772,8 +777,8 @@ pub mod pallet { BridgeOpened { /// Bridge identifier. bridge_id: BridgeId, - /// Amount of deposit held. - bridge_deposit: BalanceOf>, + /// Bridge deposit held. + bridge_deposit: Option>>, /// Universal location of local bridge endpoint. local_endpoint: Box, @@ -801,7 +806,7 @@ pub mod pallet { /// Lane identifier. lane_id: T::LaneId, /// Amount of deposit released. - bridge_deposit: BalanceOf>, + bridge_deposit: Option>>, /// Number of pruned messages during the close call. pruned_messages: MessageNonce, }, @@ -838,6 +843,7 @@ mod tests { use frame_support::{assert_err, assert_noop, assert_ok, traits::fungible::Mutate, BoundedVec}; use frame_system::{EventRecord, Phase}; + use sp_runtime::traits::Zero; use sp_runtime::TryRuntimeError; fn fund_origin_sovereign_account(locations: &BridgeLocations, balance: Balance) -> AccountId { @@ -850,15 +856,19 @@ mod tests { fn mock_open_bridge_from_with( origin: RuntimeOrigin, - deposit: Balance, + deposit: Option, with: InteriorLocation, ) -> (BridgeOf, BridgeLocations) { let locations = XcmOverBridge::bridge_locations_from_origin(origin, Box::new(with.into())).unwrap(); let lane_id = locations.calculate_lane_id(xcm::latest::VERSION).unwrap(); - let bridge_owner_account = - fund_origin_sovereign_account(&locations, deposit + ExistentialDeposit::get()); - Balances::hold(&HoldReason::BridgeDeposit.into(), &bridge_owner_account, deposit).unwrap(); + + let deposit = deposit.map(|deposit| { + let bridge_owner_account = + fund_origin_sovereign_account(&locations, deposit + ExistentialDeposit::get()); + Balances::hold(&HoldReason::BridgeDeposit.into(), &bridge_owner_account, deposit).unwrap(); + Deposit::new(bridge_owner_account, deposit) + }); let bridge = Bridge { bridge_origin_relative_location: Box::new( @@ -871,7 +881,6 @@ mod tests { locations.bridge_destination_universal_location().clone().into(), ), state: BridgeState::Opened, - bridge_owner_account, deposit, lane_id, }; @@ -889,7 +898,7 @@ mod tests { fn mock_open_bridge_from( origin: RuntimeOrigin, - deposit: Balance, + deposit: Option, ) -> (BridgeOf, BridgeLocations) { mock_open_bridge_from_with(origin, deposit, bridged_asset_hub_universal_location()) } @@ -1013,10 +1022,6 @@ mod tests { ) .unwrap(); let lane_id = locations.calculate_lane_id(xcm::latest::VERSION).unwrap(); - fund_origin_sovereign_account( - &locations, - BridgeDeposit::get() + ExistentialDeposit::get(), - ); Bridges::::insert( locations.bridge_id(), @@ -1031,8 +1036,7 @@ mod tests { locations.bridge_destination_universal_location().clone().into(), ), state: BridgeState::Opened, - bridge_owner_account: [0u8; 32].into(), - deposit: 0, + deposit: None, lane_id, }, ); @@ -1093,14 +1097,14 @@ mod tests { // in our test runtime, we expect that bridge may be opened by parent relay chain // and any sibling parachain let origins = [ - (OpenBridgeOrigin::parent_relay_chain_origin(), 0), - (OpenBridgeOrigin::sibling_parachain_origin(), BridgeDeposit::get()), + (OpenBridgeOrigin::parent_relay_chain_origin(), None), + (OpenBridgeOrigin::sibling_parachain_origin(), Some(BridgeDeposit::get())), ]; // check that every origin may open the bridge let lanes_manager = LanesManagerOf::::new(); let existential_deposit = ExistentialDeposit::get(); - for (origin, expected_deposit) in origins { + for (origin, expected_deposit_amount) in origins { // reset events System::set_block_number(1); System::reset_events(); @@ -1131,15 +1135,18 @@ mod tests { assert_eq!(LaneToBridge::::get(lane_id), None); // give enough funds to the sovereign account of the bridge origin - let bridge_owner_account = fund_origin_sovereign_account( - &locations, - expected_deposit + existential_deposit, - ); - assert_eq!( - Balances::free_balance(&bridge_owner_account), - expected_deposit + existential_deposit - ); - assert_eq!(Balances::reserved_balance(&bridge_owner_account), 0); + let expected_deposit = expected_deposit_amount.map(|deposit_amount| { + let bridge_owner_account = fund_origin_sovereign_account( + &locations, + deposit_amount + existential_deposit, + ); + assert_eq!( + Balances::free_balance(&bridge_owner_account), + deposit_amount + existential_deposit + ); + assert_eq!(Balances::reserved_balance(&bridge_owner_account), 0); + Deposit::new(bridge_owner_account, deposit_amount) + }); // now open the bridge assert_ok!(XcmOverBridge::open_bridge( @@ -1161,8 +1168,7 @@ mod tests { locations.bridge_destination_universal_location().clone().into(), ), state: BridgeState::Opened, - bridge_owner_account: bridge_owner_account.clone(), - deposit: expected_deposit, + deposit: expected_deposit.clone(), lane_id }), ); @@ -1178,8 +1184,10 @@ mod tests { LaneToBridge::::get(lane_id), Some(*locations.bridge_id()) ); - assert_eq!(Balances::free_balance(&bridge_owner_account), existential_deposit); - assert_eq!(Balances::reserved_balance(&bridge_owner_account), expected_deposit); + if let Some(expected_deposit) = expected_deposit.as_ref() { + assert_eq!(Balances::free_balance(&expected_deposit.account), existential_deposit); + assert_eq!(Balances::reserved_balance(&expected_deposit.account), expected_deposit.amount); + } // ensure that the proper event is deposited assert_eq!( @@ -1252,7 +1260,7 @@ mod tests { fn close_bridge_fails_if_its_lanes_are_unknown() { run_test(|| { let origin = OpenBridgeOrigin::parent_relay_chain_origin(); - let (bridge, locations) = mock_open_bridge_from(origin.clone(), 0); + let (bridge, locations) = mock_open_bridge_from(origin.clone(), None); let lanes_manager = LanesManagerOf::::new(); lanes_manager.any_state_inbound_lane(bridge.lane_id).unwrap().purge(); @@ -1266,7 +1274,7 @@ mod tests { ); lanes_manager.any_state_outbound_lane(bridge.lane_id).unwrap().purge(); - let (_, locations) = mock_open_bridge_from(origin.clone(), 0); + let (_, locations) = mock_open_bridge_from(origin.clone(), None); lanes_manager.any_state_outbound_lane(bridge.lane_id).unwrap().purge(); assert_noop!( XcmOverBridge::close_bridge( @@ -1284,12 +1292,13 @@ mod tests { run_test(|| { let origin = OpenBridgeOrigin::parent_relay_chain_origin(); let expected_deposit = BridgeDeposit::get(); - let (bridge, locations) = mock_open_bridge_from(origin.clone(), expected_deposit); + let (bridge, locations) = mock_open_bridge_from(origin.clone(), Some(expected_deposit)); System::set_block_number(1); + let bridge_owner_account = bridge.deposit.unwrap().account; // remember owner balances - let free_balance = Balances::free_balance(&bridge.bridge_owner_account); - let reserved_balance = Balances::reserved_balance(&bridge.bridge_owner_account); + let free_balance = Balances::free_balance(&bridge_owner_account); + let reserved_balance = Balances::reserved_balance(&bridge_owner_account); // enqueue some messages for _ in 0..32 { @@ -1330,8 +1339,8 @@ mod tests { LaneToBridge::::get(bridge.lane_id), Some(*locations.bridge_id()) ); - assert_eq!(Balances::free_balance(&bridge.bridge_owner_account), free_balance); - assert_eq!(Balances::reserved_balance(&bridge.bridge_owner_account), reserved_balance); + assert_eq!(Balances::free_balance(&bridge_owner_account), free_balance); + assert_eq!(Balances::reserved_balance(&bridge_owner_account), reserved_balance); assert_eq!( System::events().last(), Some(&EventRecord { @@ -1378,8 +1387,8 @@ mod tests { LaneToBridge::::get(bridge.lane_id), Some(*locations.bridge_id()) ); - assert_eq!(Balances::free_balance(&bridge.bridge_owner_account), free_balance); - assert_eq!(Balances::reserved_balance(&bridge.bridge_owner_account), reserved_balance); + assert_eq!(Balances::free_balance(&bridge_owner_account), free_balance); + assert_eq!(Balances::reserved_balance(&bridge_owner_account), reserved_balance); assert_eq!( System::events().last(), Some(&EventRecord { @@ -1417,10 +1426,10 @@ mod tests { ); assert_eq!(LaneToBridge::::get(bridge.lane_id), None); assert_eq!( - Balances::free_balance(&bridge.bridge_owner_account), + Balances::free_balance(&bridge_owner_account), free_balance + reserved_balance ); - assert_eq!(Balances::reserved_balance(&bridge.bridge_owner_account), 0); + assert_eq!(Balances::reserved_balance(&bridge_owner_account), 0); assert_eq!( System::events().last(), Some(&EventRecord { @@ -1428,7 +1437,7 @@ mod tests { event: RuntimeEvent::XcmOverBridge(Event::BridgePruned { bridge_id: *locations.bridge_id(), lane_id: bridge.lane_id.into(), - bridge_deposit: expected_deposit, + bridge_deposit: Some(Deposit::new(bridge_owner_account, expected_deposit)), pruned_messages: 8, }), topics: vec![], @@ -1507,8 +1516,7 @@ mod tests { ), ), state: BridgeState::Opened, - bridge_owner_account: bridge_owner_account.clone(), - deposit: Zero::zero(), + deposit: Some(Deposit::new(bridge_owner_account.clone(), Zero::zero())), lane_id, }, (lane_id, bridge_id), @@ -1533,8 +1541,7 @@ mod tests { ), ), state: BridgeState::Opened, - bridge_owner_account: bridge_owner_account.clone(), - deposit: Zero::zero(), + deposit: Some(Deposit::new(bridge_owner_account.clone(), Zero::zero())), lane_id, }, (lane_id, bridge_id_mismatch), @@ -1559,13 +1566,12 @@ mod tests { bridge_destination_universal_location.clone(), )), state: BridgeState::Opened, - bridge_owner_account: bridge_owner_account_mismatch.clone(), - deposit: Zero::zero(), + deposit: Some(Deposit::new(bridge_owner_account_mismatch.clone(), Zero::zero())), lane_id, }, (lane_id, bridge_id), (lane_id, lane_id), - Some(TryRuntimeError::Other("`bridge.bridge_owner_account` is different than calculated from `bridge.bridge_origin_relative_location`, needs migration!")), + Some(TryRuntimeError::Other("`bridge.deposit.account` is different than calculated from `bridge.bridge_origin_relative_location`, needs migration!")), ); cleanup(bridge_id, vec![lane_id]); @@ -1584,8 +1590,7 @@ mod tests { bridge_destination_universal_location.clone(), )), state: BridgeState::Opened, - bridge_owner_account: bridge_owner_account_mismatch.clone(), - deposit: Zero::zero(), + deposit: Some(Deposit::new(bridge_owner_account_mismatch.clone(), Zero::zero())), lane_id, }, (lane_id, bridge_id_mismatch), @@ -1610,8 +1615,7 @@ mod tests { ), ), state: BridgeState::Opened, - bridge_owner_account: bridge_owner_account.clone(), - deposit: Zero::zero(), + deposit: Some(Deposit::new(bridge_owner_account.clone(), Zero::zero())), lane_id, }, (lane_id, bridge_id), @@ -1636,8 +1640,7 @@ mod tests { ), ), state: BridgeState::Opened, - bridge_owner_account: bridge_owner_account.clone(), - deposit: Zero::zero(), + deposit: Some(Deposit::new(bridge_owner_account, Zero::zero())), lane_id, }, (lane_id, bridge_id), diff --git a/bridges/modules/xcm-bridge-hub/src/migration.rs b/bridges/modules/xcm-bridge-hub/src/migration.rs index ffd5233a917b..a8c73a00d2ec 100644 --- a/bridges/modules/xcm-bridge-hub/src/migration.rs +++ b/bridges/modules/xcm-bridge-hub/src/migration.rs @@ -24,7 +24,7 @@ use frame_support::{ use xcm::prelude::{InteriorLocation, Location}; /// The in-code storage version. -pub const STORAGE_VERSION: StorageVersion = StorageVersion::new(0); +pub const STORAGE_VERSION: StorageVersion = StorageVersion::new(1); /// This migration does not modify storage but can be used to open a bridge and link it to the /// specified LaneId. This is useful when we want to open a bridge and use a custom LaneId instead @@ -143,3 +143,102 @@ impl< Ok(()) } } + +/// This module contains data structures that are valid for the initial state of `0`. +/// (used with v1 migration). +pub mod v0 { + use crate::{LaneIdOf, ThisChainOf}; + use bp_messages::LaneIdType; + use bp_runtime::{AccountIdOf, BalanceOf, Chain}; + use bp_xcm_bridge_hub::BridgeState; + use codec::{Decode, Encode, MaxEncodedLen}; + use frame_support::{CloneNoBound, PartialEqNoBound, RuntimeDebugNoBound}; + use scale_info::TypeInfo; + use sp_std::boxed::Box; + use xcm::{VersionedInteriorLocation, VersionedLocation}; + + #[derive( + CloneNoBound, + Decode, + Encode, + Eq, + PartialEqNoBound, + TypeInfo, + MaxEncodedLen, + RuntimeDebugNoBound, + )] + #[scale_info(skip_type_params(ThisChain, LaneId))] + pub(crate) struct Bridge { + pub bridge_origin_relative_location: Box, + pub bridge_origin_universal_location: Box, + pub bridge_destination_universal_location: Box, + pub state: BridgeState, + pub bridge_owner_account: AccountIdOf, + pub deposit: BalanceOf, + pub lane_id: LaneId, + } + + pub(crate) type BridgeOf = Bridge, LaneIdOf>; +} + +/// This migration to `1` updates the metadata of `Bridge`. +pub mod v1 { + use super::*; + use crate::{BalanceOf, Bridge, BridgeOf, Bridges, Deposit, ThisChainOf}; + use frame_support::pallet_prelude::Zero; + use frame_support::traits::UncheckedOnRuntimeUpgrade; + use sp_std::marker::PhantomData; + + /// Migrates the pallet storage to v1. + pub struct UncheckedMigrationV0ToV1(PhantomData<(T, I)>); + + impl, I: 'static> UncheckedOnRuntimeUpgrade for UncheckedMigrationV0ToV1 { + fn on_runtime_upgrade() -> Weight { + let mut weight = T::DbWeight::get().reads(1); + + // Migrate account/deposit to the `Deposit` struct. + let translate = |pre: v0::BridgeOf| -> Option> { + weight.saturating_accrue(T::DbWeight::get().reads_writes(1, 1)); + let v0::Bridge { + bridge_origin_relative_location, + bridge_origin_universal_location, + bridge_destination_universal_location, + state, + bridge_owner_account, + deposit, + lane_id, + } = pre; + + // map deposit to the `Deposit` + let deposit = if deposit > BalanceOf::>::zero() { + Some(Deposit::new(bridge_owner_account, deposit)) + } else { + None + }; + + Some(v1::Bridge { + bridge_origin_relative_location, + bridge_origin_universal_location, + bridge_destination_universal_location, + state, + deposit, + lane_id, + }) + }; + Bridges::::translate_values(translate); + + weight + } + } + + /// [`UncheckedMigrationV0ToV1`] wrapped in a + /// [`VersionedMigration`](frame_support::migrations::VersionedMigration), ensuring the + /// migration is only performed when on-chain version is 0. + pub type MigrationToV1 = frame_support::migrations::VersionedMigration< + 0, + 1, + UncheckedMigrationV0ToV1, + Pallet, + ::DbWeight, + >; +} diff --git a/bridges/primitives/xcm-bridge-hub/src/lib.rs b/bridges/primitives/xcm-bridge-hub/src/lib.rs index 63beb1bc3041..e759c61a7097 100644 --- a/bridges/primitives/xcm-bridge-hub/src/lib.rs +++ b/bridges/primitives/xcm-bridge-hub/src/lib.rs @@ -169,15 +169,39 @@ pub struct Bridge { /// Current bridge state. pub state: BridgeState, - /// Account with the reserved funds. Derived from `self.bridge_origin_relative_location`. - pub bridge_owner_account: AccountIdOf, + /// Reserved amount on the sovereign account of the sibling bridge origin. - pub deposit: BalanceOf, + /// The account is derived from `self.bridge_origin_relative_location`. + pub deposit: Option>, /// Mapping to the unique `LaneId`. pub lane_id: LaneId, } +/// An alias for the bridge deposit of `ThisChain`. +pub type DepositOf = Deposit, BalanceOf>; + +/// A structure containing information about from whom the deposit is reserved. +#[derive( + Clone, Decode, Encode, Eq, PartialEq, TypeInfo, MaxEncodedLen, RuntimeDebug, +)] +pub struct Deposit { + /// Account with the reserved funds. + pub account: AccountId, + /// Reserved amount. + pub amount: Balance, +} + +impl Deposit { + /// Create new deposit. + pub fn new(account: AccountId, amount: Balance) -> Self { + Self { + account, + amount, + } + } +} + /// Locations of bridge endpoints at both sides of the bridge. #[derive(Clone, RuntimeDebug, PartialEq, Eq)] pub struct BridgeLocations { From 382dbe8517c637a284d03e2273a288613af47c03 Mon Sep 17 00:00:00 2001 From: Branislav Kontur Date: Sat, 26 Oct 2024 08:00:55 +0200 Subject: [PATCH 07/72] Update prdoc/pr_6231.prdoc --- prdoc/pr_6231.prdoc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/prdoc/pr_6231.prdoc b/prdoc/pr_6231.prdoc index d246843e61fd..7a5cb6fc48c8 100644 --- a/prdoc/pr_6231.prdoc +++ b/prdoc/pr_6231.prdoc @@ -20,3 +20,5 @@ crates: bump: patch - name: asset-hub-westend-runtime bump: patch +- name: bp-xcm-bridge-hub + bump: patch From 660b3fa70a38ea19fb2cae50ad9d0ae029c62dda Mon Sep 17 00:00:00 2001 From: Branislav Kontur Date: Sat, 26 Oct 2024 22:23:56 +0200 Subject: [PATCH 08/72] Add tests that `pallet-xcm-bridge-hub-router` can work locally with `pallet-xcm-bridge-hub` for `ExportXcm` (needed for AH deploymend) --- .../modules/xcm-bridge-hub/src/exporter.rs | 133 ++++++++++-------- bridges/modules/xcm-bridge-hub/src/lib.rs | 15 +- bridges/modules/xcm-bridge-hub/src/mock.rs | 68 +++++++-- 3 files changed, 130 insertions(+), 86 deletions(-) diff --git a/bridges/modules/xcm-bridge-hub/src/exporter.rs b/bridges/modules/xcm-bridge-hub/src/exporter.rs index 0dcd3a8fccdc..3a2f811ac772 100644 --- a/bridges/modules/xcm-bridge-hub/src/exporter.rs +++ b/bridges/modules/xcm-bridge-hub/src/exporter.rs @@ -133,8 +133,9 @@ where let bridge = Self::bridge(locations.bridge_id()).ok_or_else(|| { log::error!( target: LOG_TARGET, - "No opened bridge for requested bridge_origin_relative_location: {:?} and bridge_destination_universal_location: {:?}", + "No opened bridge for requested bridge_origin_relative_location: {:?} (bridge_origin_universal_location: {:?}) and bridge_destination_universal_location: {:?}", locations.bridge_origin_relative_location(), + locations.bridge_origin_universal_location(), locations.bridge_destination_universal_location(), ); SendError::NotApplicable @@ -360,12 +361,12 @@ impl HaulBlob for DummyHaulBlob { #[cfg(test)] mod tests { use super::*; - use crate::{mock::*, Bridges, LaneToBridge, LanesManagerOf}; + use crate::{mock::*, Bridges, LanesManagerOf}; use bp_runtime::RangeInclusiveExt; use bp_xcm_bridge_hub::{Bridge, BridgeLocations, BridgeState}; use frame_support::assert_ok; - use pallet_bridge_messages::InboundLaneStorage; + use frame_support::traits::{Contains, EnsureOrigin}; use xcm_builder::{NetworkExportTable, UnpaidRemoteExporter}; use xcm_executor::traits::export_xcm; @@ -381,61 +382,31 @@ mod tests { BridgedUniversalDestination::get() } - fn open_lane() -> (BridgeLocations, TestLaneIdType) { + fn open_lane(origin: RuntimeOrigin) -> (BridgeLocations, TestLaneIdType) { // open expected outbound lane - let origin = OpenBridgeOrigin::sibling_parachain_origin(); let with = bridged_asset_hub_universal_location(); let locations = - XcmOverBridge::bridge_locations_from_origin(origin, Box::new(with.into())).unwrap(); + XcmOverBridge::bridge_locations_from_origin(origin.clone(), Box::new(with.into())).unwrap(); let lane_id = locations.calculate_lane_id(xcm::latest::VERSION).unwrap(); if !Bridges::::contains_key(locations.bridge_id()) { - // insert bridge - Bridges::::insert( - locations.bridge_id(), - Bridge { - bridge_origin_relative_location: Box::new(SiblingLocation::get().into()), - bridge_origin_universal_location: Box::new( - locations.bridge_origin_universal_location().clone().into(), - ), - bridge_destination_universal_location: Box::new( - locations.bridge_destination_universal_location().clone().into(), - ), - state: BridgeState::Opened, - deposit: None, - lane_id, - }, - ); - LaneToBridge::::insert(lane_id, locations.bridge_id()); - - // create lanes - let lanes_manager = LanesManagerOf::::new(); - if lanes_manager.create_inbound_lane(lane_id).is_ok() { - assert_eq!( - 0, - lanes_manager - .active_inbound_lane(lane_id) - .unwrap() - .storage() - .data() - .last_confirmed_nonce - ); - } - if lanes_manager.create_outbound_lane(lane_id).is_ok() { - assert!(lanes_manager - .active_outbound_lane(lane_id) - .unwrap() - .queued_messages() - .is_empty()); + // fund origin (if needed) + if !>::AllowWithoutBridgeDeposit::contains( + locations.bridge_origin_relative_location() + ) { + fund_origin_sovereign_account(&locations, BridgeDeposit::get() + ExistentialDeposit::get()); } + + // open bridge + assert_ok!(XcmOverBridge::do_open_bridge(locations.clone(), lane_id, true)); } assert_ok!(XcmOverBridge::do_try_state()); (*locations, lane_id) } - fn open_lane_and_send_regular_message() -> (BridgeId, TestLaneIdType) { - let (locations, lane_id) = open_lane(); + fn open_lane_and_send_regular_message(source_origin: RuntimeOrigin) -> (BridgeId, TestLaneIdType) { + let (locations, lane_id) = open_lane(source_origin); // now let's try to enqueue message using our `ExportXcm` implementation export_xcm::( @@ -453,7 +424,7 @@ mod tests { #[test] fn exporter_works() { run_test(|| { - let (_, lane_id) = open_lane_and_send_regular_message(); + let (_, lane_id) = open_lane_and_send_regular_message(OpenBridgeOrigin::sibling_parachain_origin()); // double check that the message has been pushed to the expected lane // (it should already been checked during `send_message` call) @@ -468,7 +439,7 @@ mod tests { #[test] fn exporter_does_not_suspend_the_bridge_if_outbound_bridge_queue_is_not_congested() { run_test(|| { - let (bridge_id, _) = open_lane_and_send_regular_message(); + let (bridge_id, _) = open_lane_and_send_regular_message(OpenBridgeOrigin::sibling_parachain_origin()); assert!(!TestLocalXcmChannelManager::is_bridge_suspened()); assert_eq!(XcmOverBridge::bridge(&bridge_id).unwrap().state, BridgeState::Opened); }); @@ -477,15 +448,15 @@ mod tests { #[test] fn exporter_does_not_suspend_the_bridge_if_it_is_already_suspended() { run_test(|| { - let (bridge_id, _) = open_lane_and_send_regular_message(); + let (bridge_id, _) = open_lane_and_send_regular_message(OpenBridgeOrigin::sibling_parachain_origin()); Bridges::::mutate_extant(bridge_id, |bridge| { bridge.state = BridgeState::Suspended; }); for _ in 1..OUTBOUND_LANE_CONGESTED_THRESHOLD { - open_lane_and_send_regular_message(); + open_lane_and_send_regular_message(OpenBridgeOrigin::sibling_parachain_origin()); } - open_lane_and_send_regular_message(); + open_lane_and_send_regular_message(OpenBridgeOrigin::sibling_parachain_origin()); assert!(!TestLocalXcmChannelManager::is_bridge_suspened()); }); } @@ -493,15 +464,15 @@ mod tests { #[test] fn exporter_suspends_the_bridge_if_outbound_bridge_queue_is_congested() { run_test(|| { - let (bridge_id, _) = open_lane_and_send_regular_message(); + let (bridge_id, _) = open_lane_and_send_regular_message(OpenBridgeOrigin::sibling_parachain_origin()); for _ in 1..OUTBOUND_LANE_CONGESTED_THRESHOLD { - open_lane_and_send_regular_message(); + open_lane_and_send_regular_message(OpenBridgeOrigin::sibling_parachain_origin()); } assert!(!TestLocalXcmChannelManager::is_bridge_suspened()); assert_eq!(XcmOverBridge::bridge(&bridge_id).unwrap().state, BridgeState::Opened); - open_lane_and_send_regular_message(); + open_lane_and_send_regular_message(OpenBridgeOrigin::sibling_parachain_origin()); assert!(TestLocalXcmChannelManager::is_bridge_suspened()); assert_eq!(XcmOverBridge::bridge(&bridge_id).unwrap().state, BridgeState::Suspended); }); @@ -510,7 +481,7 @@ mod tests { #[test] fn bridge_is_not_resumed_if_outbound_bridge_queue_is_still_congested() { run_test(|| { - let (bridge_id, lane_id) = open_lane_and_send_regular_message(); + let (bridge_id, lane_id) = open_lane_and_send_regular_message(OpenBridgeOrigin::sibling_parachain_origin()); Bridges::::mutate_extant(bridge_id, |bridge| { bridge.state = BridgeState::Suspended; }); @@ -527,7 +498,7 @@ mod tests { #[test] fn bridge_is_not_resumed_if_it_was_not_suspended_before() { run_test(|| { - let (bridge_id, lane_id) = open_lane_and_send_regular_message(); + let (bridge_id, lane_id) = open_lane_and_send_regular_message(OpenBridgeOrigin::sibling_parachain_origin()); XcmOverBridge::on_bridge_messages_delivered( lane_id, OUTBOUND_LANE_UNCONGESTED_THRESHOLD, @@ -541,7 +512,7 @@ mod tests { #[test] fn bridge_is_resumed_when_enough_messages_are_delivered() { run_test(|| { - let (bridge_id, lane_id) = open_lane_and_send_regular_message(); + let (bridge_id, lane_id) = open_lane_and_send_regular_message(OpenBridgeOrigin::sibling_parachain_origin()); Bridges::::mutate_extant(bridge_id, |bridge| { bridge.state = BridgeState::Suspended; }); @@ -637,13 +608,15 @@ mod tests { } #[test] - fn exporter_is_compatible_with_pallet_xcm_bridge_hub_router() { + fn pallet_as_exporter_is_compatible_with_pallet_xcm_bridge_hub_router_for_export_message() { run_test(|| { // valid routable destination let dest = Location::new(2, BridgedUniversalDestination::get()); // open bridge - let (_, expected_lane_id) = open_lane(); + let origin = OpenBridgeOrigin::sibling_parachain_origin(); + let origin_as_location = OpenBridgeOriginOf::::try_origin(origin.clone()).unwrap(); + let (_, expected_lane_id) = open_lane(origin); // check before - no messages assert_eq!( @@ -657,7 +630,7 @@ mod tests { ); // send `ExportMessage(message)` by `UnpaidRemoteExporter`. - ExecuteXcmOverSendXcm::set_origin_for_execute(SiblingLocation::get()); + ExecuteXcmOverSendXcm::set_origin_for_execute(origin_as_location.clone()); assert_ok!(send_xcm::< UnpaidRemoteExporter< NetworkExportTable, @@ -667,8 +640,8 @@ mod tests { >(dest.clone(), Xcm::<()>::default())); // send `ExportMessage(message)` by `pallet_xcm_bridge_hub_router`. - ExecuteXcmOverSendXcm::set_origin_for_execute(SiblingLocation::get()); - assert_ok!(send_xcm::(dest.clone(), Xcm::<()>::default())); + ExecuteXcmOverSendXcm::set_origin_for_execute(origin_as_location); + assert_ok!(send_xcm::(dest, Xcm::<()>::default())); // check after - a message ready to be relayed assert_eq!( @@ -683,6 +656,42 @@ mod tests { }) } + #[test] + fn pallet_as_exporter_is_compatible_with_pallet_xcm_bridge_hub_router_for_export_xcm() { + run_test(|| { + // valid routable destination + let dest = Location::new(2, BridgedUniversalDestination::get()); + + // open bridge as a root on the local chain, which should be converted as `Location::here()` + let (_, expected_lane_id) = open_lane(RuntimeOrigin::root()); + + // check before - no messages + assert_eq!( + pallet_bridge_messages::Pallet::::outbound_lane_data( + expected_lane_id + ) + .unwrap() + .queued_messages() + .saturating_len(), + 0 + ); + + // trigger `ExportXcm` by `pallet_xcm_bridge_hub_router`. + assert_ok!(send_xcm::(dest, Xcm::<()>::default())); + + // check after - a message ready to be relayed + assert_eq!( + pallet_bridge_messages::Pallet::::outbound_lane_data( + expected_lane_id + ) + .unwrap() + .queued_messages() + .saturating_len(), + 1 + ); + }) + } + #[test] fn validate_works() { run_test(|| { @@ -760,7 +769,7 @@ mod tests { ); // ok - let _ = open_lane(); + let _ = open_lane(OpenBridgeOrigin::sibling_parachain_origin()); let mut dest_wrapper = Some(bridged_relative_destination()); assert_ok!(XcmOverBridge::validate( BridgedRelayNetwork::get(), diff --git a/bridges/modules/xcm-bridge-hub/src/lib.rs b/bridges/modules/xcm-bridge-hub/src/lib.rs index aa3c755bd348..7429ff6da455 100644 --- a/bridges/modules/xcm-bridge-hub/src/lib.rs +++ b/bridges/modules/xcm-bridge-hub/src/lib.rs @@ -841,19 +841,11 @@ mod tests { use bp_messages::LaneIdType; use mock::*; - use frame_support::{assert_err, assert_noop, assert_ok, traits::fungible::Mutate, BoundedVec}; + use frame_support::{assert_err, assert_noop, assert_ok, BoundedVec}; use frame_system::{EventRecord, Phase}; use sp_runtime::traits::Zero; use sp_runtime::TryRuntimeError; - fn fund_origin_sovereign_account(locations: &BridgeLocations, balance: Balance) -> AccountId { - let bridge_owner_account = - LocationToAccountId::convert_location(locations.bridge_origin_relative_location()) - .unwrap(); - assert_ok!(Balances::mint_into(&bridge_owner_account, balance)); - bridge_owner_account - } - fn mock_open_bridge_from_with( origin: RuntimeOrigin, deposit: Option, @@ -1094,11 +1086,12 @@ mod tests { #[test] fn open_bridge_works() { run_test(|| { - // in our test runtime, we expect that bridge may be opened by parent relay chain - // and any sibling parachain + // in our test runtime, we expect that bridge may be opened by parent relay chain, + // any sibling parachain or local root let origins = [ (OpenBridgeOrigin::parent_relay_chain_origin(), None), (OpenBridgeOrigin::sibling_parachain_origin(), Some(BridgeDeposit::get())), + (RuntimeOrigin::root(), None), ]; // check that every origin may open the bridge diff --git a/bridges/modules/xcm-bridge-hub/src/mock.rs b/bridges/modules/xcm-bridge-hub/src/mock.rs index 0ea3a7194921..db824120d5d4 100644 --- a/bridges/modules/xcm-bridge-hub/src/mock.rs +++ b/bridges/modules/xcm-bridge-hub/src/mock.rs @@ -17,19 +17,23 @@ #![cfg(test)] use crate as pallet_xcm_bridge_hub; +use std::marker::PhantomData; use bp_messages::{ target_chain::{DispatchMessage, MessageDispatch}, ChainWithMessages, HashedLaneId, MessageNonce, }; use bp_runtime::{messages::MessageDispatchResult, Chain, ChainId, HashOf}; -use bp_xcm_bridge_hub::{BridgeId, LocalXcmChannelManager}; +use bp_xcm_bridge_hub::{BridgeId, BridgeLocations, LocalXcmChannelManager}; use codec::Encode; use frame_support::{ assert_ok, derive_impl, parameter_types, traits::{EnsureOrigin, Equals, Everything, OriginTrait}, weights::RuntimeDbWeight, }; +use frame_support::traits::EitherOf; +use frame_support::traits::fungible::Mutate; +use frame_system::{EnsureRoot, EnsureRootWithSuccess}; use polkadot_parachain_primitives::primitives::Sibling; use sp_core::H256; use sp_runtime::{ @@ -42,8 +46,9 @@ use xcm::{latest::ROCOCO_GENESIS_HASH, prelude::*}; use xcm_builder::{ AllowUnpaidExecutionFrom, DispatchBlob, DispatchBlobError, FixedWeightBounds, InspectMessageQueues, NetworkExportTable, NetworkExportTableItem, ParentIsPreset, - SiblingParachainConvertsVia, SovereignPaidRemoteExporter, + SiblingParachainConvertsVia, SovereignPaidRemoteExporter, UnpaidLocalExporter }; +use xcm_executor::traits::{ConvertLocation, ConvertOrigin}; use xcm_executor::XcmExecutor; pub type AccountId = AccountId32; @@ -63,7 +68,8 @@ frame_support::construct_runtime! { Balances: pallet_balances, Messages: pallet_bridge_messages, XcmOverBridge: pallet_xcm_bridge_hub, - XcmOverBridgeRouter: pallet_xcm_bridge_hub_router = 57, + XcmOverBridgeWrappedWithExportMessageRouter: pallet_xcm_bridge_hub_router = 57, + XcmOverBridgeByExportXcmRouter: pallet_xcm_bridge_hub_router:: = 69, } } @@ -148,6 +154,7 @@ impl pallet_bridge_messages::WeightInfoExt for TestMessagesWeights { } parameter_types! { + pub const HereLocation: Location = Location::here(); pub const RelayNetwork: NetworkId = NetworkId::Kusama; pub UniversalLocation: InteriorLocation = [ GlobalConsensus(RelayNetwork::get()), @@ -195,13 +202,20 @@ impl pallet_xcm_bridge_hub::Config for TestRuntime { type DestinationVersion = AlwaysLatest; type ForceOrigin = frame_system::EnsureNever<()>; - type OpenBridgeOrigin = OpenBridgeOrigin; + type OpenBridgeOrigin = EitherOf< + // We want to translate `RuntimeOrigin::root()` to the `Location::here()` + EnsureRootWithSuccess, + OpenBridgeOrigin, + >; type BridgeOriginAccountIdConverter = LocationToAccountId; type BridgeDeposit = BridgeDeposit; type Currency = Balances; type RuntimeHoldReason = RuntimeHoldReason; - type AllowWithoutBridgeDeposit = Equals; + type AllowWithoutBridgeDeposit = ( + Equals, + Equals + ); type LocalXcmChannelManager = TestLocalXcmChannelManager; @@ -224,7 +238,7 @@ impl pallet_xcm_bridge_hub_router::Config<()> for TestRuntime { // produced by `pallet_xcm_bridge_hub_router` is compatible with the `ExportXcm` implementation // of `pallet_xcm_bridge_hub`. type ToBridgeHubSender = SovereignPaidRemoteExporter< - XcmOverBridgeRouter, + XcmOverBridgeWrappedWithExportMessageRouter, // **Note**: The crucial part is that `ExportMessage` is processed by `XcmExecutor`, which // calls the `ExportXcm` implementation of `pallet_xcm_bridge_hub` as the // `MessageExporter`. @@ -237,6 +251,28 @@ impl pallet_xcm_bridge_hub_router::Config<()> for TestRuntime { type FeeAsset = BridgeFeeAsset; } +/// A router instance simulates a scenario where the router is deployed on the same chain than the `MessageExporter`. This means that the router triggers `ExportXcm` trait directly. +impl pallet_xcm_bridge_hub_router::Config for TestRuntime { + type RuntimeEvent = RuntimeEvent; + type WeightInfo = (); + + type UniversalLocation = UniversalLocation; + type SiblingBridgeHubLocation = BridgeHubLocation; + type BridgedNetworkId = BridgedRelayNetwork; + type Bridges = NetworkExportTable; + type DestinationVersion = AlwaysLatest; + + // We use `UnpaidLocalExporter` here to test and ensure that `pallet_xcm_bridge_hub_router` can trigger directly `pallet_xcm_bridge_hub` as exporter. + type ToBridgeHubSender = UnpaidLocalExporter< + XcmOverBridge, + Self::UniversalLocation, + >; + type LocalXcmChannelManager = TestLocalXcmChannelManager; + + type ByteFee = ConstU128<0>; + type FeeAsset = BridgeFeeAsset; +} + pub struct XcmConfig; impl xcm_executor::Config for XcmConfig { type RuntimeCall = RuntimeCall; @@ -384,13 +420,9 @@ impl EnsureOrigin for OpenBridgeOrigin { return Ok(Location { parents: 1, interior: [Parachain(SIBLING_ASSET_HUB_ID), OnlyChild].into(), - }) - } - - let mut sibling_account = [0u8; 32]; - sibling_account[..4].copy_from_slice(&SIBLING_ASSET_HUB_ID.encode()[..4]); - if signer == Some(sibling_account.into()) { - return Ok(Location { parents: 1, interior: Parachain(SIBLING_ASSET_HUB_ID).into() }) + }); + } else if signer == Self::sibling_parachain_origin().into_signer() { + return Ok(SiblingLocation::get()); } Err(o) @@ -402,6 +434,16 @@ impl EnsureOrigin for OpenBridgeOrigin { } } +pub(crate) type OpenBridgeOriginOf = >::OpenBridgeOrigin; + +pub(crate) fn fund_origin_sovereign_account(locations: &BridgeLocations, balance: Balance) -> AccountId { + let bridge_owner_account = + LocationToAccountId::convert_location(locations.bridge_origin_relative_location()) + .unwrap(); + assert_ok!(Balances::mint_into(&bridge_owner_account, balance)); + bridge_owner_account +} + pub struct TestLocalXcmChannelManager; impl TestLocalXcmChannelManager { From 3b36975eca948fe17d9b70f6cadbdc123c22e6a8 Mon Sep 17 00:00:00 2001 From: Branislav Kontur Date: Sat, 26 Oct 2024 22:24:14 +0200 Subject: [PATCH 09/72] Fix testnet runtimes --- bridges/modules/xcm-bridge-hub/src/mock.rs | 5 ++--- .../bridge-hubs/bridge-hub-rococo/src/lib.rs | 4 ++++ .../bridge-hubs/bridge-hub-westend/src/lib.rs | 4 ++++ .../bridge-hubs/test-utils/src/test_cases/mod.rs | 14 ++++++++------ prdoc/pr_6231.prdoc | 4 ++++ 5 files changed, 22 insertions(+), 9 deletions(-) diff --git a/bridges/modules/xcm-bridge-hub/src/mock.rs b/bridges/modules/xcm-bridge-hub/src/mock.rs index db824120d5d4..153027590e42 100644 --- a/bridges/modules/xcm-bridge-hub/src/mock.rs +++ b/bridges/modules/xcm-bridge-hub/src/mock.rs @@ -17,7 +17,6 @@ #![cfg(test)] use crate as pallet_xcm_bridge_hub; -use std::marker::PhantomData; use bp_messages::{ target_chain::{DispatchMessage, MessageDispatch}, @@ -33,7 +32,7 @@ use frame_support::{ }; use frame_support::traits::EitherOf; use frame_support::traits::fungible::Mutate; -use frame_system::{EnsureRoot, EnsureRootWithSuccess}; +use frame_system::EnsureRootWithSuccess; use polkadot_parachain_primitives::primitives::Sibling; use sp_core::H256; use sp_runtime::{ @@ -48,7 +47,7 @@ use xcm_builder::{ InspectMessageQueues, NetworkExportTable, NetworkExportTableItem, ParentIsPreset, SiblingParachainConvertsVia, SovereignPaidRemoteExporter, UnpaidLocalExporter }; -use xcm_executor::traits::{ConvertLocation, ConvertOrigin}; +use xcm_executor::traits::ConvertLocation; use xcm_executor::XcmExecutor; pub type AccountId = AccountId32; diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs index ff7af475f5e2..421f1e0a934f 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs @@ -181,6 +181,10 @@ pub type Migrations = ( RocksDbWeight, >, pallet_bridge_relayers::migration::v1::MigrationToV1, + pallet_xcm_bridge_hub::migration::v1::MigrationToV1< + Runtime, + bridge_to_westend_config::XcmOverBridgeHubWestendInstance, + >, // permanent pallet_xcm::migration::MigrateToLatestXcmVersion, ); diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs index 065400016791..5f953c7c0640 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs @@ -161,6 +161,10 @@ pub type Migrations = ( RocksDbWeight, >, pallet_bridge_relayers::migration::v1::MigrationToV1, + pallet_xcm_bridge_hub::migration::v1::MigrationToV1< + Runtime, + bridge_to_rococo_config::XcmOverBridgeHubRococoInstance, + >, snowbridge_pallet_system::migration::v0::InitializeOnUpgrade< Runtime, ConstU32, diff --git a/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/mod.rs b/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/mod.rs index ad6db0b83e80..4450310c1bef 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/mod.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/mod.rs @@ -681,11 +681,16 @@ pub fn open_and_close_bridge_works>::AllowWithoutBridgeDeposit::contains( locations.bridge_origin_relative_location() ) { - Zero::zero() + None } else { - >::BridgeDeposit::get() + >>::BridgeDeposit::get(); + + Some(bp_xcm_bridge_hub::Deposit::new(bridge_owner_account, deposit)) }; // check bridge/lane DOES not exist @@ -735,9 +740,6 @@ pub fn open_and_close_bridge_works Date: Sat, 26 Oct 2024 20:32:14 +0000 Subject: [PATCH 10/72] ".git/.scripts/commands/fmt/fmt.sh" --- .../modules/xcm-bridge-hub/src/exporter.rs | 52 +++++++++++++------ bridges/modules/xcm-bridge-hub/src/lib.rs | 23 +++++--- .../modules/xcm-bridge-hub/src/migration.rs | 3 +- bridges/modules/xcm-bridge-hub/src/mock.rs | 36 ++++++------- bridges/primitives/xcm-bridge-hub/src/lib.rs | 9 +--- .../test-utils/src/test_cases/mod.rs | 5 +- 6 files changed, 73 insertions(+), 55 deletions(-) diff --git a/bridges/modules/xcm-bridge-hub/src/exporter.rs b/bridges/modules/xcm-bridge-hub/src/exporter.rs index 3a2f811ac772..295ea2301ab4 100644 --- a/bridges/modules/xcm-bridge-hub/src/exporter.rs +++ b/bridges/modules/xcm-bridge-hub/src/exporter.rs @@ -365,8 +365,10 @@ mod tests { use bp_runtime::RangeInclusiveExt; use bp_xcm_bridge_hub::{Bridge, BridgeLocations, BridgeState}; - use frame_support::assert_ok; - use frame_support::traits::{Contains, EnsureOrigin}; + use frame_support::{ + assert_ok, + traits::{Contains, EnsureOrigin}, + }; use xcm_builder::{NetworkExportTable, UnpaidRemoteExporter}; use xcm_executor::traits::export_xcm; @@ -386,15 +388,19 @@ mod tests { // open expected outbound lane let with = bridged_asset_hub_universal_location(); let locations = - XcmOverBridge::bridge_locations_from_origin(origin.clone(), Box::new(with.into())).unwrap(); + XcmOverBridge::bridge_locations_from_origin(origin.clone(), Box::new(with.into())) + .unwrap(); let lane_id = locations.calculate_lane_id(xcm::latest::VERSION).unwrap(); if !Bridges::::contains_key(locations.bridge_id()) { // fund origin (if needed) if !>::AllowWithoutBridgeDeposit::contains( - locations.bridge_origin_relative_location() + locations.bridge_origin_relative_location(), ) { - fund_origin_sovereign_account(&locations, BridgeDeposit::get() + ExistentialDeposit::get()); + fund_origin_sovereign_account( + &locations, + BridgeDeposit::get() + ExistentialDeposit::get(), + ); } // open bridge @@ -405,7 +411,9 @@ mod tests { (*locations, lane_id) } - fn open_lane_and_send_regular_message(source_origin: RuntimeOrigin) -> (BridgeId, TestLaneIdType) { + fn open_lane_and_send_regular_message( + source_origin: RuntimeOrigin, + ) -> (BridgeId, TestLaneIdType) { let (locations, lane_id) = open_lane(source_origin); // now let's try to enqueue message using our `ExportXcm` implementation @@ -424,7 +432,8 @@ mod tests { #[test] fn exporter_works() { run_test(|| { - let (_, lane_id) = open_lane_and_send_regular_message(OpenBridgeOrigin::sibling_parachain_origin()); + let (_, lane_id) = + open_lane_and_send_regular_message(OpenBridgeOrigin::sibling_parachain_origin()); // double check that the message has been pushed to the expected lane // (it should already been checked during `send_message` call) @@ -439,7 +448,8 @@ mod tests { #[test] fn exporter_does_not_suspend_the_bridge_if_outbound_bridge_queue_is_not_congested() { run_test(|| { - let (bridge_id, _) = open_lane_and_send_regular_message(OpenBridgeOrigin::sibling_parachain_origin()); + let (bridge_id, _) = + open_lane_and_send_regular_message(OpenBridgeOrigin::sibling_parachain_origin()); assert!(!TestLocalXcmChannelManager::is_bridge_suspened()); assert_eq!(XcmOverBridge::bridge(&bridge_id).unwrap().state, BridgeState::Opened); }); @@ -448,7 +458,8 @@ mod tests { #[test] fn exporter_does_not_suspend_the_bridge_if_it_is_already_suspended() { run_test(|| { - let (bridge_id, _) = open_lane_and_send_regular_message(OpenBridgeOrigin::sibling_parachain_origin()); + let (bridge_id, _) = + open_lane_and_send_regular_message(OpenBridgeOrigin::sibling_parachain_origin()); Bridges::::mutate_extant(bridge_id, |bridge| { bridge.state = BridgeState::Suspended; }); @@ -464,7 +475,8 @@ mod tests { #[test] fn exporter_suspends_the_bridge_if_outbound_bridge_queue_is_congested() { run_test(|| { - let (bridge_id, _) = open_lane_and_send_regular_message(OpenBridgeOrigin::sibling_parachain_origin()); + let (bridge_id, _) = + open_lane_and_send_regular_message(OpenBridgeOrigin::sibling_parachain_origin()); for _ in 1..OUTBOUND_LANE_CONGESTED_THRESHOLD { open_lane_and_send_regular_message(OpenBridgeOrigin::sibling_parachain_origin()); } @@ -481,7 +493,8 @@ mod tests { #[test] fn bridge_is_not_resumed_if_outbound_bridge_queue_is_still_congested() { run_test(|| { - let (bridge_id, lane_id) = open_lane_and_send_regular_message(OpenBridgeOrigin::sibling_parachain_origin()); + let (bridge_id, lane_id) = + open_lane_and_send_regular_message(OpenBridgeOrigin::sibling_parachain_origin()); Bridges::::mutate_extant(bridge_id, |bridge| { bridge.state = BridgeState::Suspended; }); @@ -498,7 +511,8 @@ mod tests { #[test] fn bridge_is_not_resumed_if_it_was_not_suspended_before() { run_test(|| { - let (bridge_id, lane_id) = open_lane_and_send_regular_message(OpenBridgeOrigin::sibling_parachain_origin()); + let (bridge_id, lane_id) = + open_lane_and_send_regular_message(OpenBridgeOrigin::sibling_parachain_origin()); XcmOverBridge::on_bridge_messages_delivered( lane_id, OUTBOUND_LANE_UNCONGESTED_THRESHOLD, @@ -512,7 +526,8 @@ mod tests { #[test] fn bridge_is_resumed_when_enough_messages_are_delivered() { run_test(|| { - let (bridge_id, lane_id) = open_lane_and_send_regular_message(OpenBridgeOrigin::sibling_parachain_origin()); + let (bridge_id, lane_id) = + open_lane_and_send_regular_message(OpenBridgeOrigin::sibling_parachain_origin()); Bridges::::mutate_extant(bridge_id, |bridge| { bridge.state = BridgeState::Suspended; }); @@ -615,7 +630,8 @@ mod tests { // open bridge let origin = OpenBridgeOrigin::sibling_parachain_origin(); - let origin_as_location = OpenBridgeOriginOf::::try_origin(origin.clone()).unwrap(); + let origin_as_location = + OpenBridgeOriginOf::::try_origin(origin.clone()).unwrap(); let (_, expected_lane_id) = open_lane(origin); // check before - no messages @@ -641,7 +657,10 @@ mod tests { // send `ExportMessage(message)` by `pallet_xcm_bridge_hub_router`. ExecuteXcmOverSendXcm::set_origin_for_execute(origin_as_location); - assert_ok!(send_xcm::(dest, Xcm::<()>::default())); + assert_ok!(send_xcm::( + dest, + Xcm::<()>::default() + )); // check after - a message ready to be relayed assert_eq!( @@ -662,7 +681,8 @@ mod tests { // valid routable destination let dest = Location::new(2, BridgedUniversalDestination::get()); - // open bridge as a root on the local chain, which should be converted as `Location::here()` + // open bridge as a root on the local chain, which should be converted as + // `Location::here()` let (_, expected_lane_id) = open_lane(RuntimeOrigin::root()); // check before - no messages diff --git a/bridges/modules/xcm-bridge-hub/src/lib.rs b/bridges/modules/xcm-bridge-hub/src/lib.rs index 7429ff6da455..ca581aca45d7 100644 --- a/bridges/modules/xcm-bridge-hub/src/lib.rs +++ b/bridges/modules/xcm-bridge-hub/src/lib.rs @@ -146,7 +146,9 @@ use bp_messages::{LaneState, MessageNonce}; use bp_runtime::{AccountIdOf, BalanceOf, RangeInclusiveExt}; pub use bp_xcm_bridge_hub::{Bridge, BridgeId, BridgeState}; -use bp_xcm_bridge_hub::{BridgeLocations, BridgeLocationsError, LocalXcmChannelManager, DepositOf, Deposit}; +use bp_xcm_bridge_hub::{ + BridgeLocations, BridgeLocationsError, Deposit, DepositOf, LocalXcmChannelManager, +}; use frame_support::{traits::fungible::MutateHold, DefaultNoBound}; use frame_system::Config as SystemConfig; use pallet_bridge_messages::{Config as BridgeMessagesConfig, LanesManagerError}; @@ -468,7 +470,8 @@ pub mod pallet { // get origin's sovereign account let bridge_owner_account = T::BridgeOriginAccountIdConverter::convert_location( locations.bridge_origin_relative_location(), - ).ok_or(Error::::InvalidBridgeOriginAccount)?; + ) + .ok_or(Error::::InvalidBridgeOriginAccount)?; let deposit = T::BridgeDeposit::get(); T::Currency::hold( @@ -843,8 +846,7 @@ mod tests { use frame_support::{assert_err, assert_noop, assert_ok, BoundedVec}; use frame_system::{EventRecord, Phase}; - use sp_runtime::traits::Zero; - use sp_runtime::TryRuntimeError; + use sp_runtime::{traits::Zero, TryRuntimeError}; fn mock_open_bridge_from_with( origin: RuntimeOrigin, @@ -858,7 +860,8 @@ mod tests { let deposit = deposit.map(|deposit| { let bridge_owner_account = fund_origin_sovereign_account(&locations, deposit + ExistentialDeposit::get()); - Balances::hold(&HoldReason::BridgeDeposit.into(), &bridge_owner_account, deposit).unwrap(); + Balances::hold(&HoldReason::BridgeDeposit.into(), &bridge_owner_account, deposit) + .unwrap(); Deposit::new(bridge_owner_account, deposit) }); @@ -1178,8 +1181,14 @@ mod tests { Some(*locations.bridge_id()) ); if let Some(expected_deposit) = expected_deposit.as_ref() { - assert_eq!(Balances::free_balance(&expected_deposit.account), existential_deposit); - assert_eq!(Balances::reserved_balance(&expected_deposit.account), expected_deposit.amount); + assert_eq!( + Balances::free_balance(&expected_deposit.account), + existential_deposit + ); + assert_eq!( + Balances::reserved_balance(&expected_deposit.account), + expected_deposit.amount + ); } // ensure that the proper event is deposited diff --git a/bridges/modules/xcm-bridge-hub/src/migration.rs b/bridges/modules/xcm-bridge-hub/src/migration.rs index a8c73a00d2ec..dc1a17d13072 100644 --- a/bridges/modules/xcm-bridge-hub/src/migration.rs +++ b/bridges/modules/xcm-bridge-hub/src/migration.rs @@ -185,8 +185,7 @@ pub mod v0 { pub mod v1 { use super::*; use crate::{BalanceOf, Bridge, BridgeOf, Bridges, Deposit, ThisChainOf}; - use frame_support::pallet_prelude::Zero; - use frame_support::traits::UncheckedOnRuntimeUpgrade; + use frame_support::{pallet_prelude::Zero, traits::UncheckedOnRuntimeUpgrade}; use sp_std::marker::PhantomData; /// Migrates the pallet storage to v1. diff --git a/bridges/modules/xcm-bridge-hub/src/mock.rs b/bridges/modules/xcm-bridge-hub/src/mock.rs index 153027590e42..3936bb5cef61 100644 --- a/bridges/modules/xcm-bridge-hub/src/mock.rs +++ b/bridges/modules/xcm-bridge-hub/src/mock.rs @@ -27,11 +27,9 @@ use bp_xcm_bridge_hub::{BridgeId, BridgeLocations, LocalXcmChannelManager}; use codec::Encode; use frame_support::{ assert_ok, derive_impl, parameter_types, - traits::{EnsureOrigin, Equals, Everything, OriginTrait}, + traits::{fungible::Mutate, EitherOf, EnsureOrigin, Equals, Everything, OriginTrait}, weights::RuntimeDbWeight, }; -use frame_support::traits::EitherOf; -use frame_support::traits::fungible::Mutate; use frame_system::EnsureRootWithSuccess; use polkadot_parachain_primitives::primitives::Sibling; use sp_core::H256; @@ -45,10 +43,9 @@ use xcm::{latest::ROCOCO_GENESIS_HASH, prelude::*}; use xcm_builder::{ AllowUnpaidExecutionFrom, DispatchBlob, DispatchBlobError, FixedWeightBounds, InspectMessageQueues, NetworkExportTable, NetworkExportTableItem, ParentIsPreset, - SiblingParachainConvertsVia, SovereignPaidRemoteExporter, UnpaidLocalExporter + SiblingParachainConvertsVia, SovereignPaidRemoteExporter, UnpaidLocalExporter, }; -use xcm_executor::traits::ConvertLocation; -use xcm_executor::XcmExecutor; +use xcm_executor::{traits::ConvertLocation, XcmExecutor}; pub type AccountId = AccountId32; pub type Balance = u64; @@ -211,10 +208,7 @@ impl pallet_xcm_bridge_hub::Config for TestRuntime { type BridgeDeposit = BridgeDeposit; type Currency = Balances; type RuntimeHoldReason = RuntimeHoldReason; - type AllowWithoutBridgeDeposit = ( - Equals, - Equals - ); + type AllowWithoutBridgeDeposit = (Equals, Equals); type LocalXcmChannelManager = TestLocalXcmChannelManager; @@ -250,7 +244,8 @@ impl pallet_xcm_bridge_hub_router::Config<()> for TestRuntime { type FeeAsset = BridgeFeeAsset; } -/// A router instance simulates a scenario where the router is deployed on the same chain than the `MessageExporter`. This means that the router triggers `ExportXcm` trait directly. +/// A router instance simulates a scenario where the router is deployed on the same chain than the +/// `MessageExporter`. This means that the router triggers `ExportXcm` trait directly. impl pallet_xcm_bridge_hub_router::Config for TestRuntime { type RuntimeEvent = RuntimeEvent; type WeightInfo = (); @@ -261,11 +256,9 @@ impl pallet_xcm_bridge_hub_router::Config; type DestinationVersion = AlwaysLatest; - // We use `UnpaidLocalExporter` here to test and ensure that `pallet_xcm_bridge_hub_router` can trigger directly `pallet_xcm_bridge_hub` as exporter. - type ToBridgeHubSender = UnpaidLocalExporter< - XcmOverBridge, - Self::UniversalLocation, - >; + // We use `UnpaidLocalExporter` here to test and ensure that `pallet_xcm_bridge_hub_router` can + // trigger directly `pallet_xcm_bridge_hub` as exporter. + type ToBridgeHubSender = UnpaidLocalExporter; type LocalXcmChannelManager = TestLocalXcmChannelManager; type ByteFee = ConstU128<0>; @@ -433,12 +426,15 @@ impl EnsureOrigin for OpenBridgeOrigin { } } -pub(crate) type OpenBridgeOriginOf = >::OpenBridgeOrigin; +pub(crate) type OpenBridgeOriginOf = + >::OpenBridgeOrigin; -pub(crate) fn fund_origin_sovereign_account(locations: &BridgeLocations, balance: Balance) -> AccountId { +pub(crate) fn fund_origin_sovereign_account( + locations: &BridgeLocations, + balance: Balance, +) -> AccountId { let bridge_owner_account = - LocationToAccountId::convert_location(locations.bridge_origin_relative_location()) - .unwrap(); + LocationToAccountId::convert_location(locations.bridge_origin_relative_location()).unwrap(); assert_ok!(Balances::mint_into(&bridge_owner_account, balance)); bridge_owner_account } diff --git a/bridges/primitives/xcm-bridge-hub/src/lib.rs b/bridges/primitives/xcm-bridge-hub/src/lib.rs index e759c61a7097..76cbbb0df149 100644 --- a/bridges/primitives/xcm-bridge-hub/src/lib.rs +++ b/bridges/primitives/xcm-bridge-hub/src/lib.rs @@ -182,9 +182,7 @@ pub struct Bridge { pub type DepositOf = Deposit, BalanceOf>; /// A structure containing information about from whom the deposit is reserved. -#[derive( - Clone, Decode, Encode, Eq, PartialEq, TypeInfo, MaxEncodedLen, RuntimeDebug, -)] +#[derive(Clone, Decode, Encode, Eq, PartialEq, TypeInfo, MaxEncodedLen, RuntimeDebug)] pub struct Deposit { /// Account with the reserved funds. pub account: AccountId, @@ -195,10 +193,7 @@ pub struct Deposit { impl Deposit { /// Create new deposit. pub fn new(account: AccountId, amount: Balance) -> Self { - Self { - account, - amount, - } + Self { account, amount } } } diff --git a/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/mod.rs b/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/mod.rs index 4450310c1bef..0dc1b07a3364 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/mod.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/mod.rs @@ -683,9 +683,8 @@ pub fn open_and_close_bridge_works>::BridgeDeposit::get(); From abd2f0062259c58fc35dc4cce56b5d28f491680a Mon Sep 17 00:00:00 2001 From: Branislav Kontur Date: Sat, 26 Oct 2024 22:41:04 +0200 Subject: [PATCH 11/72] nit --- bridges/modules/xcm-bridge-hub/src/lib.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/bridges/modules/xcm-bridge-hub/src/lib.rs b/bridges/modules/xcm-bridge-hub/src/lib.rs index ca581aca45d7..a839f3a7a659 100644 --- a/bridges/modules/xcm-bridge-hub/src/lib.rs +++ b/bridges/modules/xcm-bridge-hub/src/lib.rs @@ -421,9 +421,9 @@ pub mod pallet { // we can't do anything here - looks like funds have been (partially) unreserved // before by someone else. Let's not fail, though - it'll be worse for the caller log::error!( - target: LOG_TARGET, - "Failed to unreserve during the bridge {:?} closure with error: {e:?}", - locations.bridge_id(), + target: LOG_TARGET, + "Failed to unreserve during the bridge {:?} closure with error: {e:?}", + locations.bridge_id(), ); }) .map(|released| Deposit::new(deposit.account, released)) From 095d1244c4d16fdb68e26f184c5069ddce97515e Mon Sep 17 00:00:00 2001 From: Branislav Kontur Date: Mon, 28 Oct 2024 15:55:53 +0100 Subject: [PATCH 12/72] Extract dynamic fees calculation as separate feature --- .../modules/xcm-bridge-hub-router/src/lib.rs | 153 ++++++------------ .../modules/xcm-bridge-hub-router/src/mock.rs | 3 +- bridges/modules/xcm-bridge-hub/src/mock.rs | 2 +- 3 files changed, 54 insertions(+), 104 deletions(-) diff --git a/bridges/modules/xcm-bridge-hub-router/src/lib.rs b/bridges/modules/xcm-bridge-hub-router/src/lib.rs index 1826d1528efb..8343a1baa93b 100644 --- a/bridges/modules/xcm-bridge-hub-router/src/lib.rs +++ b/bridges/modules/xcm-bridge-hub-router/src/lib.rs @@ -109,9 +109,12 @@ pub mod pallet { type LocalXcmChannelManager: XcmChannelStatusProvider; /// Additional fee that is paid for every byte of the outbound message. + /// See `calculate_fees` for more details. type ByteFee: Get; - /// Asset that is used to paid bridge fee. - type FeeAsset: Get; + /// Asset used to pay the `ByteFee`. + /// If not specified, the `ByteFee` is ignored. + /// See `calculate_fees` for more details. + type FeeAsset: Get>; } #[pallet::pallet] @@ -216,6 +219,36 @@ pub mod pallet { *f }); } + + /// Calculates final fees based on the configuration, supporting two optional features: + /// + /// 1. Adds an (optional) fee for message size based on `T::ByteFee` and `T::FeeAsset`. + /// 2. Applies a dynamic fee factor `Self::delivery_fee_factor` to the `actual_cost` (useful for congestion handling). + /// + /// Parameters: + /// - `message_size` + /// - `actual_cost`: the fee for sending a message from this chain to a child, sibling, or local bridge hub, determined by `Config::ToBridgeHubSender`. + pub(crate) fn calculate_fees(message_size: u32, mut actual_cost: Assets) -> Assets { + // Apply message size `T::ByteFee/T::FeeAsset` feature (if configured). + if let Some(asset_id) = T::FeeAsset::get() { + let message_fee = (message_size as u128).saturating_mul(T::ByteFee::get()); + if message_fee > 0 { + // Keep in mind that this is only the additional fee for message size. + actual_cost.push((asset_id, message_fee).into()); + } + } + + // Apply dynamic fees feature - apply `fee_factor` to the `actual_cost`. + let fee_factor = Self::delivery_fee_factor(); + let mut new_cost = Assets::new(); + for mut a in actual_cost.into_inner() { + if let Fungibility::Fungible(ref mut amount) = a.fun { + *amount = fee_factor.saturating_mul_int(*amount); + } + new_cost.push(a); + } + new_cost + } } #[pallet::event] @@ -234,97 +267,6 @@ pub mod pallet { } } -// This pallet acts as the `ExporterFor` for the `SovereignPaidRemoteExporter` to compute -// message fee using fee factor. -impl, I: 'static> ExporterFor for Pallet { - fn exporter_for( - network: &NetworkId, - remote_location: &InteriorLocation, - message: &Xcm<()>, - ) -> Option<(Location, Option)> { - log::trace!( - target: LOG_TARGET, - "exporter_for - network: {network:?}, remote_location: {remote_location:?}, msg: {message:?}", - ); - // ensure that the message is sent to the expected bridged network (if specified). - if let Some(bridged_network) = T::BridgedNetworkId::get() { - if *network != bridged_network { - log::trace!( - target: LOG_TARGET, - "Router with bridged_network_id {bridged_network:?} does not support bridging to network {network:?}!", - ); - return None - } - } - - // ensure that the message is sent to the expected bridged network and location. - let (bridge_hub_location, maybe_payment) = match T::Bridges::exporter_for( - network, - remote_location, - message, - ) { - Some((bridge_hub_location, maybe_payment)) - if bridge_hub_location.eq(&T::SiblingBridgeHubLocation::get()) => - (bridge_hub_location, maybe_payment), - _ => { - log::trace!( - target: LOG_TARGET, - "Router configured with bridged_network_id {:?} and sibling_bridge_hub_location: {:?} does not support bridging to network {:?} and remote_location {:?}!", - T::BridgedNetworkId::get(), - T::SiblingBridgeHubLocation::get(), - network, - remote_location, - ); - return None - }, - }; - - // take `base_fee` from `T::Brides`, but it has to be the same `T::FeeAsset` - let base_fee = match maybe_payment { - Some(payment) => match payment { - Asset { fun: Fungible(amount), id } if id.eq(&T::FeeAsset::get()) => amount, - invalid_asset => { - log::error!( - target: LOG_TARGET, - "Router with bridged_network_id {:?} is configured for `T::FeeAsset` {:?} \ - which is not compatible with {:?} for bridge_hub_location: {:?} for bridging to {:?}/{:?}!", - T::BridgedNetworkId::get(), - T::FeeAsset::get(), - invalid_asset, - bridge_hub_location, - network, - remote_location, - ); - return None - }, - }, - None => 0, - }; - - // compute fee amount. Keep in mind that this is only the bridge fee. The fee for sending - // message from this chain to child/sibling bridge hub is determined by the - // `Config::ToBridgeHubSender` - let message_size = message.encoded_size(); - let message_fee = (message_size as u128).saturating_mul(T::ByteFee::get()); - let fee_sum = base_fee.saturating_add(message_fee); - - let fee_factor = Self::delivery_fee_factor(); - let fee = fee_factor.saturating_mul_int(fee_sum); - let fee = if fee > 0 { Some((T::FeeAsset::get(), fee).into()) } else { None }; - - log::info!( - target: LOG_TARGET, - "Going to send message to {:?} ({} bytes) over bridge. Computed bridge fee {:?} using fee factor {}", - (network, remote_location), - message_size, - fee, - fee_factor, - ); - - Some((bridge_hub_location, fee)) - } -} - // This pallet acts as the `SendXcm` to the sibling/child bridge hub instead of regular // XCMP/DMP transport. This allows injecting dynamic message fees into XCM programs that // are going to the bridged network. @@ -363,7 +305,7 @@ impl, I: 'static> SendXcm for Pallet { // The bridge doesn't support oversized or overweight messages. Therefore, it's // better to drop such messages here rather than at the bridge hub. Let's check the - // message size." + // message size. if message_size > HARD_MESSAGE_SIZE_LIMIT { return Err(SendError::ExceedsMaxMessageSize) } @@ -381,6 +323,14 @@ impl, I: 'static> SendXcm for Pallet { .into_version(destination_version) .map_err(|()| SendError::DestinationUnsupported)?; + // now let's apply fees features + let cost = Self::calculate_fees(message_size, cost); + + log::info!( + target: LOG_TARGET, + "Going to send message to {dest_clone:?} ({message_size:?} bytes) with actual cost: {cost:?}" + ); + Ok(((message_size, ticket), cost)) }, Err(e) => { @@ -566,8 +516,11 @@ mod tests { let xcm: Xcm<()> = vec![ClearOrigin].into(); let msg_size = xcm.encoded_size(); - // initially the base fee is used: `BASE_FEE + BYTE_FEE * msg_size + HRMP_FEE` - let expected_fee = BASE_FEE + BYTE_FEE * (msg_size as u128) + HRMP_FEE; + // `BASE_FEE + BYTE_FEE * msg_size + HRMP_FEE` + let base_cost_formula = || BASE_FEE + BYTE_FEE * (msg_size as u128) + HRMP_FEE; + + // initially the base fee is used + let expected_fee = base_cost_formula(); assert_eq!( XcmBridgeHubRouter::validate(&mut Some(dest.clone()), &mut Some(xcm.clone())) .unwrap() @@ -577,14 +530,12 @@ mod tests { ); // but when factor is larger than one, it increases the fee, so it becomes: - // `(BASE_FEE + BYTE_FEE * msg_size) * F + HRMP_FEE` + // `base_cost_formula() * F` let factor = FixedU128::from_rational(125, 100); DeliveryFeeFactor::::put(factor); let expected_fee = - (FixedU128::saturating_from_integer(BASE_FEE + BYTE_FEE * (msg_size as u128)) * - factor) - .into_inner() / FixedU128::DIV + - HRMP_FEE; + (FixedU128::saturating_from_integer(base_cost_formula()) * factor) + .into_inner() / FixedU128::DIV; assert_eq!( XcmBridgeHubRouter::validate(&mut Some(dest), &mut Some(xcm)).unwrap().1.get(0), Some(&(BridgeFeeAsset::get(), expected_fee).into()), diff --git a/bridges/modules/xcm-bridge-hub-router/src/mock.rs b/bridges/modules/xcm-bridge-hub-router/src/mock.rs index e234c01bc3e5..e366cb56ddf7 100644 --- a/bridges/modules/xcm-bridge-hub-router/src/mock.rs +++ b/bridges/modules/xcm-bridge-hub-router/src/mock.rs @@ -83,8 +83,7 @@ impl pallet_xcm_bridge_hub_router::Config<()> for TestRuntime { LatestOrNoneForLocationVersionChecker>; type ToBridgeHubSender = SovereignPaidRemoteExporter< - // use pallet itself as `ExportFor` provider. - XcmBridgeHubRouter, + NetworkExportTable, TestToBridgeHubSender, Self::UniversalLocation, >; diff --git a/bridges/modules/xcm-bridge-hub/src/mock.rs b/bridges/modules/xcm-bridge-hub/src/mock.rs index 3936bb5cef61..348ff16c6766 100644 --- a/bridges/modules/xcm-bridge-hub/src/mock.rs +++ b/bridges/modules/xcm-bridge-hub/src/mock.rs @@ -231,7 +231,7 @@ impl pallet_xcm_bridge_hub_router::Config<()> for TestRuntime { // produced by `pallet_xcm_bridge_hub_router` is compatible with the `ExportXcm` implementation // of `pallet_xcm_bridge_hub`. type ToBridgeHubSender = SovereignPaidRemoteExporter< - XcmOverBridgeWrappedWithExportMessageRouter, + NetworkExportTable, // **Note**: The crucial part is that `ExportMessage` is processed by `XcmExecutor`, which // calls the `ExportXcm` implementation of `pallet_xcm_bridge_hub` as the // `MessageExporter`. From 459228aeae7bff0d7729b87873f7c7df8aaad383 Mon Sep 17 00:00:00 2001 From: command-bot <> Date: Mon, 28 Oct 2024 15:08:03 +0000 Subject: [PATCH 13/72] ".git/.scripts/commands/fmt/fmt.sh" --- .../modules/xcm-bridge-hub-router/src/lib.rs | 12 ++++++---- bridges/modules/xcm-bridge-hub/src/lib.rs | 23 ++++++++++--------- 2 files changed, 19 insertions(+), 16 deletions(-) diff --git a/bridges/modules/xcm-bridge-hub-router/src/lib.rs b/bridges/modules/xcm-bridge-hub-router/src/lib.rs index 8343a1baa93b..54f592d81c41 100644 --- a/bridges/modules/xcm-bridge-hub-router/src/lib.rs +++ b/bridges/modules/xcm-bridge-hub-router/src/lib.rs @@ -223,11 +223,13 @@ pub mod pallet { /// Calculates final fees based on the configuration, supporting two optional features: /// /// 1. Adds an (optional) fee for message size based on `T::ByteFee` and `T::FeeAsset`. - /// 2. Applies a dynamic fee factor `Self::delivery_fee_factor` to the `actual_cost` (useful for congestion handling). + /// 2. Applies a dynamic fee factor `Self::delivery_fee_factor` to the `actual_cost` (useful + /// for congestion handling). /// /// Parameters: /// - `message_size` - /// - `actual_cost`: the fee for sending a message from this chain to a child, sibling, or local bridge hub, determined by `Config::ToBridgeHubSender`. + /// - `actual_cost`: the fee for sending a message from this chain to a child, sibling, or + /// local bridge hub, determined by `Config::ToBridgeHubSender`. pub(crate) fn calculate_fees(message_size: u32, mut actual_cost: Assets) -> Assets { // Apply message size `T::ByteFee/T::FeeAsset` feature (if configured). if let Some(asset_id) = T::FeeAsset::get() { @@ -533,9 +535,9 @@ mod tests { // `base_cost_formula() * F` let factor = FixedU128::from_rational(125, 100); DeliveryFeeFactor::::put(factor); - let expected_fee = - (FixedU128::saturating_from_integer(base_cost_formula()) * factor) - .into_inner() / FixedU128::DIV; + let expected_fee = (FixedU128::saturating_from_integer(base_cost_formula()) * factor) + .into_inner() / + FixedU128::DIV; assert_eq!( XcmBridgeHubRouter::validate(&mut Some(dest), &mut Some(xcm)).unwrap().1.get(0), Some(&(BridgeFeeAsset::get(), expected_fee).into()), diff --git a/bridges/modules/xcm-bridge-hub/src/lib.rs b/bridges/modules/xcm-bridge-hub/src/lib.rs index a839f3a7a659..658ad279aa7a 100644 --- a/bridges/modules/xcm-bridge-hub/src/lib.rs +++ b/bridges/modules/xcm-bridge-hub/src/lib.rs @@ -417,17 +417,18 @@ pub mod pallet { deposit.amount, Precision::BestEffort, ) - .inspect_err(|e| { - // we can't do anything here - looks like funds have been (partially) unreserved - // before by someone else. Let's not fail, though - it'll be worse for the caller - log::error!( - target: LOG_TARGET, - "Failed to unreserve during the bridge {:?} closure with error: {e:?}", - locations.bridge_id(), - ); - }) - .map(|released| Deposit::new(deposit.account, released)) - .ok() + .inspect_err(|e| { + // we can't do anything here - looks like funds have been (partially) unreserved + // before by someone else. Let's not fail, though - it'll be worse for the + // caller + log::error!( + target: LOG_TARGET, + "Failed to unreserve during the bridge {:?} closure with error: {e:?}", + locations.bridge_id(), + ); + }) + .map(|released| Deposit::new(deposit.account, released)) + .ok() } else { None }; From 3f32d752cf8d6d75be5c2709f58ea01c4bebec7c Mon Sep 17 00:00:00 2001 From: Branislav Kontur Date: Mon, 28 Oct 2024 17:02:04 +0100 Subject: [PATCH 14/72] We don't need `ExporterFor/Bridges` for `pallet-xcm-bridge-hub-router` anymore --- bridges/modules/xcm-bridge-hub-router/src/lib.rs | 7 ++----- bridges/modules/xcm-bridge-hub-router/src/mock.rs | 1 - bridges/modules/xcm-bridge-hub/src/mock.rs | 2 -- .../runtimes/assets/asset-hub-rococo/src/lib.rs | 8 +++++--- .../runtimes/assets/asset-hub-rococo/src/xcm_config.rs | 7 ------- .../runtimes/assets/asset-hub-westend/src/lib.rs | 8 +++++--- .../runtimes/assets/asset-hub-westend/src/xcm_config.rs | 7 ------- 7 files changed, 12 insertions(+), 28 deletions(-) diff --git a/bridges/modules/xcm-bridge-hub-router/src/lib.rs b/bridges/modules/xcm-bridge-hub-router/src/lib.rs index 54f592d81c41..845ac5475357 100644 --- a/bridges/modules/xcm-bridge-hub-router/src/lib.rs +++ b/bridges/modules/xcm-bridge-hub-router/src/lib.rs @@ -35,7 +35,7 @@ use frame_support::traits::Get; use sp_runtime::{FixedPointNumber, FixedU128, Saturating}; use sp_std::vec::Vec; use xcm::prelude::*; -use xcm_builder::{ExporterFor, InspectMessageQueues}; +use xcm_builder::InspectMessageQueues; pub use pallet::*; pub use weights::WeightInfo; @@ -90,10 +90,7 @@ pub mod pallet { /// Also used for filtering `Bridges` by `BridgedNetworkId`. /// If not specified, allows all networks pass through. type BridgedNetworkId: Get>; - /// Configuration for supported **bridged networks/locations** with **bridge location** and - /// **possible fee**. Allows to externalize better control over allowed **bridged - /// networks/locations**. - type Bridges: ExporterFor; + /// Checks the XCM version for the destination. type DestinationVersion: GetVersion; diff --git a/bridges/modules/xcm-bridge-hub-router/src/mock.rs b/bridges/modules/xcm-bridge-hub-router/src/mock.rs index e366cb56ddf7..5bb076dff683 100644 --- a/bridges/modules/xcm-bridge-hub-router/src/mock.rs +++ b/bridges/modules/xcm-bridge-hub-router/src/mock.rs @@ -78,7 +78,6 @@ impl pallet_xcm_bridge_hub_router::Config<()> for TestRuntime { type UniversalLocation = UniversalLocation; type SiblingBridgeHubLocation = SiblingBridgeHubLocation; type BridgedNetworkId = BridgedNetworkId; - type Bridges = NetworkExportTable; type DestinationVersion = LatestOrNoneForLocationVersionChecker>; diff --git a/bridges/modules/xcm-bridge-hub/src/mock.rs b/bridges/modules/xcm-bridge-hub/src/mock.rs index 348ff16c6766..281293e848a6 100644 --- a/bridges/modules/xcm-bridge-hub/src/mock.rs +++ b/bridges/modules/xcm-bridge-hub/src/mock.rs @@ -224,7 +224,6 @@ impl pallet_xcm_bridge_hub_router::Config<()> for TestRuntime { type UniversalLocation = UniversalLocation; type SiblingBridgeHubLocation = BridgeHubLocation; type BridgedNetworkId = BridgedRelayNetwork; - type Bridges = NetworkExportTable; type DestinationVersion = AlwaysLatest; // We use `SovereignPaidRemoteExporter` here to test and ensure that the `ExportMessage` @@ -253,7 +252,6 @@ impl pallet_xcm_bridge_hub_router::Config; type DestinationVersion = AlwaysLatest; // We use `UnpaidLocalExporter` here to test and ensure that `pallet_xcm_bridge_hub_router` can diff --git a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs index 01fd0198cc6b..38f2ba8be538 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs @@ -931,13 +931,15 @@ impl pallet_xcm_bridge_hub_router::Config for Runtim type UniversalLocation = xcm_config::UniversalLocation; type SiblingBridgeHubLocation = xcm_config::bridging::SiblingBridgeHub; type BridgedNetworkId = xcm_config::bridging::to_westend::WestendNetwork; - type Bridges = xcm_config::bridging::NetworkExportTable; type DestinationVersion = PolkadotXcm; // Let's use `SovereignPaidRemoteExporter`, which sends `ExportMessage` over HRMP to the sibling // BridgeHub. - type ToBridgeHubSender = - SovereignPaidRemoteExporter; + type ToBridgeHubSender = SovereignPaidRemoteExporter< + xcm_builder::NetworkExportTable, + XcmpQueue, + Self::UniversalLocation + >; type LocalXcmChannelManager = cumulus_pallet_xcmp_queue::bridging::InAndOutXcmpChannelStatusProvider; diff --git a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/xcm_config.rs b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/xcm_config.rs index 66743fa3a07e..69ee749da47d 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/xcm_config.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/xcm_config.rs @@ -556,19 +556,12 @@ pub mod bridging { /// (`AssetId` has to be aligned with `BridgeTable`) pub XcmBridgeHubRouterFeeAssetId: AssetId = TokenLocation::get().into(); - pub BridgeTable: alloc::vec::Vec = - alloc::vec::Vec::new().into_iter() - .chain(to_westend::BridgeTable::get()) - .collect(); - pub EthereumBridgeTable: alloc::vec::Vec = alloc::vec::Vec::new().into_iter() .chain(to_ethereum::BridgeTable::get()) .collect(); } - pub type NetworkExportTable = xcm_builder::NetworkExportTable; - pub type EthereumNetworkExportTable = xcm_builder::NetworkExportTable; pub mod to_westend { diff --git a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs index 29ca45b36991..eede6885bb29 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs @@ -928,13 +928,15 @@ impl pallet_xcm_bridge_hub_router::Config for Runtime type UniversalLocation = xcm_config::UniversalLocation; type SiblingBridgeHubLocation = xcm_config::bridging::SiblingBridgeHub; type BridgedNetworkId = xcm_config::bridging::to_rococo::RococoNetwork; - type Bridges = xcm_config::bridging::NetworkExportTable; type DestinationVersion = PolkadotXcm; // Let's use `SovereignPaidRemoteExporter`, which sends `ExportMessage` over HRMP to the sibling // BridgeHub. - type ToBridgeHubSender = - SovereignPaidRemoteExporter; + type ToBridgeHubSender = SovereignPaidRemoteExporter< + xcm_builder::NetworkExportTable, + XcmpQueue, + Self::UniversalLocation + >; type LocalXcmChannelManager = cumulus_pallet_xcmp_queue::bridging::InAndOutXcmpChannelStatusProvider; diff --git a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/xcm_config.rs b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/xcm_config.rs index 88ccd42dff7f..cd6906c7a643 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/xcm_config.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/xcm_config.rs @@ -577,15 +577,8 @@ pub mod bridging { /// Router expects payment with this `AssetId`. /// (`AssetId` has to be aligned with `BridgeTable`) pub XcmBridgeHubRouterFeeAssetId: AssetId = WestendLocation::get().into(); - - pub BridgeTable: alloc::vec::Vec = - alloc::vec::Vec::new().into_iter() - .chain(to_rococo::BridgeTable::get()) - .collect(); } - pub type NetworkExportTable = xcm_builder::NetworkExportTable; - pub mod to_rococo { use super::*; From cb71f3e261b6af39974405a8c542b375c367e8ad Mon Sep 17 00:00:00 2001 From: Branislav Kontur Date: Thu, 31 Oct 2024 13:32:51 +0100 Subject: [PATCH 15/72] Implement congestion and dynamic fees for logical bridges - part1 --- Cargo.lock | 1 + .../xcm-bridge-hub-router/src/impls.rs | 127 ++++++ .../modules/xcm-bridge-hub-router/src/lib.rs | 374 ++++++++++-------- .../modules/xcm-bridge-hub-router/src/mock.rs | 67 ++-- .../xcm-bridge-hub-router/src/weights.rs | 17 + bridges/modules/xcm-bridge-hub/Cargo.toml | 1 + bridges/modules/xcm-bridge-hub/src/mock.rs | 53 ++- .../xcm-bridge-hub-router/src/lib.rs | 33 +- 8 files changed, 457 insertions(+), 216 deletions(-) create mode 100644 bridges/modules/xcm-bridge-hub-router/src/impls.rs diff --git a/Cargo.lock b/Cargo.lock index 1e1c902df0e1..107ac0decf7d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -13255,6 +13255,7 @@ dependencies = [ "bp-messages", "bp-runtime", "bp-xcm-bridge-hub", + "bp-xcm-bridge-hub-router", "frame-support", "frame-system", "log", diff --git a/bridges/modules/xcm-bridge-hub-router/src/impls.rs b/bridges/modules/xcm-bridge-hub-router/src/impls.rs new file mode 100644 index 000000000000..99dac41f93c3 --- /dev/null +++ b/bridges/modules/xcm-bridge-hub-router/src/impls.rs @@ -0,0 +1,127 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Parity Bridges Common. + +// Parity Bridges Common 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. + +// Parity Bridges Common 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 Parity Bridges Common. If not, see . + +//! Various implementations supporting easier configuration of the pallet. +use crate::{Config, Pallet, Bridges, LOG_TARGET}; +use xcm_builder::ExporterFor; +use bp_xcm_bridge_hub_router::ResolveBridgeId; +use codec::Encode; +use frame_support::pallet_prelude::PhantomData; +use frame_support::traits::Get; +use xcm::prelude::*; + +pub struct ViaRemoteBridgeHubExporter(PhantomData<(T, I, E, BNF, BHLF)>); + +impl, I: 'static, E, BridgedNetworkIdFilter, BridgeHubLocationFilter> ExporterFor for ViaRemoteBridgeHubExporter +where + E: ExporterFor, + BridgedNetworkIdFilter: Get>, + BridgeHubLocationFilter: Get>, +{ + + fn exporter_for( + network: &NetworkId, + remote_location: &InteriorLocation, + message: &Xcm<()>, + ) -> Option<(Location, Option)> { + log::trace!( + target: LOG_TARGET, + "exporter_for - network: {network:?}, remote_location: {remote_location:?}, msg: {message:?}", + ); + // ensure that the message is sent to the expected bridged network (if specified). + if let Some(bridged_network) = BridgedNetworkIdFilter::get() { + if *network != bridged_network { + log::trace!( + target: LOG_TARGET, + "Router with bridged_network_id filter({bridged_network:?}) does not support bridging to network {network:?}!", + ); + return None + } + } + + // ensure that the message is sent to the expected bridged network and location. + let (bridge_hub_location, maybe_payment) = match E::exporter_for(network, remote_location, message) { + Some((bridge_hub_location, maybe_payment)) => match BridgeHubLocationFilter::get() { + Some(expected_bridge_hub_location) if expected_bridge_hub_location.eq(&bridge_hub_location) => (bridge_hub_location, maybe_payment), + None => (bridge_hub_location, maybe_payment), + _ => { + log::trace!( + target: LOG_TARGET, + "Resolved bridge_hub_location: {:?} does not match expected one: {:?} for bridging to network {:?} and remote_location {:?}!", + bridge_hub_location, + BridgeHubLocationFilter::get(), + network, + remote_location, + ); + return None + } + }, + _ => { + log::trace!( + target: LOG_TARGET, + "Inner `E` router does not support bridging to network {:?} and remote_location {:?}!", + network, + remote_location, + ); + return None + }, + }; + + // calculate message size fees (if configured) + let maybe_message_size_fees = Pallet::::calculate_message_size_fees(|| message.encoded_size() as _); + + // compute actual fees - sum(actual payment, message size fees) if possible + let fees = match (maybe_payment, maybe_message_size_fees) { + (Some(payment), None) => Some(payment), + (None, Some(message_size_fees)) => Some(message_size_fees), + (None, None) => None, + ( + Some(Asset {id: payment_asset_id, fun: Fungible(payment_amount)}), + Some(Asset {id: message_size_fees_asset_id, fun: Fungible(message_size_fees_amount)}) + ) if payment_asset_id.eq(&message_size_fees_asset_id) => { + // we can subsume two assets with the same asset_id and fungibility. + Some((payment_asset_id, (payment_amount.saturating_add(message_size_fees_amount))).into()) + }, + (Some(payment), Some(message_size_fees)) => { + log::error!( + target: LOG_TARGET, + "Router is configured for `T::FeeAsset` {:?} \ + but we have two different assets which cannot be calculated as one result asset: payment: {:?} and message_size_fees: {:?} for bridge_hub_location: {:?} for bridging to {:?}/{:?}!", + T::FeeAsset::get(), + payment, + message_size_fees, + bridge_hub_location, + network, + remote_location, + ); + return None + } + }; + + // Here, we have the actual result fees covering bridge fees, so now we need to check/apply the congestion and dynamic_fees features (if possible). + let fees = fees.map(|fees| if let Some(bridge_id) = T::BridgeIdResolver::resolve_for(network, remote_location) { + if let Some(bridge_state) = Bridges::::get(bridge_id) { + Pallet::::calculate_dynamic_fees_for_asset(&bridge_state, fees) + } else { + fees + } + } else { + fees + }); + + Some((bridge_hub_location, fees)) + } +} diff --git a/bridges/modules/xcm-bridge-hub-router/src/lib.rs b/bridges/modules/xcm-bridge-hub-router/src/lib.rs index 845ac5475357..e032c1228c82 100644 --- a/bridges/modules/xcm-bridge-hub-router/src/lib.rs +++ b/bridges/modules/xcm-bridge-hub-router/src/lib.rs @@ -30,6 +30,7 @@ #![cfg_attr(not(feature = "std"), no_std)] pub use bp_xcm_bridge_hub_router::XcmChannelStatusProvider; +use bp_xcm_bridge_hub_router::{BridgeState, ResolveBridgeId}; use codec::Encode; use frame_support::traits::Get; use sp_runtime::{FixedPointNumber, FixedU128, Saturating}; @@ -41,6 +42,7 @@ pub use pallet::*; pub use weights::WeightInfo; pub mod benchmarking; +pub mod impls; pub mod weights; mod mock; @@ -82,15 +84,6 @@ pub mod pallet { /// Benchmarks results from runtime we're plugged into. type WeightInfo: WeightInfo; - /// Universal location of this runtime. - type UniversalLocation: Get; - /// Relative location of the supported sibling bridge hub. - type SiblingBridgeHubLocation: Get; - /// The bridged network that this config is for if specified. - /// Also used for filtering `Bridges` by `BridgedNetworkId`. - /// If not specified, allows all networks pass through. - type BridgedNetworkId: Get>; - /// Checks the XCM version for the destination. type DestinationVersion: GetVersion; @@ -102,11 +95,13 @@ pub mod pallet { /// that does not use `ExportMessage` but instead directly calls the `ExportXcm` /// implementation. type ToBridgeHubSender: SendXcm; - /// Local XCM channel manager. - type LocalXcmChannelManager: XcmChannelStatusProvider; + + /// Resolves a specific `BridgeId` for `dest`, used for identifying the bridge in cases of congestion and dynamic fees. + /// If it resolves to `None`, it means no congestion or dynamic fees are handled for `dest`. + type BridgeIdResolver: ResolveBridgeId; /// Additional fee that is paid for every byte of the outbound message. - /// See `calculate_fees` for more details. + /// See `calculate_message_size_fees` for more details. type ByteFee: Get; /// Asset used to pay the `ByteFee`. /// If not specified, the `ByteFee` is ignored. @@ -114,139 +109,145 @@ pub mod pallet { type FeeAsset: Get>; } + /// An alias for the `BridgeId` of configured `T::BridgeIdResolver`. + pub type BridgeIdOf = <>::BridgeIdResolver as ResolveBridgeId>::BridgeId; + #[pallet::pallet] pub struct Pallet(PhantomData<(T, I)>); #[pallet::hooks] impl, I: 'static> Hooks> for Pallet { fn on_initialize(_n: BlockNumberFor) -> Weight { - // if XCM channel is still congested, we don't change anything - if T::LocalXcmChannelManager::is_congested(&T::SiblingBridgeHubLocation::get()) { - return T::WeightInfo::on_initialize_when_congested() + let mut weight_used = Weight::zero(); + + // Iterate all uncongested bridges + let mut bridges_to_update = Vec::new(); + let mut bridges_to_remove = Vec::new(); + for (bridge_id, mut bridge_state) in Bridges::::iter() { + weight_used.saturating_accrue(T::DbWeight::get().reads(1)); + + // if not congested anymore, we can start to decreasing fee factor + if !bridge_state.is_congested { + let previous_factor = bridge_state.delivery_fee_factor; + let new_factor = previous_factor / EXPONENTIAL_FEE_BASE; + if new_factor >= MINIMAL_DELIVERY_FEE_FACTOR { + bridge_state.delivery_fee_factor = new_factor; + bridges_to_update.push((bridge_id, previous_factor, bridge_state)); + } else { + bridges_to_remove.push((bridge_id, previous_factor)); + } + } } - // if we can't decrease the delivery fee factor anymore, we don't change anything - let mut delivery_fee_factor = Self::delivery_fee_factor(); - if delivery_fee_factor == MINIMAL_DELIVERY_FEE_FACTOR { - return T::WeightInfo::on_initialize_when_congested() + // remove + for (bridge_id, previous_value) in bridges_to_remove.into_iter() { + log::info!( + target: LOG_TARGET, + "Bridge channel with id {:?} is uncongested. Removing fee factor!", + bridge_id, + ); + Bridges::::remove(&bridge_id); + Self::deposit_event(Event::DeliveryFeeFactorDecreased { + previous_value, + new_value: 0.into(), + bridge_id, + }); + weight_used.saturating_accrue(T::WeightInfo::on_initialize_when_bridge_state_removed()); + } + // update + for (bridge_id, previous_value, bridge_state) in bridges_to_update.into_iter() { + let new_value = bridge_state.delivery_fee_factor; + log::info!( + target: LOG_TARGET, + "Bridge channel with id {:?} is uncongested. Decreasing fee factor from {} to {}!", + bridge_id, + previous_value, + new_value, + ); + Bridges::::insert(&bridge_id, bridge_state); + Self::deposit_event(Event::DeliveryFeeFactorDecreased { + previous_value, + new_value, + bridge_id, + }); + weight_used.saturating_accrue(T::WeightInfo::on_initialize_when_bridge_state_updated()); } - let previous_factor = delivery_fee_factor; - delivery_fee_factor = - MINIMAL_DELIVERY_FEE_FACTOR.max(delivery_fee_factor / EXPONENTIAL_FEE_BASE); - log::info!( - target: LOG_TARGET, - "Bridge channel is uncongested. Decreased fee factor from {} to {}", - previous_factor, - delivery_fee_factor, - ); - Self::deposit_event(Event::DeliveryFeeFactorDecreased { - new_value: delivery_fee_factor, - }); - - DeliveryFeeFactor::::put(delivery_fee_factor); - - T::WeightInfo::on_initialize_when_non_congested() + weight_used } } - /// Initialization value for the delivery fee factor. - #[pallet::type_value] - pub fn InitialFactor() -> FixedU128 { - MINIMAL_DELIVERY_FEE_FACTOR - } - - /// The number to multiply the base delivery fee by. - /// - /// This factor is shared by all bridges, served by this pallet. For example, if this - /// chain (`Config::UniversalLocation`) opens two bridges ( - /// `X2(GlobalConsensus(Config::BridgedNetworkId::get()), Parachain(1000))` and - /// `X2(GlobalConsensus(Config::BridgedNetworkId::get()), Parachain(2000))`), then they - /// both will be sharing the same fee factor. This is because both bridges are sharing - /// the same local XCM channel with the child/sibling bridge hub, which we are using - /// to detect congestion: - /// - /// ```nocompile - /// ThisChain --- Local XCM channel --> Sibling Bridge Hub ------ - /// | | - /// | | - /// | | - /// Lane1 Lane2 - /// | | - /// | | - /// | | - /// \ / | - /// Parachain1 <-- Local XCM channel --- Remote Bridge Hub <------ - /// | - /// | - /// Parachain1 <-- Local XCM channel --------- - /// ``` - /// - /// If at least one of other channels is congested, the local XCM channel with sibling - /// bridge hub eventually becomes congested too. And we have no means to detect - which - /// bridge exactly causes the congestion. So the best solution here is not to make - /// any differences between all bridges, started by this chain. + /// Stores `BridgeState` for congestion control and dynamic fees for each resolved bridge ID associated with a destination. #[pallet::storage] - #[pallet::getter(fn delivery_fee_factor)] - pub type DeliveryFeeFactor, I: 'static = ()> = - StorageValue<_, FixedU128, ValueQuery, InitialFactor>; + pub type Bridges, I: 'static = ()> = StorageMap<_, Blake2_128Concat, BridgeIdOf, BridgeState, OptionQuery>; impl, I: 'static> Pallet { - /// Called when new message is sent (queued to local outbound XCM queue) over the bridge. - pub(crate) fn on_message_sent_to_bridge(message_size: u32) { - // if outbound channel is not congested, do nothing - if !T::LocalXcmChannelManager::is_congested(&T::SiblingBridgeHubLocation::get()) { + /// Called when new message is sent to the `dest` (queued to local outbound XCM queue). + pub(crate) fn on_message_sent_to(message_size: u32, dest: Location) { + let Some(bridge_id) = T::BridgeIdResolver::resolve_for_dest(&dest) else { + // not supported bridge id, so do nothing return - } - - // ok - we need to increase the fee factor, let's do that - let message_size_factor = FixedU128::from_u32(message_size.saturating_div(1024)) - .saturating_mul(MESSAGE_SIZE_FEE_BASE); - let total_factor = EXPONENTIAL_FEE_BASE.saturating_add(message_size_factor); - DeliveryFeeFactor::::mutate(|f| { - let previous_factor = *f; - *f = f.saturating_mul(total_factor); + }; + + // handle congestion and fee factor (if detected) + let increased = Bridges::::mutate_exists(&bridge_id, |bridge_state| match bridge_state { + Some(ref mut bridge_state) if bridge_state.is_congested => { + // found congested bridge + // ok - we need to increase the fee factor, let's do that + let message_size_factor = FixedU128::from_u32(message_size.saturating_div(1024)) + .saturating_mul(MESSAGE_SIZE_FEE_BASE); + let total_factor = EXPONENTIAL_FEE_BASE.saturating_add(message_size_factor); + + let previous_factor = bridge_state.delivery_fee_factor; + bridge_state.delivery_fee_factor = bridge_state.delivery_fee_factor.saturating_mul(total_factor); + + Some((previous_factor, bridge_state.delivery_fee_factor)) + }, + _ => { + // not congested, do nothing + None + } + }); + if let Some((previous_factor, new_factor)) = increased { log::info!( - target: LOG_TARGET, - "Bridge channel is congested. Increased fee factor from {} to {}", - previous_factor, - f, + target: LOG_TARGET, + "Bridge channel with id {:?} is congested. Increased fee factor from {} to {} for {:?}", + bridge_id, + previous_factor, + new_factor, + dest ); - Self::deposit_event(Event::DeliveryFeeFactorIncreased { new_value: *f }); - *f - }); + Self::deposit_event(Event::DeliveryFeeFactorIncreased { + previous_value: previous_factor, + new_value: new_factor, + bridge_id, + dest + }); + } } - /// Calculates final fees based on the configuration, supporting two optional features: + /// Calculates dynamic fees for a given asset based on the bridge state. /// - /// 1. Adds an (optional) fee for message size based on `T::ByteFee` and `T::FeeAsset`. - /// 2. Applies a dynamic fee factor `Self::delivery_fee_factor` to the `actual_cost` (useful - /// for congestion handling). - /// - /// Parameters: - /// - `message_size` - /// - `actual_cost`: the fee for sending a message from this chain to a child, sibling, or - /// local bridge hub, determined by `Config::ToBridgeHubSender`. - pub(crate) fn calculate_fees(message_size: u32, mut actual_cost: Assets) -> Assets { + /// This function adjusts the amount of a fungible asset according to the delivery fee factor + /// specified in the `bridge_state`. If the asset is fungible, the `delivery_fee_factor` is applied + /// to the asset’s amount, potentially altering its value. + pub(crate) fn calculate_dynamic_fees_for_asset(bridge_state: &BridgeState, mut asset: Asset) -> Asset { + if let Fungibility::Fungible(ref mut amount) = asset.fun { + *amount = bridge_state.delivery_fee_factor.saturating_mul_int(*amount); + } + asset + } + + /// Calculates an (optional) fee for message size based on `T::ByteFee` and `T::FeeAsset`. + pub(crate) fn calculate_message_size_fees(message_size: impl FnOnce() -> u32) -> Option { // Apply message size `T::ByteFee/T::FeeAsset` feature (if configured). if let Some(asset_id) = T::FeeAsset::get() { - let message_fee = (message_size as u128).saturating_mul(T::ByteFee::get()); + let message_fee = (message_size() as u128).saturating_mul(T::ByteFee::get()); if message_fee > 0 { - // Keep in mind that this is only the additional fee for message size. - actual_cost.push((asset_id, message_fee).into()); - } - } - - // Apply dynamic fees feature - apply `fee_factor` to the `actual_cost`. - let fee_factor = Self::delivery_fee_factor(); - let mut new_cost = Assets::new(); - for mut a in actual_cost.into_inner() { - if let Fungibility::Fungible(ref mut amount) = a.fun { - *amount = fee_factor.saturating_mul_int(*amount); + return Some((asset_id, message_fee).into()); } - new_cost.push(a); } - new_cost + None } } @@ -255,13 +256,23 @@ pub mod pallet { pub enum Event, I: 'static = ()> { /// Delivery fee factor has been decreased. DeliveryFeeFactorDecreased { + /// Previous value of the `DeliveryFeeFactor`. + previous_value: FixedU128, /// New value of the `DeliveryFeeFactor`. new_value: FixedU128, + /// Bridge identifier. + bridge_id: BridgeIdOf, }, /// Delivery fee factor has been increased. DeliveryFeeFactorIncreased { + /// Previous value of the `DeliveryFeeFactor`. + previous_value: FixedU128, /// New value of the `DeliveryFeeFactor`. new_value: FixedU128, + /// Bridge identifier. + bridge_id: BridgeIdOf, + /// The destination to which the router sends the message. + dest: Location, }, } } @@ -270,7 +281,7 @@ pub mod pallet { // XCMP/DMP transport. This allows injecting dynamic message fees into XCM programs that // are going to the bridged network. impl, I: 'static> SendXcm for Pallet { - type Ticket = (u32, ::Ticket); + type Ticket = (u32, Location, ::Ticket); fn validate( dest: &mut Option, @@ -322,15 +333,12 @@ impl, I: 'static> SendXcm for Pallet { .into_version(destination_version) .map_err(|()| SendError::DestinationUnsupported)?; - // now let's apply fees features - let cost = Self::calculate_fees(message_size, cost); - log::info!( target: LOG_TARGET, "Going to send message to {dest_clone:?} ({message_size:?} bytes) with actual cost: {cost:?}" ); - Ok(((message_size, ticket), cost)) + Ok(((message_size, dest_clone, ticket), cost)) }, Err(e) => { log::trace!(target: LOG_TARGET, "`T::ToBridgeHubSender` validates for dest: {dest_clone:?} with error: {e:?}"); @@ -342,13 +350,17 @@ impl, I: 'static> SendXcm for Pallet { fn deliver(ticket: Self::Ticket) -> Result { // use router to enqueue message to the sibling/child bridge hub. This also should handle // payment for passing through this queue. - let (message_size, ticket) = ticket; + let (message_size, dest, ticket) = ticket; let xcm_hash = T::ToBridgeHubSender::deliver(ticket)?; - // increase delivery fee factor if required - Self::on_message_sent_to_bridge(message_size); + log::trace!( + target: LOG_TARGET, + "deliver - message (size: {message_size:?}) sent to the dest: {dest:?}, xcm_hash: {xcm_hash:?}" + ); + + // increase delivery fee factor (if required) + Self::on_message_sent_to(message_size, dest); - log::trace!(target: LOG_TARGET, "deliver - message sent, xcm_hash: {xcm_hash:?}"); Ok(xcm_hash) } } @@ -374,50 +386,69 @@ mod tests { use sp_runtime::traits::One; #[test] - fn initial_fee_factor_is_one() { + fn fee_factor_is_not_decreased_from_on_initialize_when_bridge_is_congested() { run_test(|| { - assert_eq!(DeliveryFeeFactor::::get(), MINIMAL_DELIVERY_FEE_FACTOR); - }) - } + let dest = Location::new(2, [GlobalConsensus(BridgedNetworkId::get())]); + let old_delivery_fee_factor = FixedU128::from_rational(125, 100); - #[test] - fn fee_factor_is_not_decreased_from_on_initialize_when_xcm_channel_is_congested() { - run_test(|| { - DeliveryFeeFactor::::put(FixedU128::from_rational(125, 100)); - TestLocalXcmChannelManager::make_congested(&SiblingBridgeHubLocation::get()); + // make bridge congested + update fee factor + set_bridge_state_for::(&dest, Some(BridgeState { + delivery_fee_factor: old_delivery_fee_factor, + is_congested: true, + })); // it should not decrease, because queue is congested - let old_delivery_fee_factor = XcmBridgeHubRouter::delivery_fee_factor(); XcmBridgeHubRouter::on_initialize(One::one()); - assert_eq!(XcmBridgeHubRouter::delivery_fee_factor(), old_delivery_fee_factor); + assert_eq!(get_bridge_state_for::(&dest).unwrap().delivery_fee_factor, old_delivery_fee_factor); assert_eq!(System::events(), vec![]); }) } #[test] - fn fee_factor_is_decreased_from_on_initialize_when_xcm_channel_is_uncongested() { + fn fee_factor_decreased_from_on_initialize_when_bridge_is_uncongested() { run_test(|| { + let dest = Location::new(2, [GlobalConsensus(BridgedNetworkId::get())]); let initial_fee_factor = FixedU128::from_rational(125, 100); - DeliveryFeeFactor::::put(initial_fee_factor); - // it shold eventually decreased to one - while XcmBridgeHubRouter::delivery_fee_factor() > MINIMAL_DELIVERY_FEE_FACTOR { + // make bridge uncongested + update fee factor + let bridge_id = set_bridge_state_for::(&dest, Some(BridgeState { + delivery_fee_factor: initial_fee_factor, + is_congested: false, + })); + + // it should eventually decrease and remove + let mut old_delivery_fee_factor = initial_fee_factor; + while let Some(bridge_state) = get_bridge_state_for::(&dest) { + old_delivery_fee_factor = bridge_state.delivery_fee_factor; XcmBridgeHubRouter::on_initialize(One::one()); } - // verify that it doesn't decreases anymore - XcmBridgeHubRouter::on_initialize(One::one()); - assert_eq!(XcmBridgeHubRouter::delivery_fee_factor(), MINIMAL_DELIVERY_FEE_FACTOR); - // check emitted event + // (first one for updating) let first_system_event = System::events().first().cloned(); assert_eq!( first_system_event, Some(EventRecord { phase: Phase::Initialization, event: RuntimeEvent::XcmBridgeHubRouter(Event::DeliveryFeeFactorDecreased { + previous_value: initial_fee_factor, new_value: initial_fee_factor / EXPONENTIAL_FEE_BASE, + bridge_id, + }), + topics: vec![], + }) + ); + // (last one for removing) + let last_system_event = System::events().last().cloned(); + assert_eq!( + last_system_event, + Some(EventRecord { + phase: Phase::Initialization, + event: RuntimeEvent::XcmBridgeHubRouter(Event::DeliveryFeeFactorDecreased { + previous_value: old_delivery_fee_factor, + new_value: 0.into(), + bridge_id, }), topics: vec![], }) @@ -515,11 +546,11 @@ mod tests { let xcm: Xcm<()> = vec![ClearOrigin].into(); let msg_size = xcm.encoded_size(); - // `BASE_FEE + BYTE_FEE * msg_size + HRMP_FEE` - let base_cost_formula = || BASE_FEE + BYTE_FEE * (msg_size as u128) + HRMP_FEE; + // `BASE_FEE + BYTE_FEE * msg_size` (without `HRMP_FEE`) + let base_cost_formula = || BASE_FEE + BYTE_FEE * (msg_size as u128); // initially the base fee is used - let expected_fee = base_cost_formula(); + let expected_fee = base_cost_formula() + HRMP_FEE; assert_eq!( XcmBridgeHubRouter::validate(&mut Some(dest.clone()), &mut Some(xcm.clone())) .unwrap() @@ -528,13 +559,18 @@ mod tests { Some(&(BridgeFeeAsset::get(), expected_fee).into()), ); - // but when factor is larger than one, it increases the fee, so it becomes: - // `base_cost_formula() * F` + // but when factor is larger than one, it increases the fee, so it becomes: `base_cost_formula() * F` let factor = FixedU128::from_rational(125, 100); - DeliveryFeeFactor::::put(factor); + + // make bridge congested + update fee factor + set_bridge_state_for::(&dest, Some(BridgeState { + delivery_fee_factor: factor, + is_congested: true, + })); + let expected_fee = (FixedU128::saturating_from_integer(base_cost_formula()) * factor) .into_inner() / - FixedU128::DIV; + FixedU128::DIV + HRMP_FEE; assert_eq!( XcmBridgeHubRouter::validate(&mut Some(dest), &mut Some(xcm)).unwrap().1.get(0), Some(&(BridgeFeeAsset::get(), expected_fee).into()), @@ -543,12 +579,20 @@ mod tests { } #[test] - fn sent_message_doesnt_increase_factor_if_queue_is_uncongested() { + fn sent_message_doesnt_increase_factor_if_bridge_is_uncongested() { run_test(|| { - let old_delivery_fee_factor = XcmBridgeHubRouter::delivery_fee_factor(); + let dest = Location::new(2, [GlobalConsensus(BridgedNetworkId::get()), Parachain(1000)]); + + // make bridge congested + update fee factor + let old_delivery_fee_factor = FixedU128::from_rational(125, 100); + set_bridge_state_for::(&dest, Some(BridgeState { + delivery_fee_factor: old_delivery_fee_factor, + is_congested: false, + })); + assert_eq!( send_xcm::( - Location::new(2, [GlobalConsensus(BridgedNetworkId::get()), Parachain(1000)]), + dest.clone(), vec![ClearOrigin].into(), ) .map(drop), @@ -556,26 +600,32 @@ mod tests { ); assert!(TestToBridgeHubSender::is_message_sent()); - assert_eq!(old_delivery_fee_factor, XcmBridgeHubRouter::delivery_fee_factor()); + assert_eq!(old_delivery_fee_factor, get_bridge_state_for::(&dest).unwrap().delivery_fee_factor); assert_eq!(System::events(), vec![]); }); } #[test] - fn sent_message_increases_factor_if_xcm_channel_is_congested() { + fn sent_message_increases_factor_if_bridge_is_congested() { run_test(|| { - TestLocalXcmChannelManager::make_congested(&SiblingBridgeHubLocation::get()); + let dest = Location::new(2, [GlobalConsensus(BridgedNetworkId::get()), Parachain(1000)]); + + // make bridge congested + update fee factor + let old_delivery_fee_factor = FixedU128::from_rational(125, 100); + set_bridge_state_for::(&dest, Some(BridgeState { + delivery_fee_factor: old_delivery_fee_factor, + is_congested: true, + })); - let old_delivery_fee_factor = XcmBridgeHubRouter::delivery_fee_factor(); assert_ok!(send_xcm::( - Location::new(2, [GlobalConsensus(BridgedNetworkId::get()), Parachain(1000)]), + dest.clone(), vec![ClearOrigin].into(), ) .map(drop)); assert!(TestToBridgeHubSender::is_message_sent()); - assert!(old_delivery_fee_factor < XcmBridgeHubRouter::delivery_fee_factor()); + assert!(old_delivery_fee_factor < get_bridge_state_for::(&dest).unwrap().delivery_fee_factor); // check emitted event let first_system_event = System::events().first().cloned(); diff --git a/bridges/modules/xcm-bridge-hub-router/src/mock.rs b/bridges/modules/xcm-bridge-hub-router/src/mock.rs index 5bb076dff683..41aa8665f7fa 100644 --- a/bridges/modules/xcm-bridge-hub-router/src/mock.rs +++ b/bridges/modules/xcm-bridge-hub-router/src/mock.rs @@ -18,7 +18,7 @@ use crate as pallet_xcm_bridge_hub_router; -use bp_xcm_bridge_hub_router::XcmChannelStatusProvider; +use bp_xcm_bridge_hub_router::{ResolveBridgeId, BridgeState}; use codec::Encode; use frame_support::{ construct_runtime, derive_impl, parameter_types, @@ -71,22 +71,41 @@ impl frame_system::Config for TestRuntime { type Block = Block; } +/// Simple implementation where every dest resolves to the exact one `BridgeId`. +pub struct EveryDestinationToSameBridgeIdResolver; +impl ResolveBridgeId for EveryDestinationToSameBridgeIdResolver { + type BridgeId = (); + + fn resolve_for_dest(_dest: &Location) -> Option { + Some(()) + } + + fn resolve_for(_bridged_network: &NetworkId, _bridged_dest: &InteriorLocation) -> Option { + Some(()) + } +} + +/// An instance of `pallet_xcm_bridge_hub_router` configured to use a remote exporter with the `ExportMessage` instruction, which will be delivered to a sibling parachain using `SiblingBridgeHubLocation`. impl pallet_xcm_bridge_hub_router::Config<()> for TestRuntime { type RuntimeEvent = RuntimeEvent; type WeightInfo = (); - type UniversalLocation = UniversalLocation; - type SiblingBridgeHubLocation = SiblingBridgeHubLocation; - type BridgedNetworkId = BridgedNetworkId; type DestinationVersion = LatestOrNoneForLocationVersionChecker>; type ToBridgeHubSender = SovereignPaidRemoteExporter< - NetworkExportTable, + pallet_xcm_bridge_hub_router::impls::ViaRemoteBridgeHubExporter< + TestRuntime, + (), + NetworkExportTable, + BridgedNetworkId, + SiblingBridgeHubLocation + >, TestToBridgeHubSender, - Self::UniversalLocation, + UniversalLocation, >; - type LocalXcmChannelManager = TestLocalXcmChannelManager; + + type BridgeIdResolver = EveryDestinationToSameBridgeIdResolver; type ByteFee = ConstU128; type FeeAsset = BridgeFeeAsset; @@ -155,25 +174,6 @@ impl InspectMessageQueues for TestToBridgeHubSender { } } -pub struct TestLocalXcmChannelManager; - -impl TestLocalXcmChannelManager { - pub fn make_congested(with: &Location) { - frame_support::storage::unhashed::put( - &(b"TestLocalXcmChannelManager.Congested", with).encode()[..], - &true, - ); - } -} - -impl XcmChannelStatusProvider for TestLocalXcmChannelManager { - fn is_congested(with: &Location) -> bool { - frame_support::storage::unhashed::get_or_default( - &(b"TestLocalXcmChannelManager.Congested", with).encode()[..], - ) - } -} - /// Return test externalities to use in tests. pub fn new_test_ext() -> sp_io::TestExternalities { let t = frame_system::GenesisConfig::::default().build_storage().unwrap(); @@ -193,3 +193,18 @@ pub fn run_test(test: impl FnOnce() -> T) -> T { pub(crate) fn fake_message_hash(message: &Xcm) -> XcmHash { message.using_encoded(sp_io::hashing::blake2_256) } + +pub(crate) fn set_bridge_state_for, I: 'static>(dest: &Location, bridge_state: Option) -> pallet_xcm_bridge_hub_router::BridgeIdOf { + let bridge_id = ::resolve_for_dest(dest).unwrap(); + if let Some(bridge_state) = bridge_state { + pallet_xcm_bridge_hub_router::Bridges::::insert(&bridge_id, bridge_state); + } else { + pallet_xcm_bridge_hub_router::Bridges::::remove(&bridge_id); + } + bridge_id +} + +pub(crate) fn get_bridge_state_for, I: 'static>(dest: &Location) -> Option { + let bridge_id = ::resolve_for_dest(dest).unwrap(); + pallet_xcm_bridge_hub_router::Bridges::::get(bridge_id) +} \ No newline at end of file diff --git a/bridges/modules/xcm-bridge-hub-router/src/weights.rs b/bridges/modules/xcm-bridge-hub-router/src/weights.rs index d9a0426fecaf..2685d676d385 100644 --- a/bridges/modules/xcm-bridge-hub-router/src/weights.rs +++ b/bridges/modules/xcm-bridge-hub-router/src/weights.rs @@ -50,6 +50,8 @@ use sp_std::marker::PhantomData; /// Weight functions needed for pallet_xcm_bridge_hub_router. pub trait WeightInfo { + fn on_initialize_when_bridge_state_removed() -> Weight; + fn on_initialize_when_bridge_state_updated() -> Weight; fn on_initialize_when_non_congested() -> Weight; fn on_initialize_when_congested() -> Weight; } @@ -59,6 +61,13 @@ pub trait WeightInfo { /// Those weights are test only and must never be used in production. pub struct BridgeWeight(PhantomData); impl WeightInfo for BridgeWeight { + fn on_initialize_when_bridge_state_removed() -> Weight { + RocksDbWeight::get().writes(1) + } + + fn on_initialize_when_bridge_state_updated() -> Weight { + RocksDbWeight::get().writes(1) + } /// /// Storage: `XcmBridgeHubRouter::DeliveryFeeFactor` (r:1 w:1) /// @@ -89,6 +98,14 @@ impl WeightInfo for BridgeWeight { // For backwards compatibility and tests impl WeightInfo for () { + fn on_initialize_when_bridge_state_removed() -> Weight { + RocksDbWeight::get().writes(1) + } + + fn on_initialize_when_bridge_state_updated() -> Weight { + RocksDbWeight::get().writes(1) + } + /// Storage: UNKNOWN KEY `0x456d756c617465645369626c696e6758636d704368616e6e656c2e436f6e6765` /// (r:1 w:0) /// diff --git a/bridges/modules/xcm-bridge-hub/Cargo.toml b/bridges/modules/xcm-bridge-hub/Cargo.toml index fe58b910a94e..8bf76d8edcfc 100644 --- a/bridges/modules/xcm-bridge-hub/Cargo.toml +++ b/bridges/modules/xcm-bridge-hub/Cargo.toml @@ -38,6 +38,7 @@ 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 } diff --git a/bridges/modules/xcm-bridge-hub/src/mock.rs b/bridges/modules/xcm-bridge-hub/src/mock.rs index 281293e848a6..377abdb8816c 100644 --- a/bridges/modules/xcm-bridge-hub/src/mock.rs +++ b/bridges/modules/xcm-bridge-hub/src/mock.rs @@ -16,6 +16,7 @@ #![cfg(test)] +use sp_std::marker::PhantomData; use crate as pallet_xcm_bridge_hub; use bp_messages::{ @@ -25,11 +26,13 @@ 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}, weights::RuntimeDbWeight, }; +use frame_support::traits::Get; use frame_system::EnsureRootWithSuccess; use polkadot_parachain_primitives::primitives::Sibling; use sp_core::H256; @@ -43,7 +46,7 @@ use xcm::{latest::ROCOCO_GENESIS_HASH, prelude::*}; use xcm_builder::{ AllowUnpaidExecutionFrom, DispatchBlob, DispatchBlobError, FixedWeightBounds, InspectMessageQueues, NetworkExportTable, NetworkExportTableItem, ParentIsPreset, - SiblingParachainConvertsVia, SovereignPaidRemoteExporter, UnpaidLocalExporter, + SiblingParachainConvertsVia, SovereignPaidRemoteExporter, UnpaidLocalExporter, ensure_is_remote, }; use xcm_executor::{traits::ConvertLocation, XcmExecutor}; @@ -221,48 +224,66 @@ impl pallet_xcm_bridge_hub_router::Config<()> for TestRuntime { type RuntimeEvent = RuntimeEvent; type WeightInfo = (); - type UniversalLocation = UniversalLocation; - type SiblingBridgeHubLocation = BridgeHubLocation; - type BridgedNetworkId = BridgedRelayNetwork; type DestinationVersion = AlwaysLatest; // We use `SovereignPaidRemoteExporter` here to test and ensure that the `ExportMessage` // produced by `pallet_xcm_bridge_hub_router` is compatible with the `ExportXcm` implementation // of `pallet_xcm_bridge_hub`. type ToBridgeHubSender = SovereignPaidRemoteExporter< - NetworkExportTable, + pallet_xcm_bridge_hub_router::impls::ViaRemoteBridgeHubExporter< + TestRuntime, + (), + NetworkExportTable, + BridgedRelayNetwork, + BridgeHubLocation + >, // **Note**: The crucial part is that `ExportMessage` is processed by `XcmExecutor`, which // calls the `ExportXcm` implementation of `pallet_xcm_bridge_hub` as the // `MessageExporter`. ExecuteXcmOverSendXcm, - Self::UniversalLocation, + UniversalLocation, >; - type LocalXcmChannelManager = TestLocalXcmChannelManager; + + type BridgeIdResolver = BridgeIdResolver; type ByteFee = ConstU128<0>; type FeeAsset = BridgeFeeAsset; } -/// A router instance simulates a scenario where the router is deployed on the same chain than the +/// A router instance simulates a scenario where the router is deployed on the same chain as the /// `MessageExporter`. This means that the router triggers `ExportXcm` trait directly. impl pallet_xcm_bridge_hub_router::Config for TestRuntime { type RuntimeEvent = RuntimeEvent; type WeightInfo = (); - type UniversalLocation = UniversalLocation; - type SiblingBridgeHubLocation = BridgeHubLocation; - type BridgedNetworkId = BridgedRelayNetwork; type DestinationVersion = AlwaysLatest; // We use `UnpaidLocalExporter` here to test and ensure that `pallet_xcm_bridge_hub_router` can // trigger directly `pallet_xcm_bridge_hub` as exporter. - type ToBridgeHubSender = UnpaidLocalExporter; - type LocalXcmChannelManager = TestLocalXcmChannelManager; + type ToBridgeHubSender = UnpaidLocalExporter; + + type BridgeIdResolver = BridgeIdResolver; type ByteFee = ConstU128<0>; type FeeAsset = BridgeFeeAsset; } +/// Implementation of `ResolveBridgeId` returning `BridgeId`. +pub struct BridgeIdResolver(PhantomData); +impl> ResolveBridgeId for BridgeIdResolver { + type BridgeId = BridgeId; + + fn resolve_for_dest(dest: &Location) -> Option { + 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 { + let bridged_universal_location = bridged_dest.clone().pushed_front_with(bridged_network.clone()).unwrap(); + Some(BridgeId::new(&UniversalLocation::get(), &bridged_universal_location)) + } +} + pub struct XcmConfig; impl xcm_executor::Config for XcmConfig { type RuntimeCall = RuntimeCall; @@ -471,12 +492,6 @@ impl LocalXcmChannelManager for TestLocalXcmChannelManager { } } -impl pallet_xcm_bridge_hub_router::XcmChannelStatusProvider for TestLocalXcmChannelManager { - fn is_congested(with: &Location) -> bool { - ::is_congested(with) - } -} - pub struct TestBlobDispatcher; impl TestBlobDispatcher { diff --git a/bridges/primitives/xcm-bridge-hub-router/src/lib.rs b/bridges/primitives/xcm-bridge-hub-router/src/lib.rs index 5e7511bb3ece..c894e577f681 100644 --- a/bridges/primitives/xcm-bridge-hub-router/src/lib.rs +++ b/bridges/primitives/xcm-bridge-hub-router/src/lib.rs @@ -18,14 +18,11 @@ #![cfg_attr(not(feature = "std"), no_std)] -use codec::{Decode, Encode, MaxEncodedLen}; +use codec::{Decode, Encode, FullCodec, MaxEncodedLen}; use scale_info::TypeInfo; -use sp_core::H256; +use sp_core::{H256, sp_std::fmt::Debug}; use sp_runtime::{FixedU128, RuntimeDebug}; -use xcm::latest::prelude::Location; - -/// Minimal delivery fee factor. -pub const MINIMAL_DELIVERY_FEE_FACTOR: FixedU128 = FixedU128::from_u32(1); +use xcm::latest::prelude::{Location, NetworkId, InteriorLocation}; /// XCM channel status provider that may report whether it is congested or not. /// @@ -51,9 +48,27 @@ pub struct BridgeState { pub is_congested: bool, } -impl Default for BridgeState { - fn default() -> BridgeState { - BridgeState { delivery_fee_factor: MINIMAL_DELIVERY_FEE_FACTOR, is_congested: false } +/// Trait that resolves a specific `BridgeId` for `dest`. +pub trait ResolveBridgeId { + /// Bridge identifier. + type BridgeId: FullCodec + MaxEncodedLen + TypeInfo + Debug + Clone + PartialEq + Eq; + /// Resolves `Self::BridgeId` for `dest`. If `None`, it means there is no supported bridge ID. + fn resolve_for_dest(bridged_dest: &Location) -> Option; + + /// Resolves `Self::BridgeId` for `bridged_network` and `bridged_dest`. If `None`, it means there is no supported bridge ID. + fn resolve_for(bridged_network: &NetworkId, bridged_dest: &InteriorLocation) -> Option; +} + +/// The default implementation of `ResolveBridgeId` for `()` returns `None`. +impl ResolveBridgeId for () { + type BridgeId = (); + + fn resolve_for_dest(_dest: &Location) -> Option { + None + } + + fn resolve_for(_bridged_network: &NetworkId, _bridged_dest: &InteriorLocation) -> Option { + None } } From 24626fd5cae9cdddbfaa14f66d54293d49dcf0e6 Mon Sep 17 00:00:00 2001 From: Branislav Kontur Date: Sun, 3 Nov 2024 00:34:54 +0100 Subject: [PATCH 16/72] Nits --- .../modules/xcm-bridge-hub-router/src/lib.rs | 33 ++++++++- .../modules/xcm-bridge-hub-router/src/mock.rs | 4 +- .../modules/xcm-bridge-hub/src/exporter.rs | 68 ++++++++++++++++++- bridges/modules/xcm-bridge-hub/src/mock.rs | 53 ++++++++------- 4 files changed, 125 insertions(+), 33 deletions(-) diff --git a/bridges/modules/xcm-bridge-hub-router/src/lib.rs b/bridges/modules/xcm-bridge-hub-router/src/lib.rs index e032c1228c82..1d4a4c4fdcdb 100644 --- a/bridges/modules/xcm-bridge-hub-router/src/lib.rs +++ b/bridges/modules/xcm-bridge-hub-router/src/lib.rs @@ -29,7 +29,6 @@ #![cfg_attr(not(feature = "std"), no_std)] -pub use bp_xcm_bridge_hub_router::XcmChannelStatusProvider; use bp_xcm_bridge_hub_router::{BridgeState, ResolveBridgeId}; use codec::Encode; use frame_support::traits::Get; @@ -76,9 +75,35 @@ pub mod pallet { use frame_support::pallet_prelude::*; use frame_system::pallet_prelude::*; - #[pallet::config] + /// Default implementations of [`DefaultConfig`], which can be used to implement [`Config`]. + pub mod config_preludes { + use super::*; + use frame_support::{derive_impl, traits::ConstU128}; + + /// A type providing default configurations for this pallet in testing environment. + pub struct TestDefaultConfig; + + #[derive_impl(frame_system::config_preludes::TestDefaultConfig, no_aggregated_types)] + impl frame_system::DefaultConfig for TestDefaultConfig {} + + #[frame_support::register_default_impl(TestDefaultConfig)] + impl DefaultConfig for TestDefaultConfig { + #[inject_runtime_type] + type RuntimeEvent = (); + type WeightInfo = (); + type DestinationVersion = AlwaysLatest; + + // We don't need (optional) message_size fees. + type ByteFee = ConstU128<0>; + // We don't need (optional) message_size fees. + type FeeAsset = (); + } + } + + #[pallet::config(with_default)] pub trait Config: frame_system::Config { /// The overarching event type. + #[pallet::no_default_bounds] type RuntimeEvent: From> + IsType<::RuntimeEvent>; /// Benchmarks results from runtime we're plugged into. @@ -94,10 +119,12 @@ pub mod pallet { /// - The local chain, in which case we need an implementation for `T::ToBridgeHubSender` /// that does not use `ExportMessage` but instead directly calls the `ExportXcm` /// implementation. + #[pallet::no_default] type ToBridgeHubSender: SendXcm; /// Resolves a specific `BridgeId` for `dest`, used for identifying the bridge in cases of congestion and dynamic fees. /// If it resolves to `None`, it means no congestion or dynamic fees are handled for `dest`. + #[pallet::no_default] type BridgeIdResolver: ResolveBridgeId; /// Additional fee that is paid for every byte of the outbound message. @@ -179,7 +206,7 @@ pub mod pallet { /// Stores `BridgeState` for congestion control and dynamic fees for each resolved bridge ID associated with a destination. #[pallet::storage] - pub type Bridges, I: 'static = ()> = StorageMap<_, Blake2_128Concat, BridgeIdOf, BridgeState, OptionQuery>; + pub type Bridges, I: 'static = ()> = StorageMap<_, Identity, BridgeIdOf, BridgeState, OptionQuery>; impl, I: 'static> Pallet { /// Called when new message is sent to the `dest` (queued to local outbound XCM queue). diff --git a/bridges/modules/xcm-bridge-hub-router/src/mock.rs b/bridges/modules/xcm-bridge-hub-router/src/mock.rs index 41aa8665f7fa..2573cb6b9f36 100644 --- a/bridges/modules/xcm-bridge-hub-router/src/mock.rs +++ b/bridges/modules/xcm-bridge-hub-router/src/mock.rs @@ -86,10 +86,8 @@ impl ResolveBridgeId for EveryDestinationToSameBridgeIdResolver { } /// An instance of `pallet_xcm_bridge_hub_router` configured to use a remote exporter with the `ExportMessage` instruction, which will be delivered to a sibling parachain using `SiblingBridgeHubLocation`. +#[derive_impl(pallet_xcm_bridge_hub_router::config_preludes::TestDefaultConfig)] impl pallet_xcm_bridge_hub_router::Config<()> for TestRuntime { - type RuntimeEvent = RuntimeEvent; - type WeightInfo = (); - type DestinationVersion = LatestOrNoneForLocationVersionChecker>; diff --git a/bridges/modules/xcm-bridge-hub/src/exporter.rs b/bridges/modules/xcm-bridge-hub/src/exporter.rs index 295ea2301ab4..bbdca5dd6dd9 100644 --- a/bridges/modules/xcm-bridge-hub/src/exporter.rs +++ b/bridges/modules/xcm-bridge-hub/src/exporter.rs @@ -365,6 +365,7 @@ mod tests { use bp_runtime::RangeInclusiveExt; use bp_xcm_bridge_hub::{Bridge, BridgeLocations, BridgeState}; + use bp_xcm_bridge_hub_router::ResolveBridgeId; use frame_support::{ assert_ok, traits::{Contains, EnsureOrigin}, @@ -632,7 +633,16 @@ mod tests { let origin = OpenBridgeOrigin::sibling_parachain_origin(); let origin_as_location = OpenBridgeOriginOf::::try_origin(origin.clone()).unwrap(); - let (_, expected_lane_id) = open_lane(origin); + let (bridge, expected_lane_id) = open_lane(origin); + + // we need to set `UniversalLocation` for `sibling_parachain_origin` for `XcmOverBridgeWrappedWithExportMessageRouterInstance`. + ExportMessageOriginUniversalLocation::set(Some(SiblingUniversalLocation::get())); + + // check compatible bridge_id + assert_eq!( + bridge.bridge_id(), + &>::BridgeIdResolver::resolve_for_dest(&dest).unwrap() + ); // check before - no messages assert_eq!( @@ -683,7 +693,13 @@ mod tests { // open bridge as a root on the local chain, which should be converted as // `Location::here()` - let (_, expected_lane_id) = open_lane(RuntimeOrigin::root()); + let (bridge, expected_lane_id) = open_lane(RuntimeOrigin::root()); + + // check compatible bridge_id + assert_eq!( + bridge.bridge_id(), + &>::BridgeIdResolver::resolve_for_dest(&dest).unwrap() + ); // check before - no messages assert_eq!( @@ -804,4 +820,52 @@ mod tests { assert_eq!(None, dest_wrapper); }); } + + #[test] + fn congestion_with_pallet_xcm_bridge_hub_router_works() { + run_test(|| { + // valid routable destination + let dest = Location::new(2, BridgedUniversalDestination::get()); + + fn router_bridge_state, I: 'static>(dest: &Location) -> Option { + let bridge_id = ::resolve_for_dest(dest).unwrap(); + pallet_xcm_bridge_hub_router::Bridges::::get(&bridge_id) + } + + // open two bridges + let origin = OpenBridgeOrigin::sibling_parachain_origin(); + let origin_as_location = OpenBridgeOriginOf::::try_origin(origin.clone()).unwrap(); + let (bridge_1, expected_lane_id_1) = open_lane(origin); + let (bridge_2, expected_lane_id_2) = open_lane(RuntimeOrigin::root()); + assert_ne!(expected_lane_id_1, expected_lane_id_2); + assert_ne!(bridge_1.bridge_id(), bridge_2.bridge_id()); + + // we need to set `UniversalLocation` for `sibling_parachain_origin` for `XcmOverBridgeWrappedWithExportMessageRouterInstance`. + ExportMessageOriginUniversalLocation::set(Some(SiblingUniversalLocation::get())); + + // check before + assert_eq!(XcmOverBridge::bridge(bridge_1.bridge_id()).unwrap().state, BridgeState::Opened); + assert_eq!(XcmOverBridge::bridge(bridge_2.bridge_id()).unwrap().state, BridgeState::Opened); + // both routers are uncongested + assert!(!router_bridge_state::(&dest).map(|bs| bs.is_congested).unwrap_or(false)); + assert!(!router_bridge_state::(&dest).map(|bs| bs.is_congested).unwrap_or(false)); + + // make bridges congested with sending too much messages + for _ in 1..(OUTBOUND_LANE_CONGESTED_THRESHOLD + 2) { + // send `ExportMessage(message)` by `pallet_xcm_bridge_hub_router`. + ExecuteXcmOverSendXcm::set_origin_for_execute(origin_as_location.clone()); + assert_ok!(send_xcm::(dest.clone(), Xcm::<()>::default())); + + // call direct `ExportXcm` by `pallet_xcm_bridge_hub_router`. + assert_ok!(send_xcm::(dest.clone(), Xcm::<()>::default())); + } + + // checks after + assert_eq!(XcmOverBridge::bridge(bridge_1.bridge_id()).unwrap().state, BridgeState::Suspended); + assert_eq!(XcmOverBridge::bridge(bridge_2.bridge_id()).unwrap().state, BridgeState::Suspended); + // both routers are congested + assert!(router_bridge_state::(&dest).unwrap().is_congested); + assert!(router_bridge_state::(&dest).unwrap().is_congested); + }) + } } diff --git a/bridges/modules/xcm-bridge-hub/src/mock.rs b/bridges/modules/xcm-bridge-hub/src/mock.rs index 377abdb8816c..8b17081783b2 100644 --- a/bridges/modules/xcm-bridge-hub/src/mock.rs +++ b/bridges/modules/xcm-bridge-hub/src/mock.rs @@ -38,7 +38,7 @@ use polkadot_parachain_primitives::primitives::Sibling; use sp_core::H256; use sp_runtime::{ testing::Header as SubstrateHeader, - traits::{BlakeTwo256, ConstU128, ConstU32, IdentityLookup}, + traits::{BlakeTwo256, ConstU32, IdentityLookup}, AccountId32, BuildStorage, StateVersion, }; use sp_std::cell::RefCell; @@ -172,7 +172,6 @@ parameter_types! { // configuration for pallet_xcm_bridge_hub_router pub BridgeHubLocation: Location = Here.into(); - pub BridgeFeeAsset: AssetId = Location::here().into(); pub BridgeTable: Vec = vec![ NetworkExportTableItem::new( @@ -220,12 +219,9 @@ impl pallet_xcm_bridge_hub::Config for TestRuntime { /// A router instance simulates a scenario where the router is deployed on a different chain than /// the `MessageExporter`. This means that the router sends an `ExportMessage`. +pub type XcmOverBridgeWrappedWithExportMessageRouterInstance = (); +#[derive_impl(pallet_xcm_bridge_hub_router::config_preludes::TestDefaultConfig)] impl pallet_xcm_bridge_hub_router::Config<()> for TestRuntime { - type RuntimeEvent = RuntimeEvent; - type WeightInfo = (); - - type DestinationVersion = AlwaysLatest; - // We use `SovereignPaidRemoteExporter` here to test and ensure that the `ExportMessage` // produced by `pallet_xcm_bridge_hub_router` is compatible with the `ExportXcm` implementation // of `pallet_xcm_bridge_hub`. @@ -241,36 +237,27 @@ impl pallet_xcm_bridge_hub_router::Config<()> for TestRuntime { // calls the `ExportXcm` implementation of `pallet_xcm_bridge_hub` as the // `MessageExporter`. ExecuteXcmOverSendXcm, - UniversalLocation, + ExportMessageOriginUniversalLocation, >; - type BridgeIdResolver = BridgeIdResolver; - - type ByteFee = ConstU128<0>; - type FeeAsset = BridgeFeeAsset; + type BridgeIdResolver = EnsureIsRemoteBridgeIdResolver; } /// A router instance simulates a scenario where the router is deployed on the same chain as the /// `MessageExporter`. This means that the router triggers `ExportXcm` trait directly. -impl pallet_xcm_bridge_hub_router::Config for TestRuntime { - type RuntimeEvent = RuntimeEvent; - type WeightInfo = (); - - type DestinationVersion = AlwaysLatest; - +pub type XcmOverBridgeByExportXcmRouterInstance = pallet_xcm_bridge_hub_router::Instance2; +#[derive_impl(pallet_xcm_bridge_hub_router::config_preludes::TestDefaultConfig)] +impl pallet_xcm_bridge_hub_router::Config for TestRuntime { // We use `UnpaidLocalExporter` here to test and ensure that `pallet_xcm_bridge_hub_router` can // trigger directly `pallet_xcm_bridge_hub` as exporter. type ToBridgeHubSender = UnpaidLocalExporter; - type BridgeIdResolver = BridgeIdResolver; - - type ByteFee = ConstU128<0>; - type FeeAsset = BridgeFeeAsset; + type BridgeIdResolver = EnsureIsRemoteBridgeIdResolver; } -/// Implementation of `ResolveBridgeId` returning `BridgeId`. -pub struct BridgeIdResolver(PhantomData); -impl> ResolveBridgeId for BridgeIdResolver { +/// Implementation of `ResolveBridgeId` returning `BridgeId` based on the configured `UniversalLocation`. +pub struct EnsureIsRemoteBridgeIdResolver(PhantomData); +impl> ResolveBridgeId for EnsureIsRemoteBridgeIdResolver { type BridgeId = BridgeId; fn resolve_for_dest(dest: &Location) -> Option { @@ -284,6 +271,22 @@ impl> ResolveBridgeId for BridgeIdResol } } +/// A dynamic way to set different universal location for the origin which sends `ExportMessage`. +pub struct ExportMessageOriginUniversalLocation; +impl ExportMessageOriginUniversalLocation { + pub(crate) fn set(universal_location: Option) { + EXPORT_MESSAGE_ORIGIN_UNIVERSAL_LOCATION.with(|o| *o.borrow_mut() = universal_location); + } +} +impl Get for ExportMessageOriginUniversalLocation { + fn get() -> InteriorLocation { + EXPORT_MESSAGE_ORIGIN_UNIVERSAL_LOCATION.with(|o| o.borrow().clone().expect("`EXPORT_MESSAGE_ORIGIN_UNIVERSAL_LOCATION` is not set!")) + } +} +thread_local! { + pub static EXPORT_MESSAGE_ORIGIN_UNIVERSAL_LOCATION: RefCell> = RefCell::new(None); +} + pub struct XcmConfig; impl xcm_executor::Config for XcmConfig { type RuntimeCall = RuntimeCall; From fa2f8c7148876b222b8deca7ae6b9708759ffa0a Mon Sep 17 00:00:00 2001 From: Branislav Kontur Date: Mon, 4 Nov 2024 16:08:13 +0100 Subject: [PATCH 17/72] Report congestion and logical bridges/channel with tests --- Cargo.lock | 3 +- .../modules/xcm-bridge-hub-router/Cargo.toml | 2 + .../xcm-bridge-hub-router/src/impls.rs | 41 ++++- .../modules/xcm-bridge-hub-router/src/lib.rs | 93 ++++++++++- .../modules/xcm-bridge-hub-router/src/mock.rs | 6 +- .../xcm-bridge-hub-router/src/weights.rs | 27 ++++ .../modules/xcm-bridge-hub/src/congestion.rs | 151 ++++++++++++++++++ .../modules/xcm-bridge-hub/src/dispatcher.rs | 14 +- .../modules/xcm-bridge-hub/src/exporter.rs | 59 +++++-- bridges/modules/xcm-bridge-hub/src/lib.rs | 20 ++- .../modules/xcm-bridge-hub/src/migration.rs | 1 + bridges/modules/xcm-bridge-hub/src/mock.rs | 139 +++++++++++++--- .../xcm-bridge-hub-router/src/lib.rs | 15 -- bridges/primitives/xcm-bridge-hub/src/lib.rs | 57 +++++-- cumulus/pallets/xcmp-queue/Cargo.toml | 6 +- cumulus/pallets/xcmp-queue/src/bridging.rs | 8 +- 16 files changed, 551 insertions(+), 91 deletions(-) create mode 100644 bridges/modules/xcm-bridge-hub/src/congestion.rs diff --git a/Cargo.lock b/Cargo.lock index 107ac0decf7d..04912ae22941 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4492,7 +4492,7 @@ name = "cumulus-pallet-xcmp-queue" version = "0.7.0" dependencies = [ "bounded-collections", - "bp-xcm-bridge-hub-router", + "bp-xcm-bridge-hub", "cumulus-pallet-parachain-system", "cumulus-primitives-core", "frame-benchmarking", @@ -13278,6 +13278,7 @@ dependencies = [ name = "pallet-xcm-bridge-hub-router" version = "0.5.0" dependencies = [ + "bp-xcm-bridge-hub", "bp-xcm-bridge-hub-router", "frame-benchmarking", "frame-support", diff --git a/bridges/modules/xcm-bridge-hub-router/Cargo.toml b/bridges/modules/xcm-bridge-hub-router/Cargo.toml index 55824f6a7fe7..1cda8893967e 100644 --- a/bridges/modules/xcm-bridge-hub-router/Cargo.toml +++ b/bridges/modules/xcm-bridge-hub-router/Cargo.toml @@ -17,6 +17,7 @@ scale-info = { features = ["bit-vec", "derive", "serde"], workspace = true } # Bridge dependencies bp-xcm-bridge-hub-router = { workspace = true } +bp-xcm-bridge-hub = { workspace = true } # Substrate Dependencies frame-benchmarking = { optional = true, workspace = true } @@ -38,6 +39,7 @@ sp-std = { workspace = true, default-features = true } default = ["std"] std = [ "bp-xcm-bridge-hub-router/std", + "bp-xcm-bridge-hub/std", "codec/std", "frame-benchmarking/std", "frame-support/std", diff --git a/bridges/modules/xcm-bridge-hub-router/src/impls.rs b/bridges/modules/xcm-bridge-hub-router/src/impls.rs index 99dac41f93c3..6114a0b75ca6 100644 --- a/bridges/modules/xcm-bridge-hub-router/src/impls.rs +++ b/bridges/modules/xcm-bridge-hub-router/src/impls.rs @@ -15,14 +15,53 @@ // along with Parity Bridges Common. If not, see . //! Various implementations supporting easier configuration of the pallet. -use crate::{Config, Pallet, Bridges, LOG_TARGET}; +use crate::{Config, Pallet, Bridges, BridgeIdOf, LOG_TARGET}; use xcm_builder::ExporterFor; use bp_xcm_bridge_hub_router::ResolveBridgeId; use codec::Encode; use frame_support::pallet_prelude::PhantomData; use frame_support::traits::Get; +use frame_support::ensure; use xcm::prelude::*; +/// Implementation of `LocalXcmChannelManager` which tracks and updates `is_congested` for a given `BridgeId`. +/// This implementation is useful for managing congestion and dynamic fees with the local `ExportXcm` implementation. +impl, I: 'static> bp_xcm_bridge_hub::LocalXcmChannelManager> for Pallet { + type Error = (); + + /// Suspends the given bridge. + /// + /// This function ensures that the `local_origin` matches the expected `Location::here()`. If the check passes, it updates the bridge status to congested. + fn suspend_bridge(local_origin: &Location, bridge: BridgeIdOf) -> Result<(), Self::Error> { + log::trace!( + target: LOG_TARGET, + "LocalXcmChannelManager::suspend_bridge(local_origin: {local_origin:?}, bridge: {bridge:?})", + ); + ensure!(local_origin.eq(&Location::here()), ()); + + // update status + Self::update_bridge_status(bridge, true); + + Ok(()) + } + + /// Resumes the given bridge. + /// + /// This function ensures that the `local_origin` matches the expected `Location::here()`. If the check passes, it updates the bridge status to not congested. + fn resume_bridge(local_origin: &Location, bridge: BridgeIdOf) -> Result<(), Self::Error> { + log::trace!( + target: LOG_TARGET, + "LocalXcmChannelManager::resume_bridge(local_origin: {local_origin:?}, bridge: {bridge:?})", + ); + ensure!(local_origin.eq(&Location::here()), ()); + + // update status + Self::update_bridge_status(bridge, false); + + Ok(()) + } +} + pub struct ViaRemoteBridgeHubExporter(PhantomData<(T, I, E, BNF, BHLF)>); impl, I: 'static, E, BridgedNetworkIdFilter, BridgeHubLocationFilter> ExporterFor for ViaRemoteBridgeHubExporter diff --git a/bridges/modules/xcm-bridge-hub-router/src/lib.rs b/bridges/modules/xcm-bridge-hub-router/src/lib.rs index 1d4a4c4fdcdb..a6dfe20266f9 100644 --- a/bridges/modules/xcm-bridge-hub-router/src/lib.rs +++ b/bridges/modules/xcm-bridge-hub-router/src/lib.rs @@ -31,7 +31,7 @@ use bp_xcm_bridge_hub_router::{BridgeState, ResolveBridgeId}; use codec::Encode; -use frame_support::traits::Get; +use frame_support::traits::{EnsureOriginWithArg, Get}; use sp_runtime::{FixedPointNumber, FixedU128, Saturating}; use sp_std::vec::Vec; use xcm::prelude::*; @@ -127,6 +127,10 @@ pub mod pallet { #[pallet::no_default] type BridgeIdResolver: ResolveBridgeId; + /// Origin of the sibling bridge hub that is allowed to report bridge status. + #[pallet::no_default] + type BridgeHubOrigin: EnsureOriginWithArg>; + /// Additional fee that is paid for every byte of the outbound message. /// See `calculate_message_size_fees` for more details. type ByteFee: Get; @@ -204,9 +208,35 @@ pub mod pallet { } } + #[pallet::call] + impl, I: 'static> Pallet { + /// Notification about congested bridge queue. + #[pallet::call_index(0)] + #[pallet::weight(T::WeightInfo::report_bridge_status())] + pub fn report_bridge_status( + origin: OriginFor, + bridge_id: BridgeIdOf, + is_congested: bool, + ) -> DispatchResult { + let _ = T::BridgeHubOrigin::ensure_origin(origin, &bridge_id)?; + + log::info!( + target: LOG_TARGET, + "Received bridge status from {:?}: congested = {}", + bridge_id, + is_congested, + ); + + // update status + Self::update_bridge_status(bridge_id, is_congested); + + Ok(()) + } + } + /// Stores `BridgeState` for congestion control and dynamic fees for each resolved bridge ID associated with a destination. #[pallet::storage] - pub type Bridges, I: 'static = ()> = StorageMap<_, Identity, BridgeIdOf, BridgeState, OptionQuery>; + pub type Bridges, I: 'static = ()> = StorageMap<_, Blake2_128Concat, BridgeIdOf, BridgeState, OptionQuery>; impl, I: 'static> Pallet { /// Called when new message is sent to the `dest` (queued to local outbound XCM queue). @@ -276,6 +306,24 @@ pub mod pallet { } None } + /// Updates the congestion status of a bridge for a given `bridge_id`. + /// + /// If the bridge does not exist and: + /// - `is_congested` is true, a new `BridgeState` is created with a default `delivery_fee_factor`. + /// - `is_congested` is false, does nothing and no `BridgeState` is created. + pub(crate) fn update_bridge_status(bridge_id: BridgeIdOf, is_congested: bool) { + Bridges::::mutate(bridge_id, |bridge| match bridge { + Some(bridge) => bridge.is_congested = is_congested, + None => { + if is_congested { + *bridge = Some(BridgeState { + delivery_fee_factor: MINIMAL_DELIVERY_FEE_FACTOR, + is_congested, + }) + } + } + }); + } } #[pallet::event] @@ -410,7 +458,7 @@ mod tests { use frame_support::traits::Hooks; use frame_system::{EventRecord, Phase}; - use sp_runtime::traits::One; + use sp_runtime::traits::{Dispatchable, One}; #[test] fn fee_factor_is_not_decreased_from_on_initialize_when_bridge_is_congested() { @@ -445,9 +493,9 @@ mod tests { })); // it should eventually decrease and remove - let mut old_delivery_fee_factor = initial_fee_factor; + let mut last_delivery_fee_factor = initial_fee_factor; while let Some(bridge_state) = get_bridge_state_for::(&dest) { - old_delivery_fee_factor = bridge_state.delivery_fee_factor; + last_delivery_fee_factor = bridge_state.delivery_fee_factor; XcmBridgeHubRouter::on_initialize(One::one()); } @@ -473,7 +521,7 @@ mod tests { Some(EventRecord { phase: Phase::Initialization, event: RuntimeEvent::XcmBridgeHubRouter(Event::DeliveryFeeFactorDecreased { - previous_value: old_delivery_fee_factor, + previous_value: last_delivery_fee_factor, new_value: 0.into(), bridge_id, }), @@ -679,4 +727,37 @@ mod tests { assert_eq!(XcmBridgeHubRouter::get_messages(), vec![]); }); } + + #[test] + fn report_bridge_status_works() { + run_test(|| { + let dest = Location::new(2, [GlobalConsensus(BridgedNetworkId::get()), Parachain(1000)]); + let bridge_id = (); + let report_bridge_status = |bridge_id, is_congested| { + let call = RuntimeCall::XcmBridgeHubRouter(Call::report_bridge_status { + bridge_id, + is_congested, + }); + assert_ok!(call.dispatch(RuntimeOrigin::root())); + }; + + assert!(get_bridge_state_for::(&dest).is_none()); + report_bridge_status(bridge_id, false); + assert!(get_bridge_state_for::(&dest).is_none()); + + // make congested + report_bridge_status(bridge_id, true); + assert_eq!(get_bridge_state_for::(&dest), Some(BridgeState { + delivery_fee_factor: MINIMAL_DELIVERY_FEE_FACTOR, + is_congested: true, + })); + + // make uncongested + report_bridge_status(bridge_id, false); + assert_eq!(get_bridge_state_for::(&dest), Some(BridgeState { + delivery_fee_factor: MINIMAL_DELIVERY_FEE_FACTOR, + is_congested: false, + })); + }); + } } diff --git a/bridges/modules/xcm-bridge-hub-router/src/mock.rs b/bridges/modules/xcm-bridge-hub-router/src/mock.rs index 2573cb6b9f36..0f7d632c4876 100644 --- a/bridges/modules/xcm-bridge-hub-router/src/mock.rs +++ b/bridges/modules/xcm-bridge-hub-router/src/mock.rs @@ -24,6 +24,7 @@ use frame_support::{ construct_runtime, derive_impl, parameter_types, traits::{Contains, Equals}, }; +use frame_system::EnsureRoot; use sp_runtime::{traits::ConstU128, BuildStorage}; use sp_std::cell::RefCell; use xcm::prelude::*; @@ -43,8 +44,8 @@ pub const BYTE_FEE: u128 = 1_000; construct_runtime! { pub enum TestRuntime { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - XcmBridgeHubRouter: pallet_xcm_bridge_hub_router::{Pallet, Storage, Event}, + System: frame_system, + XcmBridgeHubRouter: pallet_xcm_bridge_hub_router, } } @@ -104,6 +105,7 @@ impl pallet_xcm_bridge_hub_router::Config<()> for TestRuntime { >; type BridgeIdResolver = EveryDestinationToSameBridgeIdResolver; + type BridgeHubOrigin = EnsureRoot; type ByteFee = ConstU128; type FeeAsset = BridgeFeeAsset; diff --git a/bridges/modules/xcm-bridge-hub-router/src/weights.rs b/bridges/modules/xcm-bridge-hub-router/src/weights.rs index 2685d676d385..dc5f1ea1a99a 100644 --- a/bridges/modules/xcm-bridge-hub-router/src/weights.rs +++ b/bridges/modules/xcm-bridge-hub-router/src/weights.rs @@ -54,6 +54,7 @@ pub trait WeightInfo { fn on_initialize_when_bridge_state_updated() -> Weight; fn on_initialize_when_non_congested() -> Weight; fn on_initialize_when_congested() -> Weight; + fn report_bridge_status() -> Weight; } /// Weights for `pallet_xcm_bridge_hub_router` that are generated using one of the Bridge testnets. @@ -94,6 +95,19 @@ impl WeightInfo for BridgeWeight { // Minimum execution time: 4_239 nanoseconds. Weight::from_parts(4_383_000, 3547).saturating_add(T::DbWeight::get().reads(1_u64)) } + /// Storage: `XcmBridgeHubRouter::Bridge` (r:1 w:1) + /// + /// Proof: `XcmBridgeHubRouter::Bridge` (`max_values`: Some(1), `max_size`: Some(17), added: + /// 512, mode: `MaxEncodedLen`) + 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)) + } } // For backwards compatibility and tests @@ -137,4 +151,17 @@ impl WeightInfo for () { // Minimum execution time: 4_239 nanoseconds. Weight::from_parts(4_383_000, 3547).saturating_add(RocksDbWeight::get().reads(1_u64)) } + /// Storage: `XcmBridgeHubRouter::Bridge` (r:1 w:1) + /// + /// Proof: `XcmBridgeHubRouter::Bridge` (`max_values`: Some(1), `max_size`: Some(17), added: + /// 512, mode: `MaxEncodedLen`) + 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(RocksDbWeight::get().reads(1_u64)) + .saturating_add(RocksDbWeight::get().writes(1_u64)) + } } diff --git a/bridges/modules/xcm-bridge-hub/src/congestion.rs b/bridges/modules/xcm-bridge-hub/src/congestion.rs new file mode 100644 index 000000000000..2307f692a0af --- /dev/null +++ b/bridges/modules/xcm-bridge-hub/src/congestion.rs @@ -0,0 +1,151 @@ +// Copyright 2019-2021 Parity Technologies (UK) Ltd. +// This file is part of Parity Bridges Common. + +// Parity Bridges Common 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. + +// Parity Bridges Common 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 Parity Bridges Common. If not, see . + +//! The module contains utilities for handling congestion between the bridge hub and routers. + +use sp_std::vec::Vec; +use sp_std::marker::PhantomData; +use codec::Encode; +use bp_xcm_bridge_hub::{BridgeId, LocalXcmChannelManager, Receiver}; +use sp_runtime::traits::Convert; +use xcm::latest::{send_xcm, Location, SendXcm, Xcm}; +use crate::{Config, Bridges, LOG_TARGET}; + +/// Switches the implementation of `LocalXcmChannelManager` based on the `local_origin`. +/// +/// - `HereXcmChannelManager` is applied when the origin is `Here`. +/// - Otherwise, `LocalConsensusXcmChannelManager` is used. +/// +/// This is useful when the `pallet-xcm-bridge-hub` needs to support both: +/// - A local router deployed on the same chain as the `pallet-xcm-bridge-hub`. +/// - A remote router deployed on a different chain than the `pallet-xcm-bridge-hub`. +pub struct HereOrLocalConsensusXcmChannelManager(PhantomData<(Bridge, HereXcmChannelManager, LocalConsensusXcmChannelManager)>); +impl, LocalConsensusXcmChannelManager: LocalXcmChannelManager> LocalXcmChannelManager +for HereOrLocalConsensusXcmChannelManager { + type Error = (); + + fn suspend_bridge(local_origin: &Location, bridge: Bridge) -> Result<(), Self::Error> { + if local_origin.eq(&Location::here()) { + HereXcmChannelManager::suspend_bridge(local_origin, bridge).map_err(|e| { + log::error!( + target: LOG_TARGET, + "HereXcmChannelManager::suspend_bridge error: {e:?} for local_origin: {:?} and bridge: {:?}", + local_origin, + bridge, + ); + () + }) + } else { + LocalConsensusXcmChannelManager::suspend_bridge(local_origin, bridge).map_err(|e| { + log::error!( + target: LOG_TARGET, + "LocalConsensusXcmChannelManager::suspend_bridge error: {e:?} for local_origin: {:?} and bridge: {:?}", + local_origin, + bridge, + ); + () + }) + } + } + + fn resume_bridge(local_origin: &Location, bridge: Bridge) -> Result<(), Self::Error> { + if local_origin.eq(&Location::here()) { + HereXcmChannelManager::resume_bridge(local_origin, bridge).map_err(|e| { + log::error!( + target: LOG_TARGET, + "HereXcmChannelManager::resume_bridge error: {e:?} for local_origin: {:?} and bridge: {:?}", + local_origin, + bridge, + ); + () + }) + } else { + LocalConsensusXcmChannelManager::resume_bridge(local_origin, bridge).map_err(|e| { + log::error!( + target: LOG_TARGET, + "LocalConsensusXcmChannelManager::resume_bridge error: {e:?} for local_origin: {:?} and bridge: {:?}", + local_origin, + bridge, + ); + () + }) + } + } +} + +/// Manages the local XCM channels by sending XCM messages with the `report_bridge_status` extrinsic to the `local_origin`. +/// The `XcmProvider` type converts the encoded call to `XCM`, which is then sent by `XcmSender` to the `local_origin`. +/// This is useful, for example, when a router with `ExportMessage` is deployed on a different chain, and we want to control congestion by sending XCMs. +pub struct ReportBridgeStatusXcmChannelManager(PhantomData<(T, I, XcmProvider, XcmSender)>); +impl, I: 'static, XcmProvider: Convert, Xcm<()>>, XcmSender: SendXcm> ReportBridgeStatusXcmChannelManager { + fn report_bridge_status(local_origin: &Location, bridge_id: BridgeId, is_congested: bool) -> Result<(), ()> { + // check the bridge and get `maybe_notify` callback. + let bridge = Bridges::::get(&bridge_id).ok_or(())?; + let Some(Receiver { pallet_index, call_index }) = bridge.maybe_notify else { + // `local_origin` did not set `maybe_notify`, so nothing to notify, so it is ok. + return Ok(()) + }; + + // constructing expected call + let remote_runtime_call = (pallet_index, call_index, bridge_id, is_congested); + // construct XCM + let xcm = XcmProvider::convert(remote_runtime_call.encode()); + log::trace!( + target: LOG_TARGET, + "ReportBridgeStatusXcmChannelManager is going to send status with is_congested: {:?} to the local_origin: {:?} and bridge: {:?} as xcm: {:?}", + is_congested, + local_origin, + bridge, + xcm, + ); + + // send XCM + send_xcm::(local_origin.clone(), xcm) + .map(|result| { + log::warn!( + target: LOG_TARGET, + "ReportBridgeStatusXcmChannelManager successfully sent status with is_congested: {:?} to the local_origin: {:?} and bridge: {:?} with result: {:?}", + is_congested, + local_origin, + bridge, + result, + ); + () + }) + .map_err(|e| { + log::error!( + target: LOG_TARGET, + "ReportBridgeStatusXcmChannelManager failed to send status with is_congested: {:?} to the local_origin: {:?} and bridge: {:?} with error: {:?}", + is_congested, + local_origin, + bridge, + e, + ); + () + }) + } +} +impl, I: 'static, XcmProvider: Convert, Xcm<()>>, XcmSender: SendXcm> LocalXcmChannelManager for ReportBridgeStatusXcmChannelManager { + type Error = (); + + fn suspend_bridge(local_origin: &Location, bridge: BridgeId) -> Result<(), Self::Error> { + Self::report_bridge_status(local_origin, bridge, true) + } + + fn resume_bridge(local_origin: &Location, bridge: BridgeId) -> Result<(), Self::Error> { + Self::report_bridge_status(local_origin, bridge, false) + } +} diff --git a/bridges/modules/xcm-bridge-hub/src/dispatcher.rs b/bridges/modules/xcm-bridge-hub/src/dispatcher.rs index daa49ed415d3..bbc9c8ae54d6 100644 --- a/bridges/modules/xcm-bridge-hub/src/dispatcher.rs +++ b/bridges/modules/xcm-bridge-hub/src/dispatcher.rs @@ -21,11 +21,11 @@ //! //! This code is executed at the target bridge hub. -use crate::{Config, Pallet, LOG_TARGET}; +use crate::{Config, Pallet, LOG_TARGET, DispatchChannelStatusProvider}; use bp_messages::target_chain::{DispatchMessage, MessageDispatch}; use bp_runtime::messages::MessageDispatchResult; -use bp_xcm_bridge_hub::{LocalXcmChannelManager, XcmAsPlainPayload}; +use bp_xcm_bridge_hub::XcmAsPlainPayload; use codec::{Decode, Encode}; use frame_support::{weights::Weight, CloneNoBound, EqNoBound, PartialEqNoBound}; use pallet_bridge_messages::{Config as BridgeMessagesConfig, WeightInfoExt}; @@ -60,7 +60,7 @@ where fn is_active(lane: Self::LaneId) -> bool { Pallet::::bridge_by_lane_id(&lane) .and_then(|(_, bridge)| bridge.bridge_origin_relative_location.try_as().cloned().ok()) - .map(|recipient: Location| !T::LocalXcmChannelManager::is_congested(&recipient)) + .map(|recipient: Location| !T::BlobDispatcher::is_congested(&recipient)) .unwrap_or(false) } @@ -158,6 +158,7 @@ mod tests { state: BridgeState::Opened, deposit: None, lane_id, + maybe_notify: None, }, ); LaneToBridge::::insert(lane_id, bridge.bridge_id()); @@ -206,8 +207,11 @@ mod tests { #[test] fn dispatcher_is_inactive_when_channel_with_target_chain_is_congested() { run_test_with_opened_bridge(|| { - TestLocalXcmChannelManager::make_congested(); - assert!(!XcmOverBridge::is_active(bridge().1)); + let bridge = bridge(); + let with = bridge.0.bridge_origin_relative_location(); + let lane_id = bridge.1; + TestBlobDispatcher::make_congested(with); + assert!(!XcmOverBridge::is_active(lane_id)); }); } diff --git a/bridges/modules/xcm-bridge-hub/src/exporter.rs b/bridges/modules/xcm-bridge-hub/src/exporter.rs index bbdca5dd6dd9..392fe4490642 100644 --- a/bridges/modules/xcm-bridge-hub/src/exporter.rs +++ b/bridges/modules/xcm-bridge-hub/src/exporter.rs @@ -233,7 +233,7 @@ impl, I: 'static> Pallet { { Ok(bridge_origin_relative_location) => bridge_origin_relative_location, Err(_) => { - log::debug!( + log::error!( target: LOG_TARGET, "Failed to convert the bridge {:?} origin location {:?}", bridge_id, @@ -255,7 +255,7 @@ impl, I: 'static> Pallet { ); }, Err(e) => { - log::debug!( + log::error!( target: LOG_TARGET, "Failed to suspended the bridge {:?}, originated by the {:?}: {:?}", bridge_id, @@ -298,7 +298,7 @@ impl, I: 'static> Pallet { let bridge_origin_relative_location = match bridge_origin_relative_location { Ok(bridge_origin_relative_location) => bridge_origin_relative_location, Err(e) => { - log::debug!( + log::error!( target: LOG_TARGET, "Failed to convert the bridge {:?} location for lane_id: {:?}, error {:?}", bridge_id, @@ -323,7 +323,7 @@ impl, I: 'static> Pallet { ); }, Err(e) => { - log::debug!( + log::error!( target: LOG_TARGET, "Failed to resume the bridge {:?} and lane_id: {:?}, originated by the {:?}: {:?}", bridge_id, @@ -364,7 +364,7 @@ mod tests { use crate::{mock::*, Bridges, LanesManagerOf}; use bp_runtime::RangeInclusiveExt; - use bp_xcm_bridge_hub::{Bridge, BridgeLocations, BridgeState}; + use bp_xcm_bridge_hub::{Bridge, BridgeLocations, BridgeState, Receiver}; use bp_xcm_bridge_hub_router::ResolveBridgeId; use frame_support::{ assert_ok, @@ -451,7 +451,7 @@ mod tests { run_test(|| { let (bridge_id, _) = open_lane_and_send_regular_message(OpenBridgeOrigin::sibling_parachain_origin()); - assert!(!TestLocalXcmChannelManager::is_bridge_suspened()); + assert!(!TestLocalXcmChannelManager::is_bridge_suspened(&bridge_id)); assert_eq!(XcmOverBridge::bridge(&bridge_id).unwrap().state, BridgeState::Opened); }); } @@ -469,7 +469,7 @@ mod tests { } open_lane_and_send_regular_message(OpenBridgeOrigin::sibling_parachain_origin()); - assert!(!TestLocalXcmChannelManager::is_bridge_suspened()); + assert!(!TestLocalXcmChannelManager::is_bridge_suspened(&bridge_id)); }); } @@ -482,11 +482,11 @@ mod tests { open_lane_and_send_regular_message(OpenBridgeOrigin::sibling_parachain_origin()); } - assert!(!TestLocalXcmChannelManager::is_bridge_suspened()); + assert!(!TestLocalXcmChannelManager::is_bridge_suspened(&bridge_id)); assert_eq!(XcmOverBridge::bridge(&bridge_id).unwrap().state, BridgeState::Opened); open_lane_and_send_regular_message(OpenBridgeOrigin::sibling_parachain_origin()); - assert!(TestLocalXcmChannelManager::is_bridge_suspened()); + assert!(TestLocalXcmChannelManager::is_bridge_suspened(&bridge_id)); assert_eq!(XcmOverBridge::bridge(&bridge_id).unwrap().state, BridgeState::Suspended); }); } @@ -504,7 +504,7 @@ mod tests { OUTBOUND_LANE_UNCONGESTED_THRESHOLD + 1, ); - assert!(!TestLocalXcmChannelManager::is_bridge_resumed()); + assert!(!TestLocalXcmChannelManager::is_bridge_resumed(&bridge_id)); assert_eq!(XcmOverBridge::bridge(&bridge_id).unwrap().state, BridgeState::Suspended); }); } @@ -519,7 +519,7 @@ mod tests { OUTBOUND_LANE_UNCONGESTED_THRESHOLD, ); - assert!(!TestLocalXcmChannelManager::is_bridge_resumed()); + assert!(!TestLocalXcmChannelManager::is_bridge_resumed(&bridge_id)); assert_eq!(XcmOverBridge::bridge(&bridge_id).unwrap().state, BridgeState::Opened); }); } @@ -537,7 +537,7 @@ mod tests { OUTBOUND_LANE_UNCONGESTED_THRESHOLD, ); - assert!(TestLocalXcmChannelManager::is_bridge_resumed()); + assert!(TestLocalXcmChannelManager::is_bridge_resumed(&bridge_id)); assert_eq!(XcmOverBridge::bridge(&bridge_id).unwrap().state, BridgeState::Opened); }); } @@ -603,6 +603,7 @@ mod tests { state: BridgeState::Opened, deposit: None, lane_id: expected_lane_id, + maybe_notify: None, }, ); } @@ -843,12 +844,22 @@ mod tests { // we need to set `UniversalLocation` for `sibling_parachain_origin` for `XcmOverBridgeWrappedWithExportMessageRouterInstance`. ExportMessageOriginUniversalLocation::set(Some(SiblingUniversalLocation::get())); + // we need to update `maybe_notify` for `bridge_1` with `pallet_index` of `XcmOverBridgeWrappedWithExportMessageRouter`, + Bridges::::mutate_extant(bridge_1.bridge_id(), |bridge| { + bridge.maybe_notify = Some(Receiver::new(57, 0)); + }); + // check before + // bridges are opened assert_eq!(XcmOverBridge::bridge(bridge_1.bridge_id()).unwrap().state, BridgeState::Opened); assert_eq!(XcmOverBridge::bridge(bridge_2.bridge_id()).unwrap().state, BridgeState::Opened); // both routers are uncongested assert!(!router_bridge_state::(&dest).map(|bs| bs.is_congested).unwrap_or(false)); assert!(!router_bridge_state::(&dest).map(|bs| bs.is_congested).unwrap_or(false)); + assert!(!TestLocalXcmChannelManager::is_bridge_suspened(bridge_1.bridge_id())); + assert!(!TestLocalXcmChannelManager::is_bridge_suspened(bridge_2.bridge_id())); + assert!(!TestLocalXcmChannelManager::is_bridge_resumed(bridge_1.bridge_id())); + assert!(!TestLocalXcmChannelManager::is_bridge_resumed(bridge_2.bridge_id())); // make bridges congested with sending too much messages for _ in 1..(OUTBOUND_LANE_CONGESTED_THRESHOLD + 2) { @@ -861,11 +872,35 @@ mod tests { } // checks after + // bridges are suspended assert_eq!(XcmOverBridge::bridge(bridge_1.bridge_id()).unwrap().state, BridgeState::Suspended); assert_eq!(XcmOverBridge::bridge(bridge_2.bridge_id()).unwrap().state, BridgeState::Suspended); // both routers are congested assert!(router_bridge_state::(&dest).unwrap().is_congested); assert!(router_bridge_state::(&dest).unwrap().is_congested); + assert!(TestLocalXcmChannelManager::is_bridge_suspened(bridge_1.bridge_id())); + assert!(TestLocalXcmChannelManager::is_bridge_suspened(bridge_2.bridge_id())); + assert!(!TestLocalXcmChannelManager::is_bridge_resumed(bridge_1.bridge_id())); + assert!(!TestLocalXcmChannelManager::is_bridge_resumed(bridge_2.bridge_id())); + + // make bridges uncongested to trigger resume signal + XcmOverBridge::on_bridge_messages_delivered( + expected_lane_id_1, + OUTBOUND_LANE_UNCONGESTED_THRESHOLD, + ); + XcmOverBridge::on_bridge_messages_delivered( + expected_lane_id_2, + OUTBOUND_LANE_UNCONGESTED_THRESHOLD, + ); + + // bridges are again opened + assert_eq!(XcmOverBridge::bridge(bridge_1.bridge_id()).unwrap().state, BridgeState::Opened); + assert_eq!(XcmOverBridge::bridge(bridge_2.bridge_id()).unwrap().state, BridgeState::Opened); + // both routers are uncongested + assert!(!router_bridge_state::(&dest).unwrap().is_congested); + assert!(!router_bridge_state::(&dest).unwrap().is_congested); + assert!(TestLocalXcmChannelManager::is_bridge_resumed(bridge_1.bridge_id())); + assert!(TestLocalXcmChannelManager::is_bridge_resumed(bridge_2.bridge_id())); }) } } diff --git a/bridges/modules/xcm-bridge-hub/src/lib.rs b/bridges/modules/xcm-bridge-hub/src/lib.rs index 658ad279aa7a..75e76bd11b2b 100644 --- a/bridges/modules/xcm-bridge-hub/src/lib.rs +++ b/bridges/modules/xcm-bridge-hub/src/lib.rs @@ -148,6 +148,7 @@ use bp_runtime::{AccountIdOf, BalanceOf, RangeInclusiveExt}; pub use bp_xcm_bridge_hub::{Bridge, BridgeId, BridgeState}; use bp_xcm_bridge_hub::{ BridgeLocations, BridgeLocationsError, Deposit, DepositOf, LocalXcmChannelManager, + ChannelStatusProvider as DispatchChannelStatusProvider, }; use frame_support::{traits::fungible::MutateHold, DefaultNoBound}; use frame_system::Config as SystemConfig; @@ -164,6 +165,7 @@ pub use pallet::*; mod dispatcher; mod exporter; +pub mod congestion; pub mod migration; mod mock; @@ -241,10 +243,10 @@ pub mod pallet { /// For example, it is possible to make an exception for a system parachain or relay. type AllowWithoutBridgeDeposit: Contains; - /// Local XCM channel manager. - type LocalXcmChannelManager: LocalXcmChannelManager; + /// Local XCM channel manager. Dedicated to exporting capabilities when handling congestion with the sending side. + type LocalXcmChannelManager: LocalXcmChannelManager; /// XCM-level dispatcher for inbound bridge messages. - type BlobDispatcher: DispatchBlob; + type BlobDispatcher: DispatchBlob + DispatchChannelStatusProvider; } /// An alias for the bridge metadata. @@ -510,6 +512,7 @@ pub mod pallet { state: BridgeState::Opened, deposit: deposit.clone(), lane_id, + maybe_notify: None, }); Ok(()) }, @@ -879,6 +882,7 @@ mod tests { state: BridgeState::Opened, deposit, lane_id, + maybe_notify: None, }; Bridges::::insert(locations.bridge_id(), bridge.clone()); LaneToBridge::::insert(bridge.lane_id, locations.bridge_id()); @@ -1034,6 +1038,7 @@ mod tests { state: BridgeState::Opened, deposit: None, lane_id, + maybe_notify: None, }, ); @@ -1166,7 +1171,8 @@ mod tests { ), state: BridgeState::Opened, deposit: expected_deposit.clone(), - lane_id + lane_id, + maybe_notify: None, }), ); assert_eq!( @@ -1521,6 +1527,7 @@ mod tests { state: BridgeState::Opened, deposit: Some(Deposit::new(bridge_owner_account.clone(), Zero::zero())), lane_id, + maybe_notify: None, }, (lane_id, bridge_id), (lane_id, lane_id), @@ -1546,6 +1553,7 @@ mod tests { state: BridgeState::Opened, deposit: Some(Deposit::new(bridge_owner_account.clone(), Zero::zero())), lane_id, + maybe_notify: None, }, (lane_id, bridge_id_mismatch), (lane_id, lane_id), @@ -1571,6 +1579,7 @@ mod tests { state: BridgeState::Opened, deposit: Some(Deposit::new(bridge_owner_account_mismatch.clone(), Zero::zero())), lane_id, + maybe_notify: None, }, (lane_id, bridge_id), (lane_id, lane_id), @@ -1595,6 +1604,7 @@ mod tests { state: BridgeState::Opened, deposit: Some(Deposit::new(bridge_owner_account_mismatch.clone(), Zero::zero())), lane_id, + maybe_notify: None, }, (lane_id, bridge_id_mismatch), (lane_id, lane_id), @@ -1620,6 +1630,7 @@ mod tests { state: BridgeState::Opened, deposit: Some(Deposit::new(bridge_owner_account.clone(), Zero::zero())), lane_id, + maybe_notify: None, }, (lane_id, bridge_id), (lane_id_mismatch, lane_id), @@ -1645,6 +1656,7 @@ mod tests { state: BridgeState::Opened, deposit: Some(Deposit::new(bridge_owner_account, Zero::zero())), lane_id, + maybe_notify: None, }, (lane_id, bridge_id), (lane_id, lane_id_mismatch), diff --git a/bridges/modules/xcm-bridge-hub/src/migration.rs b/bridges/modules/xcm-bridge-hub/src/migration.rs index dc1a17d13072..c9474e628300 100644 --- a/bridges/modules/xcm-bridge-hub/src/migration.rs +++ b/bridges/modules/xcm-bridge-hub/src/migration.rs @@ -222,6 +222,7 @@ pub mod v1 { state, deposit, lane_id, + maybe_notify: None, }) }; Bridges::::translate_values(translate); diff --git a/bridges/modules/xcm-bridge-hub/src/mock.rs b/bridges/modules/xcm-bridge-hub/src/mock.rs index 8b17081783b2..7a387b4f1d06 100644 --- a/bridges/modules/xcm-bridge-hub/src/mock.rs +++ b/bridges/modules/xcm-bridge-hub/src/mock.rs @@ -18,7 +18,7 @@ use sp_std::marker::PhantomData; use crate as pallet_xcm_bridge_hub; - +use pallet_xcm_bridge_hub::{congestion::{HereOrLocalConsensusXcmChannelManager, ReportBridgeStatusXcmChannelManager}}; use bp_messages::{ target_chain::{DispatchMessage, MessageDispatch}, ChainWithMessages, HashedLaneId, MessageNonce, @@ -33,7 +33,7 @@ use frame_support::{ weights::RuntimeDbWeight, }; use frame_support::traits::Get; -use frame_system::EnsureRootWithSuccess; +use frame_system::{EnsureNever, EnsureRoot, EnsureRootWithSuccess}; use polkadot_parachain_primitives::primitives::Sibling; use sp_core::H256; use sp_runtime::{ @@ -41,6 +41,7 @@ use sp_runtime::{ traits::{BlakeTwo256, ConstU32, IdentityLookup}, AccountId32, BuildStorage, StateVersion, }; +use sp_runtime::traits::Convert; use sp_std::cell::RefCell; use xcm::{latest::ROCOCO_GENESIS_HASH, prelude::*}; use xcm_builder::{ @@ -48,7 +49,7 @@ use xcm_builder::{ InspectMessageQueues, NetworkExportTable, NetworkExportTableItem, ParentIsPreset, SiblingParachainConvertsVia, SovereignPaidRemoteExporter, UnpaidLocalExporter, ensure_is_remote, }; -use xcm_executor::{traits::ConvertLocation, XcmExecutor}; +use xcm_executor::{traits::{ConvertLocation, ConvertOrigin}, XcmExecutor}; pub type AccountId = AccountId32; pub type Balance = u64; @@ -189,6 +190,22 @@ pub fn bridged_asset_hub_universal_location() -> InteriorLocation { BridgedUniversalDestination::get() } +pub(crate) type TestLocalXcmChannelManager = TestingLocalXcmChannelManager< + BridgeId, + HereOrLocalConsensusXcmChannelManager< + BridgeId, + // handles congestion for `XcmOverBridgeByExportXcmRouter` + XcmOverBridgeByExportXcmRouter, + // handles congestion for `XcmOverBridgeWrappedWithExportMessageRouter` + ReportBridgeStatusXcmChannelManager< + TestRuntime, + (), + ReportBridgeStatusXcmProvider, + FromBridgeHubLocationXcmSender + >, + > +>; + impl pallet_xcm_bridge_hub::Config for TestRuntime { type RuntimeEvent = RuntimeEvent; @@ -199,7 +216,7 @@ impl pallet_xcm_bridge_hub::Config for TestRuntime { type MessageExportPrice = (); type DestinationVersion = AlwaysLatest; - type ForceOrigin = frame_system::EnsureNever<()>; + type ForceOrigin = EnsureNever<()>; type OpenBridgeOrigin = EitherOf< // We want to translate `RuntimeOrigin::root()` to the `Location::here()` EnsureRootWithSuccess, @@ -241,6 +258,8 @@ impl pallet_xcm_bridge_hub_router::Config<()> for TestRuntime { >; type BridgeIdResolver = EnsureIsRemoteBridgeIdResolver; + // We convert to root here `BridgeHubLocationXcmOriginAsRoot` + type BridgeHubOrigin = EnsureRoot; } /// A router instance simulates a scenario where the router is deployed on the same chain as the @@ -253,6 +272,8 @@ impl pallet_xcm_bridge_hub_router::Config; type BridgeIdResolver = EnsureIsRemoteBridgeIdResolver; + // We don't need to support here `report_bridge_status`. + type BridgeHubOrigin = EnsureNever<()>; } /// Implementation of `ResolveBridgeId` returning `BridgeId` based on the configured `UniversalLocation`. @@ -287,12 +308,29 @@ thread_local! { pub static EXPORT_MESSAGE_ORIGIN_UNIVERSAL_LOCATION: RefCell> = RefCell::new(None); } +pub struct BridgeHubLocationXcmOriginAsRoot(PhantomData); +impl ConvertOrigin + for BridgeHubLocationXcmOriginAsRoot +{ + fn convert_origin( + origin: impl Into, + kind: OriginKind, + ) -> Result { + let origin = origin.into(); + if kind == OriginKind::Xcm && origin.eq(&BridgeHubLocation::get()) { + Ok(RuntimeOrigin::root()) + } else { + Err(origin) + } + } +} + pub struct XcmConfig; impl xcm_executor::Config for XcmConfig { type RuntimeCall = RuntimeCall; type XcmSender = (); type AssetTransactor = (); - type OriginConverter = (); + type OriginConverter = BridgeHubLocationXcmOriginAsRoot; type IsReserve = (); type IsTeleporter = (); type UniversalLocation = UniversalLocation; @@ -461,37 +499,78 @@ pub(crate) fn fund_origin_sovereign_account( bridge_owner_account } -pub struct TestLocalXcmChannelManager; +/// Testing wrapper implementation of `LocalXcmChannelManager`, that supports storing flags in storage to facilitate testing of `LocalXcmChannelManager` implementation. +pub struct TestingLocalXcmChannelManager(PhantomData<(Bridge, Tested)>); -impl TestLocalXcmChannelManager { - pub fn make_congested() { - frame_support::storage::unhashed::put(b"TestLocalXcmChannelManager.Congested", &true); +impl TestingLocalXcmChannelManager { + fn suspended_key(bridge: &Bridge) -> Vec { + [b"SwitchedLocalXcmChannelManager.Suspended", bridge.encode().as_slice()].concat() + } + fn resumed_key(bridge: &Bridge) -> Vec { + [b"SwitchedLocalXcmChannelManager.Resumed", bridge.encode().as_slice()].concat() } - pub fn is_bridge_suspened() -> bool { - frame_support::storage::unhashed::get_or_default(b"TestLocalXcmChannelManager.Suspended") + pub fn is_bridge_suspened(bridge: &Bridge) -> bool { + frame_support::storage::unhashed::get_or_default(&Self::suspended_key(bridge)) } - pub fn is_bridge_resumed() -> bool { - frame_support::storage::unhashed::get_or_default(b"TestLocalXcmChannelManager.Resumed") + pub fn is_bridge_resumed(bridge: &Bridge) -> bool { + frame_support::storage::unhashed::get_or_default(&Self::resumed_key(bridge)) } } -impl LocalXcmChannelManager for TestLocalXcmChannelManager { - type Error = (); +impl> LocalXcmChannelManager for TestingLocalXcmChannelManager { + type Error = Tested::Error; + + fn suspend_bridge(local_origin: &Location, bridge: Bridge) -> Result<(), Self::Error> { + let result = Tested::suspend_bridge(local_origin, bridge); + + if result.is_ok() { + frame_support::storage::unhashed::put(&Self::suspended_key(&bridge), &true); + } - fn is_congested(_with: &Location) -> bool { - frame_support::storage::unhashed::get_or_default(b"TestLocalXcmChannelManager.Congested") + result } - fn suspend_bridge(_local_origin: &Location, _bridge: BridgeId) -> Result<(), Self::Error> { - frame_support::storage::unhashed::put(b"TestLocalXcmChannelManager.Suspended", &true); - Ok(()) + fn resume_bridge(local_origin: &Location, bridge: Bridge) -> Result<(), Self::Error> { + let result = Tested::resume_bridge(local_origin, bridge); + + if result.is_ok() { + frame_support::storage::unhashed::put(&Self::resumed_key(&bridge), &true); + } + + result } +} - fn resume_bridge(_local_origin: &Location, _bridge: BridgeId) -> Result<(), Self::Error> { - frame_support::storage::unhashed::put(b"TestLocalXcmChannelManager.Resumed", &true); - Ok(()) +/// Converts encoded call to the unpaid XCM `Transact`. +pub struct ReportBridgeStatusXcmProvider; +impl Convert, Xcm<()>> for ReportBridgeStatusXcmProvider { + fn convert(encoded_call: Vec) -> Xcm<()> { + Xcm(vec![ + UnpaidExecution { weight_limit: Unlimited, check_origin: None }, + Transact { + origin_kind: OriginKind::Xcm, + require_weight_at_most: Weight::from_parts(10_000_000_000, 8 * 1024), + call: encoded_call.into(), + }, + ExpectTransactStatus(MaybeErrorCode::Success), + ]) + } +} + +/// `SendXcm` implementation which sets `BridgeHubLocation` as origin for `ExecuteXcmOverSendXcm`. +pub struct FromBridgeHubLocationXcmSender(PhantomData); +impl SendXcm for FromBridgeHubLocationXcmSender { + type Ticket = Inner::Ticket; + + fn validate(destination: &mut Option, message: &mut Option>) -> SendResult { + Inner::validate(destination, message) + } + + fn deliver(ticket: Self::Ticket) -> Result { + ExecuteXcmOverSendXcm::set_origin_for_execute(BridgeHubLocation::get()); + Inner::deliver(ticket) } } @@ -501,6 +580,20 @@ impl TestBlobDispatcher { pub fn is_dispatched() -> bool { frame_support::storage::unhashed::get_or_default(b"TestBlobDispatcher.Dispatched") } + + fn congestion_key(with: &Location) -> Vec { + [b"TestBlobDispatcher.Congested.", with.encode().as_slice()].concat() + } + + pub fn make_congested(with: &Location) { + frame_support::storage::unhashed::put(&Self::congestion_key(with), &true); + } +} + +impl pallet_xcm_bridge_hub::DispatchChannelStatusProvider for TestBlobDispatcher { + fn is_congested(with: &Location) -> bool { + frame_support::storage::unhashed::get_or_default(&Self::congestion_key(with)) + } } impl DispatchBlob for TestBlobDispatcher { diff --git a/bridges/primitives/xcm-bridge-hub-router/src/lib.rs b/bridges/primitives/xcm-bridge-hub-router/src/lib.rs index c894e577f681..a87bec8e227e 100644 --- a/bridges/primitives/xcm-bridge-hub-router/src/lib.rs +++ b/bridges/primitives/xcm-bridge-hub-router/src/lib.rs @@ -24,21 +24,6 @@ use sp_core::{H256, sp_std::fmt::Debug}; use sp_runtime::{FixedU128, RuntimeDebug}; use xcm::latest::prelude::{Location, NetworkId, InteriorLocation}; -/// XCM channel status provider that may report whether it is congested or not. -/// -/// By the channel we mean the physical channel that is used to deliver messages of one -/// of the bridge queues. -pub trait XcmChannelStatusProvider { - /// Returns true if the channel is currently congested. - fn is_congested(with: &Location) -> bool; -} - -impl XcmChannelStatusProvider for () { - fn is_congested(_with: &Location) -> bool { - false - } -} - /// Current status of the bridge. #[derive(Clone, Decode, Encode, Eq, PartialEq, TypeInfo, MaxEncodedLen, RuntimeDebug)] pub struct BridgeState { diff --git a/bridges/primitives/xcm-bridge-hub/src/lib.rs b/bridges/primitives/xcm-bridge-hub/src/lib.rs index 76cbbb0df149..4b87c54b4298 100644 --- a/bridges/primitives/xcm-bridge-hub/src/lib.rs +++ b/bridges/primitives/xcm-bridge-hub/src/lib.rs @@ -96,42 +96,45 @@ impl core::fmt::Debug for BridgeId { } /// Local XCM channel manager. -pub trait LocalXcmChannelManager { +pub trait LocalXcmChannelManager { /// Error that may be returned when suspending/resuming the bridge. type Error: sp_std::fmt::Debug; - /// Returns true if the channel with given location is currently congested. - /// - /// The `with` is guaranteed to be in the same consensus. However, it may point to something - /// below the chain level - like the contract or pallet instance, for example. - fn is_congested(with: &Location) -> bool; - /// Suspend the bridge, opened by given origin. /// /// The `local_origin` is guaranteed to be in the same consensus. However, it may point to /// something below the chain level - like the contract or pallet instance, for example. - fn suspend_bridge(local_origin: &Location, bridge: BridgeId) -> Result<(), Self::Error>; + fn suspend_bridge(local_origin: &Location, bridge: Bridge) -> Result<(), Self::Error>; /// Resume the previously suspended bridge, opened by given origin. /// /// The `local_origin` is guaranteed to be in the same consensus. However, it may point to /// something below the chain level - like the contract or pallet instance, for example. - fn resume_bridge(local_origin: &Location, bridge: BridgeId) -> Result<(), Self::Error>; + fn resume_bridge(local_origin: &Location, bridge: Bridge) -> Result<(), Self::Error>; } -impl LocalXcmChannelManager for () { +impl LocalXcmChannelManager for () { type Error = (); - fn is_congested(_with: &Location) -> bool { - false + fn suspend_bridge(_local_origin: &Location, _bridge: Bridge) -> Result<(), Self::Error> { + Ok(()) } - fn suspend_bridge(_local_origin: &Location, _bridge: BridgeId) -> Result<(), Self::Error> { + fn resume_bridge(_local_origin: &Location, _bridge: Bridge) -> Result<(), Self::Error> { Ok(()) } +} - fn resume_bridge(_local_origin: &Location, _bridge: BridgeId) -> Result<(), Self::Error> { - Ok(()) +/// Channel status provider that may report whether it is congested or not. +pub trait ChannelStatusProvider { + /// Returns true if the channel is currently active and can be used. + fn is_congested(with: &Location) -> bool; +} + +/// Default implementation of `ChannelStatusProvider`, indicating no congestion. +impl ChannelStatusProvider for () { + fn is_congested(_with: &Location) -> bool { + false } } @@ -176,6 +179,30 @@ pub struct Bridge { /// Mapping to the unique `LaneId`. pub lane_id: LaneId, + + /// Holds data about the `bridge_origin_relative_location` where notifications can be sent for handling congestion. + pub maybe_notify: Option, +} + +/// Receiver metadata. +#[derive( + CloneNoBound, Decode, Encode, Eq, PartialEqNoBound, TypeInfo, MaxEncodedLen, RuntimeDebugNoBound, +)] +pub struct Receiver { + /// Pallet index. + pub pallet_index: u8, + /// Call/extrinsic index. + pub call_index: u8, +} + +impl Receiver { + /// Create a new receiver. + pub fn new(pallet_index: u8, call_index: u8) -> Self { + Self { + pallet_index, + call_index, + } + } } /// An alias for the bridge deposit of `ThisChain`. diff --git a/cumulus/pallets/xcmp-queue/Cargo.toml b/cumulus/pallets/xcmp-queue/Cargo.toml index 9c7470eda6da..cb33b8232ab2 100644 --- a/cumulus/pallets/xcmp-queue/Cargo.toml +++ b/cumulus/pallets/xcmp-queue/Cargo.toml @@ -37,7 +37,7 @@ frame-benchmarking = { optional = true, workspace = true } bounded-collections = { workspace = true } # Bridges -bp-xcm-bridge-hub-router = { optional = true, workspace = true } +bp-xcm-bridge-hub = { optional = true, workspace = true } [dev-dependencies] @@ -53,7 +53,7 @@ cumulus-pallet-parachain-system = { workspace = true, default-features = true } default = ["std"] std = [ "bounded-collections/std", - "bp-xcm-bridge-hub-router?/std", + "bp-xcm-bridge-hub?/std", "codec/std", "cumulus-primitives-core/std", "frame-benchmarking?/std", @@ -96,4 +96,4 @@ try-runtime = [ "polkadot-runtime-parachains/try-runtime", "sp-runtime/try-runtime", ] -bridging = ["bp-xcm-bridge-hub-router"] +bridging = ["bp-xcm-bridge-hub"] diff --git a/cumulus/pallets/xcmp-queue/src/bridging.rs b/cumulus/pallets/xcmp-queue/src/bridging.rs index 8ed11505a27a..d896a40cb705 100644 --- a/cumulus/pallets/xcmp-queue/src/bridging.rs +++ b/cumulus/pallets/xcmp-queue/src/bridging.rs @@ -17,11 +17,11 @@ use crate::{pallet, OutboundState}; use cumulus_primitives_core::ParaId; use xcm::latest::prelude::*; -/// Adapter implementation for `bp_xcm_bridge_hub_router::XcmChannelStatusProvider` which checks +/// 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(core::marker::PhantomData); -impl bp_xcm_bridge_hub_router::XcmChannelStatusProvider +impl bp_xcm_bridge_hub::ChannelStatusProvider for InAndOutXcmpChannelStatusProvider { fn is_congested(with: &Location) -> bool { @@ -45,10 +45,10 @@ impl bp_xcm_bridge_hub_router::XcmChannelStatusProvider } } -/// Adapter implementation for `bp_xcm_bridge_hub_router::XcmChannelStatusProvider` which checks +/// Adapter implementation for `bp_xcm_bridge_hub::ChannelStatusProvider` which checks /// only `OutboundXcmpStatus` for defined `SiblingParaId` if is suspended. pub struct OutXcmpChannelStatusProvider(core::marker::PhantomData); -impl bp_xcm_bridge_hub_router::XcmChannelStatusProvider +impl bp_xcm_bridge_hub::ChannelStatusProvider for OutXcmpChannelStatusProvider { fn is_congested(with: &Location) -> bool { From 0505440faa5686c8dbb905c278e2707efe55ad76 Mon Sep 17 00:00:00 2001 From: Branislav Kontur Date: Tue, 5 Nov 2024 09:49:57 +0100 Subject: [PATCH 18/72] Add `BlobDispatcherWithChannelStatus` adapter --- .../modules/xcm-bridge-hub/src/congestion.rs | 18 +++++++++++++++++- bridges/modules/xcm-bridge-hub/src/mock.rs | 3 ++- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/bridges/modules/xcm-bridge-hub/src/congestion.rs b/bridges/modules/xcm-bridge-hub/src/congestion.rs index 2307f692a0af..09e3e230ae6f 100644 --- a/bridges/modules/xcm-bridge-hub/src/congestion.rs +++ b/bridges/modules/xcm-bridge-hub/src/congestion.rs @@ -22,7 +22,8 @@ use codec::Encode; use bp_xcm_bridge_hub::{BridgeId, LocalXcmChannelManager, Receiver}; use sp_runtime::traits::Convert; use xcm::latest::{send_xcm, Location, SendXcm, Xcm}; -use crate::{Config, Bridges, LOG_TARGET}; +use xcm_builder::{DispatchBlob, DispatchBlobError}; +use crate::{Config, Bridges, LOG_TARGET, DispatchChannelStatusProvider}; /// Switches the implementation of `LocalXcmChannelManager` based on the `local_origin`. /// @@ -149,3 +150,18 @@ impl, I: 'static, XcmProvider: Convert, Xcm<()>>, XcmSender Self::report_bridge_status(local_origin, bridge, false) } } + +/// Adapter that ties together the `DispatchBlob` trait with the `DispatchChannelStatusProvider` trait. +/// The idea is that `DispatchBlob` triggers message dispatch/delivery on the receiver side, +/// while `DispatchChannelStatusProvider` provides an status check to ensure the dispatch channel is active (not congested). +pub struct BlobDispatcherWithChannelStatus(PhantomData<(ChannelDispatch, ChannelStatus)>); +impl DispatchBlob for BlobDispatcherWithChannelStatus { + fn dispatch_blob(blob: Vec) -> Result<(), DispatchBlobError> { + ChannelDispatch::dispatch_blob(blob) + } +} +impl DispatchChannelStatusProvider for BlobDispatcherWithChannelStatus { + fn is_congested(with: &Location) -> bool { + ChannelStatus::is_congested(with) + } +} \ No newline at end of file diff --git a/bridges/modules/xcm-bridge-hub/src/mock.rs b/bridges/modules/xcm-bridge-hub/src/mock.rs index 7a387b4f1d06..d3d0cf4ce43e 100644 --- a/bridges/modules/xcm-bridge-hub/src/mock.rs +++ b/bridges/modules/xcm-bridge-hub/src/mock.rs @@ -50,6 +50,7 @@ use xcm_builder::{ SiblingParachainConvertsVia, SovereignPaidRemoteExporter, UnpaidLocalExporter, ensure_is_remote, }; use xcm_executor::{traits::{ConvertLocation, ConvertOrigin}, XcmExecutor}; +use crate::congestion::BlobDispatcherWithChannelStatus; pub type AccountId = AccountId32; pub type Balance = u64; @@ -231,7 +232,7 @@ impl pallet_xcm_bridge_hub::Config for TestRuntime { type LocalXcmChannelManager = TestLocalXcmChannelManager; - type BlobDispatcher = TestBlobDispatcher; + type BlobDispatcher = BlobDispatcherWithChannelStatus; } /// A router instance simulates a scenario where the router is deployed on a different chain than From a56c546e63372f16ddbd5781ef5d874d48cc1b7e Mon Sep 17 00:00:00 2001 From: Branislav Kontur Date: Tue, 5 Nov 2024 10:33:19 +0100 Subject: [PATCH 19/72] Cleanup primitives/consts --- Cargo.lock | 12 --------- .../chains/chain-asset-hub-rococo/Cargo.toml | 15 +---------- .../chains/chain-asset-hub-rococo/src/lib.rs | 26 ------------------- .../chains/chain-asset-hub-westend/Cargo.toml | 15 +---------- .../chains/chain-asset-hub-westend/src/lib.rs | 26 ------------------- .../chains/chain-bridge-hub-rococo/src/lib.rs | 6 +++++ .../chain-bridge-hub-westend/src/lib.rs | 6 +++++ .../xcm-bridge-hub-router/src/lib.rs | 11 +------- 8 files changed, 15 insertions(+), 102 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 04912ae22941..c81c380ed689 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1863,22 +1863,10 @@ dependencies = [ [[package]] name = "bp-asset-hub-rococo" version = "0.4.0" -dependencies = [ - "bp-xcm-bridge-hub-router", - "frame-support", - "parity-scale-codec", - "scale-info", -] [[package]] name = "bp-asset-hub-westend" version = "0.3.0" -dependencies = [ - "bp-xcm-bridge-hub-router", - "frame-support", - "parity-scale-codec", - "scale-info", -] [[package]] name = "bp-beefy" diff --git a/bridges/chains/chain-asset-hub-rococo/Cargo.toml b/bridges/chains/chain-asset-hub-rococo/Cargo.toml index 363a869048aa..7a83bba87481 100644 --- a/bridges/chains/chain-asset-hub-rococo/Cargo.toml +++ b/bridges/chains/chain-asset-hub-rococo/Cargo.toml @@ -14,20 +14,7 @@ exclude-from-umbrella = true workspace = true [dependencies] -codec = { workspace = true } -scale-info = { features = ["derive"], workspace = true } - -# Substrate Dependencies -frame-support = { workspace = true } - -# Bridge Dependencies -bp-xcm-bridge-hub-router = { workspace = true } [features] default = ["std"] -std = [ - "bp-xcm-bridge-hub-router/std", - "codec/std", - "frame-support/std", - "scale-info/std", -] +std = [] diff --git a/bridges/chains/chain-asset-hub-rococo/src/lib.rs b/bridges/chains/chain-asset-hub-rococo/src/lib.rs index de2e9ae856d1..3504be9bb0f8 100644 --- a/bridges/chains/chain-asset-hub-rococo/src/lib.rs +++ b/bridges/chains/chain-asset-hub-rococo/src/lib.rs @@ -18,31 +18,5 @@ #![cfg_attr(not(feature = "std"), no_std)] -use codec::{Decode, Encode}; -use scale_info::TypeInfo; - -pub use bp_xcm_bridge_hub_router::XcmBridgeHubRouterCall; - -/// `AssetHubRococo` Runtime `Call` enum. -/// -/// The enum represents a subset of possible `Call`s we can send to `AssetHubRococo` 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 -/// `AssetHubRococo` `construct_runtime`, so that we maintain SCALE-compatibility. -#[allow(clippy::large_enum_variant)] -#[derive(Encode, Decode, Debug, PartialEq, Eq, Clone, TypeInfo)] -pub enum Call { - /// `ToWestendXcmRouter` bridge pallet. - #[codec(index = 45)] - ToWestendXcmRouter(XcmBridgeHubRouterCall), -} - -frame_support::parameter_types! { - /// Some sane weight to execute `xcm::Transact(pallet-xcm-bridge-hub-router::Call::report_bridge_status)`. - pub const XcmBridgeHubRouterTransactCallMaxWeight: frame_support::weights::Weight = frame_support::weights::Weight::from_parts(200_000_000, 6144); -} - /// Identifier of AssetHubRococo in the Rococo relay chain. pub const ASSET_HUB_ROCOCO_PARACHAIN_ID: u32 = 1000; diff --git a/bridges/chains/chain-asset-hub-westend/Cargo.toml b/bridges/chains/chain-asset-hub-westend/Cargo.toml index 430d9b6116cf..ad8d2778a4bc 100644 --- a/bridges/chains/chain-asset-hub-westend/Cargo.toml +++ b/bridges/chains/chain-asset-hub-westend/Cargo.toml @@ -14,20 +14,7 @@ exclude-from-umbrella = true workspace = true [dependencies] -codec = { workspace = true } -scale-info = { features = ["derive"], workspace = true } - -# Substrate Dependencies -frame-support = { workspace = true } - -# Bridge Dependencies -bp-xcm-bridge-hub-router = { workspace = true } [features] default = ["std"] -std = [ - "bp-xcm-bridge-hub-router/std", - "codec/std", - "frame-support/std", - "scale-info/std", -] +std = [] diff --git a/bridges/chains/chain-asset-hub-westend/src/lib.rs b/bridges/chains/chain-asset-hub-westend/src/lib.rs index 9de1c8809894..c21bdff45934 100644 --- a/bridges/chains/chain-asset-hub-westend/src/lib.rs +++ b/bridges/chains/chain-asset-hub-westend/src/lib.rs @@ -18,31 +18,5 @@ #![cfg_attr(not(feature = "std"), no_std)] -use codec::{Decode, Encode}; -use scale_info::TypeInfo; - -pub use bp_xcm_bridge_hub_router::XcmBridgeHubRouterCall; - -/// `AssetHubWestend` Runtime `Call` enum. -/// -/// The enum represents a subset of possible `Call`s we can send to `AssetHubWestend` 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 -/// `AssetHubWestend` `construct_runtime`, so that we maintain SCALE-compatibility. -#[allow(clippy::large_enum_variant)] -#[derive(Encode, Decode, Debug, PartialEq, Eq, Clone, TypeInfo)] -pub enum Call { - /// `ToRococoXcmRouter` bridge pallet. - #[codec(index = 34)] - ToRococoXcmRouter(XcmBridgeHubRouterCall), -} - -frame_support::parameter_types! { - /// Some sane weight to execute `xcm::Transact(pallet-xcm-bridge-hub-router::Call::report_bridge_status)`. - pub const XcmBridgeHubRouterTransactCallMaxWeight: frame_support::weights::Weight = frame_support::weights::Weight::from_parts(200_000_000, 6144); -} - /// Identifier of AssetHubWestend in the Westend relay chain. pub const ASSET_HUB_WESTEND_PARACHAIN_ID: u32 = 1000; diff --git a/bridges/chains/chain-bridge-hub-rococo/src/lib.rs b/bridges/chains/chain-bridge-hub-rococo/src/lib.rs index fda6a5f0b722..6fed41875218 100644 --- a/bridges/chains/chain-bridge-hub-rococo/src/lib.rs +++ b/bridges/chains/chain-bridge-hub-rococo/src/lib.rs @@ -123,3 +123,9 @@ pub enum RuntimeCall { #[codec(index = 52)] XcmOverBridgeHubWestend(bp_xcm_bridge_hub::XcmBridgeHubCall), } + +// TODO: remove when xcm:v5 +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(1_000_000_000, 1024*8); +} \ No newline at end of file diff --git a/bridges/chains/chain-bridge-hub-westend/src/lib.rs b/bridges/chains/chain-bridge-hub-westend/src/lib.rs index e941b5840238..39899daa7610 100644 --- a/bridges/chains/chain-bridge-hub-westend/src/lib.rs +++ b/bridges/chains/chain-bridge-hub-westend/src/lib.rs @@ -112,3 +112,9 @@ pub enum RuntimeCall { #[codec(index = 45)] XcmOverBridgeHubRococo(bp_xcm_bridge_hub::XcmBridgeHubCall), } + +// TODO: remove when xcm:v5 +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(1_000_000_000, 1024*8); +} \ No newline at end of file diff --git a/bridges/primitives/xcm-bridge-hub-router/src/lib.rs b/bridges/primitives/xcm-bridge-hub-router/src/lib.rs index a87bec8e227e..ef58c6338f36 100644 --- a/bridges/primitives/xcm-bridge-hub-router/src/lib.rs +++ b/bridges/primitives/xcm-bridge-hub-router/src/lib.rs @@ -20,7 +20,7 @@ use codec::{Decode, Encode, FullCodec, MaxEncodedLen}; use scale_info::TypeInfo; -use sp_core::{H256, sp_std::fmt::Debug}; +use sp_core::sp_std::fmt::Debug; use sp_runtime::{FixedU128, RuntimeDebug}; use xcm::latest::prelude::{Location, NetworkId, InteriorLocation}; @@ -56,12 +56,3 @@ impl ResolveBridgeId for () { None } } - -/// A minimized version of `pallet-xcm-bridge-hub-router::Call` that can be used without a runtime. -#[derive(Encode, Decode, Debug, PartialEq, Eq, Clone, TypeInfo)] -#[allow(non_camel_case_types)] -pub enum XcmBridgeHubRouterCall { - /// `pallet-xcm-bridge-hub-router::Call::report_bridge_status` - #[codec(index = 0)] - report_bridge_status { bridge_id: H256, is_congested: bool }, -} From 4334b703425807c25f41a8aca8342e391e579f5d Mon Sep 17 00:00:00 2001 From: Branislav Kontur Date: Tue, 5 Nov 2024 13:31:59 +0100 Subject: [PATCH 20/72] Adapt testnet runtimes to latest congestion changes --- Cargo.lock | 1 - .../xcm-bridge-hub-router/src/impls.rs | 104 +++++++++++++++++- .../modules/xcm-bridge-hub-router/src/lib.rs | 4 +- .../modules/xcm-bridge-hub-router/src/mock.rs | 3 +- bridges/modules/xcm-bridge-hub/Cargo.toml | 1 - .../modules/xcm-bridge-hub/src/exporter.rs | 4 +- bridges/modules/xcm-bridge-hub/src/mock.rs | 23 +--- cumulus/pallets/xcmp-queue/src/bridging.rs | 28 ----- cumulus/pallets/xcmp-queue/src/lib.rs | 5 - .../assets/asset-hub-rococo/src/lib.rs | 26 +++-- .../weights/pallet_xcm_bridge_hub_router.rs | 20 ++++ .../assets/asset-hub-rococo/tests/tests.rs | 66 +++++++++-- .../assets/asset-hub-westend/src/lib.rs | 27 +++-- .../weights/pallet_xcm_bridge_hub_router.rs | 20 ++++ .../assets/asset-hub-westend/tests/tests.rs | 66 +++++++++-- .../test-utils/src/test_cases_over_bridge.rs | 26 +++-- .../src/bridge_to_bulletin_config.rs | 16 +-- .../src/bridge_to_westend_config.rs | 36 ++++-- .../src/bridge_to_rococo_config.rs | 36 ++++-- .../test-utils/src/test_cases/mod.rs | 3 +- 20 files changed, 384 insertions(+), 131 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c81c380ed689..2f480509a3da 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -13243,7 +13243,6 @@ dependencies = [ "bp-messages", "bp-runtime", "bp-xcm-bridge-hub", - "bp-xcm-bridge-hub-router", "frame-support", "frame-system", "log", diff --git a/bridges/modules/xcm-bridge-hub-router/src/impls.rs b/bridges/modules/xcm-bridge-hub-router/src/impls.rs index 6114a0b75ca6..85c5ed956f14 100644 --- a/bridges/modules/xcm-bridge-hub-router/src/impls.rs +++ b/bridges/modules/xcm-bridge-hub-router/src/impls.rs @@ -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; @@ -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(PhantomData); +impl> ResolveBridgeId for EnsureIsRemoteBridgeIdResolver { + type BridgeId = bp_xcm_bridge_hub::BridgeId; + + fn resolve_for_dest(dest: &Location) -> Option { + 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 { + 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; + + // 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()), + ); + } +} \ No newline at end of file diff --git a/bridges/modules/xcm-bridge-hub-router/src/lib.rs b/bridges/modules/xcm-bridge-hub-router/src/lib.rs index a6dfe20266f9..568d0449510e 100644 --- a/bridges/modules/xcm-bridge-hub-router/src/lib.rs +++ b/bridges/modules/xcm-bridge-hub-router/src/lib.rs @@ -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}; @@ -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, diff --git a/bridges/modules/xcm-bridge-hub-router/src/mock.rs b/bridges/modules/xcm-bridge-hub-router/src/mock.rs index 0f7d632c4876..0c9c4ad74a02 100644 --- a/bridges/modules/xcm-bridge-hub-router/src/mock.rs +++ b/bridges/modules/xcm-bridge-hub-router/src/mock.rs @@ -31,6 +31,7 @@ use xcm::prelude::*; use xcm_builder::{ InspectMessageQueues, NetworkExportTable, NetworkExportTableItem, SovereignPaidRemoteExporter, }; +use crate::impls::EnsureIsRemoteBridgeIdResolver; type Block = frame_system::mocking::MockBlock; @@ -104,7 +105,7 @@ impl pallet_xcm_bridge_hub_router::Config<()> for TestRuntime { UniversalLocation, >; - type BridgeIdResolver = EveryDestinationToSameBridgeIdResolver; + type BridgeIdResolver = EnsureIsRemoteBridgeIdResolver; type BridgeHubOrigin = EnsureRoot; type ByteFee = ConstU128; diff --git a/bridges/modules/xcm-bridge-hub/Cargo.toml b/bridges/modules/xcm-bridge-hub/Cargo.toml index 8bf76d8edcfc..fe58b910a94e 100644 --- a/bridges/modules/xcm-bridge-hub/Cargo.toml +++ b/bridges/modules/xcm-bridge-hub/Cargo.toml @@ -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 } diff --git a/bridges/modules/xcm-bridge-hub/src/exporter.rs b/bridges/modules/xcm-bridge-hub/src/exporter.rs index 392fe4490642..09bb1f94ac35 100644 --- a/bridges/modules/xcm-bridge-hub/src/exporter.rs +++ b/bridges/modules/xcm-bridge-hub/src/exporter.rs @@ -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}, @@ -828,7 +828,7 @@ mod tests { // valid routable destination let dest = Location::new(2, BridgedUniversalDestination::get()); - fn router_bridge_state, I: 'static>(dest: &Location) -> Option { + fn router_bridge_state, I: 'static>(dest: &Location) -> Option { let bridge_id = ::resolve_for_dest(dest).unwrap(); pallet_xcm_bridge_hub_router::Bridges::::get(&bridge_id) } diff --git a/bridges/modules/xcm-bridge-hub/src/mock.rs b/bridges/modules/xcm-bridge-hub/src/mock.rs index d3d0cf4ce43e..82f385d13f34 100644 --- a/bridges/modules/xcm-bridge-hub/src/mock.rs +++ b/bridges/modules/xcm-bridge-hub/src/mock.rs @@ -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}, @@ -47,7 +46,7 @@ use xcm::{latest::ROCOCO_GENESIS_HASH, 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; @@ -258,7 +257,7 @@ impl pallet_xcm_bridge_hub_router::Config<()> for TestRuntime { ExportMessageOriginUniversalLocation, >; - type BridgeIdResolver = EnsureIsRemoteBridgeIdResolver; + type BridgeIdResolver = pallet_xcm_bridge_hub_router::impls::EnsureIsRemoteBridgeIdResolver; // We convert to root here `BridgeHubLocationXcmOriginAsRoot` type BridgeHubOrigin = EnsureRoot; } @@ -272,27 +271,11 @@ impl pallet_xcm_bridge_hub_router::Config; - type BridgeIdResolver = EnsureIsRemoteBridgeIdResolver; + type BridgeIdResolver = pallet_xcm_bridge_hub_router::impls::EnsureIsRemoteBridgeIdResolver; // 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(PhantomData); -impl> ResolveBridgeId for EnsureIsRemoteBridgeIdResolver { - type BridgeId = BridgeId; - - fn resolve_for_dest(dest: &Location) -> Option { - 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 { - 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 { diff --git a/cumulus/pallets/xcmp-queue/src/bridging.rs b/cumulus/pallets/xcmp-queue/src/bridging.rs index d896a40cb705..69ffbd400166 100644 --- a/cumulus/pallets/xcmp-queue/src/bridging.rs +++ b/cumulus/pallets/xcmp-queue/src/bridging.rs @@ -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(core::marker::PhantomData); -impl bp_xcm_bridge_hub::ChannelStatusProvider - for InAndOutXcmpChannelStatusProvider -{ - 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::::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::::is_congested(with) - } -} - /// Adapter implementation for `bp_xcm_bridge_hub::ChannelStatusProvider` which checks /// only `OutboundXcmpStatus` for defined `SiblingParaId` if is suspended. pub struct OutXcmpChannelStatusProvider(core::marker::PhantomData); diff --git a/cumulus/pallets/xcmp-queue/src/lib.rs b/cumulus/pallets/xcmp-queue/src/lib.rs index 91f71558b54a..80ba902539be 100644 --- a/cumulus/pallets/xcmp-queue/src/lib.rs +++ b/cumulus/pallets/xcmp-queue/src/lib.rs @@ -691,11 +691,6 @@ impl Pallet { .max(::WeightInfo::on_idle_large_msg()) } - #[cfg(feature = "bridging")] - fn is_inbound_channel_suspended(sender: ParaId) -> bool { - >::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)> { diff --git a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs index 38f2ba8be538..48fd48766d70 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs @@ -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, @@ -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 { @@ -928,22 +929,31 @@ impl pallet_xcm_bridge_hub_router::Config for Runtim type RuntimeEvent = RuntimeEvent; type WeightInfo = weights::pallet_xcm_bridge_hub_router::WeightInfo; - 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, + // `ExporterFor` wrapper handling dynamic fees for congestion. + pallet_xcm_bridge_hub_router::impls::ViaRemoteBridgeHubExporter< + Runtime, + ToWestendXcmRouterInstance, + NetworkExportTable, + xcm_config::bridging::to_westend::WestendNetwork, + xcm_config::bridging::SiblingBridgeHub + >, XcmpQueue, - Self::UniversalLocation + xcm_config::UniversalLocation, >; - type LocalXcmChannelManager = - cumulus_pallet_xcmp_queue::bridging::InAndOutXcmpChannelStatusProvider; + // 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; + // For congestion - allow only calls from BH. + type BridgeHubOrigin = AsEnsureOriginWithArg>>; + + // For adding message size fees type ByteFee = xcm_config::bridging::XcmBridgeHubRouterByteFee; + // For adding message size fees type FeeAsset = xcm_config::bridging::XcmBridgeHubRouterFeeAssetId; } diff --git a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/pallet_xcm_bridge_hub_router.rs b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/pallet_xcm_bridge_hub_router.rs index 00ecf239428f..9fa2264fb8d9 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/pallet_xcm_bridge_hub_router.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/pallet_xcm_bridge_hub_router.rs @@ -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(PhantomData); impl pallet_xcm_bridge_hub_router::WeightInfo for WeightInfo { + // 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) @@ -77,4 +87,14 @@ impl 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)) + } } diff --git a/cumulus/parachains/runtimes/assets/asset-hub-rococo/tests/tests.rs b/cumulus/parachains/runtimes/assets/asset-hub-rococo/tests/tests.rs index 5da8b45417a3..d75c174ded86 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-rococo/tests/tests.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-rococo/tests/tests.rs @@ -17,18 +17,11 @@ //! Tests for the Rococo Assets Hub chain. -use asset_hub_rococo_runtime::{ - xcm_config, - xcm_config::{ - bridging, AssetFeeAsExistentialDepositMultiplierFeeCharger, CheckingAccount, - ForeignAssetFeeAsExistentialDepositMultiplierFeeCharger, LocationToAccountId, StakingPot, - TokenLocation, TrustBackedAssetsPalletLocation, XcmConfig, - }, - AllPalletsWithoutSystem, AssetConversion, AssetDeposit, Assets, Balances, CollatorSelection, - ExistentialDeposit, ForeignAssets, ForeignAssetsInstance, MetadataDepositBase, - MetadataDepositPerByte, ParachainSystem, Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin, - SessionKeys, TrustBackedAssetsInstance, XcmpQueue, -}; +use asset_hub_rococo_runtime::{xcm_config, xcm_config::{ + bridging, AssetFeeAsExistentialDepositMultiplierFeeCharger, CheckingAccount, + ForeignAssetFeeAsExistentialDepositMultiplierFeeCharger, LocationToAccountId, StakingPot, + TokenLocation, TrustBackedAssetsPalletLocation, XcmConfig, +}, AllPalletsWithoutSystem, AssetConversion, AssetDeposit, Assets, Balances, CollatorSelection, ExistentialDeposit, ForeignAssets, ForeignAssetsInstance, MetadataDepositBase, MetadataDepositPerByte, ParachainSystem, Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin, SessionKeys, ToWestendXcmRouterInstance, TrustBackedAssetsInstance, XcmpQueue}; use asset_test_utils::{ test_cases_over_bridge::TestBridgingConfig, CollatorSessionKey, CollatorSessionKeys, ExtBuilder, SlotDurations, @@ -1271,6 +1264,55 @@ mod asset_hub_rococo_tests { WeightLimit::Unlimited, ); } + + #[test] + fn report_bridge_status_from_xcm_bridge_router_for_rococo_works() { + asset_test_utils::test_cases_over_bridge::report_bridge_status_from_xcm_bridge_router_works::< + Runtime, + AllPalletsWithoutSystem, + XcmConfig, + LocationToAccountId, + ToWestendXcmRouterInstance, + >( + collator_session_keys(), + bridging_to_asset_hub_westend, + |bridge_id, is_congested| { + vec![ + UnpaidExecution { weight_limit: Unlimited, check_origin: None }, + Transact { + origin_kind: OriginKind::Xcm, + require_weight_at_most: + bp_bridge_hub_rococo::XcmBridgeHubRouterTransactCallMaxWeight::get(), + call: RuntimeCall::ToWestendXcmRouter( + pallet_xcm_bridge_hub_router::Call::report_bridge_status { + bridge_id, + is_congested, + }, + ) + .encode() + .into(), + }, + ExpectTransactStatus(MaybeErrorCode::Success) + ] + .into() + }, + ) + } +} + +#[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_bridge_hub_westend::XcmBridgeHubRouterTransactCallMaxWeight::get(); + assert!( + actual.all_lte(max_weight), + "max_weight: {:?} should be adjusted to actual {:?}", + max_weight, + actual + ); } #[test] diff --git a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs index eede6885bb29..90f18167ddcd 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs @@ -94,6 +94,8 @@ use assets_common::{ foreign_creators::ForeignCreators, matching::{FromNetwork, FromSiblingParachain}, }; +use frame_support::traits::Equals; +use pallet_xcm::EnsureXcm; use polkadot_runtime_common::{BlockHashCount, SlowAdjustingFeeUpdate}; use xcm::{ latest::prelude::AssetId, @@ -112,7 +114,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 { @@ -925,22 +927,31 @@ impl pallet_xcm_bridge_hub_router::Config for Runtime type RuntimeEvent = RuntimeEvent; type WeightInfo = weights::pallet_xcm_bridge_hub_router::WeightInfo; - type UniversalLocation = xcm_config::UniversalLocation; - type SiblingBridgeHubLocation = xcm_config::bridging::SiblingBridgeHub; - type BridgedNetworkId = xcm_config::bridging::to_rococo::RococoNetwork; type DestinationVersion = PolkadotXcm; // Let's use `SovereignPaidRemoteExporter`, which sends `ExportMessage` over HRMP to the sibling // BridgeHub. type ToBridgeHubSender = SovereignPaidRemoteExporter< - xcm_builder::NetworkExportTable, + // `ExporterFor` wrapper handling dynamic fees for congestion. + pallet_xcm_bridge_hub_router::impls::ViaRemoteBridgeHubExporter< + Runtime, + ToRococoXcmRouterInstance, + NetworkExportTable, + xcm_config::bridging::to_rococo::RococoNetwork, + xcm_config::bridging::SiblingBridgeHub + >, XcmpQueue, - Self::UniversalLocation + xcm_config::UniversalLocation, >; - type LocalXcmChannelManager = - cumulus_pallet_xcmp_queue::bridging::InAndOutXcmpChannelStatusProvider; + // 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; + // For congestion - allow only calls from BH. + type BridgeHubOrigin = AsEnsureOriginWithArg>>; + + // For adding message size fees type ByteFee = xcm_config::bridging::XcmBridgeHubRouterByteFee; + // For adding message size fees type FeeAsset = xcm_config::bridging::XcmBridgeHubRouterFeeAssetId; } diff --git a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/pallet_xcm_bridge_hub_router.rs b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/pallet_xcm_bridge_hub_router.rs index c0898012e9f3..9c1fe64ac16f 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/pallet_xcm_bridge_hub_router.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/pallet_xcm_bridge_hub_router.rs @@ -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(PhantomData); impl pallet_xcm_bridge_hub_router::WeightInfo for WeightInfo { + // 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) @@ -77,4 +87,14 @@ impl 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)) + } } diff --git a/cumulus/parachains/runtimes/assets/asset-hub-westend/tests/tests.rs b/cumulus/parachains/runtimes/assets/asset-hub-westend/tests/tests.rs index 5d0f843554a1..edd5b7d8d253 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-westend/tests/tests.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-westend/tests/tests.rs @@ -17,18 +17,11 @@ //! Tests for the Westmint (Westend Assets Hub) chain. -use asset_hub_westend_runtime::{ - xcm_config, - xcm_config::{ - bridging, AssetFeeAsExistentialDepositMultiplierFeeCharger, CheckingAccount, - ForeignAssetFeeAsExistentialDepositMultiplierFeeCharger, LocationToAccountId, StakingPot, - TrustBackedAssetsPalletLocation, WestendLocation, XcmConfig, - }, - AllPalletsWithoutSystem, Assets, Balances, ExistentialDeposit, ForeignAssets, - ForeignAssetsInstance, MetadataDepositBase, MetadataDepositPerByte, ParachainSystem, - PolkadotXcm, Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin, SessionKeys, - TrustBackedAssetsInstance, XcmpQueue, -}; +use asset_hub_westend_runtime::{xcm_config, xcm_config::{ + bridging, AssetFeeAsExistentialDepositMultiplierFeeCharger, CheckingAccount, + ForeignAssetFeeAsExistentialDepositMultiplierFeeCharger, LocationToAccountId, StakingPot, + TrustBackedAssetsPalletLocation, WestendLocation, XcmConfig, +}, AllPalletsWithoutSystem, Assets, Balances, ExistentialDeposit, ForeignAssets, ForeignAssetsInstance, MetadataDepositBase, MetadataDepositPerByte, ParachainSystem, PolkadotXcm, Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin, SessionKeys, ToRococoXcmRouterInstance, TrustBackedAssetsInstance, XcmpQueue}; pub use asset_hub_westend_runtime::{AssetConversion, AssetDeposit, CollatorSelection, System}; use asset_test_utils::{ test_cases_over_bridge::TestBridgingConfig, CollatorSessionKey, CollatorSessionKeys, @@ -1250,6 +1243,55 @@ fn receive_reserve_asset_deposited_roc_from_asset_hub_rococo_fees_paid_by_suffic ) } +#[test] +fn report_bridge_status_from_xcm_bridge_router_for_rococo_works() { + asset_test_utils::test_cases_over_bridge::report_bridge_status_from_xcm_bridge_router_works::< + Runtime, + AllPalletsWithoutSystem, + XcmConfig, + LocationToAccountId, + ToRococoXcmRouterInstance, + >( + collator_session_keys(), + bridging_to_asset_hub_rococo, + |bridge_id, is_congested| { + vec![ + UnpaidExecution { weight_limit: Unlimited, check_origin: None }, + Transact { + origin_kind: OriginKind::Xcm, + require_weight_at_most: + bp_bridge_hub_rococo::XcmBridgeHubRouterTransactCallMaxWeight::get(), + call: RuntimeCall::ToRococoXcmRouter( + pallet_xcm_bridge_hub_router::Call::report_bridge_status { + bridge_id, + is_congested, + }, + ) + .encode() + .into(), + }, + ExpectTransactStatus(MaybeErrorCode::Success) + ] + .into() + }, + ) +} + +#[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_bridge_hub_rococo::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::< diff --git a/cumulus/parachains/runtimes/assets/test-utils/src/test_cases_over_bridge.rs b/cumulus/parachains/runtimes/assets/test-utils/src/test_cases_over_bridge.rs index 4f144e24aa30..3ad788c74163 100644 --- a/cumulus/parachains/runtimes/assets/test-utils/src/test_cases_over_bridge.rs +++ b/cumulus/parachains/runtimes/assets/test-utils/src/test_cases_over_bridge.rs @@ -498,8 +498,7 @@ pub fn report_bridge_status_from_xcm_bridge_router_works< >( collator_session_keys: CollatorSessionKeys, prepare_configuration: fn() -> TestBridgingConfig, - congested_message: fn() -> Xcm, - uncongested_message: fn() -> Xcm, + congestion_message: fn(pallet_xcm_bridge_hub_router::BridgeIdOf, bool) -> Xcm, ) where Runtime: frame_system::Config + pallet_balances::Config @@ -534,10 +533,18 @@ pub fn report_bridge_status_from_xcm_bridge_router_works< .execute_with(|| { let report_bridge_status = |is_congested: bool| { // prepare bridge config - let TestBridgingConfig { local_bridge_hub_location, .. } = prepare_configuration(); + let TestBridgingConfig { local_bridge_hub_location, bridged_target_location, .. } = prepare_configuration(); + + + use pallet_xcm_bridge_hub_router::ResolveBridgeId; + let bridge_id = <>::BridgeIdResolver>::resolve_for_dest(&bridged_target_location).expect("resolved BridgeId"); + + // check before + let bridge_state = pallet_xcm_bridge_hub_router::Bridges::::get(&bridge_id); + let is_congested_before = bridge_state.map(|bs| bs.is_congested).unwrap_or(false); // Call received XCM execution - let xcm = if is_congested { congested_message() } else { uncongested_message() }; + let xcm = congestion_message(bridge_id.clone(), is_congested); let mut hash = xcm.using_encoded(sp_io::hashing::blake2_256); // execute xcm as XcmpQueue would do @@ -551,9 +558,14 @@ pub fn report_bridge_status_from_xcm_bridge_router_works< Weight::zero(), ); assert_ok!(outcome.ensure_complete()); - assert_eq!( - is_congested, - <>::LocalXcmChannelManager as pallet_xcm_bridge_hub_router::XcmChannelStatusProvider>::is_congested(&local_bridge_hub_location) + + // check after + let bridge_state = pallet_xcm_bridge_hub_router::Bridges::::get(&bridge_id); + let is_congested_after = bridge_state.map(|bs| bs.is_congested).unwrap_or(false); + assert_eq!(is_congested_after, is_congested); + assert_ne!( + is_congested_after, + is_congested_before, ); }; diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_bulletin_config.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_bulletin_config.rs index 7e0385692375..ade0bfd63b18 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_bulletin_config.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_bulletin_config.rs @@ -40,6 +40,7 @@ use pallet_bridge_messages::LaneIdOf; use pallet_bridge_relayers::extension::{ BridgeRelayersTransactionExtension, WithMessagesExtensionConfig, }; +use pallet_xcm_bridge_hub::congestion::BlobDispatcherWithChannelStatus; use pallet_xcm_bridge_hub::XcmAsPlainPayload; use polkadot_parachain_primitives::primitives::Sibling; use testnet_parachains_constants::rococo::currency::UNITS as ROC; @@ -85,13 +86,6 @@ pub type FromRococoBulletinMessagesProof = pub type ToRococoBulletinMessagesDeliveryProof = FromBridgedChainMessagesDeliveryProof>; -/// Dispatches received XCM messages from other bridge. -type FromRococoBulletinMessageBlobDispatcher = BridgeBlobDispatcher< - XcmRouter, - UniversalLocation, - BridgeRococoToRococoBulletinMessagesPalletInstance, ->; - /// Transaction extension that refunds relayers that are delivering messages from the Rococo /// Bulletin chain. pub type OnBridgeHubRococoRefundRococoBulletinMessages = BridgeRelayersTransactionExtension< @@ -156,7 +150,13 @@ impl pallet_xcm_bridge_hub::Config for Runtime type AllowWithoutBridgeDeposit = Equals; type LocalXcmChannelManager = (); - type BlobDispatcher = FromRococoBulletinMessageBlobDispatcher; + // Dispatching inbound messages from the bridge. + type BlobDispatcher = BlobDispatcherWithChannelStatus< + // Dispatches received XCM messages from other bridge + BridgeBlobDispatcher, + // no congestion checking + (), + >; } #[cfg(test)] diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_westend_config.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_westend_config.rs index 0eab3c74a7e2..9a3fd1587d80 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_westend_config.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_westend_config.rs @@ -26,6 +26,7 @@ use crate::{ AccountId, Balance, Balances, BridgeWestendMessages, PolkadotXcm, Runtime, RuntimeEvent, RuntimeHoldReason, XcmOverBridgeHubWestend, XcmRouter, }; +use alloc::{vec, vec::Vec}; use bp_messages::{ source_chain::FromBridgedChainMessagesDeliveryProof, target_chain::FromBridgedChainMessagesProof, LegacyLaneId, @@ -39,8 +40,10 @@ use pallet_bridge_messages::LaneIdOf; use pallet_bridge_relayers::extension::{ BridgeRelayersTransactionExtension, WithMessagesExtensionConfig, }; +use pallet_xcm_bridge_hub::congestion::{BlobDispatcherWithChannelStatus, ReportBridgeStatusXcmChannelManager}; use parachains_common::xcm_config::{AllSiblingSystemParachains, RelayOrOtherSystemParachains}; use polkadot_parachain_primitives::primitives::Sibling; +use sp_runtime::traits::Convert; use testnet_parachains_constants::rococo::currency::UNITS as ROC; use xcm::{ latest::{prelude::*, WESTEND_GENESIS_HASH}, @@ -80,10 +83,6 @@ pub type FromWestendBridgeHubMessagesProof = pub type ToWestendBridgeHubMessagesDeliveryProof = FromBridgedChainMessagesDeliveryProof>; -/// Dispatches received XCM messages from other bridge -type FromWestendMessageBlobDispatcher = - BridgeBlobDispatcher; - /// Transaction extension that refunds relayers that are delivering messages from the Westend /// parachain. pub type OnBridgeHubRococoRefundBridgeHubWestendMessages = BridgeRelayersTransactionExtension< @@ -128,6 +127,22 @@ impl pallet_bridge_messages::Config for Ru type OnMessagesDelivered = XcmOverBridgeHubWestend; } +/// Converts encoded call to the unpaid XCM `Transact`. +pub struct ReportBridgeStatusXcmProvider; +impl Convert, Xcm<()>> for ReportBridgeStatusXcmProvider { + fn convert(encoded_call: Vec) -> Xcm<()> { + Xcm(vec![ + UnpaidExecution { weight_limit: Unlimited, check_origin: None }, + Transact { + origin_kind: OriginKind::Xcm, + require_weight_at_most: bp_bridge_hub_rococo::XcmBridgeHubRouterTransactCallMaxWeight::get(), + call: encoded_call.into(), + }, + ExpectTransactStatus(MaybeErrorCode::Success), + ]) + } +} + /// Add support for the export and dispatch of XCM programs withing /// `WithBridgeHubWestendMessagesInstance`. pub type XcmOverBridgeHubWestendInstance = pallet_xcm_bridge_hub::Instance1; @@ -156,9 +171,16 @@ impl pallet_xcm_bridge_hub::Config for Runtime type AllowWithoutBridgeDeposit = RelayOrOtherSystemParachains; - // TODO:(bridges-v2) - add `LocalXcmChannelManager` impl - https://github.com/paritytech/parity-bridges-common/issues/3047 - type LocalXcmChannelManager = (); - type BlobDispatcher = FromWestendMessageBlobDispatcher; + // This pallet is deployed on BH, so we expect a remote router with `ExportMessage`. We handle congestion with XCM using `report_bridge_status` sent to the sending chain. + // (congestion with local sending chain) + type LocalXcmChannelManager = ReportBridgeStatusXcmChannelManager; + // Dispatching inbound messages from the bridge and managing congestion with the local receiving/destination chain + type BlobDispatcher = BlobDispatcherWithChannelStatus< + // Dispatches received XCM messages from other bridge + BridgeBlobDispatcher, + // Provides the status of the XCMP queue's outbound queue, indicating whether messages can be dispatched to the sibling. + cumulus_pallet_xcmp_queue::bridging::OutXcmpChannelStatusProvider, + >; } #[cfg(feature = "runtime-benchmarks")] diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/bridge_to_rococo_config.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/bridge_to_rococo_config.rs index 62c93da7c831..d46ba1e08ef0 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/bridge_to_rococo_config.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/bridge_to_rococo_config.rs @@ -23,6 +23,7 @@ use crate::{ AccountId, Balance, Balances, BridgeRococoMessages, PolkadotXcm, Runtime, RuntimeEvent, RuntimeHoldReason, XcmOverBridgeHubRococo, XcmRouter, }; +use alloc::{vec, vec::Vec}; use bp_messages::{ source_chain::FromBridgedChainMessagesDeliveryProof, target_chain::FromBridgedChainMessagesProof, LegacyLaneId, @@ -40,8 +41,10 @@ use pallet_bridge_messages::LaneIdOf; use pallet_bridge_relayers::extension::{ BridgeRelayersTransactionExtension, WithMessagesExtensionConfig, }; +use pallet_xcm_bridge_hub::congestion::{BlobDispatcherWithChannelStatus, ReportBridgeStatusXcmChannelManager}; use parachains_common::xcm_config::{AllSiblingSystemParachains, RelayOrOtherSystemParachains}; use polkadot_parachain_primitives::primitives::Sibling; +use sp_runtime::traits::Convert; use testnet_parachains_constants::westend::currency::UNITS as WND; use xcm::{ latest::{prelude::*, ROCOCO_GENESIS_HASH}, @@ -87,10 +90,6 @@ pub type FromRococoBridgeHubMessagesProof = pub type ToRococoBridgeHubMessagesDeliveryProof = FromBridgedChainMessagesDeliveryProof>; -/// Dispatches received XCM messages from other bridge -type FromRococoMessageBlobDispatcher = - BridgeBlobDispatcher; - /// Transaction extension that refunds relayers that are delivering messages from the Rococo /// parachain. pub type OnBridgeHubWestendRefundBridgeHubRococoMessages = BridgeRelayersTransactionExtension< @@ -159,6 +158,22 @@ impl pallet_bridge_messages::Config for Run type OnMessagesDelivered = XcmOverBridgeHubRococo; } +/// Converts encoded call to the unpaid XCM `Transact`. +pub struct ReportBridgeStatusXcmProvider; +impl Convert, Xcm<()>> for ReportBridgeStatusXcmProvider { + fn convert(encoded_call: Vec) -> Xcm<()> { + Xcm(vec![ + UnpaidExecution { weight_limit: Unlimited, check_origin: None }, + Transact { + origin_kind: OriginKind::Xcm, + require_weight_at_most: bp_bridge_hub_westend::XcmBridgeHubRouterTransactCallMaxWeight::get(), + call: encoded_call.into(), + }, + ExpectTransactStatus(MaybeErrorCode::Success), + ]) + } +} + /// Add support for the export and dispatch of XCM programs. pub type XcmOverBridgeHubRococoInstance = pallet_xcm_bridge_hub::Instance1; impl pallet_xcm_bridge_hub::Config for Runtime { @@ -185,9 +200,16 @@ impl pallet_xcm_bridge_hub::Config for Runtime { type AllowWithoutBridgeDeposit = RelayOrOtherSystemParachains; - // TODO:(bridges-v2) - add `LocalXcmChannelManager` impl - https://github.com/paritytech/parity-bridges-common/issues/3047 - type LocalXcmChannelManager = (); - type BlobDispatcher = FromRococoMessageBlobDispatcher; + // This pallet is deployed on BH, so we expect a remote router with `ExportMessage`. We handle congestion with XCM using `report_bridge_status` sent to the sending chain. + // (congestion with local sending chain) + type LocalXcmChannelManager = ReportBridgeStatusXcmChannelManager; + // Dispatching inbound messages from the bridge and managing congestion with the local receiving/destination chain + type BlobDispatcher = BlobDispatcherWithChannelStatus< + // Dispatches received XCM messages from other bridge + BridgeBlobDispatcher, + // Provides the status of the XCMP queue's outbound queue, indicating whether messages can be dispatched to the sibling. + cumulus_pallet_xcmp_queue::bridging::OutXcmpChannelStatusProvider, + >; } #[cfg(feature = "runtime-benchmarks")] diff --git a/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/mod.rs b/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/mod.rs index 0dc1b07a3364..2b8ea84bc861 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/mod.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/mod.rs @@ -740,7 +740,8 @@ pub fn open_and_close_bridge_works Date: Tue, 5 Nov 2024 12:44:26 +0000 Subject: [PATCH 21/72] ".git/.scripts/commands/fmt/fmt.sh" --- .../chains/chain-bridge-hub-rococo/src/lib.rs | 2 +- .../chain-bridge-hub-westend/src/lib.rs | 2 +- .../xcm-bridge-hub-router/src/impls.rs | 421 ++++++++++-------- .../modules/xcm-bridge-hub-router/src/lib.rs | 205 +++++---- .../modules/xcm-bridge-hub-router/src/mock.rs | 26 +- .../modules/xcm-bridge-hub/src/congestion.rs | 184 ++++---- .../modules/xcm-bridge-hub/src/dispatcher.rs | 2 +- .../modules/xcm-bridge-hub/src/exporter.rs | 116 ++++- bridges/modules/xcm-bridge-hub/src/lib.rs | 9 +- bridges/modules/xcm-bridge-hub/src/mock.rs | 51 ++- .../xcm-bridge-hub-router/src/lib.rs | 15 +- bridges/primitives/xcm-bridge-hub/src/lib.rs | 8 +- .../assets/asset-hub-rococo/src/lib.rs | 16 +- .../assets/asset-hub-rococo/tests/tests.rs | 59 +-- .../assets/asset-hub-westend/src/lib.rs | 12 +- .../assets/asset-hub-westend/tests/tests.rs | 59 +-- .../test-utils/src/test_cases_over_bridge.rs | 32 +- .../src/bridge_to_bulletin_config.rs | 9 +- .../src/bridge_to_westend_config.rs | 31 +- .../src/bridge_to_rococo_config.rs | 31 +- 20 files changed, 784 insertions(+), 506 deletions(-) diff --git a/bridges/chains/chain-bridge-hub-rococo/src/lib.rs b/bridges/chains/chain-bridge-hub-rococo/src/lib.rs index 6fed41875218..014fe6241c05 100644 --- a/bridges/chains/chain-bridge-hub-rococo/src/lib.rs +++ b/bridges/chains/chain-bridge-hub-rococo/src/lib.rs @@ -128,4 +128,4 @@ pub enum RuntimeCall { 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(1_000_000_000, 1024*8); -} \ No newline at end of file +} diff --git a/bridges/chains/chain-bridge-hub-westend/src/lib.rs b/bridges/chains/chain-bridge-hub-westend/src/lib.rs index 39899daa7610..6aba3f892c50 100644 --- a/bridges/chains/chain-bridge-hub-westend/src/lib.rs +++ b/bridges/chains/chain-bridge-hub-westend/src/lib.rs @@ -117,4 +117,4 @@ pub enum RuntimeCall { 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(1_000_000_000, 1024*8); -} \ No newline at end of file +} diff --git a/bridges/modules/xcm-bridge-hub-router/src/impls.rs b/bridges/modules/xcm-bridge-hub-router/src/impls.rs index 85c5ed956f14..37429a5f05d1 100644 --- a/bridges/modules/xcm-bridge-hub-router/src/impls.rs +++ b/bridges/modules/xcm-bridge-hub-router/src/impls.rs @@ -15,89 +15,101 @@ // along with Parity Bridges Common. If not, see . //! Various implementations supporting easier configuration of the pallet. -use crate::{Config, Pallet, Bridges, BridgeIdOf, LOG_TARGET}; -use xcm_builder::{ensure_is_remote, ExporterFor}; +use crate::{BridgeIdOf, Bridges, Config, Pallet, LOG_TARGET}; use bp_xcm_bridge_hub_router::ResolveBridgeId; use codec::Encode; -use frame_support::pallet_prelude::PhantomData; -use frame_support::traits::Get; -use frame_support::ensure; +use frame_support::{ensure, pallet_prelude::PhantomData, traits::Get}; use xcm::prelude::*; +use xcm_builder::{ensure_is_remote, ExporterFor}; -/// Implementation of `LocalXcmChannelManager` which tracks and updates `is_congested` for a given `BridgeId`. -/// This implementation is useful for managing congestion and dynamic fees with the local `ExportXcm` implementation. -impl, I: 'static> bp_xcm_bridge_hub::LocalXcmChannelManager> for Pallet { - type Error = (); +/// Implementation of `LocalXcmChannelManager` which tracks and updates `is_congested` for a given +/// `BridgeId`. This implementation is useful for managing congestion and dynamic fees with the +/// local `ExportXcm` implementation. +impl, I: 'static> bp_xcm_bridge_hub::LocalXcmChannelManager> + for Pallet +{ + type Error = (); - /// Suspends the given bridge. - /// - /// This function ensures that the `local_origin` matches the expected `Location::here()`. If the check passes, it updates the bridge status to congested. - fn suspend_bridge(local_origin: &Location, bridge: BridgeIdOf) -> Result<(), Self::Error> { - log::trace!( - target: LOG_TARGET, - "LocalXcmChannelManager::suspend_bridge(local_origin: {local_origin:?}, bridge: {bridge:?})", - ); - ensure!(local_origin.eq(&Location::here()), ()); + /// Suspends the given bridge. + /// + /// This function ensures that the `local_origin` matches the expected `Location::here()`. If + /// the check passes, it updates the bridge status to congested. + fn suspend_bridge( + local_origin: &Location, + bridge: BridgeIdOf, + ) -> Result<(), Self::Error> { + log::trace!( + target: LOG_TARGET, + "LocalXcmChannelManager::suspend_bridge(local_origin: {local_origin:?}, bridge: {bridge:?})", + ); + ensure!(local_origin.eq(&Location::here()), ()); - // update status - Self::update_bridge_status(bridge, true); + // update status + Self::update_bridge_status(bridge, true); - Ok(()) - } + Ok(()) + } - /// Resumes the given bridge. - /// - /// This function ensures that the `local_origin` matches the expected `Location::here()`. If the check passes, it updates the bridge status to not congested. - fn resume_bridge(local_origin: &Location, bridge: BridgeIdOf) -> Result<(), Self::Error> { - log::trace!( - target: LOG_TARGET, - "LocalXcmChannelManager::resume_bridge(local_origin: {local_origin:?}, bridge: {bridge:?})", - ); - ensure!(local_origin.eq(&Location::here()), ()); + /// Resumes the given bridge. + /// + /// This function ensures that the `local_origin` matches the expected `Location::here()`. If + /// the check passes, it updates the bridge status to not congested. + fn resume_bridge(local_origin: &Location, bridge: BridgeIdOf) -> Result<(), Self::Error> { + log::trace!( + target: LOG_TARGET, + "LocalXcmChannelManager::resume_bridge(local_origin: {local_origin:?}, bridge: {bridge:?})", + ); + ensure!(local_origin.eq(&Location::here()), ()); - // update status - Self::update_bridge_status(bridge, false); + // update status + Self::update_bridge_status(bridge, false); - Ok(()) - } + Ok(()) + } } pub struct ViaRemoteBridgeHubExporter(PhantomData<(T, I, E, BNF, BHLF)>); -impl, I: 'static, E, BridgedNetworkIdFilter, BridgeHubLocationFilter> ExporterFor for ViaRemoteBridgeHubExporter +impl, I: 'static, E, BridgedNetworkIdFilter, BridgeHubLocationFilter> ExporterFor + for ViaRemoteBridgeHubExporter where - E: ExporterFor, - BridgedNetworkIdFilter: Get>, - BridgeHubLocationFilter: Get>, + E: ExporterFor, + BridgedNetworkIdFilter: Get>, + BridgeHubLocationFilter: Get>, { - - fn exporter_for( - network: &NetworkId, - remote_location: &InteriorLocation, - message: &Xcm<()>, - ) -> Option<(Location, Option)> { - log::trace!( + fn exporter_for( + network: &NetworkId, + remote_location: &InteriorLocation, + message: &Xcm<()>, + ) -> Option<(Location, Option)> { + log::trace!( target: LOG_TARGET, "exporter_for - network: {network:?}, remote_location: {remote_location:?}, msg: {message:?}", ); - // ensure that the message is sent to the expected bridged network (if specified). - if let Some(bridged_network) = BridgedNetworkIdFilter::get() { - if *network != bridged_network { - log::trace!( + // ensure that the message is sent to the expected bridged network (if specified). + if let Some(bridged_network) = BridgedNetworkIdFilter::get() { + if *network != bridged_network { + log::trace!( target: LOG_TARGET, "Router with bridged_network_id filter({bridged_network:?}) does not support bridging to network {network:?}!", ); - return None - } - } + return None + } + } - // ensure that the message is sent to the expected bridged network and location. - let (bridge_hub_location, maybe_payment) = match E::exporter_for(network, remote_location, message) { - Some((bridge_hub_location, maybe_payment)) => match BridgeHubLocationFilter::get() { - Some(expected_bridge_hub_location) if expected_bridge_hub_location.eq(&bridge_hub_location) => (bridge_hub_location, maybe_payment), - None => (bridge_hub_location, maybe_payment), - _ => { - log::trace!( + // ensure that the message is sent to the expected bridged network and location. + let (bridge_hub_location, maybe_payment) = match E::exporter_for( + network, + remote_location, + message, + ) { + Some((bridge_hub_location, maybe_payment)) => match BridgeHubLocationFilter::get() { + Some(expected_bridge_hub_location) + if expected_bridge_hub_location.eq(&bridge_hub_location) => + (bridge_hub_location, maybe_payment), + None => (bridge_hub_location, maybe_payment), + _ => { + log::trace!( target: LOG_TARGET, "Resolved bridge_hub_location: {:?} does not match expected one: {:?} for bridging to network {:?} and remote_location {:?}!", bridge_hub_location, @@ -105,37 +117,44 @@ where network, remote_location, ); - return None - } - }, - _ => { - log::trace!( + return None + }, + }, + _ => { + log::trace!( target: LOG_TARGET, "Inner `E` router does not support bridging to network {:?} and remote_location {:?}!", network, remote_location, ); - return None - }, - }; + return None + }, + }; - // calculate message size fees (if configured) - let maybe_message_size_fees = Pallet::::calculate_message_size_fees(|| message.encoded_size() as _); + // calculate message size fees (if configured) + let maybe_message_size_fees = + Pallet::::calculate_message_size_fees(|| message.encoded_size() as _); - // compute actual fees - sum(actual payment, message size fees) if possible - let fees = match (maybe_payment, maybe_message_size_fees) { - (Some(payment), None) => Some(payment), - (None, Some(message_size_fees)) => Some(message_size_fees), - (None, None) => None, - ( - Some(Asset {id: payment_asset_id, fun: Fungible(payment_amount)}), - Some(Asset {id: message_size_fees_asset_id, fun: Fungible(message_size_fees_amount)}) - ) if payment_asset_id.eq(&message_size_fees_asset_id) => { - // we can subsume two assets with the same asset_id and fungibility. - Some((payment_asset_id, (payment_amount.saturating_add(message_size_fees_amount))).into()) - }, - (Some(payment), Some(message_size_fees)) => { - log::error!( + // compute actual fees - sum(actual payment, message size fees) if possible + let fees = match (maybe_payment, maybe_message_size_fees) { + (Some(payment), None) => Some(payment), + (None, Some(message_size_fees)) => Some(message_size_fees), + (None, None) => None, + ( + Some(Asset { id: payment_asset_id, fun: Fungible(payment_amount) }), + Some(Asset { + id: message_size_fees_asset_id, + fun: Fungible(message_size_fees_amount), + }), + ) if payment_asset_id.eq(&message_size_fees_asset_id) => { + // we can subsume two assets with the same asset_id and fungibility. + Some( + (payment_asset_id, (payment_amount.saturating_add(message_size_fees_amount))) + .into(), + ) + }, + (Some(payment), Some(message_size_fees)) => { + log::error!( target: LOG_TARGET, "Router is configured for `T::FeeAsset` {:?} \ but we have two different assets which cannot be calculated as one result asset: payment: {:?} and message_size_fees: {:?} for bridge_hub_location: {:?} for bridging to {:?}/{:?}!", @@ -146,123 +165,155 @@ where network, remote_location, ); - return None - } - }; + return None + }, + }; - // Here, we have the actual result fees covering bridge fees, so now we need to check/apply the congestion and dynamic_fees features (if possible). - let fees = fees.map(|fees| if let Some(bridge_id) = T::BridgeIdResolver::resolve_for(network, remote_location) { - if let Some(bridge_state) = Bridges::::get(bridge_id) { - Pallet::::calculate_dynamic_fees_for_asset(&bridge_state, fees) - } else { - fees - } - } else { - fees - }); + // Here, we have the actual result fees covering bridge fees, so now we need to check/apply + // the congestion and dynamic_fees features (if possible). + let fees = fees.map(|fees| { + if let Some(bridge_id) = T::BridgeIdResolver::resolve_for(network, remote_location) { + if let Some(bridge_state) = Bridges::::get(bridge_id) { + Pallet::::calculate_dynamic_fees_for_asset(&bridge_state, fees) + } else { + fees + } + } else { + fees + } + }); - Some((bridge_hub_location, fees)) - } + Some((bridge_hub_location, fees)) + } } -/// Implementation of `ResolveBridgeId` returning `bp_xcm_bridge_hub::BridgeId` based on the configured `UniversalLocation` and remote universal location. +/// Implementation of `ResolveBridgeId` returning `bp_xcm_bridge_hub::BridgeId` based on the +/// configured `UniversalLocation` and remote universal location. pub struct EnsureIsRemoteBridgeIdResolver(PhantomData); -impl> ResolveBridgeId for EnsureIsRemoteBridgeIdResolver { - type BridgeId = bp_xcm_bridge_hub::BridgeId; +impl> ResolveBridgeId + for EnsureIsRemoteBridgeIdResolver +{ + type BridgeId = bp_xcm_bridge_hub::BridgeId; - fn resolve_for_dest(dest: &Location) -> Option { - let Ok((remote_network, remote_dest)) = ensure_is_remote(UniversalLocation::get(), dest.clone()) else { - log::trace!( - target: LOG_TARGET, + fn resolve_for_dest(dest: &Location) -> Option { + 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) - } + ); + return None + }; + Self::resolve_for(&remote_network, &remote_dest) + } - fn resolve_for(bridged_network: &NetworkId, bridged_dest: &InteriorLocation) -> Option { - 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 - } - } - }; + fn resolve_for( + bridged_network: &NetworkId, + bridged_dest: &InteriorLocation, + ) -> Option { + 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 - } - } + 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)) - } + // 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::*; + use super::*; + use frame_support::__private::sp_tracing; - #[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()); + #[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; + type Resolver = EnsureIsRemoteBridgeIdResolver; - // 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()); + // 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 + 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()), - ); - } -} \ No newline at end of file + // 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() + ), + ); + } +} diff --git a/bridges/modules/xcm-bridge-hub-router/src/lib.rs b/bridges/modules/xcm-bridge-hub-router/src/lib.rs index 568d0449510e..70f9737059d4 100644 --- a/bridges/modules/xcm-bridge-hub-router/src/lib.rs +++ b/bridges/modules/xcm-bridge-hub-router/src/lib.rs @@ -122,8 +122,9 @@ pub mod pallet { #[pallet::no_default] type ToBridgeHubSender: SendXcm; - /// Resolves a specific `BridgeId` for `dest`, used for identifying the bridge in cases of congestion and dynamic fees. - /// If it resolves to `None`, it means no congestion or dynamic fees are handled for `dest`. + /// Resolves a specific `BridgeId` for `dest`, used for identifying the bridge in cases of + /// congestion and dynamic fees. If it resolves to `None`, it means no congestion or + /// dynamic fees are handled for `dest`. #[pallet::no_default] type BridgeIdResolver: ResolveBridgeId; @@ -183,7 +184,8 @@ pub mod pallet { new_value: 0.into(), bridge_id, }); - weight_used.saturating_accrue(T::WeightInfo::on_initialize_when_bridge_state_removed()); + weight_used + .saturating_accrue(T::WeightInfo::on_initialize_when_bridge_state_removed()); } // update for (bridge_id, previous_value, bridge_state) in bridges_to_update.into_iter() { @@ -201,7 +203,8 @@ pub mod pallet { new_value, bridge_id, }); - weight_used.saturating_accrue(T::WeightInfo::on_initialize_when_bridge_state_updated()); + weight_used + .saturating_accrue(T::WeightInfo::on_initialize_when_bridge_state_updated()); } weight_used @@ -234,9 +237,11 @@ pub mod pallet { } } - /// Stores `BridgeState` for congestion control and dynamic fees for each resolved bridge ID associated with a destination. + /// Stores `BridgeState` for congestion control and dynamic fees for each resolved bridge ID + /// associated with a destination. #[pallet::storage] - pub type Bridges, I: 'static = ()> = StorageMap<_, Blake2_128Concat, BridgeIdOf, BridgeState, OptionQuery>; + pub type Bridges, I: 'static = ()> = + StorageMap<_, Blake2_128Concat, BridgeIdOf, BridgeState, OptionQuery>; impl, I: 'static> Pallet { /// Called when new message is sent to the `dest` (queued to local outbound XCM queue). @@ -247,24 +252,27 @@ pub mod pallet { }; // handle congestion and fee factor (if detected) - let increased = Bridges::::mutate_exists(&bridge_id, |bridge_state| match bridge_state { - Some(ref mut bridge_state) if bridge_state.is_congested => { - // found congested bridge - // ok - we need to increase the fee factor, let's do that - let message_size_factor = FixedU128::from_u32(message_size.saturating_div(1024)) - .saturating_mul(MESSAGE_SIZE_FEE_BASE); - let total_factor = EXPONENTIAL_FEE_BASE.saturating_add(message_size_factor); - - let previous_factor = bridge_state.delivery_fee_factor; - bridge_state.delivery_fee_factor = bridge_state.delivery_fee_factor.saturating_mul(total_factor); - - Some((previous_factor, bridge_state.delivery_fee_factor)) - }, - _ => { - // not congested, do nothing - None - } - }); + let increased = + Bridges::::mutate_exists(&bridge_id, |bridge_state| match bridge_state { + Some(ref mut bridge_state) if bridge_state.is_congested => { + // found congested bridge + // ok - we need to increase the fee factor, let's do that + let message_size_factor = + FixedU128::from_u32(message_size.saturating_div(1024)) + .saturating_mul(MESSAGE_SIZE_FEE_BASE); + let total_factor = EXPONENTIAL_FEE_BASE.saturating_add(message_size_factor); + + let previous_factor = bridge_state.delivery_fee_factor; + bridge_state.delivery_fee_factor = + bridge_state.delivery_fee_factor.saturating_mul(total_factor); + + Some((previous_factor, bridge_state.delivery_fee_factor)) + }, + _ => { + // not congested, do nothing + None + }, + }); if let Some((previous_factor, new_factor)) = increased { log::info!( target: LOG_TARGET, @@ -278,17 +286,21 @@ pub mod pallet { previous_value: previous_factor, new_value: new_factor, bridge_id, - dest + dest, }); } } /// Calculates dynamic fees for a given asset based on the bridge state. /// - /// This function adjusts the amount of a fungible asset according to the delivery fee factor - /// specified in the `bridge_state`. If the asset is fungible, the `delivery_fee_factor` is applied - /// to the asset’s amount, potentially altering its value. - pub(crate) fn calculate_dynamic_fees_for_asset(bridge_state: &BridgeState, mut asset: Asset) -> Asset { + /// This function adjusts the amount of a fungible asset according to the delivery fee + /// factor specified in the `bridge_state`. If the asset is fungible, the + /// `delivery_fee_factor` is applied to the asset’s amount, potentially altering its + /// value. + pub(crate) fn calculate_dynamic_fees_for_asset( + bridge_state: &BridgeState, + mut asset: Asset, + ) -> Asset { if let Fungibility::Fungible(ref mut amount) = asset.fun { *amount = bridge_state.delivery_fee_factor.saturating_mul_int(*amount); } @@ -296,7 +308,9 @@ pub mod pallet { } /// Calculates an (optional) fee for message size based on `T::ByteFee` and `T::FeeAsset`. - pub(crate) fn calculate_message_size_fees(message_size: impl FnOnce() -> u32) -> Option { + pub(crate) fn calculate_message_size_fees( + message_size: impl FnOnce() -> u32, + ) -> Option { // Apply message size `T::ByteFee/T::FeeAsset` feature (if configured). if let Some(asset_id) = T::FeeAsset::get() { let message_fee = (message_size() as u128).saturating_mul(T::ByteFee::get()); @@ -309,19 +323,19 @@ pub mod pallet { /// Updates the congestion status of a bridge for a given `bridge_id`. /// /// If the bridge does not exist and: - /// - `is_congested` is true, a new `BridgeState` is created with a default `delivery_fee_factor`. + /// - `is_congested` is true, a new `BridgeState` is created with a default + /// `delivery_fee_factor`. /// - `is_congested` is false, does nothing and no `BridgeState` is created. pub(crate) fn update_bridge_status(bridge_id: BridgeIdOf, is_congested: bool) { Bridges::::mutate(bridge_id, |bridge| match bridge { Some(bridge) => bridge.is_congested = is_congested, - None => { + None => if is_congested { *bridge = Some(BridgeState { delivery_fee_factor: MINIMAL_DELIVERY_FEE_FACTOR, is_congested, }) - } - } + }, }); } } @@ -467,14 +481,20 @@ mod tests { let old_delivery_fee_factor = FixedU128::from_rational(125, 100); // make bridge congested + update fee factor - set_bridge_state_for::(&dest, Some(BridgeState { - delivery_fee_factor: old_delivery_fee_factor, - is_congested: true, - })); + set_bridge_state_for::( + &dest, + Some(BridgeState { + delivery_fee_factor: old_delivery_fee_factor, + is_congested: true, + }), + ); // it should not decrease, because queue is congested XcmBridgeHubRouter::on_initialize(One::one()); - assert_eq!(get_bridge_state_for::(&dest).unwrap().delivery_fee_factor, old_delivery_fee_factor); + assert_eq!( + get_bridge_state_for::(&dest).unwrap().delivery_fee_factor, + old_delivery_fee_factor + ); assert_eq!(System::events(), vec![]); }) @@ -487,10 +507,10 @@ mod tests { let initial_fee_factor = FixedU128::from_rational(125, 100); // make bridge uncongested + update fee factor - let bridge_id = set_bridge_state_for::(&dest, Some(BridgeState { - delivery_fee_factor: initial_fee_factor, - is_congested: false, - })); + let bridge_id = set_bridge_state_for::( + &dest, + Some(BridgeState { delivery_fee_factor: initial_fee_factor, is_congested: false }), + ); // it should eventually decrease and remove let mut last_delivery_fee_factor = initial_fee_factor; @@ -634,18 +654,19 @@ mod tests { Some(&(BridgeFeeAsset::get(), expected_fee).into()), ); - // but when factor is larger than one, it increases the fee, so it becomes: `base_cost_formula() * F` + // but when factor is larger than one, it increases the fee, so it becomes: + // `base_cost_formula() * F` let factor = FixedU128::from_rational(125, 100); // make bridge congested + update fee factor - set_bridge_state_for::(&dest, Some(BridgeState { - delivery_fee_factor: factor, - is_congested: true, - })); - - let expected_fee = (FixedU128::saturating_from_integer(base_cost_formula()) * factor) - .into_inner() / - FixedU128::DIV + HRMP_FEE; + set_bridge_state_for::( + &dest, + Some(BridgeState { delivery_fee_factor: factor, is_congested: true }), + ); + + let expected_fee = + (FixedU128::saturating_from_integer(base_cost_formula()) * factor).into_inner() / + FixedU128::DIV + HRMP_FEE; assert_eq!( XcmBridgeHubRouter::validate(&mut Some(dest), &mut Some(xcm)).unwrap().1.get(0), Some(&(BridgeFeeAsset::get(), expected_fee).into()), @@ -656,26 +677,29 @@ mod tests { #[test] fn sent_message_doesnt_increase_factor_if_bridge_is_uncongested() { run_test(|| { - let dest = Location::new(2, [GlobalConsensus(BridgedNetworkId::get()), Parachain(1000)]); + let dest = + Location::new(2, [GlobalConsensus(BridgedNetworkId::get()), Parachain(1000)]); // make bridge congested + update fee factor let old_delivery_fee_factor = FixedU128::from_rational(125, 100); - set_bridge_state_for::(&dest, Some(BridgeState { - delivery_fee_factor: old_delivery_fee_factor, - is_congested: false, - })); + set_bridge_state_for::( + &dest, + Some(BridgeState { + delivery_fee_factor: old_delivery_fee_factor, + is_congested: false, + }), + ); assert_eq!( - send_xcm::( - dest.clone(), - vec![ClearOrigin].into(), - ) - .map(drop), + send_xcm::(dest.clone(), vec![ClearOrigin].into(),).map(drop), Ok(()), ); assert!(TestToBridgeHubSender::is_message_sent()); - assert_eq!(old_delivery_fee_factor, get_bridge_state_for::(&dest).unwrap().delivery_fee_factor); + assert_eq!( + old_delivery_fee_factor, + get_bridge_state_for::(&dest).unwrap().delivery_fee_factor + ); assert_eq!(System::events(), vec![]); }); @@ -684,23 +708,28 @@ mod tests { #[test] fn sent_message_increases_factor_if_bridge_is_congested() { run_test(|| { - let dest = Location::new(2, [GlobalConsensus(BridgedNetworkId::get()), Parachain(1000)]); + let dest = + Location::new(2, [GlobalConsensus(BridgedNetworkId::get()), Parachain(1000)]); // make bridge congested + update fee factor let old_delivery_fee_factor = FixedU128::from_rational(125, 100); - set_bridge_state_for::(&dest, Some(BridgeState { - delivery_fee_factor: old_delivery_fee_factor, - is_congested: true, - })); + set_bridge_state_for::( + &dest, + Some(BridgeState { + delivery_fee_factor: old_delivery_fee_factor, + is_congested: true, + }), + ); - assert_ok!(send_xcm::( - dest.clone(), - vec![ClearOrigin].into(), - ) - .map(drop)); + assert_ok!( + send_xcm::(dest.clone(), vec![ClearOrigin].into(),).map(drop) + ); assert!(TestToBridgeHubSender::is_message_sent()); - assert!(old_delivery_fee_factor < get_bridge_state_for::(&dest).unwrap().delivery_fee_factor); + assert!( + old_delivery_fee_factor < + get_bridge_state_for::(&dest).unwrap().delivery_fee_factor + ); // check emitted event let first_system_event = System::events().first().cloned(); @@ -731,8 +760,10 @@ mod tests { #[test] fn report_bridge_status_works() { run_test(|| { - let dest = Location::new(2, [GlobalConsensus(BridgedNetworkId::get()), Parachain(1000)]); - let bridge_id = bp_xcm_bridge_hub::BridgeId::new(&UniversalLocation::get(), dest.interior()); + let dest = + Location::new(2, [GlobalConsensus(BridgedNetworkId::get()), Parachain(1000)]); + 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, @@ -747,17 +778,23 @@ mod tests { // make congested report_bridge_status(bridge_id, true); - assert_eq!(get_bridge_state_for::(&dest), Some(BridgeState { - delivery_fee_factor: MINIMAL_DELIVERY_FEE_FACTOR, - is_congested: true, - })); + assert_eq!( + get_bridge_state_for::(&dest), + Some(BridgeState { + delivery_fee_factor: MINIMAL_DELIVERY_FEE_FACTOR, + is_congested: true, + }) + ); // make uncongested report_bridge_status(bridge_id, false); - assert_eq!(get_bridge_state_for::(&dest), Some(BridgeState { - delivery_fee_factor: MINIMAL_DELIVERY_FEE_FACTOR, - is_congested: false, - })); + assert_eq!( + get_bridge_state_for::(&dest), + Some(BridgeState { + delivery_fee_factor: MINIMAL_DELIVERY_FEE_FACTOR, + is_congested: false, + }) + ); }); } } diff --git a/bridges/modules/xcm-bridge-hub-router/src/mock.rs b/bridges/modules/xcm-bridge-hub-router/src/mock.rs index 0c9c4ad74a02..68cf0356aa4e 100644 --- a/bridges/modules/xcm-bridge-hub-router/src/mock.rs +++ b/bridges/modules/xcm-bridge-hub-router/src/mock.rs @@ -18,7 +18,8 @@ use crate as pallet_xcm_bridge_hub_router; -use bp_xcm_bridge_hub_router::{ResolveBridgeId, BridgeState}; +use crate::impls::EnsureIsRemoteBridgeIdResolver; +use bp_xcm_bridge_hub_router::{BridgeState, ResolveBridgeId}; use codec::Encode; use frame_support::{ construct_runtime, derive_impl, parameter_types, @@ -31,7 +32,6 @@ use xcm::prelude::*; use xcm_builder::{ InspectMessageQueues, NetworkExportTable, NetworkExportTableItem, SovereignPaidRemoteExporter, }; -use crate::impls::EnsureIsRemoteBridgeIdResolver; type Block = frame_system::mocking::MockBlock; @@ -82,12 +82,17 @@ impl ResolveBridgeId for EveryDestinationToSameBridgeIdResolver { Some(()) } - fn resolve_for(_bridged_network: &NetworkId, _bridged_dest: &InteriorLocation) -> Option { + fn resolve_for( + _bridged_network: &NetworkId, + _bridged_dest: &InteriorLocation, + ) -> Option { Some(()) } } -/// An instance of `pallet_xcm_bridge_hub_router` configured to use a remote exporter with the `ExportMessage` instruction, which will be delivered to a sibling parachain using `SiblingBridgeHubLocation`. +/// An instance of `pallet_xcm_bridge_hub_router` configured to use a remote exporter with the +/// `ExportMessage` instruction, which will be delivered to a sibling parachain using +/// `SiblingBridgeHubLocation`. #[derive_impl(pallet_xcm_bridge_hub_router::config_preludes::TestDefaultConfig)] impl pallet_xcm_bridge_hub_router::Config<()> for TestRuntime { type DestinationVersion = @@ -99,7 +104,7 @@ impl pallet_xcm_bridge_hub_router::Config<()> for TestRuntime { (), NetworkExportTable, BridgedNetworkId, - SiblingBridgeHubLocation + SiblingBridgeHubLocation, >, TestToBridgeHubSender, UniversalLocation, @@ -195,7 +200,10 @@ pub(crate) fn fake_message_hash(message: &Xcm) -> XcmHash { message.using_encoded(sp_io::hashing::blake2_256) } -pub(crate) fn set_bridge_state_for, I: 'static>(dest: &Location, bridge_state: Option) -> pallet_xcm_bridge_hub_router::BridgeIdOf { +pub(crate) fn set_bridge_state_for, I: 'static>( + dest: &Location, + bridge_state: Option, +) -> pallet_xcm_bridge_hub_router::BridgeIdOf { let bridge_id = ::resolve_for_dest(dest).unwrap(); if let Some(bridge_state) = bridge_state { pallet_xcm_bridge_hub_router::Bridges::::insert(&bridge_id, bridge_state); @@ -205,7 +213,9 @@ pub(crate) fn set_bridge_state_for, I bridge_id } -pub(crate) fn get_bridge_state_for, I: 'static>(dest: &Location) -> Option { +pub(crate) fn get_bridge_state_for, I: 'static>( + dest: &Location, +) -> Option { let bridge_id = ::resolve_for_dest(dest).unwrap(); pallet_xcm_bridge_hub_router::Bridges::::get(bridge_id) -} \ No newline at end of file +} diff --git a/bridges/modules/xcm-bridge-hub/src/congestion.rs b/bridges/modules/xcm-bridge-hub/src/congestion.rs index 09e3e230ae6f..e1e9af3e025b 100644 --- a/bridges/modules/xcm-bridge-hub/src/congestion.rs +++ b/bridges/modules/xcm-bridge-hub/src/congestion.rs @@ -16,14 +16,13 @@ //! The module contains utilities for handling congestion between the bridge hub and routers. -use sp_std::vec::Vec; -use sp_std::marker::PhantomData; -use codec::Encode; +use crate::{Bridges, Config, DispatchChannelStatusProvider, LOG_TARGET}; use bp_xcm_bridge_hub::{BridgeId, LocalXcmChannelManager, Receiver}; +use codec::Encode; use sp_runtime::traits::Convert; +use sp_std::{marker::PhantomData, vec::Vec}; use xcm::latest::{send_xcm, Location, SendXcm, Xcm}; use xcm_builder::{DispatchBlob, DispatchBlobError}; -use crate::{Config, Bridges, LOG_TARGET, DispatchChannelStatusProvider}; /// Switches the implementation of `LocalXcmChannelManager` based on the `local_origin`. /// @@ -33,24 +32,37 @@ use crate::{Config, Bridges, LOG_TARGET, DispatchChannelStatusProvider}; /// This is useful when the `pallet-xcm-bridge-hub` needs to support both: /// - A local router deployed on the same chain as the `pallet-xcm-bridge-hub`. /// - A remote router deployed on a different chain than the `pallet-xcm-bridge-hub`. -pub struct HereOrLocalConsensusXcmChannelManager(PhantomData<(Bridge, HereXcmChannelManager, LocalConsensusXcmChannelManager)>); -impl, LocalConsensusXcmChannelManager: LocalXcmChannelManager> LocalXcmChannelManager -for HereOrLocalConsensusXcmChannelManager { - type Error = (); +pub struct HereOrLocalConsensusXcmChannelManager< + Bridge, + HereXcmChannelManager, + LocalConsensusXcmChannelManager, +>(PhantomData<(Bridge, HereXcmChannelManager, LocalConsensusXcmChannelManager)>); +impl< + Bridge: Encode + sp_std::fmt::Debug + Copy, + HereXcmChannelManager: LocalXcmChannelManager, + LocalConsensusXcmChannelManager: LocalXcmChannelManager, + > LocalXcmChannelManager + for HereOrLocalConsensusXcmChannelManager< + Bridge, + HereXcmChannelManager, + LocalConsensusXcmChannelManager, + > +{ + type Error = (); - fn suspend_bridge(local_origin: &Location, bridge: Bridge) -> Result<(), Self::Error> { - if local_origin.eq(&Location::here()) { - HereXcmChannelManager::suspend_bridge(local_origin, bridge).map_err(|e| { - log::error!( - target: LOG_TARGET, + fn suspend_bridge(local_origin: &Location, bridge: Bridge) -> Result<(), Self::Error> { + if local_origin.eq(&Location::here()) { + HereXcmChannelManager::suspend_bridge(local_origin, bridge).map_err(|e| { + log::error!( + target: LOG_TARGET, "HereXcmChannelManager::suspend_bridge error: {e:?} for local_origin: {:?} and bridge: {:?}", local_origin, bridge, ); - () - }) - } else { - LocalConsensusXcmChannelManager::suspend_bridge(local_origin, bridge).map_err(|e| { + () + }) + } else { + LocalConsensusXcmChannelManager::suspend_bridge(local_origin, bridge).map_err(|e| { log::error!( target: LOG_TARGET, "LocalConsensusXcmChannelManager::suspend_bridge error: {e:?} for local_origin: {:?} and bridge: {:?}", @@ -59,22 +71,22 @@ for HereOrLocalConsensusXcmChannelManager Result<(), Self::Error> { - if local_origin.eq(&Location::here()) { - HereXcmChannelManager::resume_bridge(local_origin, bridge).map_err(|e| { - log::error!( - target: LOG_TARGET, + fn resume_bridge(local_origin: &Location, bridge: Bridge) -> Result<(), Self::Error> { + if local_origin.eq(&Location::here()) { + HereXcmChannelManager::resume_bridge(local_origin, bridge).map_err(|e| { + log::error!( + target: LOG_TARGET, "HereXcmChannelManager::resume_bridge error: {e:?} for local_origin: {:?} and bridge: {:?}", local_origin, bridge, ); - () - }) - } else { - LocalConsensusXcmChannelManager::resume_bridge(local_origin, bridge).map_err(|e| { + () + }) + } else { + LocalConsensusXcmChannelManager::resume_bridge(local_origin, bridge).map_err(|e| { log::error!( target: LOG_TARGET, "LocalConsensusXcmChannelManager::resume_bridge error: {e:?} for local_origin: {:?} and bridge: {:?}", @@ -83,38 +95,48 @@ for HereOrLocalConsensusXcmChannelManager(PhantomData<(T, I, XcmProvider, XcmSender)>); -impl, I: 'static, XcmProvider: Convert, Xcm<()>>, XcmSender: SendXcm> ReportBridgeStatusXcmChannelManager { - fn report_bridge_status(local_origin: &Location, bridge_id: BridgeId, is_congested: bool) -> Result<(), ()> { - // check the bridge and get `maybe_notify` callback. - let bridge = Bridges::::get(&bridge_id).ok_or(())?; - let Some(Receiver { pallet_index, call_index }) = bridge.maybe_notify else { - // `local_origin` did not set `maybe_notify`, so nothing to notify, so it is ok. - return Ok(()) - }; +/// Manages the local XCM channels by sending XCM messages with the `report_bridge_status` extrinsic +/// to the `local_origin`. The `XcmProvider` type converts the encoded call to `XCM`, which is then +/// sent by `XcmSender` to the `local_origin`. This is useful, for example, when a router with +/// `ExportMessage` is deployed on a different chain, and we want to control congestion by sending +/// XCMs. +pub struct ReportBridgeStatusXcmChannelManager( + PhantomData<(T, I, XcmProvider, XcmSender)>, +); +impl, I: 'static, XcmProvider: Convert, Xcm<()>>, XcmSender: SendXcm> + ReportBridgeStatusXcmChannelManager +{ + fn report_bridge_status( + local_origin: &Location, + bridge_id: BridgeId, + is_congested: bool, + ) -> Result<(), ()> { + // check the bridge and get `maybe_notify` callback. + let bridge = Bridges::::get(&bridge_id).ok_or(())?; + let Some(Receiver { pallet_index, call_index }) = bridge.maybe_notify else { + // `local_origin` did not set `maybe_notify`, so nothing to notify, so it is ok. + return Ok(()) + }; - // constructing expected call - let remote_runtime_call = (pallet_index, call_index, bridge_id, is_congested); - // construct XCM - let xcm = XcmProvider::convert(remote_runtime_call.encode()); - log::trace!( - target: LOG_TARGET, + // constructing expected call + let remote_runtime_call = (pallet_index, call_index, bridge_id, is_congested); + // construct XCM + let xcm = XcmProvider::convert(remote_runtime_call.encode()); + log::trace!( + target: LOG_TARGET, "ReportBridgeStatusXcmChannelManager is going to send status with is_congested: {:?} to the local_origin: {:?} and bridge: {:?} as xcm: {:?}", - is_congested, + is_congested, local_origin, - bridge, - xcm, - ); + bridge, + xcm, + ); - // send XCM - send_xcm::(local_origin.clone(), xcm) + // send XCM + send_xcm::(local_origin.clone(), xcm) .map(|result| { log::warn!( target: LOG_TARGET, @@ -137,31 +159,41 @@ impl, I: 'static, XcmProvider: Convert, Xcm<()>>, XcmSender ); () }) - } + } } -impl, I: 'static, XcmProvider: Convert, Xcm<()>>, XcmSender: SendXcm> LocalXcmChannelManager for ReportBridgeStatusXcmChannelManager { - type Error = (); +impl, I: 'static, XcmProvider: Convert, Xcm<()>>, XcmSender: SendXcm> + LocalXcmChannelManager + for ReportBridgeStatusXcmChannelManager +{ + type Error = (); - fn suspend_bridge(local_origin: &Location, bridge: BridgeId) -> Result<(), Self::Error> { - Self::report_bridge_status(local_origin, bridge, true) - } + fn suspend_bridge(local_origin: &Location, bridge: BridgeId) -> Result<(), Self::Error> { + Self::report_bridge_status(local_origin, bridge, true) + } - fn resume_bridge(local_origin: &Location, bridge: BridgeId) -> Result<(), Self::Error> { - Self::report_bridge_status(local_origin, bridge, false) - } + fn resume_bridge(local_origin: &Location, bridge: BridgeId) -> Result<(), Self::Error> { + Self::report_bridge_status(local_origin, bridge, false) + } } -/// Adapter that ties together the `DispatchBlob` trait with the `DispatchChannelStatusProvider` trait. -/// The idea is that `DispatchBlob` triggers message dispatch/delivery on the receiver side, -/// while `DispatchChannelStatusProvider` provides an status check to ensure the dispatch channel is active (not congested). -pub struct BlobDispatcherWithChannelStatus(PhantomData<(ChannelDispatch, ChannelStatus)>); -impl DispatchBlob for BlobDispatcherWithChannelStatus { - fn dispatch_blob(blob: Vec) -> Result<(), DispatchBlobError> { - ChannelDispatch::dispatch_blob(blob) - } +/// Adapter that ties together the `DispatchBlob` trait with the `DispatchChannelStatusProvider` +/// trait. The idea is that `DispatchBlob` triggers message dispatch/delivery on the receiver side, +/// while `DispatchChannelStatusProvider` provides an status check to ensure the dispatch channel is +/// active (not congested). +pub struct BlobDispatcherWithChannelStatus( + PhantomData<(ChannelDispatch, ChannelStatus)>, +); +impl DispatchBlob + for BlobDispatcherWithChannelStatus +{ + fn dispatch_blob(blob: Vec) -> Result<(), DispatchBlobError> { + ChannelDispatch::dispatch_blob(blob) + } +} +impl DispatchChannelStatusProvider + for BlobDispatcherWithChannelStatus +{ + fn is_congested(with: &Location) -> bool { + ChannelStatus::is_congested(with) + } } -impl DispatchChannelStatusProvider for BlobDispatcherWithChannelStatus { - fn is_congested(with: &Location) -> bool { - ChannelStatus::is_congested(with) - } -} \ No newline at end of file diff --git a/bridges/modules/xcm-bridge-hub/src/dispatcher.rs b/bridges/modules/xcm-bridge-hub/src/dispatcher.rs index bbc9c8ae54d6..b93bd63d011b 100644 --- a/bridges/modules/xcm-bridge-hub/src/dispatcher.rs +++ b/bridges/modules/xcm-bridge-hub/src/dispatcher.rs @@ -21,7 +21,7 @@ //! //! This code is executed at the target bridge hub. -use crate::{Config, Pallet, LOG_TARGET, DispatchChannelStatusProvider}; +use crate::{Config, DispatchChannelStatusProvider, Pallet, LOG_TARGET}; use bp_messages::target_chain::{DispatchMessage, MessageDispatch}; use bp_runtime::messages::MessageDispatchResult; diff --git a/bridges/modules/xcm-bridge-hub/src/exporter.rs b/bridges/modules/xcm-bridge-hub/src/exporter.rs index 09bb1f94ac35..a89724ef3efc 100644 --- a/bridges/modules/xcm-bridge-hub/src/exporter.rs +++ b/bridges/modules/xcm-bridge-hub/src/exporter.rs @@ -365,11 +365,11 @@ mod tests { use bp_runtime::RangeInclusiveExt; use bp_xcm_bridge_hub::{Bridge, BridgeLocations, BridgeState, Receiver}; - use pallet_xcm_bridge_hub_router::ResolveBridgeId; use frame_support::{ assert_ok, traits::{Contains, EnsureOrigin}, }; + use pallet_xcm_bridge_hub_router::ResolveBridgeId; use xcm_builder::{NetworkExportTable, UnpaidRemoteExporter}; use xcm_executor::traits::export_xcm; @@ -636,13 +636,17 @@ mod tests { OpenBridgeOriginOf::::try_origin(origin.clone()).unwrap(); let (bridge, expected_lane_id) = open_lane(origin); - // we need to set `UniversalLocation` for `sibling_parachain_origin` for `XcmOverBridgeWrappedWithExportMessageRouterInstance`. + // we need to set `UniversalLocation` for `sibling_parachain_origin` for + // `XcmOverBridgeWrappedWithExportMessageRouterInstance`. ExportMessageOriginUniversalLocation::set(Some(SiblingUniversalLocation::get())); // check compatible bridge_id assert_eq!( bridge.bridge_id(), - &>::BridgeIdResolver::resolve_for_dest(&dest).unwrap() + &>::BridgeIdResolver::resolve_for_dest(&dest) + .unwrap() ); // check before - no messages @@ -699,7 +703,10 @@ mod tests { // check compatible bridge_id assert_eq!( bridge.bridge_id(), - &>::BridgeIdResolver::resolve_for_dest(&dest).unwrap() + &>::BridgeIdResolver::resolve_for_dest(&dest) + .unwrap() ); // check before - no messages @@ -828,56 +835,100 @@ mod tests { // valid routable destination let dest = Location::new(2, BridgedUniversalDestination::get()); - fn router_bridge_state, I: 'static>(dest: &Location) -> Option { - let bridge_id = ::resolve_for_dest(dest).unwrap(); + fn router_bridge_state, I: 'static>( + dest: &Location, + ) -> Option { + let bridge_id = + ::resolve_for_dest(dest).unwrap(); pallet_xcm_bridge_hub_router::Bridges::::get(&bridge_id) } // open two bridges let origin = OpenBridgeOrigin::sibling_parachain_origin(); - let origin_as_location = OpenBridgeOriginOf::::try_origin(origin.clone()).unwrap(); + let origin_as_location = + OpenBridgeOriginOf::::try_origin(origin.clone()).unwrap(); let (bridge_1, expected_lane_id_1) = open_lane(origin); let (bridge_2, expected_lane_id_2) = open_lane(RuntimeOrigin::root()); assert_ne!(expected_lane_id_1, expected_lane_id_2); assert_ne!(bridge_1.bridge_id(), bridge_2.bridge_id()); - // we need to set `UniversalLocation` for `sibling_parachain_origin` for `XcmOverBridgeWrappedWithExportMessageRouterInstance`. + // we need to set `UniversalLocation` for `sibling_parachain_origin` for + // `XcmOverBridgeWrappedWithExportMessageRouterInstance`. ExportMessageOriginUniversalLocation::set(Some(SiblingUniversalLocation::get())); - // we need to update `maybe_notify` for `bridge_1` with `pallet_index` of `XcmOverBridgeWrappedWithExportMessageRouter`, + // we need to update `maybe_notify` for `bridge_1` with `pallet_index` of + // `XcmOverBridgeWrappedWithExportMessageRouter`, Bridges::::mutate_extant(bridge_1.bridge_id(), |bridge| { bridge.maybe_notify = Some(Receiver::new(57, 0)); }); // check before // bridges are opened - assert_eq!(XcmOverBridge::bridge(bridge_1.bridge_id()).unwrap().state, BridgeState::Opened); - assert_eq!(XcmOverBridge::bridge(bridge_2.bridge_id()).unwrap().state, BridgeState::Opened); + assert_eq!( + XcmOverBridge::bridge(bridge_1.bridge_id()).unwrap().state, + BridgeState::Opened + ); + assert_eq!( + XcmOverBridge::bridge(bridge_2.bridge_id()).unwrap().state, + BridgeState::Opened + ); // both routers are uncongested - assert!(!router_bridge_state::(&dest).map(|bs| bs.is_congested).unwrap_or(false)); - assert!(!router_bridge_state::(&dest).map(|bs| bs.is_congested).unwrap_or(false)); + assert!(!router_bridge_state::< + TestRuntime, + XcmOverBridgeWrappedWithExportMessageRouterInstance, + >(&dest) + .map(|bs| bs.is_congested) + .unwrap_or(false)); + assert!(!router_bridge_state::( + &dest + ) + .map(|bs| bs.is_congested) + .unwrap_or(false)); assert!(!TestLocalXcmChannelManager::is_bridge_suspened(bridge_1.bridge_id())); assert!(!TestLocalXcmChannelManager::is_bridge_suspened(bridge_2.bridge_id())); assert!(!TestLocalXcmChannelManager::is_bridge_resumed(bridge_1.bridge_id())); assert!(!TestLocalXcmChannelManager::is_bridge_resumed(bridge_2.bridge_id())); // make bridges congested with sending too much messages - for _ in 1..(OUTBOUND_LANE_CONGESTED_THRESHOLD + 2) { + for _ in 1..(OUTBOUND_LANE_CONGESTED_THRESHOLD + 2) { // send `ExportMessage(message)` by `pallet_xcm_bridge_hub_router`. ExecuteXcmOverSendXcm::set_origin_for_execute(origin_as_location.clone()); - assert_ok!(send_xcm::(dest.clone(), Xcm::<()>::default())); + assert_ok!(send_xcm::( + dest.clone(), + Xcm::<()>::default() + )); // call direct `ExportXcm` by `pallet_xcm_bridge_hub_router`. - assert_ok!(send_xcm::(dest.clone(), Xcm::<()>::default())); + assert_ok!(send_xcm::( + dest.clone(), + Xcm::<()>::default() + )); } // checks after // bridges are suspended - assert_eq!(XcmOverBridge::bridge(bridge_1.bridge_id()).unwrap().state, BridgeState::Suspended); - assert_eq!(XcmOverBridge::bridge(bridge_2.bridge_id()).unwrap().state, BridgeState::Suspended); + assert_eq!( + XcmOverBridge::bridge(bridge_1.bridge_id()).unwrap().state, + BridgeState::Suspended + ); + assert_eq!( + XcmOverBridge::bridge(bridge_2.bridge_id()).unwrap().state, + BridgeState::Suspended + ); // both routers are congested - assert!(router_bridge_state::(&dest).unwrap().is_congested); - assert!(router_bridge_state::(&dest).unwrap().is_congested); + assert!( + router_bridge_state::< + TestRuntime, + XcmOverBridgeWrappedWithExportMessageRouterInstance, + >(&dest) + .unwrap() + .is_congested + ); + assert!( + router_bridge_state::(&dest) + .unwrap() + .is_congested + ); assert!(TestLocalXcmChannelManager::is_bridge_suspened(bridge_1.bridge_id())); assert!(TestLocalXcmChannelManager::is_bridge_suspened(bridge_2.bridge_id())); assert!(!TestLocalXcmChannelManager::is_bridge_resumed(bridge_1.bridge_id())); @@ -894,11 +945,28 @@ mod tests { ); // bridges are again opened - assert_eq!(XcmOverBridge::bridge(bridge_1.bridge_id()).unwrap().state, BridgeState::Opened); - assert_eq!(XcmOverBridge::bridge(bridge_2.bridge_id()).unwrap().state, BridgeState::Opened); + assert_eq!( + XcmOverBridge::bridge(bridge_1.bridge_id()).unwrap().state, + BridgeState::Opened + ); + assert_eq!( + XcmOverBridge::bridge(bridge_2.bridge_id()).unwrap().state, + BridgeState::Opened + ); // both routers are uncongested - assert!(!router_bridge_state::(&dest).unwrap().is_congested); - assert!(!router_bridge_state::(&dest).unwrap().is_congested); + assert!( + !router_bridge_state::< + TestRuntime, + XcmOverBridgeWrappedWithExportMessageRouterInstance, + >(&dest) + .unwrap() + .is_congested + ); + assert!( + !router_bridge_state::(&dest) + .unwrap() + .is_congested + ); assert!(TestLocalXcmChannelManager::is_bridge_resumed(bridge_1.bridge_id())); assert!(TestLocalXcmChannelManager::is_bridge_resumed(bridge_2.bridge_id())); }) diff --git a/bridges/modules/xcm-bridge-hub/src/lib.rs b/bridges/modules/xcm-bridge-hub/src/lib.rs index 75e76bd11b2b..538d0cb802be 100644 --- a/bridges/modules/xcm-bridge-hub/src/lib.rs +++ b/bridges/modules/xcm-bridge-hub/src/lib.rs @@ -147,8 +147,8 @@ use bp_messages::{LaneState, MessageNonce}; use bp_runtime::{AccountIdOf, BalanceOf, RangeInclusiveExt}; pub use bp_xcm_bridge_hub::{Bridge, BridgeId, BridgeState}; use bp_xcm_bridge_hub::{ - BridgeLocations, BridgeLocationsError, Deposit, DepositOf, LocalXcmChannelManager, - ChannelStatusProvider as DispatchChannelStatusProvider, + BridgeLocations, BridgeLocationsError, ChannelStatusProvider as DispatchChannelStatusProvider, + Deposit, DepositOf, LocalXcmChannelManager, }; use frame_support::{traits::fungible::MutateHold, DefaultNoBound}; use frame_system::Config as SystemConfig; @@ -163,9 +163,9 @@ pub use dispatcher::XcmBlobMessageDispatchResult; pub use exporter::PalletAsHaulBlobExporter; pub use pallet::*; +pub mod congestion; mod dispatcher; mod exporter; -pub mod congestion; pub mod migration; mod mock; @@ -243,7 +243,8 @@ pub mod pallet { /// For example, it is possible to make an exception for a system parachain or relay. type AllowWithoutBridgeDeposit: Contains; - /// Local XCM channel manager. Dedicated to exporting capabilities when handling congestion with the sending side. + /// Local XCM channel manager. Dedicated to exporting capabilities when handling congestion + /// with the sending side. type LocalXcmChannelManager: LocalXcmChannelManager; /// XCM-level dispatcher for inbound bridge messages. type BlobDispatcher: DispatchBlob + DispatchChannelStatusProvider; diff --git a/bridges/modules/xcm-bridge-hub/src/mock.rs b/bridges/modules/xcm-bridge-hub/src/mock.rs index 82f385d13f34..d56e30964858 100644 --- a/bridges/modules/xcm-bridge-hub/src/mock.rs +++ b/bridges/modules/xcm-bridge-hub/src/mock.rs @@ -16,9 +16,8 @@ #![cfg(test)] -use sp_std::marker::PhantomData; use crate as pallet_xcm_bridge_hub; -use pallet_xcm_bridge_hub::{congestion::{HereOrLocalConsensusXcmChannelManager, ReportBridgeStatusXcmChannelManager}}; +use crate::congestion::BlobDispatcherWithChannelStatus; use bp_messages::{ target_chain::{DispatchMessage, MessageDispatch}, ChainWithMessages, HashedLaneId, MessageNonce, @@ -28,28 +27,31 @@ use bp_xcm_bridge_hub::{BridgeId, BridgeLocations, LocalXcmChannelManager}; use codec::Encode; use frame_support::{ assert_ok, derive_impl, parameter_types, - traits::{fungible::Mutate, EitherOf, EnsureOrigin, Equals, Everything, OriginTrait}, + traits::{fungible::Mutate, EitherOf, EnsureOrigin, Equals, Everything, Get, OriginTrait}, weights::RuntimeDbWeight, }; -use frame_support::traits::Get; use frame_system::{EnsureNever, EnsureRoot, EnsureRootWithSuccess}; +use pallet_xcm_bridge_hub::congestion::{ + HereOrLocalConsensusXcmChannelManager, ReportBridgeStatusXcmChannelManager, +}; use polkadot_parachain_primitives::primitives::Sibling; use sp_core::H256; use sp_runtime::{ testing::Header as SubstrateHeader, - traits::{BlakeTwo256, ConstU32, IdentityLookup}, + traits::{BlakeTwo256, ConstU32, Convert, IdentityLookup}, AccountId32, BuildStorage, StateVersion, }; -use sp_runtime::traits::Convert; -use sp_std::cell::RefCell; +use sp_std::{cell::RefCell, marker::PhantomData}; use xcm::{latest::ROCOCO_GENESIS_HASH, prelude::*}; use xcm_builder::{ AllowUnpaidExecutionFrom, DispatchBlob, DispatchBlobError, FixedWeightBounds, InspectMessageQueues, NetworkExportTable, NetworkExportTableItem, ParentIsPreset, SiblingParachainConvertsVia, SovereignPaidRemoteExporter, UnpaidLocalExporter, }; -use xcm_executor::{traits::{ConvertLocation, ConvertOrigin}, XcmExecutor}; -use crate::congestion::BlobDispatcherWithChannelStatus; +use xcm_executor::{ + traits::{ConvertLocation, ConvertOrigin}, + XcmExecutor, +}; pub type AccountId = AccountId32; pub type Balance = u64; @@ -201,9 +203,9 @@ pub(crate) type TestLocalXcmChannelManager = TestingLocalXcmChannelManager< TestRuntime, (), ReportBridgeStatusXcmProvider, - FromBridgeHubLocationXcmSender + FromBridgeHubLocationXcmSender, >, - > + >, >; impl pallet_xcm_bridge_hub::Config for TestRuntime { @@ -248,7 +250,7 @@ impl pallet_xcm_bridge_hub_router::Config<()> for TestRuntime { (), NetworkExportTable, BridgedRelayNetwork, - BridgeHubLocation + BridgeHubLocation, >, // **Note**: The crucial part is that `ExportMessage` is processed by `XcmExecutor`, which // calls the `ExportXcm` implementation of `pallet_xcm_bridge_hub` as the @@ -257,7 +259,9 @@ impl pallet_xcm_bridge_hub_router::Config<()> for TestRuntime { ExportMessageOriginUniversalLocation, >; - type BridgeIdResolver = pallet_xcm_bridge_hub_router::impls::EnsureIsRemoteBridgeIdResolver; + type BridgeIdResolver = pallet_xcm_bridge_hub_router::impls::EnsureIsRemoteBridgeIdResolver< + ExportMessageOriginUniversalLocation, + >; // We convert to root here `BridgeHubLocationXcmOriginAsRoot` type BridgeHubOrigin = EnsureRoot; } @@ -271,7 +275,8 @@ impl pallet_xcm_bridge_hub_router::Config; - type BridgeIdResolver = pallet_xcm_bridge_hub_router::impls::EnsureIsRemoteBridgeIdResolver; + type BridgeIdResolver = + pallet_xcm_bridge_hub_router::impls::EnsureIsRemoteBridgeIdResolver; // We don't need to support here `report_bridge_status`. type BridgeHubOrigin = EnsureNever<()>; } @@ -285,7 +290,11 @@ impl ExportMessageOriginUniversalLocation { } impl Get for ExportMessageOriginUniversalLocation { fn get() -> InteriorLocation { - EXPORT_MESSAGE_ORIGIN_UNIVERSAL_LOCATION.with(|o| o.borrow().clone().expect("`EXPORT_MESSAGE_ORIGIN_UNIVERSAL_LOCATION` is not set!")) + EXPORT_MESSAGE_ORIGIN_UNIVERSAL_LOCATION.with(|o| { + o.borrow() + .clone() + .expect("`EXPORT_MESSAGE_ORIGIN_UNIVERSAL_LOCATION` is not set!") + }) } } thread_local! { @@ -483,7 +492,8 @@ pub(crate) fn fund_origin_sovereign_account( bridge_owner_account } -/// Testing wrapper implementation of `LocalXcmChannelManager`, that supports storing flags in storage to facilitate testing of `LocalXcmChannelManager` implementation. +/// Testing wrapper implementation of `LocalXcmChannelManager`, that supports storing flags in +/// storage to facilitate testing of `LocalXcmChannelManager` implementation. pub struct TestingLocalXcmChannelManager(PhantomData<(Bridge, Tested)>); impl TestingLocalXcmChannelManager { @@ -503,7 +513,9 @@ impl TestingLocalXcmChannelManager< } } -impl> LocalXcmChannelManager for TestingLocalXcmChannelManager { +impl> + LocalXcmChannelManager for TestingLocalXcmChannelManager +{ type Error = Tested::Error; fn suspend_bridge(local_origin: &Location, bridge: Bridge) -> Result<(), Self::Error> { @@ -548,7 +560,10 @@ pub struct FromBridgeHubLocationXcmSender(PhantomData); impl SendXcm for FromBridgeHubLocationXcmSender { type Ticket = Inner::Ticket; - fn validate(destination: &mut Option, message: &mut Option>) -> SendResult { + fn validate( + destination: &mut Option, + message: &mut Option>, + ) -> SendResult { Inner::validate(destination, message) } diff --git a/bridges/primitives/xcm-bridge-hub-router/src/lib.rs b/bridges/primitives/xcm-bridge-hub-router/src/lib.rs index ef58c6338f36..f2e4a794c0ad 100644 --- a/bridges/primitives/xcm-bridge-hub-router/src/lib.rs +++ b/bridges/primitives/xcm-bridge-hub-router/src/lib.rs @@ -22,7 +22,7 @@ use codec::{Decode, Encode, FullCodec, MaxEncodedLen}; use scale_info::TypeInfo; use sp_core::sp_std::fmt::Debug; use sp_runtime::{FixedU128, RuntimeDebug}; -use xcm::latest::prelude::{Location, NetworkId, InteriorLocation}; +use xcm::latest::prelude::{InteriorLocation, Location, NetworkId}; /// Current status of the bridge. #[derive(Clone, Decode, Encode, Eq, PartialEq, TypeInfo, MaxEncodedLen, RuntimeDebug)] @@ -40,8 +40,12 @@ pub trait ResolveBridgeId { /// Resolves `Self::BridgeId` for `dest`. If `None`, it means there is no supported bridge ID. fn resolve_for_dest(bridged_dest: &Location) -> Option; - /// Resolves `Self::BridgeId` for `bridged_network` and `bridged_dest`. If `None`, it means there is no supported bridge ID. - fn resolve_for(bridged_network: &NetworkId, bridged_dest: &InteriorLocation) -> Option; + /// Resolves `Self::BridgeId` for `bridged_network` and `bridged_dest`. If `None`, it means + /// there is no supported bridge ID. + fn resolve_for( + bridged_network: &NetworkId, + bridged_dest: &InteriorLocation, + ) -> Option; } /// The default implementation of `ResolveBridgeId` for `()` returns `None`. @@ -52,7 +56,10 @@ impl ResolveBridgeId for () { None } - fn resolve_for(_bridged_network: &NetworkId, _bridged_dest: &InteriorLocation) -> Option { + fn resolve_for( + _bridged_network: &NetworkId, + _bridged_dest: &InteriorLocation, + ) -> Option { None } } diff --git a/bridges/primitives/xcm-bridge-hub/src/lib.rs b/bridges/primitives/xcm-bridge-hub/src/lib.rs index 4b87c54b4298..eb2378ff23f3 100644 --- a/bridges/primitives/xcm-bridge-hub/src/lib.rs +++ b/bridges/primitives/xcm-bridge-hub/src/lib.rs @@ -180,7 +180,8 @@ pub struct Bridge { /// Mapping to the unique `LaneId`. pub lane_id: LaneId, - /// Holds data about the `bridge_origin_relative_location` where notifications can be sent for handling congestion. + /// Holds data about the `bridge_origin_relative_location` where notifications can be sent for + /// handling congestion. pub maybe_notify: Option, } @@ -198,10 +199,7 @@ pub struct Receiver { impl Receiver { /// Create a new receiver. pub fn new(pallet_index: u8, call_index: u8) -> Self { - Self { - pallet_index, - call_index, - } + Self { pallet_index, call_index } } } diff --git a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs index 48fd48766d70..c333d85e7e75 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs @@ -62,12 +62,12 @@ use frame_support::{ ord_parameter_types, parameter_types, traits::{ fungible, fungibles, tokens::imbalance::ResolveAssetTo, AsEnsureOriginWithArg, ConstBool, - ConstU128, ConstU32, ConstU64, ConstU8, EitherOfDiverse, InstanceFilter, TransformOrigin, + ConstU128, ConstU32, ConstU64, ConstU8, EitherOfDiverse, Equals, InstanceFilter, + TransformOrigin, }, weights::{ConstantMultiplier, Weight, WeightToFee as _}, BoundedVec, PalletId, }; -use frame_support::traits::Equals; use frame_system::{ limits::{BlockLength, BlockWeights}, EnsureRoot, EnsureSigned, EnsureSignedBy, @@ -940,16 +940,20 @@ impl pallet_xcm_bridge_hub_router::Config for Runtim ToWestendXcmRouterInstance, NetworkExportTable, xcm_config::bridging::to_westend::WestendNetwork, - xcm_config::bridging::SiblingBridgeHub + xcm_config::bridging::SiblingBridgeHub, >, XcmpQueue, xcm_config::UniversalLocation, >; - // 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; + // 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>>; + type BridgeHubOrigin = + AsEnsureOriginWithArg>>; // For adding message size fees type ByteFee = xcm_config::bridging::XcmBridgeHubRouterByteFee; diff --git a/cumulus/parachains/runtimes/assets/asset-hub-rococo/tests/tests.rs b/cumulus/parachains/runtimes/assets/asset-hub-rococo/tests/tests.rs index d75c174ded86..b23f8811408c 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-rococo/tests/tests.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-rococo/tests/tests.rs @@ -17,11 +17,18 @@ //! Tests for the Rococo Assets Hub chain. -use asset_hub_rococo_runtime::{xcm_config, xcm_config::{ - bridging, AssetFeeAsExistentialDepositMultiplierFeeCharger, CheckingAccount, - ForeignAssetFeeAsExistentialDepositMultiplierFeeCharger, LocationToAccountId, StakingPot, - TokenLocation, TrustBackedAssetsPalletLocation, XcmConfig, -}, AllPalletsWithoutSystem, AssetConversion, AssetDeposit, Assets, Balances, CollatorSelection, ExistentialDeposit, ForeignAssets, ForeignAssetsInstance, MetadataDepositBase, MetadataDepositPerByte, ParachainSystem, Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin, SessionKeys, ToWestendXcmRouterInstance, TrustBackedAssetsInstance, XcmpQueue}; +use asset_hub_rococo_runtime::{ + xcm_config, + xcm_config::{ + bridging, AssetFeeAsExistentialDepositMultiplierFeeCharger, CheckingAccount, + ForeignAssetFeeAsExistentialDepositMultiplierFeeCharger, LocationToAccountId, StakingPot, + TokenLocation, TrustBackedAssetsPalletLocation, XcmConfig, + }, + AllPalletsWithoutSystem, AssetConversion, AssetDeposit, Assets, Balances, CollatorSelection, + ExistentialDeposit, ForeignAssets, ForeignAssetsInstance, MetadataDepositBase, + MetadataDepositPerByte, ParachainSystem, Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin, + SessionKeys, ToWestendXcmRouterInstance, TrustBackedAssetsInstance, XcmpQueue, +}; use asset_test_utils::{ test_cases_over_bridge::TestBridgingConfig, CollatorSessionKey, CollatorSessionKeys, ExtBuilder, SlotDurations, @@ -1273,30 +1280,26 @@ mod asset_hub_rococo_tests { XcmConfig, LocationToAccountId, ToWestendXcmRouterInstance, - >( - collator_session_keys(), - bridging_to_asset_hub_westend, - |bridge_id, is_congested| { - vec![ - UnpaidExecution { weight_limit: Unlimited, check_origin: None }, - Transact { - origin_kind: OriginKind::Xcm, - require_weight_at_most: + >(collator_session_keys(), bridging_to_asset_hub_westend, |bridge_id, is_congested| { + vec![ + UnpaidExecution { weight_limit: Unlimited, check_origin: None }, + Transact { + origin_kind: OriginKind::Xcm, + require_weight_at_most: bp_bridge_hub_rococo::XcmBridgeHubRouterTransactCallMaxWeight::get(), - call: RuntimeCall::ToWestendXcmRouter( - pallet_xcm_bridge_hub_router::Call::report_bridge_status { - bridge_id, - is_congested, - }, - ) - .encode() - .into(), - }, - ExpectTransactStatus(MaybeErrorCode::Success) - ] - .into() - }, - ) + call: RuntimeCall::ToWestendXcmRouter( + pallet_xcm_bridge_hub_router::Call::report_bridge_status { + bridge_id, + is_congested, + }, + ) + .encode() + .into(), + }, + ExpectTransactStatus(MaybeErrorCode::Success), + ] + .into() + }) } } diff --git a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs index 90f18167ddcd..1002d8beba35 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs @@ -938,16 +938,20 @@ impl pallet_xcm_bridge_hub_router::Config for Runtime ToRococoXcmRouterInstance, NetworkExportTable, xcm_config::bridging::to_rococo::RococoNetwork, - xcm_config::bridging::SiblingBridgeHub + xcm_config::bridging::SiblingBridgeHub, >, XcmpQueue, xcm_config::UniversalLocation, >; - // 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; + // 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>>; + type BridgeHubOrigin = + AsEnsureOriginWithArg>>; // For adding message size fees type ByteFee = xcm_config::bridging::XcmBridgeHubRouterByteFee; diff --git a/cumulus/parachains/runtimes/assets/asset-hub-westend/tests/tests.rs b/cumulus/parachains/runtimes/assets/asset-hub-westend/tests/tests.rs index edd5b7d8d253..3d33b4a7170d 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-westend/tests/tests.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-westend/tests/tests.rs @@ -17,11 +17,18 @@ //! Tests for the Westmint (Westend Assets Hub) chain. -use asset_hub_westend_runtime::{xcm_config, xcm_config::{ - bridging, AssetFeeAsExistentialDepositMultiplierFeeCharger, CheckingAccount, - ForeignAssetFeeAsExistentialDepositMultiplierFeeCharger, LocationToAccountId, StakingPot, - TrustBackedAssetsPalletLocation, WestendLocation, XcmConfig, -}, AllPalletsWithoutSystem, Assets, Balances, ExistentialDeposit, ForeignAssets, ForeignAssetsInstance, MetadataDepositBase, MetadataDepositPerByte, ParachainSystem, PolkadotXcm, Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin, SessionKeys, ToRococoXcmRouterInstance, TrustBackedAssetsInstance, XcmpQueue}; +use asset_hub_westend_runtime::{ + xcm_config, + xcm_config::{ + bridging, AssetFeeAsExistentialDepositMultiplierFeeCharger, CheckingAccount, + ForeignAssetFeeAsExistentialDepositMultiplierFeeCharger, LocationToAccountId, StakingPot, + TrustBackedAssetsPalletLocation, WestendLocation, XcmConfig, + }, + AllPalletsWithoutSystem, Assets, Balances, ExistentialDeposit, ForeignAssets, + ForeignAssetsInstance, MetadataDepositBase, MetadataDepositPerByte, ParachainSystem, + PolkadotXcm, Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin, SessionKeys, + ToRococoXcmRouterInstance, TrustBackedAssetsInstance, XcmpQueue, +}; pub use asset_hub_westend_runtime::{AssetConversion, AssetDeposit, CollatorSelection, System}; use asset_test_utils::{ test_cases_over_bridge::TestBridgingConfig, CollatorSessionKey, CollatorSessionKeys, @@ -1251,30 +1258,26 @@ fn report_bridge_status_from_xcm_bridge_router_for_rococo_works() { XcmConfig, LocationToAccountId, ToRococoXcmRouterInstance, - >( - collator_session_keys(), - bridging_to_asset_hub_rococo, - |bridge_id, is_congested| { - vec![ - UnpaidExecution { weight_limit: Unlimited, check_origin: None }, - Transact { - origin_kind: OriginKind::Xcm, - require_weight_at_most: + >(collator_session_keys(), bridging_to_asset_hub_rococo, |bridge_id, is_congested| { + vec![ + UnpaidExecution { weight_limit: Unlimited, check_origin: None }, + Transact { + origin_kind: OriginKind::Xcm, + require_weight_at_most: bp_bridge_hub_rococo::XcmBridgeHubRouterTransactCallMaxWeight::get(), - call: RuntimeCall::ToRococoXcmRouter( - pallet_xcm_bridge_hub_router::Call::report_bridge_status { - bridge_id, - is_congested, - }, - ) - .encode() - .into(), - }, - ExpectTransactStatus(MaybeErrorCode::Success) - ] - .into() - }, - ) + call: RuntimeCall::ToRococoXcmRouter( + pallet_xcm_bridge_hub_router::Call::report_bridge_status { + bridge_id, + is_congested, + }, + ) + .encode() + .into(), + }, + ExpectTransactStatus(MaybeErrorCode::Success), + ] + .into() + }) } #[test] diff --git a/cumulus/parachains/runtimes/assets/test-utils/src/test_cases_over_bridge.rs b/cumulus/parachains/runtimes/assets/test-utils/src/test_cases_over_bridge.rs index 3ad788c74163..14470c5d49a9 100644 --- a/cumulus/parachains/runtimes/assets/test-utils/src/test_cases_over_bridge.rs +++ b/cumulus/parachains/runtimes/assets/test-utils/src/test_cases_over_bridge.rs @@ -498,7 +498,10 @@ pub fn report_bridge_status_from_xcm_bridge_router_works< >( collator_session_keys: CollatorSessionKeys, prepare_configuration: fn() -> TestBridgingConfig, - congestion_message: fn(pallet_xcm_bridge_hub_router::BridgeIdOf, bool) -> Xcm, + congestion_message: fn( + pallet_xcm_bridge_hub_router::BridgeIdOf, + bool, + ) -> Xcm, ) where Runtime: frame_system::Config + pallet_balances::Config @@ -533,14 +536,23 @@ pub fn report_bridge_status_from_xcm_bridge_router_works< .execute_with(|| { let report_bridge_status = |is_congested: bool| { // prepare bridge config - let TestBridgingConfig { local_bridge_hub_location, bridged_target_location, .. } = prepare_configuration(); - + let TestBridgingConfig { + local_bridge_hub_location, bridged_target_location, .. + } = prepare_configuration(); use pallet_xcm_bridge_hub_router::ResolveBridgeId; - let bridge_id = <>::BridgeIdResolver>::resolve_for_dest(&bridged_target_location).expect("resolved BridgeId"); + let bridge_id = <>::BridgeIdResolver>::resolve_for_dest( + &bridged_target_location + ) + .expect("resolved BridgeId"); // check before - let bridge_state = pallet_xcm_bridge_hub_router::Bridges::::get(&bridge_id); + let bridge_state = pallet_xcm_bridge_hub_router::Bridges::< + Runtime, + XcmBridgeHubRouterInstance, + >::get(&bridge_id); let is_congested_before = bridge_state.map(|bs| bs.is_congested).unwrap_or(false); // Call received XCM execution @@ -560,13 +572,13 @@ pub fn report_bridge_status_from_xcm_bridge_router_works< assert_ok!(outcome.ensure_complete()); // check after - let bridge_state = pallet_xcm_bridge_hub_router::Bridges::::get(&bridge_id); + let bridge_state = pallet_xcm_bridge_hub_router::Bridges::< + Runtime, + XcmBridgeHubRouterInstance, + >::get(&bridge_id); let is_congested_after = bridge_state.map(|bs| bs.is_congested).unwrap_or(false); assert_eq!(is_congested_after, is_congested); - assert_ne!( - is_congested_after, - is_congested_before, - ); + assert_ne!(is_congested_after, is_congested_before,); }; report_bridge_status(true); diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_bulletin_config.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_bulletin_config.rs index ade0bfd63b18..fa7ef0a55093 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_bulletin_config.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_bulletin_config.rs @@ -40,8 +40,7 @@ use pallet_bridge_messages::LaneIdOf; use pallet_bridge_relayers::extension::{ BridgeRelayersTransactionExtension, WithMessagesExtensionConfig, }; -use pallet_xcm_bridge_hub::congestion::BlobDispatcherWithChannelStatus; -use pallet_xcm_bridge_hub::XcmAsPlainPayload; +use pallet_xcm_bridge_hub::{congestion::BlobDispatcherWithChannelStatus, XcmAsPlainPayload}; use polkadot_parachain_primitives::primitives::Sibling; use testnet_parachains_constants::rococo::currency::UNITS as ROC; use xcm::{ @@ -153,7 +152,11 @@ impl pallet_xcm_bridge_hub::Config for Runtime // Dispatching inbound messages from the bridge. type BlobDispatcher = BlobDispatcherWithChannelStatus< // Dispatches received XCM messages from other bridge - BridgeBlobDispatcher, + BridgeBlobDispatcher< + XcmRouter, + UniversalLocation, + BridgeRococoToRococoBulletinMessagesPalletInstance, + >, // no congestion checking (), >; diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_westend_config.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_westend_config.rs index 9a3fd1587d80..395baeec3d73 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_westend_config.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_westend_config.rs @@ -40,7 +40,9 @@ use pallet_bridge_messages::LaneIdOf; use pallet_bridge_relayers::extension::{ BridgeRelayersTransactionExtension, WithMessagesExtensionConfig, }; -use pallet_xcm_bridge_hub::congestion::{BlobDispatcherWithChannelStatus, ReportBridgeStatusXcmChannelManager}; +use pallet_xcm_bridge_hub::congestion::{ + BlobDispatcherWithChannelStatus, ReportBridgeStatusXcmChannelManager, +}; use parachains_common::xcm_config::{AllSiblingSystemParachains, RelayOrOtherSystemParachains}; use polkadot_parachain_primitives::primitives::Sibling; use sp_runtime::traits::Convert; @@ -135,7 +137,8 @@ impl Convert, Xcm<()>> for ReportBridgeStatusXcmProvider { UnpaidExecution { weight_limit: Unlimited, check_origin: None }, Transact { origin_kind: OriginKind::Xcm, - require_weight_at_most: bp_bridge_hub_rococo::XcmBridgeHubRouterTransactCallMaxWeight::get(), + require_weight_at_most: + bp_bridge_hub_rococo::XcmBridgeHubRouterTransactCallMaxWeight::get(), call: encoded_call.into(), }, ExpectTransactStatus(MaybeErrorCode::Success), @@ -171,14 +174,26 @@ impl pallet_xcm_bridge_hub::Config for Runtime type AllowWithoutBridgeDeposit = RelayOrOtherSystemParachains; - // This pallet is deployed on BH, so we expect a remote router with `ExportMessage`. We handle congestion with XCM using `report_bridge_status` sent to the sending chain. - // (congestion with local sending chain) - type LocalXcmChannelManager = ReportBridgeStatusXcmChannelManager; - // Dispatching inbound messages from the bridge and managing congestion with the local receiving/destination chain + // This pallet is deployed on BH, so we expect a remote router with `ExportMessage`. We handle + // congestion with XCM using `report_bridge_status` sent to the sending chain. (congestion with + // local sending chain) + type LocalXcmChannelManager = ReportBridgeStatusXcmChannelManager< + Runtime, + XcmOverBridgeHubWestendInstance, + ReportBridgeStatusXcmProvider, + XcmRouter, + >; + // Dispatching inbound messages from the bridge and managing congestion with the local + // receiving/destination chain type BlobDispatcher = BlobDispatcherWithChannelStatus< // Dispatches received XCM messages from other bridge - BridgeBlobDispatcher, - // Provides the status of the XCMP queue's outbound queue, indicating whether messages can be dispatched to the sibling. + BridgeBlobDispatcher< + XcmRouter, + UniversalLocation, + BridgeRococoToWestendMessagesPalletInstance, + >, + // Provides the status of the XCMP queue's outbound queue, indicating whether messages can + // be dispatched to the sibling. cumulus_pallet_xcmp_queue::bridging::OutXcmpChannelStatusProvider, >; } diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/bridge_to_rococo_config.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/bridge_to_rococo_config.rs index d46ba1e08ef0..70b5ffc5115a 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/bridge_to_rococo_config.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/bridge_to_rococo_config.rs @@ -41,7 +41,9 @@ use pallet_bridge_messages::LaneIdOf; use pallet_bridge_relayers::extension::{ BridgeRelayersTransactionExtension, WithMessagesExtensionConfig, }; -use pallet_xcm_bridge_hub::congestion::{BlobDispatcherWithChannelStatus, ReportBridgeStatusXcmChannelManager}; +use pallet_xcm_bridge_hub::congestion::{ + BlobDispatcherWithChannelStatus, ReportBridgeStatusXcmChannelManager, +}; use parachains_common::xcm_config::{AllSiblingSystemParachains, RelayOrOtherSystemParachains}; use polkadot_parachain_primitives::primitives::Sibling; use sp_runtime::traits::Convert; @@ -166,7 +168,8 @@ impl Convert, Xcm<()>> for ReportBridgeStatusXcmProvider { UnpaidExecution { weight_limit: Unlimited, check_origin: None }, Transact { origin_kind: OriginKind::Xcm, - require_weight_at_most: bp_bridge_hub_westend::XcmBridgeHubRouterTransactCallMaxWeight::get(), + require_weight_at_most: + bp_bridge_hub_westend::XcmBridgeHubRouterTransactCallMaxWeight::get(), call: encoded_call.into(), }, ExpectTransactStatus(MaybeErrorCode::Success), @@ -200,14 +203,26 @@ impl pallet_xcm_bridge_hub::Config for Runtime { type AllowWithoutBridgeDeposit = RelayOrOtherSystemParachains; - // This pallet is deployed on BH, so we expect a remote router with `ExportMessage`. We handle congestion with XCM using `report_bridge_status` sent to the sending chain. - // (congestion with local sending chain) - type LocalXcmChannelManager = ReportBridgeStatusXcmChannelManager; - // Dispatching inbound messages from the bridge and managing congestion with the local receiving/destination chain + // This pallet is deployed on BH, so we expect a remote router with `ExportMessage`. We handle + // congestion with XCM using `report_bridge_status` sent to the sending chain. (congestion with + // local sending chain) + type LocalXcmChannelManager = ReportBridgeStatusXcmChannelManager< + Runtime, + XcmOverBridgeHubRococoInstance, + ReportBridgeStatusXcmProvider, + XcmRouter, + >; + // Dispatching inbound messages from the bridge and managing congestion with the local + // receiving/destination chain type BlobDispatcher = BlobDispatcherWithChannelStatus< // Dispatches received XCM messages from other bridge - BridgeBlobDispatcher, - // Provides the status of the XCMP queue's outbound queue, indicating whether messages can be dispatched to the sibling. + BridgeBlobDispatcher< + XcmRouter, + UniversalLocation, + BridgeWestendToRococoMessagesPalletInstance, + >, + // Provides the status of the XCMP queue's outbound queue, indicating whether messages can + // be dispatched to the sibling. cumulus_pallet_xcmp_queue::bridging::OutXcmpChannelStatusProvider, >; } From 5e28b0dec40c370fda2cb7869e4555119c45deae Mon Sep 17 00:00:00 2001 From: Branislav Kontur Date: Wed, 6 Nov 2024 14:24:30 +0100 Subject: [PATCH 22/72] Add `maybe_notify` callback for congestion WIP --- .../xcm-bridge-hub-router/src/impls.rs | 49 ++++++++++++++++++- .../modules/xcm-bridge-hub-router/src/lib.rs | 38 ++++++++++---- .../modules/xcm-bridge-hub/src/exporter.rs | 2 +- bridges/modules/xcm-bridge-hub/src/lib.rs | 42 ++++++++++++---- .../modules/xcm-bridge-hub/src/migration.rs | 13 +++-- bridges/modules/xcm-bridge-hub/src/mock.rs | 9 +++- .../xcm-bridge-hub/src/call_info.rs | 3 ++ bridges/primitives/xcm-bridge-hub/src/lib.rs | 2 +- .../bridges/bridge-hub-rococo/src/genesis.rs | 1 + .../bridges/bridge-hub-westend/src/genesis.rs | 1 + .../emulated/common/src/impls.rs | 8 +-- .../bridge-hub-rococo/src/tests/mod.rs | 2 + .../bridge-hub-westend/src/tests/mod.rs | 2 + .../src/bridge_to_bulletin_config.rs | 1 + .../src/bridge_to_westend_config.rs | 1 + .../src/genesis_config_presets.rs | 3 +- .../bridge-hub-rococo/tests/tests.rs | 12 ++--- .../src/genesis_config_presets.rs | 3 +- .../bridge-hub-westend/tests/tests.rs | 6 +-- .../test-utils/src/test_cases/helpers.rs | 5 +- 20 files changed, 158 insertions(+), 45 deletions(-) diff --git a/bridges/modules/xcm-bridge-hub-router/src/impls.rs b/bridges/modules/xcm-bridge-hub-router/src/impls.rs index 37429a5f05d1..789f445d8aa4 100644 --- a/bridges/modules/xcm-bridge-hub-router/src/impls.rs +++ b/bridges/modules/xcm-bridge-hub-router/src/impls.rs @@ -68,8 +68,9 @@ impl, I: 'static> bp_xcm_bridge_hub::LocalXcmChannelManager(PhantomData<(T, I, E, BNF, BHLF)>); - impl, I: 'static, E, BridgedNetworkIdFilter, BridgeHubLocationFilter> ExporterFor for ViaRemoteBridgeHubExporter where @@ -187,6 +188,50 @@ where } } +/// Adapter implementation for `SendXcm` that allows adding a message size fee and/or dynamic fees based on the `BridgeId` resolved by the `T::BridgeIdResolver` resolver, +/// if and only if `E` supports routing. +/// This adapter can be used, for example, as a wrapper over `UnpaidLocalExporter`, enabling it to compute message and/or dynamic fees using a fee factor. +pub struct ViaLocalBridgeHubExporter(PhantomData<(T, I, E)>); +impl, I: 'static, E: SendXcm> SendXcm for ViaLocalBridgeHubExporter { + type Ticket = E::Ticket; + + fn validate(destination: &mut Option, message: &mut Option>) -> SendResult { + let dest_clone = destination.clone().ok_or(SendError::MissingArgument)?; + let message_size = message.as_ref().map_or(0, |message|message.encoded_size()) as _; + + match E::validate(destination, message) { + Ok((ticket, mut fees)) => { + // calculate message size fees (if configured) + let maybe_message_size_fees = Pallet::::calculate_message_size_fees(|| message_size); + if let Some(message_size_fees) = maybe_message_size_fees { + fees.push(message_size_fees); + } + + // Here, we have the actual result fees covering bridge fees, so now we need to check/apply + // the congestion and dynamic_fees features (if possible). + if let Some(bridge_id) = T::BridgeIdResolver::resolve_for_dest(&dest_clone) { + if let Some(bridge_state) = Bridges::::get(bridge_id) { + let mut dynamic_fees = sp_std::vec::Vec::with_capacity(fees.len()); + for fee in fees.into_inner() { + dynamic_fees.push(Pallet::::calculate_dynamic_fees_for_asset(&bridge_state, fee)); + } + fees = Assets::from(dynamic_fees); + } + } + + // return original ticket with possibly extended fees + Ok((ticket, fees)) + } + e => e + } + } + + fn deliver(ticket: Self::Ticket) -> Result { + E::deliver(ticket) + } +} + + /// Implementation of `ResolveBridgeId` returning `bp_xcm_bridge_hub::BridgeId` based on the /// configured `UniversalLocation` and remote universal location. pub struct EnsureIsRemoteBridgeIdResolver(PhantomData); @@ -224,7 +269,7 @@ impl> ResolveBridgeId } } else { // if `bridged_dest` does not contain `GlobalConsensus`, let's prepend one - match bridged_dest.clone().pushed_front_with(bridged_network.clone()) { + match bridged_dest.clone().pushed_front_with(*bridged_network) { Ok(bridged_universal_location) => bridged_universal_location, Err((original, prepend_with)) => { log::error!( diff --git a/bridges/modules/xcm-bridge-hub-router/src/lib.rs b/bridges/modules/xcm-bridge-hub-router/src/lib.rs index 70f9737059d4..e32aac3c4aa8 100644 --- a/bridges/modules/xcm-bridge-hub-router/src/lib.rs +++ b/bridges/modules/xcm-bridge-hub-router/src/lib.rs @@ -14,18 +14,36 @@ // You should have received a copy of the GNU General Public License // along with Parity Bridges Common. If not, see . -//! A pallet that can be used instead of `SovereignPaidRemoteExporter` (or others) in the XCM router -//! configuration. The main feature this pallet offers is a dynamic message fee, -//! which is computed based on the state of the bridge queues. The fee increases exponentially -//! if the queue between this chain and the sibling or child bridge hub becomes congested. +//! A pallet that can be used as an alternative in the XCM router configuration — see the `SendXcm` implementation for details. //! -//! All other bridge hub queues offer backpressure mechanisms, so if any of these -//! queues are congested, it will eventually lead to increased queuing on this chain. +//! ## Features //! -//! **Note on Terminology**: When we refer to the bridge hub here, we mean the chain that -//! has the `pallet-bridge-messages` with an `ExportXcm` implementation deployed, e.g., provided by -//! `pallet-xcm-bridge-hub`. Depending on the deployment setup, `T::ToBridgeHubSender` can be -//! configured accordingly - see `T::ToBridgeHubSender` for more documentation. +//! This pallet offers several optional features to customize functionality: +//! +//! ### Message Size Fee +//! An optional fee based on `T::FeeAsset` and `T::ByteFee`. If `T::FeeAsset` is not specified, this fee is not calculated. +//! +//! ### Dynamic Fees and Congestion +//! +//! This pallet supports storing the congestion status of bridge outbound queues. The fee increases exponentially if the queue between this chain and a sibling or child bridge hub becomes congested. All other bridge hub queues provide backpressure mechanisms, so if any of these queues are congested, it will eventually lead to increased queuing on this chain. +//! +//! There are two methods for storing congestion status: +//! 1. A dedicated extrinsic `report_bridge_status`, which relies on `T::BridgeHubOrigin`. This allows the message exporter to send, for example, an XCM `Transact`. +//! 2. An implementation of `bp_xcm_bridge_hub::LocalXcmChannelManager`. +//! +//! ## Usage +//! +//! This pallet provides several implementations, such as `ViaLocalBridgeHubExporter` and `ViaRemoteBridgeHubExporter`, which can expose or access these features. +//! +//! This router can be used in two main scenarios, depending on where the router and message exporter (e.g., `pallet_xcm_bridge_hub` or another pallet with an `ExportXcm` implementation) are deployed: +//! +//! ### On the Same Chain as the Message Exporter +//! In this setup, the router directly calls an `ExportXcm` implementation. In this case, `ViaLocalBridgeHubExporter` can be used as a wrapper with `T::ToBridgeHubSender`. +//! +//! ### On a Different Chain than the Message Exporter +//! In this setup, we need to provide a `SendXcm` implementation for `T::ToBridgeHubSender`, which sends `ExportMessage`. For example, `SovereignPaidRemoteExporter` can be used with `ViaRemoteBridgeHubExporter`. +//! +//! **Note on Terminology**: When we refer to the bridge hub, we mean the chain that has the `pallet-bridge-messages` with an `ExportXcm` implementation deployed, such as `pallet-xcm-bridge-hub`. Depending on the deployment setup, `T::ToBridgeHubSender` can be configured accordingly—see `T::ToBridgeHubSender` for additional documentation. #![cfg_attr(not(feature = "std"), no_std)] diff --git a/bridges/modules/xcm-bridge-hub/src/exporter.rs b/bridges/modules/xcm-bridge-hub/src/exporter.rs index a89724ef3efc..61eb2858fd63 100644 --- a/bridges/modules/xcm-bridge-hub/src/exporter.rs +++ b/bridges/modules/xcm-bridge-hub/src/exporter.rs @@ -405,7 +405,7 @@ mod tests { } // open bridge - assert_ok!(XcmOverBridge::do_open_bridge(locations.clone(), lane_id, true)); + assert_ok!(XcmOverBridge::do_open_bridge(locations.clone(), lane_id, true, None)); } assert_ok!(XcmOverBridge::do_try_state()); diff --git a/bridges/modules/xcm-bridge-hub/src/lib.rs b/bridges/modules/xcm-bridge-hub/src/lib.rs index 538d0cb802be..612c9476abc1 100644 --- a/bridges/modules/xcm-bridge-hub/src/lib.rs +++ b/bridges/modules/xcm-bridge-hub/src/lib.rs @@ -145,7 +145,7 @@ use bp_messages::{LaneState, MessageNonce}; use bp_runtime::{AccountIdOf, BalanceOf, RangeInclusiveExt}; -pub use bp_xcm_bridge_hub::{Bridge, BridgeId, BridgeState}; +pub use bp_xcm_bridge_hub::{Bridge, BridgeId, BridgeState, Receiver}; use bp_xcm_bridge_hub::{ BridgeLocations, BridgeLocationsError, ChannelStatusProvider as DispatchChannelStatusProvider, Deposit, DepositOf, LocalXcmChannelManager, @@ -295,11 +295,15 @@ pub mod pallet { /// /// The states after this call: bridge is `Opened`, outbound lane is `Opened`, inbound lane /// is `Opened`. + /// + /// Optional `maybe_notify` holds data about the `bridge_origin_relative_location` where notifications can be sent to + /// handle congestion. The notification contains an encoded tuple `(BridgeId, bool)`, where `bool` is the `is_congested` flag. #[pallet::call_index(0)] - #[pallet::weight(Weight::zero())] // TODO:(bridges-v2) - https://github.com/paritytech/parity-bridges-common/issues/3046 - add benchmarks impl + #[pallet::weight(Weight::zero())] // TODO:(bridges-v2) - https://github.com/paritytech/parity-bridges-common/issues/3046 - add benchmarks impl FAIL-CI pub fn open_bridge( origin: OriginFor, bridge_destination_universal_location: Box, + maybe_notify: Option, ) -> DispatchResult { // check and compute required bridge locations and laneId let xcm_version = bridge_destination_universal_location.identify_version(); @@ -313,7 +317,7 @@ pub mod pallet { Error::::BridgeLocations(e) })?; - Self::do_open_bridge(locations, lane_id, true) + Self::do_open_bridge(locations, lane_id, true, maybe_notify) } /// Try to close the bridge. @@ -334,7 +338,7 @@ pub mod pallet { /// The states after this call: everything is either `Closed`, or purged from the /// runtime storage. #[pallet::call_index(1)] - #[pallet::weight(Weight::zero())] // TODO:(bridges-v2) - https://github.com/paritytech/parity-bridges-common/issues/3046 - add benchmarks impl + #[pallet::weight(Weight::zero())] // TODO:(bridges-v2) - https://github.com/paritytech/parity-bridges-common/issues/3046 - add benchmarks impl FAIL-CI pub fn close_bridge( origin: OriginFor, bridge_destination_universal_location: Box, @@ -464,6 +468,7 @@ pub mod pallet { locations: Box, lane_id: T::LaneId, create_lanes: bool, + maybe_notify: Option, ) -> Result<(), DispatchError> { // reserve balance (if needed) let deposit = if T::AllowWithoutBridgeDeposit::contains( @@ -513,7 +518,7 @@ pub mod pallet { state: BridgeState::Opened, deposit: deposit.clone(), lane_id, - maybe_notify: None, + maybe_notify, }); Ok(()) }, @@ -742,7 +747,7 @@ pub mod pallet { /// Keep in mind that we are **NOT** reserving any amount for the bridges opened at /// genesis. We are **NOT** opening lanes, used by this bridge. It all must be done using /// other pallets genesis configuration or some other means. - pub opened_bridges: Vec<(Location, InteriorLocation, Option)>, + pub opened_bridges: Vec<(Location, InteriorLocation, Option, Option)>, /// Dummy marker. #[serde(skip)] pub _phantom: sp_std::marker::PhantomData<(T, I)>, @@ -758,6 +763,7 @@ pub mod pallet { bridge_origin_relative_location, bridge_destination_universal_location, maybe_lane_id, + maybe_notify, ) in &self.opened_bridges { let locations = Pallet::::bridge_locations( @@ -772,7 +778,7 @@ pub mod pallet { locations.calculate_lane_id(xcm::latest::VERSION).expect("Valid locations"), }; - Pallet::::do_open_bridge(locations, lane_id, true) + Pallet::::do_open_bridge(locations, lane_id, true, maybe_notify.clone()) .expect("Valid opened bridge!"); } } @@ -919,6 +925,7 @@ mod tests { XcmOverBridge::open_bridge( OpenBridgeOrigin::disallowed_origin(), Box::new(bridged_asset_hub_universal_location().into()), + None, ), sp_runtime::DispatchError::BadOrigin, ); @@ -932,6 +939,7 @@ mod tests { XcmOverBridge::open_bridge( OpenBridgeOrigin::parent_relay_chain_universal_origin(), Box::new(bridged_asset_hub_universal_location().into()), + None, ), Error::::BridgeLocations( BridgeLocationsError::InvalidBridgeOrigin @@ -942,6 +950,7 @@ mod tests { XcmOverBridge::open_bridge( OpenBridgeOrigin::sibling_parachain_universal_origin(), Box::new(bridged_asset_hub_universal_location().into()), + None, ), Error::::BridgeLocations( BridgeLocationsError::InvalidBridgeOrigin @@ -960,6 +969,7 @@ mod tests { [GlobalConsensus(RelayNetwork::get()), Parachain(BRIDGED_ASSET_HUB_ID)] .into() ), + None, ), Error::::BridgeLocations(BridgeLocationsError::DestinationIsLocal), ); @@ -979,6 +989,7 @@ mod tests { ] .into() ), + None, ), Error::::BridgeLocations( BridgeLocationsError::UnreachableDestination @@ -994,6 +1005,7 @@ mod tests { XcmOverBridge::open_bridge( OpenBridgeOrigin::origin_without_sovereign_account(), Box::new(bridged_asset_hub_universal_location().into()), + None, ), Error::::InvalidBridgeOriginAccount, ); @@ -1007,6 +1019,7 @@ mod tests { XcmOverBridge::open_bridge( OpenBridgeOrigin::sibling_parachain_origin(), Box::new(bridged_asset_hub_universal_location().into()), + None, ), Error::::FailedToReserveBridgeDeposit, ); @@ -1047,6 +1060,7 @@ mod tests { XcmOverBridge::open_bridge( origin, Box::new(bridged_asset_hub_universal_location().into()), + None, ), Error::::BridgeAlreadyExists, ); @@ -1075,6 +1089,7 @@ mod tests { XcmOverBridge::open_bridge( origin.clone(), Box::new(bridged_asset_hub_universal_location().into()), + None, ), Error::::LanesManager(LanesManagerError::InboundLaneAlreadyExists), ); @@ -1085,6 +1100,7 @@ mod tests { XcmOverBridge::open_bridge( origin, Box::new(bridged_asset_hub_universal_location().into()), + None, ), Error::::LanesManager( LanesManagerError::OutboundLaneAlreadyExists @@ -1151,10 +1167,13 @@ mod tests { Deposit::new(bridge_owner_account, deposit_amount) }); + let maybe_notify = Some(Receiver::new(13, 15)); + // now open the bridge assert_ok!(XcmOverBridge::open_bridge( origin, Box::new(locations.bridge_destination_universal_location().clone().into()), + maybe_notify.clone(), )); // ensure that everything has been set up in the runtime storage @@ -1173,7 +1192,7 @@ mod tests { state: BridgeState::Opened, deposit: expected_deposit.clone(), lane_id, - maybe_notify: None, + maybe_notify: maybe_notify, }), ); assert_eq!( @@ -1685,18 +1704,21 @@ mod tests { let bridge_destination_universal_location = BridgedUniversalDestination::get(); let may_prune_messages = 13; + let receiver = Receiver::new(13, 15); assert_eq!( bp_xcm_bridge_hub::XcmBridgeHubCall::open_bridge { bridge_destination_universal_location: Box::new( bridge_destination_universal_location.clone().into() - ) + ), + maybe_notify: Some(receiver.clone()), } .encode(), Call::::open_bridge { bridge_destination_universal_location: Box::new( bridge_destination_universal_location.clone().into() - ) + ), + maybe_notify: Some(receiver), } .encode() ); diff --git a/bridges/modules/xcm-bridge-hub/src/migration.rs b/bridges/modules/xcm-bridge-hub/src/migration.rs index c9474e628300..f69502a65470 100644 --- a/bridges/modules/xcm-bridge-hub/src/migration.rs +++ b/bridges/modules/xcm-bridge-hub/src/migration.rs @@ -16,7 +16,7 @@ //! A module that is responsible for migration of storage. -use crate::{Config, Pallet, LOG_TARGET}; +use crate::{Config, Pallet, LOG_TARGET, Receiver}; use frame_support::{ traits::{Get, OnRuntimeUpgrade, StorageVersion}, weights::Weight, @@ -38,6 +38,7 @@ pub struct OpenBridgeForLane< CreateLane, SourceRelativeLocation, BridgedUniversalLocation, + MaybeNotifyRelativeLocation, >( core::marker::PhantomData<( T, @@ -46,6 +47,7 @@ pub struct OpenBridgeForLane< CreateLane, SourceRelativeLocation, BridgedUniversalLocation, + MaybeNotifyRelativeLocation, )>, ); impl< @@ -55,19 +57,22 @@ impl< CreateLane: Get, SourceRelativeLocation: Get, BridgedUniversalLocation: Get, + MaybeNotifyRelativeLocation: Get>, > OnRuntimeUpgrade - for OpenBridgeForLane + for OpenBridgeForLane { fn on_runtime_upgrade() -> Weight { let bridge_origin_relative_location = SourceRelativeLocation::get(); let bridge_destination_universal_location = BridgedUniversalLocation::get(); let lane_id = Lane::get(); let create_lane = CreateLane::get(); + let maybe_notify = MaybeNotifyRelativeLocation::get(); log::info!( target: LOG_TARGET, "OpenBridgeForLane - going to open bridge with lane_id: {lane_id:?} (create_lane: {create_lane:?}) \ between bridge_origin_relative_location: {bridge_origin_relative_location:?} and \ - bridge_destination_universal_location: {bridge_destination_universal_location:?}", + bridge_destination_universal_location: {bridge_destination_universal_location:?} \ + maybe_notify: {maybe_notify:?}", ); let locations = match Pallet::::bridge_locations( @@ -103,7 +108,7 @@ impl< return T::DbWeight::get().reads(2) } - if let Err(e) = Pallet::::do_open_bridge(locations, lane_id, create_lane) { + if let Err(e) = Pallet::::do_open_bridge(locations, lane_id, create_lane, maybe_notify) { log::error!(target: LOG_TARGET, "OpenBridgeForLane - do_open_bridge failed with error: {e:?}"); T::DbWeight::get().reads(6) } else { diff --git a/bridges/modules/xcm-bridge-hub/src/mock.rs b/bridges/modules/xcm-bridge-hub/src/mock.rs index d56e30964858..82e3fb6bcb9d 100644 --- a/bridges/modules/xcm-bridge-hub/src/mock.rs +++ b/bridges/modules/xcm-bridge-hub/src/mock.rs @@ -247,6 +247,7 @@ impl pallet_xcm_bridge_hub_router::Config<()> for TestRuntime { type ToBridgeHubSender = SovereignPaidRemoteExporter< pallet_xcm_bridge_hub_router::impls::ViaRemoteBridgeHubExporter< TestRuntime, + // () - means `pallet_xcm_bridge_hub_router::Config<()>` (), NetworkExportTable, BridgedRelayNetwork, @@ -271,9 +272,13 @@ impl pallet_xcm_bridge_hub_router::Config<()> for TestRuntime { pub type XcmOverBridgeByExportXcmRouterInstance = pallet_xcm_bridge_hub_router::Instance2; #[derive_impl(pallet_xcm_bridge_hub_router::config_preludes::TestDefaultConfig)] impl pallet_xcm_bridge_hub_router::Config for TestRuntime { - // We use `UnpaidLocalExporter` here to test and ensure that `pallet_xcm_bridge_hub_router` can + // We use `UnpaidLocalExporter` with `ViaLocalBridgeHubExporter` here to test and ensure that `pallet_xcm_bridge_hub_router` can // trigger directly `pallet_xcm_bridge_hub` as exporter. - type ToBridgeHubSender = UnpaidLocalExporter; + type ToBridgeHubSender = pallet_xcm_bridge_hub_router::impls::ViaLocalBridgeHubExporter< + TestRuntime, + XcmOverBridgeByExportXcmRouterInstance, + UnpaidLocalExporter + >; type BridgeIdResolver = pallet_xcm_bridge_hub_router::impls::EnsureIsRemoteBridgeIdResolver; diff --git a/bridges/primitives/xcm-bridge-hub/src/call_info.rs b/bridges/primitives/xcm-bridge-hub/src/call_info.rs index fd4fc67822fe..5fa93711b341 100644 --- a/bridges/primitives/xcm-bridge-hub/src/call_info.rs +++ b/bridges/primitives/xcm-bridge-hub/src/call_info.rs @@ -16,6 +16,7 @@ //! Defines structures related to calls of the `pallet-xcm-bridge-hub` pallet. +use crate::Receiver; use bp_messages::MessageNonce; use codec::{Decode, Encode}; use scale_info::TypeInfo; @@ -31,6 +32,8 @@ pub enum XcmBridgeHubCall { open_bridge { /// Universal `InteriorLocation` from the bridged consensus. bridge_destination_universal_location: Box, + /// Optional `maybe_notify` holds data about the `bridge_origin_relative_location` where notifications can be sent to handle congestion. + maybe_notify: Option, }, /// `pallet_xcm_bridge_hub::Call::close_bridge` #[codec(index = 1)] diff --git a/bridges/primitives/xcm-bridge-hub/src/lib.rs b/bridges/primitives/xcm-bridge-hub/src/lib.rs index eb2378ff23f3..2a353b7fda13 100644 --- a/bridges/primitives/xcm-bridge-hub/src/lib.rs +++ b/bridges/primitives/xcm-bridge-hub/src/lib.rs @@ -187,7 +187,7 @@ pub struct Bridge { /// Receiver metadata. #[derive( - CloneNoBound, Decode, Encode, Eq, PartialEqNoBound, TypeInfo, MaxEncodedLen, RuntimeDebugNoBound, + CloneNoBound, Decode, Encode, Eq, PartialEqNoBound, TypeInfo, MaxEncodedLen, RuntimeDebugNoBound, Serialize, Deserialize, )] pub struct Receiver { /// Pallet index. diff --git a/cumulus/parachains/integration-tests/emulated/chains/parachains/bridges/bridge-hub-rococo/src/genesis.rs b/cumulus/parachains/integration-tests/emulated/chains/parachains/bridges/bridge-hub-rococo/src/genesis.rs index 575017f88bb5..752bd3af05d1 100644 --- a/cumulus/parachains/integration-tests/emulated/chains/parachains/bridges/bridge-hub-rococo/src/genesis.rs +++ b/cumulus/parachains/integration-tests/emulated/chains/parachains/bridges/bridge-hub-rococo/src/genesis.rs @@ -75,6 +75,7 @@ pub fn genesis() -> Storage { Location::new(1, [Parachain(1000)]), Junctions::from([ByGenesis(WESTEND_GENESIS_HASH).into(), Parachain(1000)]), Some(bp_messages::LegacyLaneId([0, 0, 0, 2])), + None, ), ], ..Default::default() diff --git a/cumulus/parachains/integration-tests/emulated/chains/parachains/bridges/bridge-hub-westend/src/genesis.rs b/cumulus/parachains/integration-tests/emulated/chains/parachains/bridges/bridge-hub-westend/src/genesis.rs index eb4623084f85..794762566bda 100644 --- a/cumulus/parachains/integration-tests/emulated/chains/parachains/bridges/bridge-hub-westend/src/genesis.rs +++ b/cumulus/parachains/integration-tests/emulated/chains/parachains/bridges/bridge-hub-westend/src/genesis.rs @@ -78,6 +78,7 @@ pub fn genesis() -> Storage { Parachain(1000), ]), Some(bp_messages::LegacyLaneId([0, 0, 0, 2])), + None, ), ], ..Default::default() diff --git a/cumulus/parachains/integration-tests/emulated/common/src/impls.rs b/cumulus/parachains/integration-tests/emulated/common/src/impls.rs index c0d42cf2758e..78fa12619e08 100644 --- a/cumulus/parachains/integration-tests/emulated/common/src/impls.rs +++ b/cumulus/parachains/integration-tests/emulated/common/src/impls.rs @@ -63,7 +63,7 @@ use bp_messages::{ target_chain::{DispatchMessage, DispatchMessageData, MessageDispatch}, MessageKey, OutboundLaneData, }; -pub use bp_xcm_bridge_hub::XcmBridgeHubCall; +pub use bp_xcm_bridge_hub::{Receiver, XcmBridgeHubCall}; use pallet_bridge_messages::{Config as BridgeMessagesConfig, LaneIdOf, OutboundLanes, Pallet}; pub use pallet_bridge_messages::{ Instance1 as BridgeMessagesInstance1, Instance2 as BridgeMessagesInstance2, @@ -938,7 +938,8 @@ macro_rules! impl_bridge_helpers_for_chain { pub fn open_bridge( bridge_location: $crate::impls::Location, bridge_destination_universal_location: $crate::impls::InteriorLocation, - maybe_paid: Option<($crate::impls::Asset, $crate::impls::AccountId)> + maybe_paid: Option<($crate::impls::Asset, $crate::impls::AccountId)>, + maybe_notify: Option<$crate::impls::Receiver>, ) { ::execute_with(|| { use $crate::impls::{bx, Chain}; @@ -952,7 +953,8 @@ macro_rules! impl_bridge_helpers_for_chain { let call: $crate::impls::DoubleEncoded<()> = $runtime_call_wrapper(XcmBridgeHubCall::open_bridge { bridge_destination_universal_location: bx!( bridge_destination_universal_location.clone().into() - ) + ), + maybe_notify, }).encode().into(); let xcm = if let Some((fee_asset, beneficiary)) = maybe_paid { diff --git a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/tests/mod.rs b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/tests/mod.rs index 8aff87755961..ca951e9becab 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/tests/mod.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/tests/mod.rs @@ -261,6 +261,7 @@ pub(crate) fn open_bridge_between_asset_hub_rococo_and_asset_hub_westend() { AssetHubRococo::para_id(), )), )), + None, ); // open AHW -> AHR @@ -278,5 +279,6 @@ pub(crate) fn open_bridge_between_asset_hub_rococo_and_asset_hub_westend() { AssetHubWestend::para_id(), )), )), + None, ); } diff --git a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/tests/mod.rs b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/tests/mod.rs index 6c1cdb98e8b2..643ec83a7bfd 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/tests/mod.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/tests/mod.rs @@ -271,6 +271,7 @@ pub(crate) fn open_bridge_between_asset_hub_rococo_and_asset_hub_westend() { AssetHubRococo::para_id(), )), )), + None, ); // open AHW -> AHR @@ -288,5 +289,6 @@ pub(crate) fn open_bridge_between_asset_hub_rococo_and_asset_hub_westend() { AssetHubWestend::para_id(), )), )), + None, ); } diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_bulletin_config.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_bulletin_config.rs index fa7ef0a55093..d18dd2afb998 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_bulletin_config.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_bulletin_config.rs @@ -307,5 +307,6 @@ pub mod migration { ConstBool, PeopleRococoLocation, BulletinRococoLocation, + (), >; } diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_westend_config.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_westend_config.rs index 395baeec3d73..307cc86966f7 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_westend_config.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_westend_config.rs @@ -360,6 +360,7 @@ pub mod migration { ConstBool, AssetHubRococoLocation, AssetHubWestendUniversalLocation, + (), >; mod v1_wrong { diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/genesis_config_presets.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/genesis_config_presets.rs index 98e2450ee832..c7c805bcd0b8 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/genesis_config_presets.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/genesis_config_presets.rs @@ -33,7 +33,7 @@ fn bridge_hub_rococo_genesis( id: ParaId, bridges_pallet_owner: Option, asset_hub_para_id: ParaId, - opened_bridges: Vec<(Location, InteriorLocation, Option)>, + opened_bridges: Vec<(Location, InteriorLocation, Option, Option)>, ) -> serde_json::Value { build_struct_json_patch!(RuntimeGenesisConfig { balances: BalancesConfig { @@ -87,6 +87,7 @@ pub fn get_preset(id: &sp_genesis_builder::PresetId) -> Option bridge_hub_rococo_genesis( diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/tests/tests.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/tests/tests.rs index 2e7dd98e9dce..b9b083ebf2a9 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/tests/tests.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/tests/tests.rs @@ -328,7 +328,7 @@ mod bridge_hub_westend_tests { bridge_hub_test_utils::open_bridge_with_storage::< Runtime, XcmOverBridgeHubWestendInstance - >(locations, fee, LegacyLaneId([0, 0, 0, 1])) + >(locations, fee, LegacyLaneId([0, 0, 0, 1]), None) } ).1 }, @@ -392,7 +392,7 @@ mod bridge_hub_westend_tests { bridge_hub_test_utils::open_bridge_with_storage::< Runtime, XcmOverBridgeHubWestendInstance, - >(locations, fee, LegacyLaneId([0, 0, 0, 1])) + >(locations, fee, LegacyLaneId([0, 0, 0, 1]), None) }, ) .1 @@ -426,7 +426,7 @@ mod bridge_hub_westend_tests { bridge_hub_test_utils::open_bridge_with_storage::< Runtime, XcmOverBridgeHubWestendInstance, - >(locations, fee, LegacyLaneId([0, 0, 0, 1])) + >(locations, fee, LegacyLaneId([0, 0, 0, 1]), None) }, ) .1 @@ -595,7 +595,7 @@ mod bridge_hub_bulletin_tests { bridge_hub_test_utils::open_bridge_with_storage::< Runtime, XcmOverPolkadotBulletinInstance - >(locations, fee, HashedLaneId::try_new(1, 2).unwrap()) + >(locations, fee, HashedLaneId::try_new(1, 2).unwrap(), None) } ).1 }, @@ -658,7 +658,7 @@ mod bridge_hub_bulletin_tests { bridge_hub_test_utils::open_bridge_with_storage::< Runtime, XcmOverPolkadotBulletinInstance, - >(locations, fee, HashedLaneId::try_new(1, 2).unwrap()) + >(locations, fee, HashedLaneId::try_new(1, 2).unwrap(), None) }, ) .1 @@ -691,7 +691,7 @@ mod bridge_hub_bulletin_tests { bridge_hub_test_utils::open_bridge_with_storage::< Runtime, XcmOverPolkadotBulletinInstance, - >(locations, fee, HashedLaneId::try_new(1, 2).unwrap()) + >(locations, fee, HashedLaneId::try_new(1, 2).unwrap(), None) }, ) .1 diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/genesis_config_presets.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/genesis_config_presets.rs index 69ba9ca9ece7..ee736c7fa8d0 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/genesis_config_presets.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/genesis_config_presets.rs @@ -33,7 +33,7 @@ fn bridge_hub_westend_genesis( id: ParaId, bridges_pallet_owner: Option, asset_hub_para_id: ParaId, - opened_bridges: Vec<(Location, InteriorLocation, Option)>, + opened_bridges: Vec<(Location, InteriorLocation, Option, Option)>, ) -> serde_json::Value { build_struct_json_patch!(RuntimeGenesisConfig { balances: BalancesConfig { @@ -88,6 +88,7 @@ pub fn get_preset(id: &sp_genesis_builder::PresetId) -> Option bridge_hub_westend_genesis( diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/tests/tests.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/tests/tests.rs index 69301b34fe6b..8698c9bc935b 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/tests/tests.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/tests/tests.rs @@ -249,7 +249,7 @@ fn handle_export_message_from_system_parachain_add_to_outbound_queue_works() { |locations, fee| { bridge_hub_test_utils::open_bridge_with_storage::< Runtime, XcmOverBridgeHubRococoInstance - >(locations, fee, LegacyLaneId([0, 0, 0, 1])) + >(locations, fee, LegacyLaneId([0, 0, 0, 1]), None) } ).1 }, @@ -311,7 +311,7 @@ fn relayed_incoming_message_works() { bridge_hub_test_utils::open_bridge_with_storage::< Runtime, XcmOverBridgeHubRococoInstance, - >(locations, fee, LegacyLaneId([0, 0, 0, 1])) + >(locations, fee, LegacyLaneId([0, 0, 0, 1]), None) }, ) .1 @@ -345,7 +345,7 @@ fn free_relay_extrinsic_works() { bridge_hub_test_utils::open_bridge_with_storage::< Runtime, XcmOverBridgeHubRococoInstance, - >(locations, fee, LegacyLaneId([0, 0, 0, 1])) + >(locations, fee, LegacyLaneId([0, 0, 0, 1]), None) }, ) .1 diff --git a/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/helpers.rs b/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/helpers.rs index aac60bba0b53..35e81c2cdc23 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/helpers.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/helpers.rs @@ -471,6 +471,7 @@ pub fn open_bridge_with_extrinsic( bridge_destination_universal_location: Box::new( locations.bridge_destination_universal_location().clone().into(), ), + maybe_notify: None, }); // execute XCM as source origin would do with `Transact -> Origin::Xcm` @@ -488,6 +489,7 @@ pub fn open_bridge_with_storage( locations: BridgeLocations, _buy_execution_fee: Asset, lane_id: pallet_xcm_bridge_hub::LaneIdOf, + maybe_notify: Option, ) where Runtime: pallet_xcm_bridge_hub::Config, XcmOverBridgePalletInstance: 'static, @@ -497,7 +499,8 @@ pub fn open_bridge_with_storage( pallet_xcm_bridge_hub::Pallet::::do_open_bridge( Box::new(locations), lane_id, - true + true, + maybe_notify, ) ); } From 2fc4cbaf073b5377cbc8c952a74d856d2019fe88 Mon Sep 17 00:00:00 2001 From: Branislav Kontur Date: Wed, 6 Nov 2024 23:04:38 +0100 Subject: [PATCH 23/72] Added `update_notification_receiver` extrinsic --- .../modules/xcm-bridge-hub-router/src/lib.rs | 36 ++++++++ bridges/modules/xcm-bridge-hub/src/lib.rs | 89 +++++++++++++++++++ 2 files changed, 125 insertions(+) diff --git a/bridges/modules/xcm-bridge-hub-router/src/lib.rs b/bridges/modules/xcm-bridge-hub-router/src/lib.rs index e32aac3c4aa8..15806142f7c3 100644 --- a/bridges/modules/xcm-bridge-hub-router/src/lib.rs +++ b/bridges/modules/xcm-bridge-hub-router/src/lib.rs @@ -338,6 +338,7 @@ pub mod pallet { } None } + /// Updates the congestion status of a bridge for a given `bridge_id`. /// /// If the bridge does not exist and: @@ -815,4 +816,39 @@ mod tests { ); }); } + + #[test] + fn update_bridge_status_works() { + run_test(|| { + let dest = Location::new(2, [GlobalConsensus(BridgedNetworkId::get())]); + let bridge_id = + bp_xcm_bridge_hub::BridgeId::new(&UniversalLocation::get(), dest.interior()); + assert!(get_bridge_state_for::(&dest).is_none()); + + // update as is_congested=false when `None` + Pallet::::update_bridge_status(bridge_id, false); + assert!(get_bridge_state_for::(&dest).is_none()); + + + // update as is_congested=true + Pallet::::update_bridge_status(bridge_id, true); + assert_eq!( + get_bridge_state_for::(&dest), + Some(BridgeState { + delivery_fee_factor: MINIMAL_DELIVERY_FEE_FACTOR, + is_congested: true, + }) + ); + + // update as is_congested=false when `Some(..)` + Pallet::::update_bridge_status(bridge_id, false); + assert_eq!( + get_bridge_state_for::(&dest), + Some(BridgeState { + delivery_fee_factor: MINIMAL_DELIVERY_FEE_FACTOR, + is_congested: false, + }) + ); + }) + } } diff --git a/bridges/modules/xcm-bridge-hub/src/lib.rs b/bridges/modules/xcm-bridge-hub/src/lib.rs index 612c9476abc1..59d273bb0b0c 100644 --- a/bridges/modules/xcm-bridge-hub/src/lib.rs +++ b/bridges/modules/xcm-bridge-hub/src/lib.rs @@ -460,6 +460,32 @@ pub mod pallet { Ok(()) } + + /// Attempts to update the `maybe_notify` callback for receiving congestion notifications. + /// + /// This can only be called by the "owner" of this side of the bridge, which means that the + /// inbound XCM channel with the local origin chain is functional. + #[pallet::call_index(2)] + #[pallet::weight(Weight::zero())] // TODO:(bridges-v2) - https://github.com/paritytech/parity-bridges-common/issues/3046 - add benchmarks impl FAIL-CI + pub fn update_notification_receiver( + origin: OriginFor, + bridge_destination_universal_location: Box, + maybe_notify: Option, + ) -> DispatchResult { + let locations = Self::bridge_locations_from_origin(origin, bridge_destination_universal_location)?; + Bridges::::try_mutate_exists(locations.bridge_id(), |bridge| match bridge { + Some(b) => { + b.maybe_notify = maybe_notify; + + Self::deposit_event(Event::::NotificationReceiverUpdated { + bridge_id: * locations.bridge_id(), + maybe_notify: b.maybe_notify.clone(), + }); + Ok(()) + }, + None => Err(Error::::UnknownBridge.into()), + }) + } } impl, I: 'static> Pallet { @@ -824,6 +850,13 @@ pub mod pallet { /// Number of pruned messages during the close call. pruned_messages: MessageNonce, }, + /// The bridge has been updated with a new notification receiver. + NotificationReceiverUpdated { + /// Bridge identifier. + bridge_id: BridgeId, + /// Updated notification receiver. + maybe_notify: Option, + } } #[pallet::error] @@ -1475,6 +1508,62 @@ mod tests { }); } + #[test] + fn update_notification_receiver_works() { + run_test(|| { + let origin = OpenBridgeOrigin::parent_relay_chain_origin(); + let locations = XcmOverBridge::bridge_locations_from_origin( + origin.clone(), + Box::new( + VersionedInteriorLocation::from(bridged_asset_hub_universal_location()) + ), + ).unwrap(); + + // open the bridge + assert_ok!(XcmOverBridge::open_bridge( + origin.clone(), + Box::new(locations.bridge_destination_universal_location().clone().into()), + Some(Receiver::new(13, 15)), + )); + assert_eq!( + Bridges::::get(locations.bridge_id()).map(|b| b.maybe_notify).unwrap(), + Some(Receiver::new(13, 15)) + ); + + // update the notification receiver to `None` + assert_ok!(XcmOverBridge::update_notification_receiver( + origin.clone(), + Box::new(locations.bridge_destination_universal_location().clone().into()), + None, + )); + assert_eq!( + Bridges::::get(locations.bridge_id()).map(|b| b.maybe_notify).unwrap(), + None, + ); + + // update the notification receiver to `Some(..)` + assert_ok!(XcmOverBridge::update_notification_receiver( + origin.clone(), + Box::new(locations.bridge_destination_universal_location().clone().into()), + Some(Receiver::new(29, 43)), + )); + assert_eq!( + Bridges::::get(locations.bridge_id()).map(|b| b.maybe_notify).unwrap(), + Some(Receiver::new(29, 43)) + ); + // update the notification receiver to `Some(..)` + assert_ok!(XcmOverBridge::update_notification_receiver( + origin.clone(), + Box::new(locations.bridge_destination_universal_location().clone().into()), + Some(Receiver::new(29, 79)), + )); + assert_eq!( + Bridges::::get(locations.bridge_id()).map(|b| b.maybe_notify).unwrap(), + Some(Receiver::new(29, 79)) + ); + }); + } + #[test] fn do_try_state_works() { let bridge_origin_relative_location = SiblingLocation::get(); From 7e5dd3f60b7cf84e3460e882e995d30c95fb5042 Mon Sep 17 00:00:00 2001 From: Branislav Kontur Date: Thu, 7 Nov 2024 12:03:51 +0100 Subject: [PATCH 24/72] Removed `require_weight_at_most` for xcm::v5 --- .../chains/chain-bridge-hub-rococo/src/lib.rs | 6 ------ .../chains/chain-bridge-hub-westend/src/lib.rs | 6 ------ bridges/modules/xcm-bridge-hub/src/mock.rs | 1 - .../assets/asset-hub-rococo/tests/tests.rs | 17 ----------------- .../assets/asset-hub-westend/tests/tests.rs | 17 ----------------- .../src/bridge_to_westend_config.rs | 2 -- .../src/bridge_to_rococo_config.rs | 2 -- 7 files changed, 51 deletions(-) diff --git a/bridges/chains/chain-bridge-hub-rococo/src/lib.rs b/bridges/chains/chain-bridge-hub-rococo/src/lib.rs index 014fe6241c05..fda6a5f0b722 100644 --- a/bridges/chains/chain-bridge-hub-rococo/src/lib.rs +++ b/bridges/chains/chain-bridge-hub-rococo/src/lib.rs @@ -123,9 +123,3 @@ pub enum RuntimeCall { #[codec(index = 52)] XcmOverBridgeHubWestend(bp_xcm_bridge_hub::XcmBridgeHubCall), } - -// TODO: remove when xcm:v5 -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(1_000_000_000, 1024*8); -} diff --git a/bridges/chains/chain-bridge-hub-westend/src/lib.rs b/bridges/chains/chain-bridge-hub-westend/src/lib.rs index 6aba3f892c50..e941b5840238 100644 --- a/bridges/chains/chain-bridge-hub-westend/src/lib.rs +++ b/bridges/chains/chain-bridge-hub-westend/src/lib.rs @@ -112,9 +112,3 @@ pub enum RuntimeCall { #[codec(index = 45)] XcmOverBridgeHubRococo(bp_xcm_bridge_hub::XcmBridgeHubCall), } - -// TODO: remove when xcm:v5 -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(1_000_000_000, 1024*8); -} diff --git a/bridges/modules/xcm-bridge-hub/src/mock.rs b/bridges/modules/xcm-bridge-hub/src/mock.rs index 82e3fb6bcb9d..6af1d28c78b2 100644 --- a/bridges/modules/xcm-bridge-hub/src/mock.rs +++ b/bridges/modules/xcm-bridge-hub/src/mock.rs @@ -552,7 +552,6 @@ impl Convert, Xcm<()>> for ReportBridgeStatusXcmProvider { UnpaidExecution { weight_limit: Unlimited, check_origin: None }, Transact { origin_kind: OriginKind::Xcm, - require_weight_at_most: Weight::from_parts(10_000_000_000, 8 * 1024), call: encoded_call.into(), }, ExpectTransactStatus(MaybeErrorCode::Success), diff --git a/cumulus/parachains/runtimes/assets/asset-hub-rococo/tests/tests.rs b/cumulus/parachains/runtimes/assets/asset-hub-rococo/tests/tests.rs index b23f8811408c..2c2ca229c495 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-rococo/tests/tests.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-rococo/tests/tests.rs @@ -1285,8 +1285,6 @@ mod asset_hub_rococo_tests { UnpaidExecution { weight_limit: Unlimited, check_origin: None }, Transact { origin_kind: OriginKind::Xcm, - require_weight_at_most: - bp_bridge_hub_rococo::XcmBridgeHubRouterTransactCallMaxWeight::get(), call: RuntimeCall::ToWestendXcmRouter( pallet_xcm_bridge_hub_router::Call::report_bridge_status { bridge_id, @@ -1303,21 +1301,6 @@ mod asset_hub_rococo_tests { } } -#[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_bridge_hub_westend::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::< diff --git a/cumulus/parachains/runtimes/assets/asset-hub-westend/tests/tests.rs b/cumulus/parachains/runtimes/assets/asset-hub-westend/tests/tests.rs index 3d33b4a7170d..987edda652f2 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-westend/tests/tests.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-westend/tests/tests.rs @@ -1263,8 +1263,6 @@ fn report_bridge_status_from_xcm_bridge_router_for_rococo_works() { UnpaidExecution { weight_limit: Unlimited, check_origin: None }, Transact { origin_kind: OriginKind::Xcm, - require_weight_at_most: - bp_bridge_hub_rococo::XcmBridgeHubRouterTransactCallMaxWeight::get(), call: RuntimeCall::ToRococoXcmRouter( pallet_xcm_bridge_hub_router::Call::report_bridge_status { bridge_id, @@ -1280,21 +1278,6 @@ fn report_bridge_status_from_xcm_bridge_router_for_rococo_works() { }) } -#[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_bridge_hub_rococo::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::< diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_westend_config.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_westend_config.rs index 307cc86966f7..1f0d2f1be715 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_westend_config.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_westend_config.rs @@ -137,8 +137,6 @@ impl Convert, Xcm<()>> for ReportBridgeStatusXcmProvider { UnpaidExecution { weight_limit: Unlimited, check_origin: None }, Transact { origin_kind: OriginKind::Xcm, - require_weight_at_most: - bp_bridge_hub_rococo::XcmBridgeHubRouterTransactCallMaxWeight::get(), call: encoded_call.into(), }, ExpectTransactStatus(MaybeErrorCode::Success), diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/bridge_to_rococo_config.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/bridge_to_rococo_config.rs index 70b5ffc5115a..48ce74d13b99 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/bridge_to_rococo_config.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/bridge_to_rococo_config.rs @@ -168,8 +168,6 @@ impl Convert, Xcm<()>> for ReportBridgeStatusXcmProvider { UnpaidExecution { weight_limit: Unlimited, check_origin: None }, Transact { origin_kind: OriginKind::Xcm, - require_weight_at_most: - bp_bridge_hub_westend::XcmBridgeHubRouterTransactCallMaxWeight::get(), call: encoded_call.into(), }, ExpectTransactStatus(MaybeErrorCode::Success), From 73e404a070d6062fc370802b432ce632a3c2bf62 Mon Sep 17 00:00:00 2001 From: Branislav Kontur Date: Thu, 7 Nov 2024 14:00:21 +0100 Subject: [PATCH 25/72] Benchmarks for `pallet-xcm-bridge-hub-router` --- .../xcm-bridge-hub-router/src/benchmarking.rs | 72 +++++++++++++------ .../modules/xcm-bridge-hub-router/src/mock.rs | 7 ++ .../xcm-bridge-hub-router/src/weights.rs | 59 --------------- .../assets/asset-hub-rococo/src/lib.rs | 27 +------ .../weights/pallet_xcm_bridge_hub_router.rs | 30 +------- .../assets/asset-hub-westend/src/lib.rs | 27 +------ .../weights/pallet_xcm_bridge_hub_router.rs | 30 +------- 7 files changed, 64 insertions(+), 188 deletions(-) diff --git a/bridges/modules/xcm-bridge-hub-router/src/benchmarking.rs b/bridges/modules/xcm-bridge-hub-router/src/benchmarking.rs index 3c4a10f82e7d..213087f5bd2c 100644 --- a/bridges/modules/xcm-bridge-hub-router/src/benchmarking.rs +++ b/bridges/modules/xcm-bridge-hub-router/src/benchmarking.rs @@ -18,10 +18,10 @@ #![cfg(feature = "runtime-benchmarks")] -use crate::{DeliveryFeeFactor, MINIMAL_DELIVERY_FEE_FACTOR}; -use frame_benchmarking::{benchmarks_instance_pallet, BenchmarkError}; -use frame_support::traits::{Get, Hooks}; -use sp_runtime::traits::Zero; +use crate::{BridgeState, ResolveBridgeId, Bridges, Call, MINIMAL_DELIVERY_FEE_FACTOR}; +use frame_benchmarking::{benchmarks_instance_pallet, BenchmarkError, BenchmarkResult}; +use frame_support::traits::{UnfilteredDispatchable, EnsureOriginWithArg, Hooks}; +use sp_runtime::{Saturating, traits::Zero}; use xcm::prelude::*; /// Pallet we're benchmarking here. @@ -29,32 +29,62 @@ pub struct Pallet, I: 'static = ()>(crate::Pallet); /// Trait that must be implemented by runtime to be able to benchmark pallet properly. pub trait Config: crate::Config { - /// Fill up queue so it becomes congested. - fn make_congested(); - + // /// Fill up queue so it becomes congested. + // fn make_congested(); + // /// Returns destination which is valid for this router instance. - /// (Needs to pass `T::Bridges`) - /// Make sure that `SendXcm` will pass. - fn ensure_bridged_target_destination() -> Result { - Ok(Location::new( - Self::UniversalLocation::get().len() as u8, - [GlobalConsensus(Self::BridgedNetworkId::get().unwrap())], - )) - } + fn ensure_bridged_target_destination() -> Result; } benchmarks_instance_pallet! { - on_initialize_when_non_congested { - DeliveryFeeFactor::::put(MINIMAL_DELIVERY_FEE_FACTOR + MINIMAL_DELIVERY_FEE_FACTOR); + on_initialize_when_bridge_state_removed { + let bridge_id = T::BridgeIdResolver::resolve_for_dest(&T::ensure_bridged_target_destination()?) + .ok_or(BenchmarkError::Weightless)?; + // uncongested and less than a minimal factor is removed + Bridges::::insert(&bridge_id, BridgeState { + delivery_fee_factor: 0.into(), + is_congested: false, + }); + assert!(Bridges::::get(&bridge_id).is_some()); }: { crate::Pallet::::on_initialize(Zero::zero()) + } verify { + assert!(Bridges::::get(bridge_id).is_none()); } - on_initialize_when_congested { - DeliveryFeeFactor::::put(MINIMAL_DELIVERY_FEE_FACTOR + MINIMAL_DELIVERY_FEE_FACTOR); - let _ = T::ensure_bridged_target_destination()?; - T::make_congested(); + on_initialize_when_bridge_state_updated { + let bridge_id = T::BridgeIdResolver::resolve_for_dest(&T::ensure_bridged_target_destination()?) + .ok_or(BenchmarkError::Weightless)?; + // uncongested and higher than a minimal factor is decreased + let old_delivery_fee_factor = MINIMAL_DELIVERY_FEE_FACTOR.saturating_mul(1000.into()); + Bridges::::insert(&bridge_id, BridgeState { + delivery_fee_factor: old_delivery_fee_factor, + is_congested: false, + }); + assert!(Bridges::::get(&bridge_id).is_some()); }: { crate::Pallet::::on_initialize(Zero::zero()) + } verify { + assert!(Bridges::::get(bridge_id).unwrap().delivery_fee_factor < old_delivery_fee_factor); + } + + report_bridge_status { + let bridge_id = T::BridgeIdResolver::resolve_for_dest(&T::ensure_bridged_target_destination()?) + .ok_or(BenchmarkError::Override(BenchmarkResult::from_weight(Weight::MAX)))?; + let origin: T::RuntimeOrigin = T::BridgeHubOrigin::try_successful_origin(&bridge_id).map_err(|_| BenchmarkError::Weightless)?; + let is_congested = true; + + let call = Call::::report_bridge_status { bridge_id: bridge_id.clone(), is_congested }; + }: { call.dispatch_bypass_filter(origin)? } + verify { + assert_eq!( + Bridges::::get(&bridge_id), + Some(BridgeState { + delivery_fee_factor: MINIMAL_DELIVERY_FEE_FACTOR, + is_congested, + }) + ); } + + impl_benchmark_test_suite!(Pallet, crate::mock::new_test_ext(), crate::mock::TestRuntime) } diff --git a/bridges/modules/xcm-bridge-hub-router/src/mock.rs b/bridges/modules/xcm-bridge-hub-router/src/mock.rs index 68cf0356aa4e..6f65e3f30a0c 100644 --- a/bridges/modules/xcm-bridge-hub-router/src/mock.rs +++ b/bridges/modules/xcm-bridge-hub-router/src/mock.rs @@ -219,3 +219,10 @@ pub(crate) fn get_bridge_state_for, I let bridge_id = ::resolve_for_dest(dest).unwrap(); pallet_xcm_bridge_hub_router::Bridges::::get(bridge_id) } + +#[cfg(feature = "runtime-benchmarks")] +impl crate::benchmarking::Config<()> for TestRuntime { + fn ensure_bridged_target_destination() -> Result { + Ok(Location::new(2, [GlobalConsensus(BridgedNetworkId::get())])) + } +} \ No newline at end of file diff --git a/bridges/modules/xcm-bridge-hub-router/src/weights.rs b/bridges/modules/xcm-bridge-hub-router/src/weights.rs index dc5f1ea1a99a..f462e649bc9c 100644 --- a/bridges/modules/xcm-bridge-hub-router/src/weights.rs +++ b/bridges/modules/xcm-bridge-hub-router/src/weights.rs @@ -52,8 +52,6 @@ use sp_std::marker::PhantomData; pub trait WeightInfo { fn on_initialize_when_bridge_state_removed() -> Weight; fn on_initialize_when_bridge_state_updated() -> Weight; - fn on_initialize_when_non_congested() -> Weight; - fn on_initialize_when_congested() -> Weight; fn report_bridge_status() -> Weight; } @@ -69,32 +67,6 @@ impl WeightInfo for BridgeWeight { fn on_initialize_when_bridge_state_updated() -> Weight { RocksDbWeight::get().writes(1) } - /// - /// Storage: `XcmBridgeHubRouter::DeliveryFeeFactor` (r:1 w:1) - /// - /// Proof: `XcmBridgeHubRouter::DeliveryFeeFactor` (`max_values`: Some(1), `max_size`: Some(16), - /// added: 511, mode: `MaxEncodedLen`) - fn on_initialize_when_non_congested() -> Weight { - // Proof Size summary in bytes: - // Measured: `52` - // Estimated: `3517` - // Minimum execution time: 11_141 nanoseconds. - Weight::from_parts(11_339_000, 3517) - .saturating_add(T::DbWeight::get().reads(2_u64)) - .saturating_add(T::DbWeight::get().writes(1_u64)) - } - /// Storage: UNKNOWN KEY `0x456d756c617465645369626c696e6758636d704368616e6e656c2e436f6e6765` - /// (r:1 w:0) - /// - /// Proof: UNKNOWN KEY `0x456d756c617465645369626c696e6758636d704368616e6e656c2e436f6e6765` (r:1 - /// w:0) - fn on_initialize_when_congested() -> Weight { - // Proof Size summary in bytes: - // Measured: `82` - // Estimated: `3547` - // Minimum execution time: 4_239 nanoseconds. - Weight::from_parts(4_383_000, 3547).saturating_add(T::DbWeight::get().reads(1_u64)) - } /// Storage: `XcmBridgeHubRouter::Bridge` (r:1 w:1) /// /// Proof: `XcmBridgeHubRouter::Bridge` (`max_values`: Some(1), `max_size`: Some(17), added: @@ -120,37 +92,6 @@ impl WeightInfo for () { RocksDbWeight::get().writes(1) } - /// Storage: UNKNOWN KEY `0x456d756c617465645369626c696e6758636d704368616e6e656c2e436f6e6765` - /// (r:1 w:0) - /// - /// Proof: UNKNOWN KEY `0x456d756c617465645369626c696e6758636d704368616e6e656c2e436f6e6765` (r:1 - /// w:0) - /// - /// Storage: `XcmBridgeHubRouter::DeliveryFeeFactor` (r:1 w:1) - /// - /// Proof: `XcmBridgeHubRouter::DeliveryFeeFactor` (`max_values`: Some(1), `max_size`: Some(16), - /// added: 511, mode: `MaxEncodedLen`) - fn on_initialize_when_non_congested() -> Weight { - // Proof Size summary in bytes: - // Measured: `52` - // Estimated: `3517` - // Minimum execution time: 11_141 nanoseconds. - Weight::from_parts(11_339_000, 3517) - .saturating_add(RocksDbWeight::get().reads(2_u64)) - .saturating_add(RocksDbWeight::get().writes(1_u64)) - } - /// Storage: UNKNOWN KEY `0x456d756c617465645369626c696e6758636d704368616e6e656c2e436f6e6765` - /// (r:1 w:0) - /// - /// Proof: UNKNOWN KEY `0x456d756c617465645369626c696e6758636d704368616e6e656c2e436f6e6765` (r:1 - /// w:0) - fn on_initialize_when_congested() -> Weight { - // Proof Size summary in bytes: - // Measured: `82` - // Estimated: `3547` - // Minimum execution time: 4_239 nanoseconds. - Weight::from_parts(4_383_000, 3547).saturating_add(RocksDbWeight::get().reads(1_u64)) - } /// Storage: `XcmBridgeHubRouter::Bridge` (r:1 w:1) /// /// Proof: `XcmBridgeHubRouter::Bridge` (`max_values`: Some(1), `max_size`: Some(17), added: diff --git a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs index c333d85e7e75..7b8eb43b7848 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs @@ -100,7 +100,7 @@ use polkadot_runtime_common::{BlockHashCount, SlowAdjustingFeeUpdate}; #[cfg(feature = "runtime-benchmarks")] use xcm::latest::prelude::{ Asset, Assets as XcmAssets, Fungible, Here, InteriorLocation, Junction, Junction::*, Location, - NetworkId, NonFungible, Parent, ParentThen, Response, XCM_VERSION, + NetworkId, NonFungible, Parent, ParentThen, Response, }; use xcm::{ latest::prelude::{AssetId, BodyId}, @@ -1710,31 +1710,8 @@ impl_runtime_apis! { } 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() -> Result { - ParachainSystem::open_outbound_hrmp_channel_for_benchmarks_or_tests( - xcm_config::bridging::SiblingBridgeHubParaId::get().into() - ); - let bridged_asset_hub = xcm_config::bridging::to_westend::AssetHubWestend::get(); - let _ = PolkadotXcm::force_xcm_version( - RuntimeOrigin::root(), - alloc::boxed::Box::new(bridged_asset_hub.clone()), - XCM_VERSION, - ).map_err(|e| { - log::error!( - "Failed to dispatch `force_xcm_version({:?}, {:?}, {:?})`, error: {:?}", - RuntimeOrigin::root(), - bridged_asset_hub, - XCM_VERSION, - e - ); - BenchmarkError::Stop("XcmVersion was not stored!") - })?; - Ok(bridged_asset_hub) + Ok(xcm_config::bridging::to_westend::AssetHubWestend::get()) } } diff --git a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/pallet_xcm_bridge_hub_router.rs b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/pallet_xcm_bridge_hub_router.rs index 9fa2264fb8d9..1532fa8aaa2d 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/pallet_xcm_bridge_hub_router.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/pallet_xcm_bridge_hub_router.rs @@ -58,35 +58,7 @@ impl pallet_xcm_bridge_hub_router::WeightInfo for Weigh 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) - /// Proof: `XcmpQueue::OutboundXcmpStatus` (`max_values`: Some(1), `max_size`: Some(1282), added: 1777, mode: `MaxEncodedLen`) - /// Storage: `ToWestendXcmRouter::DeliveryFeeFactor` (r:1 w:1) - /// Proof: `ToWestendXcmRouter::DeliveryFeeFactor` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) - fn on_initialize_when_non_congested() -> Weight { - // Proof Size summary in bytes: - // Measured: `153` - // Estimated: `5487` - // Minimum execution time: 12_993_000 picoseconds. - Weight::from_parts(13_428_000, 0) - .saturating_add(Weight::from_parts(0, 5487)) - .saturating_add(T::DbWeight::get().reads(3)) - .saturating_add(T::DbWeight::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) - /// Proof: `XcmpQueue::OutboundXcmpStatus` (`max_values`: Some(1), `max_size`: Some(1282), added: 1777, mode: `MaxEncodedLen`) - fn on_initialize_when_congested() -> Weight { - // Proof Size summary in bytes: - // Measured: `144` - // Estimated: `5487` - // Minimum execution time: 6_305_000 picoseconds. - Weight::from_parts(6_536_000, 0) - .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: diff --git a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs index 1002d8beba35..7da24dc02495 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs @@ -105,7 +105,7 @@ use xcm::{ #[cfg(feature = "runtime-benchmarks")] use xcm::latest::prelude::{ Asset, Assets as XcmAssets, Fungible, Here, InteriorLocation, Junction, Junction::*, Location, - NetworkId, NonFungible, Parent, ParentThen, Response, XCM_VERSION, + NetworkId, NonFungible, Parent, ParentThen, Response, }; use xcm_runtime_apis::{ @@ -1891,31 +1891,8 @@ impl_runtime_apis! { }; 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() -> Result { - ParachainSystem::open_outbound_hrmp_channel_for_benchmarks_or_tests( - xcm_config::bridging::SiblingBridgeHubParaId::get().into() - ); - let bridged_asset_hub = xcm_config::bridging::to_rococo::AssetHubRococo::get(); - let _ = PolkadotXcm::force_xcm_version( - RuntimeOrigin::root(), - alloc::boxed::Box::new(bridged_asset_hub.clone()), - XCM_VERSION, - ).map_err(|e| { - log::error!( - "Failed to dispatch `force_xcm_version({:?}, {:?}, {:?})`, error: {:?}", - RuntimeOrigin::root(), - bridged_asset_hub, - XCM_VERSION, - e - ); - BenchmarkError::Stop("XcmVersion was not stored!") - })?; - Ok(bridged_asset_hub) + Ok(xcm_config::bridging::to_rococo::AssetHubRococo::get()) } } diff --git a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/pallet_xcm_bridge_hub_router.rs b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/pallet_xcm_bridge_hub_router.rs index 9c1fe64ac16f..ec72a522356c 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/pallet_xcm_bridge_hub_router.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/pallet_xcm_bridge_hub_router.rs @@ -58,35 +58,7 @@ impl pallet_xcm_bridge_hub_router::WeightInfo for Weigh 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) - /// Proof: `XcmpQueue::OutboundXcmpStatus` (`max_values`: Some(1), `max_size`: Some(1282), added: 1777, mode: `MaxEncodedLen`) - /// Storage: `ToRococoXcmRouter::DeliveryFeeFactor` (r:1 w:1) - /// Proof: `ToRococoXcmRouter::DeliveryFeeFactor` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) - fn on_initialize_when_non_congested() -> Weight { - // Proof Size summary in bytes: - // Measured: `225` - // Estimated: `5487` - // Minimum execution time: 13_483_000 picoseconds. - Weight::from_parts(13_862_000, 0) - .saturating_add(Weight::from_parts(0, 5487)) - .saturating_add(T::DbWeight::get().reads(3)) - .saturating_add(T::DbWeight::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) - /// Proof: `XcmpQueue::OutboundXcmpStatus` (`max_values`: Some(1), `max_size`: Some(1282), added: 1777, mode: `MaxEncodedLen`) - fn on_initialize_when_congested() -> Weight { - // Proof Size summary in bytes: - // Measured: `111` - // Estimated: `5487` - // Minimum execution time: 5_078_000 picoseconds. - Weight::from_parts(5_233_000, 0) - .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: From 5eefeec735919a1dd04e0f67071f27710cb0f68e Mon Sep 17 00:00:00 2001 From: GitHub Action Date: Thu, 7 Nov 2024 13:18:40 +0000 Subject: [PATCH 26/72] Update from bkontur running command 'fmt' --- .../xcm-bridge-hub-router/src/benchmarking.rs | 6 +- .../xcm-bridge-hub-router/src/impls.rs | 38 ++++++---- .../modules/xcm-bridge-hub-router/src/lib.rs | 34 ++++++--- .../modules/xcm-bridge-hub-router/src/mock.rs | 2 +- bridges/modules/xcm-bridge-hub/src/lib.rs | 69 +++++++++++-------- .../modules/xcm-bridge-hub/src/migration.rs | 16 ++++- bridges/modules/xcm-bridge-hub/src/mock.rs | 11 ++- .../xcm-bridge-hub/src/call_info.rs | 3 +- bridges/primitives/xcm-bridge-hub/src/lib.rs | 11 ++- .../src/bridge_to_westend_config.rs | 5 +- .../src/genesis_config_presets.rs | 7 +- .../src/bridge_to_rococo_config.rs | 5 +- .../src/genesis_config_presets.rs | 7 +- 13 files changed, 134 insertions(+), 80 deletions(-) diff --git a/bridges/modules/xcm-bridge-hub-router/src/benchmarking.rs b/bridges/modules/xcm-bridge-hub-router/src/benchmarking.rs index 213087f5bd2c..cc11533c86bb 100644 --- a/bridges/modules/xcm-bridge-hub-router/src/benchmarking.rs +++ b/bridges/modules/xcm-bridge-hub-router/src/benchmarking.rs @@ -18,10 +18,10 @@ #![cfg(feature = "runtime-benchmarks")] -use crate::{BridgeState, ResolveBridgeId, Bridges, Call, MINIMAL_DELIVERY_FEE_FACTOR}; +use crate::{BridgeState, Bridges, Call, ResolveBridgeId, MINIMAL_DELIVERY_FEE_FACTOR}; use frame_benchmarking::{benchmarks_instance_pallet, BenchmarkError, BenchmarkResult}; -use frame_support::traits::{UnfilteredDispatchable, EnsureOriginWithArg, Hooks}; -use sp_runtime::{Saturating, traits::Zero}; +use frame_support::traits::{EnsureOriginWithArg, Hooks, UnfilteredDispatchable}; +use sp_runtime::{traits::Zero, Saturating}; use xcm::prelude::*; /// Pallet we're benchmarking here. diff --git a/bridges/modules/xcm-bridge-hub-router/src/impls.rs b/bridges/modules/xcm-bridge-hub-router/src/impls.rs index 789f445d8aa4..c6431e1215d6 100644 --- a/bridges/modules/xcm-bridge-hub-router/src/impls.rs +++ b/bridges/modules/xcm-bridge-hub-router/src/impls.rs @@ -68,8 +68,11 @@ impl, I: 'static> bp_xcm_bridge_hub::LocalXcmChannelManager(PhantomData<(T, I, E, BNF, BHLF)>); impl, I: 'static, E, BridgedNetworkIdFilter, BridgeHubLocationFilter> ExporterFor for ViaRemoteBridgeHubExporter @@ -188,32 +191,40 @@ where } } -/// Adapter implementation for `SendXcm` that allows adding a message size fee and/or dynamic fees based on the `BridgeId` resolved by the `T::BridgeIdResolver` resolver, -/// if and only if `E` supports routing. -/// This adapter can be used, for example, as a wrapper over `UnpaidLocalExporter`, enabling it to compute message and/or dynamic fees using a fee factor. +/// Adapter implementation for `SendXcm` that allows adding a message size fee and/or dynamic fees +/// based on the `BridgeId` resolved by the `T::BridgeIdResolver` resolver, if and only if `E` +/// supports routing. This adapter can be used, for example, as a wrapper over +/// `UnpaidLocalExporter`, enabling it to compute message and/or dynamic fees using a fee factor. pub struct ViaLocalBridgeHubExporter(PhantomData<(T, I, E)>); impl, I: 'static, E: SendXcm> SendXcm for ViaLocalBridgeHubExporter { type Ticket = E::Ticket; - fn validate(destination: &mut Option, message: &mut Option>) -> SendResult { + fn validate( + destination: &mut Option, + message: &mut Option>, + ) -> SendResult { let dest_clone = destination.clone().ok_or(SendError::MissingArgument)?; - let message_size = message.as_ref().map_or(0, |message|message.encoded_size()) as _; + let message_size = message.as_ref().map_or(0, |message| message.encoded_size()) as _; match E::validate(destination, message) { Ok((ticket, mut fees)) => { // calculate message size fees (if configured) - let maybe_message_size_fees = Pallet::::calculate_message_size_fees(|| message_size); + let maybe_message_size_fees = + Pallet::::calculate_message_size_fees(|| message_size); if let Some(message_size_fees) = maybe_message_size_fees { fees.push(message_size_fees); } - // Here, we have the actual result fees covering bridge fees, so now we need to check/apply - // the congestion and dynamic_fees features (if possible). + // Here, we have the actual result fees covering bridge fees, so now we need to + // check/apply the congestion and dynamic_fees features (if possible). if let Some(bridge_id) = T::BridgeIdResolver::resolve_for_dest(&dest_clone) { if let Some(bridge_state) = Bridges::::get(bridge_id) { let mut dynamic_fees = sp_std::vec::Vec::with_capacity(fees.len()); for fee in fees.into_inner() { - dynamic_fees.push(Pallet::::calculate_dynamic_fees_for_asset(&bridge_state, fee)); + dynamic_fees.push(Pallet::::calculate_dynamic_fees_for_asset( + &bridge_state, + fee, + )); } fees = Assets::from(dynamic_fees); } @@ -221,8 +232,8 @@ impl, I: 'static, E: SendXcm> SendXcm for ViaLocalBridgeHubExporter // return original ticket with possibly extended fees Ok((ticket, fees)) - } - e => e + }, + e => e, } } @@ -231,7 +242,6 @@ impl, I: 'static, E: SendXcm> SendXcm for ViaLocalBridgeHubExporter } } - /// Implementation of `ResolveBridgeId` returning `bp_xcm_bridge_hub::BridgeId` based on the /// configured `UniversalLocation` and remote universal location. pub struct EnsureIsRemoteBridgeIdResolver(PhantomData); diff --git a/bridges/modules/xcm-bridge-hub-router/src/lib.rs b/bridges/modules/xcm-bridge-hub-router/src/lib.rs index 15806142f7c3..1a371de05983 100644 --- a/bridges/modules/xcm-bridge-hub-router/src/lib.rs +++ b/bridges/modules/xcm-bridge-hub-router/src/lib.rs @@ -14,36 +14,51 @@ // You should have received a copy of the GNU General Public License // along with Parity Bridges Common. If not, see . -//! A pallet that can be used as an alternative in the XCM router configuration — see the `SendXcm` implementation for details. +//! A pallet that can be used as an alternative in the XCM router configuration — see the `SendXcm` +//! implementation for details. //! //! ## Features //! //! This pallet offers several optional features to customize functionality: //! //! ### Message Size Fee -//! An optional fee based on `T::FeeAsset` and `T::ByteFee`. If `T::FeeAsset` is not specified, this fee is not calculated. +//! An optional fee based on `T::FeeAsset` and `T::ByteFee`. If `T::FeeAsset` is not specified, this +//! fee is not calculated. //! //! ### Dynamic Fees and Congestion //! -//! This pallet supports storing the congestion status of bridge outbound queues. The fee increases exponentially if the queue between this chain and a sibling or child bridge hub becomes congested. All other bridge hub queues provide backpressure mechanisms, so if any of these queues are congested, it will eventually lead to increased queuing on this chain. +//! This pallet supports storing the congestion status of bridge outbound queues. The fee increases +//! exponentially if the queue between this chain and a sibling or child bridge hub becomes +//! congested. All other bridge hub queues provide backpressure mechanisms, so if any of these +//! queues are congested, it will eventually lead to increased queuing on this chain. //! //! There are two methods for storing congestion status: -//! 1. A dedicated extrinsic `report_bridge_status`, which relies on `T::BridgeHubOrigin`. This allows the message exporter to send, for example, an XCM `Transact`. +//! 1. A dedicated extrinsic `report_bridge_status`, which relies on `T::BridgeHubOrigin`. This +//! allows the message exporter to send, for example, an XCM `Transact`. //! 2. An implementation of `bp_xcm_bridge_hub::LocalXcmChannelManager`. //! //! ## Usage //! -//! This pallet provides several implementations, such as `ViaLocalBridgeHubExporter` and `ViaRemoteBridgeHubExporter`, which can expose or access these features. +//! This pallet provides several implementations, such as `ViaLocalBridgeHubExporter` and +//! `ViaRemoteBridgeHubExporter`, which can expose or access these features. //! -//! This router can be used in two main scenarios, depending on where the router and message exporter (e.g., `pallet_xcm_bridge_hub` or another pallet with an `ExportXcm` implementation) are deployed: +//! This router can be used in two main scenarios, depending on where the router and message +//! exporter (e.g., `pallet_xcm_bridge_hub` or another pallet with an `ExportXcm` implementation) +//! are deployed: //! //! ### On the Same Chain as the Message Exporter -//! In this setup, the router directly calls an `ExportXcm` implementation. In this case, `ViaLocalBridgeHubExporter` can be used as a wrapper with `T::ToBridgeHubSender`. +//! In this setup, the router directly calls an `ExportXcm` implementation. In this case, +//! `ViaLocalBridgeHubExporter` can be used as a wrapper with `T::ToBridgeHubSender`. //! //! ### On a Different Chain than the Message Exporter -//! In this setup, we need to provide a `SendXcm` implementation for `T::ToBridgeHubSender`, which sends `ExportMessage`. For example, `SovereignPaidRemoteExporter` can be used with `ViaRemoteBridgeHubExporter`. +//! In this setup, we need to provide a `SendXcm` implementation for `T::ToBridgeHubSender`, which +//! sends `ExportMessage`. For example, `SovereignPaidRemoteExporter` can be used with +//! `ViaRemoteBridgeHubExporter`. //! -//! **Note on Terminology**: When we refer to the bridge hub, we mean the chain that has the `pallet-bridge-messages` with an `ExportXcm` implementation deployed, such as `pallet-xcm-bridge-hub`. Depending on the deployment setup, `T::ToBridgeHubSender` can be configured accordingly—see `T::ToBridgeHubSender` for additional documentation. +//! **Note on Terminology**: When we refer to the bridge hub, we mean the chain that has the +//! `pallet-bridge-messages` with an `ExportXcm` implementation deployed, such as +//! `pallet-xcm-bridge-hub`. Depending on the deployment setup, `T::ToBridgeHubSender` can be +//! configured accordingly—see `T::ToBridgeHubSender` for additional documentation. #![cfg_attr(not(feature = "std"), no_std)] @@ -829,7 +844,6 @@ mod tests { Pallet::::update_bridge_status(bridge_id, false); assert!(get_bridge_state_for::(&dest).is_none()); - // update as is_congested=true Pallet::::update_bridge_status(bridge_id, true); assert_eq!( diff --git a/bridges/modules/xcm-bridge-hub-router/src/mock.rs b/bridges/modules/xcm-bridge-hub-router/src/mock.rs index 6f65e3f30a0c..e7c53579775d 100644 --- a/bridges/modules/xcm-bridge-hub-router/src/mock.rs +++ b/bridges/modules/xcm-bridge-hub-router/src/mock.rs @@ -225,4 +225,4 @@ impl crate::benchmarking::Config<()> for TestRuntime { fn ensure_bridged_target_destination() -> Result { Ok(Location::new(2, [GlobalConsensus(BridgedNetworkId::get())])) } -} \ No newline at end of file +} diff --git a/bridges/modules/xcm-bridge-hub/src/lib.rs b/bridges/modules/xcm-bridge-hub/src/lib.rs index 59d273bb0b0c..7af7dbb96a21 100644 --- a/bridges/modules/xcm-bridge-hub/src/lib.rs +++ b/bridges/modules/xcm-bridge-hub/src/lib.rs @@ -296,8 +296,9 @@ pub mod pallet { /// The states after this call: bridge is `Opened`, outbound lane is `Opened`, inbound lane /// is `Opened`. /// - /// Optional `maybe_notify` holds data about the `bridge_origin_relative_location` where notifications can be sent to - /// handle congestion. The notification contains an encoded tuple `(BridgeId, bool)`, where `bool` is the `is_congested` flag. + /// Optional `maybe_notify` holds data about the `bridge_origin_relative_location` where + /// notifications can be sent to handle congestion. The notification contains an encoded + /// tuple `(BridgeId, bool)`, where `bool` is the `is_congested` flag. #[pallet::call_index(0)] #[pallet::weight(Weight::zero())] // TODO:(bridges-v2) - https://github.com/paritytech/parity-bridges-common/issues/3046 - add benchmarks impl FAIL-CI pub fn open_bridge( @@ -472,13 +473,14 @@ pub mod pallet { bridge_destination_universal_location: Box, maybe_notify: Option, ) -> DispatchResult { - let locations = Self::bridge_locations_from_origin(origin, bridge_destination_universal_location)?; + let locations = + Self::bridge_locations_from_origin(origin, bridge_destination_universal_location)?; Bridges::::try_mutate_exists(locations.bridge_id(), |bridge| match bridge { Some(b) => { b.maybe_notify = maybe_notify; Self::deposit_event(Event::::NotificationReceiverUpdated { - bridge_id: * locations.bridge_id(), + bridge_id: *locations.bridge_id(), maybe_notify: b.maybe_notify.clone(), }); Ok(()) @@ -856,7 +858,7 @@ pub mod pallet { bridge_id: BridgeId, /// Updated notification receiver. maybe_notify: Option, - } + }, } #[pallet::error] @@ -1225,7 +1227,7 @@ mod tests { state: BridgeState::Opened, deposit: expected_deposit.clone(), lane_id, - maybe_notify: maybe_notify, + maybe_notify, }), ); assert_eq!( @@ -1514,51 +1516,58 @@ mod tests { let origin = OpenBridgeOrigin::parent_relay_chain_origin(); let locations = XcmOverBridge::bridge_locations_from_origin( origin.clone(), - Box::new( - VersionedInteriorLocation::from(bridged_asset_hub_universal_location()) - ), - ).unwrap(); + Box::new(VersionedInteriorLocation::from(bridged_asset_hub_universal_location())), + ) + .unwrap(); // open the bridge assert_ok!(XcmOverBridge::open_bridge( - origin.clone(), - Box::new(locations.bridge_destination_universal_location().clone().into()), - Some(Receiver::new(13, 15)), - )); + origin.clone(), + Box::new(locations.bridge_destination_universal_location().clone().into()), + Some(Receiver::new(13, 15)), + )); assert_eq!( - Bridges::::get(locations.bridge_id()).map(|b| b.maybe_notify).unwrap(), + Bridges::::get(locations.bridge_id()) + .map(|b| b.maybe_notify) + .unwrap(), Some(Receiver::new(13, 15)) ); // update the notification receiver to `None` assert_ok!(XcmOverBridge::update_notification_receiver( - origin.clone(), - Box::new(locations.bridge_destination_universal_location().clone().into()), - None, - )); + origin.clone(), + Box::new(locations.bridge_destination_universal_location().clone().into()), + None, + )); assert_eq!( - Bridges::::get(locations.bridge_id()).map(|b| b.maybe_notify).unwrap(), + Bridges::::get(locations.bridge_id()) + .map(|b| b.maybe_notify) + .unwrap(), None, ); // update the notification receiver to `Some(..)` assert_ok!(XcmOverBridge::update_notification_receiver( - origin.clone(), - Box::new(locations.bridge_destination_universal_location().clone().into()), - Some(Receiver::new(29, 43)), - )); + origin.clone(), + Box::new(locations.bridge_destination_universal_location().clone().into()), + Some(Receiver::new(29, 43)), + )); assert_eq!( - Bridges::::get(locations.bridge_id()).map(|b| b.maybe_notify).unwrap(), + Bridges::::get(locations.bridge_id()) + .map(|b| b.maybe_notify) + .unwrap(), Some(Receiver::new(29, 43)) ); // update the notification receiver to `Some(..)` assert_ok!(XcmOverBridge::update_notification_receiver( - origin.clone(), - Box::new(locations.bridge_destination_universal_location().clone().into()), - Some(Receiver::new(29, 79)), - )); + origin.clone(), + Box::new(locations.bridge_destination_universal_location().clone().into()), + Some(Receiver::new(29, 79)), + )); assert_eq!( - Bridges::::get(locations.bridge_id()).map(|b| b.maybe_notify).unwrap(), + Bridges::::get(locations.bridge_id()) + .map(|b| b.maybe_notify) + .unwrap(), Some(Receiver::new(29, 79)) ); }); diff --git a/bridges/modules/xcm-bridge-hub/src/migration.rs b/bridges/modules/xcm-bridge-hub/src/migration.rs index f69502a65470..32761a1cfa5a 100644 --- a/bridges/modules/xcm-bridge-hub/src/migration.rs +++ b/bridges/modules/xcm-bridge-hub/src/migration.rs @@ -16,7 +16,7 @@ //! A module that is responsible for migration of storage. -use crate::{Config, Pallet, LOG_TARGET, Receiver}; +use crate::{Config, Pallet, Receiver, LOG_TARGET}; use frame_support::{ traits::{Get, OnRuntimeUpgrade, StorageVersion}, weights::Weight, @@ -59,7 +59,15 @@ impl< BridgedUniversalLocation: Get, MaybeNotifyRelativeLocation: Get>, > OnRuntimeUpgrade - for OpenBridgeForLane + for OpenBridgeForLane< + T, + I, + Lane, + CreateLane, + SourceRelativeLocation, + BridgedUniversalLocation, + MaybeNotifyRelativeLocation, + > { fn on_runtime_upgrade() -> Weight { let bridge_origin_relative_location = SourceRelativeLocation::get(); @@ -108,7 +116,9 @@ impl< return T::DbWeight::get().reads(2) } - if let Err(e) = Pallet::::do_open_bridge(locations, lane_id, create_lane, maybe_notify) { + if let Err(e) = + Pallet::::do_open_bridge(locations, lane_id, create_lane, maybe_notify) + { log::error!(target: LOG_TARGET, "OpenBridgeForLane - do_open_bridge failed with error: {e:?}"); T::DbWeight::get().reads(6) } else { diff --git a/bridges/modules/xcm-bridge-hub/src/mock.rs b/bridges/modules/xcm-bridge-hub/src/mock.rs index 6af1d28c78b2..8573436a3dcd 100644 --- a/bridges/modules/xcm-bridge-hub/src/mock.rs +++ b/bridges/modules/xcm-bridge-hub/src/mock.rs @@ -272,12 +272,12 @@ impl pallet_xcm_bridge_hub_router::Config<()> for TestRuntime { pub type XcmOverBridgeByExportXcmRouterInstance = pallet_xcm_bridge_hub_router::Instance2; #[derive_impl(pallet_xcm_bridge_hub_router::config_preludes::TestDefaultConfig)] impl pallet_xcm_bridge_hub_router::Config for TestRuntime { - // We use `UnpaidLocalExporter` with `ViaLocalBridgeHubExporter` here to test and ensure that `pallet_xcm_bridge_hub_router` can - // trigger directly `pallet_xcm_bridge_hub` as exporter. + // We use `UnpaidLocalExporter` with `ViaLocalBridgeHubExporter` here to test and ensure that + // `pallet_xcm_bridge_hub_router` can trigger directly `pallet_xcm_bridge_hub` as exporter. type ToBridgeHubSender = pallet_xcm_bridge_hub_router::impls::ViaLocalBridgeHubExporter< TestRuntime, XcmOverBridgeByExportXcmRouterInstance, - UnpaidLocalExporter + UnpaidLocalExporter, >; type BridgeIdResolver = @@ -550,10 +550,7 @@ impl Convert, Xcm<()>> for ReportBridgeStatusXcmProvider { fn convert(encoded_call: Vec) -> Xcm<()> { Xcm(vec![ UnpaidExecution { weight_limit: Unlimited, check_origin: None }, - Transact { - origin_kind: OriginKind::Xcm, - call: encoded_call.into(), - }, + Transact { origin_kind: OriginKind::Xcm, call: encoded_call.into() }, ExpectTransactStatus(MaybeErrorCode::Success), ]) } diff --git a/bridges/primitives/xcm-bridge-hub/src/call_info.rs b/bridges/primitives/xcm-bridge-hub/src/call_info.rs index 5fa93711b341..28323dbeed07 100644 --- a/bridges/primitives/xcm-bridge-hub/src/call_info.rs +++ b/bridges/primitives/xcm-bridge-hub/src/call_info.rs @@ -32,7 +32,8 @@ pub enum XcmBridgeHubCall { open_bridge { /// Universal `InteriorLocation` from the bridged consensus. bridge_destination_universal_location: Box, - /// Optional `maybe_notify` holds data about the `bridge_origin_relative_location` where notifications can be sent to handle congestion. + /// Optional `maybe_notify` holds data about the `bridge_origin_relative_location` where + /// notifications can be sent to handle congestion. maybe_notify: Option, }, /// `pallet_xcm_bridge_hub::Call::close_bridge` diff --git a/bridges/primitives/xcm-bridge-hub/src/lib.rs b/bridges/primitives/xcm-bridge-hub/src/lib.rs index 2a353b7fda13..719e7439cfa7 100644 --- a/bridges/primitives/xcm-bridge-hub/src/lib.rs +++ b/bridges/primitives/xcm-bridge-hub/src/lib.rs @@ -187,7 +187,16 @@ pub struct Bridge { /// Receiver metadata. #[derive( - CloneNoBound, Decode, Encode, Eq, PartialEqNoBound, TypeInfo, MaxEncodedLen, RuntimeDebugNoBound, Serialize, Deserialize, + CloneNoBound, + Decode, + Encode, + Eq, + PartialEqNoBound, + TypeInfo, + MaxEncodedLen, + RuntimeDebugNoBound, + Serialize, + Deserialize, )] pub struct Receiver { /// Pallet index. diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_westend_config.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_westend_config.rs index 1f0d2f1be715..2abfedfa8c4c 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_westend_config.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_westend_config.rs @@ -135,10 +135,7 @@ impl Convert, Xcm<()>> for ReportBridgeStatusXcmProvider { fn convert(encoded_call: Vec) -> Xcm<()> { Xcm(vec![ UnpaidExecution { weight_limit: Unlimited, check_origin: None }, - Transact { - origin_kind: OriginKind::Xcm, - call: encoded_call.into(), - }, + Transact { origin_kind: OriginKind::Xcm, call: encoded_call.into() }, ExpectTransactStatus(MaybeErrorCode::Success), ]) } diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/genesis_config_presets.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/genesis_config_presets.rs index c7c805bcd0b8..3a5a0c69a4a4 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/genesis_config_presets.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/genesis_config_presets.rs @@ -33,7 +33,12 @@ fn bridge_hub_rococo_genesis( id: ParaId, bridges_pallet_owner: Option, asset_hub_para_id: ParaId, - opened_bridges: Vec<(Location, InteriorLocation, Option, Option)>, + opened_bridges: Vec<( + Location, + InteriorLocation, + Option, + Option, + )>, ) -> serde_json::Value { build_struct_json_patch!(RuntimeGenesisConfig { balances: BalancesConfig { diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/bridge_to_rococo_config.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/bridge_to_rococo_config.rs index 48ce74d13b99..34fada7258f5 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/bridge_to_rococo_config.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/bridge_to_rococo_config.rs @@ -166,10 +166,7 @@ impl Convert, Xcm<()>> for ReportBridgeStatusXcmProvider { fn convert(encoded_call: Vec) -> Xcm<()> { Xcm(vec![ UnpaidExecution { weight_limit: Unlimited, check_origin: None }, - Transact { - origin_kind: OriginKind::Xcm, - call: encoded_call.into(), - }, + Transact { origin_kind: OriginKind::Xcm, call: encoded_call.into() }, ExpectTransactStatus(MaybeErrorCode::Success), ]) } diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/genesis_config_presets.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/genesis_config_presets.rs index ee736c7fa8d0..6dee7463c218 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/genesis_config_presets.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/genesis_config_presets.rs @@ -33,7 +33,12 @@ fn bridge_hub_westend_genesis( id: ParaId, bridges_pallet_owner: Option, asset_hub_para_id: ParaId, - opened_bridges: Vec<(Location, InteriorLocation, Option, Option)>, + opened_bridges: Vec<( + Location, + InteriorLocation, + Option, + Option, + )>, ) -> serde_json::Value { build_struct_json_patch!(RuntimeGenesisConfig { balances: BalancesConfig { From 4c1129cdcdb157a32c1b1f6eebe678c630a1b303 Mon Sep 17 00:00:00 2001 From: Branislav Kontur Date: Thu, 7 Nov 2024 16:36:34 +0100 Subject: [PATCH 27/72] Fix benchmarks --- .../xcm-bridge-hub-router/src/benchmarking.rs | 60 ++++++++++++------- .../modules/xcm-bridge-hub-router/src/mock.rs | 3 + .../assets/asset-hub-rococo/src/lib.rs | 3 + .../assets/asset-hub-westend/src/lib.rs | 3 + 4 files changed, 49 insertions(+), 20 deletions(-) diff --git a/bridges/modules/xcm-bridge-hub-router/src/benchmarking.rs b/bridges/modules/xcm-bridge-hub-router/src/benchmarking.rs index cc11533c86bb..e3ed02f14ad9 100644 --- a/bridges/modules/xcm-bridge-hub-router/src/benchmarking.rs +++ b/bridges/modules/xcm-bridge-hub-router/src/benchmarking.rs @@ -19,8 +19,8 @@ #![cfg(feature = "runtime-benchmarks")] use crate::{BridgeState, Bridges, Call, ResolveBridgeId, MINIMAL_DELIVERY_FEE_FACTOR}; -use frame_benchmarking::{benchmarks_instance_pallet, BenchmarkError, BenchmarkResult}; -use frame_support::traits::{EnsureOriginWithArg, Hooks, UnfilteredDispatchable}; +use frame_benchmarking::v2::*; +use frame_support::traits::{EnsureOriginWithArg, Hooks}; use sp_runtime::{traits::Zero, Saturating}; use xcm::prelude::*; @@ -29,32 +29,43 @@ pub struct Pallet, I: 'static = ()>(crate::Pallet); /// Trait that must be implemented by runtime to be able to benchmark pallet properly. pub trait Config: crate::Config { - // /// Fill up queue so it becomes congested. - // fn make_congested(); - // /// Returns destination which is valid for this router instance. fn ensure_bridged_target_destination() -> Result; + /// Returns valid origin for `report_bridge_status` (if `T::BridgeHubOrigin` is supported). + fn report_bridge_status_origin() -> Option; } -benchmarks_instance_pallet! { - on_initialize_when_bridge_state_removed { +#[instance_benchmarks] +mod benchmarks { + use super::*; + + #[benchmark] + fn on_initialize_when_bridge_state_removed() -> Result<(), BenchmarkError> { let bridge_id = T::BridgeIdResolver::resolve_for_dest(&T::ensure_bridged_target_destination()?) .ok_or(BenchmarkError::Weightless)?; + // uncongested and less than a minimal factor is removed Bridges::::insert(&bridge_id, BridgeState { delivery_fee_factor: 0.into(), is_congested: false, }); assert!(Bridges::::get(&bridge_id).is_some()); - }: { - crate::Pallet::::on_initialize(Zero::zero()) - } verify { + + #[block] + { + let _ = crate::Pallet::::on_initialize(Zero::zero()); + } + assert!(Bridges::::get(bridge_id).is_none()); + + Ok(()) } - on_initialize_when_bridge_state_updated { + #[benchmark] + fn on_initialize_when_bridge_state_updated() -> Result<(), BenchmarkError> { let bridge_id = T::BridgeIdResolver::resolve_for_dest(&T::ensure_bridged_target_destination()?) .ok_or(BenchmarkError::Weightless)?; + // uncongested and higher than a minimal factor is decreased let old_delivery_fee_factor = MINIMAL_DELIVERY_FEE_FACTOR.saturating_mul(1000.into()); Bridges::::insert(&bridge_id, BridgeState { @@ -62,21 +73,29 @@ benchmarks_instance_pallet! { is_congested: false, }); assert!(Bridges::::get(&bridge_id).is_some()); - }: { - crate::Pallet::::on_initialize(Zero::zero()) - } verify { + + #[block] + { + let _ = crate::Pallet::::on_initialize(Zero::zero()); + } + assert!(Bridges::::get(bridge_id).unwrap().delivery_fee_factor < old_delivery_fee_factor); + Ok(()) } - report_bridge_status { + #[benchmark] + fn report_bridge_status() -> Result<(), BenchmarkError> { let bridge_id = T::BridgeIdResolver::resolve_for_dest(&T::ensure_bridged_target_destination()?) .ok_or(BenchmarkError::Override(BenchmarkResult::from_weight(Weight::MAX)))?; - let origin: T::RuntimeOrigin = T::BridgeHubOrigin::try_successful_origin(&bridge_id).map_err(|_| BenchmarkError::Weightless)?; + let origin = T::report_bridge_status_origin() + .ok_or(BenchmarkError::Override(BenchmarkResult::from_weight(Weight::MAX)))?; + let _ = T::BridgeHubOrigin::try_origin(origin.clone(), &bridge_id) + .map_err(|_| BenchmarkError::Override(BenchmarkResult::from_weight(Weight::MAX)))?; let is_congested = true; - let call = Call::::report_bridge_status { bridge_id: bridge_id.clone(), is_congested }; - }: { call.dispatch_bypass_filter(origin)? } - verify { + #[extrinsic_call] + report_bridge_status(origin as T::RuntimeOrigin, bridge_id.clone(), is_congested); + assert_eq!( Bridges::::get(&bridge_id), Some(BridgeState { @@ -84,7 +103,8 @@ benchmarks_instance_pallet! { is_congested, }) ); + Ok(()) } - impl_benchmark_test_suite!(Pallet, crate::mock::new_test_ext(), crate::mock::TestRuntime) + impl_benchmark_test_suite!(Pallet, crate::mock::new_test_ext(), crate::mock::TestRuntime); } diff --git a/bridges/modules/xcm-bridge-hub-router/src/mock.rs b/bridges/modules/xcm-bridge-hub-router/src/mock.rs index e7c53579775d..16dd9b09629f 100644 --- a/bridges/modules/xcm-bridge-hub-router/src/mock.rs +++ b/bridges/modules/xcm-bridge-hub-router/src/mock.rs @@ -225,4 +225,7 @@ impl crate::benchmarking::Config<()> for TestRuntime { fn ensure_bridged_target_destination() -> Result { Ok(Location::new(2, [GlobalConsensus(BridgedNetworkId::get())])) } + fn report_bridge_status_origin() -> Option { + Some(RuntimeOrigin::root()) + } } diff --git a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs index 7b8eb43b7848..342f1a506e35 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs @@ -1713,6 +1713,9 @@ impl_runtime_apis! { fn ensure_bridged_target_destination() -> Result { Ok(xcm_config::bridging::to_westend::AssetHubWestend::get()) } + fn report_bridge_status_origin() -> Option { + Some(pallet_xcm::Origin::Xcm(xcm_config::bridging::SiblingBridgeHub::get()).into()) + } } use xcm_config::{TokenLocation, MaxAssetsIntoHolding}; diff --git a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs index 7da24dc02495..1bc55901ea42 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs @@ -1894,6 +1894,9 @@ impl_runtime_apis! { fn ensure_bridged_target_destination() -> Result { Ok(xcm_config::bridging::to_rococo::AssetHubRococo::get()) } + fn report_bridge_status_origin() -> Option { + Some(pallet_xcm::Origin::Xcm(xcm_config::bridging::SiblingBridgeHub::get()).into()) + } } use xcm_config::{MaxAssetsIntoHolding, WestendLocation}; From 3b8f8dbe8dafc9c7e246f52384feee8d6f72c680 Mon Sep 17 00:00:00 2001 From: Branislav Kontur Date: Thu, 7 Nov 2024 17:42:20 +0100 Subject: [PATCH 28/72] Fix benchmarks for BH --- bridges/modules/xcm-bridge-hub/src/lib.rs | 26 ++++++++ .../src/bridge_to_bulletin_config.rs | 49 -------------- .../src/bridge_to_westend_config.rs | 49 -------------- .../bridge-hubs/bridge-hub-rococo/src/lib.rs | 64 +++++++++++-------- .../src/bridge_to_rococo_config.rs | 49 -------------- .../bridge-hubs/bridge-hub-westend/src/lib.rs | 36 ++++++----- 6 files changed, 83 insertions(+), 190 deletions(-) diff --git a/bridges/modules/xcm-bridge-hub/src/lib.rs b/bridges/modules/xcm-bridge-hub/src/lib.rs index 7af7dbb96a21..55e57375c871 100644 --- a/bridges/modules/xcm-bridge-hub/src/lib.rs +++ b/bridges/modules/xcm-bridge-hub/src/lib.rs @@ -656,6 +656,32 @@ pub mod pallet { } } + #[cfg(feature = "runtime-benchmarks")] + impl, I: 'static> Pallet { + /// Open bridge for lane. + pub fn open_bridge_for_benchmarks( + lane_id: LaneIdOf, + bridge_origin_relative_location: Location, + bridge_destination_universal_location: InteriorLocation, + create_lanes: bool, + maybe_notify: Option, + ) -> Result, sp_runtime::DispatchError> { + let locations = Pallet::::bridge_locations( + bridge_origin_relative_location.into(), + bridge_destination_universal_location.into(), + )?; + + Pallet::::do_open_bridge( + locations.clone(), + lane_id, + create_lanes, + maybe_notify, + )?; + + Ok(locations) + } + } + #[cfg(any(test, feature = "try-runtime", feature = "std"))] impl, I: 'static> Pallet { /// Ensure the correctness of the state of this pallet. diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_bulletin_config.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_bulletin_config.rs index d18dd2afb998..6bc0100c5310 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_bulletin_config.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_bulletin_config.rs @@ -235,55 +235,6 @@ mod tests { } } -#[cfg(feature = "runtime-benchmarks")] -pub(crate) fn open_bridge_for_benchmarks( - with: pallet_xcm_bridge_hub::LaneIdOf, - sibling_para_id: u32, -) -> InteriorLocation -where - R: pallet_xcm_bridge_hub::Config, - XBHI: 'static, - C: xcm_executor::traits::ConvertLocation< - bp_runtime::AccountIdOf>, - >, -{ - use pallet_xcm_bridge_hub::{Bridge, BridgeId, BridgeState}; - use sp_runtime::traits::Zero; - use xcm::{latest::ROCOCO_GENESIS_HASH, VersionedInteriorLocation}; - - // insert bridge metadata - let lane_id = with; - let sibling_parachain = Location::new(1, [Parachain(sibling_para_id)]); - let universal_source = - [GlobalConsensus(ByGenesis(ROCOCO_GENESIS_HASH)), Parachain(sibling_para_id)].into(); - let universal_destination = - [GlobalConsensus(RococoBulletinGlobalConsensusNetwork::get()), Parachain(2075)].into(); - let bridge_id = BridgeId::new(&universal_source, &universal_destination); - - // insert only bridge metadata, because the benchmarks create lanes - pallet_xcm_bridge_hub::Bridges::::insert( - bridge_id, - Bridge { - bridge_origin_relative_location: alloc::boxed::Box::new( - sibling_parachain.clone().into(), - ), - bridge_origin_universal_location: alloc::boxed::Box::new( - VersionedInteriorLocation::from(universal_source.clone()), - ), - bridge_destination_universal_location: alloc::boxed::Box::new( - VersionedInteriorLocation::from(universal_destination), - ), - state: BridgeState::Opened, - bridge_owner_account: C::convert_location(&sibling_parachain).expect("valid AccountId"), - deposit: Zero::zero(), - lane_id, - }, - ); - pallet_xcm_bridge_hub::LaneToBridge::::insert(lane_id, bridge_id); - - universal_source -} - /// Contains the migration for the PeopleRococo<>RococoBulletin bridge. pub mod migration { use super::*; diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_westend_config.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_westend_config.rs index 2abfedfa8c4c..8c9a127bd1bc 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_westend_config.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_westend_config.rs @@ -193,55 +193,6 @@ impl pallet_xcm_bridge_hub::Config for Runtime >; } -#[cfg(feature = "runtime-benchmarks")] -pub(crate) fn open_bridge_for_benchmarks( - with: pallet_xcm_bridge_hub::LaneIdOf, - sibling_para_id: u32, -) -> InteriorLocation -where - R: pallet_xcm_bridge_hub::Config, - XBHI: 'static, - C: xcm_executor::traits::ConvertLocation< - bp_runtime::AccountIdOf>, - >, -{ - use pallet_xcm_bridge_hub::{Bridge, BridgeId, BridgeState}; - use sp_runtime::traits::Zero; - use xcm::{latest::ROCOCO_GENESIS_HASH, VersionedInteriorLocation}; - - // insert bridge metadata - let lane_id = with; - let sibling_parachain = Location::new(1, [Parachain(sibling_para_id)]); - let universal_source = - [GlobalConsensus(ByGenesis(ROCOCO_GENESIS_HASH)), Parachain(sibling_para_id)].into(); - let universal_destination = - [GlobalConsensus(ByGenesis(WESTEND_GENESIS_HASH)), Parachain(2075)].into(); - let bridge_id = BridgeId::new(&universal_source, &universal_destination); - - // insert only bridge metadata, because the benchmarks create lanes - pallet_xcm_bridge_hub::Bridges::::insert( - bridge_id, - Bridge { - bridge_origin_relative_location: alloc::boxed::Box::new( - sibling_parachain.clone().into(), - ), - bridge_origin_universal_location: alloc::boxed::Box::new( - VersionedInteriorLocation::from(universal_source.clone()), - ), - bridge_destination_universal_location: alloc::boxed::Box::new( - VersionedInteriorLocation::from(universal_destination), - ), - state: BridgeState::Opened, - bridge_owner_account: C::convert_location(&sibling_parachain).expect("valid AccountId"), - deposit: Zero::zero(), - lane_id, - }, - ); - pallet_xcm_bridge_hub::LaneToBridge::::insert(lane_id, bridge_id); - - universal_source -} - #[cfg(test)] mod tests { use super::*; diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs index 421f1e0a934f..bc4fdd247bc4 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs @@ -1278,14 +1278,12 @@ impl_runtime_apis! { // open bridge let bridge_destination_universal_location: InteriorLocation = [GlobalConsensus(NetworkId::ByGenesis(WESTEND_GENESIS_HASH)), Parachain(8765)].into(); - let locations = XcmOverBridgeHubWestend::bridge_locations( + let _ = XcmOverBridgeHubWestend::open_bridge_for_benchmarks( + bp_messages::LegacyLaneId([1, 2, 3, 4]), sibling_parachain_location.clone(), bridge_destination_universal_location.clone(), - )?; - XcmOverBridgeHubWestend::do_open_bridge( - locations, - bp_messages::LegacyLaneId([1, 2, 3, 4]), true, + None, ).map_err(|e| { log::error!( "Failed to `XcmOverBridgeHubWestend::open_bridge`({:?}, {:?})`, error: {:?}", @@ -1354,26 +1352,32 @@ impl_runtime_apis! { use cumulus_primitives_core::XcmpMessageSource; assert!(XcmpQueue::take_outbound_messages(usize::MAX).is_empty()); ParachainSystem::open_outbound_hrmp_channel_for_benchmarks_or_tests(42.into()); - let universal_source = bridge_to_westend_config::open_bridge_for_benchmarks::< - Runtime, - bridge_to_westend_config::XcmOverBridgeHubWestendInstance, - xcm_config::LocationToAccountId, - >(params.lane, 42); + let bridge_locations = XcmOverBridgeHubWestend::open_bridge_for_benchmarks( + params.lane, + Location::new(1, [Parachain(42)]), + [GlobalConsensus(bridge_to_westend_config::WestendGlobalConsensusNetwork::get()), Parachain(2075)].into(), + // do not create lanes, because they are already created `params.lane` + false, + None, + ).expect("valid bridge opened"); prepare_message_proof_from_parachain::< Runtime, bridge_common_config::BridgeGrandpaWestendInstance, bridge_to_westend_config::WithBridgeHubWestendMessagesInstance, - >(params, generate_xcm_builder_bridge_message_sample(universal_source)) + >(params, generate_xcm_builder_bridge_message_sample(bridge_locations.bridge_origin_universal_location().clone())) } fn prepare_message_delivery_proof( params: MessageDeliveryProofParams>, ) -> bridge_to_westend_config::ToWestendBridgeHubMessagesDeliveryProof { - let _ = bridge_to_westend_config::open_bridge_for_benchmarks::< - Runtime, - bridge_to_westend_config::XcmOverBridgeHubWestendInstance, - xcm_config::LocationToAccountId, - >(params.lane, 42); + let _ = XcmOverBridgeHubWestend::open_bridge_for_benchmarks( + params.lane, + Location::new(1, [Parachain(42)]), + [GlobalConsensus(bridge_to_westend_config::WestendGlobalConsensusNetwork::get()), Parachain(2075)].into(), + // do not create lanes, because they are already created `params.lane` + false, + None, + ); prepare_message_delivery_proof_from_parachain::< Runtime, bridge_common_config::BridgeGrandpaWestendInstance, @@ -1399,26 +1403,32 @@ impl_runtime_apis! { use cumulus_primitives_core::XcmpMessageSource; assert!(XcmpQueue::take_outbound_messages(usize::MAX).is_empty()); ParachainSystem::open_outbound_hrmp_channel_for_benchmarks_or_tests(42.into()); - let universal_source = bridge_to_bulletin_config::open_bridge_for_benchmarks::< - Runtime, - bridge_to_bulletin_config::XcmOverPolkadotBulletinInstance, - xcm_config::LocationToAccountId, - >(params.lane, 42); + let bridge_locations = XcmOverPolkadotBulletin::open_bridge_for_benchmarks( + params.lane, + Location::new(1, [Parachain(42)]), + [GlobalConsensus(bridge_to_bulletin_config::RococoBulletinGlobalConsensusNetwork::get())].into(), + // do not create lanes, because they are already created `params.lane` + false, + None, + ).expect("valid bridge opened"); prepare_message_proof_from_grandpa_chain::< Runtime, bridge_common_config::BridgeGrandpaRococoBulletinInstance, bridge_to_bulletin_config::WithRococoBulletinMessagesInstance, - >(params, generate_xcm_builder_bridge_message_sample(universal_source)) + >(params, generate_xcm_builder_bridge_message_sample(bridge_locations.bridge_origin_universal_location().clone())) } fn prepare_message_delivery_proof( params: MessageDeliveryProofParams>, ) -> bridge_to_bulletin_config::ToRococoBulletinMessagesDeliveryProof { - let _ = bridge_to_bulletin_config::open_bridge_for_benchmarks::< - Runtime, - bridge_to_bulletin_config::XcmOverPolkadotBulletinInstance, - xcm_config::LocationToAccountId, - >(params.lane, 42); + let _ = XcmOverPolkadotBulletin::open_bridge_for_benchmarks( + params.lane, + Location::new(1, [Parachain(42)]), + [GlobalConsensus(bridge_to_bulletin_config::RococoBulletinGlobalConsensusNetwork::get())].into(), + // do not create lanes, because they are already created `params.lane` + false, + None, + ).expect("valid bridge opened"); prepare_message_delivery_proof_from_grandpa_chain::< Runtime, bridge_common_config::BridgeGrandpaRococoBulletinInstance, diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/bridge_to_rococo_config.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/bridge_to_rococo_config.rs index 34fada7258f5..0e8402aefc59 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/bridge_to_rococo_config.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/bridge_to_rococo_config.rs @@ -222,55 +222,6 @@ impl pallet_xcm_bridge_hub::Config for Runtime { >; } -#[cfg(feature = "runtime-benchmarks")] -pub(crate) fn open_bridge_for_benchmarks( - with: pallet_xcm_bridge_hub::LaneIdOf, - sibling_para_id: u32, -) -> InteriorLocation -where - R: pallet_xcm_bridge_hub::Config, - XBHI: 'static, - C: xcm_executor::traits::ConvertLocation< - bp_runtime::AccountIdOf>, - >, -{ - use pallet_xcm_bridge_hub::{Bridge, BridgeId, BridgeState}; - use sp_runtime::traits::Zero; - use xcm::{latest::WESTEND_GENESIS_HASH, VersionedInteriorLocation}; - - // insert bridge metadata - let lane_id = with; - let sibling_parachain = Location::new(1, [Parachain(sibling_para_id)]); - let universal_source = - [GlobalConsensus(ByGenesis(WESTEND_GENESIS_HASH)), Parachain(sibling_para_id)].into(); - let universal_destination = - [GlobalConsensus(ByGenesis(ROCOCO_GENESIS_HASH)), Parachain(2075)].into(); - let bridge_id = BridgeId::new(&universal_source, &universal_destination); - - // insert only bridge metadata, because the benchmarks create lanes - pallet_xcm_bridge_hub::Bridges::::insert( - bridge_id, - Bridge { - bridge_origin_relative_location: alloc::boxed::Box::new( - sibling_parachain.clone().into(), - ), - bridge_origin_universal_location: alloc::boxed::Box::new( - VersionedInteriorLocation::from(universal_source.clone()), - ), - bridge_destination_universal_location: alloc::boxed::Box::new( - VersionedInteriorLocation::from(universal_destination), - ), - state: BridgeState::Opened, - bridge_owner_account: C::convert_location(&sibling_parachain).expect("valid AccountId"), - deposit: Zero::zero(), - lane_id, - }, - ); - pallet_xcm_bridge_hub::LaneToBridge::::insert(lane_id, bridge_id); - - universal_source -} - #[cfg(test)] mod tests { use super::*; diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs index 5f953c7c0640..4033b6101bac 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs @@ -1163,14 +1163,12 @@ impl_runtime_apis! { // open bridge let bridge_destination_universal_location: InteriorLocation = [GlobalConsensus(ByGenesis(ROCOCO_GENESIS_HASH)), Parachain(8765)].into(); - let locations = XcmOverBridgeHubRococo::bridge_locations( + let _ = XcmOverBridgeHubRococo::open_bridge_for_benchmarks( + bp_messages::LegacyLaneId([1, 2, 3, 4]), sibling_parachain_location.clone(), bridge_destination_universal_location.clone(), - )?; - XcmOverBridgeHubRococo::do_open_bridge( - locations, - bp_messages::LegacyLaneId([1, 2, 3, 4]), true, + None, ).map_err(|e| { log::error!( "Failed to `XcmOverBridgeHubRococo::open_bridge`({:?}, {:?})`, error: {:?}", @@ -1234,26 +1232,32 @@ impl_runtime_apis! { use cumulus_primitives_core::XcmpMessageSource; assert!(XcmpQueue::take_outbound_messages(usize::MAX).is_empty()); ParachainSystem::open_outbound_hrmp_channel_for_benchmarks_or_tests(42.into()); - let universal_source = bridge_to_rococo_config::open_bridge_for_benchmarks::< - Runtime, - bridge_to_rococo_config::XcmOverBridgeHubRococoInstance, - xcm_config::LocationToAccountId, - >(params.lane, 42); + let bridge_locations = XcmOverBridgeHubRococo::open_bridge_for_benchmarks( + params.lane, + Location::new(1, [Parachain(42)]), + [GlobalConsensus(bridge_to_rococo_config::RococoGlobalConsensusNetwork::get()), Parachain(2075)].into(), + // do not create lanes, because they are already created `params.lane` + false, + None, + ).expect("valid bridge opened"); prepare_message_proof_from_parachain::< Runtime, bridge_to_rococo_config::BridgeGrandpaRococoInstance, bridge_to_rococo_config::WithBridgeHubRococoMessagesInstance, - >(params, generate_xcm_builder_bridge_message_sample(universal_source)) + >(params, generate_xcm_builder_bridge_message_sample(bridge_locations.bridge_origin_universal_location().clone())) } fn prepare_message_delivery_proof( params: MessageDeliveryProofParams>, ) -> bridge_to_rococo_config::ToRococoBridgeHubMessagesDeliveryProof { - let _ = bridge_to_rococo_config::open_bridge_for_benchmarks::< - Runtime, - bridge_to_rococo_config::XcmOverBridgeHubRococoInstance, - xcm_config::LocationToAccountId, - >(params.lane, 42); + let _ = XcmOverBridgeHubRococo::open_bridge_for_benchmarks( + params.lane, + Location::new(1, [Parachain(42)]), + [GlobalConsensus(bridge_to_rococo_config::RococoGlobalConsensusNetwork::get()), Parachain(2075)].into(), + // do not create lanes, because they are already created `params.lane` + false, + None, + ); prepare_message_delivery_proof_from_parachain::< Runtime, bridge_to_rococo_config::BridgeGrandpaRococoInstance, From b557388690393cbedd5f8a9691338b7fed2bc754 Mon Sep 17 00:00:00 2001 From: GitHub Action Date: Thu, 7 Nov 2024 16:47:55 +0000 Subject: [PATCH 29/72] Update from bkontur running command 'fmt' --- .../xcm-bridge-hub-router/src/benchmarking.rs | 40 ++++++++++--------- bridges/modules/xcm-bridge-hub/src/lib.rs | 7 +--- 2 files changed, 22 insertions(+), 25 deletions(-) diff --git a/bridges/modules/xcm-bridge-hub-router/src/benchmarking.rs b/bridges/modules/xcm-bridge-hub-router/src/benchmarking.rs index e3ed02f14ad9..0b7061db5d6c 100644 --- a/bridges/modules/xcm-bridge-hub-router/src/benchmarking.rs +++ b/bridges/modules/xcm-bridge-hub-router/src/benchmarking.rs @@ -41,14 +41,15 @@ mod benchmarks { #[benchmark] fn on_initialize_when_bridge_state_removed() -> Result<(), BenchmarkError> { - let bridge_id = T::BridgeIdResolver::resolve_for_dest(&T::ensure_bridged_target_destination()?) - .ok_or(BenchmarkError::Weightless)?; + let bridge_id = + T::BridgeIdResolver::resolve_for_dest(&T::ensure_bridged_target_destination()?) + .ok_or(BenchmarkError::Weightless)?; // uncongested and less than a minimal factor is removed - Bridges::::insert(&bridge_id, BridgeState { - delivery_fee_factor: 0.into(), - is_congested: false, - }); + Bridges::::insert( + &bridge_id, + BridgeState { delivery_fee_factor: 0.into(), is_congested: false }, + ); assert!(Bridges::::get(&bridge_id).is_some()); #[block] @@ -63,15 +64,16 @@ mod benchmarks { #[benchmark] fn on_initialize_when_bridge_state_updated() -> Result<(), BenchmarkError> { - let bridge_id = T::BridgeIdResolver::resolve_for_dest(&T::ensure_bridged_target_destination()?) - .ok_or(BenchmarkError::Weightless)?; + let bridge_id = + T::BridgeIdResolver::resolve_for_dest(&T::ensure_bridged_target_destination()?) + .ok_or(BenchmarkError::Weightless)?; // uncongested and higher than a minimal factor is decreased let old_delivery_fee_factor = MINIMAL_DELIVERY_FEE_FACTOR.saturating_mul(1000.into()); - Bridges::::insert(&bridge_id, BridgeState { - delivery_fee_factor: old_delivery_fee_factor, - is_congested: false, - }); + Bridges::::insert( + &bridge_id, + BridgeState { delivery_fee_factor: old_delivery_fee_factor, is_congested: false }, + ); assert!(Bridges::::get(&bridge_id).is_some()); #[block] @@ -79,14 +81,17 @@ mod benchmarks { let _ = crate::Pallet::::on_initialize(Zero::zero()); } - assert!(Bridges::::get(bridge_id).unwrap().delivery_fee_factor < old_delivery_fee_factor); + assert!( + Bridges::::get(bridge_id).unwrap().delivery_fee_factor < old_delivery_fee_factor + ); Ok(()) } #[benchmark] fn report_bridge_status() -> Result<(), BenchmarkError> { - let bridge_id = T::BridgeIdResolver::resolve_for_dest(&T::ensure_bridged_target_destination()?) - .ok_or(BenchmarkError::Override(BenchmarkResult::from_weight(Weight::MAX)))?; + let bridge_id = + T::BridgeIdResolver::resolve_for_dest(&T::ensure_bridged_target_destination()?) + .ok_or(BenchmarkError::Override(BenchmarkResult::from_weight(Weight::MAX)))?; let origin = T::report_bridge_status_origin() .ok_or(BenchmarkError::Override(BenchmarkResult::from_weight(Weight::MAX)))?; let _ = T::BridgeHubOrigin::try_origin(origin.clone(), &bridge_id) @@ -98,10 +103,7 @@ mod benchmarks { assert_eq!( Bridges::::get(&bridge_id), - Some(BridgeState { - delivery_fee_factor: MINIMAL_DELIVERY_FEE_FACTOR, - is_congested, - }) + Some(BridgeState { delivery_fee_factor: MINIMAL_DELIVERY_FEE_FACTOR, is_congested }) ); Ok(()) } diff --git a/bridges/modules/xcm-bridge-hub/src/lib.rs b/bridges/modules/xcm-bridge-hub/src/lib.rs index 55e57375c871..0f30dbb5bf89 100644 --- a/bridges/modules/xcm-bridge-hub/src/lib.rs +++ b/bridges/modules/xcm-bridge-hub/src/lib.rs @@ -671,12 +671,7 @@ pub mod pallet { bridge_destination_universal_location.into(), )?; - Pallet::::do_open_bridge( - locations.clone(), - lane_id, - create_lanes, - maybe_notify, - )?; + Pallet::::do_open_bridge(locations.clone(), lane_id, create_lanes, maybe_notify)?; Ok(locations) } From ca045ea1511595575cecedae5bb787bd9b611fdf Mon Sep 17 00:00:00 2001 From: command-bot <> Date: Thu, 7 Nov 2024 18:02:40 +0000 Subject: [PATCH 30/72] ".git/.scripts/commands/bench/bench.sh" --subcommand=pallet --runtime=asset-hub-westend --runtime_dir=assets --target_dir=cumulus --pallet=pallet_xcm_bridge_hub_router --- .../weights/pallet_xcm_bridge_hub_router.rs | 47 ++++++++++++------- 1 file changed, 31 insertions(+), 16 deletions(-) diff --git a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/pallet_xcm_bridge_hub_router.rs b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/pallet_xcm_bridge_hub_router.rs index ec72a522356c..0e6d9746d24a 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/pallet_xcm_bridge_hub_router.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/pallet_xcm_bridge_hub_router.rs @@ -17,9 +17,9 @@ //! Autogenerated weights for `pallet_xcm_bridge_hub_router` //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-08-15, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2024-11-07, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-696hpswk-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! HOSTNAME: `runner-vcatxqpx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("asset-hub-westend-dev")`, DB CACHE: 1024 // Executed Command: @@ -44,29 +44,44 @@ 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(PhantomData); impl pallet_xcm_bridge_hub_router::WeightInfo for WeightInfo { - // TODO: FAIL-CI + /// Storage: `ToRococoXcmRouter::Bridges` (r:2 w:1) + /// Proof: `ToRococoXcmRouter::Bridges` (`max_values`: None, `max_size`: Some(65), added: 2540, mode: `MaxEncodedLen`) fn on_initialize_when_bridge_state_removed() -> Weight { - RocksDbWeight::get().writes(1) + // Proof Size summary in bytes: + // Measured: `204` + // Estimated: `6070` + // Minimum execution time: 19_250_000 picoseconds. + Weight::from_parts(20_167_000, 0) + .saturating_add(Weight::from_parts(0, 6070)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) } - - // TODO: FAIL-CI + /// Storage: `ToRococoXcmRouter::Bridges` (r:2 w:1) + /// Proof: `ToRococoXcmRouter::Bridges` (`max_values`: None, `max_size`: Some(65), added: 2540, mode: `MaxEncodedLen`) fn on_initialize_when_bridge_state_updated() -> Weight { - RocksDbWeight::get().writes(1) + // Proof Size summary in bytes: + // Measured: `204` + // Estimated: `6070` + // Minimum execution time: 20_210_000 picoseconds. + Weight::from_parts(20_675_000, 0) + .saturating_add(Weight::from_parts(0, 6070)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) } - - // TODO: FAIL-CI + /// Storage: `ToRococoXcmRouter::Bridges` (r:1 w:1) + /// Proof: `ToRococoXcmRouter::Bridges` (`max_values`: None, `max_size`: Some(65), added: 2540, mode: `MaxEncodedLen`) 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)) + // Measured: `109` + // Estimated: `3530` + // Minimum execution time: 10_622_000 picoseconds. + Weight::from_parts(11_047_000, 0) + .saturating_add(Weight::from_parts(0, 3530)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) } } From 78afc1cceca0e97f818cf0a6d396504ac73c3d87 Mon Sep 17 00:00:00 2001 From: command-bot <> Date: Thu, 7 Nov 2024 18:03:12 +0000 Subject: [PATCH 31/72] ".git/.scripts/commands/bench/bench.sh" --subcommand=pallet --runtime=asset-hub-rococo --runtime_dir=assets --target_dir=cumulus --pallet=pallet_xcm_bridge_hub_router --- .../weights/pallet_xcm_bridge_hub_router.rs | 47 ++++++++++++------- 1 file changed, 31 insertions(+), 16 deletions(-) diff --git a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/pallet_xcm_bridge_hub_router.rs b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/pallet_xcm_bridge_hub_router.rs index 1532fa8aaa2d..712b22847d33 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/pallet_xcm_bridge_hub_router.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/pallet_xcm_bridge_hub_router.rs @@ -17,9 +17,9 @@ //! Autogenerated weights for `pallet_xcm_bridge_hub_router` //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-08-15, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2024-11-07, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-696hpswk-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! HOSTNAME: `runner-vcatxqpx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("asset-hub-rococo-dev")`, DB CACHE: 1024 // Executed Command: @@ -44,29 +44,44 @@ 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(PhantomData); impl pallet_xcm_bridge_hub_router::WeightInfo for WeightInfo { - // TODO: FAIL-CI + /// Storage: `ToWestendXcmRouter::Bridges` (r:2 w:1) + /// Proof: `ToWestendXcmRouter::Bridges` (`max_values`: None, `max_size`: Some(65), added: 2540, mode: `MaxEncodedLen`) fn on_initialize_when_bridge_state_removed() -> Weight { - RocksDbWeight::get().writes(1) + // Proof Size summary in bytes: + // Measured: `204` + // Estimated: `6070` + // Minimum execution time: 19_370_000 picoseconds. + Weight::from_parts(19_928_000, 0) + .saturating_add(Weight::from_parts(0, 6070)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) } - - // TODO: FAIL-CI + /// Storage: `ToWestendXcmRouter::Bridges` (r:2 w:1) + /// Proof: `ToWestendXcmRouter::Bridges` (`max_values`: None, `max_size`: Some(65), added: 2540, mode: `MaxEncodedLen`) fn on_initialize_when_bridge_state_updated() -> Weight { - RocksDbWeight::get().writes(1) + // Proof Size summary in bytes: + // Measured: `204` + // Estimated: `6070` + // Minimum execution time: 20_045_000 picoseconds. + Weight::from_parts(20_861_000, 0) + .saturating_add(Weight::from_parts(0, 6070)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) } - - // TODO: FAIL-CI + /// Storage: `ToWestendXcmRouter::Bridges` (r:1 w:1) + /// Proof: `ToWestendXcmRouter::Bridges` (`max_values`: None, `max_size`: Some(65), added: 2540, mode: `MaxEncodedLen`) 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)) + // Measured: `109` + // Estimated: `3530` + // Minimum execution time: 12_179_000 picoseconds. + Weight::from_parts(12_679_000, 0) + .saturating_add(Weight::from_parts(0, 3530)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) } } From 4d16cc559b75fa4a85625c4dd3b3aa4b57eeb2ba Mon Sep 17 00:00:00 2001 From: command-bot <> Date: Thu, 7 Nov 2024 18:08:34 +0000 Subject: [PATCH 32/72] ".git/.scripts/commands/bench/bench.sh" --subcommand=pallet --runtime=bridge-hub-westend --runtime_dir=bridge-hubs --target_dir=cumulus --pallet=pallet_bridge_messages --- .../src/weights/pallet_bridge_messages.rs | 176 +++++++++--------- 1 file changed, 92 insertions(+), 84 deletions(-) diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/pallet_bridge_messages.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/pallet_bridge_messages.rs index 492226d3ec2b..3163a5de4122 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/pallet_bridge_messages.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/pallet_bridge_messages.rs @@ -17,9 +17,9 @@ //! Autogenerated weights for `pallet_bridge_messages` //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-08-15, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2024-11-07, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-696hpswk-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! HOSTNAME: `runner-vcatxqpx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("bridge-hub-westend-dev")`, DB CACHE: 1024 // Executed Command: @@ -53,21 +53,23 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< /// Storage: `BridgeRococoParachains::ImportedParaHeads` (r:1 w:0) /// Proof: `BridgeRococoParachains::ImportedParaHeads` (`max_values`: Some(64), `max_size`: Some(196), added: 1186, mode: `MaxEncodedLen`) /// Storage: `BridgeRococoMessages::InboundLanes` (r:1 w:1) - /// Proof: `BridgeRococoMessages::InboundLanes` (`max_values`: None, `max_size`: Some(49209), added: 51684, mode: `MaxEncodedLen`) + /// Proof: `BridgeRococoMessages::InboundLanes` (`max_values`: None, `max_size`: Some(49180), added: 51655, mode: `MaxEncodedLen`) /// Storage: `XcmOverBridgeHubRococo::LaneToBridge` (r:1 w:0) - /// Proof: `XcmOverBridgeHubRococo::LaneToBridge` (`max_values`: None, `max_size`: Some(65), added: 2540, mode: `MaxEncodedLen`) + /// Proof: `XcmOverBridgeHubRococo::LaneToBridge` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `MaxEncodedLen`) /// Storage: `XcmOverBridgeHubRococo::Bridges` (r:1 w:0) - /// Proof: `XcmOverBridgeHubRococo::Bridges` (`max_values`: None, `max_size`: Some(1918), added: 4393, mode: `MaxEncodedLen`) + /// Proof: `XcmOverBridgeHubRococo::Bridges` (`max_values`: None, `max_size`: Some(1893), added: 4368, mode: `MaxEncodedLen`) + /// Storage: `XcmpQueue::OutboundXcmpStatus` (r:1 w:0) + /// Proof: `XcmpQueue::OutboundXcmpStatus` (`max_values`: Some(1), `max_size`: Some(1282), added: 1777, mode: `MaxEncodedLen`) /// Storage: `ParachainInfo::ParachainId` (r:1 w:0) /// Proof: `ParachainInfo::ParachainId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) fn receive_single_message_proof() -> Weight { // Proof Size summary in bytes: - // Measured: `701` - // Estimated: `52674` - // Minimum execution time: 62_015_000 picoseconds. - Weight::from_parts(63_891_000, 0) - .saturating_add(Weight::from_parts(0, 52674)) - .saturating_add(T::DbWeight::get().reads(6)) + // Measured: `765` + // Estimated: `52645` + // Minimum execution time: 59_962_000 picoseconds. + Weight::from_parts(62_031_000, 0) + .saturating_add(Weight::from_parts(0, 52645)) + .saturating_add(T::DbWeight::get().reads(7)) .saturating_add(T::DbWeight::get().writes(1)) } /// Storage: `BridgeRococoMessages::PalletOperatingMode` (r:1 w:0) @@ -75,24 +77,26 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< /// Storage: `BridgeRococoParachains::ImportedParaHeads` (r:1 w:0) /// Proof: `BridgeRococoParachains::ImportedParaHeads` (`max_values`: Some(64), `max_size`: Some(196), added: 1186, mode: `MaxEncodedLen`) /// Storage: `BridgeRococoMessages::InboundLanes` (r:1 w:1) - /// Proof: `BridgeRococoMessages::InboundLanes` (`max_values`: None, `max_size`: Some(49209), added: 51684, mode: `MaxEncodedLen`) + /// Proof: `BridgeRococoMessages::InboundLanes` (`max_values`: None, `max_size`: Some(49180), added: 51655, mode: `MaxEncodedLen`) /// Storage: `XcmOverBridgeHubRococo::LaneToBridge` (r:1 w:0) - /// Proof: `XcmOverBridgeHubRococo::LaneToBridge` (`max_values`: None, `max_size`: Some(65), added: 2540, mode: `MaxEncodedLen`) + /// Proof: `XcmOverBridgeHubRococo::LaneToBridge` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `MaxEncodedLen`) /// Storage: `XcmOverBridgeHubRococo::Bridges` (r:1 w:0) - /// Proof: `XcmOverBridgeHubRococo::Bridges` (`max_values`: None, `max_size`: Some(1918), added: 4393, mode: `MaxEncodedLen`) + /// Proof: `XcmOverBridgeHubRococo::Bridges` (`max_values`: None, `max_size`: Some(1893), added: 4368, mode: `MaxEncodedLen`) + /// Storage: `XcmpQueue::OutboundXcmpStatus` (r:1 w:0) + /// Proof: `XcmpQueue::OutboundXcmpStatus` (`max_values`: Some(1), `max_size`: Some(1282), added: 1777, mode: `MaxEncodedLen`) /// Storage: `ParachainInfo::ParachainId` (r:1 w:0) /// Proof: `ParachainInfo::ParachainId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) /// The range of component `n` is `[1, 4076]`. fn receive_n_messages_proof(n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `701` - // Estimated: `52674` - // Minimum execution time: 62_034_000 picoseconds. - Weight::from_parts(63_355_000, 0) - .saturating_add(Weight::from_parts(0, 52674)) - // Standard Error: 8_231 - .saturating_add(Weight::from_parts(14_096_117, 0).saturating_mul(n.into())) - .saturating_add(T::DbWeight::get().reads(6)) + // Measured: `765` + // Estimated: `52645` + // Minimum execution time: 59_978_000 picoseconds. + Weight::from_parts(61_443_000, 0) + .saturating_add(Weight::from_parts(0, 52645)) + // Standard Error: 21_207 + .saturating_add(Weight::from_parts(12_190_114, 0).saturating_mul(n.into())) + .saturating_add(T::DbWeight::get().reads(7)) .saturating_add(T::DbWeight::get().writes(1)) } /// Storage: `BridgeRococoMessages::PalletOperatingMode` (r:1 w:0) @@ -100,21 +104,23 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< /// Storage: `BridgeRococoParachains::ImportedParaHeads` (r:1 w:0) /// Proof: `BridgeRococoParachains::ImportedParaHeads` (`max_values`: Some(64), `max_size`: Some(196), added: 1186, mode: `MaxEncodedLen`) /// Storage: `BridgeRococoMessages::InboundLanes` (r:1 w:1) - /// Proof: `BridgeRococoMessages::InboundLanes` (`max_values`: None, `max_size`: Some(49209), added: 51684, mode: `MaxEncodedLen`) + /// Proof: `BridgeRococoMessages::InboundLanes` (`max_values`: None, `max_size`: Some(49180), added: 51655, mode: `MaxEncodedLen`) /// Storage: `XcmOverBridgeHubRococo::LaneToBridge` (r:1 w:0) - /// Proof: `XcmOverBridgeHubRococo::LaneToBridge` (`max_values`: None, `max_size`: Some(65), added: 2540, mode: `MaxEncodedLen`) + /// Proof: `XcmOverBridgeHubRococo::LaneToBridge` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `MaxEncodedLen`) /// Storage: `XcmOverBridgeHubRococo::Bridges` (r:1 w:0) - /// Proof: `XcmOverBridgeHubRococo::Bridges` (`max_values`: None, `max_size`: Some(1918), added: 4393, mode: `MaxEncodedLen`) + /// Proof: `XcmOverBridgeHubRococo::Bridges` (`max_values`: None, `max_size`: Some(1893), added: 4368, mode: `MaxEncodedLen`) + /// Storage: `XcmpQueue::OutboundXcmpStatus` (r:1 w:0) + /// Proof: `XcmpQueue::OutboundXcmpStatus` (`max_values`: Some(1), `max_size`: Some(1282), added: 1777, mode: `MaxEncodedLen`) /// Storage: `ParachainInfo::ParachainId` (r:1 w:0) /// Proof: `ParachainInfo::ParachainId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) fn receive_single_message_proof_with_outbound_lane_state() -> Weight { // Proof Size summary in bytes: - // Measured: `701` - // Estimated: `52674` - // Minimum execution time: 65_063_000 picoseconds. - Weight::from_parts(67_125_000, 0) - .saturating_add(Weight::from_parts(0, 52674)) - .saturating_add(T::DbWeight::get().reads(6)) + // Measured: `765` + // Estimated: `52645` + // Minimum execution time: 67_636_000 picoseconds. + Weight::from_parts(70_662_000, 0) + .saturating_add(Weight::from_parts(0, 52645)) + .saturating_add(T::DbWeight::get().reads(7)) .saturating_add(T::DbWeight::get().writes(1)) } /// Storage: `BridgeRococoMessages::PalletOperatingMode` (r:1 w:0) @@ -122,24 +128,26 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< /// Storage: `BridgeRococoParachains::ImportedParaHeads` (r:1 w:0) /// Proof: `BridgeRococoParachains::ImportedParaHeads` (`max_values`: Some(64), `max_size`: Some(196), added: 1186, mode: `MaxEncodedLen`) /// Storage: `BridgeRococoMessages::InboundLanes` (r:1 w:1) - /// Proof: `BridgeRococoMessages::InboundLanes` (`max_values`: None, `max_size`: Some(49209), added: 51684, mode: `MaxEncodedLen`) + /// Proof: `BridgeRococoMessages::InboundLanes` (`max_values`: None, `max_size`: Some(49180), added: 51655, mode: `MaxEncodedLen`) /// Storage: `XcmOverBridgeHubRococo::LaneToBridge` (r:1 w:0) - /// Proof: `XcmOverBridgeHubRococo::LaneToBridge` (`max_values`: None, `max_size`: Some(65), added: 2540, mode: `MaxEncodedLen`) + /// Proof: `XcmOverBridgeHubRococo::LaneToBridge` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `MaxEncodedLen`) /// Storage: `XcmOverBridgeHubRococo::Bridges` (r:1 w:0) - /// Proof: `XcmOverBridgeHubRococo::Bridges` (`max_values`: None, `max_size`: Some(1918), added: 4393, mode: `MaxEncodedLen`) + /// Proof: `XcmOverBridgeHubRococo::Bridges` (`max_values`: None, `max_size`: Some(1893), added: 4368, mode: `MaxEncodedLen`) + /// Storage: `XcmpQueue::OutboundXcmpStatus` (r:1 w:0) + /// Proof: `XcmpQueue::OutboundXcmpStatus` (`max_values`: Some(1), `max_size`: Some(1282), added: 1777, mode: `MaxEncodedLen`) /// Storage: `ParachainInfo::ParachainId` (r:1 w:0) /// Proof: `ParachainInfo::ParachainId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) /// The range of component `n` is `[1, 16384]`. fn receive_single_n_bytes_message_proof(n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `701` - // Estimated: `52674` - // Minimum execution time: 58_688_000 picoseconds. - Weight::from_parts(61_404_716, 0) - .saturating_add(Weight::from_parts(0, 52674)) - // Standard Error: 7 - .saturating_add(Weight::from_parts(2_249, 0).saturating_mul(n.into())) - .saturating_add(T::DbWeight::get().reads(6)) + // Measured: `765` + // Estimated: `52645` + // Minimum execution time: 60_681_000 picoseconds. + Weight::from_parts(65_061_839, 0) + .saturating_add(Weight::from_parts(0, 52645)) + // Standard Error: 17 + .saturating_add(Weight::from_parts(2_093, 0).saturating_mul(n.into())) + .saturating_add(T::DbWeight::get().reads(7)) .saturating_add(T::DbWeight::get().writes(1)) } /// Storage: `BridgeRococoMessages::PalletOperatingMode` (r:1 w:0) @@ -147,24 +155,24 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< /// Storage: `BridgeRococoParachains::ImportedParaHeads` (r:1 w:0) /// Proof: `BridgeRococoParachains::ImportedParaHeads` (`max_values`: Some(64), `max_size`: Some(196), added: 1186, mode: `MaxEncodedLen`) /// Storage: `BridgeRococoMessages::OutboundLanes` (r:1 w:1) - /// Proof: `BridgeRococoMessages::OutboundLanes` (`max_values`: None, `max_size`: Some(74), added: 2549, mode: `MaxEncodedLen`) + /// Proof: `BridgeRococoMessages::OutboundLanes` (`max_values`: None, `max_size`: Some(45), added: 2520, mode: `MaxEncodedLen`) /// Storage: UNKNOWN KEY `0x6e0a18b62a1de81c5f519181cc611e18` (r:1 w:0) /// Proof: UNKNOWN KEY `0x6e0a18b62a1de81c5f519181cc611e18` (r:1 w:0) /// Storage: `BridgeRelayers::RelayerRewards` (r:1 w:1) - /// Proof: `BridgeRelayers::RelayerRewards` (`max_values`: None, `max_size`: Some(102), added: 2577, mode: `MaxEncodedLen`) + /// Proof: `BridgeRelayers::RelayerRewards` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) /// Storage: `XcmOverBridgeHubRococo::LaneToBridge` (r:1 w:0) - /// Proof: `XcmOverBridgeHubRococo::LaneToBridge` (`max_values`: None, `max_size`: Some(65), added: 2540, mode: `MaxEncodedLen`) + /// Proof: `XcmOverBridgeHubRococo::LaneToBridge` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `MaxEncodedLen`) /// Storage: `XcmOverBridgeHubRococo::Bridges` (r:1 w:0) - /// Proof: `XcmOverBridgeHubRococo::Bridges` (`max_values`: None, `max_size`: Some(1918), added: 4393, mode: `MaxEncodedLen`) + /// Proof: `XcmOverBridgeHubRococo::Bridges` (`max_values`: None, `max_size`: Some(1893), added: 4368, mode: `MaxEncodedLen`) /// Storage: `BridgeRococoMessages::OutboundMessages` (r:0 w:1) - /// Proof: `BridgeRococoMessages::OutboundMessages` (`max_values`: None, `max_size`: Some(65597), added: 68072, mode: `MaxEncodedLen`) + /// Proof: `BridgeRococoMessages::OutboundMessages` (`max_values`: None, `max_size`: Some(65568), added: 68043, mode: `MaxEncodedLen`) fn receive_delivery_proof_for_single_message() -> Weight { // Proof Size summary in bytes: - // Measured: `710` - // Estimated: `5383` - // Minimum execution time: 53_123_000 picoseconds. - Weight::from_parts(54_417_000, 0) - .saturating_add(Weight::from_parts(0, 5383)) + // Measured: `642` + // Estimated: `5358` + // Minimum execution time: 50_322_000 picoseconds. + Weight::from_parts(51_399_000, 0) + .saturating_add(Weight::from_parts(0, 5358)) .saturating_add(T::DbWeight::get().reads(7)) .saturating_add(T::DbWeight::get().writes(3)) } @@ -173,24 +181,24 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< /// Storage: `BridgeRococoParachains::ImportedParaHeads` (r:1 w:0) /// Proof: `BridgeRococoParachains::ImportedParaHeads` (`max_values`: Some(64), `max_size`: Some(196), added: 1186, mode: `MaxEncodedLen`) /// Storage: `BridgeRococoMessages::OutboundLanes` (r:1 w:1) - /// Proof: `BridgeRococoMessages::OutboundLanes` (`max_values`: None, `max_size`: Some(74), added: 2549, mode: `MaxEncodedLen`) + /// Proof: `BridgeRococoMessages::OutboundLanes` (`max_values`: None, `max_size`: Some(45), added: 2520, mode: `MaxEncodedLen`) /// Storage: UNKNOWN KEY `0x6e0a18b62a1de81c5f519181cc611e18` (r:1 w:0) /// Proof: UNKNOWN KEY `0x6e0a18b62a1de81c5f519181cc611e18` (r:1 w:0) /// Storage: `BridgeRelayers::RelayerRewards` (r:1 w:1) - /// Proof: `BridgeRelayers::RelayerRewards` (`max_values`: None, `max_size`: Some(102), added: 2577, mode: `MaxEncodedLen`) + /// Proof: `BridgeRelayers::RelayerRewards` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) /// Storage: `XcmOverBridgeHubRococo::LaneToBridge` (r:1 w:0) - /// Proof: `XcmOverBridgeHubRococo::LaneToBridge` (`max_values`: None, `max_size`: Some(65), added: 2540, mode: `MaxEncodedLen`) + /// Proof: `XcmOverBridgeHubRococo::LaneToBridge` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `MaxEncodedLen`) /// Storage: `XcmOverBridgeHubRococo::Bridges` (r:1 w:0) - /// Proof: `XcmOverBridgeHubRococo::Bridges` (`max_values`: None, `max_size`: Some(1918), added: 4393, mode: `MaxEncodedLen`) + /// Proof: `XcmOverBridgeHubRococo::Bridges` (`max_values`: None, `max_size`: Some(1893), added: 4368, mode: `MaxEncodedLen`) /// Storage: `BridgeRococoMessages::OutboundMessages` (r:0 w:2) - /// Proof: `BridgeRococoMessages::OutboundMessages` (`max_values`: None, `max_size`: Some(65597), added: 68072, mode: `MaxEncodedLen`) + /// Proof: `BridgeRococoMessages::OutboundMessages` (`max_values`: None, `max_size`: Some(65568), added: 68043, mode: `MaxEncodedLen`) fn receive_delivery_proof_for_two_messages_by_single_relayer() -> Weight { // Proof Size summary in bytes: - // Measured: `710` - // Estimated: `5383` - // Minimum execution time: 55_140_000 picoseconds. - Weight::from_parts(56_456_000, 0) - .saturating_add(Weight::from_parts(0, 5383)) + // Measured: `642` + // Estimated: `5358` + // Minimum execution time: 51_521_000 picoseconds. + Weight::from_parts(52_702_000, 0) + .saturating_add(Weight::from_parts(0, 5358)) .saturating_add(T::DbWeight::get().reads(7)) .saturating_add(T::DbWeight::get().writes(4)) } @@ -199,24 +207,24 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< /// Storage: `BridgeRococoParachains::ImportedParaHeads` (r:1 w:0) /// Proof: `BridgeRococoParachains::ImportedParaHeads` (`max_values`: Some(64), `max_size`: Some(196), added: 1186, mode: `MaxEncodedLen`) /// Storage: `BridgeRococoMessages::OutboundLanes` (r:1 w:1) - /// Proof: `BridgeRococoMessages::OutboundLanes` (`max_values`: None, `max_size`: Some(74), added: 2549, mode: `MaxEncodedLen`) + /// Proof: `BridgeRococoMessages::OutboundLanes` (`max_values`: None, `max_size`: Some(45), added: 2520, mode: `MaxEncodedLen`) /// Storage: UNKNOWN KEY `0x6e0a18b62a1de81c5f519181cc611e18` (r:1 w:0) /// Proof: UNKNOWN KEY `0x6e0a18b62a1de81c5f519181cc611e18` (r:1 w:0) /// Storage: `BridgeRelayers::RelayerRewards` (r:2 w:2) - /// Proof: `BridgeRelayers::RelayerRewards` (`max_values`: None, `max_size`: Some(102), added: 2577, mode: `MaxEncodedLen`) + /// Proof: `BridgeRelayers::RelayerRewards` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) /// Storage: `XcmOverBridgeHubRococo::LaneToBridge` (r:1 w:0) - /// Proof: `XcmOverBridgeHubRococo::LaneToBridge` (`max_values`: None, `max_size`: Some(65), added: 2540, mode: `MaxEncodedLen`) + /// Proof: `XcmOverBridgeHubRococo::LaneToBridge` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `MaxEncodedLen`) /// Storage: `XcmOverBridgeHubRococo::Bridges` (r:1 w:0) - /// Proof: `XcmOverBridgeHubRococo::Bridges` (`max_values`: None, `max_size`: Some(1918), added: 4393, mode: `MaxEncodedLen`) + /// Proof: `XcmOverBridgeHubRococo::Bridges` (`max_values`: None, `max_size`: Some(1893), added: 4368, mode: `MaxEncodedLen`) /// Storage: `BridgeRococoMessages::OutboundMessages` (r:0 w:2) - /// Proof: `BridgeRococoMessages::OutboundMessages` (`max_values`: None, `max_size`: Some(65597), added: 68072, mode: `MaxEncodedLen`) + /// Proof: `BridgeRococoMessages::OutboundMessages` (`max_values`: None, `max_size`: Some(65568), added: 68043, mode: `MaxEncodedLen`) fn receive_delivery_proof_for_two_messages_by_two_relayers() -> Weight { // Proof Size summary in bytes: - // Measured: `710` - // Estimated: `6144` - // Minimum execution time: 60_415_000 picoseconds. - Weight::from_parts(62_057_000, 0) - .saturating_add(Weight::from_parts(0, 6144)) + // Measured: `642` + // Estimated: `6086` + // Minimum execution time: 56_751_000 picoseconds. + Weight::from_parts(58_542_000, 0) + .saturating_add(Weight::from_parts(0, 6086)) .saturating_add(T::DbWeight::get().reads(8)) .saturating_add(T::DbWeight::get().writes(5)) } @@ -225,11 +233,13 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< /// Storage: `BridgeRococoParachains::ImportedParaHeads` (r:1 w:0) /// Proof: `BridgeRococoParachains::ImportedParaHeads` (`max_values`: Some(64), `max_size`: Some(196), added: 1186, mode: `MaxEncodedLen`) /// Storage: `BridgeRococoMessages::InboundLanes` (r:1 w:1) - /// Proof: `BridgeRococoMessages::InboundLanes` (`max_values`: None, `max_size`: Some(49209), added: 51684, mode: `MaxEncodedLen`) + /// Proof: `BridgeRococoMessages::InboundLanes` (`max_values`: None, `max_size`: Some(49180), added: 51655, mode: `MaxEncodedLen`) /// Storage: `XcmOverBridgeHubRococo::LaneToBridge` (r:1 w:0) - /// Proof: `XcmOverBridgeHubRococo::LaneToBridge` (`max_values`: None, `max_size`: Some(65), added: 2540, mode: `MaxEncodedLen`) + /// Proof: `XcmOverBridgeHubRococo::LaneToBridge` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `MaxEncodedLen`) /// Storage: `XcmOverBridgeHubRococo::Bridges` (r:1 w:0) - /// Proof: `XcmOverBridgeHubRococo::Bridges` (`max_values`: None, `max_size`: Some(1918), added: 4393, mode: `MaxEncodedLen`) + /// Proof: `XcmOverBridgeHubRococo::Bridges` (`max_values`: None, `max_size`: Some(1893), added: 4368, mode: `MaxEncodedLen`) + /// Storage: `XcmpQueue::OutboundXcmpStatus` (r:1 w:1) + /// Proof: `XcmpQueue::OutboundXcmpStatus` (`max_values`: Some(1), `max_size`: Some(1282), added: 1777, mode: `MaxEncodedLen`) /// Storage: `ParachainInfo::ParachainId` (r:1 w:0) /// Proof: `ParachainInfo::ParachainId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) /// Storage: `XcmpQueue::DeliveryFeeFactor` (r:1 w:0) @@ -242,20 +252,18 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< /// 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`: Some(1282), added: 1777, mode: `MaxEncodedLen`) /// Storage: `XcmpQueue::OutboundXcmpMessages` (r:0 w:1) /// Proof: `XcmpQueue::OutboundXcmpMessages` (`max_values`: None, `max_size`: Some(105506), added: 107981, mode: `MaxEncodedLen`) /// The range of component `n` is `[1, 16384]`. fn receive_single_n_bytes_message_proof_with_dispatch(n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `965` - // Estimated: `52674` - // Minimum execution time: 84_340_000 picoseconds. - Weight::from_parts(89_615_003, 0) - .saturating_add(Weight::from_parts(0, 52674)) - // Standard Error: 15 - .saturating_add(Weight::from_parts(7_574, 0).saturating_mul(n.into())) + // Measured: `896` + // Estimated: `52645` + // Minimum execution time: 84_818_000 picoseconds. + Weight::from_parts(88_034_122, 0) + .saturating_add(Weight::from_parts(0, 52645)) + // Standard Error: 21 + .saturating_add(Weight::from_parts(7_352, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(12)) .saturating_add(T::DbWeight::get().writes(4)) } From c031d482f727978b805b873fbfcfa5c51d1555fa Mon Sep 17 00:00:00 2001 From: Branislav Kontur Date: Thu, 7 Nov 2024 22:49:30 +0100 Subject: [PATCH 33/72] Fixed benchmarks --- bridges/modules/xcm-bridge-hub/src/lib.rs | 7 ++ .../bridge-hubs/bridge-hub-rococo/src/lib.rs | 70 +++++++++++++++---- .../bridge-hubs/bridge-hub-westend/src/lib.rs | 48 +++++++++---- prdoc/pr_6231.prdoc | 22 ++++-- 4 files changed, 114 insertions(+), 33 deletions(-) diff --git a/bridges/modules/xcm-bridge-hub/src/lib.rs b/bridges/modules/xcm-bridge-hub/src/lib.rs index 0f30dbb5bf89..88332cb5289b 100644 --- a/bridges/modules/xcm-bridge-hub/src/lib.rs +++ b/bridges/modules/xcm-bridge-hub/src/lib.rs @@ -665,12 +665,19 @@ pub mod pallet { bridge_destination_universal_location: InteriorLocation, create_lanes: bool, maybe_notify: Option, + fund_account: impl Fn(AccountIdOf>, BalanceOf>), ) -> Result, sp_runtime::DispatchError> { let locations = Pallet::::bridge_locations( bridge_origin_relative_location.into(), bridge_destination_universal_location.into(), )?; + if !T::AllowWithoutBridgeDeposit::contains(locations.bridge_origin_relative_location()) { + let account_id = T::BridgeOriginAccountIdConverter::convert_location(locations.bridge_origin_relative_location()) + .ok_or(Error::::InvalidBridgeOriginAccount)?; + fund_account(account_id, T::BridgeDeposit::get()); + } + Pallet::::do_open_bridge(locations.clone(), lane_id, create_lanes, maybe_notify)?; Ok(locations) diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs index bc4fdd247bc4..eeaac7757dfb 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs @@ -1262,21 +1262,8 @@ impl_runtime_apis! { BenchmarkError::Stop("XcmVersion was not stored!") })?; - let sibling_parachain_location = Location::new(1, [Parachain(5678)]); - - // fund SA - use frame_support::traits::fungible::Mutate; - use xcm_executor::traits::ConvertLocation; - frame_support::assert_ok!( - Balances::mint_into( - &xcm_config::LocationToAccountId::convert_location(&sibling_parachain_location).expect("valid AccountId"), - bridge_to_westend_config::BridgeDeposit::get() - .saturating_add(ExistentialDeposit::get()) - .saturating_add(UNITS * 5) - ) - ); - // open bridge + let sibling_parachain_location = Location::new(1, [Parachain(5678)]); let bridge_destination_universal_location: InteriorLocation = [GlobalConsensus(NetworkId::ByGenesis(WESTEND_GENESIS_HASH)), Parachain(8765)].into(); let _ = XcmOverBridgeHubWestend::open_bridge_for_benchmarks( bp_messages::LegacyLaneId([1, 2, 3, 4]), @@ -1284,6 +1271,17 @@ impl_runtime_apis! { bridge_destination_universal_location.clone(), true, None, + |account_id, bridge_deposit| { + use frame_support::traits::fungible::Mutate; + frame_support::assert_ok!( + Balances::mint_into( + &account_id, + bridge_deposit + .saturating_add(ExistentialDeposit::get()) + .saturating_add(UNITS * 5) + ) + ); + }, ).map_err(|e| { log::error!( "Failed to `XcmOverBridgeHubWestend::open_bridge`({:?}, {:?})`, error: {:?}", @@ -1359,6 +1357,17 @@ impl_runtime_apis! { // do not create lanes, because they are already created `params.lane` false, None, + |account_id, bridge_deposit| { + use frame_support::traits::fungible::Mutate; + frame_support::assert_ok!( + Balances::mint_into( + &account_id, + bridge_deposit + .saturating_add(ExistentialDeposit::get()) + .saturating_add(UNITS * 5) + ) + ); + }, ).expect("valid bridge opened"); prepare_message_proof_from_parachain::< Runtime, @@ -1377,6 +1386,17 @@ impl_runtime_apis! { // do not create lanes, because they are already created `params.lane` false, None, + |account_id, bridge_deposit| { + use frame_support::traits::fungible::Mutate; + frame_support::assert_ok!( + Balances::mint_into( + &account_id, + bridge_deposit + .saturating_add(ExistentialDeposit::get()) + .saturating_add(UNITS * 5) + ) + ); + }, ); prepare_message_delivery_proof_from_parachain::< Runtime, @@ -1410,6 +1430,17 @@ impl_runtime_apis! { // do not create lanes, because they are already created `params.lane` false, None, + |account_id, bridge_deposit| { + use frame_support::traits::fungible::Mutate; + frame_support::assert_ok!( + Balances::mint_into( + &account_id, + bridge_deposit + .saturating_add(ExistentialDeposit::get()) + .saturating_add(UNITS * 5) + ) + ); + }, ).expect("valid bridge opened"); prepare_message_proof_from_grandpa_chain::< Runtime, @@ -1428,6 +1459,17 @@ impl_runtime_apis! { // do not create lanes, because they are already created `params.lane` false, None, + |account_id, bridge_deposit| { + use frame_support::traits::fungible::Mutate; + frame_support::assert_ok!( + Balances::mint_into( + &account_id, + bridge_deposit + .saturating_add(ExistentialDeposit::get()) + .saturating_add(UNITS * 5) + ) + ); + }, ).expect("valid bridge opened"); prepare_message_delivery_proof_from_grandpa_chain::< Runtime, diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs index 4033b6101bac..48d6bc5d99f5 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs @@ -1147,21 +1147,8 @@ impl_runtime_apis! { BenchmarkError::Stop("XcmVersion was not stored!") })?; - let sibling_parachain_location = Location::new(1, [Parachain(5678)]); - - // fund SA - use frame_support::traits::fungible::Mutate; - use xcm_executor::traits::ConvertLocation; - frame_support::assert_ok!( - Balances::mint_into( - &xcm_config::LocationToAccountId::convert_location(&sibling_parachain_location).expect("valid AccountId"), - bridge_to_rococo_config::BridgeDeposit::get() - .saturating_add(ExistentialDeposit::get()) - .saturating_add(UNITS * 5) - ) - ); - // open bridge + let sibling_parachain_location = Location::new(1, [Parachain(5678)]); let bridge_destination_universal_location: InteriorLocation = [GlobalConsensus(ByGenesis(ROCOCO_GENESIS_HASH)), Parachain(8765)].into(); let _ = XcmOverBridgeHubRococo::open_bridge_for_benchmarks( bp_messages::LegacyLaneId([1, 2, 3, 4]), @@ -1169,6 +1156,17 @@ impl_runtime_apis! { bridge_destination_universal_location.clone(), true, None, + |account_id, bridge_deposit| { + use frame_support::traits::fungible::Mutate; + frame_support::assert_ok!( + Balances::mint_into( + &account_id, + bridge_deposit + .saturating_add(ExistentialDeposit::get()) + .saturating_add(UNITS * 5) + ) + ); + }, ).map_err(|e| { log::error!( "Failed to `XcmOverBridgeHubRococo::open_bridge`({:?}, {:?})`, error: {:?}", @@ -1239,6 +1237,17 @@ impl_runtime_apis! { // do not create lanes, because they are already created `params.lane` false, None, + |account_id, bridge_deposit| { + use frame_support::traits::fungible::Mutate; + frame_support::assert_ok!( + Balances::mint_into( + &account_id, + bridge_deposit + .saturating_add(ExistentialDeposit::get()) + .saturating_add(UNITS * 5) + ) + ); + }, ).expect("valid bridge opened"); prepare_message_proof_from_parachain::< Runtime, @@ -1257,6 +1266,17 @@ impl_runtime_apis! { // do not create lanes, because they are already created `params.lane` false, None, + |account_id, bridge_deposit| { + use frame_support::traits::fungible::Mutate; + frame_support::assert_ok!( + Balances::mint_into( + &account_id, + bridge_deposit + .saturating_add(ExistentialDeposit::get()) + .saturating_add(UNITS * 5) + ) + ); + }, ); prepare_message_delivery_proof_from_parachain::< Runtime, diff --git a/prdoc/pr_6231.prdoc b/prdoc/pr_6231.prdoc index 3638cc799941..2e88dbde4016 100644 --- a/prdoc/pr_6231.prdoc +++ b/prdoc/pr_6231.prdoc @@ -11,18 +11,30 @@ doc: - [ ] backport to the stable-2024-09-3 till 11.Nov crates: - name: pallet-xcm-bridge-hub-router - bump: patch + bump: major - name: pallet-xcm-bridge-hub - bump: patch + bump: major - name: bp-xcm-bridge-hub-router - bump: patch + bump: major - name: asset-hub-rococo-runtime - bump: patch + bump: major - name: asset-hub-westend-runtime - bump: patch + bump: major - name: bp-xcm-bridge-hub bump: major - name: bridge-hub-rococo-runtime bump: patch - name: bridge-hub-westend-runtime + bump: patch +- name: asset-test-utils + bump: patch +- name: cumulus-pallet-xcmp-queue + bump: patch +- name: bridge-hub-test-utils + bump: patch +- name: emulated-integration-tests-common + bump: patch +- name: bp-asset-hub-rococo + bump: patch +- name: bp-asset-hub-westend bump: patch \ No newline at end of file From 28fc081229f6175c6c5b1716cafe66dbe309895b Mon Sep 17 00:00:00 2001 From: command-bot <> Date: Thu, 7 Nov 2024 23:02:44 +0000 Subject: [PATCH 34/72] ".git/.scripts/commands/bench/bench.sh" --subcommand=xcm --runtime=bridge-hub-westend --runtime_dir=bridge-hubs --target_dir=cumulus --pallet=pallet_xcm_benchmarks::generic --- .../xcm/pallet_xcm_benchmarks_generic.rs | 158 +++++++++--------- 1 file changed, 81 insertions(+), 77 deletions(-) diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/xcm/pallet_xcm_benchmarks_generic.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/xcm/pallet_xcm_benchmarks_generic.rs index 849456af9255..8c28e52e6085 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/xcm/pallet_xcm_benchmarks_generic.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/xcm/pallet_xcm_benchmarks_generic.rs @@ -17,9 +17,9 @@ //! Autogenerated weights for `pallet_xcm_benchmarks::generic` //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-08-27, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2024-11-07, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-svzsllib-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! HOSTNAME: `runner-vcatxqpx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: Compiled, CHAIN: Some("bridge-hub-westend-dev"), DB CACHE: 1024 // Executed Command: @@ -68,8 +68,8 @@ impl WeightInfo { // Proof Size summary in bytes: // Measured: `208` // Estimated: `6196` - // Minimum execution time: 70_353_000 picoseconds. - Weight::from_parts(72_257_000, 6196) + // Minimum execution time: 72_301_000 picoseconds. + Weight::from_parts(73_889_000, 6196) .saturating_add(T::DbWeight::get().reads(9)) .saturating_add(T::DbWeight::get().writes(4)) } @@ -77,15 +77,26 @@ impl WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 996_000 picoseconds. - Weight::from_parts(1_027_000, 0) + // Minimum execution time: 929_000 picoseconds. + Weight::from_parts(983_000, 0) } + // Storage: `System::Account` (r:1 w:1) + // Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) pub fn pay_fees() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `3593` + // Minimum execution time: 3_717_000 picoseconds. + Weight::from_parts(3_864_000, 3593) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + pub fn set_asset_claimer() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_926_000 picoseconds. - Weight::from_parts(2_033_000, 0) + // Minimum execution time: 899_000 picoseconds. + Weight::from_parts(962_000, 0) } // Storage: `PolkadotXcm::Queries` (r:1 w:0) // Proof: `PolkadotXcm::Queries` (`max_values`: None, `max_size`: None, mode: `Measured`) @@ -93,58 +104,58 @@ impl WeightInfo { // Proof Size summary in bytes: // Measured: `32` // Estimated: `3497` - // Minimum execution time: 7_961_000 picoseconds. - Weight::from_parts(8_256_000, 3497) + // Minimum execution time: 8_009_000 picoseconds. + Weight::from_parts(8_159_000, 3497) .saturating_add(T::DbWeight::get().reads(1)) } pub fn transact() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 7_589_000 picoseconds. - Weight::from_parts(7_867_000, 0) + // Minimum execution time: 7_580_000 picoseconds. + Weight::from_parts(7_777_000, 0) } pub fn refund_surplus() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_602_000 picoseconds. - Weight::from_parts(1_660_000, 0) + // Minimum execution time: 1_581_000 picoseconds. + Weight::from_parts(1_712_000, 0) } pub fn set_error_handler() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_056_000 picoseconds. - Weight::from_parts(1_096_000, 0) + // Minimum execution time: 946_000 picoseconds. + Weight::from_parts(1_015_000, 0) } pub fn set_appendix() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_014_000 picoseconds. - Weight::from_parts(1_075_000, 0) + // Minimum execution time: 969_000 picoseconds. + Weight::from_parts(1_037_000, 0) } pub fn clear_error() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 986_000 picoseconds. - Weight::from_parts(1_031_000, 0) + // Minimum execution time: 916_000 picoseconds. + Weight::from_parts(973_000, 0) } pub fn descend_origin() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_015_000 picoseconds. - Weight::from_parts(1_069_000, 0) + // Minimum execution time: 941_000 picoseconds. + Weight::from_parts(982_000, 0) } pub fn clear_origin() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 993_000 picoseconds. - Weight::from_parts(1_063_000, 0) + // Minimum execution time: 937_000 picoseconds. + Weight::from_parts(991_000, 0) } // Storage: `ParachainInfo::ParachainId` (r:1 w:0) // Proof: `ParachainInfo::ParachainId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) @@ -166,8 +177,8 @@ impl WeightInfo { // Proof Size summary in bytes: // Measured: `208` // Estimated: `6196` - // Minimum execution time: 66_350_000 picoseconds. - Weight::from_parts(68_248_000, 6196) + // Minimum execution time: 69_202_000 picoseconds. + Weight::from_parts(71_054_000, 6196) .saturating_add(T::DbWeight::get().reads(9)) .saturating_add(T::DbWeight::get().writes(4)) } @@ -177,8 +188,8 @@ impl WeightInfo { // Proof Size summary in bytes: // Measured: `90` // Estimated: `3555` - // Minimum execution time: 11_247_000 picoseconds. - Weight::from_parts(11_468_000, 3555) + // Minimum execution time: 11_209_000 picoseconds. + Weight::from_parts(11_588_000, 3555) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } @@ -186,8 +197,8 @@ impl WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_060_000 picoseconds. - Weight::from_parts(1_103_000, 0) + // Minimum execution time: 918_000 picoseconds. + Weight::from_parts(973_000, 0) } // Storage: `PolkadotXcm::VersionNotifyTargets` (r:1 w:1) // Proof: `PolkadotXcm::VersionNotifyTargets` (`max_values`: None, `max_size`: None, mode: `Measured`) @@ -207,8 +218,8 @@ impl WeightInfo { // Proof Size summary in bytes: // Measured: `38` // Estimated: `3503` - // Minimum execution time: 25_599_000 picoseconds. - Weight::from_parts(26_336_000, 3503) + // Minimum execution time: 25_653_000 picoseconds. + Weight::from_parts(26_505_000, 3503) .saturating_add(T::DbWeight::get().reads(7)) .saturating_add(T::DbWeight::get().writes(3)) } @@ -218,44 +229,44 @@ impl WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_863_000 picoseconds. - Weight::from_parts(3_090_000, 0) + // Minimum execution time: 2_929_000 picoseconds. + Weight::from_parts(3_071_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: 1_385_000 picoseconds. - Weight::from_parts(1_468_000, 0) + // Minimum execution time: 1_337_000 picoseconds. + Weight::from_parts(1_422_000, 0) } pub fn expect_asset() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_087_000 picoseconds. - Weight::from_parts(1_164_000, 0) + // Minimum execution time: 1_024_000 picoseconds. + Weight::from_parts(1_076_000, 0) } pub fn expect_origin() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_022_000 picoseconds. - Weight::from_parts(1_066_000, 0) + // Minimum execution time: 949_000 picoseconds. + Weight::from_parts(999_000, 0) } pub fn expect_error() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_015_000 picoseconds. - Weight::from_parts(1_070_000, 0) + // Minimum execution time: 940_000 picoseconds. + Weight::from_parts(975_000, 0) } pub fn expect_transact_status() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_203_000 picoseconds. - Weight::from_parts(1_241_000, 0) + // Minimum execution time: 1_063_000 picoseconds. + Weight::from_parts(1_166_000, 0) } // Storage: `ParachainInfo::ParachainId` (r:1 w:0) // Proof: `ParachainInfo::ParachainId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) @@ -277,8 +288,8 @@ impl WeightInfo { // Proof Size summary in bytes: // Measured: `208` // Estimated: `6196` - // Minimum execution time: 70_773_000 picoseconds. - Weight::from_parts(72_730_000, 6196) + // Minimum execution time: 75_010_000 picoseconds. + Weight::from_parts(76_402_000, 6196) .saturating_add(T::DbWeight::get().reads(9)) .saturating_add(T::DbWeight::get().writes(4)) } @@ -286,8 +297,8 @@ impl WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 4_173_000 picoseconds. - Weight::from_parts(4_445_000, 0) + // Minimum execution time: 4_316_000 picoseconds. + Weight::from_parts(4_458_000, 0) } // Storage: `ParachainInfo::ParachainId` (r:1 w:0) // Proof: `ParachainInfo::ParachainId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) @@ -309,8 +320,8 @@ impl WeightInfo { // Proof Size summary in bytes: // Measured: `208` // Estimated: `6196` - // Minimum execution time: 66_471_000 picoseconds. - Weight::from_parts(68_362_000, 6196) + // Minimum execution time: 69_876_000 picoseconds. + Weight::from_parts(71_417_000, 6196) .saturating_add(T::DbWeight::get().reads(9)) .saturating_add(T::DbWeight::get().writes(4)) } @@ -318,44 +329,44 @@ impl WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_067_000 picoseconds. - Weight::from_parts(1_108_000, 0) + // Minimum execution time: 990_000 picoseconds. + Weight::from_parts(1_045_000, 0) } pub fn set_topic() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 997_000 picoseconds. - Weight::from_parts(1_043_000, 0) + // Minimum execution time: 934_000 picoseconds. + Weight::from_parts(969_000, 0) } pub fn clear_topic() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_000_000 picoseconds. - Weight::from_parts(1_056_000, 0) + // Minimum execution time: 953_000 picoseconds. + Weight::from_parts(996_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: `XcmOverBridgeHubRococo::Bridges` (r:1 w:0) + // Proof: `XcmOverBridgeHubRococo::Bridges` (`max_values`: None, `max_size`: Some(1893), added: 4368, mode: `MaxEncodedLen`) // Storage: `PolkadotXcm::SupportedVersion` (r:2 w:0) // Proof: `PolkadotXcm::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`) - // Storage: `XcmOverBridgeHubRococo::Bridges` (r:1 w:0) - // Proof: `XcmOverBridgeHubRococo::Bridges` (`max_values`: None, `max_size`: Some(1918), added: 4393, mode: `MaxEncodedLen`) // Storage: `BridgeRococoMessages::PalletOperatingMode` (r:1 w:0) // Proof: `BridgeRococoMessages::PalletOperatingMode` (`max_values`: Some(1), `max_size`: Some(2), added: 497, mode: `MaxEncodedLen`) // Storage: `BridgeRococoMessages::OutboundLanes` (r:1 w:1) - // Proof: `BridgeRococoMessages::OutboundLanes` (`max_values`: None, `max_size`: Some(74), added: 2549, mode: `MaxEncodedLen`) + // Proof: `BridgeRococoMessages::OutboundLanes` (`max_values`: None, `max_size`: Some(45), added: 2520, mode: `MaxEncodedLen`) // Storage: `BridgeRococoMessages::OutboundMessages` (r:0 w:1) - // Proof: `BridgeRococoMessages::OutboundMessages` (`max_values`: None, `max_size`: Some(65597), added: 68072, mode: `MaxEncodedLen`) + // Proof: `BridgeRococoMessages::OutboundMessages` (`max_values`: None, `max_size`: Some(65568), added: 68043, mode: `MaxEncodedLen`) /// The range of component `x` is `[1, 1000]`. pub fn export_message(x: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `225` - // Estimated: `6165` - // Minimum execution time: 43_316_000 picoseconds. - Weight::from_parts(45_220_843, 6165) - // Standard Error: 169 - .saturating_add(Weight::from_parts(44_459, 0).saturating_mul(x.into())) + // Measured: `595` + // Estimated: `6535` + // Minimum execution time: 57_024_000 picoseconds. + Weight::from_parts(59_135_181, 6535) + // Standard Error: 163 + .saturating_add(Weight::from_parts(50_638, 0).saturating_mul(x.into())) .saturating_add(T::DbWeight::get().reads(6)) .saturating_add(T::DbWeight::get().writes(2)) } @@ -363,21 +374,14 @@ impl WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 998_000 picoseconds. - Weight::from_parts(1_054_000, 0) + // Minimum execution time: 896_000 picoseconds. + Weight::from_parts(942_000, 0) } pub fn unpaid_execution() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 995_000 picoseconds. - Weight::from_parts(1_060_000, 0) - } - pub fn set_asset_claimer() -> Weight { - // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 707_000 picoseconds. - Weight::from_parts(749_000, 0) + // Minimum execution time: 941_000 picoseconds. + Weight::from_parts(987_000, 0) } } From 87098db8695e7e4587050268f565debb4732aae4 Mon Sep 17 00:00:00 2001 From: command-bot <> Date: Thu, 7 Nov 2024 23:02:53 +0000 Subject: [PATCH 35/72] ".git/.scripts/commands/bench/bench.sh" --subcommand=xcm --runtime=bridge-hub-rococo --runtime_dir=bridge-hubs --target_dir=cumulus --pallet=pallet_xcm_benchmarks::generic --- .../xcm/pallet_xcm_benchmarks_generic.rs | 156 +++++++++--------- 1 file changed, 80 insertions(+), 76 deletions(-) diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/xcm/pallet_xcm_benchmarks_generic.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/xcm/pallet_xcm_benchmarks_generic.rs index b8bd4c4e2d44..e7913b93d0cb 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/xcm/pallet_xcm_benchmarks_generic.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/xcm/pallet_xcm_benchmarks_generic.rs @@ -17,9 +17,9 @@ //! Autogenerated weights for `pallet_xcm_benchmarks::generic` //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-08-27, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2024-11-07, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-svzsllib-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! HOSTNAME: `runner-vcatxqpx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: Compiled, CHAIN: Some("bridge-hub-rococo-dev"), DB CACHE: 1024 // Executed Command: @@ -68,8 +68,8 @@ impl WeightInfo { // Proof Size summary in bytes: // Measured: `171` // Estimated: `6196` - // Minimum execution time: 69_010_000 picoseconds. - Weight::from_parts(70_067_000, 6196) + // Minimum execution time: 72_937_000 picoseconds. + Weight::from_parts(75_819_000, 6196) .saturating_add(T::DbWeight::get().reads(9)) .saturating_add(T::DbWeight::get().writes(4)) } @@ -77,15 +77,26 @@ impl WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_069_000 picoseconds. - Weight::from_parts(1_116_000, 0) + // Minimum execution time: 1_034_000 picoseconds. + Weight::from_parts(1_102_000, 0) } + // Storage: `System::Account` (r:1 w:1) + // Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) pub fn pay_fees() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `3593` + // Minimum execution time: 3_844_000 picoseconds. + Weight::from_parts(4_059_000, 3593) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + pub fn set_asset_claimer() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_011_000 picoseconds. - Weight::from_parts(2_095_000, 0) + // Minimum execution time: 1_066_000 picoseconds. + Weight::from_parts(1_121_000, 0) } // Storage: `PolkadotXcm::Queries` (r:1 w:0) // Proof: `PolkadotXcm::Queries` (`max_values`: None, `max_size`: None, mode: `Measured`) @@ -93,58 +104,58 @@ impl WeightInfo { // Proof Size summary in bytes: // Measured: `32` // Estimated: `3497` - // Minimum execution time: 7_630_000 picoseconds. - Weight::from_parts(7_992_000, 3497) + // Minimum execution time: 8_424_000 picoseconds. + Weight::from_parts(8_697_000, 3497) .saturating_add(T::DbWeight::get().reads(1)) } pub fn transact() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 7_909_000 picoseconds. - Weight::from_parts(8_100_000, 0) + // Minimum execution time: 8_162_000 picoseconds. + Weight::from_parts(8_419_000, 0) } pub fn refund_surplus() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_749_000 picoseconds. - Weight::from_parts(1_841_000, 0) + // Minimum execution time: 1_758_000 picoseconds. + Weight::from_parts(1_871_000, 0) } pub fn set_error_handler() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_109_000 picoseconds. - Weight::from_parts(1_156_000, 0) + // Minimum execution time: 1_075_000 picoseconds. + Weight::from_parts(1_133_000, 0) } pub fn set_appendix() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_073_000 picoseconds. - Weight::from_parts(1_143_000, 0) + // Minimum execution time: 1_058_000 picoseconds. + Weight::from_parts(1_130_000, 0) } pub fn clear_error() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_050_000 picoseconds. - Weight::from_parts(1_084_000, 0) + // Minimum execution time: 1_041_000 picoseconds. + Weight::from_parts(1_076_000, 0) } pub fn descend_origin() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_060_000 picoseconds. - Weight::from_parts(1_114_000, 0) + // Minimum execution time: 1_020_000 picoseconds. + Weight::from_parts(1_101_000, 0) } pub fn clear_origin() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_065_000 picoseconds. - Weight::from_parts(1_112_000, 0) + // Minimum execution time: 1_021_000 picoseconds. + Weight::from_parts(1_088_000, 0) } // Storage: `ParachainInfo::ParachainId` (r:1 w:0) // Proof: `ParachainInfo::ParachainId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) @@ -166,8 +177,8 @@ impl WeightInfo { // Proof Size summary in bytes: // Measured: `171` // Estimated: `6196` - // Minimum execution time: 65_538_000 picoseconds. - Weight::from_parts(66_943_000, 6196) + // Minimum execution time: 69_708_000 picoseconds. + Weight::from_parts(71_269_000, 6196) .saturating_add(T::DbWeight::get().reads(9)) .saturating_add(T::DbWeight::get().writes(4)) } @@ -177,8 +188,8 @@ impl WeightInfo { // Proof Size summary in bytes: // Measured: `90` // Estimated: `3555` - // Minimum execution time: 10_898_000 picoseconds. - Weight::from_parts(11_262_000, 3555) + // Minimum execution time: 11_628_000 picoseconds. + Weight::from_parts(12_060_000, 3555) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } @@ -186,8 +197,8 @@ impl WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_026_000 picoseconds. - Weight::from_parts(1_104_000, 0) + // Minimum execution time: 1_035_000 picoseconds. + Weight::from_parts(1_078_000, 0) } // Storage: `PolkadotXcm::VersionNotifyTargets` (r:1 w:1) // Proof: `PolkadotXcm::VersionNotifyTargets` (`max_values`: None, `max_size`: None, mode: `Measured`) @@ -207,8 +218,8 @@ impl WeightInfo { // Proof Size summary in bytes: // Measured: `38` // Estimated: `3503` - // Minimum execution time: 25_133_000 picoseconds. - Weight::from_parts(25_526_000, 3503) + // Minimum execution time: 26_364_000 picoseconds. + Weight::from_parts(27_334_000, 3503) .saturating_add(T::DbWeight::get().reads(7)) .saturating_add(T::DbWeight::get().writes(3)) } @@ -218,44 +229,44 @@ impl WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_946_000 picoseconds. - Weight::from_parts(3_074_000, 0) + // Minimum execution time: 3_047_000 picoseconds. + Weight::from_parts(3_264_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: 1_428_000 picoseconds. - Weight::from_parts(1_490_000, 0) + // Minimum execution time: 1_406_000 picoseconds. + Weight::from_parts(1_484_000, 0) } pub fn expect_asset() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_158_000 picoseconds. - Weight::from_parts(1_222_000, 0) + // Minimum execution time: 1_146_000 picoseconds. + Weight::from_parts(1_194_000, 0) } pub fn expect_origin() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_056_000 picoseconds. - Weight::from_parts(1_117_000, 0) + // Minimum execution time: 1_055_000 picoseconds. + Weight::from_parts(1_101_000, 0) } pub fn expect_error() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_045_000 picoseconds. + // Minimum execution time: 1_042_000 picoseconds. Weight::from_parts(1_084_000, 0) } pub fn expect_transact_status() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_224_000 picoseconds. - Weight::from_parts(1_268_000, 0) + // Minimum execution time: 1_196_000 picoseconds. + Weight::from_parts(1_269_000, 0) } // Storage: `ParachainInfo::ParachainId` (r:1 w:0) // Proof: `ParachainInfo::ParachainId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) @@ -277,8 +288,8 @@ impl WeightInfo { // Proof Size summary in bytes: // Measured: `171` // Estimated: `6196` - // Minimum execution time: 70_789_000 picoseconds. - Weight::from_parts(72_321_000, 6196) + // Minimum execution time: 75_168_000 picoseconds. + Weight::from_parts(78_390_000, 6196) .saturating_add(T::DbWeight::get().reads(9)) .saturating_add(T::DbWeight::get().writes(4)) } @@ -286,8 +297,8 @@ impl WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 4_521_000 picoseconds. - Weight::from_parts(4_649_000, 0) + // Minimum execution time: 4_857_000 picoseconds. + Weight::from_parts(4_948_000, 0) } // Storage: `ParachainInfo::ParachainId` (r:1 w:0) // Proof: `ParachainInfo::ParachainId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) @@ -309,8 +320,8 @@ impl WeightInfo { // Proof Size summary in bytes: // Measured: `171` // Estimated: `6196` - // Minimum execution time: 66_129_000 picoseconds. - Weight::from_parts(68_089_000, 6196) + // Minimum execution time: 69_757_000 picoseconds. + Weight::from_parts(72_027_000, 6196) .saturating_add(T::DbWeight::get().reads(9)) .saturating_add(T::DbWeight::get().writes(4)) } @@ -318,44 +329,44 @@ impl WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_094_000 picoseconds. - Weight::from_parts(1_157_000, 0) + // Minimum execution time: 1_075_000 picoseconds. + Weight::from_parts(1_110_000, 0) } pub fn set_topic() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_059_000 picoseconds. - Weight::from_parts(1_109_000, 0) + // Minimum execution time: 1_019_000 picoseconds. + Weight::from_parts(1_100_000, 0) } pub fn clear_topic() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_053_000 picoseconds. - Weight::from_parts(1_080_000, 0) + // Minimum execution time: 1_046_000 picoseconds. + Weight::from_parts(1_087_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: `XcmOverBridgeHubWestend::Bridges` (r:1 w:0) + // Proof: `XcmOverBridgeHubWestend::Bridges` (`max_values`: None, `max_size`: Some(1893), added: 4368, mode: `MaxEncodedLen`) // Storage: `PolkadotXcm::SupportedVersion` (r:2 w:0) // Proof: `PolkadotXcm::SupportedVersion` (`max_values`: None, `max_size`: None, mode: `Measured`) - // Storage: `XcmOverBridgeHubWestend::Bridges` (r:1 w:0) - // Proof: `XcmOverBridgeHubWestend::Bridges` (`max_values`: None, `max_size`: Some(1918), added: 4393, mode: `MaxEncodedLen`) // Storage: `BridgeWestendMessages::PalletOperatingMode` (r:1 w:0) // Proof: `BridgeWestendMessages::PalletOperatingMode` (`max_values`: Some(1), `max_size`: Some(2), added: 497, mode: `MaxEncodedLen`) // Storage: `BridgeWestendMessages::OutboundLanes` (r:1 w:1) - // Proof: `BridgeWestendMessages::OutboundLanes` (`max_values`: None, `max_size`: Some(74), added: 2549, mode: `MaxEncodedLen`) + // Proof: `BridgeWestendMessages::OutboundLanes` (`max_values`: None, `max_size`: Some(45), added: 2520, mode: `MaxEncodedLen`) // Storage: `BridgeWestendMessages::OutboundMessages` (r:0 w:1) - // Proof: `BridgeWestendMessages::OutboundMessages` (`max_values`: None, `max_size`: Some(65597), added: 68072, mode: `MaxEncodedLen`) + // Proof: `BridgeWestendMessages::OutboundMessages` (`max_values`: None, `max_size`: Some(65568), added: 68043, mode: `MaxEncodedLen`) /// The range of component `x` is `[1, 1000]`. pub fn export_message(x: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `190` - // Estimated: `6130` - // Minimum execution time: 42_081_000 picoseconds. - Weight::from_parts(42_977_658, 6130) - // Standard Error: 77 - .saturating_add(Weight::from_parts(44_912, 0).saturating_mul(x.into())) + // Measured: `632` + // Estimated: `6572` + // Minimum execution time: 58_530_000 picoseconds. + Weight::from_parts(60_307_825, 6572) + // Standard Error: 158 + .saturating_add(Weight::from_parts(53_061, 0).saturating_mul(x.into())) .saturating_add(T::DbWeight::get().reads(6)) .saturating_add(T::DbWeight::get().writes(2)) } @@ -363,21 +374,14 @@ impl WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_041_000 picoseconds. - Weight::from_parts(1_084_000, 0) + // Minimum execution time: 1_023_000 picoseconds. + Weight::from_parts(1_074_000, 0) } pub fn unpaid_execution() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_085_000 picoseconds. - Weight::from_parts(1_161_000, 0) - } - pub fn set_asset_claimer() -> Weight { - // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 707_000 picoseconds. - Weight::from_parts(749_000, 0) + // Minimum execution time: 1_040_000 picoseconds. + Weight::from_parts(1_096_000, 0) } } From 806f096fbfc7bb15978e24f4d7fb845058a01cbc Mon Sep 17 00:00:00 2001 From: command-bot <> Date: Thu, 7 Nov 2024 23:04:39 +0000 Subject: [PATCH 36/72] ".git/.scripts/commands/bench/bench.sh" --subcommand=pallet --runtime=bridge-hub-westend --runtime_dir=bridge-hubs --target_dir=cumulus --pallet=pallet_bridge_messages --- .../src/weights/pallet_bridge_messages.rs | 44 +++++++++---------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/pallet_bridge_messages.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/pallet_bridge_messages.rs index 3163a5de4122..d3d5bccc378c 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/pallet_bridge_messages.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/pallet_bridge_messages.rs @@ -66,8 +66,8 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< // Proof Size summary in bytes: // Measured: `765` // Estimated: `52645` - // Minimum execution time: 59_962_000 picoseconds. - Weight::from_parts(62_031_000, 0) + // Minimum execution time: 62_661_000 picoseconds. + Weight::from_parts(67_185_000, 0) .saturating_add(Weight::from_parts(0, 52645)) .saturating_add(T::DbWeight::get().reads(7)) .saturating_add(T::DbWeight::get().writes(1)) @@ -91,11 +91,11 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< // Proof Size summary in bytes: // Measured: `765` // Estimated: `52645` - // Minimum execution time: 59_978_000 picoseconds. - Weight::from_parts(61_443_000, 0) + // Minimum execution time: 62_217_000 picoseconds. + Weight::from_parts(63_923_000, 0) .saturating_add(Weight::from_parts(0, 52645)) - // Standard Error: 21_207 - .saturating_add(Weight::from_parts(12_190_114, 0).saturating_mul(n.into())) + // Standard Error: 9_541 + .saturating_add(Weight::from_parts(12_052_260, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(7)) .saturating_add(T::DbWeight::get().writes(1)) } @@ -117,8 +117,8 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< // Proof Size summary in bytes: // Measured: `765` // Estimated: `52645` - // Minimum execution time: 67_636_000 picoseconds. - Weight::from_parts(70_662_000, 0) + // Minimum execution time: 67_869_000 picoseconds. + Weight::from_parts(69_290_000, 0) .saturating_add(Weight::from_parts(0, 52645)) .saturating_add(T::DbWeight::get().reads(7)) .saturating_add(T::DbWeight::get().writes(1)) @@ -142,11 +142,11 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< // Proof Size summary in bytes: // Measured: `765` // Estimated: `52645` - // Minimum execution time: 60_681_000 picoseconds. - Weight::from_parts(65_061_839, 0) + // Minimum execution time: 60_562_000 picoseconds. + Weight::from_parts(63_556_899, 0) .saturating_add(Weight::from_parts(0, 52645)) - // Standard Error: 17 - .saturating_add(Weight::from_parts(2_093, 0).saturating_mul(n.into())) + // Standard Error: 10 + .saturating_add(Weight::from_parts(2_068, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(7)) .saturating_add(T::DbWeight::get().writes(1)) } @@ -170,8 +170,8 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< // Proof Size summary in bytes: // Measured: `642` // Estimated: `5358` - // Minimum execution time: 50_322_000 picoseconds. - Weight::from_parts(51_399_000, 0) + // Minimum execution time: 50_287_000 picoseconds. + Weight::from_parts(52_104_000, 0) .saturating_add(Weight::from_parts(0, 5358)) .saturating_add(T::DbWeight::get().reads(7)) .saturating_add(T::DbWeight::get().writes(3)) @@ -196,8 +196,8 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< // Proof Size summary in bytes: // Measured: `642` // Estimated: `5358` - // Minimum execution time: 51_521_000 picoseconds. - Weight::from_parts(52_702_000, 0) + // Minimum execution time: 51_653_000 picoseconds. + Weight::from_parts(52_696_000, 0) .saturating_add(Weight::from_parts(0, 5358)) .saturating_add(T::DbWeight::get().reads(7)) .saturating_add(T::DbWeight::get().writes(4)) @@ -222,8 +222,8 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< // Proof Size summary in bytes: // Measured: `642` // Estimated: `6086` - // Minimum execution time: 56_751_000 picoseconds. - Weight::from_parts(58_542_000, 0) + // Minimum execution time: 56_055_000 picoseconds. + Weight::from_parts(57_421_000, 0) .saturating_add(Weight::from_parts(0, 6086)) .saturating_add(T::DbWeight::get().reads(8)) .saturating_add(T::DbWeight::get().writes(5)) @@ -259,11 +259,11 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< // Proof Size summary in bytes: // Measured: `896` // Estimated: `52645` - // Minimum execution time: 84_818_000 picoseconds. - Weight::from_parts(88_034_122, 0) + // Minimum execution time: 84_883_000 picoseconds. + Weight::from_parts(88_455_136, 0) .saturating_add(Weight::from_parts(0, 52645)) - // Standard Error: 21 - .saturating_add(Weight::from_parts(7_352, 0).saturating_mul(n.into())) + // Standard Error: 15 + .saturating_add(Weight::from_parts(7_215, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(12)) .saturating_add(T::DbWeight::get().writes(4)) } From b5b25ce170bf4d7ff16185b92e9e6e8acddfffa6 Mon Sep 17 00:00:00 2001 From: command-bot <> Date: Thu, 7 Nov 2024 23:10:15 +0000 Subject: [PATCH 37/72] ".git/.scripts/commands/bench/bench.sh" --subcommand=pallet --runtime=bridge-hub-rococo --runtime_dir=bridge-hubs --target_dir=cumulus --pallet=pallet_bridge_messages --- ...idge_messages_rococo_to_rococo_bulletin.rs | 150 +++++++-------- ...allet_bridge_messages_rococo_to_westend.rs | 176 +++++++++--------- 2 files changed, 167 insertions(+), 159 deletions(-) diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/pallet_bridge_messages_rococo_to_rococo_bulletin.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/pallet_bridge_messages_rococo_to_rococo_bulletin.rs index cde511fc749d..cef34033ba3e 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/pallet_bridge_messages_rococo_to_rococo_bulletin.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/pallet_bridge_messages_rococo_to_rococo_bulletin.rs @@ -17,9 +17,9 @@ //! Autogenerated weights for `pallet_bridge_messages` //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-08-15, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2024-11-07, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-696hpswk-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! HOSTNAME: `runner-vcatxqpx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("bridge-hub-rococo-dev")`, DB CACHE: 1024 // Executed Command: @@ -53,20 +53,20 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< /// Storage: `BridgePolkadotBulletinGrandpa::ImportedHeaders` (r:1 w:0) /// Proof: `BridgePolkadotBulletinGrandpa::ImportedHeaders` (`max_values`: Some(1024), `max_size`: Some(68), added: 1553, mode: `MaxEncodedLen`) /// Storage: `BridgePolkadotBulletinMessages::InboundLanes` (r:1 w:1) - /// Proof: `BridgePolkadotBulletinMessages::InboundLanes` (`max_values`: None, `max_size`: Some(49209), added: 51684, mode: `MaxEncodedLen`) + /// Proof: `BridgePolkadotBulletinMessages::InboundLanes` (`max_values`: None, `max_size`: Some(49208), added: 51683, mode: `MaxEncodedLen`) /// Storage: `XcmOverPolkadotBulletin::LaneToBridge` (r:1 w:0) - /// Proof: `XcmOverPolkadotBulletin::LaneToBridge` (`max_values`: None, `max_size`: Some(65), added: 2540, mode: `MaxEncodedLen`) + /// Proof: `XcmOverPolkadotBulletin::LaneToBridge` (`max_values`: None, `max_size`: Some(64), added: 2539, mode: `MaxEncodedLen`) /// Storage: `XcmOverPolkadotBulletin::Bridges` (r:1 w:0) - /// Proof: `XcmOverPolkadotBulletin::Bridges` (`max_values`: None, `max_size`: Some(1918), added: 4393, mode: `MaxEncodedLen`) + /// Proof: `XcmOverPolkadotBulletin::Bridges` (`max_values`: None, `max_size`: Some(1921), added: 4396, mode: `MaxEncodedLen`) /// Storage: `ParachainInfo::ParachainId` (r:1 w:0) /// Proof: `ParachainInfo::ParachainId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) fn receive_single_message_proof() -> Weight { // Proof Size summary in bytes: - // Measured: `933` - // Estimated: `52674` - // Minimum execution time: 61_893_000 picoseconds. - Weight::from_parts(63_358_000, 0) - .saturating_add(Weight::from_parts(0, 52674)) + // Measured: `963` + // Estimated: `52673` + // Minimum execution time: 61_743_000 picoseconds. + Weight::from_parts(63_580_000, 0) + .saturating_add(Weight::from_parts(0, 52673)) .saturating_add(T::DbWeight::get().reads(6)) .saturating_add(T::DbWeight::get().writes(1)) } @@ -75,24 +75,24 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< /// Storage: `BridgePolkadotBulletinGrandpa::ImportedHeaders` (r:1 w:0) /// Proof: `BridgePolkadotBulletinGrandpa::ImportedHeaders` (`max_values`: Some(1024), `max_size`: Some(68), added: 1553, mode: `MaxEncodedLen`) /// Storage: `BridgePolkadotBulletinMessages::InboundLanes` (r:1 w:1) - /// Proof: `BridgePolkadotBulletinMessages::InboundLanes` (`max_values`: None, `max_size`: Some(49209), added: 51684, mode: `MaxEncodedLen`) + /// Proof: `BridgePolkadotBulletinMessages::InboundLanes` (`max_values`: None, `max_size`: Some(49208), added: 51683, mode: `MaxEncodedLen`) /// Storage: `XcmOverPolkadotBulletin::LaneToBridge` (r:1 w:0) - /// Proof: `XcmOverPolkadotBulletin::LaneToBridge` (`max_values`: None, `max_size`: Some(65), added: 2540, mode: `MaxEncodedLen`) + /// Proof: `XcmOverPolkadotBulletin::LaneToBridge` (`max_values`: None, `max_size`: Some(64), added: 2539, mode: `MaxEncodedLen`) /// Storage: `XcmOverPolkadotBulletin::Bridges` (r:1 w:0) - /// Proof: `XcmOverPolkadotBulletin::Bridges` (`max_values`: None, `max_size`: Some(1918), added: 4393, mode: `MaxEncodedLen`) + /// Proof: `XcmOverPolkadotBulletin::Bridges` (`max_values`: None, `max_size`: Some(1921), added: 4396, mode: `MaxEncodedLen`) /// Storage: `ParachainInfo::ParachainId` (r:1 w:0) /// Proof: `ParachainInfo::ParachainId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) /// The range of component `n` is `[1, 4076]`. /// The range of component `n` is `[1, 4076]`. fn receive_n_messages_proof(n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `933` - // Estimated: `52674` - // Minimum execution time: 61_612_000 picoseconds. - Weight::from_parts(62_758_000, 0) - .saturating_add(Weight::from_parts(0, 52674)) - // Standard Error: 13_521 - .saturating_add(Weight::from_parts(14_530_846, 0).saturating_mul(n.into())) + // Measured: `963` + // Estimated: `52673` + // Minimum execution time: 61_363_000 picoseconds. + Weight::from_parts(63_084_000, 0) + .saturating_add(Weight::from_parts(0, 52673)) + // Standard Error: 15_252 + .saturating_add(Weight::from_parts(14_868_979, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(6)) .saturating_add(T::DbWeight::get().writes(1)) } @@ -101,20 +101,20 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< /// Storage: `BridgePolkadotBulletinGrandpa::ImportedHeaders` (r:1 w:0) /// Proof: `BridgePolkadotBulletinGrandpa::ImportedHeaders` (`max_values`: Some(1024), `max_size`: Some(68), added: 1553, mode: `MaxEncodedLen`) /// Storage: `BridgePolkadotBulletinMessages::InboundLanes` (r:1 w:1) - /// Proof: `BridgePolkadotBulletinMessages::InboundLanes` (`max_values`: None, `max_size`: Some(49209), added: 51684, mode: `MaxEncodedLen`) + /// Proof: `BridgePolkadotBulletinMessages::InboundLanes` (`max_values`: None, `max_size`: Some(49208), added: 51683, mode: `MaxEncodedLen`) /// Storage: `XcmOverPolkadotBulletin::LaneToBridge` (r:1 w:0) - /// Proof: `XcmOverPolkadotBulletin::LaneToBridge` (`max_values`: None, `max_size`: Some(65), added: 2540, mode: `MaxEncodedLen`) + /// Proof: `XcmOverPolkadotBulletin::LaneToBridge` (`max_values`: None, `max_size`: Some(64), added: 2539, mode: `MaxEncodedLen`) /// Storage: `XcmOverPolkadotBulletin::Bridges` (r:1 w:0) - /// Proof: `XcmOverPolkadotBulletin::Bridges` (`max_values`: None, `max_size`: Some(1918), added: 4393, mode: `MaxEncodedLen`) + /// Proof: `XcmOverPolkadotBulletin::Bridges` (`max_values`: None, `max_size`: Some(1921), added: 4396, mode: `MaxEncodedLen`) /// Storage: `ParachainInfo::ParachainId` (r:1 w:0) /// Proof: `ParachainInfo::ParachainId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) fn receive_single_message_proof_with_outbound_lane_state() -> Weight { // Proof Size summary in bytes: - // Measured: `933` - // Estimated: `52674` - // Minimum execution time: 66_862_000 picoseconds. - Weight::from_parts(69_531_000, 0) - .saturating_add(Weight::from_parts(0, 52674)) + // Measured: `963` + // Estimated: `52673` + // Minimum execution time: 67_767_000 picoseconds. + Weight::from_parts(70_683_000, 0) + .saturating_add(Weight::from_parts(0, 52673)) .saturating_add(T::DbWeight::get().reads(6)) .saturating_add(T::DbWeight::get().writes(1)) } @@ -123,24 +123,24 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< /// Storage: `BridgePolkadotBulletinGrandpa::ImportedHeaders` (r:1 w:0) /// Proof: `BridgePolkadotBulletinGrandpa::ImportedHeaders` (`max_values`: Some(1024), `max_size`: Some(68), added: 1553, mode: `MaxEncodedLen`) /// Storage: `BridgePolkadotBulletinMessages::InboundLanes` (r:1 w:1) - /// Proof: `BridgePolkadotBulletinMessages::InboundLanes` (`max_values`: None, `max_size`: Some(49209), added: 51684, mode: `MaxEncodedLen`) + /// Proof: `BridgePolkadotBulletinMessages::InboundLanes` (`max_values`: None, `max_size`: Some(49208), added: 51683, mode: `MaxEncodedLen`) /// Storage: `XcmOverPolkadotBulletin::LaneToBridge` (r:1 w:0) - /// Proof: `XcmOverPolkadotBulletin::LaneToBridge` (`max_values`: None, `max_size`: Some(65), added: 2540, mode: `MaxEncodedLen`) + /// Proof: `XcmOverPolkadotBulletin::LaneToBridge` (`max_values`: None, `max_size`: Some(64), added: 2539, mode: `MaxEncodedLen`) /// Storage: `XcmOverPolkadotBulletin::Bridges` (r:1 w:0) - /// Proof: `XcmOverPolkadotBulletin::Bridges` (`max_values`: None, `max_size`: Some(1918), added: 4393, mode: `MaxEncodedLen`) + /// Proof: `XcmOverPolkadotBulletin::Bridges` (`max_values`: None, `max_size`: Some(1921), added: 4396, mode: `MaxEncodedLen`) /// Storage: `ParachainInfo::ParachainId` (r:1 w:0) /// Proof: `ParachainInfo::ParachainId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) /// The range of component `n` is `[1, 16384]`. /// The range of component `n` is `[1, 16384]`. fn receive_single_n_bytes_message_proof(n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `933` - // Estimated: `52674` - // Minimum execution time: 58_971_000 picoseconds. - Weight::from_parts(62_999_984, 0) - .saturating_add(Weight::from_parts(0, 52674)) - // Standard Error: 7 - .saturating_add(Weight::from_parts(2_050, 0).saturating_mul(n.into())) + // Measured: `963` + // Estimated: `52673` + // Minimum execution time: 59_522_000 picoseconds. + Weight::from_parts(64_576_781, 0) + .saturating_add(Weight::from_parts(0, 52673)) + // Standard Error: 8 + .saturating_add(Weight::from_parts(2_331, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(6)) .saturating_add(T::DbWeight::get().writes(1)) } @@ -149,20 +149,20 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< /// Storage: `BridgePolkadotBulletinGrandpa::ImportedHeaders` (r:1 w:0) /// Proof: `BridgePolkadotBulletinGrandpa::ImportedHeaders` (`max_values`: Some(1024), `max_size`: Some(68), added: 1553, mode: `MaxEncodedLen`) /// Storage: `BridgePolkadotBulletinMessages::OutboundLanes` (r:1 w:1) - /// Proof: `BridgePolkadotBulletinMessages::OutboundLanes` (`max_values`: None, `max_size`: Some(74), added: 2549, mode: `MaxEncodedLen`) + /// Proof: `BridgePolkadotBulletinMessages::OutboundLanes` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) /// Storage: `XcmOverPolkadotBulletin::LaneToBridge` (r:1 w:0) - /// Proof: `XcmOverPolkadotBulletin::LaneToBridge` (`max_values`: None, `max_size`: Some(65), added: 2540, mode: `MaxEncodedLen`) + /// Proof: `XcmOverPolkadotBulletin::LaneToBridge` (`max_values`: None, `max_size`: Some(64), added: 2539, mode: `MaxEncodedLen`) /// Storage: `XcmOverPolkadotBulletin::Bridges` (r:1 w:0) - /// Proof: `XcmOverPolkadotBulletin::Bridges` (`max_values`: None, `max_size`: Some(1918), added: 4393, mode: `MaxEncodedLen`) + /// Proof: `XcmOverPolkadotBulletin::Bridges` (`max_values`: None, `max_size`: Some(1921), added: 4396, mode: `MaxEncodedLen`) /// Storage: `BridgePolkadotBulletinMessages::OutboundMessages` (r:0 w:1) - /// Proof: `BridgePolkadotBulletinMessages::OutboundMessages` (`max_values`: None, `max_size`: Some(65597), added: 68072, mode: `MaxEncodedLen`) + /// Proof: `BridgePolkadotBulletinMessages::OutboundMessages` (`max_values`: None, `max_size`: Some(65596), added: 68071, mode: `MaxEncodedLen`) fn receive_delivery_proof_for_single_message() -> Weight { // Proof Size summary in bytes: - // Measured: `900` - // Estimated: `5383` - // Minimum execution time: 43_066_000 picoseconds. - Weight::from_parts(43_878_000, 0) - .saturating_add(Weight::from_parts(0, 5383)) + // Measured: `930` + // Estimated: `5386` + // Minimum execution time: 44_282_000 picoseconds. + Weight::from_parts(45_854_000, 0) + .saturating_add(Weight::from_parts(0, 5386)) .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(2)) } @@ -171,20 +171,20 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< /// Storage: `BridgePolkadotBulletinGrandpa::ImportedHeaders` (r:1 w:0) /// Proof: `BridgePolkadotBulletinGrandpa::ImportedHeaders` (`max_values`: Some(1024), `max_size`: Some(68), added: 1553, mode: `MaxEncodedLen`) /// Storage: `BridgePolkadotBulletinMessages::OutboundLanes` (r:1 w:1) - /// Proof: `BridgePolkadotBulletinMessages::OutboundLanes` (`max_values`: None, `max_size`: Some(74), added: 2549, mode: `MaxEncodedLen`) + /// Proof: `BridgePolkadotBulletinMessages::OutboundLanes` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) /// Storage: `XcmOverPolkadotBulletin::LaneToBridge` (r:1 w:0) - /// Proof: `XcmOverPolkadotBulletin::LaneToBridge` (`max_values`: None, `max_size`: Some(65), added: 2540, mode: `MaxEncodedLen`) + /// Proof: `XcmOverPolkadotBulletin::LaneToBridge` (`max_values`: None, `max_size`: Some(64), added: 2539, mode: `MaxEncodedLen`) /// Storage: `XcmOverPolkadotBulletin::Bridges` (r:1 w:0) - /// Proof: `XcmOverPolkadotBulletin::Bridges` (`max_values`: None, `max_size`: Some(1918), added: 4393, mode: `MaxEncodedLen`) + /// Proof: `XcmOverPolkadotBulletin::Bridges` (`max_values`: None, `max_size`: Some(1921), added: 4396, mode: `MaxEncodedLen`) /// Storage: `BridgePolkadotBulletinMessages::OutboundMessages` (r:0 w:2) - /// Proof: `BridgePolkadotBulletinMessages::OutboundMessages` (`max_values`: None, `max_size`: Some(65597), added: 68072, mode: `MaxEncodedLen`) + /// Proof: `BridgePolkadotBulletinMessages::OutboundMessages` (`max_values`: None, `max_size`: Some(65596), added: 68071, mode: `MaxEncodedLen`) fn receive_delivery_proof_for_two_messages_by_single_relayer() -> Weight { // Proof Size summary in bytes: - // Measured: `900` - // Estimated: `5383` - // Minimum execution time: 44_120_000 picoseconds. - Weight::from_parts(45_914_000, 0) - .saturating_add(Weight::from_parts(0, 5383)) + // Measured: `930` + // Estimated: `5386` + // Minimum execution time: 46_155_000 picoseconds. + Weight::from_parts(47_460_000, 0) + .saturating_add(Weight::from_parts(0, 5386)) .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(3)) } @@ -193,20 +193,20 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< /// Storage: `BridgePolkadotBulletinGrandpa::ImportedHeaders` (r:1 w:0) /// Proof: `BridgePolkadotBulletinGrandpa::ImportedHeaders` (`max_values`: Some(1024), `max_size`: Some(68), added: 1553, mode: `MaxEncodedLen`) /// Storage: `BridgePolkadotBulletinMessages::OutboundLanes` (r:1 w:1) - /// Proof: `BridgePolkadotBulletinMessages::OutboundLanes` (`max_values`: None, `max_size`: Some(74), added: 2549, mode: `MaxEncodedLen`) + /// Proof: `BridgePolkadotBulletinMessages::OutboundLanes` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) /// Storage: `XcmOverPolkadotBulletin::LaneToBridge` (r:1 w:0) - /// Proof: `XcmOverPolkadotBulletin::LaneToBridge` (`max_values`: None, `max_size`: Some(65), added: 2540, mode: `MaxEncodedLen`) + /// Proof: `XcmOverPolkadotBulletin::LaneToBridge` (`max_values`: None, `max_size`: Some(64), added: 2539, mode: `MaxEncodedLen`) /// Storage: `XcmOverPolkadotBulletin::Bridges` (r:1 w:0) - /// Proof: `XcmOverPolkadotBulletin::Bridges` (`max_values`: None, `max_size`: Some(1918), added: 4393, mode: `MaxEncodedLen`) + /// Proof: `XcmOverPolkadotBulletin::Bridges` (`max_values`: None, `max_size`: Some(1921), added: 4396, mode: `MaxEncodedLen`) /// Storage: `BridgePolkadotBulletinMessages::OutboundMessages` (r:0 w:2) - /// Proof: `BridgePolkadotBulletinMessages::OutboundMessages` (`max_values`: None, `max_size`: Some(65597), added: 68072, mode: `MaxEncodedLen`) + /// Proof: `BridgePolkadotBulletinMessages::OutboundMessages` (`max_values`: None, `max_size`: Some(65596), added: 68071, mode: `MaxEncodedLen`) fn receive_delivery_proof_for_two_messages_by_two_relayers() -> Weight { // Proof Size summary in bytes: - // Measured: `900` - // Estimated: `5383` - // Minimum execution time: 44_930_000 picoseconds. - Weight::from_parts(46_111_000, 0) - .saturating_add(Weight::from_parts(0, 5383)) + // Measured: `930` + // Estimated: `5386` + // Minimum execution time: 46_050_000 picoseconds. + Weight::from_parts(47_530_000, 0) + .saturating_add(Weight::from_parts(0, 5386)) .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(3)) } @@ -215,11 +215,11 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< /// Storage: `BridgePolkadotBulletinGrandpa::ImportedHeaders` (r:1 w:0) /// Proof: `BridgePolkadotBulletinGrandpa::ImportedHeaders` (`max_values`: Some(1024), `max_size`: Some(68), added: 1553, mode: `MaxEncodedLen`) /// Storage: `BridgePolkadotBulletinMessages::InboundLanes` (r:1 w:1) - /// Proof: `BridgePolkadotBulletinMessages::InboundLanes` (`max_values`: None, `max_size`: Some(49209), added: 51684, mode: `MaxEncodedLen`) + /// Proof: `BridgePolkadotBulletinMessages::InboundLanes` (`max_values`: None, `max_size`: Some(49208), added: 51683, mode: `MaxEncodedLen`) /// Storage: `XcmOverPolkadotBulletin::LaneToBridge` (r:1 w:0) - /// Proof: `XcmOverPolkadotBulletin::LaneToBridge` (`max_values`: None, `max_size`: Some(65), added: 2540, mode: `MaxEncodedLen`) + /// Proof: `XcmOverPolkadotBulletin::LaneToBridge` (`max_values`: None, `max_size`: Some(64), added: 2539, mode: `MaxEncodedLen`) /// Storage: `XcmOverPolkadotBulletin::Bridges` (r:1 w:0) - /// Proof: `XcmOverPolkadotBulletin::Bridges` (`max_values`: None, `max_size`: Some(1918), added: 4393, mode: `MaxEncodedLen`) + /// Proof: `XcmOverPolkadotBulletin::Bridges` (`max_values`: None, `max_size`: Some(1921), added: 4396, mode: `MaxEncodedLen`) /// Storage: `ParachainInfo::ParachainId` (r:1 w:0) /// Proof: `ParachainInfo::ParachainId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) /// Storage: `XcmpQueue::DeliveryFeeFactor` (r:1 w:0) @@ -240,13 +240,13 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< /// The range of component `n` is `[1, 16384]`. fn receive_single_n_bytes_message_proof_with_dispatch(n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `1092` - // Estimated: `52674` - // Minimum execution time: 81_911_000 picoseconds. - Weight::from_parts(88_170_136, 0) - .saturating_add(Weight::from_parts(0, 52674)) - // Standard Error: 9 - .saturating_add(Weight::from_parts(7_233, 0).saturating_mul(n.into())) + // Measured: `1122` + // Estimated: `52673` + // Minimum execution time: 83_884_000 picoseconds. + Weight::from_parts(90_305_551, 0) + .saturating_add(Weight::from_parts(0, 52673)) + // Standard Error: 8 + .saturating_add(Weight::from_parts(7_569, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(12)) .saturating_add(T::DbWeight::get().writes(4)) } diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/pallet_bridge_messages_rococo_to_westend.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/pallet_bridge_messages_rococo_to_westend.rs index b27bbf4ff6c6..13862f39fd68 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/pallet_bridge_messages_rococo_to_westend.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/pallet_bridge_messages_rococo_to_westend.rs @@ -17,9 +17,9 @@ //! Autogenerated weights for `pallet_bridge_messages` //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-08-15, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2024-11-07, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-696hpswk-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! HOSTNAME: `runner-vcatxqpx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("bridge-hub-rococo-dev")`, DB CACHE: 1024 // Executed Command: @@ -53,21 +53,23 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< /// Storage: `BridgeWestendParachains::ImportedParaHeads` (r:1 w:0) /// Proof: `BridgeWestendParachains::ImportedParaHeads` (`max_values`: Some(64), `max_size`: Some(196), added: 1186, mode: `MaxEncodedLen`) /// Storage: `BridgeWestendMessages::InboundLanes` (r:1 w:1) - /// Proof: `BridgeWestendMessages::InboundLanes` (`max_values`: None, `max_size`: Some(49209), added: 51684, mode: `MaxEncodedLen`) + /// Proof: `BridgeWestendMessages::InboundLanes` (`max_values`: None, `max_size`: Some(49180), added: 51655, mode: `MaxEncodedLen`) /// Storage: `XcmOverBridgeHubWestend::LaneToBridge` (r:1 w:0) - /// Proof: `XcmOverBridgeHubWestend::LaneToBridge` (`max_values`: None, `max_size`: Some(65), added: 2540, mode: `MaxEncodedLen`) + /// Proof: `XcmOverBridgeHubWestend::LaneToBridge` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `MaxEncodedLen`) /// Storage: `XcmOverBridgeHubWestend::Bridges` (r:1 w:0) - /// Proof: `XcmOverBridgeHubWestend::Bridges` (`max_values`: None, `max_size`: Some(1918), added: 4393, mode: `MaxEncodedLen`) + /// Proof: `XcmOverBridgeHubWestend::Bridges` (`max_values`: None, `max_size`: Some(1893), added: 4368, mode: `MaxEncodedLen`) + /// Storage: `XcmpQueue::OutboundXcmpStatus` (r:1 w:0) + /// Proof: `XcmpQueue::OutboundXcmpStatus` (`max_values`: Some(1), `max_size`: Some(1282), added: 1777, mode: `MaxEncodedLen`) /// Storage: `ParachainInfo::ParachainId` (r:1 w:0) /// Proof: `ParachainInfo::ParachainId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) fn receive_single_message_proof() -> Weight { // Proof Size summary in bytes: - // Measured: `810` - // Estimated: `52674` - // Minimum execution time: 62_750_000 picoseconds. - Weight::from_parts(65_328_000, 0) - .saturating_add(Weight::from_parts(0, 52674)) - .saturating_add(T::DbWeight::get().reads(6)) + // Measured: `940` + // Estimated: `52645` + // Minimum execution time: 61_880_000 picoseconds. + Weight::from_parts(64_292_000, 0) + .saturating_add(Weight::from_parts(0, 52645)) + .saturating_add(T::DbWeight::get().reads(7)) .saturating_add(T::DbWeight::get().writes(1)) } /// Storage: `BridgeWestendMessages::PalletOperatingMode` (r:1 w:0) @@ -75,25 +77,27 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< /// Storage: `BridgeWestendParachains::ImportedParaHeads` (r:1 w:0) /// Proof: `BridgeWestendParachains::ImportedParaHeads` (`max_values`: Some(64), `max_size`: Some(196), added: 1186, mode: `MaxEncodedLen`) /// Storage: `BridgeWestendMessages::InboundLanes` (r:1 w:1) - /// Proof: `BridgeWestendMessages::InboundLanes` (`max_values`: None, `max_size`: Some(49209), added: 51684, mode: `MaxEncodedLen`) + /// Proof: `BridgeWestendMessages::InboundLanes` (`max_values`: None, `max_size`: Some(49180), added: 51655, mode: `MaxEncodedLen`) /// Storage: `XcmOverBridgeHubWestend::LaneToBridge` (r:1 w:0) - /// Proof: `XcmOverBridgeHubWestend::LaneToBridge` (`max_values`: None, `max_size`: Some(65), added: 2540, mode: `MaxEncodedLen`) + /// Proof: `XcmOverBridgeHubWestend::LaneToBridge` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `MaxEncodedLen`) /// Storage: `XcmOverBridgeHubWestend::Bridges` (r:1 w:0) - /// Proof: `XcmOverBridgeHubWestend::Bridges` (`max_values`: None, `max_size`: Some(1918), added: 4393, mode: `MaxEncodedLen`) + /// Proof: `XcmOverBridgeHubWestend::Bridges` (`max_values`: None, `max_size`: Some(1893), added: 4368, mode: `MaxEncodedLen`) + /// Storage: `XcmpQueue::OutboundXcmpStatus` (r:1 w:0) + /// Proof: `XcmpQueue::OutboundXcmpStatus` (`max_values`: Some(1), `max_size`: Some(1282), added: 1777, mode: `MaxEncodedLen`) /// Storage: `ParachainInfo::ParachainId` (r:1 w:0) /// Proof: `ParachainInfo::ParachainId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) /// The range of component `n` is `[1, 4076]`. /// The range of component `n` is `[1, 4076]`. fn receive_n_messages_proof(n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `810` - // Estimated: `52674` - // Minimum execution time: 62_275_000 picoseconds. - Weight::from_parts(63_714_000, 0) - .saturating_add(Weight::from_parts(0, 52674)) - // Standard Error: 13_139 - .saturating_add(Weight::from_parts(14_630_892, 0).saturating_mul(n.into())) - .saturating_add(T::DbWeight::get().reads(6)) + // Measured: `940` + // Estimated: `52645` + // Minimum execution time: 62_267_000 picoseconds. + Weight::from_parts(63_625_000, 0) + .saturating_add(Weight::from_parts(0, 52645)) + // Standard Error: 10_655 + .saturating_add(Weight::from_parts(11_829_871, 0).saturating_mul(n.into())) + .saturating_add(T::DbWeight::get().reads(7)) .saturating_add(T::DbWeight::get().writes(1)) } /// Storage: `BridgeWestendMessages::PalletOperatingMode` (r:1 w:0) @@ -101,21 +105,23 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< /// Storage: `BridgeWestendParachains::ImportedParaHeads` (r:1 w:0) /// Proof: `BridgeWestendParachains::ImportedParaHeads` (`max_values`: Some(64), `max_size`: Some(196), added: 1186, mode: `MaxEncodedLen`) /// Storage: `BridgeWestendMessages::InboundLanes` (r:1 w:1) - /// Proof: `BridgeWestendMessages::InboundLanes` (`max_values`: None, `max_size`: Some(49209), added: 51684, mode: `MaxEncodedLen`) + /// Proof: `BridgeWestendMessages::InboundLanes` (`max_values`: None, `max_size`: Some(49180), added: 51655, mode: `MaxEncodedLen`) /// Storage: `XcmOverBridgeHubWestend::LaneToBridge` (r:1 w:0) - /// Proof: `XcmOverBridgeHubWestend::LaneToBridge` (`max_values`: None, `max_size`: Some(65), added: 2540, mode: `MaxEncodedLen`) + /// Proof: `XcmOverBridgeHubWestend::LaneToBridge` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `MaxEncodedLen`) /// Storage: `XcmOverBridgeHubWestend::Bridges` (r:1 w:0) - /// Proof: `XcmOverBridgeHubWestend::Bridges` (`max_values`: None, `max_size`: Some(1918), added: 4393, mode: `MaxEncodedLen`) + /// Proof: `XcmOverBridgeHubWestend::Bridges` (`max_values`: None, `max_size`: Some(1893), added: 4368, mode: `MaxEncodedLen`) + /// Storage: `XcmpQueue::OutboundXcmpStatus` (r:1 w:0) + /// Proof: `XcmpQueue::OutboundXcmpStatus` (`max_values`: Some(1), `max_size`: Some(1282), added: 1777, mode: `MaxEncodedLen`) /// Storage: `ParachainInfo::ParachainId` (r:1 w:0) /// Proof: `ParachainInfo::ParachainId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) fn receive_single_message_proof_with_outbound_lane_state() -> Weight { // Proof Size summary in bytes: - // Measured: `810` - // Estimated: `52674` - // Minimum execution time: 68_950_000 picoseconds. - Weight::from_parts(71_420_000, 0) - .saturating_add(Weight::from_parts(0, 52674)) - .saturating_add(T::DbWeight::get().reads(6)) + // Measured: `940` + // Estimated: `52645` + // Minimum execution time: 68_483_000 picoseconds. + Weight::from_parts(71_827_000, 0) + .saturating_add(Weight::from_parts(0, 52645)) + .saturating_add(T::DbWeight::get().reads(7)) .saturating_add(T::DbWeight::get().writes(1)) } /// Storage: `BridgeWestendMessages::PalletOperatingMode` (r:1 w:0) @@ -123,25 +129,27 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< /// Storage: `BridgeWestendParachains::ImportedParaHeads` (r:1 w:0) /// Proof: `BridgeWestendParachains::ImportedParaHeads` (`max_values`: Some(64), `max_size`: Some(196), added: 1186, mode: `MaxEncodedLen`) /// Storage: `BridgeWestendMessages::InboundLanes` (r:1 w:1) - /// Proof: `BridgeWestendMessages::InboundLanes` (`max_values`: None, `max_size`: Some(49209), added: 51684, mode: `MaxEncodedLen`) + /// Proof: `BridgeWestendMessages::InboundLanes` (`max_values`: None, `max_size`: Some(49180), added: 51655, mode: `MaxEncodedLen`) /// Storage: `XcmOverBridgeHubWestend::LaneToBridge` (r:1 w:0) - /// Proof: `XcmOverBridgeHubWestend::LaneToBridge` (`max_values`: None, `max_size`: Some(65), added: 2540, mode: `MaxEncodedLen`) + /// Proof: `XcmOverBridgeHubWestend::LaneToBridge` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `MaxEncodedLen`) /// Storage: `XcmOverBridgeHubWestend::Bridges` (r:1 w:0) - /// Proof: `XcmOverBridgeHubWestend::Bridges` (`max_values`: None, `max_size`: Some(1918), added: 4393, mode: `MaxEncodedLen`) + /// Proof: `XcmOverBridgeHubWestend::Bridges` (`max_values`: None, `max_size`: Some(1893), added: 4368, mode: `MaxEncodedLen`) + /// Storage: `XcmpQueue::OutboundXcmpStatus` (r:1 w:0) + /// Proof: `XcmpQueue::OutboundXcmpStatus` (`max_values`: Some(1), `max_size`: Some(1282), added: 1777, mode: `MaxEncodedLen`) /// Storage: `ParachainInfo::ParachainId` (r:1 w:0) /// Proof: `ParachainInfo::ParachainId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) /// The range of component `n` is `[1, 16384]`. /// The range of component `n` is `[1, 16384]`. fn receive_single_n_bytes_message_proof(n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `810` - // Estimated: `52674` - // Minimum execution time: 60_477_000 picoseconds. - Weight::from_parts(64_935_758, 0) - .saturating_add(Weight::from_parts(0, 52674)) - // Standard Error: 8 - .saturating_add(Weight::from_parts(2_008, 0).saturating_mul(n.into())) - .saturating_add(T::DbWeight::get().reads(6)) + // Measured: `940` + // Estimated: `52645` + // Minimum execution time: 60_870_000 picoseconds. + Weight::from_parts(65_369_830, 0) + .saturating_add(Weight::from_parts(0, 52645)) + // Standard Error: 9 + .saturating_add(Weight::from_parts(2_306, 0).saturating_mul(n.into())) + .saturating_add(T::DbWeight::get().reads(7)) .saturating_add(T::DbWeight::get().writes(1)) } /// Storage: `BridgeWestendMessages::PalletOperatingMode` (r:1 w:0) @@ -149,24 +157,24 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< /// Storage: `BridgeWestendParachains::ImportedParaHeads` (r:1 w:0) /// Proof: `BridgeWestendParachains::ImportedParaHeads` (`max_values`: Some(64), `max_size`: Some(196), added: 1186, mode: `MaxEncodedLen`) /// Storage: `BridgeWestendMessages::OutboundLanes` (r:1 w:1) - /// Proof: `BridgeWestendMessages::OutboundLanes` (`max_values`: None, `max_size`: Some(74), added: 2549, mode: `MaxEncodedLen`) + /// Proof: `BridgeWestendMessages::OutboundLanes` (`max_values`: None, `max_size`: Some(45), added: 2520, mode: `MaxEncodedLen`) /// Storage: UNKNOWN KEY `0x6e0a18b62a1de81c5f519181cc611e18` (r:1 w:0) /// Proof: UNKNOWN KEY `0x6e0a18b62a1de81c5f519181cc611e18` (r:1 w:0) /// Storage: `BridgeRelayers::RelayerRewards` (r:1 w:1) - /// Proof: `BridgeRelayers::RelayerRewards` (`max_values`: None, `max_size`: Some(102), added: 2577, mode: `MaxEncodedLen`) + /// Proof: `BridgeRelayers::RelayerRewards` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) /// Storage: `XcmOverBridgeHubWestend::LaneToBridge` (r:1 w:0) - /// Proof: `XcmOverBridgeHubWestend::LaneToBridge` (`max_values`: None, `max_size`: Some(65), added: 2540, mode: `MaxEncodedLen`) + /// Proof: `XcmOverBridgeHubWestend::LaneToBridge` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `MaxEncodedLen`) /// Storage: `XcmOverBridgeHubWestend::Bridges` (r:1 w:0) - /// Proof: `XcmOverBridgeHubWestend::Bridges` (`max_values`: None, `max_size`: Some(1918), added: 4393, mode: `MaxEncodedLen`) + /// Proof: `XcmOverBridgeHubWestend::Bridges` (`max_values`: None, `max_size`: Some(1893), added: 4368, mode: `MaxEncodedLen`) /// Storage: `BridgeWestendMessages::OutboundMessages` (r:0 w:1) - /// Proof: `BridgeWestendMessages::OutboundMessages` (`max_values`: None, `max_size`: Some(65597), added: 68072, mode: `MaxEncodedLen`) + /// Proof: `BridgeWestendMessages::OutboundMessages` (`max_values`: None, `max_size`: Some(65568), added: 68043, mode: `MaxEncodedLen`) fn receive_delivery_proof_for_single_message() -> Weight { // Proof Size summary in bytes: - // Measured: `779` - // Estimated: `5383` - // Minimum execution time: 52_939_000 picoseconds. - Weight::from_parts(54_637_000, 0) - .saturating_add(Weight::from_parts(0, 5383)) + // Measured: `711` + // Estimated: `5358` + // Minimum execution time: 50_879_000 picoseconds. + Weight::from_parts(52_159_000, 0) + .saturating_add(Weight::from_parts(0, 5358)) .saturating_add(T::DbWeight::get().reads(7)) .saturating_add(T::DbWeight::get().writes(3)) } @@ -175,24 +183,24 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< /// Storage: `BridgeWestendParachains::ImportedParaHeads` (r:1 w:0) /// Proof: `BridgeWestendParachains::ImportedParaHeads` (`max_values`: Some(64), `max_size`: Some(196), added: 1186, mode: `MaxEncodedLen`) /// Storage: `BridgeWestendMessages::OutboundLanes` (r:1 w:1) - /// Proof: `BridgeWestendMessages::OutboundLanes` (`max_values`: None, `max_size`: Some(74), added: 2549, mode: `MaxEncodedLen`) + /// Proof: `BridgeWestendMessages::OutboundLanes` (`max_values`: None, `max_size`: Some(45), added: 2520, mode: `MaxEncodedLen`) /// Storage: UNKNOWN KEY `0x6e0a18b62a1de81c5f519181cc611e18` (r:1 w:0) /// Proof: UNKNOWN KEY `0x6e0a18b62a1de81c5f519181cc611e18` (r:1 w:0) /// Storage: `BridgeRelayers::RelayerRewards` (r:1 w:1) - /// Proof: `BridgeRelayers::RelayerRewards` (`max_values`: None, `max_size`: Some(102), added: 2577, mode: `MaxEncodedLen`) + /// Proof: `BridgeRelayers::RelayerRewards` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) /// Storage: `XcmOverBridgeHubWestend::LaneToBridge` (r:1 w:0) - /// Proof: `XcmOverBridgeHubWestend::LaneToBridge` (`max_values`: None, `max_size`: Some(65), added: 2540, mode: `MaxEncodedLen`) + /// Proof: `XcmOverBridgeHubWestend::LaneToBridge` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `MaxEncodedLen`) /// Storage: `XcmOverBridgeHubWestend::Bridges` (r:1 w:0) - /// Proof: `XcmOverBridgeHubWestend::Bridges` (`max_values`: None, `max_size`: Some(1918), added: 4393, mode: `MaxEncodedLen`) + /// Proof: `XcmOverBridgeHubWestend::Bridges` (`max_values`: None, `max_size`: Some(1893), added: 4368, mode: `MaxEncodedLen`) /// Storage: `BridgeWestendMessages::OutboundMessages` (r:0 w:2) - /// Proof: `BridgeWestendMessages::OutboundMessages` (`max_values`: None, `max_size`: Some(65597), added: 68072, mode: `MaxEncodedLen`) + /// Proof: `BridgeWestendMessages::OutboundMessages` (`max_values`: None, `max_size`: Some(65568), added: 68043, mode: `MaxEncodedLen`) fn receive_delivery_proof_for_two_messages_by_single_relayer() -> Weight { // Proof Size summary in bytes: - // Measured: `779` - // Estimated: `5383` - // Minimum execution time: 54_645_000 picoseconds. - Weight::from_parts(57_391_000, 0) - .saturating_add(Weight::from_parts(0, 5383)) + // Measured: `711` + // Estimated: `5358` + // Minimum execution time: 52_336_000 picoseconds. + Weight::from_parts(53_754_000, 0) + .saturating_add(Weight::from_parts(0, 5358)) .saturating_add(T::DbWeight::get().reads(7)) .saturating_add(T::DbWeight::get().writes(4)) } @@ -201,24 +209,24 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< /// Storage: `BridgeWestendParachains::ImportedParaHeads` (r:1 w:0) /// Proof: `BridgeWestendParachains::ImportedParaHeads` (`max_values`: Some(64), `max_size`: Some(196), added: 1186, mode: `MaxEncodedLen`) /// Storage: `BridgeWestendMessages::OutboundLanes` (r:1 w:1) - /// Proof: `BridgeWestendMessages::OutboundLanes` (`max_values`: None, `max_size`: Some(74), added: 2549, mode: `MaxEncodedLen`) + /// Proof: `BridgeWestendMessages::OutboundLanes` (`max_values`: None, `max_size`: Some(45), added: 2520, mode: `MaxEncodedLen`) /// Storage: UNKNOWN KEY `0x6e0a18b62a1de81c5f519181cc611e18` (r:1 w:0) /// Proof: UNKNOWN KEY `0x6e0a18b62a1de81c5f519181cc611e18` (r:1 w:0) /// Storage: `BridgeRelayers::RelayerRewards` (r:2 w:2) - /// Proof: `BridgeRelayers::RelayerRewards` (`max_values`: None, `max_size`: Some(102), added: 2577, mode: `MaxEncodedLen`) + /// Proof: `BridgeRelayers::RelayerRewards` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) /// Storage: `XcmOverBridgeHubWestend::LaneToBridge` (r:1 w:0) - /// Proof: `XcmOverBridgeHubWestend::LaneToBridge` (`max_values`: None, `max_size`: Some(65), added: 2540, mode: `MaxEncodedLen`) + /// Proof: `XcmOverBridgeHubWestend::LaneToBridge` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `MaxEncodedLen`) /// Storage: `XcmOverBridgeHubWestend::Bridges` (r:1 w:0) - /// Proof: `XcmOverBridgeHubWestend::Bridges` (`max_values`: None, `max_size`: Some(1918), added: 4393, mode: `MaxEncodedLen`) + /// Proof: `XcmOverBridgeHubWestend::Bridges` (`max_values`: None, `max_size`: Some(1893), added: 4368, mode: `MaxEncodedLen`) /// Storage: `BridgeWestendMessages::OutboundMessages` (r:0 w:2) - /// Proof: `BridgeWestendMessages::OutboundMessages` (`max_values`: None, `max_size`: Some(65597), added: 68072, mode: `MaxEncodedLen`) + /// Proof: `BridgeWestendMessages::OutboundMessages` (`max_values`: None, `max_size`: Some(65568), added: 68043, mode: `MaxEncodedLen`) fn receive_delivery_proof_for_two_messages_by_two_relayers() -> Weight { // Proof Size summary in bytes: - // Measured: `779` - // Estimated: `6144` - // Minimum execution time: 59_581_000 picoseconds. - Weight::from_parts(61_657_000, 0) - .saturating_add(Weight::from_parts(0, 6144)) + // Measured: `711` + // Estimated: `6086` + // Minimum execution time: 56_457_000 picoseconds. + Weight::from_parts(58_435_000, 0) + .saturating_add(Weight::from_parts(0, 6086)) .saturating_add(T::DbWeight::get().reads(8)) .saturating_add(T::DbWeight::get().writes(5)) } @@ -227,11 +235,13 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< /// Storage: `BridgeWestendParachains::ImportedParaHeads` (r:1 w:0) /// Proof: `BridgeWestendParachains::ImportedParaHeads` (`max_values`: Some(64), `max_size`: Some(196), added: 1186, mode: `MaxEncodedLen`) /// Storage: `BridgeWestendMessages::InboundLanes` (r:1 w:1) - /// Proof: `BridgeWestendMessages::InboundLanes` (`max_values`: None, `max_size`: Some(49209), added: 51684, mode: `MaxEncodedLen`) + /// Proof: `BridgeWestendMessages::InboundLanes` (`max_values`: None, `max_size`: Some(49180), added: 51655, mode: `MaxEncodedLen`) /// Storage: `XcmOverBridgeHubWestend::LaneToBridge` (r:1 w:0) - /// Proof: `XcmOverBridgeHubWestend::LaneToBridge` (`max_values`: None, `max_size`: Some(65), added: 2540, mode: `MaxEncodedLen`) + /// Proof: `XcmOverBridgeHubWestend::LaneToBridge` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `MaxEncodedLen`) /// Storage: `XcmOverBridgeHubWestend::Bridges` (r:1 w:0) - /// Proof: `XcmOverBridgeHubWestend::Bridges` (`max_values`: None, `max_size`: Some(1918), added: 4393, mode: `MaxEncodedLen`) + /// Proof: `XcmOverBridgeHubWestend::Bridges` (`max_values`: None, `max_size`: Some(1893), added: 4368, mode: `MaxEncodedLen`) + /// Storage: `XcmpQueue::OutboundXcmpStatus` (r:1 w:1) + /// Proof: `XcmpQueue::OutboundXcmpStatus` (`max_values`: Some(1), `max_size`: Some(1282), added: 1777, mode: `MaxEncodedLen`) /// Storage: `ParachainInfo::ParachainId` (r:1 w:0) /// Proof: `ParachainInfo::ParachainId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) /// Storage: `XcmpQueue::DeliveryFeeFactor` (r:1 w:0) @@ -244,21 +254,19 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< /// 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`: Some(1282), added: 1777, mode: `MaxEncodedLen`) /// Storage: `XcmpQueue::OutboundXcmpMessages` (r:0 w:1) /// Proof: `XcmpQueue::OutboundXcmpMessages` (`max_values`: None, `max_size`: Some(105506), added: 107981, mode: `MaxEncodedLen`) /// The range of component `n` is `[1, 16384]`. /// The range of component `n` is `[1, 16384]`. fn receive_single_n_bytes_message_proof_with_dispatch(n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `1140` - // Estimated: `52674` - // Minimum execution time: 83_530_000 picoseconds. - Weight::from_parts(91_297_344, 0) - .saturating_add(Weight::from_parts(0, 52674)) - // Standard Error: 11 - .saturating_add(Weight::from_parts(7_197, 0).saturating_mul(n.into())) + // Measured: `1071` + // Estimated: `52645` + // Minimum execution time: 84_622_000 picoseconds. + Weight::from_parts(90_698_207, 0) + .saturating_add(Weight::from_parts(0, 52645)) + // Standard Error: 10 + .saturating_add(Weight::from_parts(7_543, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(12)) .saturating_add(T::DbWeight::get().writes(4)) } From 31a9670b362d4971bb505e6d3a491af18d67ac00 Mon Sep 17 00:00:00 2001 From: GitHub Action Date: Fri, 8 Nov 2024 17:35:21 +0000 Subject: [PATCH 38/72] Update from bkontur running command 'fmt' --- bridges/modules/xcm-bridge-hub/src/lib.rs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/bridges/modules/xcm-bridge-hub/src/lib.rs b/bridges/modules/xcm-bridge-hub/src/lib.rs index 88332cb5289b..2a13b858a8e9 100644 --- a/bridges/modules/xcm-bridge-hub/src/lib.rs +++ b/bridges/modules/xcm-bridge-hub/src/lib.rs @@ -672,9 +672,12 @@ pub mod pallet { bridge_destination_universal_location.into(), )?; - if !T::AllowWithoutBridgeDeposit::contains(locations.bridge_origin_relative_location()) { - let account_id = T::BridgeOriginAccountIdConverter::convert_location(locations.bridge_origin_relative_location()) - .ok_or(Error::::InvalidBridgeOriginAccount)?; + if !T::AllowWithoutBridgeDeposit::contains(locations.bridge_origin_relative_location()) + { + let account_id = T::BridgeOriginAccountIdConverter::convert_location( + locations.bridge_origin_relative_location(), + ) + .ok_or(Error::::InvalidBridgeOriginAccount)?; fund_account(account_id, T::BridgeDeposit::get()); } From 48f9f00b4cd2b2a638430310053f8d246c6e38d1 Mon Sep 17 00:00:00 2001 From: Branislav Kontur Date: Fri, 8 Nov 2024 18:41:02 +0100 Subject: [PATCH 39/72] Adjust const --- bridges/chains/chain-bridge-hub-rococo/src/lib.rs | 2 +- bridges/chains/chain-bridge-hub-westend/src/lib.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/bridges/chains/chain-bridge-hub-rococo/src/lib.rs b/bridges/chains/chain-bridge-hub-rococo/src/lib.rs index fda6a5f0b722..8683fb31037d 100644 --- a/bridges/chains/chain-bridge-hub-rococo/src/lib.rs +++ b/bridges/chains/chain-bridge-hub-rococo/src/lib.rs @@ -105,7 +105,7 @@ frame_support::parameter_types! { /// The XCM fee that is paid for executing XCM program (with `ExportMessage` instruction) at the Rococo /// BridgeHub. /// (initially was calculated by test `BridgeHubRococo::can_calculate_weight_for_paid_export_message_with_reserve_transfer` + `33%`) - pub const BridgeHubRococoBaseXcmFeeInRocs: u128 = 57_145_832; + pub const BridgeHubRococoBaseXcmFeeInRocs: u128 = 57_325_000; /// Transaction fee that is paid at the Rococo BridgeHub for delivering single inbound message. /// (initially was calculated by test `BridgeHubRococo::can_calculate_fee_for_standalone_message_delivery_transaction` + `33%`) diff --git a/bridges/chains/chain-bridge-hub-westend/src/lib.rs b/bridges/chains/chain-bridge-hub-westend/src/lib.rs index e941b5840238..9456089593c6 100644 --- a/bridges/chains/chain-bridge-hub-westend/src/lib.rs +++ b/bridges/chains/chain-bridge-hub-westend/src/lib.rs @@ -94,7 +94,7 @@ frame_support::parameter_types! { /// The XCM fee that is paid for executing XCM program (with `ExportMessage` instruction) at the Westend /// BridgeHub. /// (initially was calculated by test `BridgeHubWestend::can_calculate_weight_for_paid_export_message_with_reserve_transfer` + `33%`) - pub const BridgeHubWestendBaseXcmFeeInWnds: u128 = 18_191_740_000; + pub const BridgeHubWestendBaseXcmFeeInWnds: u128 = 18_248_930_000; /// Transaction fee that is paid at the Westend BridgeHub for delivering single inbound message. /// (initially was calculated by test `BridgeHubWestend::can_calculate_fee_for_standalone_message_delivery_transaction` + `33%`) From 39eeb89d59e1870e0e105b132430e7be0f1747b1 Mon Sep 17 00:00:00 2001 From: Branislav Kontur Date: Sat, 9 Nov 2024 00:51:10 +0100 Subject: [PATCH 40/72] Add benchmarks for pallet-xcm-bridge-hub --- Cargo.lock | 1 + .../xcm-bridge-hub-router/src/weights.rs | 70 ++++----- bridges/modules/xcm-bridge-hub/Cargo.toml | 3 + .../xcm-bridge-hub/src/benchmarking.rs | 136 ++++++++++++++++++ bridges/modules/xcm-bridge-hub/src/lib.rs | 26 +++- bridges/modules/xcm-bridge-hub/src/mock.rs | 14 ++ bridges/modules/xcm-bridge-hub/src/weights.rs | 90 ++++++++++++ .../src/bridge_to_bulletin_config.rs | 1 + .../src/bridge_to_westend_config.rs | 1 + .../bridge-hubs/bridge-hub-rococo/src/lib.rs | 82 ++++------- .../src/bridge_to_rococo_config.rs | 1 + .../bridge-hubs/bridge-hub-westend/src/lib.rs | 45 ++---- 12 files changed, 333 insertions(+), 137 deletions(-) create mode 100644 bridges/modules/xcm-bridge-hub/src/benchmarking.rs create mode 100644 bridges/modules/xcm-bridge-hub/src/weights.rs diff --git a/Cargo.lock b/Cargo.lock index 2f480509a3da..c8374cf6fa02 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -13243,6 +13243,7 @@ dependencies = [ "bp-messages", "bp-runtime", "bp-xcm-bridge-hub", + "frame-benchmarking", "frame-support", "frame-system", "log", diff --git a/bridges/modules/xcm-bridge-hub-router/src/weights.rs b/bridges/modules/xcm-bridge-hub-router/src/weights.rs index f462e649bc9c..046cd2bc45df 100644 --- a/bridges/modules/xcm-bridge-hub-router/src/weights.rs +++ b/bridges/modules/xcm-bridge-hub-router/src/weights.rs @@ -55,54 +55,42 @@ pub trait WeightInfo { fn report_bridge_status() -> Weight; } -/// Weights for `pallet_xcm_bridge_hub_router` that are generated using one of the Bridge testnets. -/// -/// Those weights are test only and must never be used in production. -pub struct BridgeWeight(PhantomData); -impl WeightInfo for BridgeWeight { - fn on_initialize_when_bridge_state_removed() -> Weight { - RocksDbWeight::get().writes(1) - } - - fn on_initialize_when_bridge_state_updated() -> Weight { - RocksDbWeight::get().writes(1) - } - /// Storage: `XcmBridgeHubRouter::Bridge` (r:1 w:1) - /// - /// Proof: `XcmBridgeHubRouter::Bridge` (`max_values`: Some(1), `max_size`: Some(17), added: - /// 512, mode: `MaxEncodedLen`) - 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)) - } -} - // For backwards compatibility and tests impl WeightInfo for () { + /// Storage: `ToUnknownXcmRouter::Bridges` (r:2 w:1) + /// Proof: `ToUnknownXcmRouter::Bridges` (`max_values`: None, `max_size`: Some(65), added: 2540, mode: `MaxEncodedLen`) fn on_initialize_when_bridge_state_removed() -> Weight { - RocksDbWeight::get().writes(1) + // Proof Size summary in bytes: + // Measured: `204` + // Estimated: `6070` + // Minimum execution time: 19_370_000 picoseconds. + Weight::from_parts(19_928_000, 0) + .saturating_add(Weight::from_parts(0, 6070)) + .saturating_add(RocksDbWeight::get().reads(2)) + .saturating_add(RocksDbWeight::get().writes(1)) } - + /// Storage: `ToUnknownXcmRouter::Bridges` (r:2 w:1) + /// Proof: `ToUnknownXcmRouter::Bridges` (`max_values`: None, `max_size`: Some(65), added: 2540, mode: `MaxEncodedLen`) fn on_initialize_when_bridge_state_updated() -> Weight { - RocksDbWeight::get().writes(1) + // Proof Size summary in bytes: + // Measured: `204` + // Estimated: `6070` + // Minimum execution time: 20_045_000 picoseconds. + Weight::from_parts(20_861_000, 0) + .saturating_add(Weight::from_parts(0, 6070)) + .saturating_add(RocksDbWeight::get().reads(2)) + .saturating_add(RocksDbWeight::get().writes(1)) } - - /// Storage: `XcmBridgeHubRouter::Bridge` (r:1 w:1) - /// - /// Proof: `XcmBridgeHubRouter::Bridge` (`max_values`: Some(1), `max_size`: Some(17), added: - /// 512, mode: `MaxEncodedLen`) + /// Storage: `ToUnknownXcmRouter::Bridges` (r:1 w:1) + /// Proof: `ToUnknownXcmRouter::Bridges` (`max_values`: None, `max_size`: Some(65), added: 2540, mode: `MaxEncodedLen`) 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(RocksDbWeight::get().reads(1_u64)) - .saturating_add(RocksDbWeight::get().writes(1_u64)) + // Measured: `109` + // Estimated: `3530` + // Minimum execution time: 12_179_000 picoseconds. + Weight::from_parts(12_679_000, 0) + .saturating_add(Weight::from_parts(0, 3530)) + .saturating_add(RocksDbWeight::get().reads(1)) + .saturating_add(RocksDbWeight::get().writes(1)) } } diff --git a/bridges/modules/xcm-bridge-hub/Cargo.toml b/bridges/modules/xcm-bridge-hub/Cargo.toml index fe58b910a94e..209c5b6d38fa 100644 --- a/bridges/modules/xcm-bridge-hub/Cargo.toml +++ b/bridges/modules/xcm-bridge-hub/Cargo.toml @@ -22,6 +22,7 @@ bp-xcm-bridge-hub = { workspace = true } pallet-bridge-messages = { workspace = true } # Substrate Dependencies +frame-benchmarking = { optional = true, workspace = true } frame-support = { workspace = true } frame-system = { workspace = true } sp-core = { workspace = true } @@ -49,6 +50,7 @@ std = [ "bp-runtime/std", "bp-xcm-bridge-hub/std", "codec/std", + "frame-benchmarking/std", "frame-support/std", "frame-system/std", "log/std", @@ -66,6 +68,7 @@ std = [ "xcm/std", ] runtime-benchmarks = [ + "frame-benchmarking/runtime-benchmarks", "frame-support/runtime-benchmarks", "frame-system/runtime-benchmarks", "pallet-balances/runtime-benchmarks", diff --git a/bridges/modules/xcm-bridge-hub/src/benchmarking.rs b/bridges/modules/xcm-bridge-hub/src/benchmarking.rs new file mode 100644 index 000000000000..6b21171b8fc8 --- /dev/null +++ b/bridges/modules/xcm-bridge-hub/src/benchmarking.rs @@ -0,0 +1,136 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Parity Bridges Common. + +// Parity Bridges Common 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. + +// Parity Bridges Common 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 Parity Bridges Common. If not, see . + +//! XCM bridge hub pallet benchmarks. + +#![cfg(feature = "runtime-benchmarks")] + +use bp_runtime::BalanceOf; +use crate::{Call, ThisChainOf, Receiver}; +use frame_benchmarking::v2::*; +use sp_std::boxed::Box; +use bp_xcm_bridge_hub::BridgeLocations; +use frame_support::traits::tokens::Precision; +use frame_support::traits::Contains; +use frame_support::traits::Get; +use frame_support::traits::fungible::Unbalanced; +use frame_support::assert_ok; +use xcm_executor::traits::ConvertLocation; + +use sp_runtime::Saturating; +use xcm::prelude::*; + +/// Pallet we're benchmarking here. +pub struct Pallet, I: 'static = ()>(crate::Pallet); + +/// Trait that must be implemented by runtime to be able to benchmark pallet properly. +pub trait Config: crate::Config { + /// Returns a valida origin along with the initial balance (e.g., existential deposit), + /// required for operation `open_bridge`. + /// If `None`, that means that `open_bridge` is not supported. + fn open_bridge_origin() -> Option<(Self::RuntimeOrigin, BalanceOf>)>; +} + +#[instance_benchmarks] +mod benchmarks { + use super::*; + + fn prepare_for_open_bridge, I: 'static>() -> Result<(T::RuntimeOrigin, Box), BenchmarkError> { + let (origin, initial_balance) = T::open_bridge_origin() + .ok_or(BenchmarkError::Override(BenchmarkResult::from_weight(Weight::MAX)))?; + let bridge_destination_universal_location: Box = Box::new([GlobalConsensus(crate::Pallet::::bridged_network_id()?)].into()); + let expected = + crate::Pallet::::bridge_locations_from_origin(origin.clone(), bridge_destination_universal_location)?; + + if !T::AllowWithoutBridgeDeposit::contains(expected.bridge_origin_relative_location()) { + // fund origin's sovereign account + let bridge_owner_account = T::BridgeOriginAccountIdConverter::convert_location( + expected.bridge_origin_relative_location(), + ).ok_or(BenchmarkError::Stop("InvalidBridgeOriginAccount"))?; + + T::Currency::increase_balance( + &bridge_owner_account, + initial_balance.saturating_add(T::BridgeDeposit::get()), + Precision::BestEffort, + )?; + } + + Ok((origin, expected)) + } + + #[benchmark] + fn open_bridge() -> Result<(), BenchmarkError> { + let (origin, locations) = prepare_for_open_bridge::()?; + let bridge_destination_universal_location: Box = Box::new(locations.bridge_destination_universal_location().clone().into()); + assert!(crate::Pallet::::bridge(locations.bridge_id()).is_none()); + + #[extrinsic_call] + _(origin as T::RuntimeOrigin, bridge_destination_universal_location, None); + + assert!(crate::Pallet::::bridge(locations.bridge_id()).is_some()); + Ok(()) + } + + #[benchmark] + fn close_bridge() -> Result<(), BenchmarkError> { + let (origin, locations) = prepare_for_open_bridge::()?; + let bridge_destination_universal_location: Box = Box::new(locations.bridge_destination_universal_location().clone().into()); + assert!(crate::Pallet::::bridge(locations.bridge_id()).is_none()); + + // open bridge + assert_ok!(crate::Pallet::::open_bridge( + origin.clone(), + bridge_destination_universal_location.clone(), + None, + )); + assert!(crate::Pallet::::bridge(locations.bridge_id()).is_some()); + + #[extrinsic_call] + _(origin as T::RuntimeOrigin, bridge_destination_universal_location, 10); + + assert!(crate::Pallet::::bridge(locations.bridge_id()).is_none()); + Ok(()) + } + + #[benchmark] + fn update_notification_receiver() -> Result<(), BenchmarkError> { + let (origin, locations) = prepare_for_open_bridge::()?; + let bridge_destination_universal_location: Box = Box::new(locations.bridge_destination_universal_location().clone().into()); + assert!(crate::Pallet::::bridge(locations.bridge_id()).is_none()); + + // open bridge with None + assert_ok!(crate::Pallet::::open_bridge( + origin.clone(), + bridge_destination_universal_location.clone(), + None, + )); + assert_eq!( + crate::Pallet::::bridge(locations.bridge_id()).map(|b| b.maybe_notify), + Some(None) + ); + + #[extrinsic_call] + _(origin as T::RuntimeOrigin, bridge_destination_universal_location, Some(Receiver::new(1, 5))); + + assert_eq!( + crate::Pallet::::bridge(locations.bridge_id()).map(|b| b.maybe_notify), + Some(Some(Receiver::new(1, 5))) + ); + Ok(()) + } + + impl_benchmark_test_suite!(Pallet, crate::mock::new_test_ext(), crate::mock::TestRuntime); +} diff --git a/bridges/modules/xcm-bridge-hub/src/lib.rs b/bridges/modules/xcm-bridge-hub/src/lib.rs index 2a13b858a8e9..05f86e008f34 100644 --- a/bridges/modules/xcm-bridge-hub/src/lib.rs +++ b/bridges/modules/xcm-bridge-hub/src/lib.rs @@ -163,11 +163,14 @@ pub use dispatcher::XcmBlobMessageDispatchResult; pub use exporter::PalletAsHaulBlobExporter; pub use pallet::*; +pub mod benchmarking; pub mod congestion; mod dispatcher; mod exporter; pub mod migration; mod mock; +pub use weights::WeightInfo; +pub mod weights; /// The target that will be used when publishing logs related to this pallet. pub const LOG_TARGET: &str = "runtime::bridge-xcm"; @@ -197,6 +200,8 @@ pub mod pallet { /// The overarching event type. type RuntimeEvent: From> + IsType<::RuntimeEvent>; + /// Benchmarks results from runtime we're plugged into. + type WeightInfo: WeightInfo; /// Runtime's universal location. type UniversalLocation: Get; @@ -261,6 +266,8 @@ pub mod pallet { /// An alias for the associated lanes manager. pub type LanesManagerOf = pallet_bridge_messages::LanesManager>::BridgeMessagesPalletInstance>; + /// Weight info of the given pallet. + pub type WeightInfoOf = >::WeightInfo; #[pallet::pallet] #[pallet::storage_version(migration::STORAGE_VERSION)] @@ -300,7 +307,7 @@ pub mod pallet { /// notifications can be sent to handle congestion. The notification contains an encoded /// tuple `(BridgeId, bool)`, where `bool` is the `is_congested` flag. #[pallet::call_index(0)] - #[pallet::weight(Weight::zero())] // TODO:(bridges-v2) - https://github.com/paritytech/parity-bridges-common/issues/3046 - add benchmarks impl FAIL-CI + #[pallet::weight(WeightInfoOf::::open_bridge())] pub fn open_bridge( origin: OriginFor, bridge_destination_universal_location: Box, @@ -339,7 +346,7 @@ pub mod pallet { /// The states after this call: everything is either `Closed`, or purged from the /// runtime storage. #[pallet::call_index(1)] - #[pallet::weight(Weight::zero())] // TODO:(bridges-v2) - https://github.com/paritytech/parity-bridges-common/issues/3046 - add benchmarks impl FAIL-CI + #[pallet::weight(WeightInfoOf::::close_bridge())] pub fn close_bridge( origin: OriginFor, bridge_destination_universal_location: Box, @@ -467,7 +474,7 @@ pub mod pallet { /// This can only be called by the "owner" of this side of the bridge, which means that the /// inbound XCM channel with the local origin chain is functional. #[pallet::call_index(2)] - #[pallet::weight(Weight::zero())] // TODO:(bridges-v2) - https://github.com/paritytech/parity-bridges-common/issues/3046 - add benchmarks impl FAIL-CI + #[pallet::weight(WeightInfoOf::::update_notification_receiver())] pub fn update_notification_receiver( origin: OriginFor, bridge_destination_universal_location: Box, @@ -645,7 +652,7 @@ pub mod pallet { impl, I: 'static> Pallet { /// Returns some `NetworkId` if contains `GlobalConsensus` junction. - fn bridged_network_id() -> Result { + pub fn bridged_network_id() -> Result { match T::BridgedNetwork::get().take_first_interior() { Some(GlobalConsensus(network)) => Ok(network), _ => Err(Error::::BridgeLocations( @@ -665,7 +672,7 @@ pub mod pallet { bridge_destination_universal_location: InteriorLocation, create_lanes: bool, maybe_notify: Option, - fund_account: impl Fn(AccountIdOf>, BalanceOf>), + initial_balance: impl Fn() -> BalanceOf>, ) -> Result, sp_runtime::DispatchError> { let locations = Pallet::::bridge_locations( bridge_origin_relative_location.into(), @@ -678,7 +685,14 @@ pub mod pallet { locations.bridge_origin_relative_location(), ) .ok_or(Error::::InvalidBridgeOriginAccount)?; - fund_account(account_id, T::BridgeDeposit::get()); + + use frame_support::traits::fungible::Unbalanced; + use sp_runtime::Saturating; + T::Currency::increase_balance( + &account_id, + initial_balance().saturating_add(T::BridgeDeposit::get()), + Precision::BestEffort, + )?; } Pallet::::do_open_bridge(locations.clone(), lane_id, create_lanes, maybe_notify)?; diff --git a/bridges/modules/xcm-bridge-hub/src/mock.rs b/bridges/modules/xcm-bridge-hub/src/mock.rs index 8573436a3dcd..545fdecf07fe 100644 --- a/bridges/modules/xcm-bridge-hub/src/mock.rs +++ b/bridges/modules/xcm-bridge-hub/src/mock.rs @@ -210,6 +210,7 @@ pub(crate) type TestLocalXcmChannelManager = TestingLocalXcmChannelManager< impl pallet_xcm_bridge_hub::Config for TestRuntime { type RuntimeEvent = RuntimeEvent; + type WeightInfo = (); type UniversalLocation = UniversalLocation; type BridgedNetwork = BridgedRelayNetworkLocation; @@ -236,6 +237,13 @@ impl pallet_xcm_bridge_hub::Config for TestRuntime { type BlobDispatcher = BlobDispatcherWithChannelStatus; } +#[cfg(feature = "runtime-benchmarks")] +impl crate::benchmarking::Config<()> for TestRuntime { + fn open_bridge_origin() -> Option<(RuntimeOrigin, Balance)> { + Some((OpenBridgeOrigin::sibling_parachain_origin(), ExistentialDeposit::get())) + } +} + /// A router instance simulates a scenario where the router is deployed on a different chain than /// the `MessageExporter`. This means that the router sends an `ExportMessage`. pub type XcmOverBridgeWrappedWithExportMessageRouterInstance = (); @@ -707,6 +715,12 @@ impl MessageDispatch for TestMessageDispatch { } } +/// Return test externalities to use in tests. +pub fn new_test_ext() -> sp_io::TestExternalities { + let t = frame_system::GenesisConfig::::default().build_storage().unwrap(); + sp_io::TestExternalities::new(t) +} + /// Run pallet test. pub fn run_test(test: impl FnOnce() -> T) -> T { sp_io::TestExternalities::new( diff --git a/bridges/modules/xcm-bridge-hub/src/weights.rs b/bridges/modules/xcm-bridge-hub/src/weights.rs new file mode 100644 index 000000000000..c0bab87ef727 --- /dev/null +++ b/bridges/modules/xcm-bridge-hub/src/weights.rs @@ -0,0 +1,90 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Parity Bridges Common. + +// Parity Bridges Common 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. + +// Parity Bridges Common 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 Parity Bridges Common. If not, see . + +//! Autogenerated weights for pallet_xcm_bridge_hub +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-08-03, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `covid`, CPU: `11th Gen Intel(R) Core(TM) i7-11800H @ 2.30GHz` +//! EXECUTION: , WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024 + +// Executed Command: +// target/release/rip-bridge-node +// benchmark +// pallet +// --chain=dev +// --steps=50 +// --repeat=20 +// --pallet=pallet_xcm_bridge_hub_router +// --extrinsic=* +// --execution=wasm +// --wasm-execution=Compiled +// --heap-pages=4096 +// --output=./modules/xcm-bridge-hub-router/src/weights.rs +// --template=./.maintain/bridge-weight-template.hbs + +#![allow(clippy::all)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{ + traits::Get, + weights::{constants::RocksDbWeight, Weight}, +}; +use sp_std::marker::PhantomData; + +/// Weight functions needed for pallet_xcm_bridge_hub_router. +pub trait WeightInfo { + fn open_bridge() -> Weight; + fn close_bridge() -> Weight; + fn update_notification_receiver() -> Weight; +} + +// For backwards compatibility and tests +impl WeightInfo for () { + fn open_bridge() -> Weight { + // Proof Size summary in bytes: + // Measured: `204` + // Estimated: `6070` + // Minimum execution time: 19_370_000 picoseconds. + Weight::from_parts(19_928_000, 0) + .saturating_add(Weight::from_parts(0, 6070)) + .saturating_add(RocksDbWeight::get().reads(2)) + .saturating_add(RocksDbWeight::get().writes(1)) + } + fn close_bridge() -> Weight { + // Proof Size summary in bytes: + // Measured: `204` + // Estimated: `6070` + // Minimum execution time: 20_045_000 picoseconds. + Weight::from_parts(20_861_000, 0) + .saturating_add(Weight::from_parts(0, 6070)) + .saturating_add(RocksDbWeight::get().reads(2)) + .saturating_add(RocksDbWeight::get().writes(1)) + } + fn update_notification_receiver() -> Weight { + // Proof Size summary in bytes: + // Measured: `109` + // Estimated: `3530` + // Minimum execution time: 12_179_000 picoseconds. + Weight::from_parts(12_679_000, 0) + .saturating_add(Weight::from_parts(0, 3530)) + .saturating_add(RocksDbWeight::get().reads(1)) + .saturating_add(RocksDbWeight::get().writes(1)) + } +} diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_bulletin_config.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_bulletin_config.rs index 6bc0100c5310..1bb89209e58e 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_bulletin_config.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_bulletin_config.rs @@ -126,6 +126,7 @@ impl pallet_bridge_messages::Config for Runt pub type XcmOverPolkadotBulletinInstance = pallet_xcm_bridge_hub::Instance2; impl pallet_xcm_bridge_hub::Config for Runtime { type RuntimeEvent = RuntimeEvent; + type WeightInfo = (); type UniversalLocation = UniversalLocation; type BridgedNetwork = RococoBulletinGlobalConsensusNetworkLocation; diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_westend_config.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_westend_config.rs index 8c9a127bd1bc..3f403134491c 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_westend_config.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_westend_config.rs @@ -146,6 +146,7 @@ impl Convert, Xcm<()>> for ReportBridgeStatusXcmProvider { pub type XcmOverBridgeHubWestendInstance = pallet_xcm_bridge_hub::Instance1; impl pallet_xcm_bridge_hub::Config for Runtime { type RuntimeEvent = RuntimeEvent; + type WeightInfo = (); type UniversalLocation = UniversalLocation; type BridgedNetwork = WestendGlobalConsensusNetworkLocation; diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs index eeaac7757dfb..4dc38e553d0e 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs @@ -683,6 +683,8 @@ mod benches { [pallet_bridge_messages, RococoToRococoBulletin] [pallet_bridge_relayers, Legacy] [pallet_bridge_relayers, PermissionlessLanes] + [pallet_xcm_bridge_hub, OverWestend] + [pallet_xcm_bridge_hub, OverBulletin] // Ethereum Bridge [snowbridge_pallet_inbound_queue, EthereumInboundQueue] [snowbridge_pallet_outbound_queue, EthereumOutboundQueue] @@ -1063,10 +1065,12 @@ impl_runtime_apis! { // Change weight file names. type WestendFinality = BridgeWestendGrandpa; type WithinWestend = pallet_bridge_parachains::benchmarking::Pallet::; - type RococoToWestend = pallet_bridge_messages::benchmarking::Pallet ::; - type RococoToRococoBulletin = pallet_bridge_messages::benchmarking::Pallet ::; + type RococoToWestend = pallet_bridge_messages::benchmarking::Pallet::; + type RococoToRococoBulletin = pallet_bridge_messages::benchmarking::Pallet::; type Legacy = BridgeRelayersBench::; type PermissionlessLanes = BridgeRelayersBench::; + type OverWestend = pallet_xcm_bridge_hub::benchmarking::Pallet::; + type OverBulletin = pallet_xcm_bridge_hub::benchmarking::Pallet::; let mut list = Vec::::new(); list_benchmarks!(list, extra); @@ -1271,17 +1275,7 @@ impl_runtime_apis! { bridge_destination_universal_location.clone(), true, None, - |account_id, bridge_deposit| { - use frame_support::traits::fungible::Mutate; - frame_support::assert_ok!( - Balances::mint_into( - &account_id, - bridge_deposit - .saturating_add(ExistentialDeposit::get()) - .saturating_add(UNITS * 5) - ) - ); - }, + || ExistentialDeposit::get(), ).map_err(|e| { log::error!( "Failed to `XcmOverBridgeHubWestend::open_bridge`({:?}, {:?})`, error: {:?}", @@ -1315,6 +1309,8 @@ impl_runtime_apis! { type RococoToRococoBulletin = pallet_bridge_messages::benchmarking::Pallet ::; type Legacy = BridgeRelayersBench::; type PermissionlessLanes = BridgeRelayersBench::; + type OverWestend = pallet_xcm_bridge_hub::benchmarking::Pallet::; + type OverBulletin = pallet_xcm_bridge_hub::benchmarking::Pallet::; use bridge_runtime_common::messages_benchmarking::{ prepare_message_delivery_proof_from_grandpa_chain, @@ -1329,6 +1325,18 @@ impl_runtime_apis! { MessageProofParams, }; + impl pallet_xcm_bridge_hub::benchmarking::Config for Runtime { + fn open_bridge_origin() -> Option<(RuntimeOrigin, Balance)> { + None + } + } + + impl pallet_xcm_bridge_hub::benchmarking::Config for Runtime { + fn open_bridge_origin() -> Option<(RuntimeOrigin, Balance)> { + None + } + } + impl BridgeMessagesConfig for Runtime { fn is_relayer_rewarded(relayer: &Self::AccountId) -> bool { let bench_lane_id = >::bench_lane_id(); @@ -1357,17 +1365,7 @@ impl_runtime_apis! { // do not create lanes, because they are already created `params.lane` false, None, - |account_id, bridge_deposit| { - use frame_support::traits::fungible::Mutate; - frame_support::assert_ok!( - Balances::mint_into( - &account_id, - bridge_deposit - .saturating_add(ExistentialDeposit::get()) - .saturating_add(UNITS * 5) - ) - ); - }, + || ExistentialDeposit::get(), ).expect("valid bridge opened"); prepare_message_proof_from_parachain::< Runtime, @@ -1386,17 +1384,7 @@ impl_runtime_apis! { // do not create lanes, because they are already created `params.lane` false, None, - |account_id, bridge_deposit| { - use frame_support::traits::fungible::Mutate; - frame_support::assert_ok!( - Balances::mint_into( - &account_id, - bridge_deposit - .saturating_add(ExistentialDeposit::get()) - .saturating_add(UNITS * 5) - ) - ); - }, + || ExistentialDeposit::get(), ); prepare_message_delivery_proof_from_parachain::< Runtime, @@ -1430,17 +1418,7 @@ impl_runtime_apis! { // do not create lanes, because they are already created `params.lane` false, None, - |account_id, bridge_deposit| { - use frame_support::traits::fungible::Mutate; - frame_support::assert_ok!( - Balances::mint_into( - &account_id, - bridge_deposit - .saturating_add(ExistentialDeposit::get()) - .saturating_add(UNITS * 5) - ) - ); - }, + || ExistentialDeposit::get(), ).expect("valid bridge opened"); prepare_message_proof_from_grandpa_chain::< Runtime, @@ -1459,17 +1437,7 @@ impl_runtime_apis! { // do not create lanes, because they are already created `params.lane` false, None, - |account_id, bridge_deposit| { - use frame_support::traits::fungible::Mutate; - frame_support::assert_ok!( - Balances::mint_into( - &account_id, - bridge_deposit - .saturating_add(ExistentialDeposit::get()) - .saturating_add(UNITS * 5) - ) - ); - }, + || ExistentialDeposit::get(), ).expect("valid bridge opened"); prepare_message_delivery_proof_from_grandpa_chain::< Runtime, diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/bridge_to_rococo_config.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/bridge_to_rococo_config.rs index 0e8402aefc59..c77f8d2bfb6e 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/bridge_to_rococo_config.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/bridge_to_rococo_config.rs @@ -176,6 +176,7 @@ impl Convert, Xcm<()>> for ReportBridgeStatusXcmProvider { pub type XcmOverBridgeHubRococoInstance = pallet_xcm_bridge_hub::Instance1; impl pallet_xcm_bridge_hub::Config for Runtime { type RuntimeEvent = RuntimeEvent; + type WeightInfo = (); type UniversalLocation = UniversalLocation; type BridgedNetwork = RococoGlobalConsensusNetworkLocation; diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs index 48d6bc5d99f5..1998058938a9 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs @@ -620,6 +620,7 @@ mod benches { [pallet_bridge_grandpa, RococoFinality] [pallet_bridge_parachains, WithinRococo] [pallet_bridge_messages, WestendToRococo] + [pallet_xcm_bridge_hub, OverRococo] // Ethereum Bridge [snowbridge_pallet_inbound_queue, EthereumInboundQueue] [snowbridge_pallet_outbound_queue, EthereumOutboundQueue] @@ -952,6 +953,7 @@ impl_runtime_apis! { type RococoFinality = BridgeRococoGrandpa; type WithinRococo = pallet_bridge_parachains::benchmarking::Pallet::; type WestendToRococo = pallet_bridge_messages::benchmarking::Pallet ::; + type OverRococo = pallet_xcm_bridge_hub::benchmarking::Pallet::; let mut list = Vec::::new(); list_benchmarks!(list, extra); @@ -1156,17 +1158,7 @@ impl_runtime_apis! { bridge_destination_universal_location.clone(), true, None, - |account_id, bridge_deposit| { - use frame_support::traits::fungible::Mutate; - frame_support::assert_ok!( - Balances::mint_into( - &account_id, - bridge_deposit - .saturating_add(ExistentialDeposit::get()) - .saturating_add(UNITS * 5) - ) - ); - }, + || ExistentialDeposit::get(), ).map_err(|e| { log::error!( "Failed to `XcmOverBridgeHubRococo::open_bridge`({:?}, {:?})`, error: {:?}", @@ -1197,6 +1189,7 @@ impl_runtime_apis! { type RococoFinality = BridgeRococoGrandpa; type WithinRococo = pallet_bridge_parachains::benchmarking::Pallet::; type WestendToRococo = pallet_bridge_messages::benchmarking::Pallet ::; + type OverRococo = pallet_xcm_bridge_hub::benchmarking::Pallet::; use bridge_runtime_common::messages_benchmarking::{ prepare_message_delivery_proof_from_parachain, @@ -1209,6 +1202,12 @@ impl_runtime_apis! { MessageProofParams, }; + impl pallet_xcm_bridge_hub::benchmarking::Config for Runtime { + fn open_bridge_origin() -> Option<(RuntimeOrigin, Balance)> { + None + } + } + impl BridgeMessagesConfig for Runtime { fn is_relayer_rewarded(relayer: &Self::AccountId) -> bool { let bench_lane_id = >::bench_lane_id(); @@ -1237,17 +1236,7 @@ impl_runtime_apis! { // do not create lanes, because they are already created `params.lane` false, None, - |account_id, bridge_deposit| { - use frame_support::traits::fungible::Mutate; - frame_support::assert_ok!( - Balances::mint_into( - &account_id, - bridge_deposit - .saturating_add(ExistentialDeposit::get()) - .saturating_add(UNITS * 5) - ) - ); - }, + || ExistentialDeposit::get(), ).expect("valid bridge opened"); prepare_message_proof_from_parachain::< Runtime, @@ -1266,17 +1255,7 @@ impl_runtime_apis! { // do not create lanes, because they are already created `params.lane` false, None, - |account_id, bridge_deposit| { - use frame_support::traits::fungible::Mutate; - frame_support::assert_ok!( - Balances::mint_into( - &account_id, - bridge_deposit - .saturating_add(ExistentialDeposit::get()) - .saturating_add(UNITS * 5) - ) - ); - }, + || ExistentialDeposit::get(), ); prepare_message_delivery_proof_from_parachain::< Runtime, From 7adcefd538d00a7392f15d549e96a03cd110fc48 Mon Sep 17 00:00:00 2001 From: GitHub Action Date: Fri, 8 Nov 2024 23:54:18 +0000 Subject: [PATCH 41/72] Update from bkontur running command 'fmt' --- .../xcm-bridge-hub-router/src/weights.rs | 9 ++-- .../xcm-bridge-hub/src/benchmarking.rs | 43 ++++++++++++------- 2 files changed, 33 insertions(+), 19 deletions(-) diff --git a/bridges/modules/xcm-bridge-hub-router/src/weights.rs b/bridges/modules/xcm-bridge-hub-router/src/weights.rs index 046cd2bc45df..788b4e48c7aa 100644 --- a/bridges/modules/xcm-bridge-hub-router/src/weights.rs +++ b/bridges/modules/xcm-bridge-hub-router/src/weights.rs @@ -58,7 +58,8 @@ pub trait WeightInfo { // For backwards compatibility and tests impl WeightInfo for () { /// Storage: `ToUnknownXcmRouter::Bridges` (r:2 w:1) - /// Proof: `ToUnknownXcmRouter::Bridges` (`max_values`: None, `max_size`: Some(65), added: 2540, mode: `MaxEncodedLen`) + /// Proof: `ToUnknownXcmRouter::Bridges` (`max_values`: None, `max_size`: Some(65), added: 2540, + /// mode: `MaxEncodedLen`) fn on_initialize_when_bridge_state_removed() -> Weight { // Proof Size summary in bytes: // Measured: `204` @@ -70,7 +71,8 @@ impl WeightInfo for () { .saturating_add(RocksDbWeight::get().writes(1)) } /// Storage: `ToUnknownXcmRouter::Bridges` (r:2 w:1) - /// Proof: `ToUnknownXcmRouter::Bridges` (`max_values`: None, `max_size`: Some(65), added: 2540, mode: `MaxEncodedLen`) + /// Proof: `ToUnknownXcmRouter::Bridges` (`max_values`: None, `max_size`: Some(65), added: 2540, + /// mode: `MaxEncodedLen`) fn on_initialize_when_bridge_state_updated() -> Weight { // Proof Size summary in bytes: // Measured: `204` @@ -82,7 +84,8 @@ impl WeightInfo for () { .saturating_add(RocksDbWeight::get().writes(1)) } /// Storage: `ToUnknownXcmRouter::Bridges` (r:1 w:1) - /// Proof: `ToUnknownXcmRouter::Bridges` (`max_values`: None, `max_size`: Some(65), added: 2540, mode: `MaxEncodedLen`) + /// Proof: `ToUnknownXcmRouter::Bridges` (`max_values`: None, `max_size`: Some(65), added: 2540, + /// mode: `MaxEncodedLen`) fn report_bridge_status() -> Weight { // Proof Size summary in bytes: // Measured: `109` diff --git a/bridges/modules/xcm-bridge-hub/src/benchmarking.rs b/bridges/modules/xcm-bridge-hub/src/benchmarking.rs index 6b21171b8fc8..31846867b999 100644 --- a/bridges/modules/xcm-bridge-hub/src/benchmarking.rs +++ b/bridges/modules/xcm-bridge-hub/src/benchmarking.rs @@ -18,16 +18,15 @@ #![cfg(feature = "runtime-benchmarks")] +use crate::{Call, Receiver, ThisChainOf}; use bp_runtime::BalanceOf; -use crate::{Call, ThisChainOf, Receiver}; +use bp_xcm_bridge_hub::BridgeLocations; use frame_benchmarking::v2::*; +use frame_support::{ + assert_ok, + traits::{fungible::Unbalanced, tokens::Precision, Contains, Get}, +}; use sp_std::boxed::Box; -use bp_xcm_bridge_hub::BridgeLocations; -use frame_support::traits::tokens::Precision; -use frame_support::traits::Contains; -use frame_support::traits::Get; -use frame_support::traits::fungible::Unbalanced; -use frame_support::assert_ok; use xcm_executor::traits::ConvertLocation; use sp_runtime::Saturating; @@ -48,18 +47,23 @@ pub trait Config: crate::Config { mod benchmarks { use super::*; - fn prepare_for_open_bridge, I: 'static>() -> Result<(T::RuntimeOrigin, Box), BenchmarkError> { + fn prepare_for_open_bridge, I: 'static>( + ) -> Result<(T::RuntimeOrigin, Box), BenchmarkError> { let (origin, initial_balance) = T::open_bridge_origin() .ok_or(BenchmarkError::Override(BenchmarkResult::from_weight(Weight::MAX)))?; - let bridge_destination_universal_location: Box = Box::new([GlobalConsensus(crate::Pallet::::bridged_network_id()?)].into()); - let expected = - crate::Pallet::::bridge_locations_from_origin(origin.clone(), bridge_destination_universal_location)?; + let bridge_destination_universal_location: Box = + Box::new([GlobalConsensus(crate::Pallet::::bridged_network_id()?)].into()); + let expected = crate::Pallet::::bridge_locations_from_origin( + origin.clone(), + bridge_destination_universal_location, + )?; if !T::AllowWithoutBridgeDeposit::contains(expected.bridge_origin_relative_location()) { // fund origin's sovereign account let bridge_owner_account = T::BridgeOriginAccountIdConverter::convert_location( expected.bridge_origin_relative_location(), - ).ok_or(BenchmarkError::Stop("InvalidBridgeOriginAccount"))?; + ) + .ok_or(BenchmarkError::Stop("InvalidBridgeOriginAccount"))?; T::Currency::increase_balance( &bridge_owner_account, @@ -74,7 +78,8 @@ mod benchmarks { #[benchmark] fn open_bridge() -> Result<(), BenchmarkError> { let (origin, locations) = prepare_for_open_bridge::()?; - let bridge_destination_universal_location: Box = Box::new(locations.bridge_destination_universal_location().clone().into()); + let bridge_destination_universal_location: Box = + Box::new(locations.bridge_destination_universal_location().clone().into()); assert!(crate::Pallet::::bridge(locations.bridge_id()).is_none()); #[extrinsic_call] @@ -87,7 +92,8 @@ mod benchmarks { #[benchmark] fn close_bridge() -> Result<(), BenchmarkError> { let (origin, locations) = prepare_for_open_bridge::()?; - let bridge_destination_universal_location: Box = Box::new(locations.bridge_destination_universal_location().clone().into()); + let bridge_destination_universal_location: Box = + Box::new(locations.bridge_destination_universal_location().clone().into()); assert!(crate::Pallet::::bridge(locations.bridge_id()).is_none()); // open bridge @@ -108,7 +114,8 @@ mod benchmarks { #[benchmark] fn update_notification_receiver() -> Result<(), BenchmarkError> { let (origin, locations) = prepare_for_open_bridge::()?; - let bridge_destination_universal_location: Box = Box::new(locations.bridge_destination_universal_location().clone().into()); + let bridge_destination_universal_location: Box = + Box::new(locations.bridge_destination_universal_location().clone().into()); assert!(crate::Pallet::::bridge(locations.bridge_id()).is_none()); // open bridge with None @@ -123,7 +130,11 @@ mod benchmarks { ); #[extrinsic_call] - _(origin as T::RuntimeOrigin, bridge_destination_universal_location, Some(Receiver::new(1, 5))); + _( + origin as T::RuntimeOrigin, + bridge_destination_universal_location, + Some(Receiver::new(1, 5)), + ); assert_eq!( crate::Pallet::::bridge(locations.bridge_id()).map(|b| b.maybe_notify), From 26bb7a9fb7ece38aa0ec8a503106f691ece98a3a Mon Sep 17 00:00:00 2001 From: command-bot <> Date: Sat, 9 Nov 2024 01:05:28 +0000 Subject: [PATCH 42/72] ".git/.scripts/commands/bench/bench.sh" --subcommand=pallet --runtime=bridge-hub-westend --runtime_dir=bridge-hubs --target_dir=cumulus --pallet=pallet_xcm_bridge_hub --- .../src/weights/pallet_xcm_bridge_hub.rs | 81 +++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/pallet_xcm_bridge_hub.rs diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/pallet_xcm_bridge_hub.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/pallet_xcm_bridge_hub.rs new file mode 100644 index 000000000000..dec909a57015 --- /dev/null +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/pallet_xcm_bridge_hub.rs @@ -0,0 +1,81 @@ +// 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_bridge_hub` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-11-09, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner-wiukf8gn-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("bridge-hub-westend-dev")`, DB CACHE: 1024 + +// Executed Command: +// target/production/polkadot-parachain +// benchmark +// pallet +// --steps=50 +// --repeat=20 +// --extrinsic=* +// --wasm-execution=compiled +// --heap-pages=4096 +// --json-file=/builds/parity/mirrors/polkadot-sdk/.git/.artifacts/bench.json +// --pallet=pallet_xcm_bridge_hub +// --chain=bridge-hub-westend-dev +// --header=./cumulus/file_header.txt +// --output=./cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/ + +#![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`. +pub struct WeightInfo(PhantomData); +impl pallet_xcm_bridge_hub::WeightInfo for WeightInfo { + /// Storage: `Benchmark::Override` (r:0 w:0) + /// Proof: `Benchmark::Override` (`max_values`: None, `max_size`: None, mode: `Measured`) + fn open_bridge() -> 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)) + } + /// Storage: `Benchmark::Override` (r:0 w:0) + /// Proof: `Benchmark::Override` (`max_values`: None, `max_size`: None, mode: `Measured`) + fn close_bridge() -> 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)) + } + /// Storage: `Benchmark::Override` (r:0 w:0) + /// Proof: `Benchmark::Override` (`max_values`: None, `max_size`: None, mode: `Measured`) + fn update_notification_receiver() -> 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)) + } +} From 4602edb3c80fc3690fa06d00509c00c9b35e06bb Mon Sep 17 00:00:00 2001 From: command-bot <> Date: Sat, 9 Nov 2024 01:05:57 +0000 Subject: [PATCH 43/72] ".git/.scripts/commands/bench/bench.sh" --subcommand=pallet --runtime=asset-hub-rococo --runtime_dir=assets --target_dir=cumulus --pallet=pallet_xcm_bridge_hub_router --- .../src/weights/pallet_xcm_bridge_hub_router.rs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/pallet_xcm_bridge_hub_router.rs b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/pallet_xcm_bridge_hub_router.rs index 712b22847d33..3ef17f80b9ea 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/pallet_xcm_bridge_hub_router.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/pallet_xcm_bridge_hub_router.rs @@ -17,9 +17,9 @@ //! Autogenerated weights for `pallet_xcm_bridge_hub_router` //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-11-07, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2024-11-09, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-vcatxqpx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! HOSTNAME: `runner-wiukf8gn-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("asset-hub-rococo-dev")`, DB CACHE: 1024 // Executed Command: @@ -54,8 +54,8 @@ impl pallet_xcm_bridge_hub_router::WeightInfo for Weigh // Proof Size summary in bytes: // Measured: `204` // Estimated: `6070` - // Minimum execution time: 19_370_000 picoseconds. - Weight::from_parts(19_928_000, 0) + // Minimum execution time: 19_038_000 picoseconds. + Weight::from_parts(19_659_000, 0) .saturating_add(Weight::from_parts(0, 6070)) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(1)) @@ -66,8 +66,8 @@ impl pallet_xcm_bridge_hub_router::WeightInfo for Weigh // Proof Size summary in bytes: // Measured: `204` // Estimated: `6070` - // Minimum execution time: 20_045_000 picoseconds. - Weight::from_parts(20_861_000, 0) + // Minimum execution time: 20_051_000 picoseconds. + Weight::from_parts(20_698_000, 0) .saturating_add(Weight::from_parts(0, 6070)) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(1)) @@ -78,8 +78,8 @@ impl pallet_xcm_bridge_hub_router::WeightInfo for Weigh // Proof Size summary in bytes: // Measured: `109` // Estimated: `3530` - // Minimum execution time: 12_179_000 picoseconds. - Weight::from_parts(12_679_000, 0) + // Minimum execution time: 12_193_000 picoseconds. + Weight::from_parts(12_658_000, 0) .saturating_add(Weight::from_parts(0, 3530)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) From be876b2c252d0f51ffe109ad4a3f276dbfecc031 Mon Sep 17 00:00:00 2001 From: command-bot <> Date: Sat, 9 Nov 2024 01:06:51 +0000 Subject: [PATCH 44/72] ".git/.scripts/commands/bench/bench.sh" --subcommand=xcm --runtime=bridge-hub-westend --runtime_dir=bridge-hubs --target_dir=cumulus --pallet=pallet_xcm_benchmarks::generic --- .../xcm/pallet_xcm_benchmarks_generic.rs | 132 +++++++++--------- 1 file changed, 66 insertions(+), 66 deletions(-) diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/xcm/pallet_xcm_benchmarks_generic.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/xcm/pallet_xcm_benchmarks_generic.rs index 8c28e52e6085..26df9ea4388d 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/xcm/pallet_xcm_benchmarks_generic.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/xcm/pallet_xcm_benchmarks_generic.rs @@ -17,9 +17,9 @@ //! Autogenerated weights for `pallet_xcm_benchmarks::generic` //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-11-07, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2024-11-09, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-vcatxqpx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! HOSTNAME: `runner-wiukf8gn-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: Compiled, CHAIN: Some("bridge-hub-westend-dev"), DB CACHE: 1024 // Executed Command: @@ -68,8 +68,8 @@ impl WeightInfo { // Proof Size summary in bytes: // Measured: `208` // Estimated: `6196` - // Minimum execution time: 72_301_000 picoseconds. - Weight::from_parts(73_889_000, 6196) + // Minimum execution time: 73_953_000 picoseconds. + Weight::from_parts(77_340_000, 6196) .saturating_add(T::DbWeight::get().reads(9)) .saturating_add(T::DbWeight::get().writes(4)) } @@ -77,8 +77,8 @@ impl WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 929_000 picoseconds. - Weight::from_parts(983_000, 0) + // Minimum execution time: 1_087_000 picoseconds. + Weight::from_parts(1_144_000, 0) } // Storage: `System::Account` (r:1 w:1) // Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) @@ -86,8 +86,8 @@ impl WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `3593` - // Minimum execution time: 3_717_000 picoseconds. - Weight::from_parts(3_864_000, 3593) + // Minimum execution time: 3_908_000 picoseconds. + Weight::from_parts(4_071_000, 3593) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } @@ -95,8 +95,8 @@ impl WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 899_000 picoseconds. - Weight::from_parts(962_000, 0) + // Minimum execution time: 1_066_000 picoseconds. + Weight::from_parts(1_121_000, 0) } // Storage: `PolkadotXcm::Queries` (r:1 w:0) // Proof: `PolkadotXcm::Queries` (`max_values`: None, `max_size`: None, mode: `Measured`) @@ -104,58 +104,58 @@ impl WeightInfo { // Proof Size summary in bytes: // Measured: `32` // Estimated: `3497` - // Minimum execution time: 8_009_000 picoseconds. - Weight::from_parts(8_159_000, 3497) + // Minimum execution time: 8_100_000 picoseconds. + Weight::from_parts(8_237_000, 3497) .saturating_add(T::DbWeight::get().reads(1)) } pub fn transact() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 7_580_000 picoseconds. - Weight::from_parts(7_777_000, 0) + // Minimum execution time: 7_861_000 picoseconds. + Weight::from_parts(8_196_000, 0) } pub fn refund_surplus() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_581_000 picoseconds. - Weight::from_parts(1_712_000, 0) + // Minimum execution time: 1_757_000 picoseconds. + Weight::from_parts(1_841_000, 0) } pub fn set_error_handler() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 946_000 picoseconds. - Weight::from_parts(1_015_000, 0) + // Minimum execution time: 1_057_000 picoseconds. + Weight::from_parts(1_123_000, 0) } pub fn set_appendix() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 969_000 picoseconds. - Weight::from_parts(1_037_000, 0) + // Minimum execution time: 1_065_000 picoseconds. + Weight::from_parts(1_119_000, 0) } pub fn clear_error() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 916_000 picoseconds. - Weight::from_parts(973_000, 0) + // Minimum execution time: 1_030_000 picoseconds. + Weight::from_parts(1_102_000, 0) } pub fn descend_origin() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 941_000 picoseconds. - Weight::from_parts(982_000, 0) + // Minimum execution time: 1_052_000 picoseconds. + Weight::from_parts(1_138_000, 0) } pub fn clear_origin() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 937_000 picoseconds. - Weight::from_parts(991_000, 0) + // Minimum execution time: 1_056_000 picoseconds. + Weight::from_parts(1_169_000, 0) } // Storage: `ParachainInfo::ParachainId` (r:1 w:0) // Proof: `ParachainInfo::ParachainId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) @@ -177,8 +177,8 @@ impl WeightInfo { // Proof Size summary in bytes: // Measured: `208` // Estimated: `6196` - // Minimum execution time: 69_202_000 picoseconds. - Weight::from_parts(71_054_000, 6196) + // Minimum execution time: 69_990_000 picoseconds. + Weight::from_parts(72_086_000, 6196) .saturating_add(T::DbWeight::get().reads(9)) .saturating_add(T::DbWeight::get().writes(4)) } @@ -188,8 +188,8 @@ impl WeightInfo { // Proof Size summary in bytes: // Measured: `90` // Estimated: `3555` - // Minimum execution time: 11_209_000 picoseconds. - Weight::from_parts(11_588_000, 3555) + // Minimum execution time: 11_270_000 picoseconds. + Weight::from_parts(11_624_000, 3555) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } @@ -197,8 +197,8 @@ impl WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 918_000 picoseconds. - Weight::from_parts(973_000, 0) + // Minimum execution time: 1_025_000 picoseconds. + Weight::from_parts(1_112_000, 0) } // Storage: `PolkadotXcm::VersionNotifyTargets` (r:1 w:1) // Proof: `PolkadotXcm::VersionNotifyTargets` (`max_values`: None, `max_size`: None, mode: `Measured`) @@ -218,8 +218,8 @@ impl WeightInfo { // Proof Size summary in bytes: // Measured: `38` // Estimated: `3503` - // Minimum execution time: 25_653_000 picoseconds. - Weight::from_parts(26_505_000, 3503) + // Minimum execution time: 25_768_000 picoseconds. + Weight::from_parts(26_467_000, 3503) .saturating_add(T::DbWeight::get().reads(7)) .saturating_add(T::DbWeight::get().writes(3)) } @@ -229,44 +229,44 @@ impl WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_929_000 picoseconds. - Weight::from_parts(3_071_000, 0) + // Minimum execution time: 3_020_000 picoseconds. + Weight::from_parts(3_199_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: 1_337_000 picoseconds. - Weight::from_parts(1_422_000, 0) + // Minimum execution time: 1_533_000 picoseconds. + Weight::from_parts(1_598_000, 0) } pub fn expect_asset() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_024_000 picoseconds. - Weight::from_parts(1_076_000, 0) + // Minimum execution time: 1_109_000 picoseconds. + Weight::from_parts(1_181_000, 0) } pub fn expect_origin() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 949_000 picoseconds. - Weight::from_parts(999_000, 0) + // Minimum execution time: 1_062_000 picoseconds. + Weight::from_parts(1_121_000, 0) } pub fn expect_error() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 940_000 picoseconds. - Weight::from_parts(975_000, 0) + // Minimum execution time: 1_094_000 picoseconds. + Weight::from_parts(1_120_000, 0) } pub fn expect_transact_status() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_063_000 picoseconds. - Weight::from_parts(1_166_000, 0) + // Minimum execution time: 1_254_000 picoseconds. + Weight::from_parts(1_327_000, 0) } // Storage: `ParachainInfo::ParachainId` (r:1 w:0) // Proof: `ParachainInfo::ParachainId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) @@ -288,8 +288,8 @@ impl WeightInfo { // Proof Size summary in bytes: // Measured: `208` // Estimated: `6196` - // Minimum execution time: 75_010_000 picoseconds. - Weight::from_parts(76_402_000, 6196) + // Minimum execution time: 75_152_000 picoseconds. + Weight::from_parts(77_164_000, 6196) .saturating_add(T::DbWeight::get().reads(9)) .saturating_add(T::DbWeight::get().writes(4)) } @@ -297,8 +297,8 @@ impl WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 4_316_000 picoseconds. - Weight::from_parts(4_458_000, 0) + // Minimum execution time: 4_454_000 picoseconds. + Weight::from_parts(4_613_000, 0) } // Storage: `ParachainInfo::ParachainId` (r:1 w:0) // Proof: `ParachainInfo::ParachainId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) @@ -320,8 +320,8 @@ impl WeightInfo { // Proof Size summary in bytes: // Measured: `208` // Estimated: `6196` - // Minimum execution time: 69_876_000 picoseconds. - Weight::from_parts(71_417_000, 6196) + // Minimum execution time: 70_387_000 picoseconds. + Weight::from_parts(71_863_000, 6196) .saturating_add(T::DbWeight::get().reads(9)) .saturating_add(T::DbWeight::get().writes(4)) } @@ -329,22 +329,22 @@ impl WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 990_000 picoseconds. - Weight::from_parts(1_045_000, 0) + // Minimum execution time: 1_108_000 picoseconds. + Weight::from_parts(1_150_000, 0) } pub fn set_topic() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 934_000 picoseconds. - Weight::from_parts(969_000, 0) + // Minimum execution time: 1_051_000 picoseconds. + Weight::from_parts(1_108_000, 0) } pub fn clear_topic() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 953_000 picoseconds. - Weight::from_parts(996_000, 0) + // Minimum execution time: 1_041_000 picoseconds. + Weight::from_parts(1_110_000, 0) } // Storage: `ParachainInfo::ParachainId` (r:1 w:0) // Proof: `ParachainInfo::ParachainId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) @@ -363,10 +363,10 @@ impl WeightInfo { // Proof Size summary in bytes: // Measured: `595` // Estimated: `6535` - // Minimum execution time: 57_024_000 picoseconds. - Weight::from_parts(59_135_181, 6535) - // Standard Error: 163 - .saturating_add(Weight::from_parts(50_638, 0).saturating_mul(x.into())) + // Minimum execution time: 56_987_000 picoseconds. + Weight::from_parts(58_914_389, 6535) + // Standard Error: 154 + .saturating_add(Weight::from_parts(52_548, 0).saturating_mul(x.into())) .saturating_add(T::DbWeight::get().reads(6)) .saturating_add(T::DbWeight::get().writes(2)) } @@ -374,14 +374,14 @@ impl WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 896_000 picoseconds. - Weight::from_parts(942_000, 0) + // Minimum execution time: 1_019_000 picoseconds. + Weight::from_parts(1_090_000, 0) } pub fn unpaid_execution() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 941_000 picoseconds. - Weight::from_parts(987_000, 0) + // Minimum execution time: 1_053_000 picoseconds. + Weight::from_parts(1_112_000, 0) } } From 178b76ee52cb303b4155d2b8571fbe76fb13fa36 Mon Sep 17 00:00:00 2001 From: command-bot <> Date: Sat, 9 Nov 2024 01:07:35 +0000 Subject: [PATCH 45/72] ".git/.scripts/commands/bench/bench.sh" --subcommand=pallet --runtime=bridge-hub-westend --runtime_dir=bridge-hubs --target_dir=cumulus --pallet=pallet_bridge_messages --- .../src/weights/pallet_bridge_messages.rs | 48 +++++++++---------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/pallet_bridge_messages.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/pallet_bridge_messages.rs index d3d5bccc378c..b16f00706657 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/pallet_bridge_messages.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/pallet_bridge_messages.rs @@ -17,9 +17,9 @@ //! Autogenerated weights for `pallet_bridge_messages` //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-11-07, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2024-11-09, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-vcatxqpx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! HOSTNAME: `runner-wiukf8gn-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("bridge-hub-westend-dev")`, DB CACHE: 1024 // Executed Command: @@ -66,8 +66,8 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< // Proof Size summary in bytes: // Measured: `765` // Estimated: `52645` - // Minimum execution time: 62_661_000 picoseconds. - Weight::from_parts(67_185_000, 0) + // Minimum execution time: 61_826_000 picoseconds. + Weight::from_parts(65_518_000, 0) .saturating_add(Weight::from_parts(0, 52645)) .saturating_add(T::DbWeight::get().reads(7)) .saturating_add(T::DbWeight::get().writes(1)) @@ -91,11 +91,11 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< // Proof Size summary in bytes: // Measured: `765` // Estimated: `52645` - // Minimum execution time: 62_217_000 picoseconds. - Weight::from_parts(63_923_000, 0) + // Minimum execution time: 62_597_000 picoseconds. + Weight::from_parts(64_453_000, 0) .saturating_add(Weight::from_parts(0, 52645)) - // Standard Error: 9_541 - .saturating_add(Weight::from_parts(12_052_260, 0).saturating_mul(n.into())) + // Standard Error: 12_681 + .saturating_add(Weight::from_parts(12_812_446, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(7)) .saturating_add(T::DbWeight::get().writes(1)) } @@ -117,8 +117,8 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< // Proof Size summary in bytes: // Measured: `765` // Estimated: `52645` - // Minimum execution time: 67_869_000 picoseconds. - Weight::from_parts(69_290_000, 0) + // Minimum execution time: 69_093_000 picoseconds. + Weight::from_parts(72_845_000, 0) .saturating_add(Weight::from_parts(0, 52645)) .saturating_add(T::DbWeight::get().reads(7)) .saturating_add(T::DbWeight::get().writes(1)) @@ -142,11 +142,11 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< // Proof Size summary in bytes: // Measured: `765` // Estimated: `52645` - // Minimum execution time: 60_562_000 picoseconds. - Weight::from_parts(63_556_899, 0) + // Minimum execution time: 60_938_000 picoseconds. + Weight::from_parts(65_548_162, 0) .saturating_add(Weight::from_parts(0, 52645)) - // Standard Error: 10 - .saturating_add(Weight::from_parts(2_068, 0).saturating_mul(n.into())) + // Standard Error: 21 + .saturating_add(Weight::from_parts(2_344, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(7)) .saturating_add(T::DbWeight::get().writes(1)) } @@ -170,8 +170,8 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< // Proof Size summary in bytes: // Measured: `642` // Estimated: `5358` - // Minimum execution time: 50_287_000 picoseconds. - Weight::from_parts(52_104_000, 0) + // Minimum execution time: 51_254_000 picoseconds. + Weight::from_parts(52_130_000, 0) .saturating_add(Weight::from_parts(0, 5358)) .saturating_add(T::DbWeight::get().reads(7)) .saturating_add(T::DbWeight::get().writes(3)) @@ -196,8 +196,8 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< // Proof Size summary in bytes: // Measured: `642` // Estimated: `5358` - // Minimum execution time: 51_653_000 picoseconds. - Weight::from_parts(52_696_000, 0) + // Minimum execution time: 51_764_000 picoseconds. + Weight::from_parts(53_507_000, 0) .saturating_add(Weight::from_parts(0, 5358)) .saturating_add(T::DbWeight::get().reads(7)) .saturating_add(T::DbWeight::get().writes(4)) @@ -222,8 +222,8 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< // Proof Size summary in bytes: // Measured: `642` // Estimated: `6086` - // Minimum execution time: 56_055_000 picoseconds. - Weight::from_parts(57_421_000, 0) + // Minimum execution time: 56_972_000 picoseconds. + Weight::from_parts(58_619_000, 0) .saturating_add(Weight::from_parts(0, 6086)) .saturating_add(T::DbWeight::get().reads(8)) .saturating_add(T::DbWeight::get().writes(5)) @@ -259,11 +259,11 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< // Proof Size summary in bytes: // Measured: `896` // Estimated: `52645` - // Minimum execution time: 84_883_000 picoseconds. - Weight::from_parts(88_455_136, 0) + // Minimum execution time: 85_043_000 picoseconds. + Weight::from_parts(89_141_726, 0) .saturating_add(Weight::from_parts(0, 52645)) - // Standard Error: 15 - .saturating_add(Weight::from_parts(7_215, 0).saturating_mul(n.into())) + // Standard Error: 14 + .saturating_add(Weight::from_parts(7_597, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(12)) .saturating_add(T::DbWeight::get().writes(4)) } From 54adf0040837bc66d4d43d355f5a22af7eade260 Mon Sep 17 00:00:00 2001 From: command-bot <> Date: Sat, 9 Nov 2024 01:07:59 +0000 Subject: [PATCH 46/72] ".git/.scripts/commands/bench/bench.sh" --subcommand=pallet --runtime=bridge-hub-rococo --runtime_dir=bridge-hubs --target_dir=cumulus --pallet=pallet_xcm_bridge_hub --- .../pallet_xcm_bridge_hub_over_bulletin.rs | 81 +++++++++++++++++++ .../pallet_xcm_bridge_hub_over_westend.rs | 81 +++++++++++++++++++ 2 files changed, 162 insertions(+) create mode 100644 cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/pallet_xcm_bridge_hub_over_bulletin.rs create mode 100644 cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/pallet_xcm_bridge_hub_over_westend.rs diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/pallet_xcm_bridge_hub_over_bulletin.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/pallet_xcm_bridge_hub_over_bulletin.rs new file mode 100644 index 000000000000..048dd45d06ff --- /dev/null +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/pallet_xcm_bridge_hub_over_bulletin.rs @@ -0,0 +1,81 @@ +// 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_bridge_hub` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-11-09, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner-wiukf8gn-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("bridge-hub-rococo-dev")`, DB CACHE: 1024 + +// Executed Command: +// target/production/polkadot-parachain +// benchmark +// pallet +// --steps=50 +// --repeat=20 +// --extrinsic=* +// --wasm-execution=compiled +// --heap-pages=4096 +// --json-file=/builds/parity/mirrors/polkadot-sdk/.git/.artifacts/bench.json +// --pallet=pallet_xcm_bridge_hub +// --chain=bridge-hub-rococo-dev +// --header=./cumulus/file_header.txt +// --output=./cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/ + +#![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`. +pub struct WeightInfo(PhantomData); +impl pallet_xcm_bridge_hub::WeightInfo for WeightInfo { + /// Storage: `Benchmark::Override` (r:0 w:0) + /// Proof: `Benchmark::Override` (`max_values`: None, `max_size`: None, mode: `Measured`) + fn open_bridge() -> 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)) + } + /// Storage: `Benchmark::Override` (r:0 w:0) + /// Proof: `Benchmark::Override` (`max_values`: None, `max_size`: None, mode: `Measured`) + fn close_bridge() -> 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)) + } + /// Storage: `Benchmark::Override` (r:0 w:0) + /// Proof: `Benchmark::Override` (`max_values`: None, `max_size`: None, mode: `Measured`) + fn update_notification_receiver() -> 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)) + } +} diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/pallet_xcm_bridge_hub_over_westend.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/pallet_xcm_bridge_hub_over_westend.rs new file mode 100644 index 000000000000..048dd45d06ff --- /dev/null +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/pallet_xcm_bridge_hub_over_westend.rs @@ -0,0 +1,81 @@ +// 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_bridge_hub` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-11-09, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner-wiukf8gn-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("bridge-hub-rococo-dev")`, DB CACHE: 1024 + +// Executed Command: +// target/production/polkadot-parachain +// benchmark +// pallet +// --steps=50 +// --repeat=20 +// --extrinsic=* +// --wasm-execution=compiled +// --heap-pages=4096 +// --json-file=/builds/parity/mirrors/polkadot-sdk/.git/.artifacts/bench.json +// --pallet=pallet_xcm_bridge_hub +// --chain=bridge-hub-rococo-dev +// --header=./cumulus/file_header.txt +// --output=./cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/ + +#![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`. +pub struct WeightInfo(PhantomData); +impl pallet_xcm_bridge_hub::WeightInfo for WeightInfo { + /// Storage: `Benchmark::Override` (r:0 w:0) + /// Proof: `Benchmark::Override` (`max_values`: None, `max_size`: None, mode: `Measured`) + fn open_bridge() -> 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)) + } + /// Storage: `Benchmark::Override` (r:0 w:0) + /// Proof: `Benchmark::Override` (`max_values`: None, `max_size`: None, mode: `Measured`) + fn close_bridge() -> 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)) + } + /// Storage: `Benchmark::Override` (r:0 w:0) + /// Proof: `Benchmark::Override` (`max_values`: None, `max_size`: None, mode: `Measured`) + fn update_notification_receiver() -> 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)) + } +} From ef2321a3ade1a4e7f603f27e65f30f7c78d82347 Mon Sep 17 00:00:00 2001 From: command-bot <> Date: Sat, 9 Nov 2024 01:09:18 +0000 Subject: [PATCH 47/72] ".git/.scripts/commands/bench/bench.sh" --subcommand=pallet --runtime=asset-hub-westend --runtime_dir=assets --target_dir=cumulus --pallet=pallet_xcm_bridge_hub_router --- .../src/weights/pallet_xcm_bridge_hub_router.rs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/pallet_xcm_bridge_hub_router.rs b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/pallet_xcm_bridge_hub_router.rs index 0e6d9746d24a..142701e0b2bd 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/pallet_xcm_bridge_hub_router.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/pallet_xcm_bridge_hub_router.rs @@ -17,9 +17,9 @@ //! Autogenerated weights for `pallet_xcm_bridge_hub_router` //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-11-07, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2024-11-09, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-vcatxqpx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! HOSTNAME: `runner-wiukf8gn-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("asset-hub-westend-dev")`, DB CACHE: 1024 // Executed Command: @@ -54,8 +54,8 @@ impl pallet_xcm_bridge_hub_router::WeightInfo for Weigh // Proof Size summary in bytes: // Measured: `204` // Estimated: `6070` - // Minimum execution time: 19_250_000 picoseconds. - Weight::from_parts(20_167_000, 0) + // Minimum execution time: 19_382_000 picoseconds. + Weight::from_parts(20_031_000, 0) .saturating_add(Weight::from_parts(0, 6070)) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(1)) @@ -66,8 +66,8 @@ impl pallet_xcm_bridge_hub_router::WeightInfo for Weigh // Proof Size summary in bytes: // Measured: `204` // Estimated: `6070` - // Minimum execution time: 20_210_000 picoseconds. - Weight::from_parts(20_675_000, 0) + // Minimum execution time: 19_869_000 picoseconds. + Weight::from_parts(20_528_000, 0) .saturating_add(Weight::from_parts(0, 6070)) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(1)) @@ -78,8 +78,8 @@ impl pallet_xcm_bridge_hub_router::WeightInfo for Weigh // Proof Size summary in bytes: // Measured: `109` // Estimated: `3530` - // Minimum execution time: 10_622_000 picoseconds. - Weight::from_parts(11_047_000, 0) + // Minimum execution time: 10_800_000 picoseconds. + Weight::from_parts(11_171_000, 0) .saturating_add(Weight::from_parts(0, 3530)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) From ea8d9dc7e6c71ab3bb1331be9904ea46d162dce7 Mon Sep 17 00:00:00 2001 From: command-bot <> Date: Sat, 9 Nov 2024 01:09:53 +0000 Subject: [PATCH 48/72] ".git/.scripts/commands/bench/bench.sh" --subcommand=xcm --runtime=bridge-hub-rococo --runtime_dir=bridge-hubs --target_dir=cumulus --pallet=pallet_xcm_benchmarks::generic --- .../xcm/pallet_xcm_benchmarks_generic.rs | 132 +++++++++--------- 1 file changed, 66 insertions(+), 66 deletions(-) diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/xcm/pallet_xcm_benchmarks_generic.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/xcm/pallet_xcm_benchmarks_generic.rs index e7913b93d0cb..6f7088e94bd7 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/xcm/pallet_xcm_benchmarks_generic.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/xcm/pallet_xcm_benchmarks_generic.rs @@ -17,9 +17,9 @@ //! Autogenerated weights for `pallet_xcm_benchmarks::generic` //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-11-07, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2024-11-09, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-vcatxqpx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! HOSTNAME: `runner-wiukf8gn-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: Compiled, CHAIN: Some("bridge-hub-rococo-dev"), DB CACHE: 1024 // Executed Command: @@ -68,8 +68,8 @@ impl WeightInfo { // Proof Size summary in bytes: // Measured: `171` // Estimated: `6196` - // Minimum execution time: 72_937_000 picoseconds. - Weight::from_parts(75_819_000, 6196) + // Minimum execution time: 73_985_000 picoseconds. + Weight::from_parts(75_642_000, 6196) .saturating_add(T::DbWeight::get().reads(9)) .saturating_add(T::DbWeight::get().writes(4)) } @@ -77,8 +77,8 @@ impl WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_034_000 picoseconds. - Weight::from_parts(1_102_000, 0) + // Minimum execution time: 946_000 picoseconds. + Weight::from_parts(1_025_000, 0) } // Storage: `System::Account` (r:1 w:1) // Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) @@ -86,8 +86,8 @@ impl WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `3593` - // Minimum execution time: 3_844_000 picoseconds. - Weight::from_parts(4_059_000, 3593) + // Minimum execution time: 3_881_000 picoseconds. + Weight::from_parts(4_137_000, 3593) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } @@ -95,8 +95,8 @@ impl WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_066_000 picoseconds. - Weight::from_parts(1_121_000, 0) + // Minimum execution time: 960_000 picoseconds. + Weight::from_parts(1_023_000, 0) } // Storage: `PolkadotXcm::Queries` (r:1 w:0) // Proof: `PolkadotXcm::Queries` (`max_values`: None, `max_size`: None, mode: `Measured`) @@ -104,58 +104,58 @@ impl WeightInfo { // Proof Size summary in bytes: // Measured: `32` // Estimated: `3497` - // Minimum execution time: 8_424_000 picoseconds. - Weight::from_parts(8_697_000, 3497) + // Minimum execution time: 7_926_000 picoseconds. + Weight::from_parts(8_167_000, 3497) .saturating_add(T::DbWeight::get().reads(1)) } pub fn transact() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 8_162_000 picoseconds. - Weight::from_parts(8_419_000, 0) + // Minimum execution time: 7_878_000 picoseconds. + Weight::from_parts(8_181_000, 0) } pub fn refund_surplus() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_758_000 picoseconds. - Weight::from_parts(1_871_000, 0) + // Minimum execution time: 1_580_000 picoseconds. + Weight::from_parts(1_738_000, 0) } pub fn set_error_handler() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_075_000 picoseconds. - Weight::from_parts(1_133_000, 0) + // Minimum execution time: 967_000 picoseconds. + Weight::from_parts(1_028_000, 0) } pub fn set_appendix() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_058_000 picoseconds. - Weight::from_parts(1_130_000, 0) + // Minimum execution time: 990_000 picoseconds. + Weight::from_parts(1_043_000, 0) } pub fn clear_error() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_041_000 picoseconds. - Weight::from_parts(1_076_000, 0) + // Minimum execution time: 924_000 picoseconds. + Weight::from_parts(1_001_000, 0) } pub fn descend_origin() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_020_000 picoseconds. - Weight::from_parts(1_101_000, 0) + // Minimum execution time: 971_000 picoseconds. + Weight::from_parts(1_016_000, 0) } pub fn clear_origin() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_021_000 picoseconds. - Weight::from_parts(1_088_000, 0) + // Minimum execution time: 953_000 picoseconds. + Weight::from_parts(1_023_000, 0) } // Storage: `ParachainInfo::ParachainId` (r:1 w:0) // Proof: `ParachainInfo::ParachainId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) @@ -177,8 +177,8 @@ impl WeightInfo { // Proof Size summary in bytes: // Measured: `171` // Estimated: `6196` - // Minimum execution time: 69_708_000 picoseconds. - Weight::from_parts(71_269_000, 6196) + // Minimum execution time: 69_178_000 picoseconds. + Weight::from_parts(71_090_000, 6196) .saturating_add(T::DbWeight::get().reads(9)) .saturating_add(T::DbWeight::get().writes(4)) } @@ -188,8 +188,8 @@ impl WeightInfo { // Proof Size summary in bytes: // Measured: `90` // Estimated: `3555` - // Minimum execution time: 11_628_000 picoseconds. - Weight::from_parts(12_060_000, 3555) + // Minimum execution time: 11_211_000 picoseconds. + Weight::from_parts(11_590_000, 3555) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } @@ -197,8 +197,8 @@ impl WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_035_000 picoseconds. - Weight::from_parts(1_078_000, 0) + // Minimum execution time: 925_000 picoseconds. + Weight::from_parts(995_000, 0) } // Storage: `PolkadotXcm::VersionNotifyTargets` (r:1 w:1) // Proof: `PolkadotXcm::VersionNotifyTargets` (`max_values`: None, `max_size`: None, mode: `Measured`) @@ -218,8 +218,8 @@ impl WeightInfo { // Proof Size summary in bytes: // Measured: `38` // Estimated: `3503` - // Minimum execution time: 26_364_000 picoseconds. - Weight::from_parts(27_334_000, 3503) + // Minimum execution time: 25_942_000 picoseconds. + Weight::from_parts(26_756_000, 3503) .saturating_add(T::DbWeight::get().reads(7)) .saturating_add(T::DbWeight::get().writes(3)) } @@ -229,44 +229,44 @@ impl WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 3_047_000 picoseconds. - Weight::from_parts(3_264_000, 0) + // Minimum execution time: 3_019_000 picoseconds. + Weight::from_parts(3_245_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: 1_406_000 picoseconds. - Weight::from_parts(1_484_000, 0) + // Minimum execution time: 1_359_000 picoseconds. + Weight::from_parts(1_442_000, 0) } pub fn expect_asset() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_146_000 picoseconds. - Weight::from_parts(1_194_000, 0) + // Minimum execution time: 1_053_000 picoseconds. + Weight::from_parts(1_169_000, 0) } pub fn expect_origin() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_055_000 picoseconds. - Weight::from_parts(1_101_000, 0) + // Minimum execution time: 953_000 picoseconds. + Weight::from_parts(1_039_000, 0) } pub fn expect_error() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_042_000 picoseconds. - Weight::from_parts(1_084_000, 0) + // Minimum execution time: 957_000 picoseconds. + Weight::from_parts(1_005_000, 0) } pub fn expect_transact_status() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_196_000 picoseconds. - Weight::from_parts(1_269_000, 0) + // Minimum execution time: 1_151_000 picoseconds. + Weight::from_parts(1_198_000, 0) } // Storage: `ParachainInfo::ParachainId` (r:1 w:0) // Proof: `ParachainInfo::ParachainId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) @@ -288,8 +288,8 @@ impl WeightInfo { // Proof Size summary in bytes: // Measured: `171` // Estimated: `6196` - // Minimum execution time: 75_168_000 picoseconds. - Weight::from_parts(78_390_000, 6196) + // Minimum execution time: 75_598_000 picoseconds. + Weight::from_parts(78_209_000, 6196) .saturating_add(T::DbWeight::get().reads(9)) .saturating_add(T::DbWeight::get().writes(4)) } @@ -297,8 +297,8 @@ impl WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 4_857_000 picoseconds. - Weight::from_parts(4_948_000, 0) + // Minimum execution time: 4_954_000 picoseconds. + Weight::from_parts(5_198_000, 0) } // Storage: `ParachainInfo::ParachainId` (r:1 w:0) // Proof: `ParachainInfo::ParachainId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) @@ -320,8 +320,8 @@ impl WeightInfo { // Proof Size summary in bytes: // Measured: `171` // Estimated: `6196` - // Minimum execution time: 69_757_000 picoseconds. - Weight::from_parts(72_027_000, 6196) + // Minimum execution time: 69_330_000 picoseconds. + Weight::from_parts(71_245_000, 6196) .saturating_add(T::DbWeight::get().reads(9)) .saturating_add(T::DbWeight::get().writes(4)) } @@ -329,22 +329,22 @@ impl WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_075_000 picoseconds. - Weight::from_parts(1_110_000, 0) + // Minimum execution time: 993_000 picoseconds. + Weight::from_parts(1_078_000, 0) } pub fn set_topic() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_019_000 picoseconds. - Weight::from_parts(1_100_000, 0) + // Minimum execution time: 942_000 picoseconds. + Weight::from_parts(1_017_000, 0) } pub fn clear_topic() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_046_000 picoseconds. - Weight::from_parts(1_087_000, 0) + // Minimum execution time: 928_000 picoseconds. + Weight::from_parts(1_005_000, 0) } // Storage: `ParachainInfo::ParachainId` (r:1 w:0) // Proof: `ParachainInfo::ParachainId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) @@ -363,10 +363,10 @@ impl WeightInfo { // Proof Size summary in bytes: // Measured: `632` // Estimated: `6572` - // Minimum execution time: 58_530_000 picoseconds. - Weight::from_parts(60_307_825, 6572) - // Standard Error: 158 - .saturating_add(Weight::from_parts(53_061, 0).saturating_mul(x.into())) + // Minimum execution time: 58_042_000 picoseconds. + Weight::from_parts(59_689_657, 6572) + // Standard Error: 212 + .saturating_add(Weight::from_parts(49_274, 0).saturating_mul(x.into())) .saturating_add(T::DbWeight::get().reads(6)) .saturating_add(T::DbWeight::get().writes(2)) } @@ -374,14 +374,14 @@ impl WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_023_000 picoseconds. - Weight::from_parts(1_074_000, 0) + // Minimum execution time: 947_000 picoseconds. + Weight::from_parts(1_018_000, 0) } pub fn unpaid_execution() -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_040_000 picoseconds. - Weight::from_parts(1_096_000, 0) + // Minimum execution time: 944_000 picoseconds. + Weight::from_parts(1_050_000, 0) } } From 15f4e699a64f3b203246bc30eb8e6ce5eb60d758 Mon Sep 17 00:00:00 2001 From: command-bot <> Date: Sat, 9 Nov 2024 01:17:37 +0000 Subject: [PATCH 49/72] ".git/.scripts/commands/bench/bench.sh" --subcommand=pallet --runtime=bridge-hub-rococo --runtime_dir=bridge-hubs --target_dir=cumulus --pallet=pallet_bridge_messages --- ...idge_messages_rococo_to_rococo_bulletin.rs | 48 +++++++++---------- ...allet_bridge_messages_rococo_to_westend.rs | 46 +++++++++--------- 2 files changed, 47 insertions(+), 47 deletions(-) diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/pallet_bridge_messages_rococo_to_rococo_bulletin.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/pallet_bridge_messages_rococo_to_rococo_bulletin.rs index cef34033ba3e..e99b5c529d6f 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/pallet_bridge_messages_rococo_to_rococo_bulletin.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/pallet_bridge_messages_rococo_to_rococo_bulletin.rs @@ -17,9 +17,9 @@ //! Autogenerated weights for `pallet_bridge_messages` //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-11-07, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2024-11-09, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-vcatxqpx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! HOSTNAME: `runner-wiukf8gn-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("bridge-hub-rococo-dev")`, DB CACHE: 1024 // Executed Command: @@ -64,8 +64,8 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< // Proof Size summary in bytes: // Measured: `963` // Estimated: `52673` - // Minimum execution time: 61_743_000 picoseconds. - Weight::from_parts(63_580_000, 0) + // Minimum execution time: 63_162_000 picoseconds. + Weight::from_parts(64_800_000, 0) .saturating_add(Weight::from_parts(0, 52673)) .saturating_add(T::DbWeight::get().reads(6)) .saturating_add(T::DbWeight::get().writes(1)) @@ -88,11 +88,11 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< // Proof Size summary in bytes: // Measured: `963` // Estimated: `52673` - // Minimum execution time: 61_363_000 picoseconds. - Weight::from_parts(63_084_000, 0) + // Minimum execution time: 62_746_000 picoseconds. + Weight::from_parts(64_378_000, 0) .saturating_add(Weight::from_parts(0, 52673)) - // Standard Error: 15_252 - .saturating_add(Weight::from_parts(14_868_979, 0).saturating_mul(n.into())) + // Standard Error: 18_595 + .saturating_add(Weight::from_parts(15_438_479, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(6)) .saturating_add(T::DbWeight::get().writes(1)) } @@ -112,8 +112,8 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< // Proof Size summary in bytes: // Measured: `963` // Estimated: `52673` - // Minimum execution time: 67_767_000 picoseconds. - Weight::from_parts(70_683_000, 0) + // Minimum execution time: 68_757_000 picoseconds. + Weight::from_parts(71_599_000, 0) .saturating_add(Weight::from_parts(0, 52673)) .saturating_add(T::DbWeight::get().reads(6)) .saturating_add(T::DbWeight::get().writes(1)) @@ -136,11 +136,11 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< // Proof Size summary in bytes: // Measured: `963` // Estimated: `52673` - // Minimum execution time: 59_522_000 picoseconds. - Weight::from_parts(64_576_781, 0) + // Minimum execution time: 60_861_000 picoseconds. + Weight::from_parts(65_303_205, 0) .saturating_add(Weight::from_parts(0, 52673)) - // Standard Error: 8 - .saturating_add(Weight::from_parts(2_331, 0).saturating_mul(n.into())) + // Standard Error: 9 + .saturating_add(Weight::from_parts(2_156, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(6)) .saturating_add(T::DbWeight::get().writes(1)) } @@ -160,8 +160,8 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< // Proof Size summary in bytes: // Measured: `930` // Estimated: `5386` - // Minimum execution time: 44_282_000 picoseconds. - Weight::from_parts(45_854_000, 0) + // Minimum execution time: 44_686_000 picoseconds. + Weight::from_parts(46_494_000, 0) .saturating_add(Weight::from_parts(0, 5386)) .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(2)) @@ -182,8 +182,8 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< // Proof Size summary in bytes: // Measured: `930` // Estimated: `5386` - // Minimum execution time: 46_155_000 picoseconds. - Weight::from_parts(47_460_000, 0) + // Minimum execution time: 46_167_000 picoseconds. + Weight::from_parts(47_728_000, 0) .saturating_add(Weight::from_parts(0, 5386)) .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(3)) @@ -204,8 +204,8 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< // Proof Size summary in bytes: // Measured: `930` // Estimated: `5386` - // Minimum execution time: 46_050_000 picoseconds. - Weight::from_parts(47_530_000, 0) + // Minimum execution time: 46_285_000 picoseconds. + Weight::from_parts(48_097_000, 0) .saturating_add(Weight::from_parts(0, 5386)) .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(3)) @@ -242,11 +242,11 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< // Proof Size summary in bytes: // Measured: `1122` // Estimated: `52673` - // Minimum execution time: 83_884_000 picoseconds. - Weight::from_parts(90_305_551, 0) + // Minimum execution time: 86_225_000 picoseconds. + Weight::from_parts(91_787_938, 0) .saturating_add(Weight::from_parts(0, 52673)) - // Standard Error: 8 - .saturating_add(Weight::from_parts(7_569, 0).saturating_mul(n.into())) + // Standard Error: 10 + .saturating_add(Weight::from_parts(7_223, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(12)) .saturating_add(T::DbWeight::get().writes(4)) } diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/pallet_bridge_messages_rococo_to_westend.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/pallet_bridge_messages_rococo_to_westend.rs index 13862f39fd68..2243d02adbd2 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/pallet_bridge_messages_rococo_to_westend.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/pallet_bridge_messages_rococo_to_westend.rs @@ -17,9 +17,9 @@ //! Autogenerated weights for `pallet_bridge_messages` //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-11-07, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2024-11-09, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-vcatxqpx-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! HOSTNAME: `runner-wiukf8gn-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("bridge-hub-rococo-dev")`, DB CACHE: 1024 // Executed Command: @@ -66,8 +66,8 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< // Proof Size summary in bytes: // Measured: `940` // Estimated: `52645` - // Minimum execution time: 61_880_000 picoseconds. - Weight::from_parts(64_292_000, 0) + // Minimum execution time: 62_868_000 picoseconds. + Weight::from_parts(65_210_000, 0) .saturating_add(Weight::from_parts(0, 52645)) .saturating_add(T::DbWeight::get().reads(7)) .saturating_add(T::DbWeight::get().writes(1)) @@ -92,11 +92,11 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< // Proof Size summary in bytes: // Measured: `940` // Estimated: `52645` - // Minimum execution time: 62_267_000 picoseconds. - Weight::from_parts(63_625_000, 0) + // Minimum execution time: 62_893_000 picoseconds. + Weight::from_parts(63_992_000, 0) .saturating_add(Weight::from_parts(0, 52645)) - // Standard Error: 10_655 - .saturating_add(Weight::from_parts(11_829_871, 0).saturating_mul(n.into())) + // Standard Error: 13_856 + .saturating_add(Weight::from_parts(12_332_627, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(7)) .saturating_add(T::DbWeight::get().writes(1)) } @@ -118,8 +118,8 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< // Proof Size summary in bytes: // Measured: `940` // Estimated: `52645` - // Minimum execution time: 68_483_000 picoseconds. - Weight::from_parts(71_827_000, 0) + // Minimum execution time: 68_193_000 picoseconds. + Weight::from_parts(70_799_000, 0) .saturating_add(Weight::from_parts(0, 52645)) .saturating_add(T::DbWeight::get().reads(7)) .saturating_add(T::DbWeight::get().writes(1)) @@ -144,11 +144,11 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< // Proof Size summary in bytes: // Measured: `940` // Estimated: `52645` - // Minimum execution time: 60_870_000 picoseconds. - Weight::from_parts(65_369_830, 0) + // Minimum execution time: 61_230_000 picoseconds. + Weight::from_parts(65_437_770, 0) .saturating_add(Weight::from_parts(0, 52645)) // Standard Error: 9 - .saturating_add(Weight::from_parts(2_306, 0).saturating_mul(n.into())) + .saturating_add(Weight::from_parts(2_168, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(7)) .saturating_add(T::DbWeight::get().writes(1)) } @@ -172,8 +172,8 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< // Proof Size summary in bytes: // Measured: `711` // Estimated: `5358` - // Minimum execution time: 50_879_000 picoseconds. - Weight::from_parts(52_159_000, 0) + // Minimum execution time: 51_650_000 picoseconds. + Weight::from_parts(53_190_000, 0) .saturating_add(Weight::from_parts(0, 5358)) .saturating_add(T::DbWeight::get().reads(7)) .saturating_add(T::DbWeight::get().writes(3)) @@ -198,8 +198,8 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< // Proof Size summary in bytes: // Measured: `711` // Estimated: `5358` - // Minimum execution time: 52_336_000 picoseconds. - Weight::from_parts(53_754_000, 0) + // Minimum execution time: 51_836_000 picoseconds. + Weight::from_parts(53_960_000, 0) .saturating_add(Weight::from_parts(0, 5358)) .saturating_add(T::DbWeight::get().reads(7)) .saturating_add(T::DbWeight::get().writes(4)) @@ -224,8 +224,8 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< // Proof Size summary in bytes: // Measured: `711` // Estimated: `6086` - // Minimum execution time: 56_457_000 picoseconds. - Weight::from_parts(58_435_000, 0) + // Minimum execution time: 56_606_000 picoseconds. + Weight::from_parts(58_528_000, 0) .saturating_add(Weight::from_parts(0, 6086)) .saturating_add(T::DbWeight::get().reads(8)) .saturating_add(T::DbWeight::get().writes(5)) @@ -262,11 +262,11 @@ impl pallet_bridge_messages::WeightInfo for WeightInfo< // Proof Size summary in bytes: // Measured: `1071` // Estimated: `52645` - // Minimum execution time: 84_622_000 picoseconds. - Weight::from_parts(90_698_207, 0) + // Minimum execution time: 85_179_000 picoseconds. + Weight::from_parts(91_600_892, 0) .saturating_add(Weight::from_parts(0, 52645)) - // Standard Error: 10 - .saturating_add(Weight::from_parts(7_543, 0).saturating_mul(n.into())) + // Standard Error: 11 + .saturating_add(Weight::from_parts(7_210, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(12)) .saturating_add(T::DbWeight::get().writes(4)) } From 6d415be3b0b24fe5afa7a6d1aae920136f507de9 Mon Sep 17 00:00:00 2001 From: Branislav Kontur Date: Sat, 9 Nov 2024 09:33:00 +0100 Subject: [PATCH 50/72] clippy + weights --- bridges/modules/xcm-bridge-hub/src/mock.rs | 5 +---- .../bridge-hub-rococo/src/bridge_to_bulletin_config.rs | 2 +- .../bridge-hub-rococo/src/bridge_to_westend_config.rs | 2 +- .../bridge-hubs/bridge-hub-rococo/src/weights/mod.rs | 2 ++ .../bridge-hub-westend/src/bridge_to_rococo_config.rs | 2 +- .../bridge-hubs/bridge-hub-westend/src/weights/mod.rs | 1 + 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/bridges/modules/xcm-bridge-hub/src/mock.rs b/bridges/modules/xcm-bridge-hub/src/mock.rs index 545fdecf07fe..f5d679067edc 100644 --- a/bridges/modules/xcm-bridge-hub/src/mock.rs +++ b/bridges/modules/xcm-bridge-hub/src/mock.rs @@ -723,8 +723,5 @@ pub fn new_test_ext() -> sp_io::TestExternalities { /// Run pallet test. pub fn run_test(test: impl FnOnce() -> T) -> T { - sp_io::TestExternalities::new( - frame_system::GenesisConfig::::default().build_storage().unwrap(), - ) - .execute_with(test) + new_test_ext().execute_with(test) } diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_bulletin_config.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_bulletin_config.rs index 1bb89209e58e..42b92453f85f 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_bulletin_config.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_bulletin_config.rs @@ -126,7 +126,7 @@ impl pallet_bridge_messages::Config for Runt pub type XcmOverPolkadotBulletinInstance = pallet_xcm_bridge_hub::Instance2; impl pallet_xcm_bridge_hub::Config for Runtime { type RuntimeEvent = RuntimeEvent; - type WeightInfo = (); + type WeightInfo = weights::pallet_xcm_bridge_hub_over_bulletin::WeightInfo; type UniversalLocation = UniversalLocation; type BridgedNetwork = RococoBulletinGlobalConsensusNetworkLocation; diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_westend_config.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_westend_config.rs index 3f403134491c..9ed27670bfe0 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_westend_config.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_westend_config.rs @@ -146,7 +146,7 @@ impl Convert, Xcm<()>> for ReportBridgeStatusXcmProvider { pub type XcmOverBridgeHubWestendInstance = pallet_xcm_bridge_hub::Instance1; impl pallet_xcm_bridge_hub::Config for Runtime { type RuntimeEvent = RuntimeEvent; - type WeightInfo = (); + type WeightInfo = weights::pallet_xcm_bridge_hub_over_westend::WeightInfo; type UniversalLocation = UniversalLocation; type BridgedNetwork = WestendGlobalConsensusNetworkLocation; diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/mod.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/mod.rs index 74796e626a2e..1dd689cde4e8 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/mod.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/mod.rs @@ -42,6 +42,8 @@ pub mod pallet_timestamp; pub mod pallet_transaction_payment; pub mod pallet_utility; pub mod pallet_xcm; +pub mod pallet_xcm_bridge_hub_over_bulletin; +pub mod pallet_xcm_bridge_hub_over_westend; pub mod paritydb_weights; pub mod rocksdb_weights; pub mod snowbridge_pallet_ethereum_client; diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/bridge_to_rococo_config.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/bridge_to_rococo_config.rs index c77f8d2bfb6e..3f81d6dc839c 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/bridge_to_rococo_config.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/bridge_to_rococo_config.rs @@ -176,7 +176,7 @@ impl Convert, Xcm<()>> for ReportBridgeStatusXcmProvider { pub type XcmOverBridgeHubRococoInstance = pallet_xcm_bridge_hub::Instance1; impl pallet_xcm_bridge_hub::Config for Runtime { type RuntimeEvent = RuntimeEvent; - type WeightInfo = (); + type WeightInfo = weights::pallet_xcm_bridge_hub::WeightInfo; type UniversalLocation = UniversalLocation; type BridgedNetwork = RococoGlobalConsensusNetworkLocation; diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/mod.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/mod.rs index c1c5c337aca8..952a97f9d12d 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/mod.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/mod.rs @@ -41,6 +41,7 @@ pub mod pallet_timestamp; pub mod pallet_transaction_payment; pub mod pallet_utility; pub mod pallet_xcm; +pub mod pallet_xcm_bridge_hub; pub mod paritydb_weights; pub mod rocksdb_weights; pub mod xcm; From 3e32dcfbd1d901842bcc8b837de1c8447ac5cded Mon Sep 17 00:00:00 2001 From: Branislav Kontur Date: Mon, 11 Nov 2024 13:57:00 +0100 Subject: [PATCH 51/72] Adds ability to stop `exporting` more messages (a.k.a dropping). --- .../modules/xcm-bridge-hub/src/congestion.rs | 34 ++++- .../modules/xcm-bridge-hub/src/exporter.rs | 140 +++++++++++++----- bridges/modules/xcm-bridge-hub/src/lib.rs | 11 +- bridges/modules/xcm-bridge-hub/src/mock.rs | 5 +- bridges/primitives/xcm-bridge-hub/src/lib.rs | 6 +- prdoc/pr_6231.prdoc | 12 +- 6 files changed, 159 insertions(+), 49 deletions(-) diff --git a/bridges/modules/xcm-bridge-hub/src/congestion.rs b/bridges/modules/xcm-bridge-hub/src/congestion.rs index e1e9af3e025b..95cf9ed1df7f 100644 --- a/bridges/modules/xcm-bridge-hub/src/congestion.rs +++ b/bridges/modules/xcm-bridge-hub/src/congestion.rs @@ -18,12 +18,44 @@ use crate::{Bridges, Config, DispatchChannelStatusProvider, LOG_TARGET}; use bp_xcm_bridge_hub::{BridgeId, LocalXcmChannelManager, Receiver}; -use codec::Encode; +use codec::{Decode, Encode}; use sp_runtime::traits::Convert; use sp_std::{marker::PhantomData, vec::Vec}; use xcm::latest::{send_xcm, Location, SendXcm, Xcm}; use xcm_builder::{DispatchBlob, DispatchBlobError}; +/// Limits for handling congestion. +#[derive(Debug, Decode, Encode)] +pub struct CongestionLimits { + /// Maximal number of messages in the outbound bridge queue. Once we reach this limit, we + /// suspend a bridge. + pub outbound_lane_congested_threshold: bp_messages::MessageNonce, + /// After we have suspended the bridge, we wait until number of messages in the outbound bridge + /// queue drops to this count, before sending resuming the bridge. + pub outbound_lane_uncongested_threshold: bp_messages::MessageNonce, + /// Maximal number of messages in the outbound bridge queue after we have suspended the bridge. + /// Once we reach this limit, we stop exporting more messages. + pub outbound_lane_stop_threshold: bp_messages::MessageNonce, +} + +impl CongestionLimits { + /// Checks if limits are valid. + pub fn is_valid(&self) -> bool { + self.outbound_lane_uncongested_threshold < self.outbound_lane_congested_threshold + && self.outbound_lane_stop_threshold > self.outbound_lane_congested_threshold + } +} + +impl Default for CongestionLimits { + fn default() -> Self { + Self { + outbound_lane_congested_threshold: 8_192, + outbound_lane_uncongested_threshold: 1_024, + outbound_lane_stop_threshold: 9216, + } + } +} + /// Switches the implementation of `LocalXcmChannelManager` based on the `local_origin`. /// /// - `HereXcmChannelManager` is applied when the origin is `Here`. diff --git a/bridges/modules/xcm-bridge-hub/src/exporter.rs b/bridges/modules/xcm-bridge-hub/src/exporter.rs index 61eb2858fd63..ba9efac10a16 100644 --- a/bridges/modules/xcm-bridge-hub/src/exporter.rs +++ b/bridges/modules/xcm-bridge-hub/src/exporter.rs @@ -37,14 +37,6 @@ use xcm::prelude::*; use xcm_builder::{HaulBlob, HaulBlobError, HaulBlobExporter}; use xcm_executor::traits::ExportXcm; -/// Maximal number of messages in the outbound bridge queue. Once we reach this limit, we -/// suspend a bridge. -const OUTBOUND_LANE_CONGESTED_THRESHOLD: MessageNonce = 8_192; - -/// After we have suspended the bridge, we wait until number of messages in the outbound bridge -/// queue drops to this count, before sending resuming the bridge. -const OUTBOUND_LANE_UNCONGESTED_THRESHOLD: MessageNonce = 1_024; - /// An easy way to access `HaulBlobExporter`. pub type PalletAsHaulBlobExporter = HaulBlobExporter< DummyHaulBlob, @@ -152,6 +144,19 @@ where message, )?; + // Here, we know that the message is relevant to this pallet instance, so let's check for congestion defense. + if bridge.state == BridgeState::Suspended(false) { + log::error!( + target: LOG_TARGET, + "Bridge for requested bridge_origin_relative_location: {:?} (bridge_origin_universal_location: {:?}) and bridge_destination_universal_location: {:?} \ + is suspended and does not accept more messages!", + locations.bridge_origin_relative_location(), + locations.bridge_origin_universal_location(), + locations.bridge_destination_universal_location(), + ); + return Err(SendError::Transport("Exporter is suspended!")); + } + let bridge_message = MessagesPallet::::validate_message(bridge.lane_id, &blob) .map_err(|e| { match e { @@ -213,19 +218,32 @@ impl, I: 'static> Pallet { enqueued_messages: MessageNonce, ) { // if the bridge queue is not congested, we don't want to do anything - let is_congested = enqueued_messages > OUTBOUND_LANE_CONGESTED_THRESHOLD; + let is_congested = enqueued_messages > T::CongestionLimits::get().outbound_lane_congested_threshold; if !is_congested { return } - // TODO: https://github.com/paritytech/parity-bridges-common/issues/2006 we either need fishermens - // to watch this rule violation (suspended, but keep sending new messages), or we need a - // hard limit for that like other XCM queues have - - // check if the lane is already suspended. If it is, do nothing. We still accept new - // messages to the suspended bridge, hoping that it'll be actually resumed soon - if bridge.state == BridgeState::Suspended { - return + // check if the lane is already suspended or not. + match bridge.state { + BridgeState::Suspended(true) => { + if enqueued_messages > T::CongestionLimits::get().outbound_lane_stop_threshold { + // If its suspended and reached `outbound_lane_stop_threshold`, we stop accepting new messages (a.k.a. start dropping). + Bridges::::mutate_extant(bridge_id, |bridge| { + bridge.state = BridgeState::Suspended(false); + }); + return + } else { + // We still can accept new messages to the suspended bridge, hoping that it'll be actually resumed soon + return + } + } + BridgeState::Suspended(false) => { + // We cannot accept new messages to the suspended bridge, hoping that it'll be actually resumed soon + return + } + _ => { + // do nothing and continue + } } // else - suspend the bridge @@ -269,14 +287,14 @@ impl, I: 'static> Pallet { // and remember that we have suspended the bridge Bridges::::mutate_extant(bridge_id, |bridge| { - bridge.state = BridgeState::Suspended; + bridge.state = BridgeState::Suspended(true); }); } /// Must be called whenever we receive a message delivery confirmation. fn on_bridge_messages_delivered(lane_id: T::LaneId, enqueued_messages: MessageNonce) { // if the bridge queue is still congested, we don't want to do anything - let is_congested = enqueued_messages > OUTBOUND_LANE_UNCONGESTED_THRESHOLD; + let is_congested = enqueued_messages > T::CongestionLimits::get().outbound_lane_uncongested_threshold; if is_congested { return } @@ -284,7 +302,7 @@ impl, I: 'static> Pallet { // if we have not suspended the bridge before (or it is closed), we don't want to do // anything let (bridge_id, bridge) = match Self::bridge_by_lane_id(&lane_id) { - Some(bridge) if bridge.1.state == BridgeState::Suspended => bridge, + Some(bridge) if bridge.1.state == BridgeState::Suspended(true) || bridge.1.state == BridgeState::Suspended(false) => bridge, _ => { // if there is no bridge or it has been closed, then we don't need to send resume // signal to the local origin - it has closed bridge itself, so it should have @@ -366,7 +384,7 @@ mod tests { use bp_runtime::RangeInclusiveExt; use bp_xcm_bridge_hub::{Bridge, BridgeLocations, BridgeState, Receiver}; use frame_support::{ - assert_ok, + assert_err, assert_ok, traits::{Contains, EnsureOrigin}, }; use pallet_xcm_bridge_hub_router::ResolveBridgeId; @@ -462,9 +480,9 @@ mod tests { let (bridge_id, _) = open_lane_and_send_regular_message(OpenBridgeOrigin::sibling_parachain_origin()); Bridges::::mutate_extant(bridge_id, |bridge| { - bridge.state = BridgeState::Suspended; + bridge.state = BridgeState::Suspended(true); }); - for _ in 1..OUTBOUND_LANE_CONGESTED_THRESHOLD { + for _ in 1..TestCongestionLimits::get().outbound_lane_congested_threshold { open_lane_and_send_regular_message(OpenBridgeOrigin::sibling_parachain_origin()); } @@ -478,7 +496,7 @@ mod tests { run_test(|| { let (bridge_id, _) = open_lane_and_send_regular_message(OpenBridgeOrigin::sibling_parachain_origin()); - for _ in 1..OUTBOUND_LANE_CONGESTED_THRESHOLD { + for _ in 1..TestCongestionLimits::get().outbound_lane_congested_threshold { open_lane_and_send_regular_message(OpenBridgeOrigin::sibling_parachain_origin()); } @@ -487,7 +505,13 @@ mod tests { open_lane_and_send_regular_message(OpenBridgeOrigin::sibling_parachain_origin()); assert!(TestLocalXcmChannelManager::is_bridge_suspened(&bridge_id)); - assert_eq!(XcmOverBridge::bridge(&bridge_id).unwrap().state, BridgeState::Suspended); + assert_eq!(XcmOverBridge::bridge(&bridge_id).unwrap().state, BridgeState::Suspended(true)); + + // send more messages to reach `outbound_lane_stop_threshold` + for _ in TestCongestionLimits::get().outbound_lane_congested_threshold..TestCongestionLimits::get().outbound_lane_stop_threshold { + open_lane_and_send_regular_message(OpenBridgeOrigin::sibling_parachain_origin()); + } + assert_eq!(XcmOverBridge::bridge(&bridge_id).unwrap().state, BridgeState::Suspended(false)); }); } @@ -497,15 +521,15 @@ mod tests { let (bridge_id, lane_id) = open_lane_and_send_regular_message(OpenBridgeOrigin::sibling_parachain_origin()); Bridges::::mutate_extant(bridge_id, |bridge| { - bridge.state = BridgeState::Suspended; + bridge.state = BridgeState::Suspended(true); }); XcmOverBridge::on_bridge_messages_delivered( lane_id, - OUTBOUND_LANE_UNCONGESTED_THRESHOLD + 1, + TestCongestionLimits::get().outbound_lane_uncongested_threshold + 1, ); assert!(!TestLocalXcmChannelManager::is_bridge_resumed(&bridge_id)); - assert_eq!(XcmOverBridge::bridge(&bridge_id).unwrap().state, BridgeState::Suspended); + assert_eq!(XcmOverBridge::bridge(&bridge_id).unwrap().state, BridgeState::Suspended(true)); }); } @@ -516,7 +540,7 @@ mod tests { open_lane_and_send_regular_message(OpenBridgeOrigin::sibling_parachain_origin()); XcmOverBridge::on_bridge_messages_delivered( lane_id, - OUTBOUND_LANE_UNCONGESTED_THRESHOLD, + TestCongestionLimits::get().outbound_lane_uncongested_threshold, ); assert!(!TestLocalXcmChannelManager::is_bridge_resumed(&bridge_id)); @@ -530,11 +554,11 @@ mod tests { let (bridge_id, lane_id) = open_lane_and_send_regular_message(OpenBridgeOrigin::sibling_parachain_origin()); Bridges::::mutate_extant(bridge_id, |bridge| { - bridge.state = BridgeState::Suspended; + bridge.state = BridgeState::Suspended(true); }); XcmOverBridge::on_bridge_messages_delivered( lane_id, - OUTBOUND_LANE_UNCONGESTED_THRESHOLD, + TestCongestionLimits::get().outbound_lane_uncongested_threshold, ); assert!(TestLocalXcmChannelManager::is_bridge_resumed(&bridge_id)); @@ -813,7 +837,7 @@ mod tests { ); // ok - let _ = open_lane(OpenBridgeOrigin::sibling_parachain_origin()); + let (locations, _) = open_lane(OpenBridgeOrigin::sibling_parachain_origin()); let mut dest_wrapper = Some(bridged_relative_destination()); assert_ok!(XcmOverBridge::validate( BridgedRelayNetwork::get(), @@ -826,6 +850,48 @@ mod tests { assert_eq!(None, xcm_wrapper); assert_eq!(&Some(universal_source()), &universal_source_wrapper); assert_eq!(None, dest_wrapper); + + // send more messages to reach `outbound_lane_congested_threshold` + for _ in 0..=TestCongestionLimits::get().outbound_lane_congested_threshold { + open_lane_and_send_regular_message(OpenBridgeOrigin::sibling_parachain_origin()); + } + // bridge is suspended but exporter accepts more messages + assert_eq!( + XcmOverBridge::bridge(locations.bridge_id()).unwrap().state, + BridgeState::Suspended(true) + ); + + // export still can accept more messages + assert_ok!(XcmOverBridge::validate( + BridgedRelayNetwork::get(), + 0, + &mut Some(universal_source()), + &mut Some(bridged_relative_destination()), + &mut Some(xcm.clone()), + )); + + // send more messages to reach `outbound_lane_stop_threshold` + for _ in TestCongestionLimits::get().outbound_lane_congested_threshold..TestCongestionLimits::get().outbound_lane_stop_threshold { + open_lane_and_send_regular_message(OpenBridgeOrigin::sibling_parachain_origin()); + } + + // bridge is suspended but exporter CANNOT accept more messages + assert_eq!( + XcmOverBridge::bridge(locations.bridge_id()).unwrap().state, + BridgeState::Suspended(false) + ); + + // export still can accept more messages + assert_err!( + XcmOverBridge::validate( + BridgedRelayNetwork::get(), + 0, + &mut Some(universal_source()), + &mut Some(bridged_relative_destination()), + &mut Some(xcm.clone()), + ), + SendError::Transport("Exporter is suspended!"), + ); }); } @@ -890,7 +956,7 @@ mod tests { assert!(!TestLocalXcmChannelManager::is_bridge_resumed(bridge_2.bridge_id())); // make bridges congested with sending too much messages - for _ in 1..(OUTBOUND_LANE_CONGESTED_THRESHOLD + 2) { + for _ in 1..(TestCongestionLimits::get().outbound_lane_congested_threshold + 2) { // send `ExportMessage(message)` by `pallet_xcm_bridge_hub_router`. ExecuteXcmOverSendXcm::set_origin_for_execute(origin_as_location.clone()); assert_ok!(send_xcm::( @@ -909,11 +975,11 @@ mod tests { // bridges are suspended assert_eq!( XcmOverBridge::bridge(bridge_1.bridge_id()).unwrap().state, - BridgeState::Suspended + BridgeState::Suspended(true) ); assert_eq!( XcmOverBridge::bridge(bridge_2.bridge_id()).unwrap().state, - BridgeState::Suspended + BridgeState::Suspended(true) ); // both routers are congested assert!( @@ -937,11 +1003,11 @@ mod tests { // make bridges uncongested to trigger resume signal XcmOverBridge::on_bridge_messages_delivered( expected_lane_id_1, - OUTBOUND_LANE_UNCONGESTED_THRESHOLD, + TestCongestionLimits::get().outbound_lane_uncongested_threshold, ); XcmOverBridge::on_bridge_messages_delivered( expected_lane_id_2, - OUTBOUND_LANE_UNCONGESTED_THRESHOLD, + TestCongestionLimits::get().outbound_lane_uncongested_threshold, ); // bridges are again opened diff --git a/bridges/modules/xcm-bridge-hub/src/lib.rs b/bridges/modules/xcm-bridge-hub/src/lib.rs index 05f86e008f34..435a6d273abc 100644 --- a/bridges/modules/xcm-bridge-hub/src/lib.rs +++ b/bridges/modules/xcm-bridge-hub/src/lib.rs @@ -253,6 +253,8 @@ pub mod pallet { type LocalXcmChannelManager: LocalXcmChannelManager; /// XCM-level dispatcher for inbound bridge messages. type BlobDispatcher: DispatchBlob + DispatchChannelStatusProvider; + /// Limits for handling congestion. + type CongestionLimits: Get; } /// An alias for the bridge metadata. @@ -278,9 +280,14 @@ pub mod pallet { fn integrity_test() { assert!( Self::bridged_network_id().is_ok(), - "Configured `T::BridgedNetwork`: {:?} does not contain `GlobalConsensus` junction with `NetworkId`", + "Configured `T::BridgedNetwork`: {:?} does not contain `GlobalConsensus` junction with `NetworkId`!", T::BridgedNetwork::get() - ) + ); + assert!( + T::CongestionLimits::get().is_valid(), + "Configured `T::CongestionLimits`: {:?} are not valid!", + T::CongestionLimits::get() + ); } #[cfg(feature = "try-runtime")] diff --git a/bridges/modules/xcm-bridge-hub/src/mock.rs b/bridges/modules/xcm-bridge-hub/src/mock.rs index f5d679067edc..6d4569e2ac7f 100644 --- a/bridges/modules/xcm-bridge-hub/src/mock.rs +++ b/bridges/modules/xcm-bridge-hub/src/mock.rs @@ -17,7 +17,6 @@ #![cfg(test)] use crate as pallet_xcm_bridge_hub; -use crate::congestion::BlobDispatcherWithChannelStatus; use bp_messages::{ target_chain::{DispatchMessage, MessageDispatch}, ChainWithMessages, HashedLaneId, MessageNonce, @@ -32,6 +31,7 @@ use frame_support::{ }; use frame_system::{EnsureNever, EnsureRoot, EnsureRootWithSuccess}; use pallet_xcm_bridge_hub::congestion::{ + BlobDispatcherWithChannelStatus, CongestionLimits, HereOrLocalConsensusXcmChannelManager, ReportBridgeStatusXcmChannelManager, }; use polkadot_parachain_primitives::primitives::Sibling; @@ -185,6 +185,7 @@ parameter_types! { ) ]; pub UnitWeightCost: Weight = Weight::from_parts(10, 10); + pub storage TestCongestionLimits: CongestionLimits = CongestionLimits::default(); } /// **Universal** `InteriorLocation` of bridged asset hub. @@ -233,8 +234,8 @@ impl pallet_xcm_bridge_hub::Config for TestRuntime { type AllowWithoutBridgeDeposit = (Equals, Equals); type LocalXcmChannelManager = TestLocalXcmChannelManager; - type BlobDispatcher = BlobDispatcherWithChannelStatus; + type CongestionLimits = TestCongestionLimits; } #[cfg(feature = "runtime-benchmarks")] diff --git a/bridges/primitives/xcm-bridge-hub/src/lib.rs b/bridges/primitives/xcm-bridge-hub/src/lib.rs index 719e7439cfa7..9ead702dbc80 100644 --- a/bridges/primitives/xcm-bridge-hub/src/lib.rs +++ b/bridges/primitives/xcm-bridge-hub/src/lib.rs @@ -144,10 +144,10 @@ pub enum BridgeState { /// Bridge is opened. Associated lanes are also opened. Opened, /// Bridge is suspended. Associated lanes are opened. + /// *suspended* means that we have sent the "Suspended" message/signal to the local bridge origin. /// - /// We keep accepting messages to the bridge. The only difference with the `Opened` state - /// is that we have sent the "Suspended" message/signal to the local bridge origin. - Suspended, + /// `bool` - `true` means that we keep accepting messages to the bridge. + Suspended(bool), /// Bridge is closed. Associated lanes are also closed. /// After all outbound messages will be pruned, the bridge will vanish without any traces. Closed, diff --git a/prdoc/pr_6231.prdoc b/prdoc/pr_6231.prdoc index 2e88dbde4016..f883447a16a9 100644 --- a/prdoc/pr_6231.prdoc +++ b/prdoc/pr_6231.prdoc @@ -7,7 +7,7 @@ doc: ## Description TBD: - ## TODO + ## FAIL-CI - [ ] backport to the stable-2024-09-3 till 11.Nov crates: - name: pallet-xcm-bridge-hub-router @@ -27,14 +27,18 @@ crates: - name: bridge-hub-westend-runtime bump: patch - name: asset-test-utils - bump: patch + bump: major - name: cumulus-pallet-xcmp-queue bump: patch - name: bridge-hub-test-utils - bump: patch + bump: major - name: emulated-integration-tests-common bump: patch - name: bp-asset-hub-rococo - bump: patch + bump: major - name: bp-asset-hub-westend + bump: major +- name: bp-bridge-hub-rococo + bump: patch +- name: bp-bridge-hub-westend bump: patch \ No newline at end of file From fbcacb0333550aabc1b53173535bd3c243a21f3c Mon Sep 17 00:00:00 2001 From: GitHub Action Date: Mon, 11 Nov 2024 13:03:03 +0000 Subject: [PATCH 52/72] Update from bkontur running command 'fmt' --- .../modules/xcm-bridge-hub/src/congestion.rs | 4 +- .../modules/xcm-bridge-hub/src/exporter.rs | 52 +++++++++++++------ bridges/modules/xcm-bridge-hub/src/mock.rs | 4 +- bridges/primitives/xcm-bridge-hub/src/lib.rs | 3 +- 4 files changed, 43 insertions(+), 20 deletions(-) diff --git a/bridges/modules/xcm-bridge-hub/src/congestion.rs b/bridges/modules/xcm-bridge-hub/src/congestion.rs index 95cf9ed1df7f..7d588f8407bb 100644 --- a/bridges/modules/xcm-bridge-hub/src/congestion.rs +++ b/bridges/modules/xcm-bridge-hub/src/congestion.rs @@ -41,8 +41,8 @@ pub struct CongestionLimits { impl CongestionLimits { /// Checks if limits are valid. pub fn is_valid(&self) -> bool { - self.outbound_lane_uncongested_threshold < self.outbound_lane_congested_threshold - && self.outbound_lane_stop_threshold > self.outbound_lane_congested_threshold + self.outbound_lane_uncongested_threshold < self.outbound_lane_congested_threshold && + self.outbound_lane_stop_threshold > self.outbound_lane_congested_threshold } } diff --git a/bridges/modules/xcm-bridge-hub/src/exporter.rs b/bridges/modules/xcm-bridge-hub/src/exporter.rs index ba9efac10a16..b5f0c64ea6f2 100644 --- a/bridges/modules/xcm-bridge-hub/src/exporter.rs +++ b/bridges/modules/xcm-bridge-hub/src/exporter.rs @@ -144,7 +144,8 @@ where message, )?; - // Here, we know that the message is relevant to this pallet instance, so let's check for congestion defense. + // Here, we know that the message is relevant to this pallet instance, so let's check for + // congestion defense. if bridge.state == BridgeState::Suspended(false) { log::error!( target: LOG_TARGET, @@ -218,7 +219,8 @@ impl, I: 'static> Pallet { enqueued_messages: MessageNonce, ) { // if the bridge queue is not congested, we don't want to do anything - let is_congested = enqueued_messages > T::CongestionLimits::get().outbound_lane_congested_threshold; + let is_congested = + enqueued_messages > T::CongestionLimits::get().outbound_lane_congested_threshold; if !is_congested { return } @@ -227,23 +229,26 @@ impl, I: 'static> Pallet { match bridge.state { BridgeState::Suspended(true) => { if enqueued_messages > T::CongestionLimits::get().outbound_lane_stop_threshold { - // If its suspended and reached `outbound_lane_stop_threshold`, we stop accepting new messages (a.k.a. start dropping). + // If its suspended and reached `outbound_lane_stop_threshold`, we stop + // accepting new messages (a.k.a. start dropping). Bridges::::mutate_extant(bridge_id, |bridge| { bridge.state = BridgeState::Suspended(false); }); return } else { - // We still can accept new messages to the suspended bridge, hoping that it'll be actually resumed soon + // We still can accept new messages to the suspended bridge, hoping that it'll + // be actually resumed soon return } - } + }, BridgeState::Suspended(false) => { - // We cannot accept new messages to the suspended bridge, hoping that it'll be actually resumed soon + // We cannot accept new messages to the suspended bridge, hoping that it'll be + // actually resumed soon return - } + }, _ => { // do nothing and continue - } + }, } // else - suspend the bridge @@ -294,7 +299,8 @@ impl, I: 'static> Pallet { /// Must be called whenever we receive a message delivery confirmation. fn on_bridge_messages_delivered(lane_id: T::LaneId, enqueued_messages: MessageNonce) { // if the bridge queue is still congested, we don't want to do anything - let is_congested = enqueued_messages > T::CongestionLimits::get().outbound_lane_uncongested_threshold; + let is_congested = + enqueued_messages > T::CongestionLimits::get().outbound_lane_uncongested_threshold; if is_congested { return } @@ -302,7 +308,10 @@ impl, I: 'static> Pallet { // if we have not suspended the bridge before (or it is closed), we don't want to do // anything let (bridge_id, bridge) = match Self::bridge_by_lane_id(&lane_id) { - Some(bridge) if bridge.1.state == BridgeState::Suspended(true) || bridge.1.state == BridgeState::Suspended(false) => bridge, + Some(bridge) + if bridge.1.state == BridgeState::Suspended(true) || + bridge.1.state == BridgeState::Suspended(false) => + bridge, _ => { // if there is no bridge or it has been closed, then we don't need to send resume // signal to the local origin - it has closed bridge itself, so it should have @@ -505,13 +514,21 @@ mod tests { open_lane_and_send_regular_message(OpenBridgeOrigin::sibling_parachain_origin()); assert!(TestLocalXcmChannelManager::is_bridge_suspened(&bridge_id)); - assert_eq!(XcmOverBridge::bridge(&bridge_id).unwrap().state, BridgeState::Suspended(true)); + assert_eq!( + XcmOverBridge::bridge(&bridge_id).unwrap().state, + BridgeState::Suspended(true) + ); // send more messages to reach `outbound_lane_stop_threshold` - for _ in TestCongestionLimits::get().outbound_lane_congested_threshold..TestCongestionLimits::get().outbound_lane_stop_threshold { + for _ in TestCongestionLimits::get().outbound_lane_congested_threshold.. + TestCongestionLimits::get().outbound_lane_stop_threshold + { open_lane_and_send_regular_message(OpenBridgeOrigin::sibling_parachain_origin()); } - assert_eq!(XcmOverBridge::bridge(&bridge_id).unwrap().state, BridgeState::Suspended(false)); + assert_eq!( + XcmOverBridge::bridge(&bridge_id).unwrap().state, + BridgeState::Suspended(false) + ); }); } @@ -529,7 +546,10 @@ mod tests { ); assert!(!TestLocalXcmChannelManager::is_bridge_resumed(&bridge_id)); - assert_eq!(XcmOverBridge::bridge(&bridge_id).unwrap().state, BridgeState::Suspended(true)); + assert_eq!( + XcmOverBridge::bridge(&bridge_id).unwrap().state, + BridgeState::Suspended(true) + ); }); } @@ -871,7 +891,9 @@ mod tests { )); // send more messages to reach `outbound_lane_stop_threshold` - for _ in TestCongestionLimits::get().outbound_lane_congested_threshold..TestCongestionLimits::get().outbound_lane_stop_threshold { + for _ in TestCongestionLimits::get().outbound_lane_congested_threshold.. + TestCongestionLimits::get().outbound_lane_stop_threshold + { open_lane_and_send_regular_message(OpenBridgeOrigin::sibling_parachain_origin()); } diff --git a/bridges/modules/xcm-bridge-hub/src/mock.rs b/bridges/modules/xcm-bridge-hub/src/mock.rs index 6d4569e2ac7f..2b638ba3eb7d 100644 --- a/bridges/modules/xcm-bridge-hub/src/mock.rs +++ b/bridges/modules/xcm-bridge-hub/src/mock.rs @@ -31,8 +31,8 @@ use frame_support::{ }; use frame_system::{EnsureNever, EnsureRoot, EnsureRootWithSuccess}; use pallet_xcm_bridge_hub::congestion::{ - BlobDispatcherWithChannelStatus, CongestionLimits, - HereOrLocalConsensusXcmChannelManager, ReportBridgeStatusXcmChannelManager, + BlobDispatcherWithChannelStatus, CongestionLimits, HereOrLocalConsensusXcmChannelManager, + ReportBridgeStatusXcmChannelManager, }; use polkadot_parachain_primitives::primitives::Sibling; use sp_core::H256; diff --git a/bridges/primitives/xcm-bridge-hub/src/lib.rs b/bridges/primitives/xcm-bridge-hub/src/lib.rs index 9ead702dbc80..7511f3c7e3bd 100644 --- a/bridges/primitives/xcm-bridge-hub/src/lib.rs +++ b/bridges/primitives/xcm-bridge-hub/src/lib.rs @@ -144,7 +144,8 @@ pub enum BridgeState { /// Bridge is opened. Associated lanes are also opened. Opened, /// Bridge is suspended. Associated lanes are opened. - /// *suspended* means that we have sent the "Suspended" message/signal to the local bridge origin. + /// *suspended* means that we have sent the "Suspended" message/signal to the local bridge + /// origin. /// /// `bool` - `true` means that we keep accepting messages to the bridge. Suspended(bool), From 9e11db59fde4e3793f388233fe757810213b5bfd Mon Sep 17 00:00:00 2001 From: Branislav Kontur Date: Mon, 11 Nov 2024 18:48:49 +0100 Subject: [PATCH 53/72] Fix --- .../bridge-hub-rococo/src/bridge_to_bulletin_config.rs | 1 + .../bridge-hub-rococo/src/bridge_to_westend_config.rs | 1 + .../bridge-hub-westend/src/bridge_to_rococo_config.rs | 1 + 3 files changed, 3 insertions(+) diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_bulletin_config.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_bulletin_config.rs index 42b92453f85f..38792b88eee3 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_bulletin_config.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_bulletin_config.rs @@ -161,6 +161,7 @@ impl pallet_xcm_bridge_hub::Config for Runtime // no congestion checking (), >; + type CongestionLimits = (); } #[cfg(test)] diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_westend_config.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_westend_config.rs index 9ed27670bfe0..3e5b73d258dd 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_westend_config.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/bridge_to_westend_config.rs @@ -192,6 +192,7 @@ impl pallet_xcm_bridge_hub::Config for Runtime // be dispatched to the sibling. cumulus_pallet_xcmp_queue::bridging::OutXcmpChannelStatusProvider, >; + type CongestionLimits = (); } #[cfg(test)] diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/bridge_to_rococo_config.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/bridge_to_rococo_config.rs index 3f81d6dc839c..bccd2dced40e 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/bridge_to_rococo_config.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/bridge_to_rococo_config.rs @@ -221,6 +221,7 @@ impl pallet_xcm_bridge_hub::Config for Runtime { // be dispatched to the sibling. cumulus_pallet_xcmp_queue::bridging::OutXcmpChannelStatusProvider, >; + type CongestionLimits = (); } #[cfg(test)] From 6513057e932e37cf30705babe4bf74e523b674b9 Mon Sep 17 00:00:00 2001 From: Branislav Kontur Date: Mon, 11 Nov 2024 22:43:23 +0100 Subject: [PATCH 54/72] Fix --- .../modules/xcm-bridge-hub/src/congestion.rs | 2 +- .../modules/xcm-bridge-hub/src/exporter.rs | 101 +++++++++++++++++- 2 files changed, 101 insertions(+), 2 deletions(-) diff --git a/bridges/modules/xcm-bridge-hub/src/congestion.rs b/bridges/modules/xcm-bridge-hub/src/congestion.rs index 7d588f8407bb..a415b2565dc5 100644 --- a/bridges/modules/xcm-bridge-hub/src/congestion.rs +++ b/bridges/modules/xcm-bridge-hub/src/congestion.rs @@ -51,7 +51,7 @@ impl Default for CongestionLimits { Self { outbound_lane_congested_threshold: 8_192, outbound_lane_uncongested_threshold: 1_024, - outbound_lane_stop_threshold: 9216, + outbound_lane_stop_threshold: 12_288, } } } diff --git a/bridges/modules/xcm-bridge-hub/src/exporter.rs b/bridges/modules/xcm-bridge-hub/src/exporter.rs index b5f0c64ea6f2..9272dec998a3 100644 --- a/bridges/modules/xcm-bridge-hub/src/exporter.rs +++ b/bridges/modules/xcm-bridge-hub/src/exporter.rs @@ -247,7 +247,7 @@ impl, I: 'static> Pallet { return }, _ => { - // do nothing and continue + // otherwise, continue handling the suspension }, } @@ -302,6 +302,17 @@ impl, I: 'static> Pallet { let is_congested = enqueued_messages > T::CongestionLimits::get().outbound_lane_uncongested_threshold; if is_congested { + // and if it is bellow the `stop_threshold` + if enqueued_messages < T::CongestionLimits::get().outbound_lane_stop_threshold { + if let Some((bridge_id, bridge)) = Self::bridge_by_lane_id(&lane_id) { + if let BridgeState::Suspended(false) = bridge.state { + // we allow exporting again + Bridges::::mutate_extant(bridge_id, |b| { + b.state = BridgeState::Suspended(true); + }); + } + } + } return } @@ -568,6 +579,94 @@ mod tests { }); } + #[test] + fn exporter_respects_stop_threshold() { + run_test(|| { + let (bridge_id, lane_id) = + open_lane_and_send_regular_message(OpenBridgeOrigin::sibling_parachain_origin()); + let xcm: Xcm<()> = vec![ClearOrigin].into(); + + // Opened - exporter works + assert_eq!(XcmOverBridge::bridge(&bridge_id).unwrap().state, BridgeState::Opened); + assert_ok!( + XcmOverBridge::validate( + BridgedRelayNetwork::get(), + 0, + &mut Some(universal_source()), + &mut Some(bridged_relative_destination()), + &mut Some(xcm.clone()), + ), + ); + + // Suspended(true) - exporter still works + XcmOverBridge::on_bridge_message_enqueued( + bridge_id, + XcmOverBridge::bridge(&bridge_id).unwrap(), + TestCongestionLimits::get().outbound_lane_congested_threshold + 1, + ); + assert_eq!(XcmOverBridge::bridge(&bridge_id).unwrap().state, BridgeState::Suspended(true)); + assert_ok!( + XcmOverBridge::validate( + BridgedRelayNetwork::get(), + 0, + &mut Some(universal_source()), + &mut Some(bridged_relative_destination()), + &mut Some(xcm.clone()), + ), + ); + + // Suspended(false) - exporter stops working + XcmOverBridge::on_bridge_message_enqueued( + bridge_id, + XcmOverBridge::bridge(&bridge_id).unwrap(), + TestCongestionLimits::get().outbound_lane_stop_threshold + 1, + ); + assert_eq!(XcmOverBridge::bridge(&bridge_id).unwrap().state, BridgeState::Suspended(false)); + assert_err!( + XcmOverBridge::validate( + BridgedRelayNetwork::get(), + 0, + &mut Some(universal_source()), + &mut Some(bridged_relative_destination()), + &mut Some(xcm.clone()), + ), + SendError::Transport("Exporter is suspended!"), + ); + + // Back to Suspended(true) - exporter again works + XcmOverBridge::on_bridge_messages_delivered( + lane_id, + TestCongestionLimits::get().outbound_lane_stop_threshold - 1, + ); + assert_eq!(XcmOverBridge::bridge(&bridge_id).unwrap().state, BridgeState::Suspended(true)); + assert_ok!( + XcmOverBridge::validate( + BridgedRelayNetwork::get(), + 0, + &mut Some(universal_source()), + &mut Some(bridged_relative_destination()), + &mut Some(xcm.clone()), + ), + ); + + // Back to Opened - exporter works + XcmOverBridge::on_bridge_messages_delivered( + lane_id, + TestCongestionLimits::get().outbound_lane_uncongested_threshold - 1, + ); + assert_eq!(XcmOverBridge::bridge(&bridge_id).unwrap().state, BridgeState::Opened); + assert_ok!( + XcmOverBridge::validate( + BridgedRelayNetwork::get(), + 0, + &mut Some(universal_source()), + &mut Some(bridged_relative_destination()), + &mut Some(xcm.clone()), + ), + ); + }); + } + #[test] fn bridge_is_resumed_when_enough_messages_are_delivered() { run_test(|| { From 31045aabf7abfb60e3030eb9ca7cbc78198c1131 Mon Sep 17 00:00:00 2001 From: GitHub Action Date: Mon, 11 Nov 2024 21:46:32 +0000 Subject: [PATCH 55/72] Update from bkontur running command 'fmt' --- .../modules/xcm-bridge-hub/src/exporter.rs | 75 ++++++++++--------- 1 file changed, 38 insertions(+), 37 deletions(-) diff --git a/bridges/modules/xcm-bridge-hub/src/exporter.rs b/bridges/modules/xcm-bridge-hub/src/exporter.rs index 9272dec998a3..134a5c3ad804 100644 --- a/bridges/modules/xcm-bridge-hub/src/exporter.rs +++ b/bridges/modules/xcm-bridge-hub/src/exporter.rs @@ -588,15 +588,13 @@ mod tests { // Opened - exporter works assert_eq!(XcmOverBridge::bridge(&bridge_id).unwrap().state, BridgeState::Opened); - assert_ok!( - XcmOverBridge::validate( - BridgedRelayNetwork::get(), - 0, - &mut Some(universal_source()), - &mut Some(bridged_relative_destination()), - &mut Some(xcm.clone()), - ), - ); + assert_ok!(XcmOverBridge::validate( + BridgedRelayNetwork::get(), + 0, + &mut Some(universal_source()), + &mut Some(bridged_relative_destination()), + &mut Some(xcm.clone()), + ),); // Suspended(true) - exporter still works XcmOverBridge::on_bridge_message_enqueued( @@ -604,16 +602,17 @@ mod tests { XcmOverBridge::bridge(&bridge_id).unwrap(), TestCongestionLimits::get().outbound_lane_congested_threshold + 1, ); - assert_eq!(XcmOverBridge::bridge(&bridge_id).unwrap().state, BridgeState::Suspended(true)); - assert_ok!( - XcmOverBridge::validate( - BridgedRelayNetwork::get(), - 0, - &mut Some(universal_source()), - &mut Some(bridged_relative_destination()), - &mut Some(xcm.clone()), - ), + assert_eq!( + XcmOverBridge::bridge(&bridge_id).unwrap().state, + BridgeState::Suspended(true) ); + assert_ok!(XcmOverBridge::validate( + BridgedRelayNetwork::get(), + 0, + &mut Some(universal_source()), + &mut Some(bridged_relative_destination()), + &mut Some(xcm.clone()), + ),); // Suspended(false) - exporter stops working XcmOverBridge::on_bridge_message_enqueued( @@ -621,7 +620,10 @@ mod tests { XcmOverBridge::bridge(&bridge_id).unwrap(), TestCongestionLimits::get().outbound_lane_stop_threshold + 1, ); - assert_eq!(XcmOverBridge::bridge(&bridge_id).unwrap().state, BridgeState::Suspended(false)); + assert_eq!( + XcmOverBridge::bridge(&bridge_id).unwrap().state, + BridgeState::Suspended(false) + ); assert_err!( XcmOverBridge::validate( BridgedRelayNetwork::get(), @@ -638,16 +640,17 @@ mod tests { lane_id, TestCongestionLimits::get().outbound_lane_stop_threshold - 1, ); - assert_eq!(XcmOverBridge::bridge(&bridge_id).unwrap().state, BridgeState::Suspended(true)); - assert_ok!( - XcmOverBridge::validate( - BridgedRelayNetwork::get(), - 0, - &mut Some(universal_source()), - &mut Some(bridged_relative_destination()), - &mut Some(xcm.clone()), - ), + assert_eq!( + XcmOverBridge::bridge(&bridge_id).unwrap().state, + BridgeState::Suspended(true) ); + assert_ok!(XcmOverBridge::validate( + BridgedRelayNetwork::get(), + 0, + &mut Some(universal_source()), + &mut Some(bridged_relative_destination()), + &mut Some(xcm.clone()), + ),); // Back to Opened - exporter works XcmOverBridge::on_bridge_messages_delivered( @@ -655,15 +658,13 @@ mod tests { TestCongestionLimits::get().outbound_lane_uncongested_threshold - 1, ); assert_eq!(XcmOverBridge::bridge(&bridge_id).unwrap().state, BridgeState::Opened); - assert_ok!( - XcmOverBridge::validate( - BridgedRelayNetwork::get(), - 0, - &mut Some(universal_source()), - &mut Some(bridged_relative_destination()), - &mut Some(xcm.clone()), - ), - ); + assert_ok!(XcmOverBridge::validate( + BridgedRelayNetwork::get(), + 0, + &mut Some(universal_source()), + &mut Some(bridged_relative_destination()), + &mut Some(xcm.clone()), + ),); }); } From 8a7eb9a306c6c6dd261fffa4fe9ed5cc9628c2a1 Mon Sep 17 00:00:00 2001 From: Branislav Kontur Date: Mon, 11 Nov 2024 22:54:50 +0100 Subject: [PATCH 56/72] Forgotten prdoc --- prdoc/pr_6231.prdoc | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/prdoc/pr_6231.prdoc b/prdoc/pr_6231.prdoc index f883447a16a9..d9db5bd25b4d 100644 --- a/prdoc/pr_6231.prdoc +++ b/prdoc/pr_6231.prdoc @@ -2,13 +2,14 @@ title: Bridges - revert-back and improve congestion doc: - audience: Runtime Dev description: |- - Closes: https://github.com/paritytech/polkadot-sdk/issues/5551 + This release introduces an enhanced bridge congestion mechanism, decoupling bridge queues from XCMP and improving suspension handling with bridge-specific channel control. + Using `BridgeId`, `pallet-xcm-bridge-hub` and `pallet-xcm-bridge-hub-router` now support selective suspension and resumption of individual bridges. + A new congestion detection feature in `pallet-xcm-bridge-hub` triggers `fn suspend_bridge` and `fn resume_bridge` callbacks: + if the router is on a sibling chain, it sends `xcm::Transact(report_bridge_status(bridge_id, is_congested))` using stored callback data, while on local chains, it directly manages state. + Additionally, a new `stop_threshold` in `pallet-xcm-bridge-hub` enables or disables `ExportXcm::validate`, acting as a safeguard if the router ignores the `suspend` signal. + Finally, `pallet-xcm-bridge-hub-router` now flexibly supports message routing to either sibling chains (`ExportMessage`) or local deployments (`ExportXcm`), + enhancing modularity and compatibility across deployment setups. - ## Description - TBD: - - ## FAIL-CI - - [ ] backport to the stable-2024-09-3 till 11.Nov crates: - name: pallet-xcm-bridge-hub-router bump: major From cd92d5e354ebf9906c9d1aac31ed100c4ba6cb58 Mon Sep 17 00:00:00 2001 From: Branislav Kontur Date: Thu, 14 Nov 2024 10:16:07 +0100 Subject: [PATCH 57/72] Update bridges/modules/xcm-bridge-hub/src/benchmarking.rs Co-authored-by: Francisco Aguirre --- bridges/modules/xcm-bridge-hub/src/benchmarking.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bridges/modules/xcm-bridge-hub/src/benchmarking.rs b/bridges/modules/xcm-bridge-hub/src/benchmarking.rs index 31846867b999..eeeed993c55c 100644 --- a/bridges/modules/xcm-bridge-hub/src/benchmarking.rs +++ b/bridges/modules/xcm-bridge-hub/src/benchmarking.rs @@ -37,7 +37,7 @@ pub struct Pallet, I: 'static = ()>(crate::Pallet); /// Trait that must be implemented by runtime to be able to benchmark pallet properly. pub trait Config: crate::Config { - /// Returns a valida origin along with the initial balance (e.g., existential deposit), + /// Returns a valid origin along with the initial balance (e.g., existential deposit), /// required for operation `open_bridge`. /// If `None`, that means that `open_bridge` is not supported. fn open_bridge_origin() -> Option<(Self::RuntimeOrigin, BalanceOf>)>; From 4b6deb9f2731a8f58ad1573f3cc3cd8be21c55bb Mon Sep 17 00:00:00 2001 From: Branislav Kontur Date: Thu, 14 Nov 2024 10:17:30 +0100 Subject: [PATCH 58/72] Update bridges/modules/xcm-bridge-hub-router/src/lib.rs Co-authored-by: Francisco Aguirre --- bridges/modules/xcm-bridge-hub-router/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bridges/modules/xcm-bridge-hub-router/src/lib.rs b/bridges/modules/xcm-bridge-hub-router/src/lib.rs index 1a371de05983..1daef3a07970 100644 --- a/bridges/modules/xcm-bridge-hub-router/src/lib.rs +++ b/bridges/modules/xcm-bridge-hub-router/src/lib.rs @@ -58,7 +58,7 @@ //! **Note on Terminology**: When we refer to the bridge hub, we mean the chain that has the //! `pallet-bridge-messages` with an `ExportXcm` implementation deployed, such as //! `pallet-xcm-bridge-hub`. Depending on the deployment setup, `T::ToBridgeHubSender` can be -//! configured accordingly—see `T::ToBridgeHubSender` for additional documentation. +//! configured accordingly — see `T::ToBridgeHubSender` for additional documentation. #![cfg_attr(not(feature = "std"), no_std)] From ac092d379440459b40b240eb27be057c08f5bb93 Mon Sep 17 00:00:00 2001 From: Branislav Kontur Date: Thu, 14 Nov 2024 10:18:01 +0100 Subject: [PATCH 59/72] Update bridges/modules/xcm-bridge-hub-router/src/impls.rs Co-authored-by: Francisco Aguirre --- bridges/modules/xcm-bridge-hub-router/src/impls.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/bridges/modules/xcm-bridge-hub-router/src/impls.rs b/bridges/modules/xcm-bridge-hub-router/src/impls.rs index c6431e1215d6..8554fa04104a 100644 --- a/bridges/modules/xcm-bridge-hub-router/src/impls.rs +++ b/bridges/modules/xcm-bridge-hub-router/src/impls.rs @@ -15,6 +15,7 @@ // along with Parity Bridges Common. If not, see . //! Various implementations supporting easier configuration of the pallet. + use crate::{BridgeIdOf, Bridges, Config, Pallet, LOG_TARGET}; use bp_xcm_bridge_hub_router::ResolveBridgeId; use codec::Encode; From 393cded97cd352f69037f090b222eddc54d371ef Mon Sep 17 00:00:00 2001 From: Branislav Kontur Date: Thu, 14 Nov 2024 10:18:42 +0100 Subject: [PATCH 60/72] Update bridges/modules/xcm-bridge-hub-router/src/impls.rs Co-authored-by: Francisco Aguirre --- bridges/modules/xcm-bridge-hub-router/src/impls.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bridges/modules/xcm-bridge-hub-router/src/impls.rs b/bridges/modules/xcm-bridge-hub-router/src/impls.rs index 8554fa04104a..8f2c5c08a4eb 100644 --- a/bridges/modules/xcm-bridge-hub-router/src/impls.rs +++ b/bridges/modules/xcm-bridge-hub-router/src/impls.rs @@ -234,7 +234,7 @@ impl, I: 'static, E: SendXcm> SendXcm for ViaLocalBridgeHubExporter // return original ticket with possibly extended fees Ok((ticket, fees)) }, - e => e, + error => error, } } From bdb8c8ab9af6804c9277ec9abbdc6b1ab60067f8 Mon Sep 17 00:00:00 2001 From: Branislav Kontur Date: Thu, 14 Nov 2024 10:22:55 +0100 Subject: [PATCH 61/72] Removed `sp_tracing::try_init_simple` --- bridges/modules/relayers/src/extension/mod.rs | 2 -- bridges/modules/xcm-bridge-hub-router/src/impls.rs | 2 -- 2 files changed, 4 deletions(-) diff --git a/bridges/modules/relayers/src/extension/mod.rs b/bridges/modules/relayers/src/extension/mod.rs index a400aeaee074..f79472d5f55e 100644 --- a/bridges/modules/relayers/src/extension/mod.rs +++ b/bridges/modules/relayers/src/extension/mod.rs @@ -454,7 +454,6 @@ mod tests { use bp_runtime::{BasicOperatingMode, HeaderId, Parachain}; use bp_test_utils::{make_default_justification, test_keyring, TEST_GRANDPA_SET_ID}; use frame_support::{ - __private::sp_tracing, assert_storage_noop, parameter_types, traits::{fungible::Mutate, ReservableCurrency}, weights::Weight, @@ -1124,7 +1123,6 @@ mod tests { Option>, TransactionValidityError, > { - sp_tracing::try_init_simple(); let extension: TestExtension = BridgeRelayersTransactionExtension(PhantomData); extension .validate_and_prepare( diff --git a/bridges/modules/xcm-bridge-hub-router/src/impls.rs b/bridges/modules/xcm-bridge-hub-router/src/impls.rs index 8f2c5c08a4eb..a61630d8d28a 100644 --- a/bridges/modules/xcm-bridge-hub-router/src/impls.rs +++ b/bridges/modules/xcm-bridge-hub-router/src/impls.rs @@ -314,11 +314,9 @@ impl> ResolveBridgeId #[cfg(test)] mod tests { use super::*; - use frame_support::__private::sp_tracing; #[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]); From b8efb0be18cc683755843f656f1e7762d26291c0 Mon Sep 17 00:00:00 2001 From: Branislav Kontur Date: Thu, 14 Nov 2024 10:32:45 +0100 Subject: [PATCH 62/72] Update bridges/modules/xcm-bridge-hub-router/src/lib.rs Co-authored-by: Francisco Aguirre --- bridges/modules/xcm-bridge-hub-router/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bridges/modules/xcm-bridge-hub-router/src/lib.rs b/bridges/modules/xcm-bridge-hub-router/src/lib.rs index 1daef3a07970..b183cac9a40f 100644 --- a/bridges/modules/xcm-bridge-hub-router/src/lib.rs +++ b/bridges/modules/xcm-bridge-hub-router/src/lib.rs @@ -191,7 +191,7 @@ pub mod pallet { for (bridge_id, mut bridge_state) in Bridges::::iter() { weight_used.saturating_accrue(T::DbWeight::get().reads(1)); - // if not congested anymore, we can start to decreasing fee factor + // If no longer congested, we can start decreasing the fee factor. if !bridge_state.is_congested { let previous_factor = bridge_state.delivery_fee_factor; let new_factor = previous_factor / EXPONENTIAL_FEE_BASE; From 162c1f68e8203321a8f06a6a7155a3782ed19365 Mon Sep 17 00:00:00 2001 From: Branislav Kontur Date: Thu, 14 Nov 2024 10:42:53 +0100 Subject: [PATCH 63/72] Link types - review comment --- bridges/modules/xcm-bridge-hub-router/src/impls.rs | 14 +++++++------- bridges/modules/xcm-bridge-hub/src/congestion.rs | 10 +++++----- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/bridges/modules/xcm-bridge-hub-router/src/impls.rs b/bridges/modules/xcm-bridge-hub-router/src/impls.rs index a61630d8d28a..29ab44088e52 100644 --- a/bridges/modules/xcm-bridge-hub-router/src/impls.rs +++ b/bridges/modules/xcm-bridge-hub-router/src/impls.rs @@ -23,7 +23,7 @@ use frame_support::{ensure, pallet_prelude::PhantomData, traits::Get}; use xcm::prelude::*; use xcm_builder::{ensure_is_remote, ExporterFor}; -/// Implementation of `LocalXcmChannelManager` which tracks and updates `is_congested` for a given +/// Implementation of [`bp_xcm_bridge_hub::LocalXcmChannelManager`] which tracks and updates `is_congested` for a given /// `BridgeId`. This implementation is useful for managing congestion and dynamic fees with the /// local `ExportXcm` implementation. impl, I: 'static> bp_xcm_bridge_hub::LocalXcmChannelManager> @@ -69,10 +69,10 @@ impl, I: 'static> bp_xcm_bridge_hub::LocalXcmChannelManager(PhantomData<(T, I, E, BNF, BHLF)>); impl, I: 'static, E, BridgedNetworkIdFilter, BridgeHubLocationFilter> ExporterFor @@ -192,10 +192,10 @@ where } } -/// Adapter implementation for `SendXcm` that allows adding a message size fee and/or dynamic fees +/// Adapter implementation for [`SendXcm`] that allows adding a message size fee and/or dynamic fees /// based on the `BridgeId` resolved by the `T::BridgeIdResolver` resolver, if and only if `E` /// supports routing. This adapter can be used, for example, as a wrapper over -/// `UnpaidLocalExporter`, enabling it to compute message and/or dynamic fees using a fee factor. +/// [`xcm_builder::UnpaidLocalExporter`], enabling it to compute message and/or dynamic fees using a fee factor. pub struct ViaLocalBridgeHubExporter(PhantomData<(T, I, E)>); impl, I: 'static, E: SendXcm> SendXcm for ViaLocalBridgeHubExporter { type Ticket = E::Ticket; @@ -243,7 +243,7 @@ impl, I: 'static, E: SendXcm> SendXcm for ViaLocalBridgeHubExporter } } -/// Implementation of `ResolveBridgeId` returning `bp_xcm_bridge_hub::BridgeId` based on the +/// Implementation of [`ResolveBridgeId`] returning [`bp_xcm_bridge_hub::BridgeId`] based on the /// configured `UniversalLocation` and remote universal location. pub struct EnsureIsRemoteBridgeIdResolver(PhantomData); impl> ResolveBridgeId diff --git a/bridges/modules/xcm-bridge-hub/src/congestion.rs b/bridges/modules/xcm-bridge-hub/src/congestion.rs index a415b2565dc5..fed8be1323cf 100644 --- a/bridges/modules/xcm-bridge-hub/src/congestion.rs +++ b/bridges/modules/xcm-bridge-hub/src/congestion.rs @@ -56,7 +56,7 @@ impl Default for CongestionLimits { } } -/// Switches the implementation of `LocalXcmChannelManager` based on the `local_origin`. +/// Switches the implementation of [`LocalXcmChannelManager`] based on the `local_origin`. /// /// - `HereXcmChannelManager` is applied when the origin is `Here`. /// - Otherwise, `LocalConsensusXcmChannelManager` is used. @@ -134,7 +134,7 @@ impl< /// Manages the local XCM channels by sending XCM messages with the `report_bridge_status` extrinsic /// to the `local_origin`. The `XcmProvider` type converts the encoded call to `XCM`, which is then /// sent by `XcmSender` to the `local_origin`. This is useful, for example, when a router with -/// `ExportMessage` is deployed on a different chain, and we want to control congestion by sending +/// [`xcm::prelude::ExportMessage`] is deployed on a different chain, and we want to control congestion by sending /// XCMs. pub struct ReportBridgeStatusXcmChannelManager( PhantomData<(T, I, XcmProvider, XcmSender)>, @@ -208,9 +208,9 @@ impl, I: 'static, XcmProvider: Convert, Xcm<()>>, XcmSender } } -/// Adapter that ties together the `DispatchBlob` trait with the `DispatchChannelStatusProvider` -/// trait. The idea is that `DispatchBlob` triggers message dispatch/delivery on the receiver side, -/// while `DispatchChannelStatusProvider` provides an status check to ensure the dispatch channel is +/// Adapter that ties together the [`DispatchBlob`] trait with the [`DispatchChannelStatusProvider`] +/// trait. The idea is that [`DispatchBlob`] triggers message dispatch/delivery on the receiver side, +/// while [`DispatchChannelStatusProvider`] provides a status check to ensure the dispatch channel is /// active (not congested). pub struct BlobDispatcherWithChannelStatus( PhantomData<(ChannelDispatch, ChannelStatus)>, From b8d274222731aef412a6c7b290d36838a239c752 Mon Sep 17 00:00:00 2001 From: Branislav Kontur Date: Thu, 14 Nov 2024 11:33:23 +0100 Subject: [PATCH 64/72] PR review - fees -> fee --- bridges/modules/xcm-bridge-hub-router/src/impls.rs | 8 ++++---- bridges/modules/xcm-bridge-hub-router/src/lib.rs | 10 +++++----- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/bridges/modules/xcm-bridge-hub-router/src/impls.rs b/bridges/modules/xcm-bridge-hub-router/src/impls.rs index 29ab44088e52..d784c4355b9e 100644 --- a/bridges/modules/xcm-bridge-hub-router/src/impls.rs +++ b/bridges/modules/xcm-bridge-hub-router/src/impls.rs @@ -138,7 +138,7 @@ where // calculate message size fees (if configured) let maybe_message_size_fees = - Pallet::::calculate_message_size_fees(|| message.encoded_size() as _); + Pallet::::calculate_message_size_fee(|| message.encoded_size() as _); // compute actual fees - sum(actual payment, message size fees) if possible let fees = match (maybe_payment, maybe_message_size_fees) { @@ -179,7 +179,7 @@ where let fees = fees.map(|fees| { if let Some(bridge_id) = T::BridgeIdResolver::resolve_for(network, remote_location) { if let Some(bridge_state) = Bridges::::get(bridge_id) { - Pallet::::calculate_dynamic_fees_for_asset(&bridge_state, fees) + Pallet::::calculate_dynamic_fee(&bridge_state, fees) } else { fees } @@ -211,7 +211,7 @@ impl, I: 'static, E: SendXcm> SendXcm for ViaLocalBridgeHubExporter Ok((ticket, mut fees)) => { // calculate message size fees (if configured) let maybe_message_size_fees = - Pallet::::calculate_message_size_fees(|| message_size); + Pallet::::calculate_message_size_fee(|| message_size); if let Some(message_size_fees) = maybe_message_size_fees { fees.push(message_size_fees); } @@ -222,7 +222,7 @@ impl, I: 'static, E: SendXcm> SendXcm for ViaLocalBridgeHubExporter if let Some(bridge_state) = Bridges::::get(bridge_id) { let mut dynamic_fees = sp_std::vec::Vec::with_capacity(fees.len()); for fee in fees.into_inner() { - dynamic_fees.push(Pallet::::calculate_dynamic_fees_for_asset( + dynamic_fees.push(Pallet::::calculate_dynamic_fee( &bridge_state, fee, )); diff --git a/bridges/modules/xcm-bridge-hub-router/src/lib.rs b/bridges/modules/xcm-bridge-hub-router/src/lib.rs index b183cac9a40f..26db874bb8f6 100644 --- a/bridges/modules/xcm-bridge-hub-router/src/lib.rs +++ b/bridges/modules/xcm-bridge-hub-router/src/lib.rs @@ -166,7 +166,7 @@ pub mod pallet { type BridgeHubOrigin: EnsureOriginWithArg>; /// Additional fee that is paid for every byte of the outbound message. - /// See `calculate_message_size_fees` for more details. + /// See `calculate_message_size_fee` for more details. type ByteFee: Get; /// Asset used to pay the `ByteFee`. /// If not specified, the `ByteFee` is ignored. @@ -194,7 +194,7 @@ pub mod pallet { // If no longer congested, we can start decreasing the fee factor. if !bridge_state.is_congested { let previous_factor = bridge_state.delivery_fee_factor; - let new_factor = previous_factor / EXPONENTIAL_FEE_BASE; + let new_factor = previous_factor / EXPONENTIAL_FEE_BASE; if new_factor >= MINIMAL_DELIVERY_FEE_FACTOR { bridge_state.delivery_fee_factor = new_factor; bridges_to_update.push((bridge_id, previous_factor, bridge_state)); @@ -324,13 +324,13 @@ pub mod pallet { } } - /// Calculates dynamic fees for a given asset based on the bridge state. + /// Returns the recalculated dynamic fee for a given asset based on the bridge state. /// /// This function adjusts the amount of a fungible asset according to the delivery fee /// factor specified in the `bridge_state`. If the asset is fungible, the /// `delivery_fee_factor` is applied to the asset’s amount, potentially altering its /// value. - pub(crate) fn calculate_dynamic_fees_for_asset( + pub(crate) fn calculate_dynamic_fee( bridge_state: &BridgeState, mut asset: Asset, ) -> Asset { @@ -341,7 +341,7 @@ pub mod pallet { } /// Calculates an (optional) fee for message size based on `T::ByteFee` and `T::FeeAsset`. - pub(crate) fn calculate_message_size_fees( + pub(crate) fn calculate_message_size_fee( message_size: impl FnOnce() -> u32, ) -> Option { // Apply message size `T::ByteFee/T::FeeAsset` feature (if configured). From ecf3499b25be5d681432caafa08b9254c65b1e7a Mon Sep 17 00:00:00 2001 From: Branislav Kontur Date: Thu, 14 Nov 2024 13:03:17 +0100 Subject: [PATCH 65/72] PR review - change `on_initialize` to `on_idle` --- .../xcm-bridge-hub-router/src/benchmarking.rs | 8 ++--- .../modules/xcm-bridge-hub-router/src/lib.rs | 30 ++++++++++++------- .../xcm-bridge-hub-router/src/weights.rs | 8 ++--- .../weights/pallet_xcm_bridge_hub_router.rs | 4 +-- .../weights/pallet_xcm_bridge_hub_router.rs | 4 +-- 5 files changed, 32 insertions(+), 22 deletions(-) diff --git a/bridges/modules/xcm-bridge-hub-router/src/benchmarking.rs b/bridges/modules/xcm-bridge-hub-router/src/benchmarking.rs index 0b7061db5d6c..a44d478a5b7a 100644 --- a/bridges/modules/xcm-bridge-hub-router/src/benchmarking.rs +++ b/bridges/modules/xcm-bridge-hub-router/src/benchmarking.rs @@ -40,7 +40,7 @@ mod benchmarks { use super::*; #[benchmark] - fn on_initialize_when_bridge_state_removed() -> Result<(), BenchmarkError> { + fn on_idle_when_bridge_state_removed() -> Result<(), BenchmarkError> { let bridge_id = T::BridgeIdResolver::resolve_for_dest(&T::ensure_bridged_target_destination()?) .ok_or(BenchmarkError::Weightless)?; @@ -54,7 +54,7 @@ mod benchmarks { #[block] { - let _ = crate::Pallet::::on_initialize(Zero::zero()); + let _ = crate::Pallet::::on_idle(Zero::zero(), Weight::MAX); } assert!(Bridges::::get(bridge_id).is_none()); @@ -63,7 +63,7 @@ mod benchmarks { } #[benchmark] - fn on_initialize_when_bridge_state_updated() -> Result<(), BenchmarkError> { + fn on_indle_when_bridge_state_updated() -> Result<(), BenchmarkError> { let bridge_id = T::BridgeIdResolver::resolve_for_dest(&T::ensure_bridged_target_destination()?) .ok_or(BenchmarkError::Weightless)?; @@ -78,7 +78,7 @@ mod benchmarks { #[block] { - let _ = crate::Pallet::::on_initialize(Zero::zero()); + let _ = crate::Pallet::::on_idle(Zero::zero(), Weight::MAX); } assert!( diff --git a/bridges/modules/xcm-bridge-hub-router/src/lib.rs b/bridges/modules/xcm-bridge-hub-router/src/lib.rs index 26db874bb8f6..e2962341a46c 100644 --- a/bridges/modules/xcm-bridge-hub-router/src/lib.rs +++ b/bridges/modules/xcm-bridge-hub-router/src/lib.rs @@ -106,6 +106,7 @@ pub const LOG_TARGET: &str = "runtime::bridge-xcm-router"; pub mod pallet { use super::*; use frame_support::pallet_prelude::*; + use frame_support::weights::WeightMeter; use frame_system::pallet_prelude::*; /// Default implementations of [`DefaultConfig`], which can be used to implement [`Config`]. @@ -182,14 +183,14 @@ pub mod pallet { #[pallet::hooks] impl, I: 'static> Hooks> for Pallet { - fn on_initialize(_n: BlockNumberFor) -> Weight { - let mut weight_used = Weight::zero(); + fn on_idle(_n: BlockNumberFor, remaining_weight: Weight) -> Weight { + let mut meter = WeightMeter::with_limit(remaining_weight); - // Iterate all uncongested bridges + // Iterate all congested bridges let mut bridges_to_update = Vec::new(); let mut bridges_to_remove = Vec::new(); for (bridge_id, mut bridge_state) in Bridges::::iter() { - weight_used.saturating_accrue(T::DbWeight::get().reads(1)); + meter.consume(T::DbWeight::get().reads(1)); // If no longer congested, we can start decreasing the fee factor. if !bridge_state.is_congested { @@ -197,8 +198,14 @@ pub mod pallet { let new_factor = previous_factor / EXPONENTIAL_FEE_BASE; if new_factor >= MINIMAL_DELIVERY_FEE_FACTOR { bridge_state.delivery_fee_factor = new_factor; + if meter.try_consume(T::WeightInfo::on_idle_when_bridge_state_updated()).is_err() { + break; + } bridges_to_update.push((bridge_id, previous_factor, bridge_state)); } else { + if meter.try_consume(T::WeightInfo::on_idle_when_bridge_state_removed()).is_err() { + break; + } bridges_to_remove.push((bridge_id, previous_factor)); } } @@ -217,8 +224,6 @@ pub mod pallet { new_value: 0.into(), bridge_id, }); - weight_used - .saturating_accrue(T::WeightInfo::on_initialize_when_bridge_state_removed()); } // update for (bridge_id, previous_value, bridge_state) in bridges_to_update.into_iter() { @@ -236,11 +241,9 @@ pub mod pallet { new_value, bridge_id, }); - weight_used - .saturating_accrue(T::WeightInfo::on_initialize_when_bridge_state_updated()); } - weight_used + meter.consumed() } } @@ -539,6 +542,7 @@ mod tests { run_test(|| { let dest = Location::new(2, [GlobalConsensus(BridgedNetworkId::get())]); let initial_fee_factor = FixedU128::from_rational(125, 100); + let mut remaining_weight = Weight::MAX; // make bridge uncongested + update fee factor let bridge_id = set_bridge_state_for::( @@ -550,8 +554,14 @@ mod tests { let mut last_delivery_fee_factor = initial_fee_factor; while let Some(bridge_state) = get_bridge_state_for::(&dest) { last_delivery_fee_factor = bridge_state.delivery_fee_factor; - XcmBridgeHubRouter::on_initialize(One::one()); + remaining_weight = XcmBridgeHubRouter::on_idle(One::one(), remaining_weight.clone()); + + // avoid infinite loops (decreasing is expected) + if let Some(bridge_state) = get_bridge_state_for::(&dest) { + assert!(bridge_state.delivery_fee_factor < last_delivery_fee_factor); + } } + assert!(remaining_weight.all_lt(Weight::MAX)); // check emitted event // (first one for updating) diff --git a/bridges/modules/xcm-bridge-hub-router/src/weights.rs b/bridges/modules/xcm-bridge-hub-router/src/weights.rs index 788b4e48c7aa..a4eef004cb4e 100644 --- a/bridges/modules/xcm-bridge-hub-router/src/weights.rs +++ b/bridges/modules/xcm-bridge-hub-router/src/weights.rs @@ -50,8 +50,8 @@ use sp_std::marker::PhantomData; /// Weight functions needed for pallet_xcm_bridge_hub_router. pub trait WeightInfo { - fn on_initialize_when_bridge_state_removed() -> Weight; - fn on_initialize_when_bridge_state_updated() -> Weight; + fn on_idle_when_bridge_state_removed() -> Weight; + fn on_idle_when_bridge_state_updated() -> Weight; fn report_bridge_status() -> Weight; } @@ -60,7 +60,7 @@ impl WeightInfo for () { /// Storage: `ToUnknownXcmRouter::Bridges` (r:2 w:1) /// Proof: `ToUnknownXcmRouter::Bridges` (`max_values`: None, `max_size`: Some(65), added: 2540, /// mode: `MaxEncodedLen`) - fn on_initialize_when_bridge_state_removed() -> Weight { + fn on_idle_when_bridge_state_removed() -> Weight { // Proof Size summary in bytes: // Measured: `204` // Estimated: `6070` @@ -73,7 +73,7 @@ impl WeightInfo for () { /// Storage: `ToUnknownXcmRouter::Bridges` (r:2 w:1) /// Proof: `ToUnknownXcmRouter::Bridges` (`max_values`: None, `max_size`: Some(65), added: 2540, /// mode: `MaxEncodedLen`) - fn on_initialize_when_bridge_state_updated() -> Weight { + fn on_idle_when_bridge_state_updated() -> Weight { // Proof Size summary in bytes: // Measured: `204` // Estimated: `6070` diff --git a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/pallet_xcm_bridge_hub_router.rs b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/pallet_xcm_bridge_hub_router.rs index 3ef17f80b9ea..3a5f55864c08 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/pallet_xcm_bridge_hub_router.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/pallet_xcm_bridge_hub_router.rs @@ -50,7 +50,7 @@ pub struct WeightInfo(PhantomData); impl pallet_xcm_bridge_hub_router::WeightInfo for WeightInfo { /// Storage: `ToWestendXcmRouter::Bridges` (r:2 w:1) /// Proof: `ToWestendXcmRouter::Bridges` (`max_values`: None, `max_size`: Some(65), added: 2540, mode: `MaxEncodedLen`) - fn on_initialize_when_bridge_state_removed() -> Weight { + fn on_idle_when_bridge_state_removed() -> Weight { // Proof Size summary in bytes: // Measured: `204` // Estimated: `6070` @@ -62,7 +62,7 @@ impl pallet_xcm_bridge_hub_router::WeightInfo for Weigh } /// Storage: `ToWestendXcmRouter::Bridges` (r:2 w:1) /// Proof: `ToWestendXcmRouter::Bridges` (`max_values`: None, `max_size`: Some(65), added: 2540, mode: `MaxEncodedLen`) - fn on_initialize_when_bridge_state_updated() -> Weight { + fn on_idle_when_bridge_state_updated() -> Weight { // Proof Size summary in bytes: // Measured: `204` // Estimated: `6070` diff --git a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/pallet_xcm_bridge_hub_router.rs b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/pallet_xcm_bridge_hub_router.rs index 142701e0b2bd..5089e21b91cb 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/pallet_xcm_bridge_hub_router.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/pallet_xcm_bridge_hub_router.rs @@ -50,7 +50,7 @@ pub struct WeightInfo(PhantomData); impl pallet_xcm_bridge_hub_router::WeightInfo for WeightInfo { /// Storage: `ToRococoXcmRouter::Bridges` (r:2 w:1) /// Proof: `ToRococoXcmRouter::Bridges` (`max_values`: None, `max_size`: Some(65), added: 2540, mode: `MaxEncodedLen`) - fn on_initialize_when_bridge_state_removed() -> Weight { + fn on_idle_when_bridge_state_removed() -> Weight { // Proof Size summary in bytes: // Measured: `204` // Estimated: `6070` @@ -62,7 +62,7 @@ impl pallet_xcm_bridge_hub_router::WeightInfo for Weigh } /// Storage: `ToRococoXcmRouter::Bridges` (r:2 w:1) /// Proof: `ToRococoXcmRouter::Bridges` (`max_values`: None, `max_size`: Some(65), added: 2540, mode: `MaxEncodedLen`) - fn on_initialize_when_bridge_state_updated() -> Weight { + fn on_idle_when_bridge_state_updated() -> Weight { // Proof Size summary in bytes: // Measured: `204` // Estimated: `6070` From f643ec7a2c0d5ddc16cfc21666709c37d46cc4f7 Mon Sep 17 00:00:00 2001 From: GitHub Action Date: Thu, 14 Nov 2024 12:11:28 +0000 Subject: [PATCH 66/72] Update from bkontur running command 'fmt' --- .../xcm-bridge-hub-router/src/impls.rs | 19 ++++++++------- .../modules/xcm-bridge-hub-router/src/lib.rs | 23 +++++++++++-------- .../modules/xcm-bridge-hub/src/congestion.rs | 10 ++++---- 3 files changed, 27 insertions(+), 25 deletions(-) diff --git a/bridges/modules/xcm-bridge-hub-router/src/impls.rs b/bridges/modules/xcm-bridge-hub-router/src/impls.rs index d784c4355b9e..87d0305d2a92 100644 --- a/bridges/modules/xcm-bridge-hub-router/src/impls.rs +++ b/bridges/modules/xcm-bridge-hub-router/src/impls.rs @@ -23,9 +23,9 @@ use frame_support::{ensure, pallet_prelude::PhantomData, traits::Get}; use xcm::prelude::*; use xcm_builder::{ensure_is_remote, ExporterFor}; -/// Implementation of [`bp_xcm_bridge_hub::LocalXcmChannelManager`] which tracks and updates `is_congested` for a given -/// `BridgeId`. This implementation is useful for managing congestion and dynamic fees with the -/// local `ExportXcm` implementation. +/// Implementation of [`bp_xcm_bridge_hub::LocalXcmChannelManager`] which tracks and updates +/// `is_congested` for a given `BridgeId`. This implementation is useful for managing congestion and +/// dynamic fees with the local `ExportXcm` implementation. impl, I: 'static> bp_xcm_bridge_hub::LocalXcmChannelManager> for Pallet { @@ -72,8 +72,8 @@ impl, I: 'static> bp_xcm_bridge_hub::LocalXcmChannelManager(PhantomData<(T, I, E, BNF, BHLF)>); impl, I: 'static, E, BridgedNetworkIdFilter, BridgeHubLocationFilter> ExporterFor for ViaRemoteBridgeHubExporter @@ -195,7 +195,8 @@ where /// Adapter implementation for [`SendXcm`] that allows adding a message size fee and/or dynamic fees /// based on the `BridgeId` resolved by the `T::BridgeIdResolver` resolver, if and only if `E` /// supports routing. This adapter can be used, for example, as a wrapper over -/// [`xcm_builder::UnpaidLocalExporter`], enabling it to compute message and/or dynamic fees using a fee factor. +/// [`xcm_builder::UnpaidLocalExporter`], enabling it to compute message and/or dynamic fees using a +/// fee factor. pub struct ViaLocalBridgeHubExporter(PhantomData<(T, I, E)>); impl, I: 'static, E: SendXcm> SendXcm for ViaLocalBridgeHubExporter { type Ticket = E::Ticket; @@ -222,10 +223,8 @@ impl, I: 'static, E: SendXcm> SendXcm for ViaLocalBridgeHubExporter if let Some(bridge_state) = Bridges::::get(bridge_id) { let mut dynamic_fees = sp_std::vec::Vec::with_capacity(fees.len()); for fee in fees.into_inner() { - dynamic_fees.push(Pallet::::calculate_dynamic_fee( - &bridge_state, - fee, - )); + dynamic_fees + .push(Pallet::::calculate_dynamic_fee(&bridge_state, fee)); } fees = Assets::from(dynamic_fees); } diff --git a/bridges/modules/xcm-bridge-hub-router/src/lib.rs b/bridges/modules/xcm-bridge-hub-router/src/lib.rs index e2962341a46c..1689926cb02b 100644 --- a/bridges/modules/xcm-bridge-hub-router/src/lib.rs +++ b/bridges/modules/xcm-bridge-hub-router/src/lib.rs @@ -105,8 +105,7 @@ pub const LOG_TARGET: &str = "runtime::bridge-xcm-router"; #[frame_support::pallet] pub mod pallet { use super::*; - use frame_support::pallet_prelude::*; - use frame_support::weights::WeightMeter; + use frame_support::{pallet_prelude::*, weights::WeightMeter}; use frame_system::pallet_prelude::*; /// Default implementations of [`DefaultConfig`], which can be used to implement [`Config`]. @@ -195,15 +194,21 @@ pub mod pallet { // If no longer congested, we can start decreasing the fee factor. if !bridge_state.is_congested { let previous_factor = bridge_state.delivery_fee_factor; - let new_factor = previous_factor / EXPONENTIAL_FEE_BASE; + let new_factor = previous_factor / EXPONENTIAL_FEE_BASE; if new_factor >= MINIMAL_DELIVERY_FEE_FACTOR { bridge_state.delivery_fee_factor = new_factor; - if meter.try_consume(T::WeightInfo::on_idle_when_bridge_state_updated()).is_err() { + if meter + .try_consume(T::WeightInfo::on_idle_when_bridge_state_updated()) + .is_err() + { break; } bridges_to_update.push((bridge_id, previous_factor, bridge_state)); } else { - if meter.try_consume(T::WeightInfo::on_idle_when_bridge_state_removed()).is_err() { + if meter + .try_consume(T::WeightInfo::on_idle_when_bridge_state_removed()) + .is_err() + { break; } bridges_to_remove.push((bridge_id, previous_factor)); @@ -333,10 +338,7 @@ pub mod pallet { /// factor specified in the `bridge_state`. If the asset is fungible, the /// `delivery_fee_factor` is applied to the asset’s amount, potentially altering its /// value. - pub(crate) fn calculate_dynamic_fee( - bridge_state: &BridgeState, - mut asset: Asset, - ) -> Asset { + pub(crate) fn calculate_dynamic_fee(bridge_state: &BridgeState, mut asset: Asset) -> Asset { if let Fungibility::Fungible(ref mut amount) = asset.fun { *amount = bridge_state.delivery_fee_factor.saturating_mul_int(*amount); } @@ -554,7 +556,8 @@ mod tests { let mut last_delivery_fee_factor = initial_fee_factor; while let Some(bridge_state) = get_bridge_state_for::(&dest) { last_delivery_fee_factor = bridge_state.delivery_fee_factor; - remaining_weight = XcmBridgeHubRouter::on_idle(One::one(), remaining_weight.clone()); + remaining_weight = + XcmBridgeHubRouter::on_idle(One::one(), remaining_weight.clone()); // avoid infinite loops (decreasing is expected) if let Some(bridge_state) = get_bridge_state_for::(&dest) { diff --git a/bridges/modules/xcm-bridge-hub/src/congestion.rs b/bridges/modules/xcm-bridge-hub/src/congestion.rs index fed8be1323cf..e570fbde6060 100644 --- a/bridges/modules/xcm-bridge-hub/src/congestion.rs +++ b/bridges/modules/xcm-bridge-hub/src/congestion.rs @@ -134,8 +134,8 @@ impl< /// Manages the local XCM channels by sending XCM messages with the `report_bridge_status` extrinsic /// to the `local_origin`. The `XcmProvider` type converts the encoded call to `XCM`, which is then /// sent by `XcmSender` to the `local_origin`. This is useful, for example, when a router with -/// [`xcm::prelude::ExportMessage`] is deployed on a different chain, and we want to control congestion by sending -/// XCMs. +/// [`xcm::prelude::ExportMessage`] is deployed on a different chain, and we want to control +/// congestion by sending XCMs. pub struct ReportBridgeStatusXcmChannelManager( PhantomData<(T, I, XcmProvider, XcmSender)>, ); @@ -209,9 +209,9 @@ impl, I: 'static, XcmProvider: Convert, Xcm<()>>, XcmSender } /// Adapter that ties together the [`DispatchBlob`] trait with the [`DispatchChannelStatusProvider`] -/// trait. The idea is that [`DispatchBlob`] triggers message dispatch/delivery on the receiver side, -/// while [`DispatchChannelStatusProvider`] provides a status check to ensure the dispatch channel is -/// active (not congested). +/// trait. The idea is that [`DispatchBlob`] triggers message dispatch/delivery on the receiver +/// side, while [`DispatchChannelStatusProvider`] provides a status check to ensure the dispatch +/// channel is active (not congested). pub struct BlobDispatcherWithChannelStatus( PhantomData<(ChannelDispatch, ChannelStatus)>, ); From 8518de3bc7d9ed02ea351dc0a5c0714b43aba69e Mon Sep 17 00:00:00 2001 From: Branislav Kontur Date: Thu, 14 Nov 2024 16:21:47 +0100 Subject: [PATCH 67/72] PR review - updated docs --- bridges/modules/xcm-bridge-hub-router/src/lib.rs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/bridges/modules/xcm-bridge-hub-router/src/lib.rs b/bridges/modules/xcm-bridge-hub-router/src/lib.rs index 1689926cb02b..8616756556ea 100644 --- a/bridges/modules/xcm-bridge-hub-router/src/lib.rs +++ b/bridges/modules/xcm-bridge-hub-router/src/lib.rs @@ -95,11 +95,6 @@ const MESSAGE_SIZE_FEE_BASE: FixedU128 = FixedU128::from_rational(1, 1000); // 0 pub const HARD_MESSAGE_SIZE_LIMIT: u32 = 32 * 1024; /// The target that will be used when publishing logs related to this pallet. -/// -/// This doesn't match the pattern used by other bridge pallets (`runtime::bridge-*`). But this -/// pallet has significant differences with those pallets. The main one is that is intended to -/// be deployed at sending chains. Other bridge pallets are likely to be deployed at the separate -/// bridge hub parachain. pub const LOG_TARGET: &str = "runtime::bridge-xcm-router"; #[frame_support::pallet] From 8a082c178b75280bf454243aaa0b5e1ae4be6d8c Mon Sep 17 00:00:00 2001 From: Branislav Kontur Date: Fri, 15 Nov 2024 09:41:32 +0100 Subject: [PATCH 68/72] clippy --- bridges/modules/xcm-bridge-hub-router/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bridges/modules/xcm-bridge-hub-router/src/lib.rs b/bridges/modules/xcm-bridge-hub-router/src/lib.rs index 8616756556ea..91526b04f745 100644 --- a/bridges/modules/xcm-bridge-hub-router/src/lib.rs +++ b/bridges/modules/xcm-bridge-hub-router/src/lib.rs @@ -552,7 +552,7 @@ mod tests { while let Some(bridge_state) = get_bridge_state_for::(&dest) { last_delivery_fee_factor = bridge_state.delivery_fee_factor; remaining_weight = - XcmBridgeHubRouter::on_idle(One::one(), remaining_weight.clone()); + XcmBridgeHubRouter::on_idle(One::one(), remaining_weight); // avoid infinite loops (decreasing is expected) if let Some(bridge_state) = get_bridge_state_for::(&dest) { From 465db5f18a6c63af6596b80c9c1ae872079f0405 Mon Sep 17 00:00:00 2001 From: GitHub Action Date: Fri, 15 Nov 2024 14:52:59 +0000 Subject: [PATCH 69/72] Update from bkontur running command 'fmt' --- bridges/modules/xcm-bridge-hub-router/src/lib.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/bridges/modules/xcm-bridge-hub-router/src/lib.rs b/bridges/modules/xcm-bridge-hub-router/src/lib.rs index 91526b04f745..f4664c0695e7 100644 --- a/bridges/modules/xcm-bridge-hub-router/src/lib.rs +++ b/bridges/modules/xcm-bridge-hub-router/src/lib.rs @@ -551,8 +551,7 @@ mod tests { let mut last_delivery_fee_factor = initial_fee_factor; while let Some(bridge_state) = get_bridge_state_for::(&dest) { last_delivery_fee_factor = bridge_state.delivery_fee_factor; - remaining_weight = - XcmBridgeHubRouter::on_idle(One::one(), remaining_weight); + remaining_weight = XcmBridgeHubRouter::on_idle(One::one(), remaining_weight); // avoid infinite loops (decreasing is expected) if let Some(bridge_state) = get_bridge_state_for::(&dest) { From 416e2e0b1d4c5efb295409a20d6ff8fdd6543111 Mon Sep 17 00:00:00 2001 From: Branislav Kontur Date: Tue, 19 Nov 2024 22:50:05 +0100 Subject: [PATCH 70/72] PR review --- .../modules/xcm-bridge-hub-router/src/lib.rs | 59 +++++++++---------- 1 file changed, 27 insertions(+), 32 deletions(-) diff --git a/bridges/modules/xcm-bridge-hub-router/src/lib.rs b/bridges/modules/xcm-bridge-hub-router/src/lib.rs index f4664c0695e7..ae708fd0d6e4 100644 --- a/bridges/modules/xcm-bridge-hub-router/src/lib.rs +++ b/bridges/modules/xcm-bridge-hub-router/src/lib.rs @@ -288,43 +288,38 @@ pub mod pallet { }; // handle congestion and fee factor (if detected) - let increased = - Bridges::::mutate_exists(&bridge_id, |bridge_state| match bridge_state { - Some(ref mut bridge_state) if bridge_state.is_congested => { - // found congested bridge - // ok - we need to increase the fee factor, let's do that - let message_size_factor = - FixedU128::from_u32(message_size.saturating_div(1024)) - .saturating_mul(MESSAGE_SIZE_FEE_BASE); - let total_factor = EXPONENTIAL_FEE_BASE.saturating_add(message_size_factor); - - let previous_factor = bridge_state.delivery_fee_factor; - bridge_state.delivery_fee_factor = - bridge_state.delivery_fee_factor.saturating_mul(total_factor); - - Some((previous_factor, bridge_state.delivery_fee_factor)) - }, - _ => { - // not congested, do nothing - None - }, - }); - if let Some((previous_factor, new_factor)) = increased { - log::info!( + Bridges::::mutate_exists(&bridge_id, |bridge_state| match bridge_state { + Some(ref mut bridge_state) if bridge_state.is_congested => { + // found congested bridge + // ok - we need to increase the fee factor, let's do that + let message_size_factor = + FixedU128::from_u32(message_size.saturating_div(1024)) + .saturating_mul(MESSAGE_SIZE_FEE_BASE); + let total_factor = EXPONENTIAL_FEE_BASE.saturating_add(message_size_factor); + + let previous_factor = bridge_state.delivery_fee_factor; + bridge_state.delivery_fee_factor = + bridge_state.delivery_fee_factor.saturating_mul(total_factor); + + log::info!( target: LOG_TARGET, "Bridge channel with id {:?} is congested. Increased fee factor from {} to {} for {:?}", bridge_id, previous_factor, - new_factor, + bridge_state.delivery_fee_factor, dest - ); - Self::deposit_event(Event::DeliveryFeeFactorIncreased { - previous_value: previous_factor, - new_value: new_factor, - bridge_id, - dest, - }); - } + ); + Self::deposit_event(Event::DeliveryFeeFactorIncreased { + previous_value: previous_factor, + new_value: bridge_state.delivery_fee_factor, + bridge_id: bridge_id.clone(), + dest, + }); + }, + _ => { + // not congested, do nothing + }, + }); } /// Returns the recalculated dynamic fee for a given asset based on the bridge state. From 15ef0a4fe048d35106369e307a328dad33f3994b Mon Sep 17 00:00:00 2001 From: Branislav Kontur Date: Tue, 19 Nov 2024 22:58:14 +0100 Subject: [PATCH 71/72] PR review - removed brackets --- bridges/modules/xcm-bridge-hub-router/src/impls.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bridges/modules/xcm-bridge-hub-router/src/impls.rs b/bridges/modules/xcm-bridge-hub-router/src/impls.rs index 87d0305d2a92..b891e2cd0f20 100644 --- a/bridges/modules/xcm-bridge-hub-router/src/impls.rs +++ b/bridges/modules/xcm-bridge-hub-router/src/impls.rs @@ -154,7 +154,7 @@ where ) if payment_asset_id.eq(&message_size_fees_asset_id) => { // we can subsume two assets with the same asset_id and fungibility. Some( - (payment_asset_id, (payment_amount.saturating_add(message_size_fees_amount))) + (payment_asset_id, payment_amount.saturating_add(message_size_fees_amount)) .into(), ) }, From 296476e54260200e038006f09df914ddca54fb3c Mon Sep 17 00:00:00 2001 From: Branislav Kontur Date: Tue, 19 Nov 2024 23:03:25 +0100 Subject: [PATCH 72/72] PR review --- .../modules/xcm-bridge-hub-router/src/impls.rs | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/bridges/modules/xcm-bridge-hub-router/src/impls.rs b/bridges/modules/xcm-bridge-hub-router/src/impls.rs index b891e2cd0f20..255c2f37ff81 100644 --- a/bridges/modules/xcm-bridge-hub-router/src/impls.rs +++ b/bridges/modules/xcm-bridge-hub-router/src/impls.rs @@ -141,7 +141,7 @@ where Pallet::::calculate_message_size_fee(|| message.encoded_size() as _); // compute actual fees - sum(actual payment, message size fees) if possible - let fees = match (maybe_payment, maybe_message_size_fees) { + let mut fees = match (maybe_payment, maybe_message_size_fees) { (Some(payment), None) => Some(payment), (None, Some(message_size_fees)) => Some(message_size_fees), (None, None) => None, @@ -176,17 +176,11 @@ where // Here, we have the actual result fees covering bridge fees, so now we need to check/apply // the congestion and dynamic_fees features (if possible). - let fees = fees.map(|fees| { - if let Some(bridge_id) = T::BridgeIdResolver::resolve_for(network, remote_location) { - if let Some(bridge_state) = Bridges::::get(bridge_id) { - Pallet::::calculate_dynamic_fee(&bridge_state, fees) - } else { - fees - } - } else { - fees + if let Some(bridge_id) = T::BridgeIdResolver::resolve_for(network, remote_location) { + if let Some(bridge_state) = Bridges::::get(bridge_id) { + fees = fees.map(|f| Pallet::::calculate_dynamic_fee(&bridge_state, f)); } - }); + } Some((bridge_hub_location, fees)) }