From 9c67e80531653cd6d072e7791aa094a12738aa17 Mon Sep 17 00:00:00 2001 From: girazoki Date: Thu, 18 Dec 2025 10:35:13 +0100 Subject: [PATCH] modify message processor trait to return worst case weight + refund excess weight --- .../pallets/inbound-queue-v2/src/lib.rs | 20 ++++++++++++---- .../inbound-queue/src/v2/processor.rs | 4 ++-- .../primitives/inbound-queue/src/v2/traits.rs | 23 ++++++++++++++++--- 3 files changed, 37 insertions(+), 10 deletions(-) diff --git a/bridges/snowbridge/pallets/inbound-queue-v2/src/lib.rs b/bridges/snowbridge/pallets/inbound-queue-v2/src/lib.rs index 51a83a5b09e21..5fd0c085d9306 100644 --- a/bridges/snowbridge/pallets/inbound-queue-v2/src/lib.rs +++ b/bridges/snowbridge/pallets/inbound-queue-v2/src/lib.rs @@ -38,6 +38,7 @@ mod test; pub use crate::weights::WeightInfo; use bp_relayers::RewardLedger; use frame_system::ensure_signed; +use frame_support::dispatch::PostDispatchInfo; use snowbridge_core::{ reward::{AddTip, AddTipError}, sparse_bitmap::{SparseBitmap, SparseBitmapImpl}, @@ -180,8 +181,8 @@ pub mod pallet { impl Pallet { /// Submit an inbound message originating from the Gateway contract on Ethereum #[pallet::call_index(0)] - #[pallet::weight(T::WeightInfo::submit())] - pub fn submit(origin: OriginFor, event: Box) -> DispatchResult { + #[pallet::weight(T::WeightInfo::submit().saturating_add(T::MessageProcessor::worst_case_message_processor_weight()))] + pub fn submit(origin: OriginFor, event: Box) -> DispatchResultWithPostInfo { let who = ensure_signed(origin)?; ensure!(!OperatingMode::::get().is_halted(), Error::::Halted); @@ -211,7 +212,7 @@ pub mod pallet { } impl Pallet { - pub fn process_message(relayer: T::AccountId, message: Message) -> DispatchResult { + pub fn process_message(relayer: T::AccountId, message: Message) -> DispatchResultWithPostInfo { // Verify that the message was submitted from the known Gateway contract ensure!(T::GatewayAddress::get() == message.gateway, Error::::InvalidGateway); @@ -223,7 +224,7 @@ pub mod pallet { // Mark message as received Nonce::::set(nonce); - let message_id = T::MessageProcessor::process_message(relayer.clone(), message) + let (message_id, maybe_corrected_weight) = T::MessageProcessor::process_message(relayer.clone(), message) .map_err(|e| match e { MessageProcessorError::ProcessMessage(e) => e, MessageProcessorError::ConvertMessage(e) => Error::::from(e).into(), @@ -240,7 +241,16 @@ pub mod pallet { // Emit event with the message_id Self::deposit_event(Event::MessageReceived { nonce, message_id }); - Ok(()) + if let Some(corrected_weight) = maybe_corrected_weight { + Ok(PostDispatchInfo { + actual_weight: Some(corrected_weight.saturating_add(T::WeightInfo::submit())), + ..Default::default() + }) + } + else { + // Pays fees and non-corrected-weight + Ok(().into()) + } } } diff --git a/bridges/snowbridge/primitives/inbound-queue/src/v2/processor.rs b/bridges/snowbridge/primitives/inbound-queue/src/v2/processor.rs index 926912f06a66f..d7e28eb9c62fa 100644 --- a/bridges/snowbridge/primitives/inbound-queue/src/v2/processor.rs +++ b/bridges/snowbridge/primitives/inbound-queue/src/v2/processor.rs @@ -33,10 +33,10 @@ where fn process_message( relayer: AccountId, message: Message, - ) -> Result<[u8; 32], MessageProcessorError> { + ) -> Result<([u8; 32], Option), MessageProcessorError> { // Process the message and return its ID let id = Self::process_xcm(relayer, message)?; - Ok(id) + Ok((id, None)) } } diff --git a/bridges/snowbridge/primitives/inbound-queue/src/v2/traits.rs b/bridges/snowbridge/primitives/inbound-queue/src/v2/traits.rs index c9e26b05ec1dd..c8fbce78c13f9 100644 --- a/bridges/snowbridge/primitives/inbound-queue/src/v2/traits.rs +++ b/bridges/snowbridge/primitives/inbound-queue/src/v2/traits.rs @@ -3,7 +3,7 @@ // SPDX-FileCopyrightText: 2021-2025 Parity Technologies (UK) Ltd. use super::Message; use sp_core::RuntimeDebug; -use sp_runtime::DispatchError; +use sp_runtime::{DispatchError, Weight}; use xcm::latest::{SendError, Xcm}; /// Converts an inbound message from Ethereum to an XCM message that can be @@ -42,7 +42,12 @@ pub trait MessageProcessor { fn process_message( relayer: AccountId, message: Message, - ) -> Result<[u8; 32], MessageProcessorError>; + ) -> Result<([u8; 32], Option), MessageProcessorError>; + + /// Returns the worst case message processor weight + fn worst_case_message_processor_weight() -> Weight { + Weight::default() + } } #[impl_trait_for_tuples::impl_for_tuples(10)] @@ -63,7 +68,7 @@ impl MessageProcessor for Tuple { fn process_message( relayer: AccountId, message: Message, - ) -> Result<[u8; 32], MessageProcessorError> { + ) -> Result<([u8; 32], Option), MessageProcessorError> { for_tuples!( #( match Tuple::can_process_message(&relayer, &message) { true => { @@ -77,4 +82,16 @@ impl MessageProcessor for Tuple { "No handler found for message!", ))) } + + fn worst_case_message_processor_weight() -> Weight { + let mut max_weight = Weight::zero(); + + for_tuples!( #( + max_weight = max_weight.max( + Tuple::worst_case_message_processor_weight() + ); + )* ); + + max_weight + } }