From 6540f74dc857f2faac6349afbb0b69ace781a01c Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Thu, 23 Mar 2023 10:44:53 +0300 Subject: [PATCH] Remove deprecated code from bridge-runtime-common (#1983) * removed FromBridgedChainMessageDispatch in favor of XcmBlobMessageDispatch * use HaulBlobExporter/HaulBlobExporterAdapter instead of XcmBridge/XcmBridgeAdapter * tests for sending/dispatching messages * use new schema in testnet bridges + some cleanup * clippy * spelling + added TODO * cleanup some checks * benchmarks compilation * all is XCM * updated README.md * ref issue from TODO --- README.md | 9 +- bin/millau/runtime/src/lib.rs | 8 +- bin/millau/runtime/src/rialto_messages.rs | 68 ++-- .../runtime/src/rialto_parachain_messages.rs | 70 ++-- bin/millau/runtime/src/xcm_config.rs | 304 +++++++++------ bin/rialto-parachain/runtime/Cargo.toml | 2 + bin/rialto-parachain/runtime/src/lib.rs | 177 ++++----- .../runtime/src/millau_messages.rs | 64 ++-- bin/rialto/runtime/src/millau_messages.rs | 68 ++-- bin/rialto/runtime/src/xcm_config.rs | 177 +++++---- bin/runtime-common/src/integrity.rs | 2 +- bin/runtime-common/src/messages.rs | 355 ++---------------- .../src/messages_xcm_extension.rs | 32 +- bin/runtime-common/src/mock.rs | 46 +-- .../bridges/common/generate_messages.sh | 3 +- .../bridges/rialto-millau/docker-compose.yml | 23 -- ...messages-to-millau-generator-entrypoint.sh | 5 +- ...messages-to-rialto-generator-entrypoint.sh | 5 +- .../relay-millau-rialto-entrypoint.sh | 1 - ...messages-to-millau-generator-entrypoint.sh | 5 +- ...o-rialto-parachain-generator-entrypoint.sh | 5 +- deployments/networks/millau.yml | 2 +- deployments/networks/rialto-parachain.yml | 2 +- deployments/networks/rialto.yml | 2 +- primitives/runtime/src/lib.rs | 4 +- relays/bin-substrate/src/chains/millau.rs | 29 +- relays/bin-substrate/src/chains/rialto.rs | 21 +- .../src/chains/rialto_parachain.rs | 22 +- relays/bin-substrate/src/cli/bridge.rs | 22 -- .../bin-substrate/src/cli/encode_message.rs | 18 +- relays/bin-substrate/src/cli/send_message.rs | 7 +- scripts/send-message-from-millau-rialto.sh | 2 +- scripts/send-message-from-rialto-millau.sh | 2 +- 33 files changed, 628 insertions(+), 934 deletions(-) diff --git a/README.md b/README.md index b5885026426..aab6007d2cd 100644 --- a/README.md +++ b/README.md @@ -215,18 +215,19 @@ In this section we'll show you how to quickly send a bridge message. The message After sending a message you will see the following logs showing a message was successfully sent: ``` -INFO bridge Sending message to Rialto. Size: 5. +INFO bridge Sending message to Rialto. Size: 11. TRACE bridge Sent transaction to Millau node: 0x5e68... ``` And at the Rialto node logs you'll something like this: ``` -... runtime::bridge-dispatch: Going to execute message ([0, 0, 0, 0], 1) (...), Trap(43)]) -... runtime::bridge-dispatch: Incoming message ([0, 0, 0, 0], 1) dispatched with result: Incomplete(2000000000, Trap(43)) +... runtime::bridge-messages: Received messages: total=1, valid=1. Weight used: Weight(ref_time: 1215065371, proof_size: 48559)/Weight(ref_time: 1215065371, proof_size: 54703). ``` -It means that the message has been delivered and successfully dispatched. +It means that the message has been delivered and dispatched. Message may be dispatched with an +error, though - the goal of our test bridge is to ensure that messages are successfully delivered +and all involved components are working. ## Full Network Docker Compose Setup diff --git a/bin/millau/runtime/src/lib.rs b/bin/millau/runtime/src/lib.rs index 574b0569875..f08f5e1c749 100644 --- a/bin/millau/runtime/src/lib.rs +++ b/bin/millau/runtime/src/lib.rs @@ -1021,10 +1021,8 @@ impl_runtime_apis! { } fn is_relayer_rewarded(relayer: &Self::AccountId) -> bool { - use bridge_runtime_common::messages::MessageBridge; - let lane = >::bench_lane_id(); - let bridged_chain_id = WithRialtoParachainMessageBridge::BRIDGED_CHAIN_ID; + let bridged_chain_id = bp_runtime::RIALTO_PARACHAIN_CHAIN_ID; pallet_bridge_relayers::Pallet::::relayer_reward( relayer, RewardsAccountParams::new(lane, bridged_chain_id, RewardsAccountOwner::BridgedChain) @@ -1054,10 +1052,8 @@ impl_runtime_apis! { } fn is_relayer_rewarded(relayer: &Self::AccountId) -> bool { - use bridge_runtime_common::messages::MessageBridge; - let lane = >::bench_lane_id(); - let bridged_chain_id = WithRialtoMessageBridge::BRIDGED_CHAIN_ID; + let bridged_chain_id = bp_runtime::RIALTO_CHAIN_ID; pallet_bridge_relayers::Pallet::::relayer_reward( relayer, RewardsAccountParams::new(lane, bridged_chain_id, RewardsAccountOwner::BridgedChain) diff --git a/bin/millau/runtime/src/rialto_messages.rs b/bin/millau/runtime/src/rialto_messages.rs index 919fac86899..311805c9849 100644 --- a/bin/millau/runtime/src/rialto_messages.rs +++ b/bin/millau/runtime/src/rialto_messages.rs @@ -16,14 +16,18 @@ //! Everything required to serve Millau <-> Rialto messages. -use crate::{RialtoGrandpaInstance, Runtime, RuntimeCall, RuntimeOrigin}; - -use bp_messages::{LaneId, MessageNonce}; -use bp_runtime::{ChainId, MILLAU_CHAIN_ID, RIALTO_CHAIN_ID}; -use bridge_runtime_common::messages::{ - self, source::TargetHeaderChainAdapter, target::SourceHeaderChainAdapter, MessageBridge, +use crate::{RialtoGrandpaInstance, Runtime, RuntimeOrigin, WithRialtoMessagesInstance}; + +use bp_messages::LaneId; +use bridge_runtime_common::{ + messages::{ + self, source::TargetHeaderChainAdapter, target::SourceHeaderChainAdapter, MessageBridge, + }, + messages_xcm_extension::{XcmBlobHauler, XcmBlobHaulerAdapter}, }; use frame_support::{parameter_types, weights::Weight, RuntimeDebug}; +use xcm::latest::prelude::*; +use xcm_builder::HaulBlobExporter; /// Default lane that is used to send messages to Rialto. pub const XCM_LANE: LaneId = LaneId([0, 0, 0, 0]); @@ -48,7 +52,7 @@ pub type ToRialtoMessageVerifier = messages::source::FromThisChainMessageVerifier; /// Message payload for Rialto -> Millau messages. -pub type FromRialtoMessagePayload = messages::target::FromBridgedChainMessagePayload; +pub type FromRialtoMessagePayload = messages::target::FromBridgedChainMessagePayload; /// Messages proof for Rialto -> Millau messages. pub type FromRialtoMessagesProof = messages::target::FromBridgedChainMessagesProof; @@ -58,12 +62,13 @@ pub type ToRialtoMessagesDeliveryProof = messages::source::FromBridgedChainMessagesDeliveryProof; /// Call-dispatch based message dispatch for Rialto -> Millau messages. -pub type FromRialtoMessageDispatch = messages::target::FromBridgedChainMessageDispatch< - WithRialtoMessageBridge, - xcm_executor::XcmExecutor, - 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, + >; /// Maximal outbound payload size of Millau -> Rialto messages. pub type ToRialtoMaximalOutboundPayloadSize = @@ -74,8 +79,6 @@ pub type ToRialtoMaximalOutboundPayloadSize = pub struct WithRialtoMessageBridge; impl MessageBridge for WithRialtoMessageBridge { - const THIS_CHAIN_ID: ChainId = MILLAU_CHAIN_ID; - const BRIDGED_CHAIN_ID: ChainId = RIALTO_CHAIN_ID; const BRIDGED_MESSAGES_PALLET_NAME: &'static str = bp_millau::WITH_MILLAU_MESSAGES_PALLET_NAME; type ThisChain = Millau; @@ -94,15 +97,6 @@ impl messages::UnderlyingChainProvider for Millau { impl messages::ThisChainWithMessages for Millau { type RuntimeOrigin = RuntimeOrigin; - type RuntimeCall = RuntimeCall; - - fn is_message_accepted(_send_origin: &Self::RuntimeOrigin, _lane: &LaneId) -> bool { - true - } - - fn maximal_pending_messages_at_outbound_lane() -> MessageNonce { - MessageNonce::MAX - } } /// Rialto chain from message lane point of view. @@ -117,9 +111,29 @@ impl messages::UnderlyingChainProvider for Rialto { type Chain = bp_rialto::Rialto; } -impl messages::BridgedChainWithMessages for Rialto { - fn verify_dispatch_weight(_message_payload: &[u8]) -> bool { - true +impl messages::BridgedChainWithMessages for Rialto {} + +/// Export XCM messages to be relayed to Rialto. +pub type ToRialtoBlobExporter = HaulBlobExporter< + XcmBlobHaulerAdapter, + crate::xcm_config::RialtoNetwork, + (), +>; + +/// To-Rialto XCM hauler. +pub struct ToRialtoXcmBlobHauler; + +impl XcmBlobHauler for ToRialtoXcmBlobHauler { + type MessageSender = pallet_bridge_messages::Pallet; + type MessageSenderOrigin = RuntimeOrigin; + + fn message_sender_origin() -> RuntimeOrigin { + pallet_xcm::Origin::from(MultiLocation::new(1, crate::xcm_config::UniversalLocation::get())) + .into() + } + + fn xcm_lane() -> LaneId { + XCM_LANE } } diff --git a/bin/millau/runtime/src/rialto_parachain_messages.rs b/bin/millau/runtime/src/rialto_parachain_messages.rs index 1cfdc9c8f49..17495e26ae2 100644 --- a/bin/millau/runtime/src/rialto_parachain_messages.rs +++ b/bin/millau/runtime/src/rialto_parachain_messages.rs @@ -16,14 +16,20 @@ //! Everything required to serve Millau <-> RialtoParachain messages. -use crate::{Runtime, RuntimeCall, RuntimeOrigin, WithRialtoParachainsInstance}; +use crate::{ + Runtime, RuntimeOrigin, WithRialtoParachainMessagesInstance, WithRialtoParachainsInstance, +}; -use bp_messages::{LaneId, MessageNonce}; -use bp_runtime::{ChainId, MILLAU_CHAIN_ID, RIALTO_PARACHAIN_CHAIN_ID}; -use bridge_runtime_common::messages::{ - self, source::TargetHeaderChainAdapter, target::SourceHeaderChainAdapter, MessageBridge, +use bp_messages::LaneId; +use bridge_runtime_common::{ + messages::{ + self, source::TargetHeaderChainAdapter, target::SourceHeaderChainAdapter, MessageBridge, + }, + messages_xcm_extension::{XcmBlobHauler, XcmBlobHaulerAdapter}, }; use frame_support::{parameter_types, weights::Weight, RuntimeDebug}; +use xcm::latest::prelude::*; +use xcm_builder::HaulBlobExporter; /// Default lane that is used to send messages to Rialto parachain. pub const XCM_LANE: LaneId = LaneId([0, 0, 0, 0]); @@ -48,16 +54,16 @@ pub type ToRialtoParachainMessageVerifier = messages::source::FromThisChainMessageVerifier; /// Message payload for RialtoParachain -> Millau messages. -pub type FromRialtoParachainMessagePayload = - messages::target::FromBridgedChainMessagePayload; +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::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, + >; /// Maximal outbound payload size of Millau -> RialtoParachain messages. pub type ToRialtoParachainMaximalOutboundPayloadSize = @@ -68,8 +74,6 @@ pub type ToRialtoParachainMaximalOutboundPayloadSize = pub struct WithRialtoParachainMessageBridge; impl MessageBridge for WithRialtoParachainMessageBridge { - const THIS_CHAIN_ID: ChainId = MILLAU_CHAIN_ID; - const BRIDGED_CHAIN_ID: ChainId = RIALTO_PARACHAIN_CHAIN_ID; const BRIDGED_MESSAGES_PALLET_NAME: &'static str = bp_millau::WITH_MILLAU_MESSAGES_PALLET_NAME; type ThisChain = Millau; @@ -90,16 +94,7 @@ impl messages::UnderlyingChainProvider for Millau { } impl messages::ThisChainWithMessages for Millau { - type RuntimeCall = RuntimeCall; type RuntimeOrigin = RuntimeOrigin; - - fn is_message_accepted(_send_origin: &Self::RuntimeOrigin, _lane: &LaneId) -> bool { - true - } - - fn maximal_pending_messages_at_outbound_lane() -> MessageNonce { - MessageNonce::MAX - } } /// RialtoParachain chain from message lane point of view. @@ -116,8 +111,29 @@ impl messages::UnderlyingChainProvider for RialtoParachain { type Chain = bp_rialto_parachain::RialtoParachain; } -impl messages::BridgedChainWithMessages for RialtoParachain { - fn verify_dispatch_weight(_message_payload: &[u8]) -> bool { - true +impl messages::BridgedChainWithMessages for RialtoParachain {} + +/// Export XCM messages to be relayed to Rialto. +pub type ToRialtoParachainBlobExporter = HaulBlobExporter< + XcmBlobHaulerAdapter, + crate::xcm_config::RialtoParachainNetwork, + (), +>; + +/// To-RialtoParachain XCM hauler. +pub struct ToRialtoParachainXcmBlobHauler; + +impl XcmBlobHauler for ToRialtoParachainXcmBlobHauler { + type MessageSender = + pallet_bridge_messages::Pallet; + type MessageSenderOrigin = RuntimeOrigin; + + fn message_sender_origin() -> RuntimeOrigin { + pallet_xcm::Origin::from(MultiLocation::new(1, crate::xcm_config::UniversalLocation::get())) + .into() + } + + fn xcm_lane() -> LaneId { + XCM_LANE } } diff --git a/bin/millau/runtime/src/xcm_config.rs b/bin/millau/runtime/src/xcm_config.rs index aaaa7bf642d..c477a684526 100644 --- a/bin/millau/runtime/src/xcm_config.rs +++ b/bin/millau/runtime/src/xcm_config.rs @@ -17,18 +17,12 @@ //! XCM configurations for the Millau runtime. use super::{ - rialto_messages::{WithRialtoMessageBridge, XCM_LANE}, - rialto_parachain_messages::{WithRialtoParachainMessageBridge, XCM_LANE as XCM_LANE_PARACHAIN}, - AccountId, AllPalletsWithSystem, Balances, Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin, - WithRialtoMessagesInstance, WithRialtoParachainMessagesInstance, XcmPallet, + rialto_messages::ToRialtoBlobExporter, + rialto_parachain_messages::ToRialtoParachainBlobExporter, AccountId, AllPalletsWithSystem, + Balances, Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin, XcmPallet, }; -use bp_messages::LaneId; use bp_millau::WeightToFee; -use bp_rialto_parachain::RIALTO_PARACHAIN_ID; -use bridge_runtime_common::{ - messages::source::{XcmBridge, XcmBridgeAdapter}, - CustomNetworkId, -}; +use bridge_runtime_common::CustomNetworkId; use frame_support::{ parameter_types, traits::{ConstU32, Everything, Nothing}, @@ -36,10 +30,11 @@ use frame_support::{ }; use xcm::latest::prelude::*; use xcm_builder::{ - AccountId32Aliases, AllowKnownQueryResponses, AllowTopLevelPaidExecutionFrom, - CurrencyAdapter as XcmCurrencyAdapter, IsConcrete, MintLocation, SignedAccountId32AsNative, - SignedToAccountId32, SovereignSignedViaLocation, TakeWeightCredit, UsingComponents, + AccountId32Aliases, CurrencyAdapter as XcmCurrencyAdapter, IsConcrete, MintLocation, + SignedAccountId32AsNative, SignedToAccountId32, SovereignSignedViaLocation, TakeWeightCredit, + UsingComponents, }; +use xcm_executor::traits::ExportXcm; parameter_types! { /// The location of the `MLAU` token, from the context of this chain. Since this token is native to this @@ -101,32 +96,28 @@ parameter_types! { pub const MaxInstructions: u32 = 100; } -/// The XCM router. When we want to send an XCM message, we use this type. It amalgamates all of our -/// individual routers. -pub type XcmRouter = ( - // Router to send messages to Rialto. - XcmBridgeAdapter, - // Router to send messages to RialtoParachains. - XcmBridgeAdapter, -); +/// The XCM router. We are not sending messages to sibling/parent/child chains here. +pub type XcmRouter = (); /// The barriers one of which must be passed for an XCM message to be executed. pub type Barrier = ( // Weight that is paid for may be consumed. TakeWeightCredit, - // If the message is one that immediately attemps to pay for execution, then allow it. - AllowTopLevelPaidExecutionFrom, - // Expected responses are OK. - AllowKnownQueryResponses, ); +/// 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; pub struct XcmConfig; impl xcm_executor::Config for XcmConfig { type RuntimeCall = RuntimeCall; - type XcmSender = XcmRouter; + type XcmSender = (); type AssetTransactor = LocalAssetTransactor; type OriginConverter = LocalOriginConverter; type IsReserve = (); @@ -145,7 +136,7 @@ impl xcm_executor::Config for XcmConfig { type PalletInstancesInfo = AllPalletsWithSystem; type MaxAssetsIntoHolding = ConstU32<64>; type FeeManager = (); - type MessageExporter = (); + type MessageExporter = ToRialtoOrRialtoParachainSwitchExporter; type UniversalAliases = Nothing; type CallDispatcher = RuntimeCall; type SafeCallFilter = Everything; @@ -160,7 +151,7 @@ pub type LocalOriginToLocation = ( #[cfg(feature = "runtime-benchmarks")] parameter_types! { - pub ReachableDest: Option = todo!("We dont use benchmarks for pallet_xcm, so if you hit this message, you need to remove this and define value instead"); + pub ReachableDest: Option = None; } impl pallet_xcm::Config for Runtime { @@ -170,7 +161,7 @@ impl pallet_xcm::Config for Runtime { // the DOT to send from the Relay-chain). But it's useless until we bring in XCM v3 which will // make `DescendOrigin` a bit more useful. type SendXcmOrigin = xcm_builder::EnsureXcmOrigin; - type XcmRouter = XcmRouter; + type XcmRouter = (); // Anyone can execute XCM messages locally. type ExecuteXcmOrigin = xcm_builder::EnsureXcmOrigin; type XcmExecuteFilter = Everything; @@ -197,70 +188,66 @@ impl pallet_xcm::Config for Runtime { type ReachableDest = ReachableDest; } -/// With-Rialto bridge. -pub struct ToRialtoBridge; - -impl XcmBridge for ToRialtoBridge { - type MessageBridge = WithRialtoMessageBridge; - type MessageSender = pallet_bridge_messages::Pallet; - - fn universal_location() -> InteriorMultiLocation { - UniversalLocation::get() +pub struct ToRialtoOrRialtoParachainSwitchExporter; + +impl ExportXcm for ToRialtoOrRialtoParachainSwitchExporter { + type Ticket = (NetworkId, (sp_std::prelude::Vec, XcmHash)); + + fn validate( + network: NetworkId, + channel: u32, + universal_source: &mut Option, + destination: &mut Option, + message: &mut Option>, + ) -> SendResult { + if network == RialtoNetwork::get() { + ToRialtoBlobExporter::validate(network, channel, universal_source, destination, message) + .map(|result| ((RialtoNetwork::get(), result.0), result.1)) + } else if network == RialtoParachainNetwork::get() { + ToRialtoParachainBlobExporter::validate( + network, + channel, + universal_source, + destination, + message, + ) + .map(|result| ((RialtoParachainNetwork::get(), result.0), result.1)) + } else { + Err(SendError::Unroutable) + } } - fn verify_destination(dest: &MultiLocation) -> bool { - matches!(*dest, MultiLocation { parents: 1, interior: X1(GlobalConsensus(r)) } if r == RialtoNetwork::get()) - } - - fn build_destination() -> MultiLocation { - let dest: InteriorMultiLocation = RialtoNetwork::get().into(); - let here = UniversalLocation::get(); - dest.relative_to(&here) - } - - fn xcm_lane() -> LaneId { - XCM_LANE - } -} - -/// With-RialtoParachain bridge. -pub struct ToRialtoParachainBridge; - -impl XcmBridge for ToRialtoParachainBridge { - type MessageBridge = WithRialtoParachainMessageBridge; - type MessageSender = - pallet_bridge_messages::Pallet; - - fn universal_location() -> InteriorMultiLocation { - UniversalLocation::get() - } - - fn verify_destination(dest: &MultiLocation) -> bool { - matches!(*dest, MultiLocation { parents: 1, interior: X2(GlobalConsensus(r), Parachain(RIALTO_PARACHAIN_ID)) } if r == RialtoNetwork::get()) - } - - fn build_destination() -> MultiLocation { - let dest: InteriorMultiLocation = RialtoParachainNetwork::get().into(); - let here = UniversalLocation::get(); - dest.relative_to(&here) - } - - fn xcm_lane() -> LaneId { - XCM_LANE_PARACHAIN + fn deliver(ticket: Self::Ticket) -> Result { + let (network, ticket) = ticket; + if network == RialtoNetwork::get() { + ToRialtoBlobExporter::deliver(ticket) + } else if network == RialtoParachainNetwork::get() { + ToRialtoParachainBlobExporter::deliver(ticket) + } else { + Err(SendError::Unroutable) + } } } #[cfg(test)] mod tests { use super::*; - use crate::rialto_messages::WeightCredit; + use crate::{ + rialto_messages::FromRialtoMessageDispatch, + rialto_parachain_messages::FromRialtoParachainMessageDispatch, DbWeight, + WithRialtoMessagesInstance, WithRialtoParachainMessagesInstance, + }; use bp_messages::{ target_chain::{DispatchMessage, DispatchMessageData, MessageDispatch}, - MessageKey, + LaneId, MessageKey, + }; + use bridge_runtime_common::messages_xcm_extension::{ + XcmBlobMessageDispatchResult, XcmRouterWeigher, }; - use bp_runtime::messages::MessageDispatchResult; - use bridge_runtime_common::messages::target::FromBridgedChainMessageDispatch; use codec::Encode; + use pallet_bridge_messages::OutboundLanes; + use sp_core::Get; + use xcm_executor::XcmExecutor; fn new_test_ext() -> sp_io::TestExternalities { sp_io::TestExternalities::new( @@ -268,59 +255,128 @@ mod tests { ) } + fn prepare_outbound_xcm_message(destination: NetworkId) -> Xcm { + vec![ExportMessage { + network: destination, + destination: destination.into(), + xcm: vec![Instruction::Trap(42)].into(), + }] + .into() + } + #[test] - fn xcm_messages_are_sent_using_bridge_router() { + fn xcm_messages_to_rialto_are_sent_using_bridge_exporter() { new_test_ext().execute_with(|| { - let xcm: Xcm<()> = vec![Instruction::Trap(42)].into(); - let expected_fee = MultiAssets::from((Here, 1_000_000_u128)); - let expected_hash = - ([0u8, 0u8, 0u8, 0u8], 1u64).using_encoded(sp_io::hashing::blake2_256); - - // message 1 to Rialto - let dest = (Parent, X1(GlobalConsensus(RialtoNetwork::get()))); - let send_result = send_xcm::(dest.into(), xcm.clone()); - assert_eq!(send_result, Ok((expected_hash, expected_fee.clone()))); - - // message 2 to RialtoParachain (expected hash is the same, since other lane is used) - let dest = - (Parent, X2(GlobalConsensus(RialtoNetwork::get()), Parachain(RIALTO_PARACHAIN_ID))); - let send_result = send_xcm::(dest.into(), xcm); - assert_eq!(send_result, Ok((expected_hash, expected_fee))); + // ensure that the there are no messages queued + assert_eq!( + OutboundLanes::::get( + crate::rialto_messages::XCM_LANE + ) + .latest_generated_nonce, + 0, + ); + + // export message instruction "sends" message to Rialto + XcmExecutor::::execute_xcm_in_credit( + Here, + prepare_outbound_xcm_message(RialtoNetwork::get()), + Default::default(), + Weight::MAX, + Weight::MAX, + ) + .ensure_complete() + .expect("runtime configuration must be correct"); + + // ensure that the message has been queued + assert_eq!( + OutboundLanes::::get( + crate::rialto_messages::XCM_LANE + ) + .latest_generated_nonce, + 1, + ); }) } #[test] - fn xcm_messages_from_rialto_are_dispatched() { - type XcmExecutor = xcm_executor::XcmExecutor; - type MessageDispatcher = FromBridgedChainMessageDispatch< - WithRialtoMessageBridge, - XcmExecutor, - XcmWeigher, - WeightCredit, - >; - + fn xcm_messages_to_rialto_parachain_are_sent_using_bridge_exporter() { new_test_ext().execute_with(|| { - let location: MultiLocation = - (Parent, X1(GlobalConsensus(RialtoNetwork::get()))).into(); - let xcm: Xcm = vec![Instruction::Trap(42)].into(); - - let mut incoming_message = DispatchMessage { - key: MessageKey { lane_id: LaneId([0, 0, 0, 0]), nonce: 1 }, - data: DispatchMessageData { payload: Ok((location, xcm).into()) }, - }; - - let dispatch_weight = MessageDispatcher::dispatch_weight(&mut incoming_message); - assert_eq!(dispatch_weight, BaseXcmWeight::get()); + // ensure that the there are no messages queued + assert_eq!( + OutboundLanes::::get( + crate::rialto_parachain_messages::XCM_LANE + ) + .latest_generated_nonce, + 0, + ); - let dispatch_result = - MessageDispatcher::dispatch(&AccountId::from([0u8; 32]), incoming_message); + // export message instruction "sends" message to Rialto + XcmExecutor::::execute_xcm_in_credit( + Here, + prepare_outbound_xcm_message(RialtoParachainNetwork::get()), + Default::default(), + Weight::MAX, + Weight::MAX, + ) + .ensure_complete() + .expect("runtime configuration must be correct"); + + // ensure that the message has been queued assert_eq!( - dispatch_result, - MessageDispatchResult { - unspent_weight: frame_support::weights::Weight::zero(), - dispatch_level_result: (), - } + OutboundLanes::::get( + crate::rialto_parachain_messages::XCM_LANE + ) + .latest_generated_nonce, + 1, ); }) } + + fn prepare_inbound_bridge_message() -> DispatchMessage> { + let xcm = xcm::VersionedXcm::::V3(vec![Instruction::Trap(42)].into()); + let location = + xcm::VersionedInteriorMultiLocation::V3(X1(GlobalConsensus(ThisNetwork::get()))); + // this is the `BridgeMessage` from polkadot xcm builder, but it has no constructor + // or public fields, so just tuple + let bridge_message = (location, xcm).encode(); + DispatchMessage { + key: MessageKey { lane_id: LaneId([0, 0, 0, 0]), nonce: 1 }, + data: DispatchMessageData { payload: Ok(bridge_message) }, + } + } + + #[test] + fn xcm_messages_from_rialto_are_dispatched() { + let mut incoming_message = prepare_inbound_bridge_message(); + + let dispatch_weight = FromRialtoMessageDispatch::dispatch_weight(&mut incoming_message); + assert_eq!(dispatch_weight, XcmRouterWeigher::::get()); + + // we care only about handing message to the XCM dispatcher, so we don't care about its + // actual dispatch + let dispatch_result = + FromRialtoMessageDispatch::dispatch(&AccountId::from([0u8; 32]), incoming_message); + assert!(matches!( + dispatch_result.dispatch_level_result, + XcmBlobMessageDispatchResult::NotDispatched(_), + )); + } + + #[test] + fn xcm_messages_from_rialto_parachain_are_dispatched() { + let mut incoming_message = prepare_inbound_bridge_message(); + + let dispatch_weight = + FromRialtoParachainMessageDispatch::dispatch_weight(&mut incoming_message); + assert_eq!(dispatch_weight, XcmRouterWeigher::::get()); + + // we care only about handing message to the XCM dispatcher, so we don't care about its + // actual dispatch + let dispatch_result = + FromRialtoMessageDispatch::dispatch(&AccountId::from([0u8; 32]), incoming_message); + assert!(matches!( + dispatch_result.dispatch_level_result, + XcmBlobMessageDispatchResult::NotDispatched(_), + )); + } } diff --git a/bin/rialto-parachain/runtime/Cargo.toml b/bin/rialto-parachain/runtime/Cargo.toml index ec8955e7fd1..ed193b4e681 100644 --- a/bin/rialto-parachain/runtime/Cargo.toml +++ b/bin/rialto-parachain/runtime/Cargo.toml @@ -111,6 +111,7 @@ std = [ "frame-support/std", "frame-executive/std", "frame-system/std", + "frame-system-rpc-runtime-api/std", "pallet-balances/std", "pallet-bridge-grandpa/std", "pallet-bridge-messages/std", @@ -118,6 +119,7 @@ std = [ "pallet-timestamp/std", "pallet-sudo/std", "pallet-transaction-payment/std", + "pallet-transaction-payment-rpc-runtime-api/std", "pallet-xcm/std", "parachain-info/std", "polkadot-parachain/std", diff --git a/bin/rialto-parachain/runtime/src/lib.rs b/bin/rialto-parachain/runtime/src/lib.rs index 3614bacdc10..58c6a8c673f 100644 --- a/bin/rialto-parachain/runtime/src/lib.rs +++ b/bin/rialto-parachain/runtime/src/lib.rs @@ -26,12 +26,7 @@ #[cfg(feature = "std")] include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs")); -use crate::millau_messages::{WithMillauMessageBridge, XCM_LANE}; - -use bridge_runtime_common::{ - generate_bridge_reject_obsolete_headers_and_messages, - messages::source::{XcmBridge, XcmBridgeAdapter}, -}; +use bridge_runtime_common::generate_bridge_reject_obsolete_headers_and_messages; use codec::{Decode, Encode}; use cumulus_pallet_parachain_system::AnyRelayNumber; use scale_info::TypeInfo; @@ -88,11 +83,10 @@ use pallet_xcm::XcmPassthrough; use polkadot_parachain::primitives::Sibling; use xcm::latest::prelude::*; use xcm_builder::{ - AccountId32Aliases, AllowTopLevelPaidExecutionFrom, AllowUnpaidExecutionFrom, CurrencyAdapter, - EnsureXcmOrigin, FixedWeightBounds, IsConcrete, NativeAsset, ParentAsSuperuser, ParentIsPreset, - RelayChainAsNative, SiblingParachainAsNative, SiblingParachainConvertsVia, - SignedAccountId32AsNative, SignedToAccountId32, SovereignSignedViaLocation, TakeWeightCredit, - UsingComponents, + AccountId32Aliases, CurrencyAdapter, EnsureXcmOrigin, FixedWeightBounds, IsConcrete, + NativeAsset, ParentAsSuperuser, ParentIsPreset, RelayChainAsNative, SiblingParachainAsNative, + SiblingParachainConvertsVia, SignedAccountId32AsNative, SignedToAccountId32, + SovereignSignedViaLocation, TakeWeightCredit, UsingComponents, }; use xcm_executor::{Config, XcmExecutor}; @@ -351,7 +345,7 @@ parameter_types! { pub const RelayLocation: MultiLocation = MultiLocation::parent(); pub const RelayNetwork: NetworkId = CustomNetworkId::Rialto.as_network_id(); pub RelayOrigin: RuntimeOrigin = cumulus_pallet_xcm::Origin::Relay.into(); - pub UniversalLocation: InteriorMultiLocation = X1(Parachain(ParachainInfo::parachain_id().into())); + pub UniversalLocation: InteriorMultiLocation = ThisNetwork::get().into(); /// The Millau network ID. pub const MillauNetwork: NetworkId = CustomNetworkId::Millau.as_network_id(); /// The RialtoParachain network ID. @@ -412,8 +406,8 @@ pub type XcmOriginToTransactDispatchOrigin = ( // the following constant must match the similar constant in the Millau runtime. parameter_types! { - /// The amount of weight an XCM operation takes. This is a safe overestimate. - pub const UnitWeightCost: Weight = Weight::from_parts(1_000_000, 64 * 1024); + /// The amount of weight an XCM operation takes. We don't care much about those values as we're on testnet. + pub const UnitWeightCost: Weight = Weight::from_parts(1_000_000, 1024); // One UNIT buys 1 second of weight. pub const WeightPrice: (MultiLocation, u128) = (MultiLocation::parent(), UNIT); pub const MaxInstructions: u32 = 100; @@ -428,12 +422,11 @@ match_types! { }; } -pub type Barrier = ( - TakeWeightCredit, - AllowTopLevelPaidExecutionFrom, - AllowUnpaidExecutionFrom, - // ^^^ Parent & its unit plurality gets free execution -); +pub type Barrier = TakeWeightCredit; + +/// Dispatches received XCM messages from other chain. +pub type OnRialtoParachainBlobDispatcher = + xcm_builder::BridgeBlobDispatcher; /// XCM weigher type. pub type XcmWeigher = FixedWeightBounds; @@ -441,7 +434,7 @@ pub type XcmWeigher = FixedWeightBounds; -/// The means for routing XCM messages which are not for local execution into the right message -/// queues. -pub type XcmRouter = ( - // Bridge is used to communicate with other relay chain (Millau). - XcmBridgeAdapter, -); - -/// With-Millau bridge. -pub struct ToMillauBridge; - -impl XcmBridge for ToMillauBridge { - type MessageBridge = WithMillauMessageBridge; - type MessageSender = pallet_bridge_messages::Pallet; - - fn universal_location() -> InteriorMultiLocation { - UniversalLocation::get() - } - - fn verify_destination(dest: &MultiLocation) -> bool { - matches!(*dest, MultiLocation { parents: 1, interior: X1(GlobalConsensus(r)) } if r == MillauNetwork::get()) - } - - fn build_destination() -> MultiLocation { - let dest: InteriorMultiLocation = MillauNetwork::get().into(); - let here = UniversalLocation::get(); - dest.relative_to(&here) - } - - fn xcm_lane() -> bp_messages::LaneId { - XCM_LANE - } -} +/// The XCM router. We are not sending messages to sibling/parent/child chains here. +pub type XcmRouter = (); #[cfg(feature = "runtime-benchmarks")] parameter_types! { - pub ReachableDest: Option = todo!("We dont use benchmarks for pallet_xcm, so if you hit this message, you need to remove this and define value instead"); + pub ReachableDest: Option = None; } impl pallet_xcm::Config for Runtime { @@ -875,17 +838,20 @@ cumulus_pallet_parachain_system::register_validate_block!( #[cfg(test)] mod tests { use super::*; - use crate::millau_messages::WeightCredit; + use crate::millau_messages::{FromMillauMessageDispatch, XCM_LANE}; use bp_messages::{ target_chain::{DispatchMessage, DispatchMessageData, MessageDispatch}, LaneId, MessageKey, }; - use bp_runtime::messages::MessageDispatchResult; use bridge_runtime_common::{ - integrity::check_additional_signed, messages::target::FromBridgedChainMessageDispatch, + integrity::check_additional_signed, + messages_xcm_extension::{XcmBlobMessageDispatchResult, XcmRouterWeigher}, }; use codec::Encode; + use pallet_bridge_messages::OutboundLanes; + use sp_core::Get; use sp_runtime::generic::Era; + use xcm_executor::XcmExecutor; fn new_test_ext() -> sp_io::TestExternalities { sp_io::TestExternalities::new( @@ -893,54 +859,75 @@ mod tests { ) } + fn prepare_outbound_xcm_message(destination: NetworkId) -> Xcm { + vec![ExportMessage { + network: destination, + destination: destination.into(), + xcm: vec![Instruction::Trap(42)].into(), + }] + .into() + } + #[test] - fn xcm_messages_to_millau_are_sent() { + fn xcm_messages_to_millau_are_sent_using_bridge_exporter() { new_test_ext().execute_with(|| { - // the encoded message (origin ++ xcm) is 0x010109020419A8 - let dest = (Parent, X1(GlobalConsensus(MillauNetwork::get()))); - let xcm: Xcm<()> = vec![Instruction::Trap(42)].into(); - - let send_result = send_xcm::(dest.into(), xcm); - let expected_fee = MultiAssets::from((Here, Fungibility::Fungible(1_000_000_u128))); - let expected_hash = - ([0u8, 0u8, 0u8, 0u8], 1u64).using_encoded(sp_io::hashing::blake2_256); - assert_eq!(send_result, Ok((expected_hash, expected_fee)),); + // ensure that the there are no messages queued + assert_eq!( + OutboundLanes::::get(XCM_LANE) + .latest_generated_nonce, + 0, + ); + + // export message instruction "sends" message to Rialto + XcmExecutor::::execute_xcm_in_credit( + Here, + prepare_outbound_xcm_message(MillauNetwork::get()), + Default::default(), + Weight::MAX, + Weight::MAX, + ) + .ensure_complete() + .expect("runtime configuration must be correct"); + + // ensure that the message has been queued + assert_eq!( + OutboundLanes::::get(XCM_LANE) + .latest_generated_nonce, + 1, + ); }) } + fn prepare_inbound_bridge_message() -> DispatchMessage> { + let xcm = xcm::VersionedXcm::::V3(vec![Instruction::Trap(42)].into()); + let location = + xcm::VersionedInteriorMultiLocation::V3(X1(GlobalConsensus(ThisNetwork::get()))); + // this is the `BridgeMessage` from polkadot xcm builder, but it has no constructor + // or public fields, so just tuple + let bridge_message = (location, xcm).encode(); + DispatchMessage { + key: MessageKey { lane_id: LaneId([0, 0, 0, 0]), nonce: 1 }, + data: DispatchMessageData { payload: Ok(bridge_message) }, + } + } + #[test] fn xcm_messages_from_millau_are_dispatched() { - type XcmExecutor = xcm_executor::XcmExecutor; - type MessageDispatcher = FromBridgedChainMessageDispatch< - WithMillauMessageBridge, - XcmExecutor, - XcmWeigher, - WeightCredit, - >; - new_test_ext().execute_with(|| { - let location: MultiLocation = - (Parent, X1(GlobalConsensus(MillauNetwork::get()))).into(); - let xcm: Xcm = vec![Instruction::Trap(42)].into(); + let mut incoming_message = prepare_inbound_bridge_message(); - let mut incoming_message = DispatchMessage { - key: MessageKey { lane_id: LaneId([0, 0, 0, 0]), nonce: 1 }, - data: DispatchMessageData { payload: Ok((location, xcm).into()) }, - }; - - let dispatch_weight = MessageDispatcher::dispatch_weight(&mut incoming_message); - assert_eq!(dispatch_weight, UnitWeightCost::get()); + let dispatch_weight = FromMillauMessageDispatch::dispatch_weight(&mut incoming_message); + assert_eq!(dispatch_weight, XcmRouterWeigher::<()>::get()); + // we care only about handing message to the XCM dispatcher, so we don't care about its + // actual dispatch let dispatch_result = - MessageDispatcher::dispatch(&AccountId::from([0u8; 32]), incoming_message); - assert_eq!( - dispatch_result, - MessageDispatchResult { - unspent_weight: frame_support::weights::Weight::zero(), - dispatch_level_result: (), - } - ); - }) + FromMillauMessageDispatch::dispatch(&AccountId::from([0u8; 32]), incoming_message); + assert!(matches!( + dispatch_result.dispatch_level_result, + XcmBlobMessageDispatchResult::NotDispatched(_), + )); + }); } #[test] diff --git a/bin/rialto-parachain/runtime/src/millau_messages.rs b/bin/rialto-parachain/runtime/src/millau_messages.rs index ee7a089992e..3fff141bf84 100644 --- a/bin/rialto-parachain/runtime/src/millau_messages.rs +++ b/bin/rialto-parachain/runtime/src/millau_messages.rs @@ -19,14 +19,18 @@ // TODO: this is almost exact copy of `millau_messages.rs` from Rialto runtime. // Should be extracted to a separate crate and reused here. -use crate::{MillauGrandpaInstance, Runtime, RuntimeCall, RuntimeOrigin}; - -use bp_messages::{LaneId, MessageNonce}; -use bp_runtime::{ChainId, MILLAU_CHAIN_ID, RIALTO_PARACHAIN_CHAIN_ID}; -use bridge_runtime_common::messages::{ - self, source::TargetHeaderChainAdapter, target::SourceHeaderChainAdapter, MessageBridge, +use crate::{MillauGrandpaInstance, Runtime, RuntimeOrigin, WithMillauMessagesInstance}; + +use bp_messages::LaneId; +use bridge_runtime_common::{ + messages::{ + self, source::TargetHeaderChainAdapter, target::SourceHeaderChainAdapter, MessageBridge, + }, + messages_xcm_extension::{XcmBlobHauler, XcmBlobHaulerAdapter}, }; use frame_support::{parameter_types, weights::Weight, RuntimeDebug}; +use xcm::latest::prelude::*; +use xcm_builder::HaulBlobExporter; /// Default lane that is used to send messages to Millau. pub const XCM_LANE: LaneId = LaneId([0, 0, 0, 0]); @@ -51,15 +55,16 @@ pub type ToMillauMessageVerifier = messages::source::FromThisChainMessageVerifier; /// Message payload for Millau -> RialtoParachain messages. -pub type FromMillauMessagePayload = messages::target::FromBridgedChainMessagePayload; +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::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; @@ -77,8 +82,6 @@ pub type ToMillauMaximalOutboundPayloadSize = pub struct WithMillauMessageBridge; impl MessageBridge for WithMillauMessageBridge { - const THIS_CHAIN_ID: ChainId = RIALTO_PARACHAIN_CHAIN_ID; - const BRIDGED_CHAIN_ID: ChainId = MILLAU_CHAIN_ID; const BRIDGED_MESSAGES_PALLET_NAME: &'static str = bp_rialto_parachain::WITH_RIALTO_PARACHAIN_MESSAGES_PALLET_NAME; @@ -97,16 +100,7 @@ impl messages::UnderlyingChainProvider for RialtoParachain { } impl messages::ThisChainWithMessages for RialtoParachain { - type RuntimeCall = RuntimeCall; type RuntimeOrigin = RuntimeOrigin; - - fn is_message_accepted(_send_origin: &Self::RuntimeOrigin, _lane: &LaneId) -> bool { - true - } - - fn maximal_pending_messages_at_outbound_lane() -> MessageNonce { - MessageNonce::MAX - } } /// Millau chain from message lane point of view. @@ -121,8 +115,24 @@ impl messages::UnderlyingChainProvider for Millau { type Chain = bp_millau::Millau; } -impl messages::BridgedChainWithMessages for Millau { - fn verify_dispatch_weight(_message_payload: &[u8]) -> bool { - true +impl messages::BridgedChainWithMessages for Millau {} + +/// Export XCM messages to be relayed to Millau. +pub type ToMillauBlobExporter = + HaulBlobExporter, crate::MillauNetwork, ()>; + +/// To-Millau XCM hauler. +pub struct ToMillauXcmBlobHauler; + +impl XcmBlobHauler for ToMillauXcmBlobHauler { + type MessageSender = pallet_bridge_messages::Pallet; + type MessageSenderOrigin = RuntimeOrigin; + + fn message_sender_origin() -> RuntimeOrigin { + pallet_xcm::Origin::from(MultiLocation::new(1, crate::UniversalLocation::get())).into() + } + + fn xcm_lane() -> LaneId { + XCM_LANE } } diff --git a/bin/rialto/runtime/src/millau_messages.rs b/bin/rialto/runtime/src/millau_messages.rs index ff08c08029a..9d0c4f97c89 100644 --- a/bin/rialto/runtime/src/millau_messages.rs +++ b/bin/rialto/runtime/src/millau_messages.rs @@ -16,14 +16,18 @@ //! Everything required to serve Millau <-> Rialto messages. -use crate::{MillauGrandpaInstance, Runtime, RuntimeCall, RuntimeOrigin}; - -use bp_messages::{LaneId, MessageNonce}; -use bp_runtime::{ChainId, MILLAU_CHAIN_ID, RIALTO_CHAIN_ID}; -use bridge_runtime_common::messages::{ - self, source::TargetHeaderChainAdapter, target::SourceHeaderChainAdapter, MessageBridge, +use crate::{MillauGrandpaInstance, Runtime, RuntimeOrigin, WithMillauMessagesInstance}; + +use bp_messages::LaneId; +use bridge_runtime_common::{ + messages::{ + self, source::TargetHeaderChainAdapter, target::SourceHeaderChainAdapter, MessageBridge, + }, + messages_xcm_extension::{XcmBlobHauler, XcmBlobHaulerAdapter}, }; use frame_support::{parameter_types, weights::Weight, RuntimeDebug}; +use xcm::latest::prelude::*; +use xcm_builder::HaulBlobExporter; /// Lane that is used for XCM messages exchange. pub const XCM_LANE: LaneId = LaneId([0, 0, 0, 0]); @@ -48,15 +52,16 @@ pub type ToMillauMessageVerifier = messages::source::FromThisChainMessageVerifier; /// Message payload for Millau -> Rialto messages. -pub type FromMillauMessagePayload = messages::target::FromBridgedChainMessagePayload; +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::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, + >; /// Messages proof for Millau -> Rialto messages. pub type FromMillauMessagesProof = messages::target::FromBridgedChainMessagesProof; @@ -74,8 +79,6 @@ pub type ToMillauMaximalOutboundPayloadSize = pub struct WithMillauMessageBridge; impl MessageBridge for WithMillauMessageBridge { - const THIS_CHAIN_ID: ChainId = RIALTO_CHAIN_ID; - const BRIDGED_CHAIN_ID: ChainId = MILLAU_CHAIN_ID; const BRIDGED_MESSAGES_PALLET_NAME: &'static str = bp_rialto::WITH_RIALTO_MESSAGES_PALLET_NAME; type ThisChain = Rialto; @@ -94,15 +97,6 @@ impl messages::UnderlyingChainProvider for Rialto { impl messages::ThisChainWithMessages for Rialto { type RuntimeOrigin = RuntimeOrigin; - type RuntimeCall = RuntimeCall; - - fn is_message_accepted(_send_origin: &Self::RuntimeOrigin, _lane: &LaneId) -> bool { - true - } - - fn maximal_pending_messages_at_outbound_lane() -> MessageNonce { - MessageNonce::MAX - } } /// Millau chain from message lane point of view. @@ -117,9 +111,29 @@ impl messages::UnderlyingChainProvider for Millau { type Chain = bp_millau::Millau; } -impl messages::BridgedChainWithMessages for Millau { - fn verify_dispatch_weight(_message_payload: &[u8]) -> bool { - true +impl messages::BridgedChainWithMessages for Millau {} + +/// Export XCM messages to be relayed to Millau. +pub type ToMillauBlobExporter = HaulBlobExporter< + XcmBlobHaulerAdapter, + crate::xcm_config::MillauNetwork, + (), +>; + +/// To-Millau XCM hauler. +pub struct ToMillauXcmBlobHauler; + +impl XcmBlobHauler for ToMillauXcmBlobHauler { + type MessageSender = pallet_bridge_messages::Pallet; + type MessageSenderOrigin = RuntimeOrigin; + + fn message_sender_origin() -> RuntimeOrigin { + pallet_xcm::Origin::from(MultiLocation::new(1, crate::xcm_config::UniversalLocation::get())) + .into() + } + + fn xcm_lane() -> LaneId { + XCM_LANE } } diff --git a/bin/rialto/runtime/src/xcm_config.rs b/bin/rialto/runtime/src/xcm_config.rs index 174ece04725..64a5a896f95 100644 --- a/bin/rialto/runtime/src/xcm_config.rs +++ b/bin/rialto/runtime/src/xcm_config.rs @@ -17,14 +17,11 @@ //! XCM configurations for the Rialto runtime. use super::{ - millau_messages::WithMillauMessageBridge, AccountId, AllPalletsWithSystem, Balances, Runtime, - RuntimeCall, RuntimeEvent, RuntimeOrigin, WithMillauMessagesInstance, XcmPallet, + millau_messages::ToMillauBlobExporter, AccountId, AllPalletsWithSystem, Balances, Runtime, + RuntimeCall, RuntimeEvent, RuntimeOrigin, XcmPallet, }; use bp_rialto::WeightToFee; -use bridge_runtime_common::{ - messages::source::{XcmBridge, XcmBridgeAdapter}, - CustomNetworkId, -}; +use bridge_runtime_common::CustomNetworkId; use frame_support::{ parameter_types, traits::{ConstU32, Everything, Nothing}, @@ -32,9 +29,9 @@ use frame_support::{ }; use xcm::latest::prelude::*; use xcm_builder::{ - AccountId32Aliases, AllowKnownQueryResponses, AllowTopLevelPaidExecutionFrom, - CurrencyAdapter as XcmCurrencyAdapter, IsConcrete, MintLocation, SignedAccountId32AsNative, - SignedToAccountId32, SovereignSignedViaLocation, TakeWeightCredit, UsingComponents, + AccountId32Aliases, CurrencyAdapter as XcmCurrencyAdapter, IsConcrete, MintLocation, + SignedAccountId32AsNative, SignedToAccountId32, SovereignSignedViaLocation, TakeWeightCredit, + UsingComponents, }; parameter_types! { @@ -95,30 +92,28 @@ parameter_types! { pub const MaxInstructions: u32 = 100; } -/// The XCM router. When we want to send an XCM message, we use this type. It amalgamates all of our -/// individual routers. -pub type XcmRouter = ( - // Router to send messages to Millau. - XcmBridgeAdapter, -); +/// The XCM router. We are not sending messages to sibling/parent/child chains here. +pub type XcmRouter = (); /// The barriers one of which must be passed for an XCM message to be executed. pub type Barrier = ( // Weight that is paid for may be consumed. TakeWeightCredit, - // If the message is one that immediately attemps to pay for execution, then allow it. - AllowTopLevelPaidExecutionFrom, - // Expected responses are OK. - AllowKnownQueryResponses, ); +/// 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; pub struct XcmConfig; impl xcm_executor::Config for XcmConfig { type RuntimeCall = RuntimeCall; - type XcmSender = XcmRouter; + type XcmSender = (); type AssetTransactor = LocalAssetTransactor; type OriginConverter = LocalOriginConverter; type IsReserve = (); @@ -137,7 +132,7 @@ impl xcm_executor::Config for XcmConfig { type PalletInstancesInfo = AllPalletsWithSystem; type MaxAssetsIntoHolding = ConstU32<64>; type FeeManager = (); - type MessageExporter = (); + type MessageExporter = ToMillauBlobExporter; type UniversalAliases = Nothing; type CallDispatcher = RuntimeCall; type SafeCallFilter = Everything; @@ -152,7 +147,7 @@ pub type LocalOriginToLocation = ( #[cfg(feature = "runtime-benchmarks")] parameter_types! { - pub ReachableDest: Option = todo!("We dont use benchmarks for pallet_xcm, so if you hit this message, you need to remove this and define value instead"); + pub ReachableDest: Option = None; } impl pallet_xcm::Config for Runtime { @@ -189,43 +184,24 @@ impl pallet_xcm::Config for Runtime { type ReachableDest = ReachableDest; } -/// With-Millau bridge. -pub struct ToMillauBridge; - -impl XcmBridge for ToMillauBridge { - type MessageBridge = WithMillauMessageBridge; - type MessageSender = pallet_bridge_messages::Pallet; - - fn universal_location() -> InteriorMultiLocation { - UniversalLocation::get() - } - - fn verify_destination(dest: &MultiLocation) -> bool { - matches!(*dest, MultiLocation { parents: 1, interior: X1(GlobalConsensus(r)) } if r == MillauNetwork::get()) - } - - fn build_destination() -> MultiLocation { - let dest: InteriorMultiLocation = MillauNetwork::get().into(); - let here = UniversalLocation::get(); - dest.relative_to(&here) - } - - fn xcm_lane() -> bp_messages::LaneId { - bp_messages::LaneId([0, 0, 0, 0]) - } -} - #[cfg(test)] mod tests { use super::*; - use crate::millau_messages::WeightCredit; + use crate::{ + millau_messages::{FromMillauMessageDispatch, XCM_LANE}, + DbWeight, WithMillauMessagesInstance, + }; use bp_messages::{ target_chain::{DispatchMessage, DispatchMessageData, MessageDispatch}, LaneId, MessageKey, }; - use bp_runtime::messages::MessageDispatchResult; - use bridge_runtime_common::messages::target::FromBridgedChainMessageDispatch; + use bridge_runtime_common::messages_xcm_extension::{ + XcmBlobMessageDispatchResult, XcmRouterWeigher, + }; use codec::Encode; + use pallet_bridge_messages::OutboundLanes; + use sp_core::Get; + use xcm_executor::XcmExecutor; fn new_test_ext() -> sp_io::TestExternalities { sp_io::TestExternalities::new( @@ -233,53 +209,72 @@ mod tests { ) } - #[test] - fn xcm_messages_to_millau_are_sent() { - new_test_ext().execute_with(|| { - // the encoded message (origin ++ xcm) is 0x010109030419A8 - let dest = (Parent, X1(GlobalConsensus(MillauNetwork::get()))); - let xcm: Xcm<()> = vec![Instruction::Trap(42)].into(); - - let send_result = send_xcm::(dest.into(), xcm); - let expected_fee = MultiAssets::from((Here, 1_000_000_u128)); - let expected_hash = - ([0u8, 0u8, 0u8, 0u8], 1u64).using_encoded(sp_io::hashing::blake2_256); - assert_eq!(send_result, Ok((expected_hash, expected_fee)),); - }) + fn prepare_outbound_xcm_message(destination: NetworkId) -> Xcm { + vec![ExportMessage { + network: destination, + destination: destination.into(), + xcm: vec![Instruction::Trap(42)].into(), + }] + .into() } #[test] - fn xcm_messages_from_millau_are_dispatched() { - type XcmExecutor = xcm_executor::XcmExecutor; - type MessageDispatcher = FromBridgedChainMessageDispatch< - WithMillauMessageBridge, - XcmExecutor, - XcmWeigher, - WeightCredit, - >; - + fn xcm_messages_to_millau_are_sent_using_bridge_exporter() { new_test_ext().execute_with(|| { - let location: MultiLocation = - (Parent, X1(GlobalConsensus(MillauNetwork::get()))).into(); - let xcm: Xcm = vec![Instruction::Trap(42)].into(); - - let mut incoming_message = DispatchMessage { - key: MessageKey { lane_id: LaneId([0, 0, 0, 0]), nonce: 1 }, - data: DispatchMessageData { payload: Ok((location, xcm).into()) }, - }; - - let dispatch_weight = MessageDispatcher::dispatch_weight(&mut incoming_message); - assert_eq!(dispatch_weight, BaseXcmWeight::get()); + // ensure that the there are no messages queued + assert_eq!( + OutboundLanes::::get(XCM_LANE) + .latest_generated_nonce, + 0, + ); - let dispatch_result = - MessageDispatcher::dispatch(&AccountId::from([0u8; 32]), incoming_message); + // export message instruction "sends" message to Rialto + XcmExecutor::::execute_xcm_in_credit( + Here, + prepare_outbound_xcm_message(MillauNetwork::get()), + Default::default(), + Weight::MAX, + Weight::MAX, + ) + .ensure_complete() + .expect("runtime configuration must be correct"); + + // ensure that the message has been queued assert_eq!( - dispatch_result, - MessageDispatchResult { - unspent_weight: frame_support::weights::Weight::zero(), - dispatch_level_result: (), - } + OutboundLanes::::get(XCM_LANE) + .latest_generated_nonce, + 1, ); }) } + + fn prepare_inbound_bridge_message() -> DispatchMessage> { + let xcm = xcm::VersionedXcm::::V3(vec![Instruction::Trap(42)].into()); + let location = + xcm::VersionedInteriorMultiLocation::V3(X1(GlobalConsensus(ThisNetwork::get()))); + // this is the `BridgeMessage` from polkadot xcm builder, but it has no constructor + // or public fields, so just tuple + let bridge_message = (location, xcm).encode(); + DispatchMessage { + key: MessageKey { lane_id: LaneId([0, 0, 0, 0]), nonce: 1 }, + data: DispatchMessageData { payload: Ok(bridge_message) }, + } + } + + #[test] + fn xcm_messages_from_millau_are_dispatched() { + let mut incoming_message = prepare_inbound_bridge_message(); + + let dispatch_weight = FromMillauMessageDispatch::dispatch_weight(&mut incoming_message); + assert_eq!(dispatch_weight, XcmRouterWeigher::::get()); + + // we care only about handing message to the XCM dispatcher, so we don't care about its + // actual dispatch + let dispatch_result = + FromMillauMessageDispatch::dispatch(&AccountId::from([0u8; 32]), incoming_message); + assert!(matches!( + dispatch_result.dispatch_level_result, + XcmBlobMessageDispatchResult::NotDispatched(_), + )); + } } diff --git a/bin/runtime-common/src/integrity.rs b/bin/runtime-common/src/integrity.rs index 5a2c796ee43..96716fe851c 100644 --- a/bin/runtime-common/src/integrity.rs +++ b/bin/runtime-common/src/integrity.rs @@ -83,7 +83,7 @@ macro_rules! assert_bridge_messages_pallet_types( use $crate::messages::{ source::{FromThisChainMessagePayload, TargetHeaderChainAdapter}, target::{FromBridgedChainMessagePayload, SourceHeaderChainAdapter}, - AccountIdOf, BalanceOf, BridgedChain, CallOf, ThisChain, + AccountIdOf, BalanceOf, BridgedChain, ThisChain, }; use pallet_bridge_messages::Config as MessagesConfig; use static_assertions::assert_type_eq_all; diff --git a/bin/runtime-common/src/messages.rs b/bin/runtime-common/src/messages.rs index 4493ac66742..9d2e5811380 100644 --- a/bin/runtime-common/src/messages.rs +++ b/bin/runtime-common/src/messages.rs @@ -25,28 +25,18 @@ pub use bp_runtime::{UnderlyingChainOf, UnderlyingChainProvider}; use bp_header_chain::{HeaderChain, HeaderChainError}; use bp_messages::{ source_chain::{LaneMessageVerifier, TargetHeaderChain}, - target_chain::{ - DispatchMessage, MessageDispatch, ProvedLaneMessages, ProvedMessages, SourceHeaderChain, - }, + target_chain::{ProvedLaneMessages, ProvedMessages, SourceHeaderChain}, InboundLaneData, LaneId, Message, MessageKey, MessageNonce, MessagePayload, OutboundLaneData, }; -use bp_runtime::{ - messages::MessageDispatchResult, Chain, ChainId, RawStorageProof, Size, StorageProofChecker, - StorageProofError, -}; -use codec::{Decode, DecodeLimit, Encode}; +use bp_runtime::{Chain, RawStorageProof, Size, StorageProofChecker, StorageProofError}; +use codec::{Decode, Encode}; use frame_support::{traits::Get, weights::Weight, RuntimeDebug}; use hash_db::Hasher; use scale_info::TypeInfo; use sp_std::{convert::TryFrom, fmt::Debug, marker::PhantomData, vec::Vec}; -use xcm::latest::prelude::*; /// Bidirectional message bridge. pub trait MessageBridge { - /// Identifier of this chain. - const THIS_CHAIN_ID: ChainId; - /// Identifier of the Bridged chain. - const BRIDGED_CHAIN_ID: ChainId; /// Name of the paired messages pallet instance at the Bridged chain. /// /// Should be the name that is used in the `construct_runtime!()` macro. @@ -64,24 +54,10 @@ pub trait MessageBridge { pub trait ThisChainWithMessages: UnderlyingChainProvider { /// Call origin on the chain. type RuntimeOrigin; - /// Call type on the chain. - type RuntimeCall: Encode + Decode; - - /// Do we accept message sent by given origin to given lane? - fn is_message_accepted(origin: &Self::RuntimeOrigin, lane: &LaneId) -> bool; - - /// Maximal number of pending (not yet delivered) messages at This chain. - /// - /// Any messages over this limit, will be rejected. - fn maximal_pending_messages_at_outbound_lane() -> MessageNonce; } /// Bridged chain that has `pallet-bridge-messages` module. -pub trait BridgedChainWithMessages: UnderlyingChainProvider { - /// Returns `true` if message dispatch weight is withing expected limits. `false` means - /// that the message is too heavy to be sent over the bridge and shall be rejected. - fn verify_dispatch_weight(message_payload: &[u8]) -> bool; -} +pub trait BridgedChainWithMessages: UnderlyingChainProvider {} /// This chain in context of message bridge. pub type ThisChain = ::ThisChain; @@ -97,8 +73,6 @@ pub type AccountIdOf = bp_runtime::AccountIdOf>; pub type BalanceOf = bp_runtime::BalanceOf>; /// Type of origin that is used on the chain. pub type OriginOf = ::RuntimeOrigin; -/// Type of call that is used on this chain. -pub type CallOf = ::RuntimeCall; /// Error that happens during message verification. #[derive(Debug, PartialEq, Eq)] @@ -128,7 +102,7 @@ pub mod source { use super::*; /// Message payload for This -> Bridged chain messages. - pub type FromThisChainMessagePayload = Vec; + pub type FromThisChainMessagePayload = crate::messages_xcm_extension::XcmAsPlainPayload; /// Maximal size of outbound message payload. pub struct FromThisChainMaximalOutboundPayloadSize(PhantomData); @@ -186,13 +160,6 @@ pub mod source { #[derive(RuntimeDebug)] pub struct FromThisChainMessageVerifier(PhantomData); - /// The error message returned from `LaneMessageVerifier` when outbound lane is disabled. - pub const MESSAGE_REJECTED_BY_OUTBOUND_LANE: &str = - "The outbound message lane has rejected the message."; - /// The error message returned from `LaneMessageVerifier` when too many pending messages at the - /// lane. - pub const TOO_MANY_PENDING_MESSAGES: &str = "Too many pending messages at the lane."; - impl LaneMessageVerifier>, FromThisChainMessagePayload> for FromThisChainMessageVerifier where @@ -205,24 +172,16 @@ pub mod source { type Error = &'static str; fn verify_message( - submitter: &OriginOf>, - lane: &LaneId, - lane_outbound_data: &OutboundLaneData, + _submitter: &OriginOf>, + _lane: &LaneId, + _lane_outbound_data: &OutboundLaneData, _payload: &FromThisChainMessagePayload, ) -> Result<(), Self::Error> { - // reject message if lane is blocked - if !ThisChain::::is_message_accepted(submitter, lane) { - return Err(MESSAGE_REJECTED_BY_OUTBOUND_LANE) - } - - // reject message if there are too many pending messages at this lane - let max_pending_messages = ThisChain::::maximal_pending_messages_at_outbound_lane(); - let pending_messages = lane_outbound_data - .latest_generated_nonce - .saturating_sub(lane_outbound_data.latest_received_nonce); - if pending_messages > max_pending_messages { - return Err(TOO_MANY_PENDING_MESSAGES) - } + // IMPORTANT: any error that is returned here is fatal for the bridge, because + // this code is executed at the bridge hub and message sender actually lives + // at some sibling parachain. So we are failing **after** the message has been + // sent and we can't report it back to sender (unless error report mechanism is + // embedded into message and its dispatcher). Ok(()) } @@ -263,9 +222,15 @@ pub mod source { pub fn verify_chain_message( payload: &FromThisChainMessagePayload, ) -> Result<(), Error> { - if !BridgedChain::::verify_dispatch_weight(payload) { - return Err(Error::InvalidMessageWeight) - } + // IMPORTANT: any error that is returned here is fatal for the bridge, because + // this code is executed at the bridge hub and message sender actually lives + // at some sibling parachain. So we are failing **after** the message has been + // sent and we can't report it back to sender (unless error report mechanism is + // embedded into message and its dispatcher). + + // apart from maximal message size check (see below), we should also check the message + // dispatch weight here. But we assume that the bridged chain will just push the message + // to some queue (XCMP, UMP, DMP), so the weight is constant and fits the block. // The maximal size of extrinsic at Substrate-based chain depends on the // `frame_system::Config::MaximumBlockLength` and @@ -316,92 +281,6 @@ pub mod source { ) .map_err(Error::HeaderChain)? } - - /// XCM bridge. - pub trait XcmBridge { - /// Runtime message bridge configuration. - type MessageBridge: MessageBridge; - /// Runtime message sender adapter. - type MessageSender: bp_messages::source_chain::MessagesBridge< - OriginOf>, - FromThisChainMessagePayload, - >; - - /// Our location within the Consensus Universe. - fn universal_location() -> InteriorMultiLocation; - /// Verify that the adapter is responsible for handling given XCM destination. - fn verify_destination(dest: &MultiLocation) -> bool; - /// Build route from this chain to the XCM destination. - fn build_destination() -> MultiLocation; - /// Return message lane used to deliver XCM messages. - fn xcm_lane() -> LaneId; - } - - /// XCM bridge adapter for `bridge-messages` pallet. - pub struct XcmBridgeAdapter(PhantomData); - - impl SendXcm for XcmBridgeAdapter - where - BalanceOf>: Into, - OriginOf>: From, - { - type Ticket = FromThisChainMessagePayload; - - fn validate( - dest: &mut Option, - msg: &mut Option>, - ) -> SendResult { - let d = dest.take().ok_or(SendError::MissingArgument)?; - if !T::verify_destination(&d) { - *dest = Some(d); - return Err(SendError::NotApplicable) - } - - let route = T::build_destination(); - let msg = (route, msg.take().ok_or(SendError::MissingArgument)?).encode(); - - // let's just take fixed (out of thin air) fee per message in our test bridges - // (this code won't be used in production anyway) - let fee_assets = MultiAssets::from((Here, 1_000_000_u128)); - - Ok((msg, fee_assets)) - } - - fn deliver(ticket: Self::Ticket) -> Result { - use bp_messages::source_chain::MessagesBridge; - - let lane = T::xcm_lane(); - let msg = ticket; - let result = T::MessageSender::send_message( - pallet_xcm::Origin::from(MultiLocation::from(T::universal_location())).into(), - lane, - msg, - ); - result - .map(|artifacts| { - let hash = (lane, artifacts.nonce).using_encoded(sp_io::hashing::blake2_256); - log::debug!( - target: "runtime::bridge", - "Sent XCM message {:?}/{} to {:?}: {:?}", - lane, - artifacts.nonce, - T::MessageBridge::BRIDGED_CHAIN_ID, - hash, - ); - hash - }) - .map_err(|e| { - log::debug!( - target: "runtime::bridge", - "Failed to send XCM message over lane {:?} to {:?}: {:?}", - lane, - T::MessageBridge::BRIDGED_CHAIN_ID, - e, - ); - SendError::Transport("Bridge has rejected the message") - }) - } - } } /// Sub-module that is declaring types required for processing Bridged -> This chain messages. @@ -409,35 +288,7 @@ pub mod target { use super::*; /// Decoded Bridged -> This message payload. - #[derive(RuntimeDebug, PartialEq, Eq)] - pub struct FromBridgedChainMessagePayload { - /// Data that is actually sent over the wire. - pub xcm: (xcm::v3::MultiLocation, xcm::v3::Xcm), - /// Weight of the message, computed by the weigher. Unknown initially. - pub weight: Option, - } - - impl Decode for FromBridgedChainMessagePayload { - fn decode(input: &mut I) -> Result { - let _: codec::Compact = Decode::decode(input)?; - type XcmPairType = (xcm::v3::MultiLocation, xcm::v3::Xcm); - Ok(FromBridgedChainMessagePayload { - xcm: XcmPairType::::decode_with_depth_limit( - sp_api::MAX_EXTRINSIC_DEPTH, - input, - )?, - weight: None, - }) - } - } - - impl From<(xcm::v3::MultiLocation, xcm::v3::Xcm)> - for FromBridgedChainMessagePayload - { - fn from(xcm: (xcm::v3::MultiLocation, xcm::v3::Xcm)) -> Self { - FromBridgedChainMessagePayload { xcm, weight: None } - } - } + pub type FromBridgedChainMessagePayload = crate::messages_xcm_extension::XcmAsPlainPayload; /// Messages proof from bridged chain: /// @@ -470,118 +321,6 @@ pub mod target { } } - /// Dispatching Bridged -> This chain messages. - #[derive(RuntimeDebug, Clone, Copy)] - pub struct FromBridgedChainMessageDispatch { - _marker: PhantomData<(B, XcmExecutor, XcmWeigher, WeightCredit)>, - } - - impl - MessageDispatch>> - for FromBridgedChainMessageDispatch - where - XcmExecutor: xcm::v3::ExecuteXcm>>, - XcmWeigher: xcm_executor::traits::WeightBounds>>, - WeightCredit: Get, - { - type DispatchPayload = FromBridgedChainMessagePayload>>; - type DispatchLevelResult = (); - - fn dispatch_weight( - message: &mut DispatchMessage, - ) -> 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>, - message: DispatchMessage, - ) -> MessageDispatchResult { - let message_id = (message.key.lane_id, message.key.nonce); - let do_dispatch = move || -> sp_std::result::Result { - 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 @@ -745,54 +484,6 @@ mod tests { use sp_core::H256; use sp_runtime::traits::Header as _; - fn test_lane_outbound_data() -> OutboundLaneData { - OutboundLaneData::default() - } - - fn regular_outbound_message_payload() -> source::FromThisChainMessagePayload { - vec![42] - } - - #[test] - fn message_is_rejected_when_sent_using_disabled_lane() { - assert_eq!( - source::FromThisChainMessageVerifier::::verify_message( - &frame_system::RawOrigin::Root.into(), - &LaneId(*b"dsbl"), - &test_lane_outbound_data(), - ®ular_outbound_message_payload(), - ), - Err(source::MESSAGE_REJECTED_BY_OUTBOUND_LANE) - ); - } - - #[test] - fn message_is_rejected_when_there_are_too_many_pending_messages_at_outbound_lane() { - assert_eq!( - source::FromThisChainMessageVerifier::::verify_message( - &frame_system::RawOrigin::Root.into(), - &TEST_LANE_ID, - &OutboundLaneData { - latest_received_nonce: 100, - latest_generated_nonce: 100 + MAXIMAL_PENDING_MESSAGES_AT_TEST_LANE + 1, - ..Default::default() - }, - ®ular_outbound_message_payload(), - ), - Err(source::TOO_MANY_PENDING_MESSAGES) - ); - } - - #[test] - fn verify_chain_message_rejects_message_with_too_small_declared_weight() { - assert!(source::verify_chain_message::(&vec![ - 42; - BRIDGED_CHAIN_MIN_EXTRINSIC_WEIGHT - - 1 - ]) - .is_err()); - } - #[test] fn verify_chain_message_rejects_message_with_too_large_declared_weight() { assert!(source::verify_chain_message::(&vec![ diff --git a/bin/runtime-common/src/messages_xcm_extension.rs b/bin/runtime-common/src/messages_xcm_extension.rs index 42ac67a0f26..a8ca86c85c3 100644 --- a/bin/runtime-common/src/messages_xcm_extension.rs +++ b/bin/runtime-common/src/messages_xcm_extension.rs @@ -28,13 +28,43 @@ 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; +// TODO: below are just rough estimations. Other things also happen there (including hashing and so +// on). Shall we do some benchmarking??? TODO: add proof_size component here +// https://github.com/paritytech/parity-bridges-common/issues/1986 + +/// 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 roughly 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(PhantomData); + +impl> Get for XcmRouterWeigher { + 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 { diff --git a/bin/runtime-common/src/mock.rs b/bin/runtime-common/src/mock.rs index 056fd3a2ccf..5c2c967c060 100644 --- a/bin/runtime-common/src/mock.rs +++ b/bin/runtime-common/src/mock.rs @@ -33,7 +33,7 @@ use crate::messages::{ }; use bp_header_chain::{ChainWithGrandpa, HeaderChain}; -use bp_messages::{target_chain::ForbidInboundMessages, LaneId, MessageNonce}; +use bp_messages::{target_chain::ForbidInboundMessages, LaneId}; use bp_parachains::SingleParaStoredHeaderDataBuilder; use bp_runtime::{Chain, ChainId, Parachain, UnderlyingChainProvider}; use codec::{Decode, Encode}; @@ -87,10 +87,6 @@ pub type BridgedChainHeader = pub const TEST_LANE_ID: LaneId = LaneId([0, 0, 0, 0]); /// Bridged chain id used in tests. pub const TEST_BRIDGED_CHAIN_ID: ChainId = *b"brdg"; -/// Maximal number of queued messages at the test lane. -pub const MAXIMAL_PENDING_MESSAGES_AT_TEST_LANE: MessageNonce = 32; -/// Minimal extrinsic weight at the `BridgedChain`. -pub const BRIDGED_CHAIN_MIN_EXTRINSIC_WEIGHT: usize = 5; /// Maximal extrinsic weight at the `BridgedChain`. pub const BRIDGED_CHAIN_MAX_EXTRINSIC_WEIGHT: usize = 2048; /// Maximal extrinsic size at the `BridgedChain`. @@ -222,7 +218,7 @@ impl pallet_bridge_messages::Config for TestRuntime { type MaximalOutboundPayloadSize = FromThisChainMaximalOutboundPayloadSize; type OutboundPayload = FromThisChainMessagePayload; - type InboundPayload = FromBridgedChainMessagePayload; + type InboundPayload = FromBridgedChainMessagePayload; type InboundRelayer = BridgedChainAccountId; type DeliveryPayments = (); @@ -235,8 +231,7 @@ impl pallet_bridge_messages::Config for TestRuntime { >; type SourceHeaderChain = SourceHeaderChainAdapter; - type MessageDispatch = - ForbidInboundMessages<(), FromBridgedChainMessagePayload>; + type MessageDispatch = ForbidInboundMessages<(), FromBridgedChainMessagePayload>; type BridgedChainId = BridgedChainId; } @@ -253,8 +248,6 @@ impl pallet_bridge_relayers::Config for TestRuntime { pub struct OnThisChainBridge; impl MessageBridge for OnThisChainBridge { - const THIS_CHAIN_ID: ChainId = *b"this"; - const BRIDGED_CHAIN_ID: ChainId = TEST_BRIDGED_CHAIN_ID; const BRIDGED_MESSAGES_PALLET_NAME: &'static str = ""; type ThisChain = ThisChain; @@ -268,8 +261,6 @@ impl MessageBridge for OnThisChainBridge { pub struct OnBridgedChainBridge; impl MessageBridge for OnBridgedChainBridge { - const THIS_CHAIN_ID: ChainId = TEST_BRIDGED_CHAIN_ID; - const BRIDGED_CHAIN_ID: ChainId = *b"this"; const BRIDGED_MESSAGES_PALLET_NAME: &'static str = ""; type ThisChain = BridgedChain; @@ -331,22 +322,9 @@ impl UnderlyingChainProvider for ThisChain { impl ThisChainWithMessages for ThisChain { type RuntimeOrigin = ThisChainCallOrigin; - type RuntimeCall = ThisChainRuntimeCall; - - fn is_message_accepted(_send_origin: &Self::RuntimeOrigin, lane: &LaneId) -> bool { - *lane == TEST_LANE_ID - } - - fn maximal_pending_messages_at_outbound_lane() -> MessageNonce { - MAXIMAL_PENDING_MESSAGES_AT_TEST_LANE - } } -impl BridgedChainWithMessages for ThisChain { - fn verify_dispatch_weight(_message_payload: &[u8]) -> bool { - unreachable!() - } -} +impl BridgedChainWithMessages for ThisChain {} /// Underlying chain of `BridgedChain`. pub struct BridgedUnderlyingChain; @@ -413,20 +391,6 @@ impl UnderlyingChainProvider for BridgedChain { impl ThisChainWithMessages for BridgedChain { type RuntimeOrigin = BridgedChainOrigin; - type RuntimeCall = BridgedChainCall; - - fn is_message_accepted(_send_origin: &Self::RuntimeOrigin, _lane: &LaneId) -> bool { - unreachable!() - } - - fn maximal_pending_messages_at_outbound_lane() -> MessageNonce { - unreachable!() - } } -impl BridgedChainWithMessages for BridgedChain { - fn verify_dispatch_weight(message_payload: &[u8]) -> bool { - message_payload.len() >= BRIDGED_CHAIN_MIN_EXTRINSIC_WEIGHT && - message_payload.len() <= BRIDGED_CHAIN_MAX_EXTRINSIC_WEIGHT - } -} +impl BridgedChainWithMessages for BridgedChain {} diff --git a/deployments/bridges/common/generate_messages.sh b/deployments/bridges/common/generate_messages.sh index 156fb5b5d2b..0987ff8987e 100755 --- a/deployments/bridges/common/generate_messages.sh +++ b/deployments/bridges/common/generate_messages.sh @@ -12,7 +12,6 @@ # SECONDARY_EXTRA_ARGS - optional, for example "--use-xcm-pallet" # EXTRA_ARGS - for example "--use-xcm-pallet" # REGULAR_PAYLOAD -# BATCH_PAYLOAD # MAX_UNCONFIRMED_MESSAGES_AT_INBOUND_LANE SECONDARY_EXTRA_ARGS=${SECONDARY_EXTRA_ARGS:-""} @@ -59,7 +58,7 @@ do do $SEND_MESSAGE \ $EXTRA_ARGS \ - raw $BATCH_PAYLOAD + raw $REGULAR_PAYLOAD done fi diff --git a/deployments/bridges/rialto-millau/docker-compose.yml b/deployments/bridges/rialto-millau/docker-compose.yml index ad61b1d174a..5d15a0398b1 100644 --- a/deployments/bridges/rialto-millau/docker-compose.yml +++ b/deployments/bridges/rialto-millau/docker-compose.yml @@ -41,21 +41,10 @@ services: - rialto-node-dave - rialto-node-eve - relay-messages-millau-to-rialto-lane-00000001: - <<: *sub-bridge-relay - environment: - MSG_EXCHANGE_GEN_LANE: "00000001" - entrypoint: /entrypoints/relay-messages-millau-to-rialto-entrypoint.sh - ports: - - "10116:9616" - depends_on: - - relay-millau-rialto - relay-messages-millau-to-rialto-generator: <<: *sub-bridge-relay environment: RUST_LOG: bridge=trace - MSG_EXCHANGE_GEN_SECONDARY_LANE: "00000001" entrypoint: /entrypoints/relay-messages-to-rialto-generator-entrypoint.sh ports: - "10216:9616" @@ -72,22 +61,10 @@ services: depends_on: - relay-messages-millau-to-rialto-generator - relay-messages-rialto-to-millau-lane-00000001: - <<: *sub-bridge-relay - environment: - RUST_LOG: bridge=trace - MSG_EXCHANGE_GEN_LANE: "00000001" - entrypoint: /entrypoints/relay-messages-rialto-to-millau-entrypoint.sh - ports: - - "10416:9616" - depends_on: - - relay-millau-rialto - relay-messages-rialto-to-millau-generator: <<: *sub-bridge-relay environment: RUST_LOG: bridge=trace - MSG_EXCHANGE_GEN_SECONDARY_LANE: "00000001" entrypoint: /entrypoints/relay-messages-to-millau-generator-entrypoint.sh ports: - "10516:9616" diff --git a/deployments/bridges/rialto-millau/entrypoints/relay-messages-to-millau-generator-entrypoint.sh b/deployments/bridges/rialto-millau/entrypoints/relay-messages-to-millau-generator-entrypoint.sh index 790e9c82110..a36538ea515 100755 --- a/deployments/bridges/rialto-millau/entrypoints/relay-messages-to-millau-generator-entrypoint.sh +++ b/deployments/bridges/rialto-millau/entrypoints/relay-messages-to-millau-generator-entrypoint.sh @@ -20,7 +20,8 @@ SEND_MESSAGE="$SHARED_CMD $SHARED_HOST $SOURCE_SIGNER" SOURCE_CHAIN="Rialto" TARGET_CHAIN="Millau" EXTRA_ARGS="" -REGULAR_PAYLOAD="020419ac" -BATCH_PAYLOAD="020419ac" +# It is the encoded `xcm::VersionedXcm::V3(prepare_outbound_xcm_message(MillauNetwork::get())` +# from the `xcm_messages_to_millau_are_sent_using_bridge_exporter` test in the `rialto-runtime` +REGULAR_PAYLOAD="030426030109030419a8" source /common/generate_messages.sh diff --git a/deployments/bridges/rialto-millau/entrypoints/relay-messages-to-rialto-generator-entrypoint.sh b/deployments/bridges/rialto-millau/entrypoints/relay-messages-to-rialto-generator-entrypoint.sh index 3f3105a4d0e..dacb5615229 100755 --- a/deployments/bridges/rialto-millau/entrypoints/relay-messages-to-rialto-generator-entrypoint.sh +++ b/deployments/bridges/rialto-millau/entrypoints/relay-messages-to-rialto-generator-entrypoint.sh @@ -20,7 +20,8 @@ SEND_MESSAGE="$SHARED_CMD $SHARED_HOST $SOURCE_SIGNER" SOURCE_CHAIN="Millau" TARGET_CHAIN="Rialto" EXTRA_ARGS="" -REGULAR_PAYLOAD="020419ac" -BATCH_PAYLOAD="020419ac" +# It is the encoded `xcm::VersionedXcm::V3(prepare_outbound_xcm_message(RialtoNetwork::get())` +# from the `xcm_messages_to_rialto_are_sent_using_bridge_exporter` test in the `millau-runtime` +REGULAR_PAYLOAD="030426020109020419a8" source /common/generate_messages.sh diff --git a/deployments/bridges/rialto-millau/entrypoints/relay-millau-rialto-entrypoint.sh b/deployments/bridges/rialto-millau/entrypoints/relay-millau-rialto-entrypoint.sh index af7ffca56d2..a1306984bca 100755 --- a/deployments/bridges/rialto-millau/entrypoints/relay-millau-rialto-entrypoint.sh +++ b/deployments/bridges/rialto-millau/entrypoints/relay-millau-rialto-entrypoint.sh @@ -34,5 +34,4 @@ RIALTO_NODE_CONNECTION_PARAMS=$([ -z ${GLOBAL_DEPLOYMENTS} ] && \ --rialto-signer //Millau.HeadersAndMessagesRelay \ --rialto-transactions-mortality=64 \ --lane=00000000 \ - --lane=73776170 \ --prometheus-host=0.0.0.0 diff --git a/deployments/bridges/rialto-parachain-millau/entrypoints/relay-messages-to-millau-generator-entrypoint.sh b/deployments/bridges/rialto-parachain-millau/entrypoints/relay-messages-to-millau-generator-entrypoint.sh index cf0c910a05b..c09116a1614 100755 --- a/deployments/bridges/rialto-parachain-millau/entrypoints/relay-messages-to-millau-generator-entrypoint.sh +++ b/deployments/bridges/rialto-parachain-millau/entrypoints/relay-messages-to-millau-generator-entrypoint.sh @@ -21,7 +21,8 @@ SEND_MESSAGE="$SHARED_CMD $SHARED_HOST $SOURCE_SIGNER" SOURCE_CHAIN="RialtoParachain" TARGET_CHAIN="Millau" EXTRA_ARGS="" -REGULAR_PAYLOAD="020419ac" -BATCH_PAYLOAD="010109020419A8" +# It is the encoded `xcm::VersionedXcm::V3(prepare_outbound_xcm_message(MillauNetwork::get())` +# from the `xcm_messages_to_millau_are_sent_using_bridge_exporter` test in the `rialto-parachain-runtime` +REGULAR_PAYLOAD="030426030109030419a8" source /common/generate_messages.sh diff --git a/deployments/bridges/rialto-parachain-millau/entrypoints/relay-messages-to-rialto-parachain-generator-entrypoint.sh b/deployments/bridges/rialto-parachain-millau/entrypoints/relay-messages-to-rialto-parachain-generator-entrypoint.sh index 7917f7739d5..dbf14ef18bc 100755 --- a/deployments/bridges/rialto-parachain-millau/entrypoints/relay-messages-to-rialto-parachain-generator-entrypoint.sh +++ b/deployments/bridges/rialto-parachain-millau/entrypoints/relay-messages-to-rialto-parachain-generator-entrypoint.sh @@ -20,7 +20,8 @@ SEND_MESSAGE="$SHARED_CMD $SHARED_HOST $SOURCE_SIGNER" SOURCE_CHAIN="Millau" TARGET_CHAIN="RialtoParachain" EXTRA_ARGS="" -REGULAR_PAYLOAD="020419ac" -BATCH_PAYLOAD="010109020419A8" +# It is the encoded `xcm::VersionedXcm::V3(prepare_outbound_xcm_message(RialtoParachainNetwork::get())` +# from the `xcm_messages_to_rialto_parachain_are_sent_using_bridge_exporter` test in the `millau-runtime` +REGULAR_PAYLOAD="030426040109040419a8" source /common/generate_messages.sh diff --git a/deployments/networks/millau.yml b/deployments/networks/millau.yml index 6c57a3863ea..0f5846571aa 100644 --- a/deployments/networks/millau.yml +++ b/deployments/networks/millau.yml @@ -21,7 +21,7 @@ services: - --unsafe-rpc-external - --unsafe-ws-external environment: - RUST_LOG: runtime=trace,rpc=debug,txpool=trace,runtime::bridge=trace,sc_basic_authorship=trace,beefy=debug + RUST_LOG: runtime=trace,rpc=debug,txpool=trace,runtime::bridge=trace,sc_basic_authorship=trace,beefy=debug,xcm=trace ports: - "19933:9933" - "19944:9944" diff --git a/deployments/networks/rialto-parachain.yml b/deployments/networks/rialto-parachain.yml index c6dab73ff72..89724183148 100644 --- a/deployments/networks/rialto-parachain.yml +++ b/deployments/networks/rialto-parachain.yml @@ -25,7 +25,7 @@ services: volumes: - rialto-share:/rialto-share:z environment: - RUST_LOG: runtime=trace,rpc=trace,txpool=trace,parachain=trace,parity_ws=trace,sc_basic_authorship=trace + RUST_LOG: runtime=trace,rpc=trace,txpool=trace,parachain=trace,parity_ws=trace,sc_basic_authorship=trace,xcm=trace depends_on: - rialto-chainspec-exporter ports: diff --git a/deployments/networks/rialto.yml b/deployments/networks/rialto.yml index 1e2bdd3e41b..5a8ed64e067 100644 --- a/deployments/networks/rialto.yml +++ b/deployments/networks/rialto.yml @@ -21,7 +21,7 @@ services: - --unsafe-rpc-external - --unsafe-ws-external environment: - RUST_LOG: runtime=trace,rpc=debug,txpool=trace,runtime::bridge=trace,beefy=debug + RUST_LOG: runtime=trace,rpc=debug,txpool=trace,runtime::bridge=trace,beefy=debug,xcm=trace ports: - "9933:9933" - "9944:9944" diff --git a/primitives/runtime/src/lib.rs b/primitives/runtime/src/lib.rs index 1d2373de6d3..d4f551ce57a 100644 --- a/primitives/runtime/src/lib.rs +++ b/primitives/runtime/src/lib.rs @@ -502,11 +502,11 @@ pub struct StrippableError { } impl From for StrippableError { - fn from(err: T) -> Self { + fn from(_err: T) -> Self { Self { _phantom_data: Default::default(), #[cfg(feature = "std")] - message: format!("{:?}", err), + message: format!("{:?}", _err), } } } diff --git a/relays/bin-substrate/src/chains/millau.rs b/relays/bin-substrate/src/chains/millau.rs index ca9a32a48a5..44416195c6a 100644 --- a/relays/bin-substrate/src/chains/millau.rs +++ b/relays/bin-substrate/src/chains/millau.rs @@ -16,37 +16,18 @@ //! Millau chain specification for CLI. -use crate::cli::{bridge, encode_message::CliEncodeMessage, CliChain}; -use bp_rialto_parachain::RIALTO_PARACHAIN_ID; +use crate::cli::{encode_message::CliEncodeMessage, CliChain}; use bp_runtime::EncodedOrDecodedCall; use relay_millau_client::Millau; use relay_substrate_client::SimpleRuntimeVersion; -use xcm::latest::prelude::*; impl CliEncodeMessage for Millau { - fn encode_send_xcm( - message: xcm::VersionedXcm<()>, - bridge_instance_index: u8, + fn encode_execute_xcm( + message: xcm::VersionedXcm, ) -> anyhow::Result> { - let dest = match bridge_instance_index { - bridge::MILLAU_TO_RIALTO_INDEX => - (Parent, X1(GlobalConsensus(millau_runtime::xcm_config::RialtoNetwork::get()))), - bridge::MILLAU_TO_RIALTO_PARACHAIN_INDEX => ( - Parent, - X2( - GlobalConsensus(millau_runtime::xcm_config::RialtoNetwork::get()), - Parachain(RIALTO_PARACHAIN_ID), - ), - ), - _ => anyhow::bail!( - "Unsupported target bridge pallet with instance index: {}", - bridge_instance_index - ), - }; - - Ok(millau_runtime::RuntimeCall::XcmPallet(millau_runtime::XcmCall::send { - dest: Box::new(dest.into()), + Ok(millau_runtime::RuntimeCall::XcmPallet(millau_runtime::XcmCall::execute { message: Box::new(message), + max_weight: Self::estimate_execute_xcm_weight(), }) .into()) } diff --git a/relays/bin-substrate/src/chains/rialto.rs b/relays/bin-substrate/src/chains/rialto.rs index e9e2d0b3eaf..34a448ae4cb 100644 --- a/relays/bin-substrate/src/chains/rialto.rs +++ b/relays/bin-substrate/src/chains/rialto.rs @@ -16,29 +16,18 @@ //! Rialto chain specification for CLI. -use crate::cli::{bridge, encode_message::CliEncodeMessage, CliChain}; +use crate::cli::{encode_message::CliEncodeMessage, CliChain}; use bp_runtime::EncodedOrDecodedCall; use relay_rialto_client::Rialto; use relay_substrate_client::SimpleRuntimeVersion; -use xcm::latest::prelude::*; impl CliEncodeMessage for Rialto { - fn encode_send_xcm( - message: xcm::VersionedXcm<()>, - bridge_instance_index: u8, + fn encode_execute_xcm( + message: xcm::VersionedXcm, ) -> anyhow::Result> { - let dest = match bridge_instance_index { - bridge::RIALTO_TO_MILLAU_INDEX => - (Parent, X1(GlobalConsensus(rialto_runtime::xcm_config::MillauNetwork::get()))), - _ => anyhow::bail!( - "Unsupported target bridge pallet with instance index: {}", - bridge_instance_index - ), - }; - - Ok(rialto_runtime::RuntimeCall::XcmPallet(rialto_runtime::XcmCall::send { - dest: Box::new(dest.into()), + Ok(rialto_runtime::RuntimeCall::XcmPallet(rialto_runtime::XcmCall::execute { message: Box::new(message), + max_weight: Self::estimate_execute_xcm_weight(), }) .into()) } diff --git a/relays/bin-substrate/src/chains/rialto_parachain.rs b/relays/bin-substrate/src/chains/rialto_parachain.rs index 1a5ea2e784e..8ea2c1ffd43 100644 --- a/relays/bin-substrate/src/chains/rialto_parachain.rs +++ b/relays/bin-substrate/src/chains/rialto_parachain.rs @@ -16,33 +16,21 @@ //! Rialto parachain specification for CLI. -use crate::cli::{bridge, encode_message::CliEncodeMessage, CliChain}; +use crate::cli::{encode_message::CliEncodeMessage, CliChain}; use bp_runtime::EncodedOrDecodedCall; -use bridge_runtime_common::CustomNetworkId; use relay_rialto_parachain_client::RialtoParachain; use relay_substrate_client::SimpleRuntimeVersion; -use xcm::latest::prelude::*; impl CliEncodeMessage for RialtoParachain { - fn encode_send_xcm( - message: xcm::VersionedXcm<()>, - bridge_instance_index: u8, + fn encode_execute_xcm( + message: xcm::VersionedXcm, ) -> anyhow::Result> { type RuntimeCall = relay_rialto_parachain_client::RuntimeCall; type XcmCall = relay_rialto_parachain_client::runtime_types::pallet_xcm::pallet::Call; - let dest = match bridge_instance_index { - bridge::RIALTO_PARACHAIN_TO_MILLAU_INDEX => - (Parent, X1(GlobalConsensus(CustomNetworkId::Millau.as_network_id()))), - _ => anyhow::bail!( - "Unsupported target bridge pallet with instance index: {}", - bridge_instance_index - ), - }; - - let xcm_call = XcmCall::send { - dest: Box::new(unsafe { std::mem::transmute(xcm::VersionedMultiLocation::from(dest)) }), + let xcm_call = XcmCall::execute { message: Box::new(unsafe { std::mem::transmute(message) }), + max_weight: Self::estimate_execute_xcm_weight(), }; Ok(RuntimeCall::PolkadotXcm(xcm_call).into()) diff --git a/relays/bin-substrate/src/cli/bridge.rs b/relays/bin-substrate/src/cli/bridge.rs index a3cacec3313..62c71183a48 100644 --- a/relays/bin-substrate/src/cli/bridge.rs +++ b/relays/bin-substrate/src/cli/bridge.rs @@ -37,28 +37,6 @@ pub enum FullBridge { BridgeHubPolkadotToBridgeHubKusama, } -impl FullBridge { - /// Return instance index of the bridge pallet in source runtime. - pub fn bridge_instance_index(&self) -> u8 { - match self { - Self::MillauToRialto => MILLAU_TO_RIALTO_INDEX, - Self::RialtoToMillau => RIALTO_TO_MILLAU_INDEX, - Self::MillauToRialtoParachain => MILLAU_TO_RIALTO_PARACHAIN_INDEX, - Self::RialtoParachainToMillau => RIALTO_PARACHAIN_TO_MILLAU_INDEX, - Self::BridgeHubRococoToBridgeHubWococo | - Self::BridgeHubWococoToBridgeHubRococo | - Self::BridgeHubKusamaToBridgeHubPolkadot | - Self::BridgeHubPolkadotToBridgeHubKusama => - unimplemented!("Relay doesn't support send-message subcommand on bridge hubs"), - } - } -} - -pub const RIALTO_TO_MILLAU_INDEX: u8 = 0; -pub const MILLAU_TO_RIALTO_INDEX: u8 = 0; -pub const MILLAU_TO_RIALTO_PARACHAIN_INDEX: u8 = 1; -pub const RIALTO_PARACHAIN_TO_MILLAU_INDEX: u8 = 0; - /// Minimal bridge representation that can be used from the CLI. /// It connects a source chain to a target chain. pub trait CliBridgeBase: Sized { diff --git a/relays/bin-substrate/src/cli/encode_message.rs b/relays/bin-substrate/src/cli/encode_message.rs index c7ca5d51f79..9abf8b2df6d 100644 --- a/relays/bin-substrate/src/cli/encode_message.rs +++ b/relays/bin-substrate/src/cli/encode_message.rs @@ -17,6 +17,7 @@ use crate::cli::{ExplicitOrMaximal, HexBytes}; use bp_runtime::EncodedOrDecodedCall; use codec::Encode; +use frame_support::weights::Weight; use relay_substrate_client::Chain; use structopt::StructOpt; @@ -42,11 +43,16 @@ pub enum Message { pub type RawMessage = Vec; pub trait CliEncodeMessage: Chain { - /// Encode a send XCM call of the XCM pallet. - fn encode_send_xcm( - message: xcm::VersionedXcm<()>, - bridge_instance_index: u8, + /// Encode an `execute` XCM call of the XCM pallet. + fn encode_execute_xcm( + message: xcm::VersionedXcm, ) -> anyhow::Result>; + + /// Estimate value of `max_weight` argument for the `execute` XCM call of the XCM pallet. + fn estimate_execute_xcm_weight() -> Weight { + // we are only executing XCM on our testnets and 1/100 of max extrinsic weight is ok + Self::max_extrinsic_weight() / 100 + } } /// Encode message payload passed through CLI flags. @@ -125,7 +131,7 @@ mod tests { .unwrap(); assert_eq!(msg.len(), 100); // check that it decodes to valid xcm - let _ = decode_xcm(msg).unwrap(); + let _ = decode_xcm::<()>(msg).unwrap(); } #[test] @@ -140,6 +146,6 @@ mod tests { .unwrap(); assert_eq!(msg.len(), maximal_size as usize); // check that it decodes to valid xcm - let _ = decode_xcm(msg).unwrap(); + let _ = decode_xcm::<()>(msg).unwrap(); } } diff --git a/relays/bin-substrate/src/cli/send_message.rs b/relays/bin-substrate/src/cli/send_message.rs index 09d7f72b7f4..8f76e501f69 100644 --- a/relays/bin-substrate/src/cli/send_message.rs +++ b/relays/bin-substrate/src/cli/send_message.rs @@ -75,10 +75,7 @@ where let source_sign = data.source_sign.to_keypair::()?; let payload_len = payload.encoded_size(); - let send_message_call = Self::Source::encode_send_xcm( - decode_xcm(payload)?, - data.bridge.bridge_instance_index(), - )?; + let send_message_call = Self::Source::encode_execute_xcm(decode_xcm(payload)?)?; source_client .submit_signed_extrinsic(&source_sign, move |_, transaction_nonce| { @@ -130,7 +127,7 @@ impl SendMessage { } /// Decode SCALE encoded raw XCM message. -pub(crate) fn decode_xcm(message: RawMessage) -> anyhow::Result> { +pub(crate) fn decode_xcm(message: RawMessage) -> anyhow::Result> { Decode::decode(&mut &message[..]) .map_err(|e| anyhow::format_err!("Failed to decode XCM program: {:?}", e)) } diff --git a/scripts/send-message-from-millau-rialto.sh b/scripts/send-message-from-millau-rialto.sh index bcfc9df2f57..1a736b4f8bd 100755 --- a/scripts/send-message-from-millau-rialto.sh +++ b/scripts/send-message-from-millau-rialto.sh @@ -15,4 +15,4 @@ RUST_LOG=runtime=trace,substrate-relay=trace,bridge=trace \ --source-host localhost \ --source-port $MILLAU_PORT \ --source-signer //Alice \ - raw 020419ac + raw 030426020109020419a8 diff --git a/scripts/send-message-from-rialto-millau.sh b/scripts/send-message-from-rialto-millau.sh index e348c33f2a2..8133978f6ce 100755 --- a/scripts/send-message-from-rialto-millau.sh +++ b/scripts/send-message-from-rialto-millau.sh @@ -15,4 +15,4 @@ RUST_LOG=runtime=trace,substrate-relay=trace,bridge=trace \ --source-host localhost \ --source-port $RIALTO_PORT \ --source-signer //Bob \ - raw 020419ac + raw 030426030109030419a8