From 1be0f8ed6df0ef7e54a9a664342be01d36697cf9 Mon Sep 17 00:00:00 2001 From: ron Date: Fri, 12 Jan 2024 21:13:07 +0800 Subject: [PATCH 1/3] Runtime test for create asset in AH --- .github/workflows/parachain.yml | 9 ++- parachain/pallets/inbound-queue/src/mock.rs | 10 +-- .../primitives/router/src/inbound/mod.rs | 75 +++++++++---------- .../primitives/router/src/inbound/tests.rs | 2 - polkadot-sdk | 2 +- 5 files changed, 45 insertions(+), 53 deletions(-) diff --git a/.github/workflows/parachain.yml b/.github/workflows/parachain.yml index ca1ff77cda..a13cbdcd95 100644 --- a/.github/workflows/parachain.yml +++ b/.github/workflows/parachain.yml @@ -233,13 +233,20 @@ jobs: repo-token: ${{ secrets.GITHUB_TOKEN }} - name: setup rust toolchain run: rustup show - - name: snowbridge runtime tests + - name: snowbridge runtime tests in bridge-hub working-directory: polkadot-sdk run: > RUST_LOG=xcm=trace cargo test --package bridge-hub-rococo-runtime --test snowbridge -- --nocapture + - name: snowbridge runtime tests in asset-hub + working-directory: polkadot-sdk + run: > + RUST_LOG=xcm=trace cargo test + --package asset-hub-rococo-runtime + --test snowbridge + -- --nocapture integration-tests: needs: check diff --git a/parachain/pallets/inbound-queue/src/mock.rs b/parachain/pallets/inbound-queue/src/mock.rs index b031a46e21..077c50f677 100644 --- a/parachain/pallets/inbound-queue/src/mock.rs +++ b/parachain/pallets/inbound-queue/src/mock.rs @@ -134,7 +134,6 @@ const GATEWAY_ADDRESS: [u8; 20] = hex!["eda338e4dc46038493b885327842fd3e301cab39 parameter_types! { pub const EthereumNetwork: xcm::v3::NetworkId = xcm::v3::NetworkId::Ethereum { chain_id: 11155111 }; pub const GatewayAddress: H160 = H160(GATEWAY_ADDRESS); - pub const CreateAssetCall: [u8;2] = [53, 0]; pub const CreateAssetExecutionFee: u128 = 2_000_000_000; pub const CreateAssetDeposit: u128 = 100_000_000_000; pub const SendTokenExecutionFee: u128 = 1_000_000_000; @@ -252,13 +251,8 @@ impl inbound_queue::Config for Test { type XcmSender = MockXcmSender; type WeightInfo = (); type GatewayAddress = GatewayAddress; - type MessageConverter = MessageToXcm< - CreateAssetCall, - CreateAssetDeposit, - InboundQueuePalletInstance, - AccountId, - Balance, - >; + type MessageConverter = + MessageToXcm; type PricingParameters = Parameters; type ChannelLookup = MockChannelLookup; #[cfg(feature = "runtime-benchmarks")] diff --git a/parachain/primitives/router/src/inbound/mod.rs b/parachain/primitives/router/src/inbound/mod.rs index a07e0eae5d..e6a765cd19 100644 --- a/parachain/primitives/router/src/inbound/mod.rs +++ b/parachain/primitives/router/src/inbound/mod.rs @@ -16,7 +16,8 @@ use sp_std::prelude::*; use xcm::prelude::{Junction::AccountKey20, *}; use xcm_executor::traits::ConvertLocation; -const MINIMUM_DEPOSIT: u128 = 1; +pub const MINIMUM_DEPOSIT: u128 = 1; +pub const FOREIGN_CREATE_ASSET_WEIGHT_AT_MOST: Weight = Weight::from_parts(400_000_000, 8_000); /// Messages from Ethereum are versioned. This is because in future, /// we may want to evolve the protocol so that the ethereum side sends XCM messages directly. @@ -83,24 +84,12 @@ pub enum Destination { }, } -pub struct MessageToXcm< - CreateAssetCall, - CreateAssetDeposit, - InboundQueuePalletInstance, - AccountId, - Balance, -> where - CreateAssetCall: Get, +pub struct MessageToXcm +where CreateAssetDeposit: Get, Balance: BalanceT, { - _phantom: PhantomData<( - CreateAssetCall, - CreateAssetDeposit, - InboundQueuePalletInstance, - AccountId, - Balance, - )>, + _phantom: PhantomData<(CreateAssetDeposit, InboundQueuePalletInstance, AccountId, Balance)>, } /// Reason why a message conversion failed. @@ -118,18 +107,9 @@ pub trait ConvertMessage { fn convert(message: VersionedMessage) -> Result<(Xcm<()>, Self::Balance), ConvertMessageError>; } -pub type CallIndex = [u8; 2]; - -impl - ConvertMessage - for MessageToXcm< - CreateAssetCall, - CreateAssetDeposit, - InboundQueuePalletInstance, - AccountId, - Balance, - > where - CreateAssetCall: Get, +impl ConvertMessage + for MessageToXcm +where CreateAssetDeposit: Get, InboundQueuePalletInstance: Get, Balance: BalanceT + From, @@ -150,10 +130,9 @@ impl - MessageToXcm +impl + MessageToXcm where - CreateAssetCall: Get, CreateAssetDeposit: Get, InboundQueuePalletInstance: Get, Balance: BalanceT + From, @@ -171,7 +150,6 @@ where let owner = GlobalConsensusEthereumConvertsFor::<[u8; 32]>::from_chain_id(&chain_id); let asset_id = Self::convert_token_address(network, token); - let create_call_index: [u8; 2] = CreateAssetCall::get(); let inbound_queue_pallet_index = InboundQueuePalletInstance::get(); let xcm: Xcm<()> = vec![ @@ -188,15 +166,14 @@ where // Call create_asset on foreign assets pallet. Transact { origin_kind: OriginKind::Xcm, - require_weight_at_most: Weight::from_parts(400_000_000, 8_000), - call: ( - create_call_index, - asset_id, - MultiAddress::<[u8; 32], ()>::Id(owner), - MINIMUM_DEPOSIT, - ) - .encode() - .into(), + require_weight_at_most: FOREIGN_CREATE_ASSET_WEIGHT_AT_MOST, + call: Call::ForeignAssets(ForeignAssetsCall::create { + id: asset_id, + admin: MultiAddress::<[u8; 32], ()>::Id(owner), + min_balance: MINIMUM_DEPOSIT, + }) + .encode() + .into(), }, RefundSurplus, // Clear the origin so that remaining assets in holding @@ -318,3 +295,19 @@ impl GlobalConsensusEthereumConvertsFor { (b"ethereum-chain", chain_id).using_encoded(blake2_256) } } + +#[allow(clippy::large_enum_variant)] +#[derive(Encode, Decode, Debug, PartialEq, Eq, Clone, TypeInfo)] +pub enum Call { + /// Call create_asset on foreign assets pallet. + #[codec(index = 53)] + ForeignAssets(ForeignAssetsCall), +} + +#[derive(Encode, Decode, Debug, PartialEq, Eq, Clone, TypeInfo)] +#[allow(non_camel_case_types)] +pub enum ForeignAssetsCall { + /// `pallet-assets::Call::create` + #[codec(index = 0)] + create { id: MultiLocation, admin: MultiAddress<[u8; 32], ()>, min_balance: u128 }, +} diff --git a/parachain/primitives/router/src/inbound/tests.rs b/parachain/primitives/router/src/inbound/tests.rs index 8c96c13cf2..9f793af5c5 100644 --- a/parachain/primitives/router/src/inbound/tests.rs +++ b/parachain/primitives/router/src/inbound/tests.rs @@ -1,5 +1,4 @@ use super::GlobalConsensusEthereumConvertsFor; -use crate::inbound::CallIndex; use frame_support::parameter_types; use hex_literal::hex; use xcm::v3::prelude::*; @@ -10,7 +9,6 @@ const NETWORK: NetworkId = Ethereum { chain_id: 11155111 }; parameter_types! { pub EthereumNetwork: NetworkId = NETWORK; - pub const CreateAssetCall: CallIndex = [1, 1]; pub const CreateAssetExecutionFee: u128 = 123; pub const CreateAssetDeposit: u128 = 891; pub const SendTokenExecutionFee: u128 = 592; diff --git a/polkadot-sdk b/polkadot-sdk index c23c50f2cb..40310a38cd 160000 --- a/polkadot-sdk +++ b/polkadot-sdk @@ -1 +1 @@ -Subproject commit c23c50f2cb4697885e1dd891da6fdd33036631a8 +Subproject commit 40310a38cdb1e56ae72d8798e7e8ad28c1494bdb From d085897d00bfafcd7682d646a69f8ba7949a0352 Mon Sep 17 00:00:00 2001 From: ron Date: Wed, 17 Jan 2024 18:21:32 +0800 Subject: [PATCH 2/3] Move call index back to runtime --- parachain/pallets/inbound-queue/src/mock.rs | 10 ++- .../primitives/router/src/inbound/mod.rs | 69 ++++++++++--------- polkadot-sdk | 2 +- 3 files changed, 47 insertions(+), 34 deletions(-) diff --git a/parachain/pallets/inbound-queue/src/mock.rs b/parachain/pallets/inbound-queue/src/mock.rs index 077c50f677..b031a46e21 100644 --- a/parachain/pallets/inbound-queue/src/mock.rs +++ b/parachain/pallets/inbound-queue/src/mock.rs @@ -134,6 +134,7 @@ const GATEWAY_ADDRESS: [u8; 20] = hex!["eda338e4dc46038493b885327842fd3e301cab39 parameter_types! { pub const EthereumNetwork: xcm::v3::NetworkId = xcm::v3::NetworkId::Ethereum { chain_id: 11155111 }; pub const GatewayAddress: H160 = H160(GATEWAY_ADDRESS); + pub const CreateAssetCall: [u8;2] = [53, 0]; pub const CreateAssetExecutionFee: u128 = 2_000_000_000; pub const CreateAssetDeposit: u128 = 100_000_000_000; pub const SendTokenExecutionFee: u128 = 1_000_000_000; @@ -251,8 +252,13 @@ impl inbound_queue::Config for Test { type XcmSender = MockXcmSender; type WeightInfo = (); type GatewayAddress = GatewayAddress; - type MessageConverter = - MessageToXcm; + type MessageConverter = MessageToXcm< + CreateAssetCall, + CreateAssetDeposit, + InboundQueuePalletInstance, + AccountId, + Balance, + >; type PricingParameters = Parameters; type ChannelLookup = MockChannelLookup; #[cfg(feature = "runtime-benchmarks")] diff --git a/parachain/primitives/router/src/inbound/mod.rs b/parachain/primitives/router/src/inbound/mod.rs index e6a765cd19..c40fca9459 100644 --- a/parachain/primitives/router/src/inbound/mod.rs +++ b/parachain/primitives/router/src/inbound/mod.rs @@ -18,6 +18,7 @@ use xcm_executor::traits::ConvertLocation; pub const MINIMUM_DEPOSIT: u128 = 1; pub const FOREIGN_CREATE_ASSET_WEIGHT_AT_MOST: Weight = Weight::from_parts(400_000_000, 8_000); +pub type CallIndex = [u8; 2]; /// Messages from Ethereum are versioned. This is because in future, /// we may want to evolve the protocol so that the ethereum side sends XCM messages directly. @@ -84,12 +85,24 @@ pub enum Destination { }, } -pub struct MessageToXcm -where +pub struct MessageToXcm< + CreateAssetCall, + CreateAssetDeposit, + InboundQueuePalletInstance, + AccountId, + Balance, +> where + CreateAssetCall: Get, CreateAssetDeposit: Get, Balance: BalanceT, { - _phantom: PhantomData<(CreateAssetDeposit, InboundQueuePalletInstance, AccountId, Balance)>, + _phantom: PhantomData<( + CreateAssetCall, + CreateAssetDeposit, + InboundQueuePalletInstance, + AccountId, + Balance, + )>, } /// Reason why a message conversion failed. @@ -107,9 +120,16 @@ pub trait ConvertMessage { fn convert(message: VersionedMessage) -> Result<(Xcm<()>, Self::Balance), ConvertMessageError>; } -impl ConvertMessage - for MessageToXcm -where +impl + ConvertMessage + for MessageToXcm< + CreateAssetCall, + CreateAssetDeposit, + InboundQueuePalletInstance, + AccountId, + Balance, + > where + CreateAssetCall: Get, CreateAssetDeposit: Get, InboundQueuePalletInstance: Get, Balance: BalanceT + From, @@ -130,9 +150,10 @@ where } } -impl - MessageToXcm +impl + MessageToXcm where + CreateAssetCall: Get, CreateAssetDeposit: Get, InboundQueuePalletInstance: Get, Balance: BalanceT + From, @@ -150,6 +171,7 @@ where let owner = GlobalConsensusEthereumConvertsFor::<[u8; 32]>::from_chain_id(&chain_id); let asset_id = Self::convert_token_address(network, token); + let create_call_index: [u8; 2] = CreateAssetCall::get(); let inbound_queue_pallet_index = InboundQueuePalletInstance::get(); let xcm: Xcm<()> = vec![ @@ -167,13 +189,14 @@ where Transact { origin_kind: OriginKind::Xcm, require_weight_at_most: FOREIGN_CREATE_ASSET_WEIGHT_AT_MOST, - call: Call::ForeignAssets(ForeignAssetsCall::create { - id: asset_id, - admin: MultiAddress::<[u8; 32], ()>::Id(owner), - min_balance: MINIMUM_DEPOSIT, - }) - .encode() - .into(), + call: ( + create_call_index, + asset_id, + MultiAddress::<[u8; 32], ()>::Id(owner), + MINIMUM_DEPOSIT, + ) + .encode() + .into(), }, RefundSurplus, // Clear the origin so that remaining assets in holding @@ -295,19 +318,3 @@ impl GlobalConsensusEthereumConvertsFor { (b"ethereum-chain", chain_id).using_encoded(blake2_256) } } - -#[allow(clippy::large_enum_variant)] -#[derive(Encode, Decode, Debug, PartialEq, Eq, Clone, TypeInfo)] -pub enum Call { - /// Call create_asset on foreign assets pallet. - #[codec(index = 53)] - ForeignAssets(ForeignAssetsCall), -} - -#[derive(Encode, Decode, Debug, PartialEq, Eq, Clone, TypeInfo)] -#[allow(non_camel_case_types)] -pub enum ForeignAssetsCall { - /// `pallet-assets::Call::create` - #[codec(index = 0)] - create { id: MultiLocation, admin: MultiAddress<[u8; 32], ()>, min_balance: u128 }, -} diff --git a/polkadot-sdk b/polkadot-sdk index b4f34d7d55..d8787fb36c 160000 --- a/polkadot-sdk +++ b/polkadot-sdk @@ -1 +1 @@ -Subproject commit b4f34d7d55f295ce1848c9b599d283a27855a482 +Subproject commit d8787fb36c592b88eed002b67be7986f7cef2029 From 37aa97eedcd0c3a13be72d78603a338ed1f332d0 Mon Sep 17 00:00:00 2001 From: ron Date: Wed, 17 Jan 2024 19:58:55 +0800 Subject: [PATCH 3/3] Refactoring with CallInfo data structure --- parachain/Cargo.lock | 1 + parachain/pallets/inbound-queue/src/mock.rs | 21 +++--- .../primitives/router/src/inbound/mod.rs | 70 +++++++++---------- polkadot-sdk | 2 +- 4 files changed, 43 insertions(+), 51 deletions(-) diff --git a/parachain/Cargo.lock b/parachain/Cargo.lock index 4720ee8148..9beaae3edc 100644 --- a/parachain/Cargo.lock +++ b/parachain/Cargo.lock @@ -6190,6 +6190,7 @@ dependencies = [ "rococo-runtime-constants", "scale-info", "smallvec", + "snowbridge-router-primitives", "sp-consensus-aura", "sp-core", "sp-io", diff --git a/parachain/pallets/inbound-queue/src/mock.rs b/parachain/pallets/inbound-queue/src/mock.rs index b031a46e21..f264e68ddc 100644 --- a/parachain/pallets/inbound-queue/src/mock.rs +++ b/parachain/pallets/inbound-queue/src/mock.rs @@ -14,7 +14,7 @@ use snowbridge_core::{ inbound::{Log, Proof, VerificationError}, meth, Channel, ChannelId, PricingParameters, Rewards, StaticLookup, }; -use snowbridge_router_primitives::inbound::MessageToXcm; +use snowbridge_router_primitives::inbound::{CreateAssetCallInfo, MessageToXcm}; use sp_core::{H160, H256}; use sp_runtime::{ traits::{BlakeTwo256, IdentifyAccount, IdentityLookup, Verify}, @@ -134,10 +134,12 @@ const GATEWAY_ADDRESS: [u8; 20] = hex!["eda338e4dc46038493b885327842fd3e301cab39 parameter_types! { pub const EthereumNetwork: xcm::v3::NetworkId = xcm::v3::NetworkId::Ethereum { chain_id: 11155111 }; pub const GatewayAddress: H160 = H160(GATEWAY_ADDRESS); - pub const CreateAssetCall: [u8;2] = [53, 0]; - pub const CreateAssetExecutionFee: u128 = 2_000_000_000; - pub const CreateAssetDeposit: u128 = 100_000_000_000; - pub const SendTokenExecutionFee: u128 = 1_000_000_000; + pub const CreateAssetCall: CreateAssetCallInfo = CreateAssetCallInfo { + call_index: [53,0], + asset_deposit: 100_000_000_000, + min_balance: 1, + transact_weight_at_most:Weight::from_parts(400_000_000, 8_000) + }; pub const InitialFund: u128 = 1_000_000_000_000; pub const InboundQueuePalletInstance: u8 = 80; } @@ -252,13 +254,8 @@ impl inbound_queue::Config for Test { type XcmSender = MockXcmSender; type WeightInfo = (); type GatewayAddress = GatewayAddress; - type MessageConverter = MessageToXcm< - CreateAssetCall, - CreateAssetDeposit, - InboundQueuePalletInstance, - AccountId, - Balance, - >; + type MessageConverter = + MessageToXcm; type PricingParameters = Parameters; type ChannelLookup = MockChannelLookup; #[cfg(feature = "runtime-benchmarks")] diff --git a/parachain/primitives/router/src/inbound/mod.rs b/parachain/primitives/router/src/inbound/mod.rs index c40fca9459..0552637c52 100644 --- a/parachain/primitives/router/src/inbound/mod.rs +++ b/parachain/primitives/router/src/inbound/mod.rs @@ -16,8 +16,6 @@ use sp_std::prelude::*; use xcm::prelude::{Junction::AccountKey20, *}; use xcm_executor::traits::ConvertLocation; -pub const MINIMUM_DEPOSIT: u128 = 1; -pub const FOREIGN_CREATE_ASSET_WEIGHT_AT_MOST: Weight = Weight::from_parts(400_000_000, 8_000); pub type CallIndex = [u8; 2]; /// Messages from Ethereum are versioned. This is because in future, @@ -85,24 +83,27 @@ pub enum Destination { }, } -pub struct MessageToXcm< - CreateAssetCall, - CreateAssetDeposit, - InboundQueuePalletInstance, - AccountId, - Balance, -> where - CreateAssetCall: Get, - CreateAssetDeposit: Get, +/// CallInfo required to create the foreign asset +#[derive(Clone, Encode, Decode, RuntimeDebug)] +pub struct CreateAssetCallInfo { + /// Index of the create call + pub call_index: CallIndex, + /// Deposit required to create the asset + pub asset_deposit: u128, + /// Minimal balance of the asset + pub min_balance: u128, + /// Weight required for the xcm transact + pub transact_weight_at_most: Weight, +} + +pub struct MessageToXcm +where + CreateAssetCall: Get, + InboundQueuePalletInstance: Get, + AccountId: Into<[u8; 32]>, Balance: BalanceT, { - _phantom: PhantomData<( - CreateAssetCall, - CreateAssetDeposit, - InboundQueuePalletInstance, - AccountId, - Balance, - )>, + _phantom: PhantomData<(CreateAssetCall, InboundQueuePalletInstance, AccountId, Balance)>, } /// Reason why a message conversion failed. @@ -120,17 +121,10 @@ pub trait ConvertMessage { fn convert(message: VersionedMessage) -> Result<(Xcm<()>, Self::Balance), ConvertMessageError>; } -impl - ConvertMessage - for MessageToXcm< - CreateAssetCall, - CreateAssetDeposit, - InboundQueuePalletInstance, - AccountId, - Balance, - > where - CreateAssetCall: Get, - CreateAssetDeposit: Get, +impl ConvertMessage + for MessageToXcm +where + CreateAssetCall: Get, InboundQueuePalletInstance: Get, Balance: BalanceT + From, AccountId: Into<[u8; 32]>, @@ -150,11 +144,10 @@ impl - MessageToXcm +impl + MessageToXcm where - CreateAssetCall: Get, - CreateAssetDeposit: Get, + CreateAssetCall: Get, InboundQueuePalletInstance: Get, Balance: BalanceT + From, AccountId: Into<[u8; 32]>, @@ -162,16 +155,17 @@ where fn convert_register_token(chain_id: u64, token: H160, fee: u128) -> (Xcm<()>, Balance) { let network = Ethereum { chain_id }; let xcm_fee: MultiAsset = (MultiLocation::parent(), fee).into(); - let deposit: MultiAsset = (MultiLocation::parent(), CreateAssetDeposit::get()).into(); + let call_info = CreateAssetCall::get(); + let deposit: MultiAsset = (MultiLocation::parent(), call_info.asset_deposit).into(); - let total_amount = fee + CreateAssetDeposit::get(); + let total_amount = fee + call_info.asset_deposit; let total: MultiAsset = (MultiLocation::parent(), total_amount).into(); let bridge_location: MultiLocation = (Parent, Parent, GlobalConsensus(network)).into(); let owner = GlobalConsensusEthereumConvertsFor::<[u8; 32]>::from_chain_id(&chain_id); let asset_id = Self::convert_token_address(network, token); - let create_call_index: [u8; 2] = CreateAssetCall::get(); + let create_call_index = call_info.call_index; let inbound_queue_pallet_index = InboundQueuePalletInstance::get(); let xcm: Xcm<()> = vec![ @@ -188,12 +182,12 @@ where // Call create_asset on foreign assets pallet. Transact { origin_kind: OriginKind::Xcm, - require_weight_at_most: FOREIGN_CREATE_ASSET_WEIGHT_AT_MOST, + require_weight_at_most: call_info.transact_weight_at_most, call: ( create_call_index, asset_id, MultiAddress::<[u8; 32], ()>::Id(owner), - MINIMUM_DEPOSIT, + call_info.min_balance, ) .encode() .into(), diff --git a/polkadot-sdk b/polkadot-sdk index d8787fb36c..7a58ab4d79 160000 --- a/polkadot-sdk +++ b/polkadot-sdk @@ -1 +1 @@ -Subproject commit d8787fb36c592b88eed002b67be7986f7cef2029 +Subproject commit 7a58ab4d79439f61ae581b1a3da142c3ef68cdb1