diff --git a/Cargo.lock b/Cargo.lock index 360e89d8ad89d..b85a31a4b491b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -21044,6 +21044,7 @@ dependencies = [ "sp-runtime 31.0.1", "sp-std 14.0.0", "staging-xcm", + "staging-xcm-builder", "staging-xcm-executor", ] diff --git a/bridges/snowbridge/primitives/router/Cargo.toml b/bridges/snowbridge/primitives/router/Cargo.toml index ee8d481cec12a..664f2dbf79304 100644 --- a/bridges/snowbridge/primitives/router/Cargo.toml +++ b/bridges/snowbridge/primitives/router/Cargo.toml @@ -24,6 +24,7 @@ sp-std = { workspace = true } xcm = { workspace = true } xcm-executor = { workspace = true } +xcm-builder = { workspace = true } snowbridge-core = { workspace = true } @@ -43,6 +44,7 @@ std = [ "sp-io/std", "sp-runtime/std", "sp-std/std", + "xcm-builder/std", "xcm-executor/std", "xcm/std", ] @@ -50,5 +52,6 @@ runtime-benchmarks = [ "frame-support/runtime-benchmarks", "snowbridge-core/runtime-benchmarks", "sp-runtime/runtime-benchmarks", + "xcm-builder/runtime-benchmarks", "xcm-executor/runtime-benchmarks", ] diff --git a/bridges/snowbridge/primitives/router/src/outbound/mod.rs b/bridges/snowbridge/primitives/router/src/outbound/mod.rs index efc1ef56f3047..c3d00147a6754 100644 --- a/bridges/snowbridge/primitives/router/src/outbound/mod.rs +++ b/bridges/snowbridge/primitives/router/src/outbound/mod.rs @@ -5,11 +5,14 @@ #[cfg(test)] mod tests; -use core::slice::Iter; - use codec::{Decode, Encode}; +use core::slice::Iter; +use sp_std::ops::ControlFlow; -use frame_support::{ensure, traits::Get}; +use frame_support::{ + ensure, + traits::{Contains, Get, ProcessMessageError}, +}; use snowbridge_core::{ outbound::{AgentExecuteCommand, Command, Message, SendMessage}, AgentId, ChannelId, ParaId, TokenId, TokenIdOf, @@ -18,6 +21,7 @@ use sp_core::{H160, H256}; use sp_runtime::traits::MaybeEquivalence; use sp_std::{iter::Peekable, marker::PhantomData, prelude::*}; use xcm::prelude::*; +use xcm_builder::{CreateMatcher, ExporterFor, MatchXcm}; use xcm_executor::traits::{ConvertLocation, ExportXcm}; pub struct EthereumBlobExporter< @@ -407,3 +411,40 @@ where Ok((Command::MintForeignToken { token_id, recipient, amount }, *topic_id)) } } + +/// An adapter for the implementation of `ExporterFor`, which attempts to find the +/// `(bridge_location, payment)` for the requested `network` and `remote_location` and `xcm` +/// in the provided `T` table containing various exporters. +pub struct XcmFilterExporter(core::marker::PhantomData<(T, M)>); +impl>> ExporterFor for XcmFilterExporter { + fn exporter_for( + network: &NetworkId, + remote_location: &InteriorLocation, + xcm: &Xcm<()>, + ) -> Option<(Location, Option)> { + // check the XCM + if !M::contains(xcm) { + return None + } + // check `network` and `remote_location` + T::exporter_for(network, remote_location, xcm) + } +} + +/// Xcm for SnowbridgeV2 which requires XCMV5 +pub struct XcmForSnowbridgeV2; +impl Contains> for XcmForSnowbridgeV2 { + fn contains(xcm: &Xcm<()>) -> bool { + let mut instructions = xcm.clone().0; + let result = instructions.matcher().match_next_inst_while( + |_| true, + |inst| { + return match inst { + AliasOrigin(..) => Err(ProcessMessageError::Yield), + _ => Ok(ControlFlow::Continue(())), + } + }, + ); + result.is_err() + } +} diff --git a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/xcm_config.rs b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/xcm_config.rs index 614ef81a4fa1b..a1324403f4d43 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/xcm_config.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/xcm_config.rs @@ -494,7 +494,10 @@ pub type XcmRouter = WithUniqueTopic<( // Router which wraps and sends xcm to BridgeHub to be delivered to the Ethereum // GlobalConsensus SovereignPaidRemoteExporter< - bridging::to_ethereum::EthereumNetworkExportTable, + ( + bridging::to_ethereum::EthereumNetworkExportTableV2, + bridging::to_ethereum::EthereumNetworkExportTable, + ), XcmpQueue, UniversalLocation, >, @@ -666,7 +669,9 @@ pub mod bridging { /// Needs to be more than fee calculated from DefaultFeeConfig FeeConfigRecord in snowbridge:parachain/pallets/outbound-queue/src/lib.rs /// Polkadot uses 10 decimals, Kusama,Rococo,Westend 12 decimals. pub const DefaultBridgeHubEthereumBaseFee: Balance = 2_750_872_500_000; + pub const DefaultBridgeHubEthereumBaseFeeV2: Balance = 4_000_000_000; pub storage BridgeHubEthereumBaseFee: Balance = DefaultBridgeHubEthereumBaseFee::get(); + pub storage BridgeHubEthereumBaseFeeV2: Balance = DefaultBridgeHubEthereumBaseFeeV2::get(); pub SiblingBridgeHubWithEthereumInboundQueueInstance: Location = Location::new( 1, [ @@ -689,6 +694,18 @@ pub mod bridging { ), ]; + pub BridgeTableV2: sp_std::vec::Vec = sp_std::vec![ + NetworkExportTableItem::new( + EthereumNetwork::get(), + Some(sp_std::vec![Junctions::Here]), + SiblingBridgeHub::get(), + Some(( + XcmBridgeHubRouterFeeAssetId::get(), + BridgeHubEthereumBaseFeeV2::get(), + ).into()) + ), + ]; + /// Universal aliases pub UniversalAliases: BTreeSet<(Location, Junction)> = BTreeSet::from_iter( sp_std::vec![ @@ -699,8 +716,18 @@ pub mod bridging { pub EthereumBridgeTable: sp_std::vec::Vec = sp_std::vec::Vec::new().into_iter() .chain(BridgeTable::get()) .collect(); + + pub EthereumBridgeTableV2: sp_std::vec::Vec = sp_std::vec::Vec::new().into_iter() + .chain(BridgeTableV2::get()) + .collect(); } + pub type EthereumNetworkExportTableV2 = + snowbridge_router_primitives::outbound::XcmFilterExporter< + xcm_builder::NetworkExportTable, + snowbridge_router_primitives::outbound::XcmForSnowbridgeV2, + >; + pub type EthereumNetworkExportTable = xcm_builder::NetworkExportTable; pub type IsTrustedBridgedReserveLocationForForeignAsset =