From 1a810a81a4080c253b21f78ae187bc09738ab484 Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Thu, 20 Jul 2023 17:34:41 +0300 Subject: [PATCH] Implement ExportXcm and MessageDispatch for pallet-xcm-bridge-hub (#2285) * implement ExportXcm and MessageDispatch for pallet-xcm-bridge-hub * spelling --- Cargo.lock | 2 - bridges/modules/xcm-bridge-hub/Cargo.toml | 5 +- .../modules/xcm-bridge-hub/src/dispatcher.rs | 107 ++++++++++ .../modules/xcm-bridge-hub/src/exporter.rs | 197 ++++++++---------- bridges/modules/xcm-bridge-hub/src/lib.rs | 87 +++----- bridges/modules/xcm-bridge-hub/src/mock.rs | 58 ++---- 6 files changed, 244 insertions(+), 212 deletions(-) create mode 100644 bridges/modules/xcm-bridge-hub/src/dispatcher.rs diff --git a/Cargo.lock b/Cargo.lock index 0012bbeb87cb..1dd19fd0a035 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -11674,11 +11674,9 @@ dependencies = [ name = "pallet-xcm-bridge-hub" version = "0.2.0" dependencies = [ - "bp-header-chain", "bp-messages", "bp-runtime", "bp-xcm-bridge-hub", - "bridge-runtime-common", "frame-support", "frame-system", "log", diff --git a/bridges/modules/xcm-bridge-hub/Cargo.toml b/bridges/modules/xcm-bridge-hub/Cargo.toml index 685928d4f23f..92701ebba5b8 100644 --- a/bridges/modules/xcm-bridge-hub/Cargo.toml +++ b/bridges/modules/xcm-bridge-hub/Cargo.toml @@ -21,7 +21,6 @@ bp-messages = { path = "../../primitives/messages", default-features = false } bp-runtime = { path = "../../primitives/runtime", default-features = false } bp-xcm-bridge-hub = { path = "../../primitives/xcm-bridge-hub", default-features = false } pallet-bridge-messages = { path = "../messages", default-features = false } -bridge-runtime-common = { path = "../../bin/runtime-common", default-features = false } # Substrate Dependencies frame-support = { path = "../../../substrate/frame/support", default-features = false } @@ -36,7 +35,6 @@ xcm-builder = { package = "staging-xcm-builder", path = "../../../polkadot/xcm/x xcm-executor = { package = "staging-xcm-executor", path = "../../../polkadot/xcm/xcm-executor", default-features = false } [dev-dependencies] -bp-header-chain = { path = "../../primitives/header-chain" } pallet-balances = { path = "../../../substrate/frame/balances" } sp-io = { path = "../../../substrate/primitives/io" } polkadot-parachain-primitives = { path = "../../../polkadot/parachain" } @@ -47,7 +45,6 @@ std = [ "bp-messages/std", "bp-runtime/std", "bp-xcm-bridge-hub/std", - "bridge-runtime-common/std", "codec/std", "frame-support/std", "frame-system/std", @@ -57,12 +54,12 @@ std = [ "sp-core/std", "sp-runtime/std", "sp-std/std", + "xcm/std", "xcm-builder/std", "xcm-executor/std", "xcm/std", ] runtime-benchmarks = [ - "bridge-runtime-common/runtime-benchmarks", "frame-support/runtime-benchmarks", "frame-system/runtime-benchmarks", "pallet-balances/runtime-benchmarks", diff --git a/bridges/modules/xcm-bridge-hub/src/dispatcher.rs b/bridges/modules/xcm-bridge-hub/src/dispatcher.rs new file mode 100644 index 000000000000..432896c25ac5 --- /dev/null +++ b/bridges/modules/xcm-bridge-hub/src/dispatcher.rs @@ -0,0 +1,107 @@ +// Copyright 2019-2021 Parity Technologies (UK) Ltd. +// This file is part of Parity Bridges Common. + +// Parity Bridges Common is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity Bridges Common is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity Bridges Common. If not, see . + +//! The code that allows to use the pallet (`pallet-xcm-bridge-hub`) as inbound +//! bridge messages dispatcher. Internally, it just forwards inbound blob to the +//! XCM-level blob dispatcher, which pushes message to some other queue (e.g. +//! to HRMP queue with the sibling target chain). + +use crate::{Config, Pallet, XcmAsPlainPayload, LOG_TARGET}; + +use bp_messages::target_chain::{DispatchMessage, MessageDispatch}; +use bp_runtime::messages::MessageDispatchResult; +use codec::{Decode, Encode}; +use frame_support::{weights::Weight, CloneNoBound, EqNoBound, PartialEqNoBound}; +use pallet_bridge_messages::{Config as BridgeMessagesConfig, WeightInfoExt}; +use scale_info::TypeInfo; +use sp_runtime::SaturatedConversion; +use xcm_builder::{DispatchBlob, DispatchBlobError}; + +/// Message dispatch result type for single message. +#[derive(CloneNoBound, EqNoBound, PartialEqNoBound, Encode, Decode, Debug, TypeInfo)] +pub enum XcmBlobMessageDispatchResult { + /// We've been unable to decode message payload. + InvalidPayload, + /// Message has been dispatched. + Dispatched, + /// Message has **NOT** been dispatched because of given error. + NotDispatched(#[codec(skip)] Option), +} + +/// An easy way to access associated messages pallet weights. +type MessagesPalletWeights = + >::BridgeMessagesPalletInstance>>::WeightInfo; + +impl, I: 'static> MessageDispatch for Pallet +where + T: BridgeMessagesConfig, +{ + type DispatchPayload = XcmAsPlainPayload; + type DispatchLevelResult = XcmBlobMessageDispatchResult; + + fn is_active() -> bool { + true + } + + fn dispatch_weight(message: &mut DispatchMessage) -> Weight { + match message.data.payload { + Ok(ref payload) => { + let payload_size = payload.encoded_size().saturated_into(); + MessagesPalletWeights::::message_dispatch_weight(payload_size) + }, + Err(_) => Weight::zero(), + } + } + + fn dispatch( + message: DispatchMessage, + ) -> MessageDispatchResult { + let payload = match message.data.payload { + Ok(payload) => payload, + Err(e) => { + log::error!( + target: LOG_TARGET, + "[XcmBlobMessageDispatch] payload error: {:?} - message_nonce: {:?}", + e, + message.key.nonce + ); + return MessageDispatchResult { + unspent_weight: Weight::zero(), + dispatch_level_result: XcmBlobMessageDispatchResult::InvalidPayload, + } + }, + }; + let dispatch_level_result = match T::BlobDispatcher::dispatch_blob(payload) { + Ok(_) => { + log::debug!( + target: LOG_TARGET, + "[XcmBlobMessageDispatch] DispatchBlob::dispatch_blob was ok - message_nonce: {:?}", + message.key.nonce + ); + XcmBlobMessageDispatchResult::Dispatched + }, + Err(e) => { + log::error!( + target: LOG_TARGET, + "[XcmBlobMessageDispatch] DispatchBlob::dispatch_blob failed, error: {:?} - message_nonce: {:?}", + e, message.key.nonce + ); + XcmBlobMessageDispatchResult::NotDispatched(Some(e)) + }, + }; + MessageDispatchResult { unspent_weight: Weight::zero(), dispatch_level_result } + } +} diff --git a/bridges/modules/xcm-bridge-hub/src/exporter.rs b/bridges/modules/xcm-bridge-hub/src/exporter.rs index af803900e5d7..7a3228acfbad 100644 --- a/bridges/modules/xcm-bridge-hub/src/exporter.rs +++ b/bridges/modules/xcm-bridge-hub/src/exporter.rs @@ -22,16 +22,19 @@ use crate::{Config, Pallet, LOG_TARGET}; -use bp_messages::source_chain::MessagesBridge; use bp_xcm_bridge_hub::XcmAsPlainPayload; -use bridge_runtime_common::messages_xcm_extension::{LocalXcmQueueManager, SenderAndLane}; -use pallet_bridge_messages::{Config as BridgeMessagesConfig, Pallet as BridgeMessagesPallet}; + +use bp_messages::{source_chain::MessagesBridge, LaneId}; +use frame_support::traits::Get; +use pallet_bridge_messages::{ + Config as BridgeMessagesConfig, Error, Pallet as BridgeMessagesPallet, +}; use xcm::prelude::*; use xcm_builder::{HaulBlob, HaulBlobError, HaulBlobExporter}; use xcm_executor::traits::ExportXcm; /// An easy way to access `HaulBlobExporter`. -pub type PalletAsHaulBlobExporter = HaulBlobExporter< +type PalletAsHaulBlobExporter = HaulBlobExporter< DummyHaulBlob, >::BridgedNetwork, >::DestinationVersion, @@ -45,7 +48,7 @@ where T: BridgeMessagesConfig, { type Ticket = ( - SenderAndLane, + LaneId, as MessagesBridge>::SendMessageArgs, XcmHash, ); @@ -57,12 +60,12 @@ where destination: &mut Option, message: &mut Option>, ) -> Result<(Self::Ticket, Assets), SendError> { - // Find supported lane_id. - let sender_and_lane = Self::lane_for( - universal_source.as_ref().ok_or(SendError::MissingArgument)?, - (&network, destination.as_ref().ok_or(SendError::MissingArgument)?), - ) - .ok_or(SendError::NotApplicable)?; + // `HaulBlobExporter` may consume the `universal_source` and `destination` arguments, so + // let's save them before + let bridge_origin_universal_location = + universal_source.clone().take().ok_or(SendError::MissingArgument)?; + let bridge_destination_interior_location = + destination.clone().take().ok_or(SendError::MissingArgument)?; // check if we are able to route the message. We use existing `HaulBlobExporter` for that. // It will make all required changes and will encode message properly, so that the @@ -75,23 +78,53 @@ where message, )?; - let bridge_message = MessagesPallet::::validate_message(sender_and_lane.lane, &blob) - .map_err(|e| { - log::error!( - target: LOG_TARGET, - "XCM message {:?} cannot be exported because of bridge error {:?} on bridge {:?}", - id, - e, - sender_and_lane.lane, - ); - SendError::Transport("BridgeValidateError") - })?; - - Ok(((sender_and_lane, bridge_message, id), price)) + // ok - now we know that the message may be routed by the pallet, let's prepare the + // destination universal location + let mut bridge_destination_universal_location: InteriorLocation = + GlobalConsensus(network).into(); + bridge_destination_universal_location + .append_with(bridge_destination_interior_location) + .map_err(|_| SendError::Unroutable)?; + + // .. and the origin relative location + let bridge_origin_relative_location = + bridge_origin_universal_location.relative_to(&T::UniversalLocation::get()); + + // then we are able to compute the lane id used to send messages + let bridge_locations = Self::bridge_locations( + Box::new(bridge_origin_relative_location), + Box::new(bridge_destination_universal_location.into()), + ) + .map_err(|_| SendError::Unroutable)?; + + let bridge_message = + MessagesPallet::::validate_message(bridge_locations.lane_id, &blob).map_err( + |e| { + match e { + Error::LanesManager(ref ei) => + log::error!(target: LOG_TARGET, "LanesManager: {ei:?}"), + Error::MessageRejectedByPallet(ref ei) => + log::error!(target: LOG_TARGET, "MessageRejectedByPallet: {ei:?}"), + Error::ReceptionConfirmation(ref ei) => + log::error!(target: LOG_TARGET, "ReceptionConfirmation: {ei:?}"), + _ => (), + }; + + log::error!( + target: LOG_TARGET, + "XCM message {:?} cannot be exported because of bridge error: {:?} on bridge {:?}", + id, + e, + bridge_locations, + ); + SendError::Transport("BridgeValidateError") + }, + )?; + + Ok(((bridge_locations.lane_id, bridge_message, id), price)) } - fn deliver((sender_and_lane, bridge_message, id): Self::Ticket) -> Result { - let lane_id = sender_and_lane.lane; + fn deliver((lane_id, bridge_message, id): Self::Ticket) -> Result { let artifacts = MessagesPallet::::send_message(bridge_message); log::info!( @@ -102,12 +135,6 @@ where artifacts.nonce, ); - // notify XCM queue manager about updated lane state - LocalXcmQueueManager::::on_bridge_message_enqueued( - &sender_and_lane, - artifacts.enqueued_messages, - ); - Ok(id) } } @@ -119,7 +146,7 @@ where /// else. But bridge messages pallet may have a dedicated channel (lane) for every pair of bridged /// chains. So we are using our own `ExportXcm` implementation, but to utilize `HaulBlobExporter` we /// still need this `DummyHaulBlob`. -pub struct DummyHaulBlob; +struct DummyHaulBlob; impl HaulBlob for DummyHaulBlob { fn haul_blob(_blob: XcmAsPlainPayload) -> Result<(), HaulBlobError> { @@ -130,89 +157,43 @@ impl HaulBlob for DummyHaulBlob { #[cfg(test)] mod tests { use super::*; - use crate::mock::*; - use bp_messages::{LaneState, OutboundLaneData}; - use frame_support::{__private::sp_tracing, assert_ok}; + use crate::{mock::*, LanesManagerOf}; use xcm_executor::traits::export_xcm; - fn universal_source() -> InteriorLocation { - [GlobalConsensus(RelayNetwork::get()), Parachain(SIBLING_ASSET_HUB_ID)].into() - } - - fn universal_destination() -> InteriorLocation { - BridgedDestination::get() - } - #[test] - fn export_works() { + fn proper_lane_is_used_by_export_xcm() { run_test(|| { - sp_tracing::try_init_simple(); - pallet_bridge_messages::OutboundLanes::::insert( - test_lane_id(), - OutboundLaneData { state: LaneState::Opened, ..Default::default() }, - ); - assert_ok!(export_xcm::( + // open expected outbound lane + let origin = OpenBridgeOrigin::sibling_parachain_origin(); + let with = bridged_asset_hub_location(); + let locations = + XcmOverBridge::bridge_locations_from_origin(origin, Box::new(with.into())).unwrap(); + + let lanes_manager = LanesManagerOf::::new(); + lanes_manager.create_outbound_lane(locations.lane_id).unwrap(); + assert!(lanes_manager + .active_outbound_lane(locations.lane_id) + .unwrap() + .queued_messages() + .is_empty()); + + // now let's try to enqueue message using our `ExportXcm` implementation + export_xcm::( BridgedRelayNetwork::get(), 0, - universal_source(), - universal_destination(), + locations.bridge_origin_universal_location, + locations.bridge_destination_universal_location.split_first().0, vec![Instruction::ClearOrigin].into(), - )); - }) - } + ) + .unwrap(); - #[test] - fn export_fails_if_argument_is_missing() { - run_test(|| { - assert_eq!( - XcmOverBridge::validate( - BridgedRelayNetwork::get(), - 0, - &mut None, - &mut Some(universal_destination()), - &mut Some(Vec::new().into()), - ), - Err(SendError::MissingArgument), - ); - - assert_eq!( - XcmOverBridge::validate( - BridgedRelayNetwork::get(), - 0, - &mut Some(universal_source()), - &mut None, - &mut Some(Vec::new().into()), - ), - Err(SendError::MissingArgument), - ); - }) - } - - #[test] - fn exporter_computes_correct_lane_id() { - run_test(|| { - sp_tracing::try_init_simple(); - let expected_lane_id = test_lane_id(); - - pallet_bridge_messages::OutboundLanes::::insert( - expected_lane_id, - OutboundLaneData { state: LaneState::Opened, ..Default::default() }, - ); - - assert_eq!( - XcmOverBridge::validate( - BridgedRelayNetwork::get(), - 0, - &mut Some(universal_source()), - &mut Some(universal_destination()), - &mut Some(Vec::new().into()), - ) + // double check that the message has been pushed to the expected lane + // (it should already been checked during `send_message` call) + assert!(!lanes_manager + .active_outbound_lane(locations.lane_id) .unwrap() - .0 - .0 - .lane, - expected_lane_id, - ); - }) + .queued_messages() + .is_empty()); + }); } } diff --git a/bridges/modules/xcm-bridge-hub/src/lib.rs b/bridges/modules/xcm-bridge-hub/src/lib.rs index f825f222bf9b..42fc3dff06c8 100644 --- a/bridges/modules/xcm-bridge-hub/src/lib.rs +++ b/bridges/modules/xcm-bridge-hub/src/lib.rs @@ -51,24 +51,24 @@ #![warn(missing_docs)] #![cfg_attr(not(feature = "std"), no_std)] -use bridge_runtime_common::messages_xcm_extension::XcmBlobHauler; - -pub use exporter::PalletAsHaulBlobExporter; -pub use pallet::*; - -mod exporter; use bp_messages::{LaneId, LaneState, MessageNonce}; use bp_runtime::{AccountIdOf, BalanceOf, RangeInclusiveExt}; use bp_xcm_bridge_hub::{ - bridge_locations, Bridge, BridgeLocations, BridgeLocationsError, BridgeState, + bridge_locations, Bridge, BridgeLocations, BridgeLocationsError, BridgeState, XcmAsPlainPayload, }; use frame_support::traits::{Currency, ReservableCurrency}; use frame_system::Config as SystemConfig; use pallet_bridge_messages::{Config as BridgeMessagesConfig, LanesManagerError}; use sp_runtime::traits::Zero; use xcm::prelude::*; +use xcm_builder::DispatchBlob; use xcm_executor::traits::ConvertLocation; +pub use dispatcher::XcmBlobMessageDispatchResult; +pub use pallet::*; + +mod dispatcher; +mod exporter; mod mock; /// The target that will be used when publishing logs related to this pallet. @@ -77,7 +77,6 @@ pub const LOG_TARGET: &str = "runtime::bridge-xcm"; #[frame_support::pallet] pub mod pallet { use super::*; - use bridge_runtime_common::messages_xcm_extension::SenderAndLane; use frame_support::pallet_prelude::*; use frame_system::pallet_prelude::{BlockNumberFor, *}; @@ -107,13 +106,6 @@ pub mod pallet { /// Checks the XCM version for the destination. type DestinationVersion: GetVersion; - /// Get point-to-point links with bridged consensus (`Self::BridgedNetworkId`). - /// (this will be replaced with dynamic on-chain bridges - `Bridges V2`) - type Lanes: Get>; - /// Support for point-to-point links - /// (this will be replaced with dynamic on-chain bridges - `Bridges V2`) - type LanesSupport: XcmBlobHauler; - /// A set of XCM locations within local consensus system that are allowed to open /// bridges with remote destinations. // TODO: there's only one impl of `EnsureOrigin` - @@ -132,6 +124,9 @@ pub mod pallet { type BridgeReserve: Get>>; /// Currency used to pay for bridge registration. type NativeCurrency: ReservableCurrency; + + /// XCM-level dispatcher for inbound bridge messages. + type BlobDispatcher: DispatchBlob; } /// An alias for the bridge metadata. @@ -182,7 +177,7 @@ pub mod pallet { ) -> DispatchResult { // check and compute required bridge locations let locations = - Self::bridge_locations(origin, bridge_destination_universal_location.clone())?; + Self::bridge_locations_from_origin(origin, bridge_destination_universal_location)?; // reserve balance on the parachain sovereign account let reserve = T::BridgeReserve::get(); @@ -262,7 +257,8 @@ pub mod pallet { may_prune_messages: MessageNonce, ) -> DispatchResult { // compute required bridge locations - let locations = Self::bridge_locations(origin, bridge_destination_universal_location)?; + let locations = + Self::bridge_locations_from_origin(origin, bridge_destination_universal_location)?; // TODO: https://github.com/paritytech/parity-bridges-common/issues/1760 - may do refund here, if // bridge/lanes are already closed + for messages that are not pruned @@ -362,19 +358,28 @@ pub mod pallet { } } - impl, I: 'static> Pallet - where - T: frame_system::Config>>, - T::NativeCurrency: Currency>>, - { + impl, I: 'static> Pallet { + /// Return bridge endpoint locations and dedicated lane identifier. This method converts + /// runtime `origin` argument to relative `Location` using the `T::OpenBridgeOrigin` + /// converter. + pub fn bridge_locations_from_origin( + origin: OriginFor, + bridge_destination_universal_location: Box, + ) -> Result, sp_runtime::DispatchError> { + Self::bridge_locations( + Box::new(T::OpenBridgeOrigin::ensure_origin(origin)?), + bridge_destination_universal_location, + ) + } + /// Return bridge endpoint locations and dedicated lane identifier. pub fn bridge_locations( - origin: OriginFor, + bridge_origin_relative_location: Box, bridge_destination_universal_location: Box, ) -> Result, sp_runtime::DispatchError> { bridge_locations( Box::new(T::UniversalLocation::get()), - Box::new(T::OpenBridgeOrigin::ensure_origin(origin)?), + bridge_origin_relative_location, Box::new( (*bridge_destination_universal_location) .try_into() @@ -454,31 +459,6 @@ pub mod pallet { /// The version of XCM location argument is unsupported. UnsupportedXcmVersion, } - - impl, I: 'static> Pallet { - /// Returns dedicated/configured lane identifier. - pub(crate) fn lane_for( - source: &InteriorLocation, - dest: (&NetworkId, &InteriorLocation), - ) -> Option { - let source = source.clone().relative_to(&T::UniversalLocation::get()); - - // Check that we have configured a point-to-point lane for 'source' and `dest`. - T::Lanes::get() - .into_iter() - .find_map(|(lane_source, (lane_dest_network, lane_dest))| { - if lane_source.location == source && - &lane_dest_network == dest.0 && - Self::bridged_network_id().as_ref() == Ok(dest.0) && - &lane_dest == dest.1 - { - Some(lane_source) - } else { - None - } - }) - } - } } #[cfg(test)] @@ -502,7 +482,8 @@ mod tests { with: InteriorLocation, ) -> (BridgeOf, BridgeLocations) { let reserve = BridgeReserve::get(); - let locations = XcmOverBridge::bridge_locations(origin, Box::new(with.into())).unwrap(); + let locations = + XcmOverBridge::bridge_locations_from_origin(origin, Box::new(with.into())).unwrap(); let bridge_owner_account = fund_origin_sovereign_account(&locations, reserve + ExistentialDeposit::get()); Balances::reserve(&bridge_owner_account, reserve).unwrap(); @@ -643,7 +624,7 @@ mod tests { fn open_bridge_fails_if_it_already_exists() { run_test(|| { let origin = OpenBridgeOrigin::parent_relay_chain_origin(); - let locations = XcmOverBridge::bridge_locations( + let locations = XcmOverBridge::bridge_locations_from_origin( origin.clone(), Box::new(bridged_asset_hub_location().into()), ) @@ -676,7 +657,7 @@ mod tests { fn open_bridge_fails_if_its_lanes_already_exists() { run_test(|| { let origin = OpenBridgeOrigin::parent_relay_chain_origin(); - let locations = XcmOverBridge::bridge_locations( + let locations = XcmOverBridge::bridge_locations_from_origin( origin.clone(), Box::new(bridged_asset_hub_location().into()), ) @@ -728,7 +709,7 @@ mod tests { System::reset_events(); // compute all other locations - let locations = XcmOverBridge::bridge_locations( + let locations = XcmOverBridge::bridge_locations_from_origin( origin.clone(), Box::new(bridged_asset_hub_location().into()), ) diff --git a/bridges/modules/xcm-bridge-hub/src/mock.rs b/bridges/modules/xcm-bridge-hub/src/mock.rs index 1276f5eae233..0c43b09a1d2e 100644 --- a/bridges/modules/xcm-bridge-hub/src/mock.rs +++ b/bridges/modules/xcm-bridge-hub/src/mock.rs @@ -22,24 +22,23 @@ use bp_messages::{ target_chain::{DispatchMessage, MessageDispatch}, ChainWithMessages, LaneId, MessageNonce, }; -use bp_runtime::{messages::MessageDispatchResult, Chain, ChainId, HashOf}; -use bridge_runtime_common::messages_xcm_extension::{SenderAndLane, XcmBlobHauler}; +use bp_runtime::{messages::MessageDispatchResult, Chain, ChainId}; use codec::Encode; use frame_support::{derive_impl, parameter_types, weights::RuntimeDbWeight}; -use sp_core::{Get, H256}; +use sp_core::H256; use sp_runtime::{ testing::Header as SubstrateHeader, traits::{BlakeTwo256, IdentityLookup}, AccountId32, BuildStorage, StateVersion, }; use xcm::prelude::*; +use xcm_builder::{DispatchBlob, DispatchBlobError, ParentIsPreset, SiblingParachainConvertsVia}; pub type AccountId = AccountId32; pub type Balance = u64; use frame_support::traits::{EnsureOrigin, OriginTrait}; use polkadot_parachain_primitives::primitives::Sibling; -use xcm_builder::{ParentIsPreset, SiblingParachainConvertsVia}; type Block = frame_system::mocking::MockBlock; @@ -47,11 +46,6 @@ pub const SIBLING_ASSET_HUB_ID: u32 = 2001; pub const THIS_BRIDGE_HUB_ID: u32 = 2002; pub const BRIDGED_ASSET_HUB_ID: u32 = 1001; -/// Message lane used in tests. -pub fn test_lane_id() -> LaneId { - bridge_runtime_common::messages_xcm_extension::LaneIdFromChainId::::get() -} - frame_support::construct_runtime! { pub enum TestRuntime { System: frame_system::{Pallet, Call, Config, Storage, Event}, @@ -92,8 +86,7 @@ impl pallet_bridge_messages::Config for TestRuntime { type ThisChain = ThisUnderlyingChain; type BridgedChain = BridgedUnderlyingChain; - type BridgedHeaderChain = BridgedHeaderChain; - // type BridgedHeaderChain = (); + type BridgedHeaderChain = (); } pub struct TestMessagesWeights; @@ -149,7 +142,6 @@ parameter_types! { GlobalConsensus(RelayNetwork::get()), Parachain(THIS_BRIDGE_HUB_ID), ].into(); - pub const Penalty: Balance = 1_000; } impl pallet_xcm_bridge_hub::Config for TestRuntime { @@ -162,36 +154,13 @@ impl pallet_xcm_bridge_hub::Config for TestRuntime { type MessageExportPrice = (); type DestinationVersion = AlwaysLatest; - type Lanes = TestLanes; - type LanesSupport = TestXcmBlobHauler; - type OpenBridgeOrigin = OpenBridgeOrigin; type BridgeOriginAccountIdConverter = LocationToAccountId; type BridgeReserve = BridgeReserve; type NativeCurrency = Balances; -} - -parameter_types! { - pub TestSenderAndLane: SenderAndLane = SenderAndLane { - location: Location::new(1, [Parachain(SIBLING_ASSET_HUB_ID)]), - lane: test_lane_id(), - }; - pub BridgedDestination: InteriorLocation = [ - Parachain(BRIDGED_ASSET_HUB_ID) - ].into(); - pub TestLanes: sp_std::vec::Vec<(SenderAndLane, (NetworkId, InteriorLocation))> = sp_std::vec![ - (TestSenderAndLane::get(), (BridgedRelayNetwork::get(), BridgedDestination::get())) - ]; -} -pub struct TestXcmBlobHauler; -impl XcmBlobHauler for TestXcmBlobHauler { - type Runtime = TestRuntime; - type MessagesInstance = (); - type ToSourceChainSender = (); - type CongestedMessage = (); - type UncongestedMessage = (); + type BlobDispatcher = TestBlobDispatcher; } /// Type for specifying how a `Location` can be converted into an `AccountId`. This is used @@ -274,6 +243,14 @@ impl EnsureOrigin for OpenBridgeOrigin { } } +pub struct TestBlobDispatcher; + +impl DispatchBlob for TestBlobDispatcher { + fn dispatch_blob(_blob: Vec) -> Result<(), DispatchBlobError> { + Ok(()) + } +} + pub struct ThisUnderlyingChain; impl Chain for ThisUnderlyingChain { @@ -365,15 +342,6 @@ impl MessageDispatch for TestMessageDispatch { } } -pub struct BridgedHeaderChain; -impl bp_header_chain::HeaderChain for BridgedHeaderChain { - fn finalized_header_state_root( - _hash: HashOf, - ) -> Option> { - unreachable!() - } -} - /// Location of bridged asset hub. pub fn bridged_asset_hub_location() -> InteriorLocation { [GlobalConsensus(BridgedRelayNetwork::get()), Parachain(BRIDGED_ASSET_HUB_ID)].into()