diff --git a/Cargo.lock b/Cargo.lock index 15a75f7279f9..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", @@ -11924,6 +11925,7 @@ dependencies = [ name = "penpal-runtime" version = "0.9.27" dependencies = [ + "assets-common", "cumulus-pallet-aura-ext", "cumulus-pallet-dmp-queue", "cumulus-pallet-parachain-system", @@ -14902,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..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 @@ -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 @@ -90,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/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..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, - 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 2ede961bf3c1..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 @@ -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,21 +225,47 @@ fn register_token() { } #[test] -fn send_token() { - BridgeHubRococo::fund_accounts(vec![( - BridgeHubRococo::sovereign_account_id_of(MultiLocation { +fn send_token_to_penpal() { + let asset_hub_sovereign = BridgeHubRococo::sovereign_account_id_of( + MultiLocation { parents: 1, - interior: X1(Parachain(DEST_PARA_ID)), - }), + interior: X1(Parachain(ASSETHUB_PARA_ID)), + } + ); + BridgeHubRococo::fund_accounts(vec![( + asset_hub_sovereign.clone(), INITIAL_FUND, )]); // Fund ethereum sovereign in asset hub AssetHubRococo::fund_accounts(vec![ - (ASSETHUB_SOVEREIGN.into(), INITIAL_FUND), (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(|| { @@ -253,17 +277,17 @@ 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 { token: WETH.into(), - destination: Destination::AccountId32 { id: AssetHubRococoReceiver::get().into() }, + destination: Destination::ForeignAccountId32 { para_id: 2000, id: PenpalAReceiver::get().into() }, amount: 1_000_000_000, }, }); 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 +302,18 @@ fn send_token() { assert_expected_events!( AssetHubRococo, + vec![ + RuntimeEvent::ForeignAssets(pallet_assets::Event::Issued { .. }) => {}, + RuntimeEvent::XcmpQueue(cumulus_pallet_xcmp_queue::Event::XcmpMessageSent { .. }) => {}, + ] + ); + }); + + PenpalA::execute_with(|| { + type RuntimeEvent = ::RuntimeEvent; + + assert_expected_events!( + PenpalA, vec![ RuntimeEvent::ForeignAssets(pallet_assets::Event::Issued { .. }) => {}, ] @@ -286,18 +322,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 +408,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 +418,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 +497,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." 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")] 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..7e2992d832c0 100644 --- a/cumulus/parachains/runtimes/testing/penpal/src/lib.rs +++ b/cumulus/parachains/runtimes/testing/penpal/src/lib.rs @@ -32,6 +32,7 @@ include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs")); mod weights; pub mod xcm_config; +use assets_common::MultiLocationForAssetId; use cumulus_pallet_parachain_system::RelayNumberStrictlyIncreases; use cumulus_primitives_core::{AggregateMessageOrigin, ParaId}; use frame_support::{ @@ -457,6 +458,42 @@ 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(); +} + +/// 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 = AsEnsureOriginWithArg>; + type ForceOrigin = EnsureRoot; + 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 +662,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..39064eede9ba 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,10 +49,10 @@ 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, + SovereignSignedViaLocation, StartsWith, TakeWeightCredit, TrailingSetTopicAsId, + UsingComponents, WithComputedOrigin, WithUniqueTopic, }; use xcm_executor::{traits::JustTry, XcmExecutor}; @@ -111,8 +111,30 @@ pub type FungiblesTransactor = FungiblesAdapter< CheckingAccount, >; +/// `AssetId/Balance` converter for `TrustBackedAssets` +pub type ForeignAssetsConvertedConcreteId = assets_common::ForeignAssetsConvertedConcreteId< + StartsWith, + 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, 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 @@ -188,16 +210,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 +273,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 { 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) {