Skip to content
Next Next commit
removed FromBridgedChainMessageDispatch in favor of XcmBlobMessageDis…
…patch
  • Loading branch information
svyatonik committed Mar 20, 2023
commit a371accae1fa940718fafdb92944f6b496b1d02d
15 changes: 8 additions & 7 deletions bin/millau/runtime/src/rialto_messages.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ pub type ToRialtoMessageVerifier =
messages::source::FromThisChainMessageVerifier<WithRialtoMessageBridge>;

/// Message payload for Rialto -> Millau messages.
pub type FromRialtoMessagePayload = messages::target::FromBridgedChainMessagePayload<RuntimeCall>;
pub type FromRialtoMessagePayload = messages::target::FromBridgedChainMessagePayload;

/// Messages proof for Rialto -> Millau messages.
pub type FromRialtoMessagesProof = messages::target::FromBridgedChainMessagesProof<bp_rialto::Hash>;
Expand All @@ -58,12 +58,13 @@ pub type ToRialtoMessagesDeliveryProof =
messages::source::FromBridgedChainMessagesDeliveryProof<bp_rialto::Hash>;

/// Call-dispatch based message dispatch for Rialto -> Millau messages.
pub type FromRialtoMessageDispatch = messages::target::FromBridgedChainMessageDispatch<
WithRialtoMessageBridge,
xcm_executor::XcmExecutor<crate::xcm_config::XcmConfig>,
crate::xcm_config::XcmWeigher,
WeightCredit,
>;
pub type FromRialtoMessageDispatch =
bridge_runtime_common::messages_xcm_extension::XcmBlobMessageDispatch<
bp_millau::Millau,
bp_rialto::Rialto,
crate::xcm_config::OnMillauBlobDispatcher,
bridge_runtime_common::messages_xcm_extension::XcmRouterWeigher<crate::DbWeight>,
>;

/// Maximal outbound payload size of Millau -> Rialto messages.
pub type ToRialtoMaximalOutboundPayloadSize =
Expand Down
16 changes: 8 additions & 8 deletions bin/millau/runtime/src/rialto_parachain_messages.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,16 +48,16 @@ pub type ToRialtoParachainMessageVerifier =
messages::source::FromThisChainMessageVerifier<WithRialtoParachainMessageBridge>;

/// Message payload for RialtoParachain -> Millau messages.
pub type FromRialtoParachainMessagePayload =
messages::target::FromBridgedChainMessagePayload<RuntimeCall>;
pub type FromRialtoParachainMessagePayload = messages::target::FromBridgedChainMessagePayload;

/// Call-dispatch based message dispatch for RialtoParachain -> Millau messages.
pub type FromRialtoParachainMessageDispatch = messages::target::FromBridgedChainMessageDispatch<
WithRialtoParachainMessageBridge,
xcm_executor::XcmExecutor<crate::xcm_config::XcmConfig>,
crate::xcm_config::XcmWeigher,
WeightCredit,
>;
pub type FromRialtoParachainMessageDispatch =
bridge_runtime_common::messages_xcm_extension::XcmBlobMessageDispatch<
bp_millau::Millau,
bp_rialto::Rialto,
crate::xcm_config::OnMillauBlobDispatcher,
bridge_runtime_common::messages_xcm_extension::XcmRouterWeigher<crate::DbWeight>,
>;

/// Maximal outbound payload size of Millau -> RialtoParachain messages.
pub type ToRialtoParachainMaximalOutboundPayloadSize =
Expand Down
9 changes: 8 additions & 1 deletion bin/millau/runtime/src/xcm_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,12 @@ pub type Barrier = (
AllowKnownQueryResponses<XcmPallet>,
);

/// Dispatches received XCM messages from other chain.
pub type OnMillauBlobDispatcher = xcm_builder::BridgeBlobDispatcher<
crate::xcm_config::XcmRouter,
crate::xcm_config::UniversalLocation,
>;

/// XCM weigher type.
pub type XcmWeigher = xcm_builder::FixedWeightBounds<BaseXcmWeight, RuntimeCall, MaxInstructions>;

Expand Down Expand Up @@ -249,7 +255,7 @@ impl XcmBridge for ToRialtoParachainBridge {
XCM_LANE_PARACHAIN
}
}

/*
#[cfg(test)]
mod tests {
use super::*;
Expand Down Expand Up @@ -324,3 +330,4 @@ mod tests {
})
}
}
*/
7 changes: 6 additions & 1 deletion bin/rialto-parachain/runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -435,6 +435,10 @@ pub type Barrier = (
// ^^^ Parent & its unit plurality gets free execution
);

/// Dispatches received XCM messages from other chain.
pub type OnRialtoParachainBlobDispatcher =
xcm_builder::BridgeBlobDispatcher<XcmRouter, UniversalLocation>;

/// XCM weigher type.
pub type XcmWeigher = FixedWeightBounds<UnitWeightCost, RuntimeCall, MaxInstructions>;

Expand Down Expand Up @@ -871,7 +875,7 @@ cumulus_pallet_parachain_system::register_validate_block!(
BlockExecutor = cumulus_pallet_aura_ext::BlockExecutor::<Runtime, Executive>,
CheckInherents = CheckInherents,
);

/*
#[cfg(test)]
mod tests {
use super::*;
Expand Down Expand Up @@ -966,3 +970,4 @@ mod tests {
check_additional_signed::<SignedExtra, bp_rialto_parachain::SignedExtension>();
}
}
*/
15 changes: 8 additions & 7 deletions bin/rialto-parachain/runtime/src/millau_messages.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,15 +51,16 @@ pub type ToMillauMessageVerifier =
messages::source::FromThisChainMessageVerifier<WithMillauMessageBridge>;

/// Message payload for Millau -> RialtoParachain messages.
pub type FromMillauMessagePayload = messages::target::FromBridgedChainMessagePayload<RuntimeCall>;
pub type FromMillauMessagePayload = messages::target::FromBridgedChainMessagePayload;

/// Call-dispatch based message dispatch for Millau -> RialtoParachain messages.
pub type FromMillauMessageDispatch = messages::target::FromBridgedChainMessageDispatch<
WithMillauMessageBridge,
xcm_executor::XcmExecutor<crate::XcmConfig>,
crate::XcmWeigher,
WeightCredit,
>;
pub type FromMillauMessageDispatch =
bridge_runtime_common::messages_xcm_extension::XcmBlobMessageDispatch<
bp_rialto_parachain::RialtoParachain,
bp_millau::Millau,
crate::OnRialtoParachainBlobDispatcher,
bridge_runtime_common::messages_xcm_extension::XcmRouterWeigher<()>,
>;

/// Messages proof for Millau -> RialtoParachain messages.
pub type FromMillauMessagesProof = messages::target::FromBridgedChainMessagesProof<bp_millau::Hash>;
Expand Down
15 changes: 8 additions & 7 deletions bin/rialto/runtime/src/millau_messages.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,15 +48,16 @@ pub type ToMillauMessageVerifier =
messages::source::FromThisChainMessageVerifier<WithMillauMessageBridge>;

/// Message payload for Millau -> Rialto messages.
pub type FromMillauMessagePayload = messages::target::FromBridgedChainMessagePayload<RuntimeCall>;
pub type FromMillauMessagePayload = messages::target::FromBridgedChainMessagePayload;

/// Call-dispatch based message dispatch for Millau -> Rialto messages.
pub type FromMillauMessageDispatch = messages::target::FromBridgedChainMessageDispatch<
WithMillauMessageBridge,
xcm_executor::XcmExecutor<crate::xcm_config::XcmConfig>,
crate::xcm_config::XcmWeigher,
WeightCredit,
>;
pub type FromMillauMessageDispatch =
bridge_runtime_common::messages_xcm_extension::XcmBlobMessageDispatch<
bp_rialto::Rialto,
bp_millau::Millau,
crate::xcm_config::OnRialtoBlobDispatcher,
bridge_runtime_common::messages_xcm_extension::XcmRouterWeigher<crate::DbWeight>,
>;

/// Messages proof for Millau -> Rialto messages.
pub type FromMillauMessagesProof = messages::target::FromBridgedChainMessagesProof<bp_millau::Hash>;
Expand Down
9 changes: 8 additions & 1 deletion bin/rialto/runtime/src/xcm_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,12 @@ pub type Barrier = (
AllowKnownQueryResponses<XcmPallet>,
);

/// Dispatches received XCM messages from other chain.
pub type OnRialtoBlobDispatcher = xcm_builder::BridgeBlobDispatcher<
crate::xcm_config::XcmRouter,
crate::xcm_config::UniversalLocation,
>;

/// Incoming XCM weigher type.
pub type XcmWeigher = xcm_builder::FixedWeightBounds<BaseXcmWeight, RuntimeCall, MaxInstructions>;

Expand Down Expand Up @@ -214,7 +220,7 @@ impl XcmBridge for ToMillauBridge {
bp_messages::LaneId([0, 0, 0, 0])
}
}

/*
#[cfg(test)]
mod tests {
use super::*;
Expand Down Expand Up @@ -283,3 +289,4 @@ mod tests {
})
}
}
*/
144 changes: 2 additions & 142 deletions bin/runtime-common/src/messages.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ use bp_runtime::{
messages::MessageDispatchResult, Chain, ChainId, RawStorageProof, Size, StorageProofChecker,
StorageProofError,
};
use codec::{Decode, DecodeLimit, Encode};
use codec::{Decode, Encode};
use frame_support::{traits::Get, weights::Weight, RuntimeDebug};
use hash_db::Hasher;
use scale_info::TypeInfo;
Expand Down Expand Up @@ -409,35 +409,7 @@ pub mod target {
use super::*;

/// Decoded Bridged -> This message payload.
#[derive(RuntimeDebug, PartialEq, Eq)]
pub struct FromBridgedChainMessagePayload<Call> {
/// Data that is actually sent over the wire.
pub xcm: (xcm::v3::MultiLocation, xcm::v3::Xcm<Call>),
/// Weight of the message, computed by the weigher. Unknown initially.
pub weight: Option<Weight>,
}

impl<Call: Decode> Decode for FromBridgedChainMessagePayload<Call> {
fn decode<I: codec::Input>(input: &mut I) -> Result<Self, codec::Error> {
let _: codec::Compact<u32> = Decode::decode(input)?;
type XcmPairType<Call> = (xcm::v3::MultiLocation, xcm::v3::Xcm<Call>);
Ok(FromBridgedChainMessagePayload {
xcm: XcmPairType::<Call>::decode_with_depth_limit(
sp_api::MAX_EXTRINSIC_DEPTH,
input,
)?,
weight: None,
})
}
}

impl<Call> From<(xcm::v3::MultiLocation, xcm::v3::Xcm<Call>)>
for FromBridgedChainMessagePayload<Call>
{
fn from(xcm: (xcm::v3::MultiLocation, xcm::v3::Xcm<Call>)) -> Self {
FromBridgedChainMessagePayload { xcm, weight: None }
}
}
pub type FromBridgedChainMessagePayload = Vec<u8>;

/// Messages proof from bridged chain:
///
Expand Down Expand Up @@ -470,118 +442,6 @@ pub mod target {
}
}

/// Dispatching Bridged -> This chain messages.
#[derive(RuntimeDebug, Clone, Copy)]
pub struct FromBridgedChainMessageDispatch<B, XcmExecutor, XcmWeigher, WeightCredit> {
_marker: PhantomData<(B, XcmExecutor, XcmWeigher, WeightCredit)>,
}

impl<B: MessageBridge, XcmExecutor, XcmWeigher, WeightCredit>
MessageDispatch<AccountIdOf<ThisChain<B>>>
for FromBridgedChainMessageDispatch<B, XcmExecutor, XcmWeigher, WeightCredit>
where
XcmExecutor: xcm::v3::ExecuteXcm<CallOf<ThisChain<B>>>,
XcmWeigher: xcm_executor::traits::WeightBounds<CallOf<ThisChain<B>>>,
WeightCredit: Get<Weight>,
{
type DispatchPayload = FromBridgedChainMessagePayload<CallOf<ThisChain<B>>>;
type DispatchLevelResult = ();

fn dispatch_weight(
message: &mut DispatchMessage<Self::DispatchPayload>,
) -> frame_support::weights::Weight {
match message.data.payload {
Ok(ref mut payload) => {
// I have no idea why this method takes `&mut` reference and there's nothing
// about that in documentation. Hope it'll only mutate iff error is returned.
let weight = XcmWeigher::weight(&mut payload.xcm.1);
let weight = weight.unwrap_or_else(|e| {
log::debug!(
target: crate::LOG_TARGET_BRIDGE_DISPATCH,
"Failed to compute dispatch weight of incoming XCM message {:?}/{}: {:?}",
message.key.lane_id,
message.key.nonce,
e,
);

// we shall return 0 and then the XCM executor will fail to execute XCM
// if we'll return something else (e.g. maximal value), the lane may stuck
Weight::zero()
});

payload.weight = Some(weight);
weight
},
_ => Weight::zero(),
}
}

fn dispatch(
_relayer_account: &AccountIdOf<ThisChain<B>>,
message: DispatchMessage<Self::DispatchPayload>,
) -> MessageDispatchResult<Self::DispatchLevelResult> {
let message_id = (message.key.lane_id, message.key.nonce);
let do_dispatch = move || -> sp_std::result::Result<Outcome, codec::Error> {
let FromBridgedChainMessagePayload { xcm: (location, xcm), weight: weight_limit } =
message.data.payload?;
log::trace!(
target: crate::LOG_TARGET_BRIDGE_DISPATCH,
"Going to execute message {:?} (weight limit: {:?}): {:?} {:?}",
message_id,
weight_limit,
location,
xcm,
);
let hash = message_id.using_encoded(sp_io::hashing::blake2_256);

// if this cod will end up in production, this most likely needs to be set to zero
let weight_credit = WeightCredit::get();

let xcm_outcome = XcmExecutor::execute_xcm_in_credit(
location,
xcm,
hash,
weight_limit.unwrap_or_else(Weight::zero),
weight_credit,
);
Ok(xcm_outcome)
};

let xcm_outcome = do_dispatch();
match xcm_outcome {
Ok(outcome) => {
log::trace!(
target: crate::LOG_TARGET_BRIDGE_DISPATCH,
"Incoming message {:?} dispatched with result: {:?}",
message_id,
outcome,
);
match outcome.ensure_execution() {
Ok(_weight) => (),
Err(e) => {
log::error!(
target: crate::LOG_TARGET_BRIDGE_DISPATCH,
"Incoming message {:?} was not dispatched, error: {:?}",
message_id,
e,
);
},
}
},
Err(e) => {
log::error!(
target: crate::LOG_TARGET_BRIDGE_DISPATCH,
"Incoming message {:?} was not dispatched, codec error: {:?}",
message_id,
e,
);
},
}

MessageDispatchResult { unspent_weight: Weight::zero(), dispatch_level_result: () }
}
}

/// Return maximal dispatch weight of the message we're able to receive.
pub fn maximal_incoming_message_dispatch_weight(maximal_extrinsic_weight: Weight) -> Weight {
maximal_extrinsic_weight / 2
Expand Down
31 changes: 30 additions & 1 deletion bin/runtime-common/src/messages_xcm_extension.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,42 @@ use bp_messages::{
};
use bp_runtime::{messages::MessageDispatchResult, AccountIdOf, Chain};
use codec::{Decode, Encode};
use frame_support::{dispatch::Weight, traits::Get, CloneNoBound, EqNoBound, PartialEqNoBound};
use frame_support::{
dispatch::Weight, traits::Get, weights::RuntimeDbWeight, CloneNoBound, EqNoBound,
PartialEqNoBound,
};
use scale_info::TypeInfo;
use sp_std::marker::PhantomData;
use xcm_builder::{DispatchBlob, DispatchBlobError, HaulBlob, HaulBlobError};

/// Plain "XCM" payload, which we transfer through bridge
pub type XcmAsPlainPayload = sp_std::prelude::Vec<u8>;

// TODO: below are just rough estimations. Other things also happen there (including hashing and so
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bkontur I've copypasted this XcmRouterWeigher from RBH/WBH code. I think we'll be using it for all bridge hubs, right? Could you please check my big comment below - am I right there?

Right now the biggest problem here is that it only returns the ref_time component and the proof_size is set to zero. Which is obviously wrong. I see two options to fix it:

  • come up with some good estimation of the proof_size and return it here. Pros: easy and fast. Cons: inaccurate + we need some mechanism to verify that it is still actual (if something changes in queue implementation);
  • remove this XcmRouterWeigher at all and add some benchmarks to the runtimes, which will measure the actual weight of the queue.push() (for us it'll be the send_fragment in the cumulus-pallet-xcmp-queue).

WDYT?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Submitted #1986 to track this

// on). Shall we do some benchmarking???

/// Simple weigher for incoming XCM dispatch at **bridge hubs** to use with
/// `XcmBlobMessageDispatch`.
///
/// By our design, message at bridge hub is simply pushed to some other queue. This implementation
/// is for this case only. If your runtime performs some other actions with incoming XCM messages,
/// you shall use your own implementation.
///
/// If message is redirected to the relay chain, then `ParentAsUmp` is used and it roughly does
/// 1 db read and 1 db write (in its `send_upward_message` method).
///
/// If message is redirected to some sibling parachain, then `XcmpQueue` is used and
/// it roughty does 2 db reads and 2 db writes (in its `SendXcm` implementation).
///
/// The difference is not that big, so let's choose maximal.
pub struct XcmRouterWeigher<T>(PhantomData<T>);

impl<T: Get<RuntimeDbWeight>> Get<Weight> for XcmRouterWeigher<T> {
fn get() -> Weight {
T::get().reads_writes(2, 2)
}
}

/// Message dispatch result type for single message
#[derive(CloneNoBound, EqNoBound, PartialEqNoBound, Encode, Decode, Debug, TypeInfo)]
pub enum XcmBlobMessageDispatchResult {
Expand Down
Loading