mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-05-30 21:01:02 +00:00
Improve Penpal runtime + emulated tests (#3543)
Issues addressed in this PR: - Improve *Penpal* runtime: - Properly handled received assets. Previously, it treated `(1, Here)` as the local native currency, whereas it should be treated as a `ForeignAsset`. This wasn't a great example of standard Parachain behaviour, as no Parachain treats the system asset as the local currency. - Remove `AllowExplicitUnpaidExecutionFrom` the system. Again, this wasn't a great example of standard Parachain behaviour. - Move duplicated `ForeignAssetFeeAsExistentialDepositMultiplierFeeCharger` to `assets_common` crate. - Improve emulated tests: - Update *Penpal* tests to new runtime. - To simplify tests, register the reserve transferred, teleported, and system assets in *Penpal* and *AssetHub* genesis. This saves us from having to create the assets repeatedly for each test - Add missing test case: `reserve_transfer_assets_from_para_to_system_para`. - Cleanup. - Prevent integration tests crates imports from being re-exported, as they were polluting the `polkadot-sdk` docs. There is still a test case missing for reserve transfers: - Reserve transfer of system asset from *Parachain* to *Parachain* trough *AssetHub*. - This is not yet possible with `pallet-xcm` due to the reasons explained in https://github.com/paritytech/polkadot-sdk/pull/3339 --------- Co-authored-by: command-bot <>
This commit is contained in:
Generated
+4
-2
@@ -841,6 +841,7 @@ dependencies = [
|
||||
"pallet-xcm",
|
||||
"parachains-common",
|
||||
"parity-scale-codec",
|
||||
"penpal-runtime",
|
||||
"rococo-runtime",
|
||||
"rococo-system-emulated-network",
|
||||
"sp-runtime",
|
||||
@@ -962,6 +963,7 @@ dependencies = [
|
||||
"pallet-xcm",
|
||||
"parachains-common",
|
||||
"parity-scale-codec",
|
||||
"penpal-runtime",
|
||||
"polkadot-runtime-common",
|
||||
"sp-runtime",
|
||||
"staging-xcm",
|
||||
@@ -4931,6 +4933,7 @@ dependencies = [
|
||||
"parachains-common",
|
||||
"parity-scale-codec",
|
||||
"paste",
|
||||
"polkadot-parachain-primitives",
|
||||
"polkadot-primitives",
|
||||
"polkadot-runtime-parachains",
|
||||
"sc-consensus-grandpa",
|
||||
@@ -11645,9 +11648,8 @@ dependencies = [
|
||||
"frame-support",
|
||||
"parachains-common",
|
||||
"penpal-runtime",
|
||||
"rococo-emulated-chain",
|
||||
"sp-core",
|
||||
"westend-emulated-chain",
|
||||
"staging-xcm",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
||||
+26
-3
@@ -14,17 +14,24 @@
|
||||
// limitations under the License.
|
||||
|
||||
// Substrate
|
||||
use sp_core::storage::Storage;
|
||||
use frame_support::parameter_types;
|
||||
use sp_core::{sr25519, storage::Storage};
|
||||
|
||||
// Cumulus
|
||||
use emulated_integration_tests_common::{
|
||||
accounts, build_genesis_storage, collators, SAFE_XCM_VERSION,
|
||||
accounts, build_genesis_storage, collators, get_account_id_from_seed,
|
||||
PenpalSiblingSovereigAccount, PenpalTeleportableAssetLocation, RESERVABLE_ASSET_ID,
|
||||
SAFE_XCM_VERSION,
|
||||
};
|
||||
use parachains_common::Balance;
|
||||
use parachains_common::{AccountId, Balance};
|
||||
|
||||
pub const PARA_ID: u32 = 1000;
|
||||
pub const ED: Balance = testnet_parachains_constants::rococo::currency::EXISTENTIAL_DEPOSIT;
|
||||
|
||||
parameter_types! {
|
||||
pub AssetHubRococoAssetOwner: AccountId = get_account_id_from_seed::<sr25519::Public>("Alice");
|
||||
}
|
||||
|
||||
pub fn genesis() -> Storage {
|
||||
let genesis_config = asset_hub_rococo_runtime::RuntimeGenesisConfig {
|
||||
system: asset_hub_rococo_runtime::SystemConfig::default(),
|
||||
@@ -60,6 +67,22 @@ pub fn genesis() -> Storage {
|
||||
safe_xcm_version: Some(SAFE_XCM_VERSION),
|
||||
..Default::default()
|
||||
},
|
||||
assets: asset_hub_rococo_runtime::AssetsConfig {
|
||||
assets: vec![(RESERVABLE_ASSET_ID, AssetHubRococoAssetOwner::get(), true, ED)],
|
||||
..Default::default()
|
||||
},
|
||||
foreign_assets: asset_hub_rococo_runtime::ForeignAssetsConfig {
|
||||
assets: vec![
|
||||
// Penpal's teleportable asset representation
|
||||
(
|
||||
PenpalTeleportableAssetLocation::get(),
|
||||
PenpalSiblingSovereigAccount::get(),
|
||||
true,
|
||||
ED,
|
||||
),
|
||||
],
|
||||
..Default::default()
|
||||
},
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
|
||||
+3
-3
@@ -21,7 +21,7 @@ use frame_support::traits::OnInitialize;
|
||||
// Cumulus
|
||||
use emulated_integration_tests_common::{
|
||||
impl_accounts_helpers_for_parachain, impl_assert_events_helpers_for_parachain,
|
||||
impl_assets_helpers_for_parachain, impl_foreign_assets_helpers_for_parachain,
|
||||
impl_assets_helpers_for_parachain, impl_assets_helpers_for_system_parachain,
|
||||
impl_xcm_helpers_for_parachain, impls::Parachain, xcm_emulator::decl_test_parachains,
|
||||
};
|
||||
use rococo_emulated_chain::Rococo;
|
||||
@@ -54,6 +54,6 @@ decl_test_parachains! {
|
||||
// AssetHubRococo implementation
|
||||
impl_accounts_helpers_for_parachain!(AssetHubRococo);
|
||||
impl_assert_events_helpers_for_parachain!(AssetHubRococo);
|
||||
impl_assets_helpers_for_parachain!(AssetHubRococo, Rococo);
|
||||
impl_foreign_assets_helpers_for_parachain!(AssetHubRococo, Rococo);
|
||||
impl_assets_helpers_for_system_parachain!(AssetHubRococo, Rococo);
|
||||
impl_assets_helpers_for_parachain!(AssetHubRococo);
|
||||
impl_xcm_helpers_for_parachain!(AssetHubRococo);
|
||||
|
||||
+26
-3
@@ -14,17 +14,24 @@
|
||||
// limitations under the License.
|
||||
|
||||
// Substrate
|
||||
use sp_core::storage::Storage;
|
||||
use frame_support::parameter_types;
|
||||
use sp_core::{sr25519, storage::Storage};
|
||||
|
||||
// Cumulus
|
||||
use emulated_integration_tests_common::{
|
||||
accounts, build_genesis_storage, collators, SAFE_XCM_VERSION,
|
||||
accounts, build_genesis_storage, collators, get_account_id_from_seed,
|
||||
PenpalSiblingSovereigAccount, PenpalTeleportableAssetLocation, RESERVABLE_ASSET_ID,
|
||||
SAFE_XCM_VERSION,
|
||||
};
|
||||
use parachains_common::Balance;
|
||||
use parachains_common::{AccountId, Balance};
|
||||
|
||||
pub const PARA_ID: u32 = 1000;
|
||||
pub const ED: Balance = testnet_parachains_constants::westend::currency::EXISTENTIAL_DEPOSIT;
|
||||
|
||||
parameter_types! {
|
||||
pub AssetHubWestendAssetOwner: AccountId = get_account_id_from_seed::<sr25519::Public>("Alice");
|
||||
}
|
||||
|
||||
pub fn genesis() -> Storage {
|
||||
let genesis_config = asset_hub_westend_runtime::RuntimeGenesisConfig {
|
||||
system: asset_hub_westend_runtime::SystemConfig::default(),
|
||||
@@ -56,6 +63,22 @@ pub fn genesis() -> Storage {
|
||||
safe_xcm_version: Some(SAFE_XCM_VERSION),
|
||||
..Default::default()
|
||||
},
|
||||
assets: asset_hub_westend_runtime::AssetsConfig {
|
||||
assets: vec![(RESERVABLE_ASSET_ID, AssetHubWestendAssetOwner::get(), true, ED)],
|
||||
..Default::default()
|
||||
},
|
||||
foreign_assets: asset_hub_westend_runtime::ForeignAssetsConfig {
|
||||
assets: vec![
|
||||
// Penpal's teleportable asset representation
|
||||
(
|
||||
PenpalTeleportableAssetLocation::get(),
|
||||
PenpalSiblingSovereigAccount::get(),
|
||||
true,
|
||||
ED,
|
||||
),
|
||||
],
|
||||
..Default::default()
|
||||
},
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
|
||||
+3
-3
@@ -21,7 +21,7 @@ use frame_support::traits::OnInitialize;
|
||||
// Cumulus
|
||||
use emulated_integration_tests_common::{
|
||||
impl_accounts_helpers_for_parachain, impl_assert_events_helpers_for_parachain,
|
||||
impl_assets_helpers_for_parachain, impl_foreign_assets_helpers_for_parachain,
|
||||
impl_assets_helpers_for_parachain, impl_assets_helpers_for_system_parachain,
|
||||
impl_xcm_helpers_for_parachain, impls::Parachain, xcm_emulator::decl_test_parachains,
|
||||
};
|
||||
use westend_emulated_chain::Westend;
|
||||
@@ -54,6 +54,6 @@ decl_test_parachains! {
|
||||
// AssetHubWestend implementation
|
||||
impl_accounts_helpers_for_parachain!(AssetHubWestend);
|
||||
impl_assert_events_helpers_for_parachain!(AssetHubWestend);
|
||||
impl_assets_helpers_for_parachain!(AssetHubWestend, Westend);
|
||||
impl_foreign_assets_helpers_for_parachain!(AssetHubWestend, Westend);
|
||||
impl_assets_helpers_for_system_parachain!(AssetHubWestend, Westend);
|
||||
impl_assets_helpers_for_parachain!(AssetHubWestend);
|
||||
impl_xcm_helpers_for_parachain!(AssetHubWestend);
|
||||
|
||||
+3
-2
@@ -16,10 +16,11 @@ workspace = true
|
||||
sp-core = { path = "../../../../../../../../substrate/primitives/core", default-features = false }
|
||||
frame-support = { path = "../../../../../../../../substrate/frame/support", default-features = false }
|
||||
|
||||
# Polkadot
|
||||
xcm = { package = "staging-xcm", path = "../../../../../../../../polkadot/xcm", default-features = false }
|
||||
|
||||
# Cumulus
|
||||
parachains-common = { path = "../../../../../../../parachains/common" }
|
||||
cumulus-primitives-core = { path = "../../../../../../../primitives/core", default-features = false }
|
||||
emulated-integration-tests-common = { path = "../../../../common", default-features = false }
|
||||
penpal-runtime = { path = "../../../../../../runtimes/testing/penpal" }
|
||||
rococo-emulated-chain = { path = "../../../relays/rococo" }
|
||||
westend-emulated-chain = { path = "../../../relays/westend" }
|
||||
|
||||
+39
-4
@@ -14,19 +14,27 @@
|
||||
// limitations under the License.
|
||||
|
||||
// Substrate
|
||||
use frame_support::parameter_types;
|
||||
use sp_core::{sr25519, storage::Storage};
|
||||
|
||||
// Polkadot
|
||||
use xcm::v3::Location;
|
||||
// Cumulus
|
||||
use emulated_integration_tests_common::{
|
||||
accounts, build_genesis_storage, collators, get_account_id_from_seed, SAFE_XCM_VERSION,
|
||||
};
|
||||
use parachains_common::Balance;
|
||||
|
||||
use parachains_common::{AccountId, Balance};
|
||||
use penpal_runtime::xcm_config::{LocalReservableFromAssetHub, RelayLocation};
|
||||
// Penpal
|
||||
pub const PARA_ID_A: u32 = 2000;
|
||||
pub const PARA_ID_B: u32 = 2001;
|
||||
pub const ED: Balance = penpal_runtime::EXISTENTIAL_DEPOSIT;
|
||||
|
||||
parameter_types! {
|
||||
pub PenpalSudoAcccount: AccountId = get_account_id_from_seed::<sr25519::Public>("Alice");
|
||||
pub PenpalAssetOwner: AccountId = PenpalSudoAcccount::get();
|
||||
}
|
||||
|
||||
pub fn genesis(para_id: u32) -> Storage {
|
||||
let genesis_config = penpal_runtime::RuntimeGenesisConfig {
|
||||
system: penpal_runtime::SystemConfig::default(),
|
||||
@@ -58,8 +66,35 @@ pub fn genesis(para_id: u32) -> Storage {
|
||||
safe_xcm_version: Some(SAFE_XCM_VERSION),
|
||||
..Default::default()
|
||||
},
|
||||
sudo: penpal_runtime::SudoConfig {
|
||||
key: Some(get_account_id_from_seed::<sr25519::Public>("Alice")),
|
||||
sudo: penpal_runtime::SudoConfig { key: Some(PenpalSudoAcccount::get()) },
|
||||
assets: penpal_runtime::AssetsConfig {
|
||||
assets: vec![(
|
||||
penpal_runtime::xcm_config::TELEPORTABLE_ASSET_ID,
|
||||
PenpalAssetOwner::get(),
|
||||
false,
|
||||
ED,
|
||||
)],
|
||||
..Default::default()
|
||||
},
|
||||
foreign_assets: penpal_runtime::ForeignAssetsConfig {
|
||||
assets: vec![
|
||||
// Relay Native asset representation
|
||||
(
|
||||
Location::try_from(RelayLocation::get()).expect("conversion works"),
|
||||
PenpalAssetOwner::get(),
|
||||
true,
|
||||
ED,
|
||||
),
|
||||
// Sufficient AssetHub asset representation
|
||||
(
|
||||
Location::try_from(LocalReservableFromAssetHub::get())
|
||||
.expect("conversion works"),
|
||||
PenpalAssetOwner::get(),
|
||||
true,
|
||||
ED,
|
||||
),
|
||||
],
|
||||
..Default::default()
|
||||
},
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
+4
-7
@@ -14,10 +14,9 @@
|
||||
// limitations under the License.
|
||||
|
||||
mod genesis;
|
||||
pub use genesis::{genesis, ED, PARA_ID_A, PARA_ID_B};
|
||||
pub use genesis::{genesis, PenpalAssetOwner, PenpalSudoAcccount, ED, PARA_ID_A, PARA_ID_B};
|
||||
pub use penpal_runtime::xcm_config::{
|
||||
CustomizableAssetFromSystemAssetHub, LocalTeleportableToAssetHub,
|
||||
LocalTeleportableToAssetHubV3, XcmConfig,
|
||||
CustomizableAssetFromSystemAssetHub, LocalTeleportableToAssetHub, XcmConfig,
|
||||
};
|
||||
|
||||
// Substrate
|
||||
@@ -28,8 +27,6 @@ use emulated_integration_tests_common::{
|
||||
impl_accounts_helpers_for_parachain, impl_assert_events_helpers_for_parachain,
|
||||
impl_assets_helpers_for_parachain, impls::Parachain, xcm_emulator::decl_test_parachains,
|
||||
};
|
||||
use rococo_emulated_chain::Rococo;
|
||||
use westend_emulated_chain::Westend;
|
||||
|
||||
// Penpal Parachain declaration
|
||||
decl_test_parachains! {
|
||||
@@ -76,7 +73,7 @@ decl_test_parachains! {
|
||||
// Penpal implementation
|
||||
impl_accounts_helpers_for_parachain!(PenpalA);
|
||||
impl_accounts_helpers_for_parachain!(PenpalB);
|
||||
impl_assets_helpers_for_parachain!(PenpalA, Rococo);
|
||||
impl_assets_helpers_for_parachain!(PenpalB, Westend);
|
||||
impl_assert_events_helpers_for_parachain!(PenpalA);
|
||||
impl_assert_events_helpers_for_parachain!(PenpalB);
|
||||
impl_assets_helpers_for_parachain!(PenpalA);
|
||||
impl_assets_helpers_for_parachain!(PenpalB);
|
||||
|
||||
@@ -27,6 +27,7 @@ pallet-message-queue = { path = "../../../../../substrate/frame/message-queue" }
|
||||
|
||||
# Polkadot
|
||||
polkadot-primitives = { path = "../../../../../polkadot/primitives" }
|
||||
polkadot-parachain-primitives = { path = "../../../../../polkadot/parachain" }
|
||||
polkadot-runtime-parachains = { path = "../../../../../polkadot/runtime/parachains" }
|
||||
xcm = { package = "staging-xcm", path = "../../../../../polkadot/xcm" }
|
||||
pallet-xcm = { path = "../../../../../polkadot/xcm/pallet-xcm" }
|
||||
|
||||
@@ -592,7 +592,7 @@ macro_rules! impl_assert_events_helpers_for_parachain {
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! impl_assets_helpers_for_parachain {
|
||||
macro_rules! impl_assets_helpers_for_system_parachain {
|
||||
( $chain:ident, $relay_chain:ident ) => {
|
||||
$crate::impls::paste::paste! {
|
||||
impl<N: $crate::impls::Network> $chain<N> {
|
||||
@@ -630,38 +630,6 @@ macro_rules! impl_assets_helpers_for_parachain {
|
||||
$crate::impls::xcm_transact_unpaid_execution(call, origin_kind)
|
||||
}
|
||||
|
||||
/// Mint assets making use of the assets pallet
|
||||
pub fn mint_asset(
|
||||
signed_origin: <Self as $crate::impls::Chain>::RuntimeOrigin,
|
||||
id: u32,
|
||||
beneficiary: $crate::impls::AccountId,
|
||||
amount_to_mint: u128,
|
||||
) {
|
||||
<Self as $crate::impls::TestExt>::execute_with(|| {
|
||||
$crate::impls::assert_ok!(<Self as [<$chain ParaPallet>]>::Assets::mint(
|
||||
signed_origin,
|
||||
id.clone().into(),
|
||||
beneficiary.clone().into(),
|
||||
amount_to_mint
|
||||
));
|
||||
|
||||
type RuntimeEvent<N> = <$chain<N> as $crate::impls::Chain>::RuntimeEvent;
|
||||
|
||||
$crate::impls::assert_expected_events!(
|
||||
Self,
|
||||
vec![
|
||||
RuntimeEvent::<N>::Assets(
|
||||
$crate::impls::pallet_assets::Event::Issued { asset_id, owner, amount }
|
||||
) => {
|
||||
asset_id: *asset_id == id,
|
||||
owner: *owner == beneficiary.clone().into(),
|
||||
amount: *amount == amount_to_mint,
|
||||
},
|
||||
]
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
/// Force create and mint assets making use of the assets pallet
|
||||
pub fn force_create_and_mint_asset(
|
||||
id: u32,
|
||||
@@ -727,8 +695,8 @@ macro_rules! impl_assets_helpers_for_parachain {
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! impl_foreign_assets_helpers_for_parachain {
|
||||
( $chain:ident, $relay_chain:ident ) => {
|
||||
macro_rules! impl_assets_helpers_for_parachain {
|
||||
( $chain:ident) => {
|
||||
$crate::impls::paste::paste! {
|
||||
impl<N: $crate::impls::Network> $chain<N> {
|
||||
/// Create foreign assets using sudo `ForeignAssets::force_create()`
|
||||
@@ -803,6 +771,118 @@ macro_rules! impl_foreign_assets_helpers_for_parachain {
|
||||
);
|
||||
});
|
||||
}
|
||||
/// Create assets using sudo `Assets::force_create()`
|
||||
pub fn force_create_asset(
|
||||
id: u32,
|
||||
owner: $crate::impls::AccountId,
|
||||
is_sufficient: bool,
|
||||
min_balance: u128,
|
||||
prefund_accounts: Vec<($crate::impls::AccountId, u128)>,
|
||||
) {
|
||||
use $crate::impls::Inspect;
|
||||
let sudo_origin = <$chain<N> as $crate::impls::Chain>::RuntimeOrigin::root();
|
||||
<Self as $crate::impls::TestExt>::execute_with(|| {
|
||||
$crate::impls::assert_ok!(
|
||||
<Self as [<$chain ParaPallet>]>::Assets::force_create(
|
||||
sudo_origin,
|
||||
id.clone().into(),
|
||||
owner.clone().into(),
|
||||
is_sufficient,
|
||||
min_balance,
|
||||
)
|
||||
);
|
||||
assert!(<Self as [<$chain ParaPallet>]>::Assets::asset_exists(id.clone()));
|
||||
type RuntimeEvent<N> = <$chain<N> as $crate::impls::Chain>::RuntimeEvent;
|
||||
$crate::impls::assert_expected_events!(
|
||||
Self,
|
||||
vec![
|
||||
RuntimeEvent::<N>::Assets(
|
||||
$crate::impls::pallet_assets::Event::ForceCreated {
|
||||
asset_id,
|
||||
..
|
||||
}
|
||||
) => { asset_id: *asset_id == id, },
|
||||
]
|
||||
);
|
||||
});
|
||||
for (beneficiary, amount) in prefund_accounts.into_iter() {
|
||||
let signed_origin =
|
||||
<$chain<N> as $crate::impls::Chain>::RuntimeOrigin::signed(owner.clone());
|
||||
Self::mint_asset(signed_origin, id.clone(), beneficiary, amount);
|
||||
}
|
||||
}
|
||||
|
||||
/// Mint assets making use of the assets pallet
|
||||
pub fn mint_asset(
|
||||
signed_origin: <Self as $crate::impls::Chain>::RuntimeOrigin,
|
||||
id: u32,
|
||||
beneficiary: $crate::impls::AccountId,
|
||||
amount_to_mint: u128,
|
||||
) {
|
||||
<Self as $crate::impls::TestExt>::execute_with(|| {
|
||||
$crate::impls::assert_ok!(<Self as [<$chain ParaPallet>]>::Assets::mint(
|
||||
signed_origin,
|
||||
id.clone().into(),
|
||||
beneficiary.clone().into(),
|
||||
amount_to_mint
|
||||
));
|
||||
|
||||
type RuntimeEvent<N> = <$chain<N> as $crate::impls::Chain>::RuntimeEvent;
|
||||
|
||||
$crate::impls::assert_expected_events!(
|
||||
Self,
|
||||
vec![
|
||||
RuntimeEvent::<N>::Assets(
|
||||
$crate::impls::pallet_assets::Event::Issued { asset_id, owner, amount }
|
||||
) => {
|
||||
asset_id: *asset_id == id,
|
||||
owner: *owner == beneficiary.clone().into(),
|
||||
amount: *amount == amount_to_mint,
|
||||
},
|
||||
]
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
/// Returns the encoded call for `create` from the assets pallet
|
||||
pub fn create_asset_call(
|
||||
asset_id: u32,
|
||||
min_balance: $crate::impls::Balance,
|
||||
admin: $crate::impls::AccountId,
|
||||
) -> $crate::impls::DoubleEncoded<()> {
|
||||
use $crate::impls::{Chain, Encode};
|
||||
|
||||
<Self as Chain>::RuntimeCall::Assets($crate::impls::pallet_assets::Call::<
|
||||
<Self as Chain>::Runtime,
|
||||
$crate::impls::pallet_assets::Instance1,
|
||||
>::create {
|
||||
id: asset_id.into(),
|
||||
min_balance,
|
||||
admin: admin.into(),
|
||||
})
|
||||
.encode()
|
||||
.into()
|
||||
}
|
||||
|
||||
/// Returns the encoded call for `create` from the foreign assets pallet
|
||||
pub fn create_foreign_asset_call(
|
||||
asset_id: $crate::impls::v3::Location,
|
||||
min_balance: $crate::impls::Balance,
|
||||
admin: $crate::impls::AccountId,
|
||||
) -> $crate::impls::DoubleEncoded<()> {
|
||||
use $crate::impls::{Chain, Encode};
|
||||
|
||||
<Self as Chain>::RuntimeCall::ForeignAssets($crate::impls::pallet_assets::Call::<
|
||||
<Self as Chain>::Runtime,
|
||||
$crate::impls::pallet_assets::Instance2,
|
||||
>::create {
|
||||
id: asset_id.into(),
|
||||
min_balance,
|
||||
admin: admin.into(),
|
||||
})
|
||||
.encode()
|
||||
.into()
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -21,17 +21,19 @@ pub use xcm_emulator;
|
||||
|
||||
// Substrate
|
||||
use beefy_primitives::ecdsa_crypto::AuthorityId as BeefyId;
|
||||
use frame_support::parameter_types;
|
||||
use grandpa::AuthorityId as GrandpaId;
|
||||
use sp_authority_discovery::AuthorityId as AuthorityDiscoveryId;
|
||||
use sp_consensus_babe::AuthorityId as BabeId;
|
||||
use sp_core::{sr25519, storage::Storage, Pair, Public};
|
||||
use sp_runtime::{
|
||||
traits::{IdentifyAccount, Verify},
|
||||
traits::{AccountIdConversion, IdentifyAccount, Verify},
|
||||
BuildStorage, MultiSignature,
|
||||
};
|
||||
|
||||
// Polakdot
|
||||
use parachains_common::BlockNumber;
|
||||
use polkadot_parachain_primitives::primitives::Sibling;
|
||||
use polkadot_runtime_parachains::configuration::HostConfiguration;
|
||||
|
||||
// Cumulus
|
||||
@@ -49,6 +51,25 @@ pub const SAFE_XCM_VERSION: u32 = xcm::prelude::XCM_VERSION;
|
||||
|
||||
type AccountPublic = <MultiSignature as Verify>::Signer;
|
||||
|
||||
// This asset is added to AH as Asset and reserved transfer between Parachain and AH
|
||||
pub const RESERVABLE_ASSET_ID: u32 = 1;
|
||||
// This asset is added to AH as ForeignAsset and teleported between Penpal and AH
|
||||
pub const TELEPORTABLE_ASSET_ID: u32 = 2;
|
||||
|
||||
pub const PENPAL_ID: u32 = 2000;
|
||||
pub const ASSETS_PALLET_ID: u8 = 50;
|
||||
|
||||
parameter_types! {
|
||||
pub PenpalTeleportableAssetLocation: xcm::v3::Location
|
||||
= xcm::v3::Location::new(1, [
|
||||
xcm::v3::Junction::Parachain(PENPAL_ID),
|
||||
xcm::v3::Junction::PalletInstance(ASSETS_PALLET_ID),
|
||||
xcm::v3::Junction::GeneralIndex(TELEPORTABLE_ASSET_ID.into()),
|
||||
]
|
||||
);
|
||||
pub PenpalSiblingSovereigAccount: AccountId = Sibling::from(PENPAL_ID).into_account_truncating();
|
||||
}
|
||||
|
||||
/// Helper function to generate a crypto pair from seed
|
||||
pub fn get_from_seed<TPublic: Public>(seed: &str) -> <TPublic::Pair as Pair>::Public {
|
||||
TPublic::Pair::from_string(&format!("//{}", seed), None)
|
||||
|
||||
@@ -16,16 +16,26 @@
|
||||
pub use paste;
|
||||
|
||||
// Substrate
|
||||
pub use frame_support::{pallet_prelude::Weight, weights::WeightToFee};
|
||||
pub use pallet_assets;
|
||||
pub use pallet_balances;
|
||||
pub use pallet_message_queue;
|
||||
pub use pallet_xcm;
|
||||
|
||||
// Polkadot
|
||||
pub use xcm::prelude::{AccountId32, WeightLimit};
|
||||
pub use xcm::{
|
||||
prelude::{
|
||||
AccountId32, All, Asset, AssetId, BuyExecution, DepositAsset, ExpectTransactStatus,
|
||||
Fungible, Here, Location, MaybeErrorCode, OriginKind, RefundSurplus, Transact, Unlimited,
|
||||
VersionedXcm, WeightLimit, WithdrawAsset, Xcm,
|
||||
},
|
||||
v3::Location as V3Location,
|
||||
};
|
||||
|
||||
// Cumulus
|
||||
pub use asset_test_utils;
|
||||
pub use cumulus_pallet_xcmp_queue;
|
||||
pub use parachains_common::AccountId;
|
||||
pub use xcm_emulator::Chain;
|
||||
|
||||
#[macro_export]
|
||||
@@ -120,102 +130,3 @@ macro_rules! test_parachain_is_trusted_teleporter {
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! include_penpal_create_foreign_asset_on_asset_hub {
|
||||
( $penpal:ident, $asset_hub:ident, $relay_ed:expr, $weight_to_fee:expr) => {
|
||||
$crate::impls::paste::paste! {
|
||||
pub fn penpal_create_foreign_asset_on_asset_hub(
|
||||
asset_id_on_penpal: u32,
|
||||
foreign_asset_at_asset_hub: v3::Location,
|
||||
ah_as_seen_by_penpal: Location,
|
||||
is_sufficient: bool,
|
||||
asset_owner: AccountId,
|
||||
prefund_amount: u128,
|
||||
) {
|
||||
use frame_support::weights::WeightToFee;
|
||||
let ah_check_account = $asset_hub::execute_with(|| {
|
||||
<$asset_hub as [<$asset_hub Pallet>]>::PolkadotXcm::check_account()
|
||||
});
|
||||
let penpal_check_account =
|
||||
$penpal::execute_with(|| <$penpal as [<$penpal Pallet>]>::PolkadotXcm::check_account());
|
||||
let penpal_as_seen_by_ah = $asset_hub::sibling_location_of($penpal::para_id());
|
||||
|
||||
// prefund SA of Penpal on AssetHub with enough native tokens to pay for creating
|
||||
// new foreign asset, also prefund CheckingAccount with ED, because teleported asset
|
||||
// itself might not be sufficient and CheckingAccount cannot be created otherwise
|
||||
let sov_penpal_on_ah = $asset_hub::sovereign_account_id_of(penpal_as_seen_by_ah.clone());
|
||||
$asset_hub::fund_accounts(vec![
|
||||
(sov_penpal_on_ah.clone().into(), $relay_ed * 100_000_000_000),
|
||||
(ah_check_account.clone().into(), $relay_ed * 1000),
|
||||
]);
|
||||
|
||||
// prefund SA of AssetHub on Penpal with native asset
|
||||
let sov_ah_on_penpal = $penpal::sovereign_account_id_of(ah_as_seen_by_penpal.clone());
|
||||
$penpal::fund_accounts(vec![
|
||||
(sov_ah_on_penpal.into(), $relay_ed * 1_000_000_000),
|
||||
(penpal_check_account.clone().into(), $relay_ed * 1000),
|
||||
]);
|
||||
|
||||
// Force create asset on $penpal and prefund [<$penpal Sender>]
|
||||
$penpal::force_create_and_mint_asset(
|
||||
asset_id_on_penpal,
|
||||
ASSET_MIN_BALANCE,
|
||||
is_sufficient,
|
||||
asset_owner,
|
||||
None,
|
||||
prefund_amount,
|
||||
);
|
||||
|
||||
let require_weight_at_most = Weight::from_parts(1_100_000_000_000, 30_000);
|
||||
// `OriginKind::Xcm` required by ForeignCreators pallet-assets origin filter
|
||||
let origin_kind = OriginKind::Xcm;
|
||||
let call_create_foreign_assets =
|
||||
<$asset_hub as Chain>::RuntimeCall::ForeignAssets(pallet_assets::Call::<
|
||||
<$asset_hub as Chain>::Runtime,
|
||||
pallet_assets::Instance2,
|
||||
>::create {
|
||||
id: foreign_asset_at_asset_hub,
|
||||
min_balance: ASSET_MIN_BALANCE,
|
||||
admin: sov_penpal_on_ah.into(),
|
||||
})
|
||||
.encode();
|
||||
let buy_execution_fee_amount = $weight_to_fee::weight_to_fee(
|
||||
&Weight::from_parts(10_100_000_000_000, 300_000),
|
||||
);
|
||||
let buy_execution_fee = Asset {
|
||||
id: AssetId(Location { parents: 1, interior: Here }),
|
||||
fun: Fungible(buy_execution_fee_amount),
|
||||
};
|
||||
let xcm = VersionedXcm::from(Xcm(vec![
|
||||
WithdrawAsset { 0: vec![buy_execution_fee.clone()].into() },
|
||||
BuyExecution { fees: buy_execution_fee.clone(), weight_limit: Unlimited },
|
||||
Transact { require_weight_at_most, origin_kind, call: call_create_foreign_assets.into() },
|
||||
ExpectTransactStatus(MaybeErrorCode::Success),
|
||||
RefundSurplus,
|
||||
DepositAsset { assets: All.into(), beneficiary: penpal_as_seen_by_ah },
|
||||
]));
|
||||
// Send XCM message from penpal => asset_hub
|
||||
let sudo_penpal_origin = <$penpal as Chain>::RuntimeOrigin::root();
|
||||
$penpal::execute_with(|| {
|
||||
assert_ok!(<$penpal as [<$penpal Pallet>]>::PolkadotXcm::send(
|
||||
sudo_penpal_origin.clone(),
|
||||
bx!(ah_as_seen_by_penpal.into()),
|
||||
bx!(xcm),
|
||||
));
|
||||
type RuntimeEvent = <$penpal as Chain>::RuntimeEvent;
|
||||
assert_expected_events!(
|
||||
$penpal,
|
||||
vec![
|
||||
RuntimeEvent::PolkadotXcm(pallet_xcm::Event::Sent { .. }) => {},
|
||||
]
|
||||
);
|
||||
});
|
||||
$asset_hub::execute_with(|| {
|
||||
type ForeignAssets = <$asset_hub as [<$asset_hub Pallet>]>::ForeignAssets;
|
||||
assert!(ForeignAssets::asset_exists(foreign_asset_at_asset_hub));
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -34,5 +34,6 @@ parachains-common = { path = "../../../../../../parachains/common" }
|
||||
cumulus-pallet-parachain-system = { path = "../../../../../../pallets/parachain-system", default-features = false }
|
||||
testnet-parachains-constants = { path = "../../../../../runtimes/constants", features = ["rococo"] }
|
||||
asset-hub-rococo-runtime = { path = "../../../../../runtimes/assets/asset-hub-rococo" }
|
||||
penpal-runtime = { path = "../../../../../runtimes/testing/penpal" }
|
||||
emulated-integration-tests-common = { path = "../../../common", default-features = false }
|
||||
rococo-system-emulated-network = { path = "../../../networks/rococo-system" }
|
||||
|
||||
+52
-32
@@ -13,39 +13,45 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
pub use codec::Encode;
|
||||
#[cfg(test)]
|
||||
mod imports {
|
||||
pub use codec::Encode;
|
||||
|
||||
// Substrate
|
||||
pub use frame_support::{
|
||||
// Substrate
|
||||
pub use frame_support::{
|
||||
assert_err, assert_ok,
|
||||
pallet_prelude::Weight,
|
||||
sp_runtime::{AccountId32, DispatchError, DispatchResult},
|
||||
sp_runtime::{DispatchError, DispatchResult, ModuleError},
|
||||
traits::fungibles::Inspect,
|
||||
};
|
||||
};
|
||||
|
||||
// Polkadot
|
||||
pub use xcm::{
|
||||
// Polkadot
|
||||
pub use xcm::{
|
||||
prelude::{AccountId32 as AccountId32Junction, *},
|
||||
v3::{self, Error, NetworkId::Rococo as RococoId},
|
||||
};
|
||||
v3,
|
||||
};
|
||||
|
||||
// Cumulus
|
||||
pub use asset_test_utils::xcm_helpers;
|
||||
pub use emulated_integration_tests_common::{
|
||||
// Cumulus
|
||||
pub use asset_test_utils::xcm_helpers;
|
||||
pub use emulated_integration_tests_common::{
|
||||
test_parachain_is_trusted_teleporter,
|
||||
xcm_emulator::{
|
||||
assert_expected_events, bx, helpers::weight_within_threshold, Chain, Parachain as Para,
|
||||
RelayChain as Relay, Test, TestArgs, TestContext, TestExt,
|
||||
assert_expected_events, bx, Chain, Parachain as Para, RelayChain as Relay, Test,
|
||||
TestArgs, TestContext, TestExt,
|
||||
},
|
||||
xcm_helpers::{xcm_transact_paid_execution, xcm_transact_unpaid_execution},
|
||||
PROOF_SIZE_THRESHOLD, REF_TIME_THRESHOLD, XCM_V3,
|
||||
};
|
||||
pub use parachains_common::{AccountId, Balance};
|
||||
pub use rococo_system_emulated_network::{
|
||||
xcm_helpers::{non_fee_asset, xcm_transact_paid_execution},
|
||||
ASSETS_PALLET_ID, RESERVABLE_ASSET_ID, XCM_V3,
|
||||
};
|
||||
pub use parachains_common::Balance;
|
||||
pub use rococo_system_emulated_network::{
|
||||
asset_hub_rococo_emulated_chain::{
|
||||
genesis::ED as ASSET_HUB_ROCOCO_ED, AssetHubRococoParaPallet as AssetHubRococoPallet,
|
||||
genesis::{AssetHubRococoAssetOwner, ED as ASSET_HUB_ROCOCO_ED},
|
||||
AssetHubRococoParaPallet as AssetHubRococoPallet,
|
||||
},
|
||||
penpal_emulated_chain::{
|
||||
PenpalAParaPallet as PenpalAPallet, PenpalAssetOwner,
|
||||
PenpalBParaPallet as PenpalBPallet, ED as PENPAL_ED,
|
||||
},
|
||||
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, BridgeHubRococoPara as BridgeHubRococo,
|
||||
@@ -53,19 +59,33 @@ pub use rococo_system_emulated_network::{
|
||||
PenpalAParaReceiver as PenpalAReceiver, PenpalAParaSender as PenpalASender,
|
||||
PenpalBPara as PenpalB, PenpalBParaReceiver as PenpalBReceiver, RococoRelay as Rococo,
|
||||
RococoRelayReceiver as RococoReceiver, RococoRelaySender as RococoSender,
|
||||
};
|
||||
};
|
||||
|
||||
pub const ASSET_ID: u32 = 1;
|
||||
pub const ASSET_MIN_BALANCE: u128 = 1000;
|
||||
// `Assets` pallet index
|
||||
pub const ASSETS_PALLET_ID: u8 = 50;
|
||||
// Runtimes
|
||||
pub use asset_hub_rococo_runtime::xcm_config::{
|
||||
TokenLocation as RelayLocation, UniversalLocation as AssetHubRococoUniversalLocation,
|
||||
XcmConfig as AssetHubRococoXcmConfig,
|
||||
};
|
||||
pub use penpal_runtime::xcm_config::{
|
||||
LocalReservableFromAssetHub as PenpalLocalReservableFromAssetHub,
|
||||
LocalTeleportableToAssetHub as PenpalLocalTeleportableToAssetHub,
|
||||
UniversalLocation as PenpalUniversalLocation, XcmConfig as PenpalRococoXcmConfig,
|
||||
};
|
||||
pub use rococo_runtime::xcm_config::{
|
||||
UniversalLocation as RococoUniversalLocation, XcmConfig as RococoXcmConfig,
|
||||
};
|
||||
|
||||
pub type RelayToSystemParaTest = Test<Rococo, AssetHubRococo>;
|
||||
pub type RelayToParaTest = Test<Rococo, PenpalA>;
|
||||
pub type SystemParaToRelayTest = Test<AssetHubRococo, Rococo>;
|
||||
pub type SystemParaToParaTest = Test<AssetHubRococo, PenpalA>;
|
||||
pub type ParaToSystemParaTest = Test<PenpalA, AssetHubRococo>;
|
||||
pub type ParaToParaTest = Test<PenpalA, PenpalB, Rococo>;
|
||||
pub const ASSET_ID: u32 = 3;
|
||||
pub const ASSET_MIN_BALANCE: u128 = 1000;
|
||||
|
||||
pub type RelayToSystemParaTest = Test<Rococo, AssetHubRococo>;
|
||||
pub type RelayToParaTest = Test<Rococo, PenpalA>;
|
||||
pub type ParaToRelayTest = Test<PenpalA, Rococo>;
|
||||
pub type SystemParaToRelayTest = Test<AssetHubRococo, Rococo>;
|
||||
pub type SystemParaToParaTest = Test<AssetHubRococo, PenpalA>;
|
||||
pub type ParaToSystemParaTest = Test<PenpalA, AssetHubRococo>;
|
||||
pub type ParaToParaThroughRelayTest = Test<PenpalA, PenpalB, Rococo>;
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
|
||||
-8
@@ -18,11 +18,3 @@ mod send;
|
||||
mod set_xcm_versions;
|
||||
mod swap;
|
||||
mod teleport;
|
||||
|
||||
use crate::*;
|
||||
emulated_integration_tests_common::include_penpal_create_foreign_asset_on_asset_hub!(
|
||||
PenpalA,
|
||||
AssetHubRococo,
|
||||
ROCOCO_ED,
|
||||
testnet_parachains_constants::rococo::fee::WeightToFee
|
||||
);
|
||||
|
||||
+678
-153
File diff suppressed because it is too large
Load Diff
+119
-26
@@ -13,7 +13,7 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
use crate::*;
|
||||
use crate::imports::*;
|
||||
|
||||
/// Relay Chain should be able to execute `Transact` instructions in System Parachain
|
||||
/// when `OriginKind::Superuser`.
|
||||
@@ -28,47 +28,52 @@ fn send_transact_as_superuser_from_relay_to_system_para_works() {
|
||||
)
|
||||
}
|
||||
|
||||
/// Parachain should be able to send XCM paying its fee with sufficient asset
|
||||
/// in the System Parachain
|
||||
/// We tests two things here:
|
||||
/// - Parachain should be able to send XCM paying its fee with system asset in the System Parachain
|
||||
/// - Parachain should be able to create a new Foreign Asset in the System Parachain
|
||||
#[test]
|
||||
fn send_xcm_from_para_to_system_para_paying_fee_with_assets_works() {
|
||||
fn send_xcm_from_para_to_system_para_paying_fee_with_system_assets_works() {
|
||||
let para_sovereign_account = AssetHubRococo::sovereign_account_id_of(
|
||||
AssetHubRococo::sibling_location_of(PenpalA::para_id()),
|
||||
);
|
||||
let asset_location_on_penpal = v3::Location::new(
|
||||
0,
|
||||
[
|
||||
v3::Junction::PalletInstance(ASSETS_PALLET_ID),
|
||||
v3::Junction::GeneralIndex(ASSET_ID.into()),
|
||||
],
|
||||
);
|
||||
let foreign_asset_at_asset_hub =
|
||||
v3::Location::new(1, [v3::Junction::Parachain(PenpalA::para_id().into())])
|
||||
.appended_with(asset_location_on_penpal)
|
||||
.unwrap();
|
||||
|
||||
// Force create and mint assets for Parachain's sovereign account
|
||||
AssetHubRococo::force_create_and_mint_asset(
|
||||
ASSET_ID,
|
||||
// Encoded `create_asset` call to be executed in AssetHub
|
||||
let call = AssetHubRococo::create_foreign_asset_call(
|
||||
foreign_asset_at_asset_hub,
|
||||
ASSET_MIN_BALANCE,
|
||||
true,
|
||||
para_sovereign_account.clone(),
|
||||
Some(Weight::from_parts(1_019_445_000, 200_000)),
|
||||
ASSET_MIN_BALANCE * 1000000000,
|
||||
);
|
||||
|
||||
// We just need a call that can pass the `SafeCallFilter`
|
||||
// Call values are not relevant
|
||||
let call = AssetHubRococo::force_create_asset_call(
|
||||
ASSET_ID,
|
||||
para_sovereign_account.clone(),
|
||||
true,
|
||||
ASSET_MIN_BALANCE,
|
||||
);
|
||||
|
||||
let origin_kind = OriginKind::SovereignAccount;
|
||||
let fee_amount = ASSET_MIN_BALANCE * 1000000;
|
||||
let native_asset =
|
||||
([PalletInstance(ASSETS_PALLET_ID), GeneralIndex(ASSET_ID.into())], fee_amount).into();
|
||||
let origin_kind = OriginKind::Xcm;
|
||||
let fee_amount = ASSET_HUB_ROCOCO_ED * 1000000;
|
||||
let system_asset = (Parent, fee_amount).into();
|
||||
|
||||
let root_origin = <PenpalA as Chain>::RuntimeOrigin::root();
|
||||
let system_para_destination = PenpalA::sibling_location_of(AssetHubRococo::para_id()).into();
|
||||
let xcm = xcm_transact_paid_execution(
|
||||
call,
|
||||
origin_kind,
|
||||
native_asset,
|
||||
system_asset,
|
||||
para_sovereign_account.clone(),
|
||||
);
|
||||
|
||||
// SA-of-Penpal-on-AHR needs to have balance to pay for fees and asset creation deposit
|
||||
AssetHubRococo::fund_accounts(vec![(
|
||||
para_sovereign_account.clone().into(),
|
||||
ASSET_HUB_ROCOCO_ED * 10000000000,
|
||||
)]);
|
||||
|
||||
PenpalA::execute_with(|| {
|
||||
assert_ok!(<PenpalA as PenpalAPallet>::PolkadotXcm::send(
|
||||
root_origin,
|
||||
@@ -90,13 +95,101 @@ fn send_xcm_from_para_to_system_para_paying_fee_with_assets_works() {
|
||||
assert_expected_events!(
|
||||
AssetHubRococo,
|
||||
vec![
|
||||
// Burned the fee
|
||||
RuntimeEvent::Balances(pallet_balances::Event::Burned { who, amount }) => {
|
||||
who: *who == para_sovereign_account,
|
||||
amount: *amount == fee_amount,
|
||||
},
|
||||
// Foreign Asset created
|
||||
RuntimeEvent::ForeignAssets(pallet_assets::Event::Created { asset_id, creator, owner }) => {
|
||||
asset_id: *asset_id == foreign_asset_at_asset_hub,
|
||||
creator: *creator == para_sovereign_account.clone(),
|
||||
owner: *owner == para_sovereign_account,
|
||||
},
|
||||
]
|
||||
);
|
||||
|
||||
type ForeignAssets = <AssetHubRococo as AssetHubRococoPallet>::ForeignAssets;
|
||||
assert!(ForeignAssets::asset_exists(foreign_asset_at_asset_hub));
|
||||
});
|
||||
}
|
||||
|
||||
/// We tests two things here:
|
||||
/// - Parachain should be able to send XCM paying its fee with system assets in the System Parachain
|
||||
/// - Parachain should be able to create a new Asset in the System Parachain
|
||||
#[test]
|
||||
fn send_xcm_from_para_to_system_para_paying_fee_with_assets_works() {
|
||||
let para_sovereign_account = AssetHubRococo::sovereign_account_id_of(
|
||||
AssetHubRococo::sibling_location_of(PenpalA::para_id()),
|
||||
);
|
||||
|
||||
// Force create and mint assets for Parachain's sovereign account
|
||||
AssetHubRococo::force_create_and_mint_asset(
|
||||
ASSET_ID,
|
||||
ASSET_MIN_BALANCE,
|
||||
true,
|
||||
para_sovereign_account.clone(),
|
||||
Some(Weight::from_parts(1_019_445_000, 200_000)),
|
||||
ASSET_MIN_BALANCE * 1000000000,
|
||||
);
|
||||
|
||||
// Just a different `asset_id`` that does not exist yet
|
||||
let new_asset_id = ASSET_ID + 1;
|
||||
|
||||
// Encoded `create_asset` call to be executed in AssetHub
|
||||
let call = AssetHubRococo::create_asset_call(
|
||||
new_asset_id,
|
||||
ASSET_MIN_BALANCE,
|
||||
para_sovereign_account.clone(),
|
||||
);
|
||||
|
||||
let origin_kind = OriginKind::SovereignAccount;
|
||||
let fee_amount = ASSET_MIN_BALANCE * 1000000;
|
||||
let asset =
|
||||
([PalletInstance(ASSETS_PALLET_ID), GeneralIndex(ASSET_ID.into())], fee_amount).into();
|
||||
|
||||
let root_origin = <PenpalA as Chain>::RuntimeOrigin::root();
|
||||
let system_para_destination = PenpalA::sibling_location_of(AssetHubRococo::para_id()).into();
|
||||
let xcm = xcm_transact_paid_execution(call, origin_kind, asset, para_sovereign_account.clone());
|
||||
|
||||
// SA-of-Penpal-on-AHR needs to have balance to pay for asset creation deposit
|
||||
AssetHubRococo::fund_accounts(vec![(
|
||||
para_sovereign_account.clone().into(),
|
||||
ASSET_HUB_ROCOCO_ED * 10000000000,
|
||||
)]);
|
||||
|
||||
PenpalA::execute_with(|| {
|
||||
assert_ok!(<PenpalA as PenpalAPallet>::PolkadotXcm::send(
|
||||
root_origin,
|
||||
bx!(system_para_destination),
|
||||
bx!(xcm),
|
||||
));
|
||||
|
||||
PenpalA::assert_xcm_pallet_sent();
|
||||
});
|
||||
|
||||
AssetHubRococo::execute_with(|| {
|
||||
type RuntimeEvent = <AssetHubRococo as Chain>::RuntimeEvent;
|
||||
|
||||
AssetHubRococo::assert_xcmp_queue_success(Some(Weight::from_parts(
|
||||
15_594_564_000,
|
||||
562_893,
|
||||
)));
|
||||
|
||||
assert_expected_events!(
|
||||
AssetHubRococo,
|
||||
vec![
|
||||
// Burned the fee
|
||||
RuntimeEvent::Assets(pallet_assets::Event::Burned { asset_id, owner, balance }) => {
|
||||
asset_id: *asset_id == ASSET_ID,
|
||||
owner: *owner == para_sovereign_account,
|
||||
balance: *balance == fee_amount,
|
||||
},
|
||||
RuntimeEvent::Assets(pallet_assets::Event::Issued { asset_id, .. }) => {
|
||||
asset_id: *asset_id == ASSET_ID,
|
||||
// Asset created
|
||||
RuntimeEvent::Assets(pallet_assets::Event::Created { asset_id, creator, owner }) => {
|
||||
asset_id: *asset_id == new_asset_id,
|
||||
creator: *creator == para_sovereign_account.clone(),
|
||||
owner: *owner == para_sovereign_account,
|
||||
},
|
||||
]
|
||||
);
|
||||
|
||||
+1
-1
@@ -13,7 +13,7 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
use crate::*;
|
||||
use crate::imports::*;
|
||||
|
||||
#[test]
|
||||
fn relay_sets_system_para_xcm_supported_version() {
|
||||
|
||||
+23
-35
@@ -13,9 +13,7 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
use crate::*;
|
||||
use rococo_system_emulated_network::penpal_emulated_chain::LocalTeleportableToAssetHubV3 as PenpalLocalTeleportableToAssetHubV3;
|
||||
use sp_runtime::ModuleError;
|
||||
use crate::imports::*;
|
||||
|
||||
#[test]
|
||||
fn swap_locally_on_chain_using_local_assets() {
|
||||
@@ -114,49 +112,39 @@ fn swap_locally_on_chain_using_local_assets() {
|
||||
|
||||
#[test]
|
||||
fn swap_locally_on_chain_using_foreign_assets() {
|
||||
let asset_native = Box::new(asset_hub_rococo_runtime::xcm_config::TokenLocationV3::get());
|
||||
let ah_as_seen_by_penpal = PenpalA::sibling_location_of(AssetHubRococo::para_id());
|
||||
let asset_location_on_penpal = PenpalLocalTeleportableToAssetHubV3::get();
|
||||
let asset_id_on_penpal = match asset_location_on_penpal.last() {
|
||||
Some(v3::Junction::GeneralIndex(id)) => *id as u32,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
let asset_owner_on_penpal = PenpalASender::get();
|
||||
let asset_native =
|
||||
Box::new(v3::Location::try_from(RelayLocation::get()).expect("conversion works"));
|
||||
let asset_location_on_penpal =
|
||||
v3::Location::try_from(PenpalLocalTeleportableToAssetHub::get()).expect("conversion works");
|
||||
let foreign_asset_at_asset_hub_rococo =
|
||||
v3::Location::new(1, [v3::Junction::Parachain(PenpalA::para_id().into())])
|
||||
.appended_with(asset_location_on_penpal)
|
||||
.unwrap();
|
||||
|
||||
// 1. Create asset on penpal and, 2. Create foreign asset on asset_hub_rococo
|
||||
super::penpal_create_foreign_asset_on_asset_hub(
|
||||
asset_id_on_penpal,
|
||||
foreign_asset_at_asset_hub_rococo,
|
||||
ah_as_seen_by_penpal,
|
||||
true,
|
||||
asset_owner_on_penpal,
|
||||
ASSET_MIN_BALANCE * 1_000_000,
|
||||
);
|
||||
|
||||
let penpal_as_seen_by_ah = AssetHubRococo::sibling_location_of(PenpalA::para_id());
|
||||
let sov_penpal_on_ahr = AssetHubRococo::sovereign_account_id_of(penpal_as_seen_by_ah);
|
||||
AssetHubRococo::fund_accounts(vec![
|
||||
(AssetHubRococoSender::get().into(), 5_000_000 * ROCOCO_ED), /* An account to swap dot
|
||||
* for something else. */
|
||||
// An account to swap dot for something else.
|
||||
(AssetHubRococoSender::get().into(), 5_000_000 * ASSET_HUB_ROCOCO_ED),
|
||||
// Penpal's sovereign account in AH should have some balance
|
||||
(sov_penpal_on_ahr.clone().into(), 100_000_000 * ASSET_HUB_ROCOCO_ED),
|
||||
]);
|
||||
|
||||
AssetHubRococo::execute_with(|| {
|
||||
// 3: Mint foreign asset on asset_hub_rococo:
|
||||
// 0: No need to create foreign asset as it exists in genesis.
|
||||
//
|
||||
// 1: Mint foreign asset on asset_hub_rococo:
|
||||
//
|
||||
// (While it might be nice to use batch,
|
||||
// currently that's disabled due to safe call filters.)
|
||||
|
||||
type RuntimeEvent = <AssetHubRococo as Chain>::RuntimeEvent;
|
||||
// 3. Mint foreign asset (in reality this should be a teleport or some such)
|
||||
// 1. Mint foreign asset (in reality this should be a teleport or some such)
|
||||
assert_ok!(<AssetHubRococo as AssetHubRococoPallet>::ForeignAssets::mint(
|
||||
<AssetHubRococo as Chain>::RuntimeOrigin::signed(sov_penpal_on_ahr.clone().into()),
|
||||
foreign_asset_at_asset_hub_rococo,
|
||||
sov_penpal_on_ahr.clone().into(),
|
||||
3_000_000_000_000,
|
||||
ASSET_HUB_ROCOCO_ED * 3_000_000_000_000,
|
||||
));
|
||||
|
||||
assert_expected_events!(
|
||||
@@ -166,7 +154,7 @@ fn swap_locally_on_chain_using_foreign_assets() {
|
||||
]
|
||||
);
|
||||
|
||||
// 4. Create pool:
|
||||
// 2. Create pool:
|
||||
assert_ok!(<AssetHubRococo as AssetHubRococoPallet>::AssetConversion::create_pool(
|
||||
<AssetHubRococo as Chain>::RuntimeOrigin::signed(AssetHubRococoSender::get()),
|
||||
asset_native.clone(),
|
||||
@@ -180,7 +168,7 @@ fn swap_locally_on_chain_using_foreign_assets() {
|
||||
]
|
||||
);
|
||||
|
||||
// 5. Add liquidity:
|
||||
// 3. Add liquidity:
|
||||
assert_ok!(<AssetHubRococo as AssetHubRococoPallet>::AssetConversion::add_liquidity(
|
||||
<AssetHubRococo as Chain>::RuntimeOrigin::signed(sov_penpal_on_ahr.clone()),
|
||||
asset_native.clone(),
|
||||
@@ -201,15 +189,15 @@ fn swap_locally_on_chain_using_foreign_assets() {
|
||||
]
|
||||
);
|
||||
|
||||
// 6. Swap!
|
||||
// 4. Swap!
|
||||
let path = vec![asset_native.clone(), Box::new(foreign_asset_at_asset_hub_rococo)];
|
||||
|
||||
assert_ok!(
|
||||
<AssetHubRococo as AssetHubRococoPallet>::AssetConversion::swap_exact_tokens_for_tokens(
|
||||
<AssetHubRococo as Chain>::RuntimeOrigin::signed(AssetHubRococoSender::get()),
|
||||
path,
|
||||
100000,
|
||||
1000,
|
||||
100000 * ASSET_HUB_ROCOCO_ED,
|
||||
1000 * ASSET_HUB_ROCOCO_ED,
|
||||
AssetHubRococoSender::get().into(),
|
||||
true
|
||||
)
|
||||
@@ -219,18 +207,18 @@ fn swap_locally_on_chain_using_foreign_assets() {
|
||||
AssetHubRococo,
|
||||
vec![
|
||||
RuntimeEvent::AssetConversion(pallet_asset_conversion::Event::SwapExecuted { amount_in, amount_out, .. },) => {
|
||||
amount_in: *amount_in == 100000,
|
||||
amount_out: *amount_out == 199399,
|
||||
amount_in: *amount_in == 333333300000,
|
||||
amount_out: *amount_out == 498874118173,
|
||||
},
|
||||
]
|
||||
);
|
||||
|
||||
// 7. Remove liquidity
|
||||
// 5. Remove liquidity
|
||||
assert_ok!(<AssetHubRococo as AssetHubRococoPallet>::AssetConversion::remove_liquidity(
|
||||
<AssetHubRococo as Chain>::RuntimeOrigin::signed(sov_penpal_on_ahr.clone()),
|
||||
asset_native.clone(),
|
||||
Box::new(foreign_asset_at_asset_hub_rococo),
|
||||
1414213562273 - 2_000_000_000, // all but the 2 EDs can't be retrieved.
|
||||
1414213562273 - ASSET_HUB_ROCOCO_ED * 2, // all but the 2 EDs can't be retrieved.
|
||||
0,
|
||||
0,
|
||||
sov_penpal_on_ahr.clone().into(),
|
||||
|
||||
+93
-42
@@ -13,11 +13,7 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
use crate::*;
|
||||
use asset_hub_rococo_runtime::xcm_config::XcmConfig as AssetHubRococoXcmConfig;
|
||||
use emulated_integration_tests_common::xcm_helpers::non_fee_asset;
|
||||
use rococo_runtime::xcm_config::XcmConfig as RococoXcmConfig;
|
||||
use rococo_system_emulated_network::penpal_emulated_chain::LocalTeleportableToAssetHubV3 as PenpalLocalTeleportableToAssetHubV3;
|
||||
use crate::imports::*;
|
||||
|
||||
fn relay_origin_assertions(t: RelayToSystemParaTest) {
|
||||
type RuntimeEvent = <Rococo as Chain>::RuntimeEvent;
|
||||
@@ -114,18 +110,21 @@ fn para_dest_assertions(t: RelayToSystemParaTest) {
|
||||
|
||||
fn penpal_to_ah_foreign_assets_sender_assertions(t: ParaToSystemParaTest) {
|
||||
type RuntimeEvent = <PenpalA as Chain>::RuntimeEvent;
|
||||
PenpalA::assert_xcm_pallet_attempted_complete(None);
|
||||
let system_para_native_asset_location =
|
||||
v3::Location::try_from(RelayLocation::get()).expect("conversion works");
|
||||
let expected_asset_id = t.args.asset_id.unwrap();
|
||||
let (_, expected_asset_amount) =
|
||||
non_fee_asset(&t.args.assets, t.args.fee_asset_item as usize).unwrap();
|
||||
|
||||
PenpalA::assert_xcm_pallet_attempted_complete(None);
|
||||
assert_expected_events!(
|
||||
PenpalA,
|
||||
vec![
|
||||
RuntimeEvent::Balances(
|
||||
pallet_balances::Event::Burned { who, amount }
|
||||
RuntimeEvent::ForeignAssets(
|
||||
pallet_assets::Event::Burned { asset_id, owner, .. }
|
||||
) => {
|
||||
who: *who == t.sender.account_id,
|
||||
amount: *amount == t.args.amount,
|
||||
asset_id: *asset_id == system_para_native_asset_location,
|
||||
owner: *owner == t.sender.account_id,
|
||||
},
|
||||
RuntimeEvent::Assets(pallet_assets::Event::Burned { asset_id, owner, balance }) => {
|
||||
asset_id: *asset_id == expected_asset_id,
|
||||
@@ -144,6 +143,9 @@ fn penpal_to_ah_foreign_assets_receiver_assertions(t: ParaToSystemParaTest) {
|
||||
let (expected_foreign_asset_id, expected_foreign_asset_amount) =
|
||||
non_fee_asset(&t.args.assets, t.args.fee_asset_item as usize).unwrap();
|
||||
let expected_foreign_asset_id_v3: v3::Location = expected_foreign_asset_id.try_into().unwrap();
|
||||
|
||||
AssetHubRococo::assert_xcmp_queue_success(None);
|
||||
|
||||
assert_expected_events!(
|
||||
AssetHubRococo,
|
||||
vec![
|
||||
@@ -163,9 +165,6 @@ fn penpal_to_ah_foreign_assets_receiver_assertions(t: ParaToSystemParaTest) {
|
||||
amount: *amount == expected_foreign_asset_amount,
|
||||
},
|
||||
RuntimeEvent::Balances(pallet_balances::Event::Deposit { .. }) => {},
|
||||
RuntimeEvent::MessageQueue(
|
||||
pallet_message_queue::Event::Processed { success: true, .. }
|
||||
) => {},
|
||||
]
|
||||
);
|
||||
}
|
||||
@@ -205,6 +204,11 @@ fn ah_to_penpal_foreign_assets_receiver_assertions(t: SystemParaToParaTest) {
|
||||
let (_, expected_asset_amount) =
|
||||
non_fee_asset(&t.args.assets, t.args.fee_asset_item as usize).unwrap();
|
||||
let checking_account = <PenpalA as PenpalAPallet>::PolkadotXcm::check_account();
|
||||
let system_para_native_asset_location =
|
||||
v3::Location::try_from(RelayLocation::get()).expect("conversion works");
|
||||
|
||||
PenpalA::assert_xcmp_queue_success(None);
|
||||
|
||||
assert_expected_events!(
|
||||
PenpalA,
|
||||
vec![
|
||||
@@ -221,12 +225,11 @@ fn ah_to_penpal_foreign_assets_receiver_assertions(t: SystemParaToParaTest) {
|
||||
amount: *amount == expected_asset_amount,
|
||||
},
|
||||
// native asset for fee is deposited to receiver
|
||||
RuntimeEvent::Balances(pallet_balances::Event::Minted { who, .. }) => {
|
||||
who: *who == t.receiver.account_id,
|
||||
RuntimeEvent::ForeignAssets(pallet_assets::Event::Issued { asset_id, owner, amount }) => {
|
||||
asset_id: *asset_id == system_para_native_asset_location,
|
||||
owner: *owner == t.receiver.account_id,
|
||||
amount: *amount == expected_asset_amount,
|
||||
},
|
||||
RuntimeEvent::MessageQueue(
|
||||
pallet_message_queue::Event::Processed { success: true, .. }
|
||||
) => {},
|
||||
]
|
||||
);
|
||||
}
|
||||
@@ -558,30 +561,21 @@ fn teleport_to_other_system_parachains_works() {
|
||||
/// (using native reserve-based transfer for fees)
|
||||
#[test]
|
||||
fn bidirectional_teleport_foreign_assets_between_para_and_asset_hub() {
|
||||
let ah_as_seen_by_penpal = PenpalA::sibling_location_of(AssetHubRococo::para_id());
|
||||
let asset_location_on_penpal = PenpalLocalTeleportableToAssetHubV3::get();
|
||||
// Init values for Parachain
|
||||
let fee_amount_to_send: Balance = ASSET_HUB_ROCOCO_ED * 10000;
|
||||
let asset_location_on_penpal =
|
||||
v3::Location::try_from(PenpalLocalTeleportableToAssetHub::get()).expect("conversion works");
|
||||
let asset_id_on_penpal = match asset_location_on_penpal.last() {
|
||||
Some(v3::Junction::GeneralIndex(id)) => *id as u32,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
let asset_owner_on_penpal = PenpalASender::get();
|
||||
let foreign_asset_at_asset_hub_rococo =
|
||||
v3::Location::new(1, [v3::Junction::Parachain(PenpalA::para_id().into())])
|
||||
.appended_with(asset_location_on_penpal)
|
||||
.unwrap();
|
||||
super::penpal_create_foreign_asset_on_asset_hub(
|
||||
asset_id_on_penpal,
|
||||
foreign_asset_at_asset_hub_rococo,
|
||||
ah_as_seen_by_penpal.clone(),
|
||||
false,
|
||||
asset_owner_on_penpal,
|
||||
ASSET_MIN_BALANCE * 1_000_000,
|
||||
);
|
||||
let penpal_to_ah_beneficiary_id = AssetHubRococoReceiver::get();
|
||||
|
||||
let fee_amount_to_send = ASSET_HUB_ROCOCO_ED * 10_000;
|
||||
let asset_amount_to_send = ASSET_MIN_BALANCE * 1000;
|
||||
|
||||
let asset_amount_to_send = ASSET_HUB_ROCOCO_ED * 1000;
|
||||
let asset_owner = PenpalAssetOwner::get();
|
||||
let system_para_native_asset_location =
|
||||
v3::Location::try_from(RelayLocation::get()).expect("conversion works");
|
||||
let sender = PenpalASender::get();
|
||||
let penpal_check_account = <PenpalA as PenpalAPallet>::PolkadotXcm::check_account();
|
||||
let ah_as_seen_by_penpal = PenpalA::sibling_location_of(AssetHubRococo::para_id());
|
||||
let asset_location_on_penpal_latest: Location = asset_location_on_penpal.try_into().unwrap();
|
||||
let penpal_assets: Assets = vec![
|
||||
(Parent, fee_amount_to_send).into(),
|
||||
@@ -594,6 +588,38 @@ fn bidirectional_teleport_foreign_assets_between_para_and_asset_hub() {
|
||||
.position(|r| r == &(Parent, fee_amount_to_send).into())
|
||||
.unwrap() as u32;
|
||||
|
||||
// fund Parachain's sender account
|
||||
PenpalA::mint_foreign_asset(
|
||||
<PenpalA as Chain>::RuntimeOrigin::signed(asset_owner.clone()),
|
||||
system_para_native_asset_location,
|
||||
sender.clone(),
|
||||
fee_amount_to_send,
|
||||
);
|
||||
// No need to create the asset (only mint) as it exists in genesis.
|
||||
PenpalA::mint_asset(
|
||||
<PenpalA as Chain>::RuntimeOrigin::signed(asset_owner.clone()),
|
||||
asset_id_on_penpal,
|
||||
sender.clone(),
|
||||
asset_amount_to_send,
|
||||
);
|
||||
// fund Parachain's check account to be able to teleport
|
||||
PenpalA::fund_accounts(vec![(penpal_check_account.clone().into(), ASSET_HUB_ROCOCO_ED * 1000)]);
|
||||
|
||||
// prefund SA of Penpal on AssetHub with enough native tokens to pay for fees
|
||||
let penpal_as_seen_by_ah = AssetHubRococo::sibling_location_of(PenpalA::para_id());
|
||||
let sov_penpal_on_ah = AssetHubRococo::sovereign_account_id_of(penpal_as_seen_by_ah);
|
||||
AssetHubRococo::fund_accounts(vec![(
|
||||
sov_penpal_on_ah.clone().into(),
|
||||
ASSET_HUB_ROCOCO_ED * 100_000_000_000,
|
||||
)]);
|
||||
|
||||
// Init values for System Parachain
|
||||
let foreign_asset_at_asset_hub_rococo =
|
||||
v3::Location::new(1, [v3::Junction::Parachain(PenpalA::para_id().into())])
|
||||
.appended_with(asset_location_on_penpal)
|
||||
.unwrap();
|
||||
let penpal_to_ah_beneficiary_id = AssetHubRococoReceiver::get();
|
||||
|
||||
// Penpal to AH test args
|
||||
let penpal_to_ah_test_args = TestContext {
|
||||
sender: PenpalASender::get(),
|
||||
@@ -608,8 +634,14 @@ fn bidirectional_teleport_foreign_assets_between_para_and_asset_hub() {
|
||||
),
|
||||
};
|
||||
let mut penpal_to_ah = ParaToSystemParaTest::new(penpal_to_ah_test_args);
|
||||
let penpal_sender_balance_before = PenpalA::execute_with(|| {
|
||||
type ForeignAssets = <PenpalA as PenpalAPallet>::ForeignAssets;
|
||||
<ForeignAssets as Inspect<_>>::balance(
|
||||
system_para_native_asset_location,
|
||||
&PenpalASender::get(),
|
||||
)
|
||||
});
|
||||
|
||||
let penpal_sender_balance_before = penpal_to_ah.sender.balance;
|
||||
let ah_receiver_balance_before = penpal_to_ah.receiver.balance;
|
||||
|
||||
let penpal_sender_assets_before = PenpalA::execute_with(|| {
|
||||
@@ -629,7 +661,14 @@ fn bidirectional_teleport_foreign_assets_between_para_and_asset_hub() {
|
||||
penpal_to_ah.set_dispatchable::<PenpalA>(para_to_system_para_transfer_assets);
|
||||
penpal_to_ah.assert();
|
||||
|
||||
let penpal_sender_balance_after = penpal_to_ah.sender.balance;
|
||||
let penpal_sender_balance_after = PenpalA::execute_with(|| {
|
||||
type ForeignAssets = <PenpalA as PenpalAPallet>::ForeignAssets;
|
||||
<ForeignAssets as Inspect<_>>::balance(
|
||||
system_para_native_asset_location,
|
||||
&PenpalASender::get(),
|
||||
)
|
||||
});
|
||||
|
||||
let ah_receiver_balance_after = penpal_to_ah.receiver.balance;
|
||||
|
||||
let penpal_sender_assets_after = PenpalA::execute_with(|| {
|
||||
@@ -704,7 +743,13 @@ fn bidirectional_teleport_foreign_assets_between_para_and_asset_hub() {
|
||||
let mut ah_to_penpal = SystemParaToParaTest::new(ah_to_penpal_test_args);
|
||||
|
||||
let ah_sender_balance_before = ah_to_penpal.sender.balance;
|
||||
let penpal_receiver_balance_before = ah_to_penpal.receiver.balance;
|
||||
let penpal_receiver_balance_before = PenpalA::execute_with(|| {
|
||||
type ForeignAssets = <PenpalA as PenpalAPallet>::ForeignAssets;
|
||||
<ForeignAssets as Inspect<_>>::balance(
|
||||
system_para_native_asset_location,
|
||||
&PenpalAReceiver::get(),
|
||||
)
|
||||
});
|
||||
|
||||
let ah_sender_assets_before = AssetHubRococo::execute_with(|| {
|
||||
type ForeignAssets = <AssetHubRococo as AssetHubRococoPallet>::ForeignAssets;
|
||||
@@ -724,7 +769,13 @@ fn bidirectional_teleport_foreign_assets_between_para_and_asset_hub() {
|
||||
ah_to_penpal.assert();
|
||||
|
||||
let ah_sender_balance_after = ah_to_penpal.sender.balance;
|
||||
let penpal_receiver_balance_after = ah_to_penpal.receiver.balance;
|
||||
let penpal_receiver_balance_after = PenpalA::execute_with(|| {
|
||||
type ForeignAssets = <PenpalA as PenpalAPallet>::ForeignAssets;
|
||||
<ForeignAssets as Inspect<_>>::balance(
|
||||
system_para_native_asset_location,
|
||||
&PenpalAReceiver::get(),
|
||||
)
|
||||
});
|
||||
|
||||
let ah_sender_assets_after = AssetHubRococo::execute_with(|| {
|
||||
type ForeignAssets = <AssetHubRococo as AssetHubRococoPallet>::ForeignAssets;
|
||||
|
||||
+1
@@ -33,6 +33,7 @@ westend-runtime = { path = "../../../../../../../polkadot/runtime/westend" }
|
||||
# Cumulus
|
||||
parachains-common = { path = "../../../../../../parachains/common" }
|
||||
testnet-parachains-constants = { path = "../../../../../runtimes/constants", features = ["westend"] }
|
||||
penpal-runtime = { path = "../../../../../runtimes/testing/penpal" }
|
||||
asset-hub-westend-runtime = { path = "../../../../../runtimes/assets/asset-hub-westend" }
|
||||
asset-test-utils = { path = "../../../../../runtimes/assets/test-utils" }
|
||||
cumulus-pallet-xcmp-queue = { default-features = false, path = "../../../../../../pallets/xcmp-queue" }
|
||||
|
||||
+59
-43
@@ -13,67 +13,83 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
pub use codec::Encode;
|
||||
#[cfg(test)]
|
||||
mod imports {
|
||||
pub use codec::Encode;
|
||||
|
||||
// Substrate
|
||||
pub use frame_support::{
|
||||
// Substrate
|
||||
pub use frame_support::{
|
||||
assert_err, assert_ok,
|
||||
instances::Instance2,
|
||||
pallet_prelude::Weight,
|
||||
sp_runtime::{AccountId32, DispatchError, DispatchResult, ModuleError},
|
||||
sp_runtime::{DispatchError, DispatchResult, ModuleError},
|
||||
traits::fungibles::Inspect,
|
||||
BoundedVec,
|
||||
};
|
||||
};
|
||||
|
||||
// Polkadot
|
||||
pub use xcm::{
|
||||
// Polkadot
|
||||
pub use xcm::{
|
||||
prelude::{AccountId32 as AccountId32Junction, *},
|
||||
v3::{self, Error, NetworkId::Westend as WestendId},
|
||||
};
|
||||
v3,
|
||||
};
|
||||
|
||||
// Cumulus
|
||||
pub use asset_test_utils::xcm_helpers;
|
||||
pub use emulated_integration_tests_common::{
|
||||
// Cumulus
|
||||
pub use asset_test_utils::xcm_helpers;
|
||||
pub use emulated_integration_tests_common::{
|
||||
test_parachain_is_trusted_teleporter,
|
||||
xcm_emulator::{
|
||||
assert_expected_events, bx, helpers::weight_within_threshold, Chain, Parachain as Para,
|
||||
RelayChain as Relay, Test, TestArgs, TestContext, TestExt,
|
||||
assert_expected_events, bx, Chain, Parachain as Para, RelayChain as Relay, Test,
|
||||
TestArgs, TestContext, TestExt,
|
||||
},
|
||||
xcm_helpers::{xcm_transact_paid_execution, xcm_transact_unpaid_execution},
|
||||
PROOF_SIZE_THRESHOLD, REF_TIME_THRESHOLD, XCM_V3,
|
||||
};
|
||||
pub use parachains_common::{AccountId, Balance};
|
||||
pub use westend_system_emulated_network::{
|
||||
xcm_helpers::{non_fee_asset, xcm_transact_paid_execution},
|
||||
ASSETS_PALLET_ID, RESERVABLE_ASSET_ID, XCM_V3,
|
||||
};
|
||||
pub use parachains_common::{AccountId, Balance};
|
||||
pub use westend_system_emulated_network::{
|
||||
asset_hub_westend_emulated_chain::{
|
||||
genesis::ED as ASSET_HUB_WESTEND_ED, AssetHubWestendParaPallet as AssetHubWestendPallet,
|
||||
genesis::{AssetHubWestendAssetOwner, ED as ASSET_HUB_WESTEND_ED},
|
||||
AssetHubWestendParaPallet as AssetHubWestendPallet,
|
||||
},
|
||||
collectives_westend_emulated_chain::{
|
||||
genesis::ED as COLLECTIVES_WESTEND_ED,
|
||||
CollectivesWestendParaPallet as CollectivesWestendPallet,
|
||||
collectives_westend_emulated_chain::CollectivesWestendParaPallet as CollectivesWestendPallet,
|
||||
penpal_emulated_chain::{
|
||||
PenpalAParaPallet as PenpalAPallet, PenpalAssetOwner,
|
||||
PenpalBParaPallet as PenpalBPallet,
|
||||
},
|
||||
penpal_emulated_chain::PenpalBParaPallet as PenpalBPallet,
|
||||
westend_emulated_chain::{genesis::ED as WESTEND_ED, WestendRelayPallet as WestendPallet},
|
||||
AssetHubWestendPara as AssetHubWestend, AssetHubWestendParaReceiver as AssetHubWestendReceiver,
|
||||
AssetHubWestendParaSender as AssetHubWestendSender, BridgeHubWestendPara as BridgeHubWestend,
|
||||
AssetHubWestendPara as AssetHubWestend,
|
||||
AssetHubWestendParaReceiver as AssetHubWestendReceiver,
|
||||
AssetHubWestendParaSender as AssetHubWestendSender,
|
||||
BridgeHubWestendPara as BridgeHubWestend,
|
||||
BridgeHubWestendParaReceiver as BridgeHubWestendReceiver,
|
||||
CollectivesWestendPara as CollectivesWestend, PenpalAPara as PenpalA,
|
||||
PenpalAParaReceiver as PenpalAReceiver, PenpalBPara as PenpalB,
|
||||
PenpalBParaReceiver as PenpalBReceiver, PenpalBParaSender as PenpalBSender,
|
||||
WestendRelay as Westend, WestendRelayReceiver as WestendReceiver,
|
||||
WestendRelaySender as WestendSender,
|
||||
};
|
||||
PenpalAParaReceiver as PenpalAReceiver, PenpalAParaSender as PenpalASender,
|
||||
PenpalBPara as PenpalB, PenpalBParaReceiver as PenpalBReceiver, WestendRelay as Westend,
|
||||
WestendRelayReceiver as WestendReceiver, WestendRelaySender as WestendSender,
|
||||
};
|
||||
|
||||
pub const ASSET_ID: u32 = 1;
|
||||
pub const ASSET_MIN_BALANCE: u128 = 1000;
|
||||
// `Assets` pallet index
|
||||
pub const ASSETS_PALLET_ID: u8 = 50;
|
||||
// Runtimes
|
||||
pub use asset_hub_westend_runtime::xcm_config::{
|
||||
UniversalLocation as AssetHubWestendUniversalLocation, WestendLocation as RelayLocation,
|
||||
XcmConfig as AssetHubWestendXcmConfig,
|
||||
};
|
||||
pub use penpal_runtime::xcm_config::{
|
||||
LocalReservableFromAssetHub as PenpalLocalReservableFromAssetHub,
|
||||
LocalTeleportableToAssetHub as PenpalLocalTeleportableToAssetHub,
|
||||
UniversalLocation as PenpalUniversalLocation, XcmConfig as PenpalWestendXcmConfig,
|
||||
};
|
||||
pub use westend_runtime::xcm_config::{
|
||||
UniversalLocation as WestendUniversalLocation, XcmConfig as WestendXcmConfig,
|
||||
};
|
||||
|
||||
pub type RelayToSystemParaTest = Test<Westend, AssetHubWestend>;
|
||||
pub type RelayToParaTest = Test<Westend, PenpalB>;
|
||||
pub type SystemParaToRelayTest = Test<AssetHubWestend, Westend>;
|
||||
pub type SystemParaToParaTest = Test<AssetHubWestend, PenpalB>;
|
||||
pub type ParaToSystemParaTest = Test<PenpalB, AssetHubWestend>;
|
||||
pub type ParaToParaTest = Test<PenpalB, PenpalA, Westend>;
|
||||
pub const ASSET_ID: u32 = 3;
|
||||
pub const ASSET_MIN_BALANCE: u128 = 1000;
|
||||
|
||||
pub type RelayToSystemParaTest = Test<Westend, AssetHubWestend>;
|
||||
pub type RelayToParaTest = Test<Westend, PenpalA>;
|
||||
pub type ParaToRelayTest = Test<PenpalA, Westend>;
|
||||
pub type SystemParaToRelayTest = Test<AssetHubWestend, Westend>;
|
||||
pub type SystemParaToParaTest = Test<AssetHubWestend, PenpalA>;
|
||||
pub type ParaToSystemParaTest = Test<PenpalA, AssetHubWestend>;
|
||||
pub type ParaToParaThroughRelayTest = Test<PenpalA, PenpalB, Westend>;
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
|
||||
+1
-1
@@ -13,7 +13,7 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
use crate::*;
|
||||
use crate::imports::*;
|
||||
use emulated_integration_tests_common::accounts::{ALICE, BOB};
|
||||
use frame_support::traits::fungibles::{Create, Inspect, Mutate};
|
||||
use polkadot_runtime_common::impls::VersionedLocatableAsset;
|
||||
|
||||
-8
@@ -20,11 +20,3 @@ mod set_xcm_versions;
|
||||
mod swap;
|
||||
mod teleport;
|
||||
mod treasury;
|
||||
|
||||
use crate::*;
|
||||
emulated_integration_tests_common::include_penpal_create_foreign_asset_on_asset_hub!(
|
||||
PenpalB,
|
||||
AssetHubWestend,
|
||||
WESTEND_ED,
|
||||
testnet_parachains_constants::westend::fee::WeightToFee
|
||||
);
|
||||
|
||||
+722
-205
File diff suppressed because it is too large
Load Diff
+118
-25
@@ -13,7 +13,7 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
use crate::*;
|
||||
use crate::imports::*;
|
||||
|
||||
/// Relay Chain should be able to execute `Transact` instructions in System Parachain
|
||||
/// when `OriginKind::Superuser`.
|
||||
@@ -28,12 +28,99 @@ fn send_transact_as_superuser_from_relay_to_system_para_works() {
|
||||
)
|
||||
}
|
||||
|
||||
/// Parachain should be able to send XCM paying its fee with sufficient asset
|
||||
/// in the System Parachain
|
||||
/// We tests two things here:
|
||||
/// - Parachain should be able to send XCM paying its fee with system asset in the System Parachain
|
||||
/// - Parachain should be able to create a new Foreign Asset in the System Parachain
|
||||
#[test]
|
||||
fn send_xcm_from_para_to_system_para_paying_fee_with_system_assets_works() {
|
||||
let para_sovereign_account = AssetHubWestend::sovereign_account_id_of(
|
||||
AssetHubWestend::sibling_location_of(PenpalA::para_id()),
|
||||
);
|
||||
let asset_location_on_penpal = v3::Location::new(
|
||||
0,
|
||||
[
|
||||
v3::Junction::PalletInstance(ASSETS_PALLET_ID),
|
||||
v3::Junction::GeneralIndex(ASSET_ID.into()),
|
||||
],
|
||||
);
|
||||
let foreign_asset_at_asset_hub =
|
||||
v3::Location::new(1, [v3::Junction::Parachain(PenpalA::para_id().into())])
|
||||
.appended_with(asset_location_on_penpal)
|
||||
.unwrap();
|
||||
|
||||
// Encoded `create_asset` call to be executed in AssetHub
|
||||
let call = AssetHubWestend::create_foreign_asset_call(
|
||||
foreign_asset_at_asset_hub,
|
||||
ASSET_MIN_BALANCE,
|
||||
para_sovereign_account.clone(),
|
||||
);
|
||||
|
||||
let origin_kind = OriginKind::Xcm;
|
||||
let fee_amount = ASSET_HUB_WESTEND_ED * 1000000;
|
||||
let system_asset = (Parent, fee_amount).into();
|
||||
|
||||
let root_origin = <PenpalA as Chain>::RuntimeOrigin::root();
|
||||
let system_para_destination = PenpalA::sibling_location_of(AssetHubWestend::para_id()).into();
|
||||
let xcm = xcm_transact_paid_execution(
|
||||
call,
|
||||
origin_kind,
|
||||
system_asset,
|
||||
para_sovereign_account.clone(),
|
||||
);
|
||||
|
||||
// SA-of-Penpal-on-AHR needs to have balance to pay for fees and asset creation deposit
|
||||
AssetHubWestend::fund_accounts(vec![(
|
||||
para_sovereign_account.clone().into(),
|
||||
ASSET_HUB_WESTEND_ED * 10000000000,
|
||||
)]);
|
||||
|
||||
PenpalA::execute_with(|| {
|
||||
assert_ok!(<PenpalA as PenpalAPallet>::PolkadotXcm::send(
|
||||
root_origin,
|
||||
bx!(system_para_destination),
|
||||
bx!(xcm),
|
||||
));
|
||||
|
||||
PenpalA::assert_xcm_pallet_sent();
|
||||
});
|
||||
|
||||
AssetHubWestend::execute_with(|| {
|
||||
type RuntimeEvent = <AssetHubWestend as Chain>::RuntimeEvent;
|
||||
|
||||
AssetHubWestend::assert_xcmp_queue_success(Some(Weight::from_parts(
|
||||
15_594_564_000,
|
||||
562_893,
|
||||
)));
|
||||
|
||||
assert_expected_events!(
|
||||
AssetHubWestend,
|
||||
vec![
|
||||
// Burned the fee
|
||||
RuntimeEvent::Balances(pallet_balances::Event::Burned { who, amount }) => {
|
||||
who: *who == para_sovereign_account,
|
||||
amount: *amount == fee_amount,
|
||||
},
|
||||
// Foreign Asset created
|
||||
RuntimeEvent::ForeignAssets(pallet_assets::Event::Created { asset_id, creator, owner }) => {
|
||||
asset_id: *asset_id == foreign_asset_at_asset_hub,
|
||||
creator: *creator == para_sovereign_account.clone(),
|
||||
owner: *owner == para_sovereign_account,
|
||||
},
|
||||
]
|
||||
);
|
||||
|
||||
type ForeignAssets = <AssetHubWestend as AssetHubWestendPallet>::ForeignAssets;
|
||||
assert!(ForeignAssets::asset_exists(foreign_asset_at_asset_hub));
|
||||
});
|
||||
}
|
||||
|
||||
/// We tests two things here:
|
||||
/// - Parachain should be able to send XCM paying its fee with system assets in the System Parachain
|
||||
/// - Parachain should be able to create a new Asset in the System Parachain
|
||||
#[test]
|
||||
fn send_xcm_from_para_to_system_para_paying_fee_with_assets_works() {
|
||||
let para_sovereign_account = AssetHubWestend::sovereign_account_id_of(
|
||||
AssetHubWestend::sibling_location_of(PenpalB::para_id()),
|
||||
AssetHubWestend::sibling_location_of(PenpalA::para_id()),
|
||||
);
|
||||
|
||||
// Force create and mint assets for Parachain's sovereign account
|
||||
@@ -46,57 +133,63 @@ fn send_xcm_from_para_to_system_para_paying_fee_with_assets_works() {
|
||||
ASSET_MIN_BALANCE * 1000000000,
|
||||
);
|
||||
|
||||
// We just need a call that can pass the `SafeCallFilter`
|
||||
// Call values are not relevant
|
||||
let call = AssetHubWestend::force_create_asset_call(
|
||||
ASSET_ID,
|
||||
para_sovereign_account.clone(),
|
||||
true,
|
||||
// Just a different `asset_id`` that does not exist yet
|
||||
let new_asset_id = ASSET_ID + 1;
|
||||
|
||||
// Encoded `create_asset` call to be executed in AssetHub
|
||||
let call = AssetHubWestend::create_asset_call(
|
||||
new_asset_id,
|
||||
ASSET_MIN_BALANCE,
|
||||
para_sovereign_account.clone(),
|
||||
);
|
||||
|
||||
let origin_kind = OriginKind::SovereignAccount;
|
||||
let fee_amount = ASSET_MIN_BALANCE * 1000000;
|
||||
let native_asset =
|
||||
let asset =
|
||||
([PalletInstance(ASSETS_PALLET_ID), GeneralIndex(ASSET_ID.into())], fee_amount).into();
|
||||
|
||||
let root_origin = <PenpalB as Chain>::RuntimeOrigin::root();
|
||||
let system_para_destination = PenpalB::sibling_location_of(AssetHubWestend::para_id()).into();
|
||||
let xcm = xcm_transact_paid_execution(
|
||||
call,
|
||||
origin_kind,
|
||||
native_asset,
|
||||
para_sovereign_account.clone(),
|
||||
);
|
||||
let root_origin = <PenpalA as Chain>::RuntimeOrigin::root();
|
||||
let system_para_destination = PenpalA::sibling_location_of(AssetHubWestend::para_id()).into();
|
||||
let xcm = xcm_transact_paid_execution(call, origin_kind, asset, para_sovereign_account.clone());
|
||||
|
||||
PenpalB::execute_with(|| {
|
||||
assert_ok!(<PenpalB as PenpalBPallet>::PolkadotXcm::send(
|
||||
// SA-of-Penpal-on-AHR needs to have balance to pay for asset creation deposit
|
||||
AssetHubWestend::fund_accounts(vec![(
|
||||
para_sovereign_account.clone().into(),
|
||||
ASSET_HUB_WESTEND_ED * 10000000000,
|
||||
)]);
|
||||
|
||||
PenpalA::execute_with(|| {
|
||||
assert_ok!(<PenpalA as PenpalAPallet>::PolkadotXcm::send(
|
||||
root_origin,
|
||||
bx!(system_para_destination),
|
||||
bx!(xcm),
|
||||
));
|
||||
|
||||
PenpalB::assert_xcm_pallet_sent();
|
||||
PenpalA::assert_xcm_pallet_sent();
|
||||
});
|
||||
|
||||
AssetHubWestend::execute_with(|| {
|
||||
type RuntimeEvent = <AssetHubWestend as Chain>::RuntimeEvent;
|
||||
|
||||
AssetHubWestend::assert_xcmp_queue_success(Some(Weight::from_parts(
|
||||
16_290_336_000,
|
||||
15_594_564_000,
|
||||
562_893,
|
||||
)));
|
||||
|
||||
assert_expected_events!(
|
||||
AssetHubWestend,
|
||||
vec![
|
||||
// Burned the fee
|
||||
RuntimeEvent::Assets(pallet_assets::Event::Burned { asset_id, owner, balance }) => {
|
||||
asset_id: *asset_id == ASSET_ID,
|
||||
owner: *owner == para_sovereign_account,
|
||||
balance: *balance == fee_amount,
|
||||
},
|
||||
RuntimeEvent::Assets(pallet_assets::Event::Issued { asset_id, .. }) => {
|
||||
asset_id: *asset_id == ASSET_ID,
|
||||
// Asset created
|
||||
RuntimeEvent::Assets(pallet_assets::Event::Created { asset_id, creator, owner }) => {
|
||||
asset_id: *asset_id == new_asset_id,
|
||||
creator: *creator == para_sovereign_account.clone(),
|
||||
owner: *owner == para_sovereign_account,
|
||||
},
|
||||
]
|
||||
);
|
||||
|
||||
+1
-1
@@ -13,7 +13,7 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
use crate::*;
|
||||
use crate::imports::*;
|
||||
|
||||
#[test]
|
||||
fn relay_sets_system_para_xcm_supported_version() {
|
||||
|
||||
+45
-54
@@ -13,8 +13,7 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
use crate::*;
|
||||
use westend_system_emulated_network::penpal_emulated_chain::LocalTeleportableToAssetHubV3 as PenpalLocalTeleportableToAssetHubV3;
|
||||
use crate::imports::*;
|
||||
|
||||
#[test]
|
||||
fn swap_locally_on_chain_using_local_assets() {
|
||||
@@ -112,49 +111,39 @@ fn swap_locally_on_chain_using_local_assets() {
|
||||
|
||||
#[test]
|
||||
fn swap_locally_on_chain_using_foreign_assets() {
|
||||
let asset_native = Box::new(asset_hub_westend_runtime::xcm_config::WestendLocationV3::get());
|
||||
let ah_as_seen_by_penpal = PenpalB::sibling_location_of(AssetHubWestend::para_id());
|
||||
let asset_location_on_penpal = PenpalLocalTeleportableToAssetHubV3::get();
|
||||
let asset_id_on_penpal = match asset_location_on_penpal.last() {
|
||||
Some(v3::Junction::GeneralIndex(id)) => *id as u32,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
let asset_owner_on_penpal = PenpalBSender::get();
|
||||
let asset_native =
|
||||
Box::new(v3::Location::try_from(RelayLocation::get()).expect("conversion works"));
|
||||
let asset_location_on_penpal =
|
||||
v3::Location::try_from(PenpalLocalTeleportableToAssetHub::get()).expect("conversion_works");
|
||||
let foreign_asset_at_asset_hub_westend =
|
||||
v3::Location::new(1, [v3::Junction::Parachain(PenpalB::para_id().into())])
|
||||
v3::Location::new(1, [v3::Junction::Parachain(PenpalA::para_id().into())])
|
||||
.appended_with(asset_location_on_penpal)
|
||||
.unwrap();
|
||||
|
||||
// 1. Create asset on penpal and, 2. Create foreign asset on asset_hub_westend
|
||||
super::penpal_create_foreign_asset_on_asset_hub(
|
||||
asset_id_on_penpal,
|
||||
foreign_asset_at_asset_hub_westend,
|
||||
ah_as_seen_by_penpal,
|
||||
true,
|
||||
asset_owner_on_penpal,
|
||||
ASSET_MIN_BALANCE * 1_000_000,
|
||||
);
|
||||
|
||||
let penpal_as_seen_by_ah = AssetHubWestend::sibling_location_of(PenpalB::para_id());
|
||||
let sov_penpal_on_ahw = AssetHubWestend::sovereign_account_id_of(penpal_as_seen_by_ah);
|
||||
let penpal_as_seen_by_ah = AssetHubWestend::sibling_location_of(PenpalA::para_id());
|
||||
let sov_penpal_on_ahr = AssetHubWestend::sovereign_account_id_of(penpal_as_seen_by_ah);
|
||||
AssetHubWestend::fund_accounts(vec![
|
||||
(AssetHubWestendSender::get().into(), 5_000_000 * WESTEND_ED), /* An account to swap dot
|
||||
* for something else. */
|
||||
// An account to swap dot for something else.
|
||||
(AssetHubWestendSender::get().into(), 5_000_000 * ASSET_HUB_WESTEND_ED),
|
||||
// Penpal's sovereign account in AH should have some balance
|
||||
(sov_penpal_on_ahr.clone().into(), 100_000_000 * ASSET_HUB_WESTEND_ED),
|
||||
]);
|
||||
|
||||
AssetHubWestend::execute_with(|| {
|
||||
// 3: Mint foreign asset on asset_hub_westend:
|
||||
// 0: No need to create foreign asset as it exists in genesis.
|
||||
//
|
||||
// 1: Mint foreign asset on asset_hub_westend:
|
||||
//
|
||||
// (While it might be nice to use batch,
|
||||
// currently that's disabled due to safe call filters.)
|
||||
|
||||
type RuntimeEvent = <AssetHubWestend as Chain>::RuntimeEvent;
|
||||
// 3. Mint foreign asset (in reality this should be a teleport or some such)
|
||||
// 1. Mint foreign asset (in reality this should be a teleport or some such)
|
||||
assert_ok!(<AssetHubWestend as AssetHubWestendPallet>::ForeignAssets::mint(
|
||||
<AssetHubWestend as Chain>::RuntimeOrigin::signed(sov_penpal_on_ahw.clone().into()),
|
||||
<AssetHubWestend as Chain>::RuntimeOrigin::signed(sov_penpal_on_ahr.clone().into()),
|
||||
foreign_asset_at_asset_hub_westend,
|
||||
sov_penpal_on_ahw.clone().into(),
|
||||
3_000_000_000_000,
|
||||
sov_penpal_on_ahr.clone().into(),
|
||||
ASSET_HUB_WESTEND_ED * 3_000_000_000_000,
|
||||
));
|
||||
|
||||
assert_expected_events!(
|
||||
@@ -164,7 +153,7 @@ fn swap_locally_on_chain_using_foreign_assets() {
|
||||
]
|
||||
);
|
||||
|
||||
// 4. Create pool:
|
||||
// 2. Create pool:
|
||||
assert_ok!(<AssetHubWestend as AssetHubWestendPallet>::AssetConversion::create_pool(
|
||||
<AssetHubWestend as Chain>::RuntimeOrigin::signed(AssetHubWestendSender::get()),
|
||||
asset_native.clone(),
|
||||
@@ -178,58 +167,60 @@ fn swap_locally_on_chain_using_foreign_assets() {
|
||||
]
|
||||
);
|
||||
|
||||
// 5. Add liquidity:
|
||||
// 3. Add liquidity:
|
||||
assert_ok!(<AssetHubWestend as AssetHubWestendPallet>::AssetConversion::add_liquidity(
|
||||
<AssetHubWestend as Chain>::RuntimeOrigin::signed(sov_penpal_on_ahw.clone()),
|
||||
<AssetHubWestend as Chain>::RuntimeOrigin::signed(sov_penpal_on_ahr.clone()),
|
||||
asset_native.clone(),
|
||||
Box::new(foreign_asset_at_asset_hub_westend),
|
||||
1_000_000_000_000,
|
||||
2_000_000_000_000,
|
||||
1_000_000_000_000_000,
|
||||
2_000_000_000_000_000,
|
||||
0,
|
||||
0,
|
||||
sov_penpal_on_ahw.clone().into()
|
||||
sov_penpal_on_ahr.clone().into()
|
||||
));
|
||||
|
||||
assert_expected_events!(
|
||||
AssetHubWestend,
|
||||
vec![
|
||||
RuntimeEvent::AssetConversion(pallet_asset_conversion::Event::LiquidityAdded {lp_token_minted, .. }) => {
|
||||
lp_token_minted: *lp_token_minted == 1414213562273,
|
||||
lp_token_minted: *lp_token_minted == 1414213562372995,
|
||||
},
|
||||
]
|
||||
);
|
||||
|
||||
// 6. Swap!
|
||||
// 4. Swap!
|
||||
let path = vec![asset_native.clone(), Box::new(foreign_asset_at_asset_hub_westend)];
|
||||
|
||||
assert_ok!(<AssetHubWestend as AssetHubWestendPallet>::AssetConversion::swap_exact_tokens_for_tokens(
|
||||
assert_ok!(
|
||||
<AssetHubWestend as AssetHubWestendPallet>::AssetConversion::swap_exact_tokens_for_tokens(
|
||||
<AssetHubWestend as Chain>::RuntimeOrigin::signed(AssetHubWestendSender::get()),
|
||||
path,
|
||||
100000,
|
||||
1000,
|
||||
100000 * ASSET_HUB_WESTEND_ED,
|
||||
1000 * ASSET_HUB_WESTEND_ED,
|
||||
AssetHubWestendSender::get().into(),
|
||||
true
|
||||
));
|
||||
)
|
||||
);
|
||||
|
||||
assert_expected_events!(
|
||||
AssetHubWestend,
|
||||
vec![
|
||||
RuntimeEvent::AssetConversion(pallet_asset_conversion::Event::SwapExecuted { amount_in, amount_out, .. },) => {
|
||||
amount_in: *amount_in == 100000,
|
||||
amount_out: *amount_out == 199399,
|
||||
amount_in: *amount_in == 100000000000000,
|
||||
amount_out: *amount_out == 181322178776029,
|
||||
},
|
||||
]
|
||||
);
|
||||
|
||||
// 7. Remove liquidity
|
||||
// 5. Remove liquidity
|
||||
assert_ok!(<AssetHubWestend as AssetHubWestendPallet>::AssetConversion::remove_liquidity(
|
||||
<AssetHubWestend as Chain>::RuntimeOrigin::signed(sov_penpal_on_ahw.clone()),
|
||||
<AssetHubWestend as Chain>::RuntimeOrigin::signed(sov_penpal_on_ahr.clone()),
|
||||
asset_native.clone(),
|
||||
Box::new(foreign_asset_at_asset_hub_westend),
|
||||
1414213562273 - 2_000_000_000, // all but the 2 EDs can't be retrieved.
|
||||
1414213562372995 - ASSET_HUB_WESTEND_ED * 2, // all but the 2 EDs can't be retrieved.
|
||||
0,
|
||||
0,
|
||||
sov_penpal_on_ahw.into(),
|
||||
sov_penpal_on_ahr.clone().into(),
|
||||
));
|
||||
});
|
||||
}
|
||||
@@ -283,7 +274,7 @@ fn pay_xcm_fee_with_some_asset_swapped_for_native() {
|
||||
.into(),
|
||||
};
|
||||
let penpal = AssetHubWestend::sovereign_account_id_of(AssetHubWestend::sibling_location_of(
|
||||
PenpalB::para_id(),
|
||||
PenpalA::para_id(),
|
||||
));
|
||||
|
||||
AssetHubWestend::execute_with(|| {
|
||||
@@ -356,7 +347,7 @@ fn pay_xcm_fee_with_some_asset_swapped_for_native() {
|
||||
));
|
||||
});
|
||||
|
||||
PenpalB::execute_with(|| {
|
||||
PenpalA::execute_with(|| {
|
||||
// send xcm transact from `penpal` account which as only `ASSET_ID` tokens on
|
||||
// `AssetHubWestend`
|
||||
let call = AssetHubWestend::force_create_asset_call(
|
||||
@@ -366,11 +357,11 @@ fn pay_xcm_fee_with_some_asset_swapped_for_native() {
|
||||
ASSET_MIN_BALANCE,
|
||||
);
|
||||
|
||||
let penpal_root = <PenpalB as Chain>::RuntimeOrigin::root();
|
||||
let penpal_root = <PenpalA as Chain>::RuntimeOrigin::root();
|
||||
let fee_amount = 4_000_000_000_000u128;
|
||||
let asset_one =
|
||||
([PalletInstance(ASSETS_PALLET_ID), GeneralIndex(ASSET_ID.into())], fee_amount).into();
|
||||
let asset_hub_location = PenpalB::sibling_location_of(AssetHubWestend::para_id()).into();
|
||||
let asset_hub_location = PenpalA::sibling_location_of(AssetHubWestend::para_id()).into();
|
||||
let xcm = xcm_transact_paid_execution(
|
||||
call,
|
||||
OriginKind::SovereignAccount,
|
||||
@@ -378,13 +369,13 @@ fn pay_xcm_fee_with_some_asset_swapped_for_native() {
|
||||
penpal.clone(),
|
||||
);
|
||||
|
||||
assert_ok!(<PenpalB as PenpalBPallet>::PolkadotXcm::send(
|
||||
assert_ok!(<PenpalA as PenpalAPallet>::PolkadotXcm::send(
|
||||
penpal_root,
|
||||
bx!(asset_hub_location),
|
||||
bx!(xcm),
|
||||
));
|
||||
|
||||
PenpalB::assert_xcm_pallet_sent();
|
||||
PenpalA::assert_xcm_pallet_sent();
|
||||
});
|
||||
|
||||
AssetHubWestend::execute_with(|| {
|
||||
|
||||
+140
-86
@@ -13,16 +13,12 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
use crate::*;
|
||||
use asset_hub_westend_runtime::xcm_config::XcmConfig as AssetHubWestendXcmConfig;
|
||||
use emulated_integration_tests_common::xcm_helpers::non_fee_asset;
|
||||
use westend_runtime::xcm_config::XcmConfig as WestendXcmConfig;
|
||||
use westend_system_emulated_network::penpal_emulated_chain::LocalTeleportableToAssetHubV3 as PenpalLocalTeleportableToAssetHubV3;
|
||||
use crate::imports::*;
|
||||
|
||||
fn relay_origin_assertions(t: RelayToSystemParaTest) {
|
||||
type RuntimeEvent = <Westend as Chain>::RuntimeEvent;
|
||||
|
||||
Westend::assert_xcm_pallet_attempted_complete(Some(Weight::from_parts(632_207_000, 7_186)));
|
||||
Westend::assert_xcm_pallet_attempted_complete(Some(Weight::from_parts(631_531_000, 7_186)));
|
||||
|
||||
assert_expected_events!(
|
||||
Westend,
|
||||
@@ -47,7 +43,7 @@ fn relay_dest_assertions(t: SystemParaToRelayTest) {
|
||||
Westend::assert_ump_queue_processed(
|
||||
true,
|
||||
Some(AssetHubWestend::para_id()),
|
||||
Some(Weight::from_parts(308_222_000, 7_186)),
|
||||
Some(Weight::from_parts(307_225_000, 7_186)),
|
||||
);
|
||||
|
||||
assert_expected_events!(
|
||||
@@ -70,7 +66,7 @@ fn relay_dest_assertions_fail(_t: SystemParaToRelayTest) {
|
||||
Westend::assert_ump_queue_processed(
|
||||
false,
|
||||
Some(AssetHubWestend::para_id()),
|
||||
Some(Weight::from_parts(148_705_000, 3_593)),
|
||||
Some(Weight::from_parts(157_718_000, 3_593)),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -78,8 +74,8 @@ fn para_origin_assertions(t: SystemParaToRelayTest) {
|
||||
type RuntimeEvent = <AssetHubWestend as Chain>::RuntimeEvent;
|
||||
|
||||
AssetHubWestend::assert_xcm_pallet_attempted_complete(Some(Weight::from_parts(
|
||||
533_910_000,
|
||||
7167,
|
||||
720_053_000,
|
||||
7_203,
|
||||
)));
|
||||
|
||||
AssetHubWestend::assert_parachain_system_ump_sent();
|
||||
@@ -99,7 +95,7 @@ fn para_origin_assertions(t: SystemParaToRelayTest) {
|
||||
fn para_dest_assertions(t: RelayToSystemParaTest) {
|
||||
type RuntimeEvent = <AssetHubWestend as Chain>::RuntimeEvent;
|
||||
|
||||
AssetHubWestend::assert_dmp_queue_complete(Some(Weight::from_parts(164_793_000, 3593)));
|
||||
AssetHubWestend::assert_dmp_queue_complete(Some(Weight::from_parts(157_718_000, 3593)));
|
||||
|
||||
assert_expected_events!(
|
||||
AssetHubWestend,
|
||||
@@ -113,19 +109,22 @@ fn para_dest_assertions(t: RelayToSystemParaTest) {
|
||||
}
|
||||
|
||||
fn penpal_to_ah_foreign_assets_sender_assertions(t: ParaToSystemParaTest) {
|
||||
type RuntimeEvent = <PenpalB as Chain>::RuntimeEvent;
|
||||
PenpalB::assert_xcm_pallet_attempted_complete(None);
|
||||
type RuntimeEvent = <PenpalA as Chain>::RuntimeEvent;
|
||||
let system_para_native_asset_location =
|
||||
v3::Location::try_from(RelayLocation::get()).expect("conversion works");
|
||||
let expected_asset_id = t.args.asset_id.unwrap();
|
||||
let (_, expected_asset_amount) =
|
||||
non_fee_asset(&t.args.assets, t.args.fee_asset_item as usize).unwrap();
|
||||
|
||||
PenpalA::assert_xcm_pallet_attempted_complete(None);
|
||||
assert_expected_events!(
|
||||
PenpalB,
|
||||
PenpalA,
|
||||
vec![
|
||||
RuntimeEvent::Balances(
|
||||
pallet_balances::Event::Burned { who, amount }
|
||||
RuntimeEvent::ForeignAssets(
|
||||
pallet_assets::Event::Burned { asset_id, owner, .. }
|
||||
) => {
|
||||
who: *who == t.sender.account_id,
|
||||
amount: *amount == t.args.amount,
|
||||
asset_id: *asset_id == system_para_native_asset_location,
|
||||
owner: *owner == t.sender.account_id,
|
||||
},
|
||||
RuntimeEvent::Assets(pallet_assets::Event::Burned { asset_id, owner, balance }) => {
|
||||
asset_id: *asset_id == expected_asset_id,
|
||||
@@ -139,11 +138,14 @@ fn penpal_to_ah_foreign_assets_sender_assertions(t: ParaToSystemParaTest) {
|
||||
fn penpal_to_ah_foreign_assets_receiver_assertions(t: ParaToSystemParaTest) {
|
||||
type RuntimeEvent = <AssetHubWestend as Chain>::RuntimeEvent;
|
||||
let sov_penpal_on_ahr = AssetHubWestend::sovereign_account_id_of(
|
||||
AssetHubWestend::sibling_location_of(PenpalB::para_id()),
|
||||
AssetHubWestend::sibling_location_of(PenpalA::para_id()),
|
||||
);
|
||||
let (expected_foreign_asset_id, expected_foreign_asset_amount) =
|
||||
non_fee_asset(&t.args.assets, t.args.fee_asset_item as usize).unwrap();
|
||||
let expected_foreign_asset_id_v3: v3::Location = expected_foreign_asset_id.try_into().unwrap();
|
||||
|
||||
AssetHubWestend::assert_xcmp_queue_success(None);
|
||||
|
||||
assert_expected_events!(
|
||||
AssetHubWestend,
|
||||
vec![
|
||||
@@ -163,9 +165,6 @@ fn penpal_to_ah_foreign_assets_receiver_assertions(t: ParaToSystemParaTest) {
|
||||
amount: *amount == expected_foreign_asset_amount,
|
||||
},
|
||||
RuntimeEvent::Balances(pallet_balances::Event::Deposit { .. }) => {},
|
||||
RuntimeEvent::MessageQueue(
|
||||
pallet_message_queue::Event::Processed { success: true, .. }
|
||||
) => {},
|
||||
]
|
||||
);
|
||||
}
|
||||
@@ -200,13 +199,18 @@ fn ah_to_penpal_foreign_assets_sender_assertions(t: SystemParaToParaTest) {
|
||||
}
|
||||
|
||||
fn ah_to_penpal_foreign_assets_receiver_assertions(t: SystemParaToParaTest) {
|
||||
type RuntimeEvent = <PenpalB as Chain>::RuntimeEvent;
|
||||
type RuntimeEvent = <PenpalA as Chain>::RuntimeEvent;
|
||||
let expected_asset_id = t.args.asset_id.unwrap();
|
||||
let (_, expected_asset_amount) =
|
||||
non_fee_asset(&t.args.assets, t.args.fee_asset_item as usize).unwrap();
|
||||
let checking_account = <PenpalB as PenpalBPallet>::PolkadotXcm::check_account();
|
||||
let checking_account = <PenpalA as PenpalAPallet>::PolkadotXcm::check_account();
|
||||
let system_para_native_asset_location =
|
||||
v3::Location::try_from(RelayLocation::get()).expect("conversion works");
|
||||
|
||||
PenpalA::assert_xcmp_queue_success(None);
|
||||
|
||||
assert_expected_events!(
|
||||
PenpalB,
|
||||
PenpalA,
|
||||
vec![
|
||||
// checking account burns local asset as part of incoming teleport
|
||||
RuntimeEvent::Assets(pallet_assets::Event::Burned { asset_id, owner, balance }) => {
|
||||
@@ -221,12 +225,11 @@ fn ah_to_penpal_foreign_assets_receiver_assertions(t: SystemParaToParaTest) {
|
||||
amount: *amount == expected_asset_amount,
|
||||
},
|
||||
// native asset for fee is deposited to receiver
|
||||
RuntimeEvent::Balances(pallet_balances::Event::Minted { who, .. }) => {
|
||||
who: *who == t.receiver.account_id,
|
||||
RuntimeEvent::ForeignAssets(pallet_assets::Event::Issued { asset_id, owner, amount }) => {
|
||||
asset_id: *asset_id == system_para_native_asset_location,
|
||||
owner: *owner == t.receiver.account_id,
|
||||
amount: *amount == expected_asset_amount,
|
||||
},
|
||||
RuntimeEvent::MessageQueue(
|
||||
pallet_message_queue::Event::Processed { success: true, .. }
|
||||
) => {},
|
||||
]
|
||||
);
|
||||
}
|
||||
@@ -273,8 +276,8 @@ fn system_para_teleport_assets(t: SystemParaToRelayTest) -> DispatchResult {
|
||||
)
|
||||
}
|
||||
|
||||
fn system_para_to_para_transfer_assets(t: SystemParaToParaTest) -> DispatchResult {
|
||||
<AssetHubWestend as AssetHubWestendPallet>::PolkadotXcm::transfer_assets(
|
||||
fn para_to_system_para_transfer_assets(t: ParaToSystemParaTest) -> DispatchResult {
|
||||
<PenpalA as PenpalAPallet>::PolkadotXcm::transfer_assets(
|
||||
t.signed_origin,
|
||||
bx!(t.args.dest.into()),
|
||||
bx!(t.args.beneficiary.into()),
|
||||
@@ -284,8 +287,8 @@ fn system_para_to_para_transfer_assets(t: SystemParaToParaTest) -> DispatchResul
|
||||
)
|
||||
}
|
||||
|
||||
fn para_to_system_para_transfer_assets(t: ParaToSystemParaTest) -> DispatchResult {
|
||||
<PenpalB as PenpalBPallet>::PolkadotXcm::transfer_assets(
|
||||
fn system_para_to_para_transfer_assets(t: SystemParaToParaTest) -> DispatchResult {
|
||||
<AssetHubWestend as AssetHubWestendPallet>::PolkadotXcm::transfer_assets(
|
||||
t.signed_origin,
|
||||
bx!(t.args.dest.into()),
|
||||
bx!(t.args.beneficiary.into()),
|
||||
@@ -301,11 +304,11 @@ fn limited_teleport_native_assets_from_relay_to_system_para_works() {
|
||||
// Init values for Relay Chain
|
||||
let amount_to_send: Balance = WESTEND_ED * 1000;
|
||||
let dest = Westend::child_location_of(AssetHubWestend::para_id());
|
||||
let beneficiary = AssetHubWestendReceiver::get();
|
||||
let beneficiary_id = AssetHubWestendReceiver::get();
|
||||
let test_args = TestContext {
|
||||
sender: WestendSender::get(),
|
||||
receiver: beneficiary.clone(),
|
||||
args: TestArgs::new_relay(dest, beneficiary, amount_to_send),
|
||||
receiver: AssetHubWestendReceiver::get(),
|
||||
args: TestArgs::new_relay(dest, beneficiary_id, amount_to_send),
|
||||
};
|
||||
|
||||
let mut test = RelayToSystemParaTest::new(test_args);
|
||||
@@ -424,11 +427,11 @@ fn teleport_native_assets_from_relay_to_system_para_works() {
|
||||
// Init values for Relay Chain
|
||||
let amount_to_send: Balance = WESTEND_ED * 1000;
|
||||
let dest = Westend::child_location_of(AssetHubWestend::para_id());
|
||||
let beneficiary = AssetHubWestendReceiver::get();
|
||||
let beneficiary_id = AssetHubWestendReceiver::get();
|
||||
let test_args = TestContext {
|
||||
sender: WestendSender::get(),
|
||||
receiver: beneficiary.clone(),
|
||||
args: TestArgs::new_relay(dest, beneficiary, amount_to_send),
|
||||
receiver: AssetHubWestendReceiver::get(),
|
||||
args: TestArgs::new_relay(dest, beneficiary_id, amount_to_send),
|
||||
};
|
||||
|
||||
let mut test = RelayToSystemParaTest::new(test_args);
|
||||
@@ -485,15 +488,15 @@ fn teleport_native_assets_back_from_system_para_to_relay_works() {
|
||||
test.set_dispatchable::<AssetHubWestend>(system_para_teleport_assets);
|
||||
test.assert();
|
||||
|
||||
let sender_balance_after = test.sender.balance;
|
||||
let receiver_balance_after = test.receiver.balance;
|
||||
|
||||
let delivery_fees = AssetHubWestend::execute_with(|| {
|
||||
xcm_helpers::transfer_assets_delivery_fees::<
|
||||
<AssetHubWestendXcmConfig as xcm_executor::Config>::XcmSender,
|
||||
>(test.args.assets.clone(), 0, test.args.weight_limit, test.args.beneficiary, test.args.dest)
|
||||
});
|
||||
|
||||
let sender_balance_after = test.sender.balance;
|
||||
let receiver_balance_after = test.receiver.balance;
|
||||
|
||||
// Sender's balance is reduced
|
||||
assert_eq!(sender_balance_before - amount_to_send - delivery_fees, sender_balance_after);
|
||||
// Receiver's balance is increased
|
||||
@@ -558,30 +561,21 @@ fn teleport_to_other_system_parachains_works() {
|
||||
/// (using native reserve-based transfer for fees)
|
||||
#[test]
|
||||
fn bidirectional_teleport_foreign_assets_between_para_and_asset_hub() {
|
||||
let ah_as_seen_by_penpal = PenpalB::sibling_location_of(AssetHubWestend::para_id());
|
||||
let asset_location_on_penpal = PenpalLocalTeleportableToAssetHubV3::get();
|
||||
// Init values for Parachain
|
||||
let fee_amount_to_send: Balance = ASSET_HUB_WESTEND_ED * 100;
|
||||
let asset_location_on_penpal =
|
||||
v3::Location::try_from(PenpalLocalTeleportableToAssetHub::get()).expect("conversion works");
|
||||
let asset_id_on_penpal = match asset_location_on_penpal.last() {
|
||||
Some(v3::Junction::GeneralIndex(id)) => *id as u32,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
let asset_owner_on_penpal = PenpalBSender::get();
|
||||
let foreign_asset_at_asset_hub_westend =
|
||||
v3::Location::new(1, [v3::Junction::Parachain(PenpalB::para_id().into())])
|
||||
.appended_with(asset_location_on_penpal)
|
||||
.unwrap();
|
||||
super::penpal_create_foreign_asset_on_asset_hub(
|
||||
asset_id_on_penpal,
|
||||
foreign_asset_at_asset_hub_westend,
|
||||
ah_as_seen_by_penpal.clone(),
|
||||
false,
|
||||
asset_owner_on_penpal,
|
||||
ASSET_MIN_BALANCE * 1_000_000,
|
||||
);
|
||||
let penpal_to_ah_beneficiary_id = AssetHubWestendReceiver::get();
|
||||
|
||||
let fee_amount_to_send = ASSET_HUB_WESTEND_ED * 1000;
|
||||
let asset_amount_to_send = ASSET_MIN_BALANCE * 1000;
|
||||
|
||||
let asset_amount_to_send = ASSET_HUB_WESTEND_ED * 100;
|
||||
let asset_owner = PenpalAssetOwner::get();
|
||||
let system_para_native_asset_location =
|
||||
v3::Location::try_from(RelayLocation::get()).expect("conversion works");
|
||||
let sender = PenpalASender::get();
|
||||
let penpal_check_account = <PenpalA as PenpalAPallet>::PolkadotXcm::check_account();
|
||||
let ah_as_seen_by_penpal = PenpalA::sibling_location_of(AssetHubWestend::para_id());
|
||||
let asset_location_on_penpal_latest: Location = asset_location_on_penpal.try_into().unwrap();
|
||||
let penpal_assets: Assets = vec![
|
||||
(Parent, fee_amount_to_send).into(),
|
||||
@@ -594,9 +588,44 @@ fn bidirectional_teleport_foreign_assets_between_para_and_asset_hub() {
|
||||
.position(|r| r == &(Parent, fee_amount_to_send).into())
|
||||
.unwrap() as u32;
|
||||
|
||||
// fund Parachain's sender account
|
||||
PenpalA::mint_foreign_asset(
|
||||
<PenpalA as Chain>::RuntimeOrigin::signed(asset_owner.clone()),
|
||||
system_para_native_asset_location,
|
||||
sender.clone(),
|
||||
fee_amount_to_send,
|
||||
);
|
||||
// No need to create the asset (only mint) as it exists in genesis.
|
||||
PenpalA::mint_asset(
|
||||
<PenpalA as Chain>::RuntimeOrigin::signed(asset_owner.clone()),
|
||||
asset_id_on_penpal,
|
||||
sender.clone(),
|
||||
asset_amount_to_send,
|
||||
);
|
||||
// fund Parachain's check account to be able to teleport
|
||||
PenpalA::fund_accounts(vec![(
|
||||
penpal_check_account.clone().into(),
|
||||
ASSET_HUB_WESTEND_ED * 1000,
|
||||
)]);
|
||||
|
||||
// prefund SA of Penpal on AssetHub with enough native tokens to pay for fees
|
||||
let penpal_as_seen_by_ah = AssetHubWestend::sibling_location_of(PenpalA::para_id());
|
||||
let sov_penpal_on_ah = AssetHubWestend::sovereign_account_id_of(penpal_as_seen_by_ah);
|
||||
AssetHubWestend::fund_accounts(vec![(
|
||||
sov_penpal_on_ah.clone().into(),
|
||||
ASSET_HUB_WESTEND_ED * 100_000_000_000,
|
||||
)]);
|
||||
|
||||
// Init values for System Parachain
|
||||
let foreign_asset_at_asset_hub_westend =
|
||||
v3::Location::new(1, [v3::Junction::Parachain(PenpalA::para_id().into())])
|
||||
.appended_with(asset_location_on_penpal)
|
||||
.unwrap();
|
||||
let penpal_to_ah_beneficiary_id = AssetHubWestendReceiver::get();
|
||||
|
||||
// Penpal to AH test args
|
||||
let penpal_to_ah_test_args = TestContext {
|
||||
sender: PenpalBSender::get(),
|
||||
sender: PenpalASender::get(),
|
||||
receiver: AssetHubWestendReceiver::get(),
|
||||
args: TestArgs::new_para(
|
||||
ah_as_seen_by_penpal,
|
||||
@@ -608,13 +637,19 @@ fn bidirectional_teleport_foreign_assets_between_para_and_asset_hub() {
|
||||
),
|
||||
};
|
||||
let mut penpal_to_ah = ParaToSystemParaTest::new(penpal_to_ah_test_args);
|
||||
let penpal_sender_balance_before = PenpalA::execute_with(|| {
|
||||
type ForeignAssets = <PenpalA as PenpalAPallet>::ForeignAssets;
|
||||
<ForeignAssets as Inspect<_>>::balance(
|
||||
system_para_native_asset_location,
|
||||
&PenpalASender::get(),
|
||||
)
|
||||
});
|
||||
|
||||
let penpal_sender_balance_before = penpal_to_ah.sender.balance;
|
||||
let ah_receiver_balance_before = penpal_to_ah.receiver.balance;
|
||||
|
||||
let penpal_sender_assets_before = PenpalB::execute_with(|| {
|
||||
type Assets = <PenpalB as PenpalBPallet>::Assets;
|
||||
<Assets as Inspect<_>>::balance(asset_id_on_penpal, &PenpalBSender::get())
|
||||
let penpal_sender_assets_before = PenpalA::execute_with(|| {
|
||||
type Assets = <PenpalA as PenpalAPallet>::Assets;
|
||||
<Assets as Inspect<_>>::balance(asset_id_on_penpal, &PenpalASender::get())
|
||||
});
|
||||
let ah_receiver_assets_before = AssetHubWestend::execute_with(|| {
|
||||
type Assets = <AssetHubWestend as AssetHubWestendPallet>::ForeignAssets;
|
||||
@@ -624,17 +659,24 @@ fn bidirectional_teleport_foreign_assets_between_para_and_asset_hub() {
|
||||
)
|
||||
});
|
||||
|
||||
penpal_to_ah.set_assertion::<PenpalB>(penpal_to_ah_foreign_assets_sender_assertions);
|
||||
penpal_to_ah.set_assertion::<PenpalA>(penpal_to_ah_foreign_assets_sender_assertions);
|
||||
penpal_to_ah.set_assertion::<AssetHubWestend>(penpal_to_ah_foreign_assets_receiver_assertions);
|
||||
penpal_to_ah.set_dispatchable::<PenpalB>(para_to_system_para_transfer_assets);
|
||||
penpal_to_ah.set_dispatchable::<PenpalA>(para_to_system_para_transfer_assets);
|
||||
penpal_to_ah.assert();
|
||||
|
||||
let penpal_sender_balance_after = penpal_to_ah.sender.balance;
|
||||
let penpal_sender_balance_after = PenpalA::execute_with(|| {
|
||||
type ForeignAssets = <PenpalA as PenpalAPallet>::ForeignAssets;
|
||||
<ForeignAssets as Inspect<_>>::balance(
|
||||
system_para_native_asset_location,
|
||||
&PenpalASender::get(),
|
||||
)
|
||||
});
|
||||
|
||||
let ah_receiver_balance_after = penpal_to_ah.receiver.balance;
|
||||
|
||||
let penpal_sender_assets_after = PenpalB::execute_with(|| {
|
||||
type Assets = <PenpalB as PenpalBPallet>::Assets;
|
||||
<Assets as Inspect<_>>::balance(asset_id_on_penpal, &PenpalBSender::get())
|
||||
let penpal_sender_assets_after = PenpalA::execute_with(|| {
|
||||
type Assets = <PenpalA as PenpalAPallet>::Assets;
|
||||
<Assets as Inspect<_>>::balance(asset_id_on_penpal, &PenpalASender::get())
|
||||
});
|
||||
let ah_receiver_assets_after = AssetHubWestend::execute_with(|| {
|
||||
type Assets = <AssetHubWestend as AssetHubWestendPallet>::ForeignAssets;
|
||||
@@ -675,8 +717,8 @@ fn bidirectional_teleport_foreign_assets_between_para_and_asset_hub() {
|
||||
|
||||
let foreign_asset_at_asset_hub_westend_latest: Location =
|
||||
foreign_asset_at_asset_hub_westend.try_into().unwrap();
|
||||
let ah_to_penpal_beneficiary_id = PenpalBReceiver::get();
|
||||
let penpal_as_seen_by_ah = AssetHubWestend::sibling_location_of(PenpalB::para_id());
|
||||
let ah_to_penpal_beneficiary_id = PenpalAReceiver::get();
|
||||
let penpal_as_seen_by_ah = AssetHubWestend::sibling_location_of(PenpalA::para_id());
|
||||
let ah_assets: Assets = vec![
|
||||
(Parent, fee_amount_to_send).into(),
|
||||
(foreign_asset_at_asset_hub_westend_latest, asset_amount_to_send).into(),
|
||||
@@ -691,7 +733,7 @@ fn bidirectional_teleport_foreign_assets_between_para_and_asset_hub() {
|
||||
// AH to Penpal test args
|
||||
let ah_to_penpal_test_args = TestContext {
|
||||
sender: AssetHubWestendSender::get(),
|
||||
receiver: PenpalBReceiver::get(),
|
||||
receiver: PenpalAReceiver::get(),
|
||||
args: TestArgs::new_para(
|
||||
penpal_as_seen_by_ah,
|
||||
ah_to_penpal_beneficiary_id,
|
||||
@@ -704,7 +746,13 @@ fn bidirectional_teleport_foreign_assets_between_para_and_asset_hub() {
|
||||
let mut ah_to_penpal = SystemParaToParaTest::new(ah_to_penpal_test_args);
|
||||
|
||||
let ah_sender_balance_before = ah_to_penpal.sender.balance;
|
||||
let penpal_receiver_balance_before = ah_to_penpal.receiver.balance;
|
||||
let penpal_receiver_balance_before = PenpalA::execute_with(|| {
|
||||
type ForeignAssets = <PenpalA as PenpalAPallet>::ForeignAssets;
|
||||
<ForeignAssets as Inspect<_>>::balance(
|
||||
system_para_native_asset_location,
|
||||
&PenpalAReceiver::get(),
|
||||
)
|
||||
});
|
||||
|
||||
let ah_sender_assets_before = AssetHubWestend::execute_with(|| {
|
||||
type ForeignAssets = <AssetHubWestend as AssetHubWestendPallet>::ForeignAssets;
|
||||
@@ -713,18 +761,24 @@ fn bidirectional_teleport_foreign_assets_between_para_and_asset_hub() {
|
||||
&AssetHubWestendSender::get(),
|
||||
)
|
||||
});
|
||||
let penpal_receiver_assets_before = PenpalB::execute_with(|| {
|
||||
type Assets = <PenpalB as PenpalBPallet>::Assets;
|
||||
<Assets as Inspect<_>>::balance(asset_id_on_penpal, &PenpalBReceiver::get())
|
||||
let penpal_receiver_assets_before = PenpalA::execute_with(|| {
|
||||
type Assets = <PenpalA as PenpalAPallet>::Assets;
|
||||
<Assets as Inspect<_>>::balance(asset_id_on_penpal, &PenpalAReceiver::get())
|
||||
});
|
||||
|
||||
ah_to_penpal.set_assertion::<AssetHubWestend>(ah_to_penpal_foreign_assets_sender_assertions);
|
||||
ah_to_penpal.set_assertion::<PenpalB>(ah_to_penpal_foreign_assets_receiver_assertions);
|
||||
ah_to_penpal.set_assertion::<PenpalA>(ah_to_penpal_foreign_assets_receiver_assertions);
|
||||
ah_to_penpal.set_dispatchable::<AssetHubWestend>(system_para_to_para_transfer_assets);
|
||||
ah_to_penpal.assert();
|
||||
|
||||
let ah_sender_balance_after = ah_to_penpal.sender.balance;
|
||||
let penpal_receiver_balance_after = ah_to_penpal.receiver.balance;
|
||||
let penpal_receiver_balance_after = PenpalA::execute_with(|| {
|
||||
type ForeignAssets = <PenpalA as PenpalAPallet>::ForeignAssets;
|
||||
<ForeignAssets as Inspect<_>>::balance(
|
||||
system_para_native_asset_location,
|
||||
&PenpalAReceiver::get(),
|
||||
)
|
||||
});
|
||||
|
||||
let ah_sender_assets_after = AssetHubWestend::execute_with(|| {
|
||||
type ForeignAssets = <AssetHubWestend as AssetHubWestendPallet>::ForeignAssets;
|
||||
@@ -733,9 +787,9 @@ fn bidirectional_teleport_foreign_assets_between_para_and_asset_hub() {
|
||||
&AssetHubWestendSender::get(),
|
||||
)
|
||||
});
|
||||
let penpal_receiver_assets_after = PenpalB::execute_with(|| {
|
||||
type Assets = <PenpalB as PenpalBPallet>::Assets;
|
||||
<Assets as Inspect<_>>::balance(asset_id_on_penpal, &PenpalBReceiver::get())
|
||||
let penpal_receiver_assets_after = PenpalA::execute_with(|| {
|
||||
type Assets = <PenpalA as PenpalAPallet>::Assets;
|
||||
<Assets as Inspect<_>>::balance(asset_id_on_penpal, &PenpalAReceiver::get())
|
||||
});
|
||||
|
||||
// Sender's balance is reduced
|
||||
|
||||
+1
-1
@@ -13,7 +13,7 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
use crate::*;
|
||||
use crate::imports::*;
|
||||
use emulated_integration_tests_common::accounts::{ALICE, BOB};
|
||||
use frame_support::traits::fungibles::{Create, Inspect, Mutate};
|
||||
use polkadot_runtime_common::impls::VersionedLocatableAsset;
|
||||
|
||||
+22
-31
@@ -13,37 +13,30 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Substrate
|
||||
pub use frame_support::{assert_err, assert_ok, pallet_prelude::DispatchResult};
|
||||
pub use sp_runtime::DispatchError;
|
||||
#[cfg(test)]
|
||||
mod imports {
|
||||
// Substrate
|
||||
pub use frame_support::{assert_err, assert_ok, pallet_prelude::DispatchResult};
|
||||
pub use sp_runtime::DispatchError;
|
||||
|
||||
// Polkadot
|
||||
pub use xcm::{
|
||||
// Polkadot
|
||||
pub use xcm::{
|
||||
latest::ParentThen,
|
||||
prelude::{AccountId32 as AccountId32Junction, *},
|
||||
v3::{
|
||||
self, Error,
|
||||
NetworkId::{Rococo as RococoId, Westend as WestendId},
|
||||
},
|
||||
};
|
||||
v3::{self, NetworkId::Westend as WestendId},
|
||||
};
|
||||
|
||||
// Bridges
|
||||
pub use bp_messages::LaneId;
|
||||
|
||||
// Cumulus
|
||||
pub use emulated_integration_tests_common::{
|
||||
// Cumulus
|
||||
pub use emulated_integration_tests_common::{
|
||||
accounts::ALICE,
|
||||
impls::Inspect,
|
||||
test_parachain_is_trusted_teleporter,
|
||||
xcm_emulator::{
|
||||
assert_expected_events, bx, helpers::weight_within_threshold, Chain, Parachain as Para,
|
||||
RelayChain as Relay, Test, TestArgs, TestContext, TestExt,
|
||||
assert_expected_events, bx, Chain, Parachain as Para, RelayChain as Relay, TestExt,
|
||||
},
|
||||
xcm_helpers::{xcm_transact_paid_execution, xcm_transact_unpaid_execution},
|
||||
PROOF_SIZE_THRESHOLD, REF_TIME_THRESHOLD, XCM_V3,
|
||||
};
|
||||
pub use parachains_common::{AccountId, Balance};
|
||||
pub use rococo_westend_system_emulated_network::{
|
||||
};
|
||||
pub use parachains_common::AccountId;
|
||||
pub use rococo_westend_system_emulated_network::{
|
||||
asset_hub_rococo_emulated_chain::{
|
||||
genesis::ED as ASSET_HUB_ROCOCO_ED, AssetHubRococoParaPallet as AssetHubRococoPallet,
|
||||
},
|
||||
@@ -59,16 +52,14 @@ pub use rococo_westend_system_emulated_network::{
|
||||
AssetHubRococoParaSender as AssetHubRococoSender, AssetHubWestendPara as AssetHubWestend,
|
||||
AssetHubWestendParaReceiver as AssetHubWestendReceiver,
|
||||
AssetHubWestendParaSender as AssetHubWestendSender, BridgeHubRococoPara as BridgeHubRococo,
|
||||
BridgeHubRococoParaReceiver as BridgeHubRococoReceiver,
|
||||
BridgeHubRococoParaSender as BridgeHubRococoSender, BridgeHubWestendPara as BridgeHubWestend,
|
||||
PenpalAPara as PenpalA, PenpalAParaReceiver as PenpalAReceiver,
|
||||
PenpalAParaSender as PenpalASender, RococoRelay as Rococo,
|
||||
RococoRelayReceiver as RococoReceiver, RococoRelaySender as RococoSender,
|
||||
};
|
||||
BridgeHubRococoParaSender as BridgeHubRococoSender,
|
||||
BridgeHubWestendPara as BridgeHubWestend, PenpalAPara as PenpalA,
|
||||
PenpalAParaReceiver as PenpalAReceiver, PenpalAParaSender as PenpalASender,
|
||||
RococoRelay as Rococo,
|
||||
};
|
||||
|
||||
pub const ASSET_ID: u32 = 1;
|
||||
pub const ASSET_MIN_BALANCE: u128 = 1000;
|
||||
pub const ASSETS_PALLET_ID: u8 = 50;
|
||||
pub const ASSET_MIN_BALANCE: u128 = 1000;
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
|
||||
+1
-1
@@ -13,7 +13,7 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
use crate::*;
|
||||
use crate::imports::*;
|
||||
|
||||
mod asset_transfers;
|
||||
mod send_xcm;
|
||||
|
||||
+1
-1
@@ -12,7 +12,7 @@
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
use crate::*;
|
||||
use crate::imports::*;
|
||||
use bridge_hub_rococo_runtime::{EthereumBeaconClient, EthereumInboundQueue, RuntimeOrigin};
|
||||
use codec::{Decode, Encode};
|
||||
use emulated_integration_tests_common::xcm_emulator::ConvertLocation;
|
||||
|
||||
+1
-1
@@ -13,7 +13,7 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
use crate::*;
|
||||
use crate::tests::*;
|
||||
use bridge_hub_rococo_runtime::xcm_config::XcmConfig;
|
||||
|
||||
#[test]
|
||||
|
||||
+22
-29
@@ -13,38 +13,31 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Substrate
|
||||
pub use frame_support::{assert_err, assert_ok, pallet_prelude::DispatchResult};
|
||||
pub use sp_runtime::DispatchError;
|
||||
#[cfg(test)]
|
||||
mod imports {
|
||||
// Substrate
|
||||
pub use frame_support::{assert_err, assert_ok, pallet_prelude::DispatchResult};
|
||||
pub use sp_runtime::DispatchError;
|
||||
|
||||
// Polkadot
|
||||
pub use xcm::{
|
||||
// Polkadot
|
||||
pub use xcm::{
|
||||
latest::ParentThen,
|
||||
prelude::{AccountId32 as AccountId32Junction, *},
|
||||
v3,
|
||||
v4::{
|
||||
Error,
|
||||
NetworkId::{Rococo as RococoId, Westend as WestendId},
|
||||
},
|
||||
};
|
||||
v4::NetworkId::Rococo as RococoId,
|
||||
};
|
||||
|
||||
// Bridges
|
||||
pub use bp_messages::LaneId;
|
||||
|
||||
// Cumulus
|
||||
pub use emulated_integration_tests_common::{
|
||||
// Cumulus
|
||||
pub use emulated_integration_tests_common::{
|
||||
accounts::ALICE,
|
||||
impls::Inspect,
|
||||
test_parachain_is_trusted_teleporter,
|
||||
xcm_emulator::{
|
||||
assert_expected_events, bx, helpers::weight_within_threshold, Chain, Parachain as Para,
|
||||
RelayChain as Relay, Test, TestArgs, TestContext, TestExt,
|
||||
assert_expected_events, bx, Chain, Parachain as Para, RelayChain as Relay, TestExt,
|
||||
},
|
||||
xcm_helpers::{xcm_transact_paid_execution, xcm_transact_unpaid_execution},
|
||||
PROOF_SIZE_THRESHOLD, REF_TIME_THRESHOLD, XCM_V3,
|
||||
};
|
||||
pub use parachains_common::{AccountId, Balance};
|
||||
pub use rococo_westend_system_emulated_network::{
|
||||
};
|
||||
pub use parachains_common::AccountId;
|
||||
pub use rococo_westend_system_emulated_network::{
|
||||
asset_hub_rococo_emulated_chain::{
|
||||
genesis::ED as ASSET_HUB_ROCOCO_ED, AssetHubRococoParaPallet as AssetHubRococoPallet,
|
||||
},
|
||||
@@ -52,20 +45,20 @@ pub use rococo_westend_system_emulated_network::{
|
||||
genesis::ED as ASSET_HUB_WESTEND_ED, AssetHubWestendParaPallet as AssetHubWestendPallet,
|
||||
},
|
||||
bridge_hub_westend_emulated_chain::{
|
||||
genesis::ED as BRIDGE_HUB_WESTEND_ED, BridgeHubWestendParaPallet as BridgeHubWestendPallet,
|
||||
genesis::ED as BRIDGE_HUB_WESTEND_ED,
|
||||
BridgeHubWestendParaPallet as BridgeHubWestendPallet,
|
||||
},
|
||||
westend_emulated_chain::WestendRelayPallet as WestendPallet,
|
||||
AssetHubRococoPara as AssetHubRococo, AssetHubRococoParaReceiver as AssetHubRococoReceiver,
|
||||
AssetHubRococoParaSender as AssetHubRococoSender, AssetHubWestendPara as AssetHubWestend,
|
||||
AssetHubWestendParaReceiver as AssetHubWestendReceiver,
|
||||
AssetHubWestendParaSender as AssetHubWestendSender, BridgeHubRococoPara as BridgeHubRococo,
|
||||
BridgeHubWestendPara as BridgeHubWestend, BridgeHubWestendParaSender as BridgeHubWestendSender,
|
||||
WestendRelay as Westend,
|
||||
};
|
||||
BridgeHubWestendPara as BridgeHubWestend,
|
||||
BridgeHubWestendParaSender as BridgeHubWestendSender, WestendRelay as Westend,
|
||||
};
|
||||
|
||||
pub const ASSET_ID: u32 = 1;
|
||||
pub const ASSET_MIN_BALANCE: u128 = 1000;
|
||||
pub const ASSETS_PALLET_ID: u8 = 50;
|
||||
pub const ASSET_MIN_BALANCE: u128 = 1000;
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
|
||||
+1
-1
@@ -13,7 +13,7 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
use crate::*;
|
||||
use crate::imports::*;
|
||||
|
||||
mod asset_transfers;
|
||||
mod send_xcm;
|
||||
|
||||
+1
-1
@@ -13,7 +13,7 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
use crate::*;
|
||||
use crate::tests::*;
|
||||
use bridge_hub_westend_runtime::xcm_config::XcmConfig;
|
||||
|
||||
#[test]
|
||||
|
||||
+25
-36
@@ -13,52 +13,41 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
pub use codec::Encode;
|
||||
#[cfg(test)]
|
||||
mod imports {
|
||||
pub use codec::Encode;
|
||||
|
||||
// Substrate
|
||||
pub use frame_support::{
|
||||
assert_err, assert_ok,
|
||||
// Substrate
|
||||
pub use frame_support::{
|
||||
assert_ok,
|
||||
pallet_prelude::Weight,
|
||||
sp_runtime::{AccountId32, DispatchError, DispatchResult},
|
||||
sp_runtime::{AccountId32, DispatchResult},
|
||||
traits::fungibles::Inspect,
|
||||
};
|
||||
};
|
||||
|
||||
// Polkadot
|
||||
pub use xcm::{
|
||||
prelude::{AccountId32 as AccountId32Junction, *},
|
||||
v3::{Error, NetworkId::Rococo as RococoId},
|
||||
};
|
||||
// Polkadot
|
||||
pub use xcm::prelude::*;
|
||||
|
||||
// Cumulus
|
||||
pub use asset_test_utils::xcm_helpers;
|
||||
pub use emulated_integration_tests_common::{
|
||||
test_parachain_is_trusted_teleporter,
|
||||
xcm_emulator::{
|
||||
assert_expected_events, bx, helpers::weight_within_threshold, Chain, Parachain as Para,
|
||||
RelayChain as Relay, Test, TestArgs, TestContext, TestExt,
|
||||
},
|
||||
xcm_helpers::{xcm_transact_paid_execution, xcm_transact_unpaid_execution},
|
||||
PROOF_SIZE_THRESHOLD, REF_TIME_THRESHOLD, XCM_V3,
|
||||
};
|
||||
pub use parachains_common::{AccountId, Balance};
|
||||
pub use rococo_system_emulated_network::{
|
||||
// Cumulus
|
||||
pub use asset_test_utils::xcm_helpers;
|
||||
pub use emulated_integration_tests_common::xcm_emulator::{
|
||||
assert_expected_events, bx, Chain, Parachain as Para, RelayChain as Relay, Test, TestArgs,
|
||||
TestContext, TestExt,
|
||||
};
|
||||
pub use parachains_common::Balance;
|
||||
pub use rococo_system_emulated_network::{
|
||||
people_rococo_emulated_chain::{
|
||||
genesis::ED as PEOPLE_ROCOCO_ED, PeopleRococoParaPallet as PeopleRococoPallet,
|
||||
},
|
||||
rococo_emulated_chain::{genesis::ED as ROCOCO_ED, RococoRelayPallet as RococoPallet},
|
||||
PenpalAPara as PenpalA, PeopleRococoPara as PeopleRococo,
|
||||
PeopleRococoParaReceiver as PeopleRococoReceiver, PeopleRococoParaSender as PeopleRococoSender,
|
||||
RococoRelay as Rococo, RococoRelayReceiver as RococoReceiver,
|
||||
RococoRelaySender as RococoSender,
|
||||
};
|
||||
PeopleRococoPara as PeopleRococo, PeopleRococoParaReceiver as PeopleRococoReceiver,
|
||||
PeopleRococoParaSender as PeopleRococoSender, RococoRelay as Rococo,
|
||||
RococoRelayReceiver as RococoReceiver, RococoRelaySender as RococoSender,
|
||||
};
|
||||
|
||||
// pub const ASSET_ID: u32 = 1;
|
||||
// pub const ASSET_MIN_BALANCE: u128 = 1000;
|
||||
pub type RelayToSystemParaTest = Test<Rococo, PeopleRococo>;
|
||||
pub type RelayToParaTest = Test<Rococo, PenpalA>;
|
||||
pub type SystemParaToRelayTest = Test<PeopleRococo, Rococo>;
|
||||
pub type SystemParaToParaTest = Test<PeopleRococo, PenpalA>;
|
||||
pub type ParaToSystemParaTest = Test<PenpalA, PeopleRococo>;
|
||||
pub type RelayToSystemParaTest = Test<Rococo, PeopleRococo>;
|
||||
pub type SystemParaToRelayTest = Test<PeopleRococo, Rococo>;
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
|
||||
+1
-1
@@ -38,7 +38,7 @@
|
||||
//! - The freed deposit from the Relay Chain is sufficient for the parachain deposit; and
|
||||
//! - The account will exist on the parachain.
|
||||
|
||||
use crate::*;
|
||||
use crate::imports::*;
|
||||
use frame_support::BoundedVec;
|
||||
use pallet_balances::Event as BalancesEvent;
|
||||
use pallet_identity::{legacy::IdentityInfo, Data, Event as IdentityEvent};
|
||||
|
||||
+1
-1
@@ -13,7 +13,7 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
use crate::*;
|
||||
use crate::imports::*;
|
||||
use people_rococo_runtime::xcm_config::XcmConfig as PeopleRococoXcmConfig;
|
||||
use rococo_runtime::xcm_config::XcmConfig as RococoXcmConfig;
|
||||
|
||||
|
||||
+23
-35
@@ -13,52 +13,40 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
pub use codec::Encode;
|
||||
|
||||
// Substrate
|
||||
pub use frame_support::{
|
||||
assert_err, assert_ok,
|
||||
#[cfg(test)]
|
||||
mod imports {
|
||||
pub use codec::Encode;
|
||||
// Substrate
|
||||
pub use frame_support::{
|
||||
assert_ok,
|
||||
pallet_prelude::Weight,
|
||||
sp_runtime::{AccountId32, DispatchError, DispatchResult},
|
||||
sp_runtime::{AccountId32, DispatchResult},
|
||||
traits::fungibles::Inspect,
|
||||
};
|
||||
};
|
||||
|
||||
// Polkadot
|
||||
pub use xcm::{
|
||||
prelude::{AccountId32 as AccountId32Junction, *},
|
||||
v3::{Error, NetworkId::Westend as WestendId},
|
||||
};
|
||||
// Polkadot
|
||||
pub use xcm::prelude::*;
|
||||
|
||||
// Cumulus
|
||||
pub use asset_test_utils::xcm_helpers;
|
||||
pub use emulated_integration_tests_common::{
|
||||
test_parachain_is_trusted_teleporter,
|
||||
xcm_emulator::{
|
||||
assert_expected_events, bx, helpers::weight_within_threshold, Chain, Parachain as Para,
|
||||
RelayChain as Relay, Test, TestArgs, TestContext, TestExt,
|
||||
},
|
||||
xcm_helpers::{xcm_transact_paid_execution, xcm_transact_unpaid_execution},
|
||||
PROOF_SIZE_THRESHOLD, REF_TIME_THRESHOLD, XCM_V3,
|
||||
};
|
||||
pub use parachains_common::{AccountId, Balance};
|
||||
pub use westend_system_emulated_network::{
|
||||
// Cumulus
|
||||
pub use asset_test_utils::xcm_helpers;
|
||||
pub use emulated_integration_tests_common::xcm_emulator::{
|
||||
assert_expected_events, bx, Chain, Parachain as Para, RelayChain as Relay, Test, TestArgs,
|
||||
TestContext, TestExt,
|
||||
};
|
||||
pub use parachains_common::Balance;
|
||||
pub use westend_system_emulated_network::{
|
||||
people_westend_emulated_chain::{
|
||||
genesis::ED as PEOPLE_WESTEND_ED, PeopleWestendParaPallet as PeopleWestendPallet,
|
||||
},
|
||||
westend_emulated_chain::{genesis::ED as WESTEND_ED, WestendRelayPallet as WestendPallet},
|
||||
PenpalAPara as PenpalA, PeopleWestendPara as PeopleWestend,
|
||||
PeopleWestendParaReceiver as PeopleWestendReceiver,
|
||||
PeopleWestendPara as PeopleWestend, PeopleWestendParaReceiver as PeopleWestendReceiver,
|
||||
PeopleWestendParaSender as PeopleWestendSender, WestendRelay as Westend,
|
||||
WestendRelayReceiver as WestendReceiver, WestendRelaySender as WestendSender,
|
||||
};
|
||||
};
|
||||
|
||||
// pub const ASSET_ID: u32 = 1;
|
||||
// pub const ASSET_MIN_BALANCE: u128 = 1000;
|
||||
pub type RelayToSystemParaTest = Test<Westend, PeopleWestend>;
|
||||
pub type RelayToParaTest = Test<Westend, PenpalA>;
|
||||
pub type SystemParaToRelayTest = Test<PeopleWestend, Westend>;
|
||||
pub type SystemParaToParaTest = Test<PeopleWestend, PenpalA>;
|
||||
pub type ParaToSystemParaTest = Test<PenpalA, PeopleWestend>;
|
||||
pub type RelayToSystemParaTest = Test<Westend, PeopleWestend>;
|
||||
pub type SystemParaToRelayTest = Test<PeopleWestend, Westend>;
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
|
||||
+1
-1
@@ -38,7 +38,7 @@
|
||||
//! - The freed deposit from the Relay Chain is sufficient for the parachain deposit; and
|
||||
//! - The account will exist on the parachain.
|
||||
|
||||
use crate::*;
|
||||
use crate::imports::*;
|
||||
use frame_support::BoundedVec;
|
||||
use pallet_balances::Event as BalancesEvent;
|
||||
use pallet_identity::{legacy::IdentityInfo, Data, Event as IdentityEvent};
|
||||
|
||||
+1
-1
@@ -13,7 +13,7 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
use crate::*;
|
||||
use crate::imports::*;
|
||||
use people_westend_runtime::xcm_config::XcmConfig as PeopleWestendXcmConfig;
|
||||
use westend_runtime::xcm_config::XcmConfig as WestendXcmConfig;
|
||||
|
||||
|
||||
@@ -527,10 +527,10 @@ fn test_foreign_asset_xcm_take_first_trader() {
|
||||
let bought = Weight::from_parts(4_000_000_000u64, 0);
|
||||
|
||||
// Lets calculate amount needed
|
||||
let asset_amount_needed =
|
||||
ForeignAssetFeeAsExistentialDepositMultiplierFeeCharger::charge_weight_in_fungibles(
|
||||
let asset_amount_needed
|
||||
= ForeignAssetFeeAsExistentialDepositMultiplierFeeCharger::charge_weight_in_fungibles(
|
||||
foreign_location,
|
||||
bought,
|
||||
bought
|
||||
)
|
||||
.expect("failed to compute");
|
||||
|
||||
|
||||
@@ -527,11 +527,7 @@ fn test_foreign_asset_xcm_take_first_trader() {
|
||||
let bought = Weight::from_parts(4_000_000_000u64, 0);
|
||||
|
||||
// Lets calculate amount needed
|
||||
let asset_amount_needed =
|
||||
ForeignAssetFeeAsExistentialDepositMultiplierFeeCharger::charge_weight_in_fungibles(
|
||||
foreign_location,
|
||||
bought,
|
||||
)
|
||||
let asset_amount_needed = ForeignAssetFeeAsExistentialDepositMultiplierFeeCharger::charge_weight_in_fungibles(foreign_location, bought)
|
||||
.expect("failed to compute");
|
||||
|
||||
// Lets pay with: asset_amount_needed + asset_amount_extra
|
||||
|
||||
@@ -53,7 +53,10 @@ use frame_system::{
|
||||
limits::{BlockLength, BlockWeights},
|
||||
EnsureRoot, EnsureSigned,
|
||||
};
|
||||
use parachains_common::message_queue::{NarrowOriginToSibling, ParaIdToSibling};
|
||||
use parachains_common::{
|
||||
impls::{AssetsToBlockAuthor, NonZeroIssuance},
|
||||
message_queue::{NarrowOriginToSibling, ParaIdToSibling},
|
||||
};
|
||||
use polkadot_runtime_common::xcm_sender::NoPriceForMessageDelivery;
|
||||
use smallvec::smallvec;
|
||||
use sp_api::impl_runtime_apis;
|
||||
@@ -70,7 +73,7 @@ use sp_std::prelude::*;
|
||||
#[cfg(feature = "std")]
|
||||
use sp_version::NativeVersion;
|
||||
use sp_version::RuntimeVersion;
|
||||
use xcm_config::{AssetsToBlockAuthor, XcmOriginToTransactDispatchOrigin};
|
||||
use xcm_config::XcmOriginToTransactDispatchOrigin;
|
||||
|
||||
#[cfg(any(feature = "std", test))]
|
||||
pub use sp_runtime::BuildStorage;
|
||||
@@ -618,7 +621,7 @@ impl pallet_asset_tx_payment::Config for Runtime {
|
||||
ConvertInto,
|
||||
pallet_assets::Instance1,
|
||||
>,
|
||||
AssetsToBlockAuthor<Runtime>,
|
||||
AssetsToBlockAuthor<Runtime, pallet_assets::Instance1>,
|
||||
>;
|
||||
}
|
||||
|
||||
|
||||
@@ -23,41 +23,39 @@
|
||||
//! `ReserveAssetTransferDeposited` message but that will but the intension will be to support this
|
||||
//! soon.
|
||||
use super::{
|
||||
AccountId, AllPalletsWithSystem, AssetId as AssetIdPalletAssets, Assets, Balance, Balances,
|
||||
ForeignAssets, ParachainInfo, ParachainSystem, PolkadotXcm, Runtime, RuntimeCall, RuntimeEvent,
|
||||
RuntimeOrigin, WeightToFee, XcmpQueue,
|
||||
AccountId, AllPalletsWithSystem, AssetId as AssetIdPalletAssets, Assets, Authorship, Balance,
|
||||
Balances, ForeignAssets, ForeignAssetsInstance, NonZeroIssuance, ParachainInfo,
|
||||
ParachainSystem, PolkadotXcm, Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin, WeightToFee,
|
||||
XcmpQueue,
|
||||
};
|
||||
use core::marker::PhantomData;
|
||||
use frame_support::{
|
||||
parameter_types,
|
||||
traits::{
|
||||
fungibles::{self, Balanced, Credit},
|
||||
ConstU32, Contains, ContainsPair, Everything, Get, Nothing,
|
||||
},
|
||||
traits::{ConstU32, Contains, ContainsPair, Everything, EverythingBut, Get, Nothing},
|
||||
weights::Weight,
|
||||
};
|
||||
use frame_system::EnsureRoot;
|
||||
use pallet_asset_tx_payment::HandleCredit;
|
||||
use pallet_assets::Instance1;
|
||||
use pallet_xcm::XcmPassthrough;
|
||||
use parachains_common::xcm_config::AssetFeeAsExistentialDepositMultiplier;
|
||||
use polkadot_parachain_primitives::primitives::Sibling;
|
||||
use polkadot_runtime_common::impls::ToAuthor;
|
||||
use sp_runtime::traits::Zero;
|
||||
use sp_runtime::traits::ConvertInto;
|
||||
use xcm::latest::prelude::*;
|
||||
use xcm_builder::{
|
||||
AccountId32Aliases, AllowExplicitUnpaidExecutionFrom, AllowKnownQueryResponses,
|
||||
AllowSubscriptionsFrom, AllowTopLevelPaidExecutionFrom, AsPrefixedGeneralIndex,
|
||||
ConvertedConcreteId, EnsureXcmOrigin, FixedWeightBounds, FrameTransactionalProcessor,
|
||||
FungibleAdapter, FungiblesAdapter, IsConcrete, LocalMint, NativeAsset, NoChecking,
|
||||
ParentAsSuperuser, ParentIsPreset, RelayChainAsNative, SiblingParachainAsNative,
|
||||
SiblingParachainConvertsVia, SignedAccountId32AsNative, SignedToAccountId32,
|
||||
SovereignSignedViaLocation, StartsWith, TakeWeightCredit, TrailingSetTopicAsId,
|
||||
UsingComponents, WithComputedOrigin, WithUniqueTopic,
|
||||
AccountId32Aliases, AllowKnownQueryResponses, AllowSubscriptionsFrom,
|
||||
AllowTopLevelPaidExecutionFrom, AsPrefixedGeneralIndex, ConvertedConcreteId, EnsureXcmOrigin,
|
||||
FixedWeightBounds, FrameTransactionalProcessor, FungibleAdapter, FungiblesAdapter, IsConcrete,
|
||||
LocalMint, NativeAsset, NoChecking, ParentAsSuperuser, ParentIsPreset, RelayChainAsNative,
|
||||
SiblingParachainAsNative, SiblingParachainConvertsVia, SignedAccountId32AsNative,
|
||||
SignedToAccountId32, SovereignSignedViaLocation, StartsWith, TakeWeightCredit,
|
||||
TrailingSetTopicAsId, UsingComponents, WithComputedOrigin, WithUniqueTopic,
|
||||
};
|
||||
use xcm_executor::{traits::JustTry, XcmExecutor};
|
||||
|
||||
parameter_types! {
|
||||
pub const RelayLocation: Location = Location::parent();
|
||||
// Local native currency which is stored in `pallet_balances``
|
||||
pub const PenpalNativeCurrency: Location = Location::here();
|
||||
pub const RelayNetwork: Option<NetworkId> = None;
|
||||
pub RelayChainOrigin: RuntimeOrigin = cumulus_pallet_xcm::Origin::Relay.into();
|
||||
pub UniversalLocation: InteriorLocation = [Parachain(ParachainInfo::parachain_id().into())].into();
|
||||
@@ -80,7 +78,7 @@ pub type CurrencyTransactor = FungibleAdapter<
|
||||
// Use this currency:
|
||||
Balances,
|
||||
// Use this currency when it is a fungible asset matching the given location or name:
|
||||
IsConcrete<RelayLocation>,
|
||||
IsConcrete<PenpalNativeCurrency>,
|
||||
// Do a simple punn to convert an AccountId32 Location into a native chain account ID:
|
||||
LocationToAccountId,
|
||||
// Our chain's account ID type (we can't get away without mentioning it explicitly):
|
||||
@@ -123,9 +121,16 @@ pub type FungiblesTransactor = FungiblesAdapter<
|
||||
CheckingAccount,
|
||||
>;
|
||||
|
||||
/// `AssetId/Balance` converter for `TrustBackedAssets`
|
||||
pub type ForeignAssetsConvertedConcreteId =
|
||||
assets_common::ForeignAssetsConvertedConcreteId<StartsWith<RelayLocation>, Balance>;
|
||||
pub type ForeignAssetsConvertedConcreteId = assets_common::LocationConvertedConcreteId<
|
||||
EverythingBut<(
|
||||
// Here we rely on fact that something like this works:
|
||||
// assert!(Location::new(1,
|
||||
// [Parachain(100)]).starts_with(&Location::parent()));
|
||||
// assert!([Parachain(100)].into().starts_with(&Here));
|
||||
StartsWith<assets_common::matching::LocalLocationPattern>,
|
||||
)>,
|
||||
Balance,
|
||||
>;
|
||||
|
||||
/// Means for transacting foreign assets from different global consensus.
|
||||
pub type ForeignFungiblesTransactor = FungiblesAdapter<
|
||||
@@ -175,6 +180,7 @@ parameter_types! {
|
||||
pub UnitWeightCost: Weight = Weight::from_parts(1_000_000_000, 64 * 1024);
|
||||
pub const MaxInstructions: u32 = 100;
|
||||
pub const MaxAssetsIntoHolding: u32 = 64;
|
||||
pub XcmAssetFeesReceiver: Option<AccountId> = Authorship::author();
|
||||
}
|
||||
|
||||
pub struct ParentOrParentsExecutivePlurality;
|
||||
@@ -184,13 +190,6 @@ impl Contains<Location> for ParentOrParentsExecutivePlurality {
|
||||
}
|
||||
}
|
||||
|
||||
pub struct CommonGoodAssetsParachain;
|
||||
impl Contains<Location> for CommonGoodAssetsParachain {
|
||||
fn contains(location: &Location) -> bool {
|
||||
matches!(location.unpack(), (1, [Parachain(1000)]))
|
||||
}
|
||||
}
|
||||
|
||||
pub type Barrier = TrailingSetTopicAsId<(
|
||||
TakeWeightCredit,
|
||||
// Expected responses are OK.
|
||||
@@ -201,12 +200,6 @@ pub type Barrier = TrailingSetTopicAsId<(
|
||||
// If the message is one that immediately attempts to pay for execution, then
|
||||
// allow it.
|
||||
AllowTopLevelPaidExecutionFrom<Everything>,
|
||||
// System Assets parachain, parent and its exec plurality get free
|
||||
// execution
|
||||
AllowExplicitUnpaidExecutionFrom<(
|
||||
CommonGoodAssetsParachain,
|
||||
ParentOrParentsExecutivePlurality,
|
||||
)>,
|
||||
// Subscriptions for version tracking are OK.
|
||||
AllowSubscriptionsFrom<Everything>,
|
||||
),
|
||||
@@ -246,53 +239,30 @@ impl<T: Get<Location>> ContainsPair<Asset, Location> for NativeAssetFrom<T> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Allow checking in assets that have issuance > 0.
|
||||
pub struct NonZeroIssuance<AccountId, Assets>(PhantomData<(AccountId, Assets)>);
|
||||
impl<AccountId, Assets> Contains<<Assets as fungibles::Inspect<AccountId>>::AssetId>
|
||||
for NonZeroIssuance<AccountId, Assets>
|
||||
where
|
||||
Assets: fungibles::Inspect<AccountId>,
|
||||
{
|
||||
fn contains(id: &<Assets as fungibles::Inspect<AccountId>>::AssetId) -> bool {
|
||||
!Assets::total_issuance(id.clone()).is_zero()
|
||||
}
|
||||
}
|
||||
|
||||
/// A `HandleCredit` implementation that naively transfers the fees to the block author.
|
||||
/// Will drop and burn the assets in case the transfer fails.
|
||||
pub struct AssetsToBlockAuthor<R>(PhantomData<R>);
|
||||
impl<R> HandleCredit<AccountIdOf<R>, pallet_assets::Pallet<R, Instance1>> for AssetsToBlockAuthor<R>
|
||||
where
|
||||
R: pallet_authorship::Config + pallet_assets::Config<Instance1>,
|
||||
AccountIdOf<R>: From<polkadot_primitives::AccountId> + Into<polkadot_primitives::AccountId>,
|
||||
{
|
||||
fn handle_credit(credit: Credit<AccountIdOf<R>, pallet_assets::Pallet<R, Instance1>>) {
|
||||
if let Some(author) = pallet_authorship::Pallet::<R>::author() {
|
||||
// In case of error: Will drop the result triggering the `OnDrop` of the imbalance.
|
||||
let _ = pallet_assets::Pallet::<R, Instance1>::resolve(&author, credit);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// This asset can be added to AH as Asset and reserved transfer between Penpal and AH
|
||||
pub const RESERVABLE_ASSET_ID: u32 = 1;
|
||||
// This asset can be added to AH as ForeignAsset and teleported between Penpal and AH
|
||||
pub const TELEPORTABLE_ASSET_ID: u32 = 2;
|
||||
|
||||
pub const ASSETS_PALLET_ID: u8 = 50;
|
||||
pub const ASSET_HUB_ID: u32 = 1000;
|
||||
|
||||
parameter_types! {
|
||||
/// The location that this chain recognizes as the Relay network's Asset Hub.
|
||||
pub SystemAssetHubLocation: Location = Location::new(1, [Parachain(1000)]);
|
||||
// ALWAYS ensure that the index in PalletInstance stays up-to-date with
|
||||
pub SystemAssetHubLocation: Location = Location::new(1, [Parachain(ASSET_HUB_ID)]);
|
||||
// the Relay Chain's Asset Hub's Assets pallet index
|
||||
pub SystemAssetHubAssetsPalletLocation: Location =
|
||||
Location::new(1, [Parachain(1000), PalletInstance(50)]);
|
||||
Location::new(1, [Parachain(ASSET_HUB_ID), PalletInstance(ASSETS_PALLET_ID)]);
|
||||
pub AssetsPalletLocation: Location =
|
||||
Location::new(0, [PalletInstance(50)]);
|
||||
Location::new(0, [PalletInstance(ASSETS_PALLET_ID)]);
|
||||
pub CheckingAccount: AccountId = PolkadotXcm::check_account();
|
||||
pub LocalTeleportableToAssetHub: Location = Location::new(
|
||||
0,
|
||||
[PalletInstance(50), GeneralIndex(TELEPORTABLE_ASSET_ID.into())]
|
||||
[PalletInstance(ASSETS_PALLET_ID), GeneralIndex(TELEPORTABLE_ASSET_ID.into())]
|
||||
);
|
||||
pub LocalTeleportableToAssetHubV3: xcm::v3::Location = xcm::v3::Location::new(
|
||||
0,
|
||||
[xcm::v3::Junction::PalletInstance(50), xcm::v3::Junction::GeneralIndex(TELEPORTABLE_ASSET_ID.into())]
|
||||
pub LocalReservableFromAssetHub: Location = Location::new(
|
||||
1,
|
||||
[Parachain(ASSET_HUB_ID), PalletInstance(ASSETS_PALLET_ID), GeneralIndex(RESERVABLE_ASSET_ID.into())]
|
||||
);
|
||||
|
||||
/// The Penpal runtime is utilized for testing with various environment setups.
|
||||
@@ -337,8 +307,22 @@ impl xcm_executor::Config for XcmConfig {
|
||||
type UniversalLocation = UniversalLocation;
|
||||
type Barrier = Barrier;
|
||||
type Weigher = FixedWeightBounds<UnitWeightCost, RuntimeCall, MaxInstructions>;
|
||||
type Trader =
|
||||
UsingComponents<WeightToFee, RelayLocation, AccountId, Balances, ToAuthor<Runtime>>;
|
||||
type Trader = (
|
||||
UsingComponents<WeightToFee, RelayLocation, AccountId, Balances, ToAuthor<Runtime>>,
|
||||
// This trader allows to pay with `is_sufficient=true` "Foreign" assets from dedicated
|
||||
// `pallet_assets` instance - `ForeignAssets`.
|
||||
cumulus_primitives_utility::TakeFirstAssetTrader<
|
||||
AccountId,
|
||||
ForeignAssetFeeAsExistentialDepositMultiplierFeeCharger,
|
||||
ForeignAssetsConvertedConcreteId,
|
||||
ForeignAssets,
|
||||
cumulus_primitives_utility::XcmFeesTo32ByteAccount<
|
||||
ForeignFungiblesTransactor,
|
||||
AccountId,
|
||||
XcmAssetFeesReceiver,
|
||||
>,
|
||||
>,
|
||||
);
|
||||
type ResponseHandler = PolkadotXcm;
|
||||
type AssetTrap = PolkadotXcm;
|
||||
type AssetClaims = PolkadotXcm;
|
||||
@@ -356,6 +340,15 @@ impl xcm_executor::Config for XcmConfig {
|
||||
type TransactionalProcessor = FrameTransactionalProcessor;
|
||||
}
|
||||
|
||||
/// Multiplier used for dedicated `TakeFirstAssetTrader` with `ForeignAssets` instance.
|
||||
pub type ForeignAssetFeeAsExistentialDepositMultiplierFeeCharger =
|
||||
AssetFeeAsExistentialDepositMultiplier<
|
||||
Runtime,
|
||||
WeightToFee,
|
||||
pallet_assets::BalanceToAssetBalance<Balances, Runtime, ConvertInto, ForeignAssetsInstance>,
|
||||
ForeignAssetsInstance,
|
||||
>;
|
||||
|
||||
/// No local origins on this chain are allowed to dispatch XCM sends/executions.
|
||||
pub type LocalOriginToLocation = SignedToAccountId32<RuntimeOrigin, AccountId, RelayNetwork>;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user