diff --git a/bridges/snowbridge/pallets/system-v2/src/lib.rs b/bridges/snowbridge/pallets/system-v2/src/lib.rs index 095b263f8f257..95a4e278fd471 100644 --- a/bridges/snowbridge/pallets/system-v2/src/lib.rs +++ b/bridges/snowbridge/pallets/system-v2/src/lib.rs @@ -46,7 +46,7 @@ use snowbridge_outbound_queue_primitives::{ use snowbridge_pallet_system::ForeignToNativeId; use sp_core::{H160, H256}; use sp_io::hashing::blake2_256; -use sp_runtime::traits::MaybeConvert; +use sp_runtime::traits::{MaybeConvert, MaybeEquivalence}; use sp_std::prelude::*; use xcm::prelude::*; use xcm_executor::traits::ConvertLocation; @@ -318,4 +318,13 @@ pub mod pallet { snowbridge_pallet_system::Pallet::::maybe_convert(foreign_id) } } + + impl MaybeEquivalence for Pallet { + fn convert(foreign_id: &TokenId) -> Option { + snowbridge_pallet_system::Pallet::::convert(foreign_id) + } + fn convert_back(location: &Location) -> Option { + snowbridge_pallet_system::Pallet::::convert_back(location) + } + } } diff --git a/bridges/snowbridge/pallets/system-v2/src/tests.rs b/bridges/snowbridge/pallets/system-v2/src/tests.rs index 2475dfa67c399..d92a7aa249c78 100644 --- a/bridges/snowbridge/pallets/system-v2/src/tests.rs +++ b/bridges/snowbridge/pallets/system-v2/src/tests.rs @@ -138,6 +138,11 @@ fn register_all_tokens_succeeds() { let foreign_token_id = EthereumSystemV2::location_to_message_origin(tc.native.clone()).unwrap(); + assert_eq!( + NativeToForeignId::::get(reanchored_location.clone()), + Some(foreign_token_id) + ); + assert_eq!( ForeignToNativeId::::get(foreign_token_id), Some(reanchored_location.clone()) diff --git a/bridges/snowbridge/pallets/system/src/lib.rs b/bridges/snowbridge/pallets/system/src/lib.rs index d277186bd5b9d..a827284c741be 100644 --- a/bridges/snowbridge/pallets/system/src/lib.rs +++ b/bridges/snowbridge/pallets/system/src/lib.rs @@ -52,7 +52,7 @@ use snowbridge_outbound_queue_primitives::{ }; use sp_core::{RuntimeDebug, H160, H256}; use sp_io::hashing::blake2_256; -use sp_runtime::{traits::MaybeConvert, DispatchError, SaturatedConversion}; +use sp_runtime::{traits::{MaybeConvert, MaybeEquivalence}, DispatchError, SaturatedConversion}; use sp_std::prelude::*; use xcm::prelude::*; use xcm_executor::traits::ConvertLocation; @@ -233,6 +233,11 @@ pub mod pallet { pub type ForeignToNativeId = StorageMap<_, Blake2_128Concat, TokenId, Location, OptionQuery>; + /// Lookup table for native location relative to ethereum to foreign token ID + #[pallet::storage] + pub type NativeToForeignId = + StorageMap<_, Blake2_128Concat, Location, TokenId, OptionQuery>; + #[pallet::genesis_config] #[derive(frame_support::DefaultNoBound)] pub struct GenesisConfig { @@ -489,6 +494,7 @@ pub mod pallet { .ok_or(Error::::LocationConversionFailed)?; if !ForeignToNativeId::::contains_key(token_id) { + NativeToForeignId::::insert(location.clone(), token_id); ForeignToNativeId::::insert(token_id, location.clone()); } @@ -534,4 +540,13 @@ pub mod pallet { ForeignToNativeId::::get(foreign_id) } } + + impl MaybeEquivalence for Pallet { + fn convert(foreign_id: &TokenId) -> Option { + ForeignToNativeId::::get(foreign_id) + } + fn convert_back(location: &Location) -> Option { + NativeToForeignId::::get(location) + } + } } diff --git a/bridges/snowbridge/primitives/outbound-queue/src/v1/converter/mod.rs b/bridges/snowbridge/primitives/outbound-queue/src/v1/converter/mod.rs index 7f6275fa331e7..ad7c4e5cb5993 100644 --- a/bridges/snowbridge/primitives/outbound-queue/src/v1/converter/mod.rs +++ b/bridges/snowbridge/primitives/outbound-queue/src/v1/converter/mod.rs @@ -13,7 +13,7 @@ use super::message::{Command, Message, SendMessage}; use frame_support::{ensure, traits::Get}; use snowbridge_core::{AgentId, ChannelId, ParaId, TokenId, TokenIdOf}; use sp_core::{H160, H256}; -use sp_runtime::traits::MaybeConvert; +use sp_runtime::traits::{MaybeConvert, MaybeEquivalence}; use sp_std::{iter::Peekable, marker::PhantomData, prelude::*}; use xcm::prelude::*; use xcm_executor::traits::{ConvertLocation, ExportXcm}; @@ -48,7 +48,7 @@ where EthereumNetwork: Get, OutboundQueue: SendMessage, AgentHashedDescription: ConvertLocation, - ConvertAssetId: MaybeConvert, + ConvertAssetId: MaybeEquivalence, { type Ticket = (Vec, XcmHash); @@ -194,7 +194,7 @@ struct XcmConverter<'a, ConvertAssetId, Call> { } impl<'a, ConvertAssetId, Call> XcmConverter<'a, ConvertAssetId, Call> where - ConvertAssetId: MaybeConvert, + ConvertAssetId: MaybeEquivalence, { fn new(message: &'a Xcm, ethereum_network: NetworkId, agent_id: AgentId) -> Self { Self { @@ -411,9 +411,7 @@ where // transfer amount must be greater than 0. ensure!(amount > 0, ZeroAssetTransfer); - let token_id = TokenIdOf::convert_location(&asset_id).ok_or(InvalidAsset)?; - - ConvertAssetId::maybe_convert(token_id).ok_or(InvalidAsset)?; + let token_id = ConvertAssetId::convert_back(&asset_id).ok_or(InvalidAsset)?; // Check if there is a SetTopic and skip over it if found. let topic_id = match_expression!(self.next()?, SetTopic(id), id).ok_or(SetTopicExpected)?; diff --git a/bridges/snowbridge/primitives/outbound-queue/src/v1/converter/tests.rs b/bridges/snowbridge/primitives/outbound-queue/src/v1/converter/tests.rs index 9ce5bb8b29d30..158c4604a9435 100644 --- a/bridges/snowbridge/primitives/outbound-queue/src/v1/converter/tests.rs +++ b/bridges/snowbridge/primitives/outbound-queue/src/v1/converter/tests.rs @@ -62,10 +62,13 @@ impl SendMessageFeeProvider for MockErrOutboundQueue { } pub struct MockTokenIdConvert; -impl MaybeConvert for MockTokenIdConvert { - fn maybe_convert(_id: TokenId) -> Option { +impl MaybeEquivalence for MockTokenIdConvert { + fn convert(_id: &TokenId) -> Option { Some(Location::new(1, [GlobalConsensus(ByGenesis(WESTEND_GENESIS_HASH))])) } + fn convert_back(_loc: &Location) -> Option { + Some(1) + } } #[test] diff --git a/bridges/snowbridge/primitives/outbound-queue/src/v2/converter/convert.rs b/bridges/snowbridge/primitives/outbound-queue/src/v2/converter/convert.rs index f64554e42756a..040a42246ff33 100644 --- a/bridges/snowbridge/primitives/outbound-queue/src/v2/converter/convert.rs +++ b/bridges/snowbridge/primitives/outbound-queue/src/v2/converter/convert.rs @@ -14,7 +14,7 @@ use crate::v2::{ use crate::v2::convert::XcmConverterError::{AssetResolutionFailed, FilterDoesNotConsumeAllAssets}; use sp_core::H160; -use sp_runtime::traits::MaybeConvert; +use sp_runtime::traits::{MaybeConvert, MaybeEquivalence}; use sp_std::{iter::Peekable, marker::PhantomData, prelude::*}; use xcm::prelude::*; use xcm_executor::traits::ConvertLocation; @@ -64,7 +64,7 @@ pub struct XcmConverter<'a, ConvertAssetId, Call> { } impl<'a, ConvertAssetId, Call> XcmConverter<'a, ConvertAssetId, Call> where - ConvertAssetId: MaybeConvert, + ConvertAssetId: MaybeEquivalence, { pub fn new(message: &'a Xcm, ethereum_network: NetworkId) -> Self { Self { @@ -173,8 +173,7 @@ where ensure!(amount > 0, ZeroAssetTransfer); // Ensure PNA already registered - let token_id = TokenIdOf::convert_location(&asset_id).ok_or(InvalidAsset)?; - ConvertAssetId::maybe_convert(token_id).ok_or(InvalidAsset)?; + let token_id = ConvertAssetId::convert_back(&asset_id).ok_or(InvalidAsset)?; commands.push(Command::MintForeignToken { token_id, recipient, amount }); } diff --git a/bridges/snowbridge/primitives/outbound-queue/src/v2/converter/mod.rs b/bridges/snowbridge/primitives/outbound-queue/src/v2/converter/mod.rs index c4459a05c7c51..d5cc48d1c9ed5 100644 --- a/bridges/snowbridge/primitives/outbound-queue/src/v2/converter/mod.rs +++ b/bridges/snowbridge/primitives/outbound-queue/src/v2/converter/mod.rs @@ -15,7 +15,7 @@ use frame_support::{ traits::{Contains, Get, ProcessMessageError}, }; use snowbridge_core::{ParaId, TokenId}; -use sp_runtime::traits::MaybeConvert; +use sp_runtime::traits::{MaybeConvert, MaybeEquivalence}; use sp_std::{marker::PhantomData, ops::ControlFlow, prelude::*}; use xcm::prelude::*; use xcm_builder::{CreateMatcher, ExporterFor, MatchXcm}; @@ -53,7 +53,7 @@ where UniversalLocation: Get, EthereumNetwork: Get, OutboundQueue: SendMessage, - ConvertAssetId: MaybeConvert, + ConvertAssetId: MaybeEquivalence, AssetHubParaId: Get, { type Ticket = (Vec, XcmHash); diff --git a/bridges/snowbridge/primitives/outbound-queue/src/v2/converter/tests.rs b/bridges/snowbridge/primitives/outbound-queue/src/v2/converter/tests.rs index bb5a88c73c809..e5baa10b90d83 100644 --- a/bridges/snowbridge/primitives/outbound-queue/src/v2/converter/tests.rs +++ b/bridges/snowbridge/primitives/outbound-queue/src/v2/converter/tests.rs @@ -62,10 +62,13 @@ impl SendMessageFeeProvider for MockErrOutboundQueue { } pub struct MockTokenIdConvert; -impl MaybeConvert for MockTokenIdConvert { - fn maybe_convert(_id: TokenId) -> Option { +impl MaybeEquivalence for MockTokenIdConvert { + fn convert(_id: &TokenId) -> Option { Some(Location::new(1, [GlobalConsensus(ByGenesis(WESTEND_GENESIS_HASH))])) } + fn convert_back(_loc: &Location) -> Option { + Some(1) + } } #[test]