From 25ed2d9e85dd3c6c5dc6f45e40db3b25ae5562dd Mon Sep 17 00:00:00 2001 From: Alistair Singh Date: Thu, 16 Nov 2023 10:30:04 +0200 Subject: [PATCH 01/10] add foreign assets pallet --- Cargo.lock | 1 + .../runtimes/testing/penpal/Cargo.toml | 3 ++ .../runtimes/testing/penpal/src/lib.rs | 51 ++++++++++++++++++- .../runtimes/testing/penpal/src/xcm_config.rs | 7 +++ 4 files changed, 61 insertions(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index 15a75f7279f9..a9933002285e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -11924,6 +11924,7 @@ dependencies = [ name = "penpal-runtime" version = "0.9.27" dependencies = [ + "assets-common", "cumulus-pallet-aura-ext", "cumulus-pallet-dmp-queue", "cumulus-pallet-parachain-system", diff --git a/cumulus/parachains/runtimes/testing/penpal/Cargo.toml b/cumulus/parachains/runtimes/testing/penpal/Cargo.toml index fb66275b025a..4152c092aef9 100644 --- a/cumulus/parachains/runtimes/testing/penpal/Cargo.toml +++ b/cumulus/parachains/runtimes/testing/penpal/Cargo.toml @@ -75,10 +75,12 @@ cumulus-primitives-utility = { path = "../../../../primitives/utility", default- pallet-collator-selection = { path = "../../../../pallets/collator-selection", default-features = false } parachain-info = { package = "staging-parachain-info", path = "../../../pallets/parachain-info", default-features = false } parachains-common = { path = "../../../common", default-features = false } +assets-common = { path = "../../assets/common", default-features = false } [features] default = [ "std" ] std = [ + "assets-common/std", "codec/std", "cumulus-pallet-aura-ext/std", "cumulus-pallet-dmp-queue/std", @@ -135,6 +137,7 @@ std = [ ] runtime-benchmarks = [ + "assets-common/runtime-benchmarks", "cumulus-pallet-dmp-queue/runtime-benchmarks", "cumulus-pallet-parachain-system/runtime-benchmarks", "cumulus-pallet-session-benchmarking/runtime-benchmarks", diff --git a/cumulus/parachains/runtimes/testing/penpal/src/lib.rs b/cumulus/parachains/runtimes/testing/penpal/src/lib.rs index 1ddad31920a5..e4698ccaa129 100644 --- a/cumulus/parachains/runtimes/testing/penpal/src/lib.rs +++ b/cumulus/parachains/runtimes/testing/penpal/src/lib.rs @@ -32,6 +32,11 @@ include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs")); mod weights; pub mod xcm_config; +use assets_common::{ + foreign_creators::ForeignCreators, + matching::FromSiblingParachain, + MultiLocationForAssetId, +}; use cumulus_pallet_parachain_system::RelayNumberStrictlyIncreases; use cumulus_primitives_core::{AggregateMessageOrigin, ParaId}; use frame_support::{ @@ -70,7 +75,7 @@ use sp_std::prelude::*; #[cfg(feature = "std")] use sp_version::NativeVersion; use sp_version::RuntimeVersion; -use xcm_config::{AssetsToBlockAuthor, XcmOriginToTransactDispatchOrigin}; +use xcm_config::{AssetsToBlockAuthor, ForeignCreatorsSovereignAccountOf, XcmOriginToTransactDispatchOrigin}; #[cfg(any(feature = "std", test))] pub use sp_runtime::BuildStorage; @@ -457,6 +462,49 @@ impl pallet_assets::Config for Runtime { type BenchmarkHelper = (); } + +parameter_types! { + // we just reuse the same deposits + pub const ForeignAssetsAssetDeposit: Balance = AssetDeposit::get(); + pub const ForeignAssetsAssetAccountDeposit: Balance = AssetAccountDeposit::get(); + pub const ForeignAssetsApprovalDeposit: Balance = ApprovalDeposit::get(); + pub const ForeignAssetsAssetsStringLimit: u32 = AssetsStringLimit::get(); + pub const ForeignAssetsMetadataDepositBase: Balance = MetadataDepositBase::get(); + pub const ForeignAssetsMetadataDepositPerByte: Balance = MetadataDepositPerByte::get(); +} + +/// We allow root to execute privileged asset operations. +pub type AssetsForceOrigin = EnsureRoot; + +/// Another pallet assets instance to store foreign assets from bridgehub. +pub type ForeignAssetsInstance = pallet_assets::Instance2; +impl pallet_assets::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type Balance = Balance; + type AssetId = MultiLocationForAssetId; + type AssetIdParameter = MultiLocationForAssetId; + type Currency = Balances; + type CreateOrigin = ForeignCreators< + (FromSiblingParachain>,), + ForeignCreatorsSovereignAccountOf, + AccountId, + >; + type ForceOrigin = AssetsForceOrigin; + type AssetDeposit = ForeignAssetsAssetDeposit; + type MetadataDepositBase = ForeignAssetsMetadataDepositBase; + type MetadataDepositPerByte = ForeignAssetsMetadataDepositPerByte; + type ApprovalDeposit = ForeignAssetsApprovalDeposit; + type StringLimit = ForeignAssetsAssetsStringLimit; + type Freezer = (); + type Extra = (); + type WeightInfo = pallet_assets::weights::SubstrateWeight; + type CallbackHandle = (); + type AssetAccountDeposit = ForeignAssetsAssetAccountDeposit; + type RemoveItemsLimit = frame_support::traits::ConstU32<1000>; + #[cfg(feature = "runtime-benchmarks")] + type BenchmarkHelper = xcm_config::XcmBenchmarkHelper; +} + parameter_types! { pub const ReservedXcmpWeight: Weight = MAXIMUM_BLOCK_WEIGHT.saturating_div(4); pub const ReservedDmpWeight: Weight = MAXIMUM_BLOCK_WEIGHT.saturating_div(4); @@ -625,6 +673,7 @@ construct_runtime!( // The main stage. Assets: pallet_assets::::{Pallet, Call, Storage, Event} = 50, + ForeignAssets: pallet_assets::::{Pallet, Call, Storage, Event} = 51, Sudo: pallet_sudo::{Pallet, Call, Storage, Event, Config} = 255, } diff --git a/cumulus/parachains/runtimes/testing/penpal/src/xcm_config.rs b/cumulus/parachains/runtimes/testing/penpal/src/xcm_config.rs index 74d9a0b071d8..3ef755079bdd 100644 --- a/cumulus/parachains/runtimes/testing/penpal/src/xcm_config.rs +++ b/cumulus/parachains/runtimes/testing/penpal/src/xcm_config.rs @@ -293,6 +293,13 @@ pub type XcmRouter = WithUniqueTopic<( XcmpQueue, )>; +// TODO(alistair): Only assethub should be able to create. +pub type ForeignCreatorsSovereignAccountOf = ( + SiblingParachainConvertsVia, + AccountId32Aliases, + ParentIsPreset, +); + impl pallet_xcm::Config for Runtime { type RuntimeEvent = RuntimeEvent; type SendXcmOrigin = EnsureXcmOrigin; From 668da4cbe80436a45c1b4f048d3ef8377fdfc7c6 Mon Sep 17 00:00:00 2001 From: Alistair Singh Date: Thu, 16 Nov 2023 20:04:57 +0200 Subject: [PATCH 02/10] test compiles and fails --- Cargo.lock | 2 + .../parachains/testing/penpal/src/lib.rs | 2 + .../networks/rococo-wococo-system/Cargo.toml | 1 + .../networks/rococo-wococo-system/src/lib.rs | 3 + .../bridges/bridge-hub-rococo/Cargo.toml | 1 + .../bridges/bridge-hub-rococo/src/lib.rs | 2 +- .../bridge-hub-rococo/src/tests/snowbridge.rs | 100 +++++++++++++++--- 7 files changed, 94 insertions(+), 17 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a9933002285e..e54c42da2a42 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2403,6 +2403,7 @@ dependencies = [ "pallet-xcm", "parachains-common", "parity-scale-codec", + "penpal-emulated-chain", "rococo-wococo-system-emulated-network", "scale-info", "snowbridge-control", @@ -14903,6 +14904,7 @@ dependencies = [ "bridge-hub-rococo-emulated-chain", "bridge-hub-wococo-emulated-chain", "emulated-integration-tests-common", + "penpal-emulated-chain", "rococo-emulated-chain", "wococo-emulated-chain", ] diff --git a/cumulus/parachains/integration-tests/emulated/chains/parachains/testing/penpal/src/lib.rs b/cumulus/parachains/integration-tests/emulated/chains/parachains/testing/penpal/src/lib.rs index 537f96f45b47..ec23257eae53 100644 --- a/cumulus/parachains/integration-tests/emulated/chains/parachains/testing/penpal/src/lib.rs +++ b/cumulus/parachains/integration-tests/emulated/chains/parachains/testing/penpal/src/lib.rs @@ -42,6 +42,7 @@ decl_test_parachains! { pallets = { PolkadotXcm: penpal_runtime::PolkadotXcm, Assets: penpal_runtime::Assets, + ForeignAssets: penpal_runtime::ForeignAssets, Balances: penpal_runtime::Balances, } }, @@ -59,6 +60,7 @@ decl_test_parachains! { pallets = { PolkadotXcm: penpal_runtime::PolkadotXcm, Assets: penpal_runtime::Assets, + ForeignAssets: penpal_runtime::ForeignAssets, Balances: penpal_runtime::Balances, } }, diff --git a/cumulus/parachains/integration-tests/emulated/networks/rococo-wococo-system/Cargo.toml b/cumulus/parachains/integration-tests/emulated/networks/rococo-wococo-system/Cargo.toml index 53a6f0840a5b..8e10c89ea24d 100644 --- a/cumulus/parachains/integration-tests/emulated/networks/rococo-wococo-system/Cargo.toml +++ b/cumulus/parachains/integration-tests/emulated/networks/rococo-wococo-system/Cargo.toml @@ -16,3 +16,4 @@ asset-hub-rococo-emulated-chain = { path = "../../chains/parachains/assets/asset asset-hub-wococo-emulated-chain = { path = "../../chains/parachains/assets/asset-hub-wococo" } bridge-hub-rococo-emulated-chain = { path = "../../chains/parachains/bridges/bridge-hub-rococo" } bridge-hub-wococo-emulated-chain = { path = "../../chains/parachains/bridges/bridge-hub-wococo" } +penpal-emulated-chain = { path = "../../chains/parachains/testing/penpal" } diff --git a/cumulus/parachains/integration-tests/emulated/networks/rococo-wococo-system/src/lib.rs b/cumulus/parachains/integration-tests/emulated/networks/rococo-wococo-system/src/lib.rs index e20dcfa6b32c..f5ddd82576f2 100644 --- a/cumulus/parachains/integration-tests/emulated/networks/rococo-wococo-system/src/lib.rs +++ b/cumulus/parachains/integration-tests/emulated/networks/rococo-wococo-system/src/lib.rs @@ -17,6 +17,7 @@ pub use asset_hub_rococo_emulated_chain; pub use asset_hub_wococo_emulated_chain; pub use bridge_hub_rococo_emulated_chain; pub use bridge_hub_wococo_emulated_chain; +pub use penpal_emulated_chain; pub use rococo_emulated_chain; pub use wococo_emulated_chain; @@ -24,6 +25,7 @@ use asset_hub_rococo_emulated_chain::AssetHubRococo; use asset_hub_wococo_emulated_chain::AssetHubWococo; use bridge_hub_rococo_emulated_chain::BridgeHubRococo; use bridge_hub_wococo_emulated_chain::BridgeHubWococo; +use penpal_emulated_chain::PenpalA; use rococo_emulated_chain::Rococo; use wococo_emulated_chain::Wococo; @@ -43,6 +45,7 @@ decl_test_networks! { parachains = vec![ AssetHubRococo, BridgeHubRococo, + PenpalA, ], bridge = RococoWococoMockBridge diff --git a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/Cargo.toml b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/Cargo.toml index aad2807edde5..4d6a9b67cf65 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/Cargo.toml +++ b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/Cargo.toml @@ -39,6 +39,7 @@ emulated-integration-tests-common = { path = "../../../common", default-features rococo-wococo-system-emulated-network = { path = "../../../networks/rococo-wococo-system" } bridge-hub-rococo-emulated-chain = { path = "../../../chains/parachains/bridges/bridge-hub-rococo"} asset-hub-rococo-emulated-chain = { path = "../../../chains/parachains/assets/asset-hub-rococo"} +penpal-emulated-chain = { path = "../../../chains/parachains/testing/penpal" } # Snowbridge snowbridge-core = { path = "../../../../../../../../parachain/primitives/core", default-features = false } diff --git a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/lib.rs b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/lib.rs index 19e10d23bbba..a3353282e7df 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/lib.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/lib.rs @@ -48,7 +48,7 @@ pub use rococo_wococo_system_emulated_network::{ AssetHubRococoParaSender as AssetHubRococoSender, AssetHubWococoPara as AssetHubWococo, BridgeHubRococoPara as BridgeHubRococo, BridgeHubRococoParaReceiver as BridgeHubRococoReceiver, BridgeHubRococoParaSender as BridgeHubRococoSender, BridgeHubWococoPara as BridgeHubWococo, - RococoRelay as Rococo, RococoRelayReceiver as RococoReceiver, + PenpalAPara as PenpalARococo, RococoRelay as Rococo, RococoRelayReceiver as RococoReceiver, RococoRelaySender as RococoSender, }; diff --git a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/tests/snowbridge.rs b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/tests/snowbridge.rs index 2ede961bf3c1..99de9a3e086c 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/tests/snowbridge.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/tests/snowbridge.rs @@ -25,12 +25,10 @@ use sp_core::H256; const INITIAL_FUND: u128 = 5_000_000_000 * ROCOCO_ED; const CHAIN_ID: u64 = 15; -const DEST_PARA_ID: u32 = 1000; +const ASSETHUB_PARA_ID: u32 = 1000; const TREASURY_ACCOUNT: [u8; 32] = hex!("6d6f646c70792f74727372790000000000000000000000000000000000000000"); const WETH: [u8; 20] = hex!("87d1f7fdfEe7f651FaBc8bFCB6E086C278b77A7d"); -const ASSETHUB_SOVEREIGN: [u8; 32] = - hex!("7369626ce8030000000000000000000000000000000000000000000000000000"); const ETHEREUM_DESTINATION_ADDRESS: [u8; 20] = hex!("44a57ee2f2FCcb85FDa2B0B18EBD0D8D2333700e"); #[test] @@ -188,7 +186,7 @@ fn register_token() { BridgeHubRococo::fund_accounts(vec![( BridgeHubRococo::sovereign_account_id_of(MultiLocation { parents: 1, - interior: X1(Parachain(DEST_PARA_ID)), + interior: X1(Parachain(ASSETHUB_PARA_ID)), }), INITIAL_FUND, )]); @@ -204,7 +202,7 @@ fn register_token() { command: Command::RegisterToken { token: WETH.into() }, }); let (xcm, _) = EthereumInboundQueue::do_convert(message_id_, message).unwrap(); - let _ = EthereumInboundQueue::send_xcm(xcm, DEST_PARA_ID.into()).unwrap(); + let _ = EthereumInboundQueue::send_xcm(xcm, ASSETHUB_PARA_ID.into()).unwrap(); assert_expected_events!( BridgeHubRococo, @@ -227,18 +225,17 @@ fn register_token() { } #[test] -fn send_token() { +fn send_token_to_penpal() { BridgeHubRococo::fund_accounts(vec![( BridgeHubRococo::sovereign_account_id_of(MultiLocation { parents: 1, - interior: X1(Parachain(DEST_PARA_ID)), + interior: X1(Parachain(ASSETHUB_PARA_ID)), }), INITIAL_FUND, )]); // Fund ethereum sovereign in asset hub AssetHubRococo::fund_accounts(vec![ - (ASSETHUB_SOVEREIGN.into(), INITIAL_FUND), (AssetHubRococoReceiver::get(), INITIAL_FUND), ]); @@ -253,7 +250,7 @@ fn send_token() { command: Command::RegisterToken { token: WETH.into() }, }); let (xcm, _) = EthereumInboundQueue::do_convert(message_id_, message).unwrap(); - let _ = EthereumInboundQueue::send_xcm(xcm, DEST_PARA_ID.into()).unwrap(); + let _ = EthereumInboundQueue::send_xcm(xcm, ASSETHUB_PARA_ID.into()).unwrap(); let message = VersionedMessage::V1(MessageV1 { chain_id: CHAIN_ID, command: Command::SendToken { @@ -263,7 +260,7 @@ fn send_token() { }, }); let (xcm, _) = EthereumInboundQueue::do_convert(message_id_, message).unwrap(); - let _ = EthereumInboundQueue::send_xcm(xcm, DEST_PARA_ID.into()).unwrap(); + let _ = EthereumInboundQueue::send_xcm(xcm, ASSETHUB_PARA_ID.into()).unwrap(); assert_expected_events!( BridgeHubRococo, @@ -278,6 +275,18 @@ fn send_token() { assert_expected_events!( AssetHubRococo, + vec![ + RuntimeEvent::ForeignAssets(pallet_assets::Event::Issued { .. }) => {}, + RuntimeEvent::XcmpQueue(cumulus_pallet_xcmp_queue::Event::XcmpMessageSent { .. }) => {}, + ] + ); + }); + + PenpalARococo::execute_with(|| { + type RuntimeEvent = ::RuntimeEvent; + + assert_expected_events!( + PenpalARococo, vec![ RuntimeEvent::ForeignAssets(pallet_assets::Event::Issued { .. }) => {}, ] @@ -286,18 +295,77 @@ fn send_token() { } #[test] -fn reserve_transfer_token() { +fn send_token() { BridgeHubRococo::fund_accounts(vec![( BridgeHubRococo::sovereign_account_id_of(MultiLocation { parents: 1, - interior: X1(Parachain(DEST_PARA_ID)), + interior: X1(Parachain(ASSETHUB_PARA_ID)), }), INITIAL_FUND, )]); // Fund ethereum sovereign in asset hub AssetHubRococo::fund_accounts(vec![ - (ASSETHUB_SOVEREIGN.into(), INITIAL_FUND), + (AssetHubRococoReceiver::get(), INITIAL_FUND), + ]); + + let message_id_: H256 = [1; 32].into(); + + BridgeHubRococo::execute_with(|| { + type RuntimeEvent = ::RuntimeEvent; + type EthereumInboundQueue = + ::EthereumInboundQueue; + let message = VersionedMessage::V1(MessageV1 { + chain_id: CHAIN_ID, + command: Command::RegisterToken { token: WETH.into() }, + }); + let (xcm, _) = EthereumInboundQueue::do_convert(message_id_, message).unwrap(); + let _ = EthereumInboundQueue::send_xcm(xcm, ASSETHUB_PARA_ID.into()).unwrap(); + let message = VersionedMessage::V1(MessageV1 { + chain_id: CHAIN_ID, + command: Command::SendToken { + token: WETH.into(), + destination: Destination::AccountId32 { id: AssetHubRococoReceiver::get().into() }, + amount: 1_000_000_000, + }, + }); + let (xcm, _) = EthereumInboundQueue::do_convert(message_id_, message).unwrap(); + let _ = EthereumInboundQueue::send_xcm(xcm, ASSETHUB_PARA_ID.into()).unwrap(); + + assert_expected_events!( + BridgeHubRococo, + vec![ + RuntimeEvent::XcmpQueue(cumulus_pallet_xcmp_queue::Event::XcmpMessageSent { .. }) => {}, + ] + ); + }); + + AssetHubRococo::execute_with(|| { + type RuntimeEvent = ::RuntimeEvent; + + assert_expected_events!( + AssetHubRococo, + vec![ + RuntimeEvent::ForeignAssets(pallet_assets::Event::Issued { .. }) => {}, + ] + ); + }); +} + +#[test] +fn reserve_transfer_token() { + let assethub_sovereign = BridgeHubRococo::sovereign_account_id_of( + MultiLocation { + parents: 1, + interior: X1(Parachain(ASSETHUB_PARA_ID)), + } + ); + + BridgeHubRococo::fund_accounts(vec![ + (assethub_sovereign.clone(), INITIAL_FUND) + ]); + + AssetHubRococo::fund_accounts(vec![ (AssetHubRococoReceiver::get(), INITIAL_FUND), ]); @@ -313,7 +381,7 @@ fn reserve_transfer_token() { command: Command::RegisterToken { token: WETH.into() }, }); let (xcm, _) = EthereumInboundQueue::do_convert(message_id_, message).unwrap(); - let _ = EthereumInboundQueue::send_xcm(xcm, DEST_PARA_ID.into()).unwrap(); + let _ = EthereumInboundQueue::send_xcm(xcm, ASSETHUB_PARA_ID.into()).unwrap(); let message = VersionedMessage::V1(MessageV1 { chain_id: CHAIN_ID, command: Command::SendToken { @@ -323,7 +391,7 @@ fn reserve_transfer_token() { }, }); let (xcm, _) = EthereumInboundQueue::do_convert(message_id_, message).unwrap(); - let _ = EthereumInboundQueue::send_xcm(xcm, DEST_PARA_ID.into()).unwrap(); + let _ = EthereumInboundQueue::send_xcm(xcm, ASSETHUB_PARA_ID.into()).unwrap(); assert_expected_events!( BridgeHubRococo, @@ -402,7 +470,7 @@ fn reserve_transfer_token() { .find(|&event| matches!( event, RuntimeEvent::Balances(pallet_balances::Event::Deposit{ who, amount }) - if *who == ASSETHUB_SOVEREIGN.into() && *amount == 2200000000000 + if who == &assethub_sovereign && *amount == 2200000000000 )) .is_some(), "Assethub sovereign takes remote fee." From d0f7e3edab74067715c0ddd9474ec498e40016dd Mon Sep 17 00:00:00 2001 From: Alistair Singh Date: Thu, 16 Nov 2023 21:25:40 +0200 Subject: [PATCH 03/10] failing on buy execution --- .../networks/rococo-wococo-system/src/lib.rs | 3 +- .../bridges/bridge-hub-rococo/src/lib.rs | 5 ++- .../bridge-hub-rococo/src/tests/snowbridge.rs | 41 +++++++++++++++---- .../runtimes/testing/penpal/src/lib.rs | 19 ++------- .../runtimes/testing/penpal/src/xcm_config.rs | 30 ++++++++------ 5 files changed, 60 insertions(+), 38 deletions(-) diff --git a/cumulus/parachains/integration-tests/emulated/networks/rococo-wococo-system/src/lib.rs b/cumulus/parachains/integration-tests/emulated/networks/rococo-wococo-system/src/lib.rs index f5ddd82576f2..5aaa7ef55a84 100644 --- a/cumulus/parachains/integration-tests/emulated/networks/rococo-wococo-system/src/lib.rs +++ b/cumulus/parachains/integration-tests/emulated/networks/rococo-wococo-system/src/lib.rs @@ -93,5 +93,6 @@ decl_test_sender_receiver_accounts_parameter_types! { BridgeHubRococoPara { sender: ALICE, receiver: BOB }, WococoRelay { sender: ALICE, receiver: BOB }, AssetHubWococoPara { sender: ALICE, receiver: BOB }, - BridgeHubWococoPara { sender: ALICE, receiver: BOB } + BridgeHubWococoPara { sender: ALICE, receiver: BOB }, + PenpalAPara { sender: ALICE, receiver: BOB } } diff --git a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/lib.rs b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/lib.rs index a3353282e7df..bccc9e3b9553 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/lib.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/lib.rs @@ -43,13 +43,14 @@ pub use rococo_wococo_system_emulated_network::{ bridge_hub_rococo_emulated_chain::{ genesis::ED as BRIDGE_HUB_ROCOCO_ED, BridgeHubRococoParaPallet as BridgeHubRococoPallet, }, + penpal_emulated_chain::PenpalAParaPallet as PenpalAPallet, rococo_emulated_chain::{genesis::ED as ROCOCO_ED, RococoRelayPallet as RococoPallet}, AssetHubRococoPara as AssetHubRococo, AssetHubRococoParaReceiver as AssetHubRococoReceiver, AssetHubRococoParaSender as AssetHubRococoSender, AssetHubWococoPara as AssetHubWococo, BridgeHubRococoPara as BridgeHubRococo, BridgeHubRococoParaReceiver as BridgeHubRococoReceiver, BridgeHubRococoParaSender as BridgeHubRococoSender, BridgeHubWococoPara as BridgeHubWococo, - PenpalAPara as PenpalARococo, RococoRelay as Rococo, RococoRelayReceiver as RococoReceiver, - RococoRelaySender as RococoSender, + PenpalAPara as PenpalA, PenpalAParaSender as PenpalASender, PenpalAParaReceiver as PenpalAReceiver, + RococoRelay as Rococo, RococoRelayReceiver as RococoReceiver, RococoRelaySender as RococoSender, }; pub const ASSET_ID: u32 = 1; diff --git a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/tests/snowbridge.rs b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/tests/snowbridge.rs index 99de9a3e086c..376dcdfbf311 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/tests/snowbridge.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/tests/snowbridge.rs @@ -226,11 +226,14 @@ fn register_token() { #[test] fn send_token_to_penpal() { - BridgeHubRococo::fund_accounts(vec![( - BridgeHubRococo::sovereign_account_id_of(MultiLocation { + let asset_hub_sovereign = BridgeHubRococo::sovereign_account_id_of( + MultiLocation { parents: 1, interior: X1(Parachain(ASSETHUB_PARA_ID)), - }), + } + ); + BridgeHubRococo::fund_accounts(vec![( + asset_hub_sovereign.clone(), INITIAL_FUND, )]); @@ -239,6 +242,30 @@ fn send_token_to_penpal() { (AssetHubRococoReceiver::get(), INITIAL_FUND), ]); + PenpalA::fund_accounts(vec![ + (PenpalAReceiver::get(), INITIAL_FUND), + (PenpalASender::get(), INITIAL_FUND), + ]); + + let weth_asset_id: MultiLocation = ( + Parent, + Parent, + Ethereum { chain_id: 15 }, + AccountKey20 { network: None, key: WETH } + ).into(); + + // Create asset on penpal. + PenpalA::execute_with(|| { + assert_ok!(::ForeignAssets::create( + ::RuntimeOrigin::signed(PenpalASender::get()), + weth_asset_id, + asset_hub_sovereign.into(), + 1000, + )); + + //assert!(::Assets::asset_exists(weth_asset_id)); + }); + let message_id_: H256 = [1; 32].into(); BridgeHubRococo::execute_with(|| { @@ -255,7 +282,7 @@ fn send_token_to_penpal() { chain_id: CHAIN_ID, command: Command::SendToken { token: WETH.into(), - destination: Destination::AccountId32 { id: AssetHubRococoReceiver::get().into() }, + destination: Destination::ForeignAccountId32 { para_id: 2000, id: AssetHubRococoReceiver::get().into() }, amount: 1_000_000_000, }, }); @@ -282,11 +309,11 @@ fn send_token_to_penpal() { ); }); - PenpalARococo::execute_with(|| { - type RuntimeEvent = ::RuntimeEvent; + PenpalA::execute_with(|| { + type RuntimeEvent = ::RuntimeEvent; assert_expected_events!( - PenpalARococo, + PenpalA, vec![ RuntimeEvent::ForeignAssets(pallet_assets::Event::Issued { .. }) => {}, ] diff --git a/cumulus/parachains/runtimes/testing/penpal/src/lib.rs b/cumulus/parachains/runtimes/testing/penpal/src/lib.rs index e4698ccaa129..7e2992d832c0 100644 --- a/cumulus/parachains/runtimes/testing/penpal/src/lib.rs +++ b/cumulus/parachains/runtimes/testing/penpal/src/lib.rs @@ -32,11 +32,7 @@ include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs")); mod weights; pub mod xcm_config; -use assets_common::{ - foreign_creators::ForeignCreators, - matching::FromSiblingParachain, - MultiLocationForAssetId, -}; +use assets_common::MultiLocationForAssetId; use cumulus_pallet_parachain_system::RelayNumberStrictlyIncreases; use cumulus_primitives_core::{AggregateMessageOrigin, ParaId}; use frame_support::{ @@ -75,7 +71,7 @@ use sp_std::prelude::*; #[cfg(feature = "std")] use sp_version::NativeVersion; use sp_version::RuntimeVersion; -use xcm_config::{AssetsToBlockAuthor, ForeignCreatorsSovereignAccountOf, XcmOriginToTransactDispatchOrigin}; +use xcm_config::{AssetsToBlockAuthor, XcmOriginToTransactDispatchOrigin}; #[cfg(any(feature = "std", test))] pub use sp_runtime::BuildStorage; @@ -473,9 +469,6 @@ parameter_types! { pub const ForeignAssetsMetadataDepositPerByte: Balance = MetadataDepositPerByte::get(); } -/// We allow root to execute privileged asset operations. -pub type AssetsForceOrigin = EnsureRoot; - /// Another pallet assets instance to store foreign assets from bridgehub. pub type ForeignAssetsInstance = pallet_assets::Instance2; impl pallet_assets::Config for Runtime { @@ -484,12 +477,8 @@ impl pallet_assets::Config for Runtime { type AssetId = MultiLocationForAssetId; type AssetIdParameter = MultiLocationForAssetId; type Currency = Balances; - type CreateOrigin = ForeignCreators< - (FromSiblingParachain>,), - ForeignCreatorsSovereignAccountOf, - AccountId, - >; - type ForceOrigin = AssetsForceOrigin; + type CreateOrigin = AsEnsureOriginWithArg>; + type ForceOrigin = EnsureRoot; type AssetDeposit = ForeignAssetsAssetDeposit; type MetadataDepositBase = ForeignAssetsMetadataDepositBase; type MetadataDepositPerByte = ForeignAssetsMetadataDepositPerByte; diff --git a/cumulus/parachains/runtimes/testing/penpal/src/xcm_config.rs b/cumulus/parachains/runtimes/testing/penpal/src/xcm_config.rs index 3ef755079bdd..81a591452834 100644 --- a/cumulus/parachains/runtimes/testing/penpal/src/xcm_config.rs +++ b/cumulus/parachains/runtimes/testing/penpal/src/xcm_config.rs @@ -188,16 +188,22 @@ pub type Barrier = TrailingSetTopicAsId< pub type AccountIdOf = ::AccountId; /// Asset filter that allows all assets from a certain location matching asset id. -pub struct AssetsFrom(PhantomData); -impl> ContainsPair for AssetsFrom { +pub struct AssetPrefixFrom(PhantomData<(Prefix, Origin)>); +impl ContainsPair for AssetPrefixFrom +where + Prefix: Get, + Origin: Get, +{ fn contains(asset: &MultiAsset, origin: &MultiLocation) -> bool { - let loc = T::get(); + let loc = Origin::get(); &loc == origin && matches!(asset, MultiAsset { id: AssetId::Concrete(asset_loc), fun: Fungible(_a) } - if asset_loc.starts_with(&loc)) + if asset_loc.starts_with(&Prefix::get())) } } +type AssetsFrom = AssetPrefixFrom; + /// Asset filter that allows native/relay asset if coming from a certain location. pub struct NativeAssetFrom(PhantomData); impl> ContainsPair for NativeAssetFrom { @@ -245,10 +251,15 @@ parameter_types! { pub SystemAssetHubAssetsPalletLocation: MultiLocation = MultiLocation::new(1, X2(Parachain(1000), PalletInstance(50))); pub CheckingAccount: AccountId = PolkadotXcm::check_account(); + pub EthereumLocation: MultiLocation = MultiLocation::new(2, X1(GlobalConsensus(Ethereum { chain_id: 15 }))); } -pub type Reserves = - (NativeAsset, AssetsFrom, NativeAssetFrom); +pub type Reserves = ( + NativeAsset, + AssetsFrom, + NativeAssetFrom, + AssetPrefixFrom, +); pub struct XcmConfig; impl xcm_executor::Config for XcmConfig { @@ -293,13 +304,6 @@ pub type XcmRouter = WithUniqueTopic<( XcmpQueue, )>; -// TODO(alistair): Only assethub should be able to create. -pub type ForeignCreatorsSovereignAccountOf = ( - SiblingParachainConvertsVia, - AccountId32Aliases, - ParentIsPreset, -); - impl pallet_xcm::Config for Runtime { type RuntimeEvent = RuntimeEvent; type SendXcmOrigin = EnsureXcmOrigin; From ef5c61560d57e5d3ca6ca3d2fdd512a02b9914f3 Mon Sep 17 00:00:00 2001 From: Alistair Singh Date: Thu, 16 Nov 2023 21:46:24 +0200 Subject: [PATCH 04/10] config foreign assets transactor --- .../runtimes/testing/penpal/src/xcm_config.rs | 30 ++++++++++++++++--- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/cumulus/parachains/runtimes/testing/penpal/src/xcm_config.rs b/cumulus/parachains/runtimes/testing/penpal/src/xcm_config.rs index 81a591452834..fe7110c24e73 100644 --- a/cumulus/parachains/runtimes/testing/penpal/src/xcm_config.rs +++ b/cumulus/parachains/runtimes/testing/penpal/src/xcm_config.rs @@ -24,8 +24,8 @@ //! soon. use super::{ AccountId, AllPalletsWithSystem, AssetId as AssetIdPalletAssets, Assets, Balance, Balances, - ParachainInfo, ParachainSystem, PolkadotXcm, Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin, - WeightToFee, XcmpQueue, + ForeignAssets, ParachainInfo, ParachainSystem, PolkadotXcm, Runtime, RuntimeCall, RuntimeEvent, + RuntimeOrigin, WeightToFee, XcmpQueue, }; use core::marker::PhantomData; use frame_support::{ @@ -49,7 +49,7 @@ use xcm_builder::{ AllowSubscriptionsFrom, AllowTopLevelPaidExecutionFrom, AsPrefixedGeneralIndex, ConvertedConcreteId, CurrencyAdapter, DenyReserveTransferToRelayChain, DenyThenTry, EnsureXcmOrigin, FixedWeightBounds, FungiblesAdapter, IsConcrete, LocalMint, NativeAsset, - ParentAsSuperuser, ParentIsPreset, RelayChainAsNative, SiblingParachainAsNative, + NoChecking, ParentAsSuperuser, ParentIsPreset, RelayChainAsNative, SiblingParachainAsNative, SiblingParachainConvertsVia, SignedAccountId32AsNative, SignedToAccountId32, SovereignSignedViaLocation, TakeWeightCredit, TrailingSetTopicAsId, UsingComponents, WithComputedOrigin, WithUniqueTopic, @@ -111,8 +111,30 @@ pub type FungiblesTransactor = FungiblesAdapter< CheckingAccount, >; +/// `AssetId/Balance` converter for `TrustBackedAssets` +pub type ForeignAssetsConvertedConcreteId = assets_common::ForeignAssetsConvertedConcreteId< + Nothing, + Balance, +>; + +/// Means for transacting foreign assets from different global consensus. +pub type ForeignFungiblesTransactor = FungiblesAdapter< + // Use this fungibles implementation: + ForeignAssets, + // Use this currency when it is a fungible asset matching the given location or name: + ForeignAssetsConvertedConcreteId, + // Convert an XCM MultiLocation into a local account id: + LocationToAccountId, + // Our chain's account ID type (we can't get away without mentioning it explicitly): + AccountId, + // We dont need to check teleports here. + NoChecking, + // The account to use for tracking teleports. + CheckingAccount, +>; + /// Means for transacting assets on this chain. -pub type AssetTransactors = (CurrencyTransactor, FungiblesTransactor); +pub type AssetTransactors = (CurrencyTransactor, FungiblesTransactor, ForeignFungiblesTransactor); /// This is the type we use to convert an (incoming) XCM origin into a local `Origin` instance, /// ready for dispatching a transaction with Xcm's `Transact`. There is an `OriginKind` which can From 325c816087888b5a7447347384c0366f842e0635 Mon Sep 17 00:00:00 2001 From: Alistair Singh Date: Thu, 16 Nov 2023 21:57:08 +0200 Subject: [PATCH 05/10] fixed fee issue --- .../tests/bridges/bridge-hub-rococo/src/tests/snowbridge.rs | 2 +- .../runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/tests/snowbridge.rs b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/tests/snowbridge.rs index 376dcdfbf311..5fdd7db17e69 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/tests/snowbridge.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/tests/snowbridge.rs @@ -282,7 +282,7 @@ fn send_token_to_penpal() { chain_id: CHAIN_ID, command: Command::SendToken { token: WETH.into(), - destination: Destination::ForeignAccountId32 { para_id: 2000, id: AssetHubRococoReceiver::get().into() }, + destination: Destination::ForeignAccountId32 { para_id: 2000, id: PenpalAReceiver::get().into() }, amount: 1_000_000_000, }, }); diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs index b6ba07f2d982..34532eee1621 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs @@ -527,7 +527,7 @@ parameter_types! { pub const CreateAssetCall: [u8;2] = [53, 0]; pub const CreateAssetExecutionFee: u128 = 2_000_000_000; pub const CreateAssetDeposit: u128 = (UNITS / 10) + EXISTENTIAL_DEPOSIT; - pub const SendTokenExecutionFee: u128 = 2_000_000_000; + pub const SendTokenExecutionFee: u128 = 4_000_000_000; } #[cfg(feature = "runtime-benchmarks")] From 52215a7f22da143d7057a827392b74d0af6ca639 Mon Sep 17 00:00:00 2001 From: Alistair Singh Date: Thu, 16 Nov 2023 22:05:33 +0200 Subject: [PATCH 06/10] tests pass --- cumulus/parachains/runtimes/testing/penpal/src/xcm_config.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cumulus/parachains/runtimes/testing/penpal/src/xcm_config.rs b/cumulus/parachains/runtimes/testing/penpal/src/xcm_config.rs index fe7110c24e73..ff1c50a103b1 100644 --- a/cumulus/parachains/runtimes/testing/penpal/src/xcm_config.rs +++ b/cumulus/parachains/runtimes/testing/penpal/src/xcm_config.rs @@ -134,7 +134,7 @@ pub type ForeignFungiblesTransactor = FungiblesAdapter< >; /// Means for transacting assets on this chain. -pub type AssetTransactors = (CurrencyTransactor, FungiblesTransactor, ForeignFungiblesTransactor); +pub type AssetTransactors = (CurrencyTransactor, ForeignFungiblesTransactor, FungiblesTransactor); /// This is the type we use to convert an (incoming) XCM origin into a local `Origin` instance, /// ready for dispatching a transaction with Xcm's `Transact`. There is an `OriginKind` which can From 039db0e8bae4fcd68be3c5bb934285fa1a0adafe Mon Sep 17 00:00:00 2001 From: Alistair Singh Date: Thu, 16 Nov 2023 23:07:05 +0200 Subject: [PATCH 07/10] fix asset hub tests --- .../parachains/runtimes/testing/penpal/src/xcm_config.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cumulus/parachains/runtimes/testing/penpal/src/xcm_config.rs b/cumulus/parachains/runtimes/testing/penpal/src/xcm_config.rs index ff1c50a103b1..39064eede9ba 100644 --- a/cumulus/parachains/runtimes/testing/penpal/src/xcm_config.rs +++ b/cumulus/parachains/runtimes/testing/penpal/src/xcm_config.rs @@ -51,8 +51,8 @@ use xcm_builder::{ EnsureXcmOrigin, FixedWeightBounds, FungiblesAdapter, IsConcrete, LocalMint, NativeAsset, NoChecking, ParentAsSuperuser, ParentIsPreset, RelayChainAsNative, SiblingParachainAsNative, SiblingParachainConvertsVia, SignedAccountId32AsNative, SignedToAccountId32, - SovereignSignedViaLocation, TakeWeightCredit, TrailingSetTopicAsId, UsingComponents, - WithComputedOrigin, WithUniqueTopic, + SovereignSignedViaLocation, StartsWith, TakeWeightCredit, TrailingSetTopicAsId, + UsingComponents, WithComputedOrigin, WithUniqueTopic, }; use xcm_executor::{traits::JustTry, XcmExecutor}; @@ -113,7 +113,7 @@ pub type FungiblesTransactor = FungiblesAdapter< /// `AssetId/Balance` converter for `TrustBackedAssets` pub type ForeignAssetsConvertedConcreteId = assets_common::ForeignAssetsConvertedConcreteId< - Nothing, + StartsWith, Balance, >; From 1e7f6ffb518e50884f78244c1b5e7fcbce2f3bb3 Mon Sep 17 00:00:00 2001 From: Alistair Singh Date: Thu, 16 Nov 2023 23:15:53 +0200 Subject: [PATCH 08/10] add penpal-rococo --- cumulus/polkadot-parachain/src/command.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/cumulus/polkadot-parachain/src/command.rs b/cumulus/polkadot-parachain/src/command.rs index 3f93c90558a3..5bf73fb18c08 100644 --- a/cumulus/polkadot-parachain/src/command.rs +++ b/cumulus/polkadot-parachain/src/command.rs @@ -245,6 +245,10 @@ fn load_spec(id: &str) -> std::result::Result, String> { .load_config()?, // -- Penpall + "penpal-rococo" => Box::new(chain_spec::penpal::get_penpal_chain_spec( + para_id.expect("Must specify parachain id"), + "rococo-local", + )), "penpal-kusama" => Box::new(chain_spec::penpal::get_penpal_chain_spec( para_id.expect("Must specify parachain id"), "kusama-local", From eba035e03be7989c5df155accbcd72f21fd5ef2f Mon Sep 17 00:00:00 2001 From: Alistair Singh Date: Tue, 21 Nov 2023 10:16:07 +0200 Subject: [PATCH 09/10] remove addition --- cumulus/polkadot-parachain/src/command.rs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/cumulus/polkadot-parachain/src/command.rs b/cumulus/polkadot-parachain/src/command.rs index 5bf73fb18c08..3f93c90558a3 100644 --- a/cumulus/polkadot-parachain/src/command.rs +++ b/cumulus/polkadot-parachain/src/command.rs @@ -245,10 +245,6 @@ fn load_spec(id: &str) -> std::result::Result, String> { .load_config()?, // -- Penpall - "penpal-rococo" => Box::new(chain_spec::penpal::get_penpal_chain_spec( - para_id.expect("Must specify parachain id"), - "rococo-local", - )), "penpal-kusama" => Box::new(chain_spec::penpal::get_penpal_chain_spec( para_id.expect("Must specify parachain id"), "kusama-local", From a0c2f3a7e39b89a926c12f5048b7f41d7dc5b172 Mon Sep 17 00:00:00 2001 From: Alistair Singh Date: Tue, 21 Nov 2023 13:55:54 +0200 Subject: [PATCH 10/10] add penpal rococo runtime --- cumulus/polkadot-parachain/src/command.rs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/cumulus/polkadot-parachain/src/command.rs b/cumulus/polkadot-parachain/src/command.rs index 3f93c90558a3..deca24833a66 100644 --- a/cumulus/polkadot-parachain/src/command.rs +++ b/cumulus/polkadot-parachain/src/command.rs @@ -245,6 +245,10 @@ fn load_spec(id: &str) -> std::result::Result, String> { .load_config()?, // -- Penpall + "penpal-rococo" => Box::new(chain_spec::penpal::get_penpal_chain_spec( + para_id.expect("Must specify parachain id"), + "rococo-local", + )), "penpal-kusama" => Box::new(chain_spec::penpal::get_penpal_chain_spec( para_id.expect("Must specify parachain id"), "kusama-local", @@ -315,6 +319,7 @@ fn load_spec(id: &str) -> std::result::Result, String> { /// (H/T to Phala for the idea) /// E.g. "penpal-kusama-2004" yields ("penpal-kusama", Some(2004)) fn extract_parachain_id(id: &str) -> (&str, &str, Option) { + const ROCOCO_TEST_PARA_PREFIX: &str = "penpal-rococo-"; const KUSAMA_TEST_PARA_PREFIX: &str = "penpal-kusama-"; const POLKADOT_TEST_PARA_PREFIX: &str = "penpal-polkadot-"; @@ -322,7 +327,10 @@ fn extract_parachain_id(id: &str) -> (&str, &str, Option) { const GLUTTON_PARA_LOCAL_PREFIX: &str = "glutton-kusama-local-"; const GLUTTON_PARA_GENESIS_PREFIX: &str = "glutton-kusama-genesis-"; - let (norm_id, orig_id, para) = if let Some(suffix) = id.strip_prefix(KUSAMA_TEST_PARA_PREFIX) { + let (norm_id, orig_id, para) = if let Some(suffix) = id.strip_prefix(ROCOCO_TEST_PARA_PREFIX) { + let para_id: u32 = suffix.parse().expect("Invalid parachain-id suffix"); + (&id[..ROCOCO_TEST_PARA_PREFIX.len() - 1], id, Some(para_id)) + } else if let Some(suffix) = id.strip_prefix(KUSAMA_TEST_PARA_PREFIX) { let para_id: u32 = suffix.parse().expect("Invalid parachain-id suffix"); (&id[..KUSAMA_TEST_PARA_PREFIX.len() - 1], id, Some(para_id)) } else if let Some(suffix) = id.strip_prefix(POLKADOT_TEST_PARA_PREFIX) {