From b7d2835373c1a92d39cbedbf227a1be3283be72a Mon Sep 17 00:00:00 2001 From: claravanstaden Date: Wed, 9 Apr 2025 14:12:45 +0200 Subject: [PATCH 1/2] use ExternalConsensusLocationsConverterFor instead of EthereumLocationsConverterFor --- .../inbound-queue/src/v2/converter.rs | 56 ++++++++++++++----- .../src/bridge_to_ethereum_config.rs | 3 + 2 files changed, 45 insertions(+), 14 deletions(-) diff --git a/bridges/snowbridge/primitives/inbound-queue/src/v2/converter.rs b/bridges/snowbridge/primitives/inbound-queue/src/v2/converter.rs index 3c765cf1e6665..c0828f3e3234a 100644 --- a/bridges/snowbridge/primitives/inbound-queue/src/v2/converter.rs +++ b/bridges/snowbridge/primitives/inbound-queue/src/v2/converter.rs @@ -3,7 +3,7 @@ //! Converts messages from Solidity ABI-encoding to XCM use super::{message::*, traits::*}; -use crate::{v2::LOG_TARGET, CallIndex, EthereumLocationsConverterFor}; +use crate::{v2::LOG_TARGET, CallIndex}; use codec::{Decode, DecodeLimit, Encode}; use core::marker::PhantomData; use frame_support::ensure; @@ -16,6 +16,8 @@ use xcm::{ prelude::{Junction::*, *}, MAX_XCM_DECODE_DEPTH, }; +use xcm_builder::ExternalConsensusLocationsConverterFor; +use xcm_executor::traits::ConvertLocation; const MINIMUM_DEPOSIT: u128 = 1; @@ -55,6 +57,8 @@ pub struct MessageToXcm< GatewayProxyAddress, EthereumUniversalLocation, GlobalAssetHubLocation, + AssetHubUniversalLocation, + AccountId, > { _phantom: PhantomData<( CreateAssetCall, @@ -65,6 +69,8 @@ pub struct MessageToXcm< GatewayProxyAddress, EthereumUniversalLocation, GlobalAssetHubLocation, + AssetHubUniversalLocation, + AccountId, )>, } @@ -77,6 +83,8 @@ impl< GatewayProxyAddress, EthereumUniversalLocation, GlobalAssetHubLocation, + AssetHubUniversalLocation, + AccountId, > MessageToXcm< CreateAssetCall, @@ -87,6 +95,8 @@ impl< GatewayProxyAddress, EthereumUniversalLocation, GlobalAssetHubLocation, + AssetHubUniversalLocation, + AccountId, > where CreateAssetCall: Get, @@ -97,6 +107,8 @@ where GatewayProxyAddress: Get, EthereumUniversalLocation: Get, GlobalAssetHubLocation: Get, + AssetHubUniversalLocation: Get, + AccountId: Into<[u8; 32]>, { /// Parse the message into an intermediate form, with all fields decoded /// and prepared. @@ -183,11 +195,13 @@ where /// Get the bridge owner account ID from the current Ethereum network chain ID. /// Returns an error if the network is not Ethereum. fn bridge_owner() -> Result<[u8; 32], ConvertMessageError> { - let chain_id = match EthereumNetwork::get() { - NetworkId::Ethereum { chain_id } => chain_id, - _ => return Err(ConvertMessageError::InvalidNetwork), - }; - Ok(EthereumLocationsConverterFor::<[u8; 32]>::from_chain_id(&chain_id)) + let account = + ExternalConsensusLocationsConverterFor::::convert_location( + &Location::new(2, [GlobalConsensus(EthereumNetwork::get())]), + ) + .ok_or(ConvertMessageError::CannotReanchor)?; + + Ok(account) } /// Construct the remote XCM needed to create a new asset in the `ForeignAssets` pallet @@ -293,6 +307,8 @@ impl< GatewayProxyAddress, EthereumUniversalLocation, GlobalAssetHubLocation, + AssetHubUniversalLocation, + AccountId, > ConvertMessage for MessageToXcm< CreateAssetCall, @@ -303,6 +319,8 @@ impl< GatewayProxyAddress, EthereumUniversalLocation, GlobalAssetHubLocation, + AssetHubUniversalLocation, + AccountId, > where CreateAssetCall: Get, @@ -313,6 +331,8 @@ where GatewayProxyAddress: Get, EthereumUniversalLocation: Get, GlobalAssetHubLocation: Get, + AssetHubUniversalLocation: Get, + AccountId: Into<[u8; 32]>, { fn convert(message: Message) -> Result, ConvertMessageError> { let message = Self::prepare(message)?; @@ -385,9 +405,10 @@ mod tests { pub const EthereumNetwork: xcm::v5::NetworkId = xcm::v5::NetworkId::Ethereum { chain_id: 11155111 }; pub const GatewayAddress: H160 = H160(GATEWAY_ADDRESS); pub InboundQueueLocation: InteriorLocation = [PalletInstance(84)].into(); - pub UniversalLocation: InteriorLocation = + pub EthereumUniversalLocation: InteriorLocation = [GlobalConsensus(ByGenesis(WESTEND_GENESIS_HASH)), Parachain(1002)].into(); pub AssetHubFromEthereum: Location = Location::new(1,[GlobalConsensus(ByGenesis(WESTEND_GENESIS_HASH)),Parachain(1000)]); + pub AssetHubUniversalLocation: InteriorLocation = [GlobalConsensus(ByGenesis(WESTEND_GENESIS_HASH)),Parachain(1000)].into(); pub const CreateAssetCall: [u8;2] = [53, 0]; pub const CreateAssetDeposit: u128 = 10_000_000_000u128; } @@ -419,8 +440,10 @@ mod tests { InboundQueueLocation, MockTokenIdConvert, GatewayAddress, - UniversalLocation, + EthereumUniversalLocation, AssetHubFromEthereum, + AssetHubUniversalLocation, + [u8; 32], >; type ConverterFailing = MessageToXcm< @@ -430,8 +453,10 @@ mod tests { InboundQueueLocation, MockFailedTokenConvert, GatewayAddress, - UniversalLocation, + EthereumUniversalLocation, AssetHubFromEthereum, + AssetHubUniversalLocation, + [u8; 32], >; #[test] @@ -725,11 +750,14 @@ mod tests { } // actual claimer should default to Snowbridge sovereign account - let chain_id = match EthereumNetwork::get() { - NetworkId::Ethereum { chain_id } => chain_id, - _ => 0, - }; - let bridge_owner = EthereumLocationsConverterFor::<[u8; 32]>::from_chain_id(&chain_id); + let bridge_owner = ExternalConsensusLocationsConverterFor::< + AssetHubUniversalLocation, + [u8; 32], + >::convert_location(&Location::new( + 2, + [GlobalConsensus(EthereumNetwork::get())], + )) + .unwrap(); assert_eq!( actual_claimer, Some(Location::new(0, [AccountId32 { network: None, id: bridge_owner }])) diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/bridge_to_ethereum_config.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/bridge_to_ethereum_config.rs index fa031fa9532dd..278348cbaf4e7 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/bridge_to_ethereum_config.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/bridge_to_ethereum_config.rs @@ -84,6 +84,7 @@ parameter_types! { multiplier: FixedU128::from_rational(1, 1), }; pub AssetHubFromEthereum: Location = Location::new(1, [GlobalConsensus(RelayNetwork::get()), Parachain(ASSET_HUB_ID)]); + pub AssetHubUniversalLocation: InteriorLocation = [GlobalConsensus(RelayNetwork::get()), Parachain(ASSET_HUB_ID)].into(); pub AssetHubLocation: Location = Location::new(1, [Parachain(ASSET_HUB_ID)]); pub EthereumUniversalLocation: InteriorLocation = [GlobalConsensus(EthereumNetwork::get())].into(); pub InboundQueueV2Location: InteriorLocation = [PalletInstance(INBOUND_QUEUE_PALLET_INDEX_V2)].into(); @@ -144,6 +145,8 @@ impl snowbridge_pallet_inbound_queue_v2::Config for Runtime { EthereumGatewayAddress, EthereumUniversalLocation, AssetHubFromEthereum, + AssetHubUniversalLocation, + AccountId, >; type AccountToLocation = xcm_builder::AliasesIntoAccountId32< xcm_config::RelayNetwork, From fe67940d4133aba0625e54b2eea4a3cffe23d929 Mon Sep 17 00:00:00 2001 From: claravanstaden Date: Fri, 11 Apr 2025 14:43:38 +0200 Subject: [PATCH 2/2] use AccountId --- .../inbound-queue/src/v2/converter.rs | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/bridges/snowbridge/primitives/inbound-queue/src/v2/converter.rs b/bridges/snowbridge/primitives/inbound-queue/src/v2/converter.rs index c0828f3e3234a..61603297d173c 100644 --- a/bridges/snowbridge/primitives/inbound-queue/src/v2/converter.rs +++ b/bridges/snowbridge/primitives/inbound-queue/src/v2/converter.rs @@ -108,7 +108,7 @@ where EthereumUniversalLocation: Get, GlobalAssetHubLocation: Get, AssetHubUniversalLocation: Get, - AccountId: Into<[u8; 32]>, + AccountId: Into<[u8; 32]> + From<[u8; 32]> + Clone, { /// Parse the message into an intermediate form, with all fields decoded /// and prepared. @@ -122,7 +122,7 @@ where // Get the claimer from the message, .and_then(|claimer_bytes| Location::decode(&mut claimer_bytes.as_ref()).ok()) // or use the Snowbridge sovereign on AH as the fallback claimer. - .unwrap_or_else(|| Location::new(0, [AccountId32 { network: None, id: bridge_owner }])); + .unwrap_or_else(|| Location::new(0, [AccountId32 { network: None, id: bridge_owner.clone().into() }])); let mut remote_xcm: Xcm<()> = match &message.xcm { XcmPayload::Raw(raw) => Self::decode_raw_xcm(raw), @@ -194,9 +194,9 @@ where /// Get the bridge owner account ID from the current Ethereum network chain ID. /// Returns an error if the network is not Ethereum. - fn bridge_owner() -> Result<[u8; 32], ConvertMessageError> { + fn bridge_owner() -> Result { let account = - ExternalConsensusLocationsConverterFor::::convert_location( + ExternalConsensusLocationsConverterFor::::convert_location( &Location::new(2, [GlobalConsensus(EthereumNetwork::get())]), ) .ok_or(ConvertMessageError::CannotReanchor)?; @@ -210,7 +210,7 @@ where token: &H160, network: super::message::Network, eth_value: u128, - bridge_owner: [u8; 32], + bridge_owner: AccountId, claimer: Location, ) -> Result, ConvertMessageError> { let dot_asset = Location::new(1, Here); @@ -245,11 +245,12 @@ where fn make_create_asset_xcm_for_polkadot( create_call_index: [u8; 2], asset_id: Location, - bridge_owner: [u8; 32], + bridge_owner: AccountId, dot_fee_asset: xcm::prelude::Asset, eth_asset: xcm::prelude::Asset, claimer: Location, ) -> Xcm<()> { + let bridge_owner_bytes: [u8; 32] = bridge_owner.into(); vec![ // Exchange eth for dot to pay the asset creation deposit. ExchangeAsset { @@ -259,7 +260,7 @@ where }, // Deposit the dot deposit into the bridge sovereign account (where the asset // creation fee will be deducted from). - DepositAsset { assets: dot_fee_asset.clone().into(), beneficiary: bridge_owner.into() }, + DepositAsset { assets: dot_fee_asset.clone().into(), beneficiary: bridge_owner_bytes.into() }, // Call to create the asset. Transact { origin_kind: OriginKind::Xcm, @@ -267,7 +268,7 @@ where call: ( create_call_index, asset_id.clone(), - MultiAddress::<[u8; 32], ()>::Id(bridge_owner.into()), + MultiAddress::<[u8; 32], ()>::Id(bridge_owner_bytes.into()), MINIMUM_DEPOSIT, ) .encode() @@ -332,7 +333,7 @@ where EthereumUniversalLocation: Get, GlobalAssetHubLocation: Get, AssetHubUniversalLocation: Get, - AccountId: Into<[u8; 32]>, + AccountId: Into<[u8; 32]> + From<[u8; 32]> + Clone, { fn convert(message: Message) -> Result, ConvertMessageError> { let message = Self::prepare(message)?;