mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-05-30 18:41:03 +00:00
Add Support for Foreign Assets (#2133)
* add foreign assets to westmint * add foreign assets to statemine * use updated api for ensure origin trait * Assets/ForeignAssets tests and fixes (#2167) * Test for create and transfer `TrustBackedAssets` with AssetTransactor * Test for transfer `local Currency` with AssetTransactor * Test for create foreign assets (covers foreign relaychain currency) * Added `ForeignFungiblesTransactor` and test for transfer `ForeignAssets` with AssetTransactor * Removed unused `pub const Local: MultiLocation` * Changed `ParaId -> Sibling` for `SiblingParachainConvertsVia` * Test for create foreign assets (covers local sibling parachain assets) * Reverted stuff for ForeignCreators from different global consensus (moved to transfer asset branch) * Refactor `weight_limit` for `execute_xcm` * Added test for `set_metadata` by ForeignCreator with `xcm::Transact(set_metadata)` * Renamed `receive_teleported_asset_works` -> `receive_teleported_asset_for_native_asset_works` * Allow `ForeignCreators` only for sibling parachains * Unify ReservedDmpWeight/ReservedXcmpWeight usage * Removed hack - replaced with `MatchedConvertedConcreteId` * Refactor `ForeignCreators` to assets-common * Add `ReceiveTeleportedAsset` test * Change test - `Utility::batch` -> Multiple `xcm::Transact` * Reusing the same deposits as for TrustBackedAssets * missing `try_successful_origin` ? * Finished `ForeignAssets` for westmint (converter, FungiblesApi, tests) * Refactoring tests - receive_teleported_asset_for_native_asset_works * ForeignAssets for statemine + refactored `receive_teleported_asset_from_foreign_creator_works` * Add `ForeignAssets` to statemine `FungiblesApi` * Add `asset_transactor_transfer_with_local_consensus_currency_works` to all runtimes * Added `asset_transactor_transfer_with_trust_backed_assets_works` test * Added `asset_transactor_transfer_with_foreign_assets_works` * Fix `missing `try_successful_origin` in implementation` * Added `create_and_manage_foreign_assets_for_local_consensus_parachain_assets_works` * Added `ExpectTransactStatus` check * Small rename * Extended `test_assets_balances_api_works` with ForeignAssets for `statemine` * PR fixes * Update parachains/runtimes/assets/test-utils/src/test_cases.rs --------- Co-authored-by: parity-processbot <> Co-authored-by: joe petrowski <25483142+joepetrowski@users.noreply.github.com> * Added `StartsWithExplicitGlobalConsensus` to ignores (#2338) * Update parachains/runtimes/assets/common/src/lib.rs Co-authored-by: Gavin Wood <gavin@parity.io> * include mint and burn in SafeCallFilter * include mint and burn in SafeCallFilter (statemine) * clarify doc * Fix compilation (moved trait `InspectMetadata`) * Fix test * Extended test for `teleport` from/to relaychain + `CheckingAccount` (Part I) * Extended test for `teleport` from/to foreign parachain + `CheckingAccount` (Part II) * Fixed TODO - `NonLocal` for `ForeignAssets` * Changed `NonLocal` to `NoChecking` * Fix weight in test --------- Co-authored-by: parity-processbot <> Co-authored-by: muharem <ismailov.m.h@gmail.com> Co-authored-by: Branislav Kontur <bkontur@gmail.com> Co-authored-by: Gavin Wood <gavin@parity.io>
This commit is contained in:
@@ -112,6 +112,7 @@ runtime-benchmarks = [
|
||||
"cumulus-pallet-xcmp-queue/runtime-benchmarks",
|
||||
"pallet-xcm-benchmarks/runtime-benchmarks",
|
||||
"pallet-state-trie-migration/runtime-benchmarks",
|
||||
"assets-common/runtime-benchmarks",
|
||||
]
|
||||
try-runtime = [
|
||||
"cumulus-pallet-aura-ext/try-runtime",
|
||||
|
||||
@@ -66,19 +66,23 @@ use parachains_common::{
|
||||
NORMAL_DISPATCH_RATIO, SLOT_DURATION,
|
||||
};
|
||||
use xcm_config::{
|
||||
FellowshipLocation, GovernanceLocation, KsmLocation, TrustBackedAssetsConvertedConcreteId,
|
||||
XcmConfig,
|
||||
FellowshipLocation, ForeignAssetsConvertedConcreteId, GovernanceLocation, KsmLocation,
|
||||
TrustBackedAssetsConvertedConcreteId, XcmConfig,
|
||||
};
|
||||
|
||||
#[cfg(any(feature = "std", test))]
|
||||
pub use sp_runtime::BuildStorage;
|
||||
|
||||
// Polkadot imports
|
||||
use assets_common::{
|
||||
foreign_creators::ForeignCreators, matching::FromSiblingParachain, MultiLocationForAssetId,
|
||||
};
|
||||
use pallet_xcm::{EnsureXcm, IsVoiceOfBody};
|
||||
use polkadot_runtime_common::{BlockHashCount, SlowAdjustingFeeUpdate};
|
||||
use xcm::latest::BodyId;
|
||||
use xcm_executor::XcmExecutor;
|
||||
|
||||
use crate::xcm_config::ForeignCreatorsSovereignAccountOf;
|
||||
use weights::{BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight};
|
||||
|
||||
impl_opaque_keys! {
|
||||
@@ -264,6 +268,48 @@ impl pallet_assets::Config<TrustBackedAssetsInstance> for Runtime {
|
||||
type BenchmarkHelper = ();
|
||||
}
|
||||
|
||||
parameter_types! {
|
||||
// we just reuse the same deposits
|
||||
pub const ForeignAssetsAssetDeposit: Balance = AssetDeposit::get();
|
||||
pub const ForeignAssetsAssetAccountDeposit: Balance = AssetAccountDeposit::get();
|
||||
pub const ForeignAssetsApprovalDeposit: Balance = ApprovalDeposit::get();
|
||||
pub const ForeignAssetsAssetsStringLimit: u32 = AssetsStringLimit::get();
|
||||
pub const ForeignAssetsMetadataDepositBase: Balance = MetadataDepositBase::get();
|
||||
pub const ForeignAssetsMetadataDepositPerByte: Balance = MetadataDepositPerByte::get();
|
||||
}
|
||||
|
||||
/// Assets managed by some foreign location. Note: we do not declare a `ForeignAssetsCall` type, as
|
||||
/// this type is used in proxy definitions. We assume that a foreign location would not want to set
|
||||
/// an individual, local account as a proxy for the issuance of their assets. This issuance should
|
||||
/// be managed by the foreign location's governance.
|
||||
pub type ForeignAssetsInstance = pallet_assets::Instance2;
|
||||
impl pallet_assets::Config<ForeignAssetsInstance> for Runtime {
|
||||
type RuntimeEvent = RuntimeEvent;
|
||||
type Balance = Balance;
|
||||
type AssetId = MultiLocationForAssetId;
|
||||
type AssetIdParameter = MultiLocationForAssetId;
|
||||
type Currency = Balances;
|
||||
type CreateOrigin = ForeignCreators<
|
||||
(FromSiblingParachain<parachain_info::Pallet<Runtime>>,),
|
||||
ForeignCreatorsSovereignAccountOf,
|
||||
AccountId,
|
||||
>;
|
||||
type ForceOrigin = AssetsForceOrigin;
|
||||
type AssetDeposit = ForeignAssetsAssetDeposit;
|
||||
type MetadataDepositBase = ForeignAssetsMetadataDepositBase;
|
||||
type MetadataDepositPerByte = ForeignAssetsMetadataDepositPerByte;
|
||||
type ApprovalDeposit = ForeignAssetsApprovalDeposit;
|
||||
type StringLimit = ForeignAssetsAssetsStringLimit;
|
||||
type Freezer = ();
|
||||
type Extra = ();
|
||||
type WeightInfo = weights::pallet_assets::WeightInfo<Runtime>;
|
||||
type CallbackHandle = ();
|
||||
type AssetAccountDeposit = ForeignAssetsAssetAccountDeposit;
|
||||
type RemoveItemsLimit = frame_support::traits::ConstU32<1000>;
|
||||
#[cfg(feature = "runtime-benchmarks")]
|
||||
type BenchmarkHelper = xcm_config::XcmBenchmarkHelper;
|
||||
}
|
||||
|
||||
parameter_types! {
|
||||
// One storage item; key size is 32; value is size 4+4+16+32 bytes = 56 bytes.
|
||||
pub const DepositBase: Balance = deposit(1, 88);
|
||||
@@ -336,6 +382,7 @@ impl Default for ProxyType {
|
||||
Self::Any
|
||||
}
|
||||
}
|
||||
|
||||
impl InstanceFilter<RuntimeCall> for ProxyType {
|
||||
fn filter(&self, c: &RuntimeCall) -> bool {
|
||||
match self {
|
||||
@@ -689,6 +736,7 @@ construct_runtime!(
|
||||
Assets: pallet_assets::<Instance1>::{Pallet, Call, Storage, Event<T>} = 50,
|
||||
Uniques: pallet_uniques::{Pallet, Call, Storage, Event<T>} = 51,
|
||||
Nfts: pallet_nfts::{Pallet, Call, Storage, Event<T>} = 52,
|
||||
ForeignAssets: pallet_assets::<Instance2>::{Pallet, Call, Storage, Event<T>} = 53,
|
||||
|
||||
#[cfg(feature = "state-trie-version-1")]
|
||||
StateTrieMigration: pallet_state_trie_migration = 70,
|
||||
@@ -741,6 +789,7 @@ mod benches {
|
||||
define_benchmarks!(
|
||||
[frame_system, SystemBench::<Runtime>]
|
||||
[pallet_assets, Assets]
|
||||
[pallet_assets, ForeignAssets]
|
||||
[pallet_balances, Balances]
|
||||
[pallet_multisig, Multisig]
|
||||
[pallet_nfts, Nfts]
|
||||
@@ -916,11 +965,17 @@ impl_runtime_apis! {
|
||||
},
|
||||
// collect pallet_assets (TrustBackedAssets)
|
||||
convert::<_, _, _, _, TrustBackedAssetsConvertedConcreteId>(
|
||||
Assets::account_balances(account)
|
||||
Assets::account_balances(account.clone())
|
||||
.iter()
|
||||
.filter(|(_, balance)| balance > &0)
|
||||
)?,
|
||||
// collect ... e.g. pallet_assets ForeignAssets
|
||||
// collect pallet_assets (ForeignAssets)
|
||||
convert::<_, _, _, _, ForeignAssetsConvertedConcreteId>(
|
||||
ForeignAssets::account_balances(account)
|
||||
.iter()
|
||||
.filter(|(_, balance)| balance > &0)
|
||||
)?,
|
||||
// collect ... e.g. other tokens
|
||||
].concat())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,10 +14,13 @@
|
||||
// limitations under the License.
|
||||
|
||||
use super::{
|
||||
AccountId, AllPalletsWithSystem, Assets, Authorship, Balance, Balances, ParachainInfo,
|
||||
ParachainSystem, PolkadotXcm, Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin,
|
||||
AccountId, AllPalletsWithSystem, Assets, Authorship, Balance, Balances, ForeignAssets,
|
||||
ParachainInfo, ParachainSystem, PolkadotXcm, Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin,
|
||||
TrustBackedAssetsInstance, WeightToFee, XcmpQueue,
|
||||
};
|
||||
use assets_common::matching::{
|
||||
FromSiblingParachain, IsForeignConcreteAsset, StartsWith, StartsWithExplicitGlobalConsensus,
|
||||
};
|
||||
use frame_support::{
|
||||
match_types, parameter_types,
|
||||
traits::{ConstU32, Contains, Everything, Nothing, PalletInfoAccess},
|
||||
@@ -36,8 +39,8 @@ use xcm::latest::prelude::*;
|
||||
use xcm_builder::{
|
||||
AccountId32Aliases, AllowExplicitUnpaidExecutionFrom, AllowKnownQueryResponses,
|
||||
AllowSubscriptionsFrom, AllowTopLevelPaidExecutionFrom, CurrencyAdapter, EnsureXcmOrigin,
|
||||
FungiblesAdapter, IsConcrete, LocalMint, NativeAsset, ParentAsSuperuser, ParentIsPreset,
|
||||
RelayChainAsNative, SiblingParachainAsNative, SiblingParachainConvertsVia,
|
||||
FungiblesAdapter, IsConcrete, LocalMint, NativeAsset, NoChecking, ParentAsSuperuser,
|
||||
ParentIsPreset, RelayChainAsNative, SiblingParachainAsNative, SiblingParachainConvertsVia,
|
||||
SignedAccountId32AsNative, SignedToAccountId32, SovereignSignedViaLocation, TakeWeightCredit,
|
||||
UsingComponents, WeightInfoBounds, WithComputedOrigin,
|
||||
};
|
||||
@@ -49,7 +52,7 @@ parameter_types! {
|
||||
pub RelayChainOrigin: RuntimeOrigin = cumulus_pallet_xcm::Origin::Relay.into();
|
||||
pub UniversalLocation: InteriorMultiLocation =
|
||||
X2(GlobalConsensus(RelayNetwork::get().unwrap()), Parachain(ParachainInfo::parachain_id().into()));
|
||||
pub const Local: MultiLocation = Here.into_location();
|
||||
pub UniversalLocationNetworkId: NetworkId = UniversalLocation::get().global_consensus().unwrap();
|
||||
pub TrustBackedAssetsPalletLocation: MultiLocation =
|
||||
PalletInstance(<Assets as PalletInfoAccess>::index() as u8).into();
|
||||
pub CheckingAccount: AccountId = PolkadotXcm::check_account();
|
||||
@@ -83,7 +86,7 @@ pub type CurrencyTransactor = CurrencyAdapter<
|
||||
(),
|
||||
>;
|
||||
|
||||
/// `AssetId/Balancer` converter for `TrustBackedAssets`
|
||||
/// `AssetId/Balance` converter for `TrustBackedAssets`
|
||||
pub type TrustBackedAssetsConvertedConcreteId =
|
||||
assets_common::TrustBackedAssetsConvertedConcreteId<TrustBackedAssetsPalletLocation, Balance>;
|
||||
|
||||
@@ -103,8 +106,38 @@ pub type FungiblesTransactor = FungiblesAdapter<
|
||||
// The account to use for tracking teleports.
|
||||
CheckingAccount,
|
||||
>;
|
||||
|
||||
/// `AssetId/Balance` converter for `TrustBackedAssets`
|
||||
pub type ForeignAssetsConvertedConcreteId = assets_common::ForeignAssetsConvertedConcreteId<
|
||||
(
|
||||
// Ignore `TrustBackedAssets` explicitly
|
||||
StartsWith<TrustBackedAssetsPalletLocation>,
|
||||
// Ignore asset which starts explicitly with our `GlobalConsensus(NetworkId)`, means:
|
||||
// - foreign assets from our consensus should be: `MultiLocation {parent: 1, X*(Parachain(xyz))}
|
||||
// - foreign assets outside our consensus with the same `GlobalConsensus(NetworkId)` wont be accepted here
|
||||
StartsWithExplicitGlobalConsensus<UniversalLocationNetworkId>,
|
||||
),
|
||||
Balance,
|
||||
>;
|
||||
|
||||
/// Means for transacting foreign assets from different global consensus.
|
||||
pub type ForeignFungiblesTransactor = FungiblesAdapter<
|
||||
// Use this fungibles implementation:
|
||||
ForeignAssets,
|
||||
// Use this currency when it is a fungible asset matching the given location or name:
|
||||
ForeignAssetsConvertedConcreteId,
|
||||
// Convert an XCM MultiLocation into a local account id:
|
||||
LocationToAccountId,
|
||||
// Our chain's account ID type (we can't get away without mentioning it explicitly):
|
||||
AccountId,
|
||||
// We dont need to check teleports here.
|
||||
NoChecking,
|
||||
// The account to use for tracking teleports.
|
||||
CheckingAccount,
|
||||
>;
|
||||
|
||||
/// Means for transacting assets on this chain.
|
||||
pub type AssetTransactors = (CurrencyTransactor, FungiblesTransactor);
|
||||
pub type AssetTransactors = (CurrencyTransactor, FungiblesTransactor, ForeignFungiblesTransactor);
|
||||
|
||||
/// This is the type we use to convert an (incoming) XCM origin into a local `Origin` instance,
|
||||
/// ready for dispatching a transaction with Xcm's `Transact`. There is an `OriginKind` which can
|
||||
@@ -213,6 +246,35 @@ impl Contains<RuntimeCall> for SafeCallFilter {
|
||||
pallet_assets::Call::touch { .. } |
|
||||
pallet_assets::Call::refund { .. },
|
||||
) |
|
||||
RuntimeCall::ForeignAssets(
|
||||
pallet_assets::Call::create { .. } |
|
||||
pallet_assets::Call::force_create { .. } |
|
||||
pallet_assets::Call::start_destroy { .. } |
|
||||
pallet_assets::Call::destroy_accounts { .. } |
|
||||
pallet_assets::Call::destroy_approvals { .. } |
|
||||
pallet_assets::Call::finish_destroy { .. } |
|
||||
pallet_assets::Call::mint { .. } |
|
||||
pallet_assets::Call::burn { .. } |
|
||||
pallet_assets::Call::transfer { .. } |
|
||||
pallet_assets::Call::transfer_keep_alive { .. } |
|
||||
pallet_assets::Call::force_transfer { .. } |
|
||||
pallet_assets::Call::freeze { .. } |
|
||||
pallet_assets::Call::thaw { .. } |
|
||||
pallet_assets::Call::freeze_asset { .. } |
|
||||
pallet_assets::Call::thaw_asset { .. } |
|
||||
pallet_assets::Call::transfer_ownership { .. } |
|
||||
pallet_assets::Call::set_team { .. } |
|
||||
pallet_assets::Call::set_metadata { .. } |
|
||||
pallet_assets::Call::clear_metadata { .. } |
|
||||
pallet_assets::Call::force_clear_metadata { .. } |
|
||||
pallet_assets::Call::force_asset_status { .. } |
|
||||
pallet_assets::Call::approve_transfer { .. } |
|
||||
pallet_assets::Call::cancel_approval { .. } |
|
||||
pallet_assets::Call::force_cancel_approval { .. } |
|
||||
pallet_assets::Call::transfer_approved { .. } |
|
||||
pallet_assets::Call::touch { .. } |
|
||||
pallet_assets::Call::refund { .. },
|
||||
) |
|
||||
RuntimeCall::Nfts(
|
||||
pallet_nfts::Call::create { .. } |
|
||||
pallet_nfts::Call::force_create { .. } |
|
||||
@@ -322,7 +384,13 @@ impl xcm_executor::Config for XcmConfig {
|
||||
// Statemine acting _as_ a reserve location for KSM and assets created under `pallet-assets`.
|
||||
// For KSM, users must use teleport where allowed (e.g. with the Relay Chain).
|
||||
type IsReserve = ();
|
||||
type IsTeleporter = NativeAsset; // <- should be enough to allow teleportation of KSM
|
||||
// We allow:
|
||||
// - teleportation of KSM
|
||||
// - teleportation of sibling parachain's assets (as ForeignCreators)
|
||||
type IsTeleporter = (
|
||||
NativeAsset,
|
||||
IsForeignConcreteAsset<FromSiblingParachain<parachain_info::Pallet<Runtime>>>,
|
||||
);
|
||||
type UniversalLocation = UniversalLocation;
|
||||
type Barrier = Barrier;
|
||||
type Weigher = WeightInfoBounds<
|
||||
@@ -415,3 +483,20 @@ impl cumulus_pallet_xcm::Config for Runtime {
|
||||
type RuntimeEvent = RuntimeEvent;
|
||||
type XcmExecutor = XcmExecutor<XcmConfig>;
|
||||
}
|
||||
|
||||
pub type ForeignCreatorsSovereignAccountOf = (
|
||||
SiblingParachainConvertsVia<Sibling, AccountId>,
|
||||
AccountId32Aliases<RelayNetwork, AccountId>,
|
||||
ParentIsPreset<AccountId>,
|
||||
);
|
||||
|
||||
/// Simple conversion of `u32` into an `AssetId` for use in benchmarking.
|
||||
pub struct XcmBenchmarkHelper;
|
||||
#[cfg(feature = "runtime-benchmarks")]
|
||||
use pallet_assets::BenchmarkHelper;
|
||||
#[cfg(feature = "runtime-benchmarks")]
|
||||
impl BenchmarkHelper<MultiLocation> for XcmBenchmarkHelper {
|
||||
fn create_asset_id_parameter(id: u32) -> MultiLocation {
|
||||
MultiLocation { parents: 1, interior: X1(Parachain(id)) }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,25 +1,27 @@
|
||||
use asset_test_utils::{ExtBuilder, RuntimeHelper};
|
||||
use codec::Encode;
|
||||
use codec::{Decode, Encode};
|
||||
use cumulus_primitives_utility::ChargeWeightInFungibles;
|
||||
use frame_support::{
|
||||
assert_noop, assert_ok, sp_io,
|
||||
assert_noop, assert_ok,
|
||||
traits::fungibles::InspectEnumerable,
|
||||
weights::{Weight, WeightToFee as WeightToFeeT},
|
||||
};
|
||||
use parachains_common::{AccountId, AuraId, Balance};
|
||||
use parachains_common::{AccountId, AssetIdForTrustBackedAssets, AuraId, Balance};
|
||||
use statemine_runtime::xcm_config::{
|
||||
AssetFeeAsExistentialDepositMultiplierFeeCharger, KsmLocation, TrustBackedAssetsPalletLocation,
|
||||
};
|
||||
pub use statemine_runtime::{
|
||||
constants::fee::WeightToFee, xcm_config::XcmConfig, Assets, Balances, ExistentialDeposit,
|
||||
ReservedDmpWeight, Runtime, SessionKeys, System,
|
||||
constants::fee::WeightToFee,
|
||||
xcm_config::{CheckingAccount, ForeignCreatorsSovereignAccountOf, XcmConfig},
|
||||
AssetDeposit, Assets, Balances, ExistentialDeposit, ForeignAssets, ForeignAssetsInstance,
|
||||
MetadataDepositBase, MetadataDepositPerByte, ParachainSystem, Runtime, RuntimeCall,
|
||||
RuntimeEvent, SessionKeys, System, TrustBackedAssetsInstance,
|
||||
};
|
||||
use xcm::latest::prelude::*;
|
||||
use xcm_executor::{
|
||||
traits::{Convert, WeightTrader},
|
||||
XcmExecutor,
|
||||
};
|
||||
use xcm_executor::traits::{Convert, Identity, JustTry, WeightTrader};
|
||||
|
||||
pub const ALICE: [u8; 32] = [1u8; 32];
|
||||
const ALICE: [u8; 32] = [1u8; 32];
|
||||
const SOME_ASSET_ADMIN: [u8; 32] = [5u8; 32];
|
||||
|
||||
type AssetIdForTrustBackedAssetsConvert =
|
||||
assets_common::AssetIdForTrustBackedAssetsConvert<TrustBackedAssetsPalletLocation>;
|
||||
@@ -371,9 +373,15 @@ fn test_assets_balances_api_works() {
|
||||
.build()
|
||||
.execute_with(|| {
|
||||
let local_asset_id = 1;
|
||||
let foreign_asset_id_multilocation =
|
||||
MultiLocation { parents: 1, interior: X2(Parachain(1234), GeneralIndex(12345)) };
|
||||
|
||||
// check before
|
||||
assert_eq!(Assets::balance(local_asset_id, AccountId::from(ALICE)), 0);
|
||||
assert_eq!(
|
||||
ForeignAssets::balance(foreign_asset_id_multilocation, AccountId::from(ALICE)),
|
||||
0
|
||||
);
|
||||
assert_eq!(Balances::free_balance(AccountId::from(ALICE)), 0);
|
||||
assert!(Runtime::query_account_balances(AccountId::from(ALICE)).unwrap().is_empty());
|
||||
|
||||
@@ -400,15 +408,37 @@ fn test_assets_balances_api_works() {
|
||||
minimum_asset_balance
|
||||
));
|
||||
|
||||
// create foreign asset
|
||||
let foreign_asset_minimum_asset_balance = 3333333_u128;
|
||||
assert_ok!(ForeignAssets::force_create(
|
||||
RuntimeHelper::<Runtime>::root_origin(),
|
||||
foreign_asset_id_multilocation.clone().into(),
|
||||
AccountId::from(SOME_ASSET_ADMIN).into(),
|
||||
false,
|
||||
foreign_asset_minimum_asset_balance
|
||||
));
|
||||
|
||||
// We first mint enough asset for the account to exist for assets
|
||||
assert_ok!(ForeignAssets::mint(
|
||||
RuntimeHelper::<Runtime>::origin_of(AccountId::from(SOME_ASSET_ADMIN)),
|
||||
foreign_asset_id_multilocation.clone().into(),
|
||||
AccountId::from(ALICE).into(),
|
||||
6 * foreign_asset_minimum_asset_balance
|
||||
));
|
||||
|
||||
// check after
|
||||
assert_eq!(
|
||||
Assets::balance(local_asset_id, AccountId::from(ALICE)),
|
||||
minimum_asset_balance
|
||||
);
|
||||
assert_eq!(
|
||||
ForeignAssets::balance(foreign_asset_id_multilocation, AccountId::from(ALICE)),
|
||||
6 * minimum_asset_balance
|
||||
);
|
||||
assert_eq!(Balances::free_balance(AccountId::from(ALICE)), some_currency);
|
||||
|
||||
let result = Runtime::query_account_balances(AccountId::from(ALICE)).unwrap();
|
||||
assert_eq!(result.len(), 2);
|
||||
assert_eq!(result.len(), 3);
|
||||
|
||||
// check currency
|
||||
assert!(result.iter().any(|asset| asset.eq(
|
||||
@@ -423,53 +453,162 @@ fn test_assets_balances_api_works() {
|
||||
minimum_asset_balance
|
||||
)
|
||||
.into())));
|
||||
// check foreign asset
|
||||
assert!(result.iter().any(|asset| asset.eq(&(
|
||||
Identity::reverse_ref(foreign_asset_id_multilocation).unwrap(),
|
||||
6 * foreign_asset_minimum_asset_balance
|
||||
)
|
||||
.into())));
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn receive_teleported_asset_works() {
|
||||
ExtBuilder::<Runtime>::default()
|
||||
.with_collators(vec![AccountId::from(ALICE)])
|
||||
.with_session_keys(vec![(
|
||||
AccountId::from(ALICE),
|
||||
AccountId::from(ALICE),
|
||||
SessionKeys { aura: AuraId::from(sp_core::sr25519::Public::from_raw(ALICE)) },
|
||||
)])
|
||||
.build()
|
||||
.execute_with(|| {
|
||||
let xcm = Xcm(vec![
|
||||
ReceiveTeleportedAsset(MultiAssets::from(vec![MultiAsset {
|
||||
id: Concrete(MultiLocation { parents: 1, interior: Here }),
|
||||
fun: Fungible(10000000000000),
|
||||
}])),
|
||||
ClearOrigin,
|
||||
BuyExecution {
|
||||
fees: MultiAsset {
|
||||
id: Concrete(MultiLocation { parents: 1, interior: Here }),
|
||||
fun: Fungible(10000000000000),
|
||||
},
|
||||
weight_limit: Limited(Weight::from_parts(303531000, 65536)),
|
||||
},
|
||||
DepositAsset {
|
||||
assets: Wild(AllCounted(1)),
|
||||
beneficiary: MultiLocation {
|
||||
parents: 0,
|
||||
interior: X1(AccountId32 {
|
||||
network: None,
|
||||
id: [
|
||||
18, 153, 85, 112, 1, 245, 88, 21, 211, 252, 181, 60, 116, 70, 58,
|
||||
203, 12, 246, 209, 77, 70, 57, 179, 64, 152, 44, 96, 135, 127, 56,
|
||||
70, 9,
|
||||
],
|
||||
}),
|
||||
},
|
||||
},
|
||||
]);
|
||||
let hash = xcm.using_encoded(sp_io::hashing::blake2_256);
|
||||
asset_test_utils::include_teleports_for_native_asset_works!(
|
||||
Runtime,
|
||||
XcmConfig,
|
||||
CheckingAccount,
|
||||
WeightToFee,
|
||||
ParachainSystem,
|
||||
asset_test_utils::CollatorSessionKeys::new(
|
||||
AccountId::from(ALICE),
|
||||
AccountId::from(ALICE),
|
||||
SessionKeys { aura: AuraId::from(sp_core::sr25519::Public::from_raw(ALICE)) }
|
||||
),
|
||||
ExistentialDeposit::get(),
|
||||
Box::new(|runtime_event_encoded: Vec<u8>| {
|
||||
match RuntimeEvent::decode(&mut &runtime_event_encoded[..]) {
|
||||
Ok(RuntimeEvent::PolkadotXcm(event)) => Some(event),
|
||||
_ => None,
|
||||
}
|
||||
}),
|
||||
Box::new(|runtime_event_encoded: Vec<u8>| {
|
||||
match RuntimeEvent::decode(&mut &runtime_event_encoded[..]) {
|
||||
Ok(RuntimeEvent::XcmpQueue(event)) => Some(event),
|
||||
_ => None,
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
let weight_limit = ReservedDmpWeight::get();
|
||||
asset_test_utils::include_teleports_for_foreign_assets_works!(
|
||||
Runtime,
|
||||
XcmConfig,
|
||||
CheckingAccount,
|
||||
WeightToFee,
|
||||
ParachainSystem,
|
||||
ForeignCreatorsSovereignAccountOf,
|
||||
ForeignAssetsInstance,
|
||||
asset_test_utils::CollatorSessionKeys::new(
|
||||
AccountId::from(ALICE),
|
||||
AccountId::from(ALICE),
|
||||
SessionKeys { aura: AuraId::from(sp_core::sr25519::Public::from_raw(ALICE)) }
|
||||
),
|
||||
ExistentialDeposit::get(),
|
||||
Box::new(|runtime_event_encoded: Vec<u8>| {
|
||||
match RuntimeEvent::decode(&mut &runtime_event_encoded[..]) {
|
||||
Ok(RuntimeEvent::PolkadotXcm(event)) => Some(event),
|
||||
_ => None,
|
||||
}
|
||||
}),
|
||||
Box::new(|runtime_event_encoded: Vec<u8>| {
|
||||
match RuntimeEvent::decode(&mut &runtime_event_encoded[..]) {
|
||||
Ok(RuntimeEvent::XcmpQueue(event)) => Some(event),
|
||||
_ => None,
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
let outcome = XcmExecutor::<XcmConfig>::execute_xcm(Parent, xcm, hash, weight_limit);
|
||||
assert_eq!(outcome.ensure_complete(), Ok(()));
|
||||
})
|
||||
}
|
||||
asset_test_utils::include_asset_transactor_transfer_with_local_consensus_currency_works!(
|
||||
Runtime,
|
||||
XcmConfig,
|
||||
asset_test_utils::CollatorSessionKeys::new(
|
||||
AccountId::from(ALICE),
|
||||
AccountId::from(ALICE),
|
||||
SessionKeys { aura: AuraId::from(sp_core::sr25519::Public::from_raw(ALICE)) }
|
||||
),
|
||||
ExistentialDeposit::get(),
|
||||
Box::new(|| {
|
||||
assert!(Assets::asset_ids().collect::<Vec<_>>().is_empty());
|
||||
assert!(ForeignAssets::asset_ids().collect::<Vec<_>>().is_empty());
|
||||
}),
|
||||
Box::new(|| {
|
||||
assert!(Assets::asset_ids().collect::<Vec<_>>().is_empty());
|
||||
assert!(ForeignAssets::asset_ids().collect::<Vec<_>>().is_empty());
|
||||
})
|
||||
);
|
||||
|
||||
asset_test_utils::include_asset_transactor_transfer_with_pallet_assets_instance_works!(
|
||||
asset_transactor_transfer_with_trust_backed_assets_works,
|
||||
Runtime,
|
||||
XcmConfig,
|
||||
TrustBackedAssetsInstance,
|
||||
AssetIdForTrustBackedAssets,
|
||||
AssetIdForTrustBackedAssetsConvert,
|
||||
asset_test_utils::CollatorSessionKeys::new(
|
||||
AccountId::from(ALICE),
|
||||
AccountId::from(ALICE),
|
||||
SessionKeys { aura: AuraId::from(sp_core::sr25519::Public::from_raw(ALICE)) }
|
||||
),
|
||||
ExistentialDeposit::get(),
|
||||
12345,
|
||||
Box::new(|| {
|
||||
assert!(ForeignAssets::asset_ids().collect::<Vec<_>>().is_empty());
|
||||
}),
|
||||
Box::new(|| {
|
||||
assert!(ForeignAssets::asset_ids().collect::<Vec<_>>().is_empty());
|
||||
})
|
||||
);
|
||||
|
||||
asset_test_utils::include_asset_transactor_transfer_with_pallet_assets_instance_works!(
|
||||
asset_transactor_transfer_with_foreign_assets_works,
|
||||
Runtime,
|
||||
XcmConfig,
|
||||
ForeignAssetsInstance,
|
||||
MultiLocation,
|
||||
JustTry,
|
||||
asset_test_utils::CollatorSessionKeys::new(
|
||||
AccountId::from(ALICE),
|
||||
AccountId::from(ALICE),
|
||||
SessionKeys { aura: AuraId::from(sp_core::sr25519::Public::from_raw(ALICE)) }
|
||||
),
|
||||
ExistentialDeposit::get(),
|
||||
MultiLocation { parents: 1, interior: X2(Parachain(1313), GeneralIndex(12345)) },
|
||||
Box::new(|| {
|
||||
assert!(Assets::asset_ids().collect::<Vec<_>>().is_empty());
|
||||
}),
|
||||
Box::new(|| {
|
||||
assert!(Assets::asset_ids().collect::<Vec<_>>().is_empty());
|
||||
})
|
||||
);
|
||||
|
||||
asset_test_utils::include_create_and_manage_foreign_assets_for_local_consensus_parachain_assets_works!(
|
||||
Runtime,
|
||||
XcmConfig,
|
||||
WeightToFee,
|
||||
ForeignCreatorsSovereignAccountOf,
|
||||
ForeignAssetsInstance,
|
||||
MultiLocation,
|
||||
JustTry,
|
||||
asset_test_utils::CollatorSessionKeys::new(
|
||||
AccountId::from(ALICE),
|
||||
AccountId::from(ALICE),
|
||||
SessionKeys { aura: AuraId::from(sp_core::sr25519::Public::from_raw(ALICE)) }
|
||||
),
|
||||
ExistentialDeposit::get(),
|
||||
AssetDeposit::get(),
|
||||
MetadataDepositBase::get(),
|
||||
MetadataDepositPerByte::get(),
|
||||
Box::new(|pallet_asset_call| RuntimeCall::ForeignAssets(pallet_asset_call).encode()),
|
||||
Box::new(|runtime_event_encoded: Vec<u8>| {
|
||||
match RuntimeEvent::decode(&mut &runtime_event_encoded[..]) {
|
||||
Ok(RuntimeEvent::ForeignAssets(pallet_asset_event)) => Some(pallet_asset_event),
|
||||
_ => None,
|
||||
}
|
||||
}),
|
||||
Box::new(|| {
|
||||
assert!(Assets::asset_ids().collect::<Vec<_>>().is_empty());
|
||||
assert!(ForeignAssets::asset_ids().collect::<Vec<_>>().is_empty());
|
||||
}),
|
||||
Box::new(|| {
|
||||
assert!(Assets::asset_ids().collect::<Vec<_>>().is_empty());
|
||||
assert_eq!(ForeignAssets::asset_ids().collect::<Vec<_>>().len(), 1);
|
||||
})
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user