Skip to content

Commit

Permalink
Get dispatch weight from the target chain (when DispatchFeePayment::A…
Browse files Browse the repository at this point in the history
…tTargetChain is used) (paritytech#1430)

* reintroduce From<SourceChain>InboundLaneApi

* impl From<Chain>InboundLaneApi for testnet runtimes

* use inboundlaneapi in relay

* remove unused OutboundXcmWeigher

* spelling

* added the only test to messages pallet

* fmt
  • Loading branch information
svyatonik authored and serban300 committed Apr 9, 2024
1 parent dedb271 commit 538e42b
Show file tree
Hide file tree
Showing 25 changed files with 411 additions and 89 deletions.
32 changes: 26 additions & 6 deletions bridges/bin/millau/runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -833,16 +833,26 @@ impl_runtime_apis! {
lane: bp_messages::LaneId,
begin: bp_messages::MessageNonce,
end: bp_messages::MessageNonce,
) -> Vec<bp_messages::MessageDetails<Balance>> {
) -> Vec<bp_messages::OutboundMessageDetails<Balance>> {
bridge_runtime_common::messages_api::outbound_message_details::<
Runtime,
WithRialtoMessagesInstance,
WithRialtoMessageBridge,
xcm_config::OutboundXcmWeigher,
>(lane, begin, end)
}
}

impl bp_rialto::FromRialtoInboundLaneApi<Block, bp_rialto::Balance> for Runtime {
fn message_details(
lane: bp_messages::LaneId,
messages: Vec<(bp_messages::MessagePayload, bp_messages::OutboundMessageDetails<bp_rialto::Balance>)>,
) -> Vec<bp_messages::InboundMessageDetails> {
bridge_runtime_common::messages_api::inbound_message_details::<
Runtime,
WithRialtoMessagesInstance,
>(lane, messages)
}
}

impl bp_rialto_parachain::ToRialtoParachainOutboundLaneApi<Block, Balance, ToRialtoParachainMessagePayload> for Runtime {
fn estimate_message_delivery_and_dispatch_fee(
_lane_id: bp_messages::LaneId,
Expand All @@ -860,16 +870,26 @@ impl_runtime_apis! {
lane: bp_messages::LaneId,
begin: bp_messages::MessageNonce,
end: bp_messages::MessageNonce,
) -> Vec<bp_messages::MessageDetails<Balance>> {
) -> Vec<bp_messages::OutboundMessageDetails<Balance>> {
bridge_runtime_common::messages_api::outbound_message_details::<
Runtime,
WithRialtoParachainMessagesInstance,
WithRialtoParachainMessageBridge,
xcm_config::OutboundXcmWeigher,
>(lane, begin, end)
}
}

impl bp_rialto_parachain::FromRialtoParachainInboundLaneApi<Block, bp_rialto_parachain::Balance> for Runtime {
fn message_details(
lane: bp_messages::LaneId,
messages: Vec<(bp_messages::MessagePayload, bp_messages::OutboundMessageDetails<bp_rialto_parachain::Balance>)>,
) -> Vec<bp_messages::InboundMessageDetails> {
bridge_runtime_common::messages_api::inbound_message_details::<
Runtime,
WithRialtoParachainMessagesInstance,
>(lane, messages)
}
}

#[cfg(feature = "runtime-benchmarks")]
impl frame_benchmarking::Benchmark<Block> for Runtime {
fn benchmark_metadata(extra: bool) -> (
Expand Down
2 changes: 0 additions & 2 deletions bridges/bin/millau/runtime/src/xcm_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,8 +122,6 @@ pub type Barrier = (
AllowKnownQueryResponses<XcmPallet>,
);

/// Outbound XCM weigher type.
pub type OutboundXcmWeigher = xcm_builder::FixedWeightBounds<BaseXcmWeight, (), MaxInstructions>;
/// XCM weigher type.
pub type XcmWeigher = xcm_builder::FixedWeightBounds<BaseXcmWeight, Call, MaxInstructions>;

Expand Down
18 changes: 13 additions & 5 deletions bridges/bin/rialto-parachain/runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -383,8 +383,6 @@ pub type Barrier = (
// ^^^ Parent & its unit plurality gets free execution
);

/// Outbound XCM weigher type.
pub type OutboundXcmWeigher = FixedWeightBounds<UnitWeightCost, (), MaxInstructions>;
/// XCM weigher type.
pub type XcmWeigher = FixedWeightBounds<UnitWeightCost, Call, MaxInstructions>;

Expand Down Expand Up @@ -708,16 +706,26 @@ impl_runtime_apis! {
lane: bp_messages::LaneId,
begin: bp_messages::MessageNonce,
end: bp_messages::MessageNonce,
) -> Vec<bp_messages::MessageDetails<Balance>> {
) -> Vec<bp_messages::OutboundMessageDetails<Balance>> {
bridge_runtime_common::messages_api::outbound_message_details::<
Runtime,
WithMillauMessagesInstance,
WithMillauMessageBridge,
OutboundXcmWeigher,
>(lane, begin, end)
}
}

impl bp_millau::FromMillauInboundLaneApi<Block, bp_millau::Balance> for Runtime {
fn message_details(
lane: bp_messages::LaneId,
messages: Vec<(bp_messages::MessagePayload, bp_messages::OutboundMessageDetails<bp_millau::Balance>)>,
) -> Vec<bp_messages::InboundMessageDetails> {
bridge_runtime_common::messages_api::inbound_message_details::<
Runtime,
WithMillauMessagesInstance,
>(lane, messages)
}
}

#[cfg(feature = "runtime-benchmarks")]
impl frame_benchmarking::Benchmark<Block> for Runtime {
fn dispatch_benchmark(
Expand Down
16 changes: 13 additions & 3 deletions bridges/bin/rialto/runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -893,15 +893,25 @@ impl_runtime_apis! {
lane: bp_messages::LaneId,
begin: bp_messages::MessageNonce,
end: bp_messages::MessageNonce,
) -> Vec<bp_messages::MessageDetails<Balance>> {
) -> Vec<bp_messages::OutboundMessageDetails<Balance>> {
bridge_runtime_common::messages_api::outbound_message_details::<
Runtime,
WithMillauMessagesInstance,
WithMillauMessageBridge,
xcm_config::OutboundXcmWeigher,
>(lane, begin, end)
}
}

impl bp_millau::FromMillauInboundLaneApi<Block, bp_millau::Balance> for Runtime {
fn message_details(
lane: bp_messages::LaneId,
messages: Vec<(bp_messages::MessagePayload, bp_messages::OutboundMessageDetails<bp_millau::Balance>)>,
) -> Vec<bp_messages::InboundMessageDetails> {
bridge_runtime_common::messages_api::inbound_message_details::<
Runtime,
WithMillauMessagesInstance,
>(lane, messages)
}
}
}

#[cfg(test)]
Expand Down
2 changes: 0 additions & 2 deletions bridges/bin/rialto/runtime/src/xcm_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,8 +122,6 @@ pub type Barrier = (
AllowKnownQueryResponses<XcmPallet>,
);

/// Outbound XCM weigher type.
pub type OutboundXcmWeigher = xcm_builder::FixedWeightBounds<BaseXcmWeight, (), MaxInstructions>;
/// Incoming XCM weigher type.
pub type XcmWeigher = xcm_builder::FixedWeightBounds<BaseXcmWeight, Call, MaxInstructions>;

Expand Down
68 changes: 27 additions & 41 deletions bridges/bin/runtime-common/src/messages_api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,68 +16,54 @@

//! Helpers for implementing various message-related runtime API mthods.

use crate::messages::{target::FromBridgedChainMessagePayload, MessageBridge};

use bp_messages::{LaneId, MessageDetails, MessageKey, MessageNonce};
use codec::Decode;
use frame_support::weights::Weight;
use bp_messages::{
InboundMessageDetails, LaneId, MessageNonce, MessagePayload, OutboundMessageDetails,
};
use sp_std::vec::Vec;

/// Implementation of the `To*OutboundLaneApi::message_details`.
pub fn outbound_message_details<Runtime, MessagesPalletInstance, BridgeConfig, XcmWeigher>(
pub fn outbound_message_details<Runtime, MessagesPalletInstance>(
lane: LaneId,
begin: MessageNonce,
end: MessageNonce,
) -> Vec<MessageDetails<Runtime::OutboundMessageFee>>
) -> Vec<OutboundMessageDetails<Runtime::OutboundMessageFee>>
where
Runtime: pallet_bridge_messages::Config<MessagesPalletInstance>,
MessagesPalletInstance: 'static,
BridgeConfig: MessageBridge,
XcmWeigher: xcm_executor::traits::WeightBounds<()>,
{
(begin..=end)
.filter_map(|nonce| {
let message_data =
pallet_bridge_messages::Pallet::<Runtime, MessagesPalletInstance>::outbound_message_data(lane, nonce)?;
Some(MessageDetails {
Some(OutboundMessageDetails {
nonce,
// this shall match the similar code in the `FromBridgedChainMessageDispatch` - if we have failed
// to decode or estimate dispatch weight, we'll just return 0 to disable actual execution
dispatch_weight: compute_message_weight::<XcmWeigher>(
MessageKey { lane_id: lane, nonce },
&message_data.payload,
).unwrap_or(0),
// dispatch message weight is always zero at the source chain, since we're paying for
// dispatch at the target chain
dispatch_weight: 0,
size: message_data.payload.len() as _,
delivery_and_dispatch_fee: message_data.fee,
// we're delivering XCM messages here, so fee is always paid at the target chain
dispatch_fee_payment: bp_runtime::messages::DispatchFeePayment::AtTargetChain,
})
})
.collect()
}

// at the source chain we don't know the type of target chain `Call` => `()` is used (it is
// similarly currently used in Polkadot codebase)
fn compute_message_weight<XcmWeigher: xcm_executor::traits::WeightBounds<()>>(
message_key: MessageKey,
encoded_payload: &[u8],
) -> Result<Weight, ()> {
let mut payload = FromBridgedChainMessagePayload::<()>::decode(&mut &encoded_payload[..])
.map_err(|e| {
log::debug!(
target: "runtime::bridge-dispatch",
"Failed to decode outbound XCM message {:?}: {:?}",
message_key,
e,
);
})?;
let weight = XcmWeigher::weight(&mut payload.xcm.1);
let weight = weight.map_err(|e| {
log::debug!(
target: "runtime::bridge-dispatch",
"Failed to compute dispatch weight of outbound XCM message {:?}: {:?}",
message_key,
e,
);
})?;
Ok(weight)
/// Implementation of the `To*InboundLaneApi::message_details`.
pub fn inbound_message_details<Runtime, MessagesPalletInstance>(
lane: LaneId,
messages: Vec<(MessagePayload, OutboundMessageDetails<Runtime::InboundMessageFee>)>,
) -> Vec<InboundMessageDetails>
where
Runtime: pallet_bridge_messages::Config<MessagesPalletInstance>,
MessagesPalletInstance: 'static,
{
messages
.into_iter()
.map(|(payload, details)| {
pallet_bridge_messages::Pallet::<Runtime, MessagesPalletInstance>::inbound_message_data(
lane, payload, details,
)
})
.collect()
}
46 changes: 42 additions & 4 deletions bridges/modules/messages/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,10 @@ use bp_messages::{
target_chain::{
DispatchMessage, MessageDispatch, ProvedLaneMessages, ProvedMessages, SourceHeaderChain,
},
total_unrewarded_messages, DeliveredMessages, InboundLaneData, LaneId, MessageData, MessageKey,
MessageNonce, OperatingMode, OutboundLaneData, Parameter as MessagesParameter,
UnrewardedRelayer, UnrewardedRelayersState,
total_unrewarded_messages, DeliveredMessages, InboundLaneData, InboundMessageDetails, LaneId,
MessageData, MessageKey, MessageNonce, MessagePayload, OperatingMode, OutboundLaneData,
OutboundMessageDetails, Parameter as MessagesParameter, UnrewardedRelayer,
UnrewardedRelayersState,
};
use bp_runtime::{ChainId, Size};
use codec::{Decode, Encode};
Expand Down Expand Up @@ -156,7 +157,7 @@ pub mod pallet {
/// Payload type of inbound messages. This payload is dispatched on this chain.
type InboundPayload: Decode;
/// Message fee type of inbound messages. This fee is paid on the bridged chain.
type InboundMessageFee: Decode;
type InboundMessageFee: Decode + Zero;
/// Identifier of relayer that deliver messages to this chain. Relayer reward is paid on the
/// bridged chain.
type InboundRelayer: Parameter;
Expand Down Expand Up @@ -762,6 +763,22 @@ pub mod pallet {
) -> Option<MessageData<T::OutboundMessageFee>> {
OutboundMessages::<T, I>::get(MessageKey { lane_id: lane, nonce })
}

/// Prepare data, related to given inbound message.
pub fn inbound_message_data(
lane: LaneId,
payload: MessagePayload,
outbound_details: OutboundMessageDetails<T::InboundMessageFee>,
) -> InboundMessageDetails {
let mut dispatch_message = DispatchMessage {
key: MessageKey { lane_id: lane, nonce: outbound_details.nonce },
data: MessageData { payload, fee: outbound_details.delivery_and_dispatch_fee }
.into(),
};
InboundMessageDetails {
dispatch_weight: T::MessageDispatch::dispatch_weight(&mut dispatch_message),
}
}
}
}

Expand Down Expand Up @@ -2332,4 +2349,25 @@ mod tests {
bp_messages::storage_keys::inbound_lane_data_key("Messages", &TEST_LANE_ID).0,
);
}

#[test]
fn inbound_message_details_works() {
run_test(|| {
assert_eq!(
Pallet::<TestRuntime>::inbound_message_data(
TEST_LANE_ID,
REGULAR_PAYLOAD.encode(),
OutboundMessageDetails {
nonce: 0,
dispatch_weight: 0,
size: 0,
delivery_and_dispatch_fee: 0,
dispatch_fee_payment:
bp_runtime::messages::DispatchFeePayment::AtTargetChain,
},
),
InboundMessageDetails { dispatch_weight: REGULAR_PAYLOAD.declared_weight },
);
});
}
}
24 changes: 22 additions & 2 deletions bridges/primitives/chain-kusama/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@
// RuntimeApi generated functions
#![allow(clippy::too_many_arguments)]

use bp_messages::{LaneId, MessageDetails, MessageNonce};
use bp_messages::{
InboundMessageDetails, LaneId, MessageNonce, MessagePayload, OutboundMessageDetails,
};
use frame_support::weights::{
WeightToFeeCoefficient, WeightToFeeCoefficients, WeightToFeePolynomial,
};
Expand Down Expand Up @@ -105,6 +107,9 @@ pub const TO_KUSAMA_ESTIMATE_MESSAGE_FEE_METHOD: &str =
/// Name of the `ToKusamaOutboundLaneApi::message_details` runtime method.
pub const TO_KUSAMA_MESSAGE_DETAILS_METHOD: &str = "ToKusamaOutboundLaneApi_message_details";

/// Name of the `FromKusamaInboundLaneApi::message_details` runtime method.
pub const FROM_KUSAMA_MESSAGE_DETAILS_METHOD: &str = "FromKusamaInboundLaneApi_message_details";

sp_api::decl_runtime_apis! {
/// API for querying information about the finalized Kusama headers.
///
Expand Down Expand Up @@ -143,6 +148,21 @@ sp_api::decl_runtime_apis! {
lane: LaneId,
begin: MessageNonce,
end: MessageNonce,
) -> Vec<MessageDetails<OutboundMessageFee>>;
) -> Vec<OutboundMessageDetails<OutboundMessageFee>>;
}

/// Inbound message lane API for messages sent by Kusama chain.
///
/// This API is implemented by runtimes that are receiving messages from Kusama chain, not the
/// Kusama runtime itself.
///
/// Entries of the resulting vector are matching entries of the `messages` vector. Entries of the
/// `messages` vector may (and need to) be read using `To<ThisChain>OutboundLaneApi::message_details`.
pub trait FromKusamaInboundLaneApi<InboundMessageFee: Parameter> {
/// Return details of given inbound messages.
fn message_details(
lane: LaneId,
messages: Vec<(MessagePayload, OutboundMessageDetails<InboundMessageFee>)>,
) -> Vec<InboundMessageDetails>;
}
}
Loading

0 comments on commit 538e42b

Please sign in to comment.