diff --git a/Cargo.dev.toml b/Cargo.dev.toml index 30a098746..9b9f5906e 100644 --- a/Cargo.dev.toml +++ b/Cargo.dev.toml @@ -81,6 +81,7 @@ sp-transaction-pool = { git = "https://github.com/paritytech//substrate", rev = sp-trie = { git = "https://github.com/paritytech//substrate", rev = "9c572625f6557dfdb19f47474369a0327d51dfbc" } sp-version = { git = "https://github.com/paritytech//substrate", rev = "9c572625f6557dfdb19f47474369a0327d51dfbc" } sp-wasm-interface = { git = "https://github.com/paritytech//substrate", rev = "9c572625f6557dfdb19f47474369a0327d51dfbc" } +sp-utils = { git = "https://github.com/paritytech//substrate", rev = "9c572625f6557dfdb19f47474369a0327d51dfbc" } [patch.'https://github.com/paritytech/cumulus'] cumulus-primitives-core = { git = "https://github.com/paritytech//cumulus", rev = "c5c3abf7eb9d4fdfb588d6560efaa8dca66a8dbc" } diff --git a/xtokens/Cargo.toml b/xtokens/Cargo.toml index 1f4ad373f..a44713f8c 100644 --- a/xtokens/Cargo.toml +++ b/xtokens/Cargo.toml @@ -26,17 +26,26 @@ orml-xcm-support = { path = "../xcm-support", default-features = false } orml-traits = { path = "../traits", default-features = false} [dev-dependencies] -# sp-core = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.7" } -# polkadot-core-primitives = { git = "https://github.com/paritytech/polkadot", branch = "release-v0.9.7" } -# polkadot-parachain = { git = "https://github.com/paritytech/polkadot", branch = "release-v0.9.7" } -# pallet-balances = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.7" } -# xcm-simulator = { git = "https://github.com/shaunxw/xcm-simulator", branch = "master" } -# parachain-info = { git = "https://github.com/paritytech/cumulus", branch = "polkadot-v0.9.7" } -# xcm-executor = { git = "https://github.com/paritytech/polkadot", branch = "release-v0.9.7" } -# xcm-builder = { git = "https://github.com/paritytech/polkadot", branch = "release-v0.9.7" } - -# orml-tokens = { path = "../tokens" } -# orml-traits = { path = "../traits" } +sp-core = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.7" } +pallet-balances = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.7" } + +# cumulus +cumulus-primitives-core = { git = "https://github.com/paritytech/cumulus", branch = "polkadot-v0.9.7" } +cumulus-pallet-dmp-queue = { git = "https://github.com/paritytech/cumulus", branch = "polkadot-v0.9.7" } +cumulus-pallet-xcmp-queue = { git = "https://github.com/paritytech/cumulus", branch = "polkadot-v0.9.7" } +cumulus-pallet-xcm = { git = "https://github.com/paritytech/cumulus", branch = "polkadot-v0.9.7" } +parachain-info = { git = "https://github.com/paritytech/cumulus", branch = "polkadot-v0.9.7" } + +# polkadot +polkadot-parachain = { git = "https://github.com/paritytech/polkadot", branch = "release-v0.9.7" } +xcm = { git = "https://github.com/paritytech/polkadot", branch = "release-v0.9.7" } +xcm-executor = { git = "https://github.com/paritytech/polkadot", branch = "release-v0.9.7" } +xcm-builder = { git = "https://github.com/paritytech/polkadot", branch = "release-v0.9.7" } +pallet-xcm = { git = "https://github.com/paritytech/polkadot", branch = "release-v0.9.7" } +polkadot-runtime-parachains = { git = "https://github.com/paritytech/polkadot", branch = "release-v0.9.7" } + +orml-tokens = { path = "../tokens" } +xcm-simulator = { git = "https://github.com/shaunxw/xcm-simulator.git", branch = "polkadot-v0.9.7"} [features] default = ["std"] @@ -55,3 +64,8 @@ std = [ "orml-traits/std", ] try-runtime = ["frame-support/try-runtime"] +# Needed because of cargo feature pollution. +runtime-benchmarks = [ + "xcm-builder/runtime-benchmarks", + "pallet-xcm/runtime-benchmarks", +] diff --git a/xtokens/src/lib.rs b/xtokens/src/lib.rs index 356351939..4581634ba 100644 --- a/xtokens/src/lib.rs +++ b/xtokens/src/lib.rs @@ -41,8 +41,8 @@ use xcm_executor::traits::WeightBounds; pub use module::*; use orml_traits::location::{Parse, Reserve}; -// mod mock; -// mod tests; +mod mock; +mod tests; enum TransferKind { /// Transfer self reserve asset. diff --git a/xtokens/src/mock.rs b/xtokens/src/mock.rs deleted file mode 100644 index fab7d9505..000000000 --- a/xtokens/src/mock.rs +++ /dev/null @@ -1,470 +0,0 @@ -#![cfg(test)] - -use super::*; -use crate as orml_xtokens; - -use frame_support::parameter_types; -use orml_traits::parameter_type_with_key; -use orml_xcm_support::{IsNativeConcrete, MultiCurrencyAdapter, MultiNativeAsset, XcmHandler as XcmHandlerT}; -use polkadot_parachain::primitives::Sibling; -use serde::{Deserialize, Serialize}; -use sp_io::TestExternalities; -use sp_runtime::AccountId32; -use xcm::v0::{Junction, MultiLocation::*, NetworkId}; -use xcm_builder::{ - AccountId32Aliases, LocationInverter, ParentIsDefault, RelayChainAsNative, SiblingParachainAsNative, - SiblingParachainConvertsVia, SignedAccountId32AsNative, SovereignSignedViaLocation, -}; -use xcm_executor::Config as XcmConfigT; -use xcm_simulator::{decl_test_network, decl_test_parachain, prelude::*}; - -pub const ALICE: AccountId32 = AccountId32::new([0u8; 32]); -pub const BOB: AccountId32 = AccountId32::new([1u8; 32]); - -#[derive(Encode, Decode, Eq, PartialEq, Copy, Clone, RuntimeDebug, PartialOrd, Ord)] -#[cfg_attr(feature = "std", derive(Serialize, Deserialize))] -pub enum CurrencyId { - /// Relay chain token. - R, - /// Parachain A token. - A, - /// Parachain B token. - B, -} - -pub struct CurrencyIdConvert; -impl Convert> for CurrencyIdConvert { - fn convert(id: CurrencyId) -> Option { - match id { - CurrencyId::R => Some(Junction::Parent.into()), - CurrencyId::A => Some( - ( - Junction::Parent, - Junction::Parachain { id: 1 }, - Junction::GeneralKey("A".into()), - ) - .into(), - ), - CurrencyId::B => Some( - ( - Junction::Parent, - Junction::Parachain { id: 2 }, - Junction::GeneralKey("B".into()), - ) - .into(), - ), - } - } -} -impl Convert> for CurrencyIdConvert { - fn convert(l: MultiLocation) -> Option { - let a: Vec = "A".into(); - let b: Vec = "B".into(); - match l { - X1(Parent) => Some(CurrencyId::R), - X3(Junction::Parent, Junction::Parachain { id: 1 }, Junction::GeneralKey(k)) if k == a => { - Some(CurrencyId::A) - } - X3(Junction::Parent, Junction::Parachain { id: 2 }, Junction::GeneralKey(k)) if k == b => { - Some(CurrencyId::B) - } - _ => None, - } - } -} -impl Convert> for CurrencyIdConvert { - fn convert(a: MultiAsset) -> Option { - if let MultiAsset::ConcreteFungible { id, amount: _ } = a { - Self::convert(id) - } else { - None - } - } -} - -pub type Balance = u128; -pub type Amount = i128; - -decl_test_parachain! { - pub struct ParaA { - new_ext = parachain_ext::(1), - para_id = 1, - } - pub mod para_a { - test_network = super::TestNetwork, - xcm_config = { - use super::*; - - parameter_types! { - pub ParaANetwork: NetworkId = NetworkId::Any; - pub RelayChainOrigin: Origin = cumulus_pallet_xcm_handler::Origin::Relay.into(); - pub Ancestry: MultiLocation = MultiLocation::X1(Junction::Parachain { - id: ParachainInfo::get().into(), - }); - pub const RelayChainCurrencyId: CurrencyId = CurrencyId::R; - } - - pub type LocationConverter = ( - ParentIsDefault, - SiblingParachainConvertsVia, - AccountId32Aliases, - ); - - pub type LocalAssetTransactor = MultiCurrencyAdapter< - Tokens, - (), - IsNativeConcrete, - AccountId, - LocationConverter, - CurrencyId, - CurrencyIdConvert, - >; - - pub type LocalOriginConverter = ( - SovereignSignedViaLocation, - RelayChainAsNative, - SiblingParachainAsNative, - SignedAccountId32AsNative, - ); - - pub struct XcmConfig; - impl XcmConfigT for XcmConfig { - type Call = Call; - type XcmSender = XcmHandler; - type AssetTransactor = LocalAssetTransactor; - type OriginConverter = LocalOriginConverter; - type IsReserve = MultiNativeAsset; - type IsTeleporter = (); - type LocationInverter = LocationInverter; - } - }, - extra_config = { - parameter_type_with_key! { - pub ExistentialDeposits: |_currency_id: super::CurrencyId| -> Balance { - Default::default() - }; - } - - impl orml_tokens::Config for Runtime { - type Event = Event; - type Balance = Balance; - type Amount = Amount; - type CurrencyId = super::CurrencyId; - type WeightInfo = (); - type ExistentialDeposits = ExistentialDeposits; - type OnDust = (); - } - - pub struct HandleXcm; - impl XcmHandlerT for HandleXcm { - fn execute_xcm(origin: AccountId, xcm: Xcm) -> DispatchResult { - XcmHandler::execute_xcm(origin, xcm) - } - } - - pub struct AccountId32Convert; - impl Convert for AccountId32Convert { - fn convert(account_id: AccountId) -> [u8; 32] { - account_id.into() - } - } - - parameter_types! { - pub SelfLocation: MultiLocation = (Junction::Parent, Junction::Parachain { id: ParachainInfo::get().into() }).into(); - } - - impl orml_xtokens::Config for Runtime { - type Event = Event; - type Balance = Balance; - type CurrencyId = CurrencyId; - type CurrencyIdConvert = CurrencyIdConvert; - type AccountId32Convert = AccountId32Convert; - type SelfLocation = SelfLocation; - type XcmHandler = HandleXcm; - } - }, - extra_modules = { - Tokens: orml_tokens::{Pallet, Storage, Event, Config}, - XTokens: orml_xtokens::{Pallet, Storage, Call, Event}, - }, - } -} - -decl_test_parachain! { - pub struct ParaB { - new_ext = parachain_ext::(2), - para_id = 2, - } - pub mod para_c { - test_network = super::TestNetwork, - xcm_config = { - use super::*; - - parameter_types! { - pub ParaANetwork: NetworkId = NetworkId::Any; - pub RelayChainOrigin: Origin = cumulus_pallet_xcm_handler::Origin::Relay.into(); - pub Ancestry: MultiLocation = MultiLocation::X1(Junction::Parachain { - id: ParachainInfo::get().into(), - }); - pub const RelayChainCurrencyId: CurrencyId = CurrencyId::R; - } - - pub type LocationConverter = ( - ParentIsDefault, - SiblingParachainConvertsVia, - AccountId32Aliases, - ); - - pub type LocalAssetTransactor = MultiCurrencyAdapter< - Tokens, - (), - IsNativeConcrete, - AccountId, - LocationConverter, - CurrencyId, - CurrencyIdConvert, - >; - - pub type LocalOriginConverter = ( - SovereignSignedViaLocation, - RelayChainAsNative, - SiblingParachainAsNative, - SignedAccountId32AsNative, - ); - - pub struct XcmConfig; - impl XcmConfigT for XcmConfig { - type Call = Call; - type XcmSender = XcmHandler; - type AssetTransactor = LocalAssetTransactor; - type OriginConverter = LocalOriginConverter; - type IsReserve = MultiNativeAsset; - type IsTeleporter = (); - type LocationInverter = LocationInverter; - } - }, - extra_config = { - parameter_type_with_key! { - pub ExistentialDeposits: |_currency_id: super::CurrencyId| -> Balance { - Default::default() - }; - } - - impl orml_tokens::Config for Runtime { - type Event = Event; - type Balance = Balance; - type Amount = Amount; - type CurrencyId = super::CurrencyId; - type WeightInfo = (); - type ExistentialDeposits = ExistentialDeposits; - type OnDust = (); - } - - pub struct HandleXcm; - impl XcmHandlerT for HandleXcm { - fn execute_xcm(origin: AccountId, xcm: Xcm) -> DispatchResult { - XcmHandler::execute_xcm(origin, xcm) - } - } - - pub struct AccountId32Convert; - impl Convert for AccountId32Convert { - fn convert(account_id: AccountId) -> [u8; 32] { - account_id.into() - } - } - - parameter_types! { - pub SelfLocation: MultiLocation = (Junction::Parent, Junction::Parachain { id: ParachainInfo::get().into() }).into(); - } - - impl orml_xtokens::Config for Runtime { - type Event = Event; - type Balance = Balance; - type CurrencyId = CurrencyId; - type CurrencyIdConvert = CurrencyIdConvert; - type AccountId32Convert = AccountId32Convert; - type SelfLocation = SelfLocation; - type XcmHandler = HandleXcm; - } - }, - extra_modules = { - Tokens: orml_tokens::{Pallet, Storage, Event, Config}, - XTokens: orml_xtokens::{Pallet, Storage, Call, Event}, - }, - } -} - -decl_test_parachain! { - pub struct ParaC { - new_ext = parachain_ext::(3), - para_id = 3, - } - pub mod para_b { - test_network = super::TestNetwork, - xcm_config = { - use super::*; - - parameter_types! { - pub ParaANetwork: NetworkId = NetworkId::Any; - pub RelayChainOrigin: Origin = cumulus_pallet_xcm_handler::Origin::Relay.into(); - pub Ancestry: MultiLocation = MultiLocation::X1(Junction::Parachain { - id: ParachainInfo::get().into(), - }); - pub const RelayChainCurrencyId: CurrencyId = CurrencyId::R; - } - - pub type LocationConverter = ( - ParentIsDefault, - SiblingParachainConvertsVia, - AccountId32Aliases, - ); - - pub type LocalAssetTransactor = MultiCurrencyAdapter< - Tokens, - (), - IsNativeConcrete, - AccountId, - LocationConverter, - CurrencyId, - CurrencyIdConvert, - >; - - pub type LocalOriginConverter = ( - SovereignSignedViaLocation, - RelayChainAsNative, - SiblingParachainAsNative, - SignedAccountId32AsNative, - ); - - pub struct XcmConfig; - impl XcmConfigT for XcmConfig { - type Call = Call; - type XcmSender = XcmHandler; - type AssetTransactor = LocalAssetTransactor; - type OriginConverter = LocalOriginConverter; - type IsReserve = MultiNativeAsset; - type IsTeleporter = (); - type LocationInverter = LocationInverter; - } - }, - extra_config = { - parameter_type_with_key! { - pub ExistentialDeposits: |_currency_id: super::CurrencyId| -> Balance { - Default::default() - }; - } - - impl orml_tokens::Config for Runtime { - type Event = Event; - type Balance = Balance; - type Amount = Amount; - type CurrencyId = super::CurrencyId; - type WeightInfo = (); - type ExistentialDeposits = ExistentialDeposits; - type OnDust = (); - } - - pub struct HandleXcm; - impl XcmHandlerT for HandleXcm { - fn execute_xcm(origin: AccountId, xcm: Xcm) -> DispatchResult { - XcmHandler::execute_xcm(origin, xcm) - } - } - - pub struct AccountId32Convert; - impl Convert for AccountId32Convert { - fn convert(account_id: AccountId) -> [u8; 32] { - account_id.into() - } - } - - parameter_types! { - pub SelfLocation: MultiLocation = (Junction::Parent, Junction::Parachain { id: ParachainInfo::get().into() }).into(); - } - - impl orml_xtokens::Config for Runtime { - type Event = Event; - type Balance = Balance; - type CurrencyId = CurrencyId; - type CurrencyIdConvert = CurrencyIdConvert; - type AccountId32Convert = AccountId32Convert; - type SelfLocation = SelfLocation; - type XcmHandler = HandleXcm; - } - }, - extra_modules = { - Tokens: orml_tokens::{Pallet, Storage, Event, Config}, - XTokens: orml_xtokens::{Pallet, Storage, Call, Event}, - }, - } -} - -decl_test_network! { - pub struct TestNetwork { - relay_chain = default, - parachains = vec![ - (1, ParaA), - (2, ParaB), - (3, ParaC), - ], - } -} - -pub type ParaAXtokens = orml_xtokens::Pallet; -pub type ParaATokens = orml_tokens::Pallet; -pub type ParaBTokens = orml_tokens::Pallet; -pub type ParaCTokens = orml_tokens::Pallet; - -pub type RelayBalances = pallet_balances::Pallet; - -pub struct ParaExtBuilder; - -impl Default for ParaExtBuilder { - fn default() -> Self { - ParaExtBuilder - } -} - -impl ParaExtBuilder { - pub fn build< - Runtime: frame_system::Config + orml_tokens::Config, - >( - self, - para_id: u32, - ) -> TestExternalities - where - ::BlockNumber: From, - { - let mut t = frame_system::GenesisConfig::default() - .build_storage::() - .unwrap(); - - parachain_info::GenesisConfig { - parachain_id: para_id.into(), - } - .assimilate_storage(&mut t) - .unwrap(); - - orml_tokens::GenesisConfig:: { - balances: vec![(ALICE, CurrencyId::R, 100)], - } - .assimilate_storage(&mut t) - .unwrap(); - - let mut ext = TestExternalities::new(t); - ext.execute_with(|| frame_system::Pallet::::set_block_number(1.into())); - ext - } -} - -pub fn parachain_ext< - Runtime: frame_system::Config + orml_tokens::Config, ->( - para_id: u32, -) -> TestExternalities -where - ::BlockNumber: From, -{ - ParaExtBuilder::default().build::(para_id) -} diff --git a/xtokens/src/mock/mod.rs b/xtokens/src/mock/mod.rs new file mode 100644 index 000000000..ef3229d67 --- /dev/null +++ b/xtokens/src/mock/mod.rs @@ -0,0 +1,155 @@ +#![cfg(test)] + +use super::*; +use crate as orml_xtokens; + +use serde::{Deserialize, Serialize}; +use sp_io::TestExternalities; +use sp_runtime::AccountId32; + +use xcm::v0::{Junction, MultiLocation}; +use xcm_simulator::{decl_test_network, decl_test_parachain, decl_test_relay_chain}; + +pub mod para; +pub mod relay; + +pub const ALICE: AccountId32 = AccountId32::new([0u8; 32]); +pub const BOB: AccountId32 = AccountId32::new([1u8; 32]); + +#[derive(Encode, Decode, Eq, PartialEq, Copy, Clone, RuntimeDebug, PartialOrd, Ord)] +#[cfg_attr(feature = "std", derive(Serialize, Deserialize))] +pub enum CurrencyId { + /// Relay chain token. + R, + /// Parachain A token. + A, + /// Parachain B token. + B, +} + +pub struct CurrencyIdConvert; +impl Convert> for CurrencyIdConvert { + fn convert(id: CurrencyId) -> Option { + match id { + CurrencyId::R => Some(Junction::Parent.into()), + CurrencyId::A => Some( + ( + Junction::Parent, + Junction::Parachain(1), + Junction::GeneralKey("A".into()), + ) + .into(), + ), + CurrencyId::B => Some( + ( + Junction::Parent, + Junction::Parachain(2), + Junction::GeneralKey("B".into()), + ) + .into(), + ), + } + } +} +impl Convert> for CurrencyIdConvert { + fn convert(l: MultiLocation) -> Option { + let a: Vec = "A".into(); + let b: Vec = "B".into(); + match l { + X1(Parent) => Some(CurrencyId::R), + X3(Junction::Parent, Junction::Parachain(1), Junction::GeneralKey(k)) if k == a => Some(CurrencyId::A), + X3(Junction::Parent, Junction::Parachain(2), Junction::GeneralKey(k)) if k == b => Some(CurrencyId::B), + _ => Option::None, + } + } +} +impl Convert> for CurrencyIdConvert { + fn convert(a: MultiAsset) -> Option { + if let MultiAsset::ConcreteFungible { id, amount: _ } = a { + Self::convert(id) + } else { + Option::None + } + } +} + +pub type Balance = u128; +pub type Amount = i128; + +decl_test_parachain! { + pub struct ParaA { + Runtime = para::Runtime, + new_ext = para_ext(1), + } +} + +decl_test_parachain! { + pub struct ParaB { + Runtime = para::Runtime, + new_ext = para_ext(2), + } +} + +decl_test_relay_chain! { + pub struct Relay { + Runtime = relay::Runtime, + XcmConfig = relay::XcmConfig, + new_ext = relay_ext(), + } +} + +decl_test_network! { + pub struct TestNet { + relay_chain = Relay, + parachains = vec![ + (1, ParaA), + (2, ParaB), + ], + } +} + +pub type RelayBalances = pallet_balances::Pallet; +pub type ParaTokens = orml_tokens::Pallet; +pub type ParaXTokens = orml_xtokens::Pallet; + +pub fn para_ext(para_id: u32) -> TestExternalities { + use para::{Runtime, System}; + + let mut t = frame_system::GenesisConfig::default() + .build_storage::() + .unwrap(); + + let parachain_info_config = parachain_info::GenesisConfig { + parachain_id: para_id.into(), + }; + >::assimilate_storage(¶chain_info_config, &mut t) + .unwrap(); + + orml_tokens::GenesisConfig:: { + balances: vec![(ALICE, CurrencyId::R, 1_000)], + } + .assimilate_storage(&mut t) + .unwrap(); + + let mut ext = TestExternalities::new(t); + ext.execute_with(|| System::set_block_number(1)); + ext +} + +pub fn relay_ext() -> sp_io::TestExternalities { + use relay::{Runtime, System}; + + let mut t = frame_system::GenesisConfig::default() + .build_storage::() + .unwrap(); + + pallet_balances::GenesisConfig:: { + balances: vec![(ALICE, 1_000)], + } + .assimilate_storage(&mut t) + .unwrap(); + + let mut ext = sp_io::TestExternalities::new(t); + ext.execute_with(|| System::set_block_number(1)); + ext +} diff --git a/xtokens/src/mock/para.rs b/xtokens/src/mock/para.rs new file mode 100644 index 000000000..4c42d26b4 --- /dev/null +++ b/xtokens/src/mock/para.rs @@ -0,0 +1,254 @@ +use super::{Amount, Balance, CurrencyId, CurrencyIdConvert, ParachainXcmRouter}; +use crate as orml_xtokens; + +use frame_support::{ + construct_runtime, parameter_types, + traits::{All, Get}, + weights::{constants::WEIGHT_PER_SECOND, Weight}, +}; +use frame_system::EnsureRoot; +use sp_core::H256; +use sp_runtime::{ + testing::Header, + traits::{Convert, IdentityLookup}, + AccountId32, +}; + +use cumulus_primitives_core::{ChannelStatus, GetChannelInfo, ParaId}; +use pallet_xcm::XcmPassthrough; +use polkadot_parachain::primitives::Sibling; +pub use xcm::v0::{ + Junction::{self, Parachain, Parent}, + MultiAsset, + MultiLocation::{self, X1, X2, X3}, + NetworkId, Xcm, +}; +pub use xcm_builder::{ + AccountId32Aliases, AllowTopLevelPaidExecutionFrom, AllowUnpaidExecutionFrom, + CurrencyAdapter as XcmCurrencyAdapter, EnsureXcmOrigin, FixedRateOfConcreteFungible, FixedWeightBounds, IsConcrete, + LocationInverter, NativeAsset, ParentAsSuperuser, ParentIsDefault, RelayChainAsNative, SiblingParachainAsNative, + SiblingParachainConvertsVia, SignedAccountId32AsNative, SignedToAccountId32, SovereignSignedViaLocation, + TakeWeightCredit, +}; +use xcm_executor::{Config, XcmExecutor}; + +use orml_traits::parameter_type_with_key; +use orml_xcm_support::{IsNativeConcrete, MultiCurrencyAdapter}; + +pub type AccountId = AccountId32; + +parameter_types! { + pub const BlockHashCount: u64 = 250; +} + +impl frame_system::Config for Runtime { + type Origin = Origin; + type Call = Call; + type Index = u64; + type BlockNumber = u64; + type Hash = H256; + type Hashing = ::sp_runtime::traits::BlakeTwo256; + type AccountId = AccountId; + type Lookup = IdentityLookup; + type Header = Header; + type Event = Event; + type BlockHashCount = BlockHashCount; + type BlockWeights = (); + type BlockLength = (); + type Version = (); + type PalletInfo = PalletInfo; + type AccountData = pallet_balances::AccountData; + type OnNewAccount = (); + type OnKilledAccount = (); + type DbWeight = (); + type BaseCallFilter = (); + type SystemWeightInfo = (); + type SS58Prefix = (); + type OnSetCode = (); +} + +parameter_types! { + pub ExistentialDeposit: Balance = 1; + pub const MaxLocks: u32 = 50; + pub const MaxReserves: u32 = 50; +} + +impl pallet_balances::Config for Runtime { + type MaxLocks = MaxLocks; + type Balance = Balance; + type Event = Event; + type DustRemoval = (); + type ExistentialDeposit = ExistentialDeposit; + type AccountStore = System; + type WeightInfo = (); + type MaxReserves = MaxReserves; + type ReserveIdentifier = [u8; 8]; +} + +parameter_type_with_key! { + pub ExistentialDeposits: |_currency_id: CurrencyId| -> Balance { + Default::default() + }; +} + +impl orml_tokens::Config for Runtime { + type Event = Event; + type Balance = Balance; + type Amount = Amount; + type CurrencyId = CurrencyId; + type WeightInfo = (); + type ExistentialDeposits = ExistentialDeposits; + type OnDust = (); + type MaxLocks = MaxLocks; +} + +parameter_types! { + pub const ReservedXcmpWeight: Weight = WEIGHT_PER_SECOND / 4; + pub const ReservedDmpWeight: Weight = WEIGHT_PER_SECOND / 4; +} + +impl parachain_info::Config for Runtime {} + +parameter_types! { + pub const RelayLocation: MultiLocation = MultiLocation::X1(Parent); + pub const RelayNetwork: NetworkId = NetworkId::Kusama; + pub RelayChainOrigin: Origin = cumulus_pallet_xcm::Origin::Relay.into(); + pub Ancestry: MultiLocation = Parachain(ParachainInfo::parachain_id().into()).into(); +} + +pub type LocationToAccountId = ( + ParentIsDefault, + SiblingParachainConvertsVia, + AccountId32Aliases, +); + +pub type XcmOriginToCallOrigin = ( + SovereignSignedViaLocation, + RelayChainAsNative, + SiblingParachainAsNative, + SignedAccountId32AsNative, + XcmPassthrough, +); + +parameter_types! { + pub const UnitWeightCost: Weight = 10; + pub KsmPerSecond: (MultiLocation, u128) = (X1(Parent), 1_000); +} + +pub type LocalAssetTransactor = MultiCurrencyAdapter< + Tokens, + (), + IsNativeConcrete, + AccountId, + LocationToAccountId, + CurrencyId, + CurrencyIdConvert, +>; + +pub type XcmRouter = ParachainXcmRouter; +pub type Barrier = AllowUnpaidExecutionFrom>; + +pub struct XcmConfig; +impl Config for XcmConfig { + type Call = Call; + type XcmSender = XcmRouter; + type AssetTransactor = LocalAssetTransactor; + type OriginConverter = XcmOriginToCallOrigin; + type IsReserve = NativeAsset; + type IsTeleporter = (); + type LocationInverter = LocationInverter; + type Barrier = Barrier; + type Weigher = FixedWeightBounds; + type Trader = FixedRateOfConcreteFungible; + type ResponseHandler = (); +} + +pub struct ChannelInfo; +impl GetChannelInfo for ChannelInfo { + fn get_channel_status(_id: ParaId) -> ChannelStatus { + ChannelStatus::Ready(10, 10) + } + fn get_channel_max(_id: ParaId) -> Option { + Some(usize::max_value()) + } +} + +impl cumulus_pallet_xcmp_queue::Config for Runtime { + type Event = Event; + type XcmExecutor = XcmExecutor; + type ChannelInfo = ChannelInfo; +} + +impl cumulus_pallet_dmp_queue::Config for Runtime { + type Event = Event; + type XcmExecutor = XcmExecutor; + type ExecuteOverweightOrigin = EnsureRoot; +} + +impl cumulus_pallet_xcm::Config for Runtime { + type Event = Event; + type XcmExecutor = XcmExecutor; +} + +pub type LocalOriginToLocation = SignedToAccountId32; + +impl pallet_xcm::Config for Runtime { + type Event = Event; + type SendXcmOrigin = EnsureXcmOrigin; + type XcmRouter = XcmRouter; + type ExecuteXcmOrigin = EnsureXcmOrigin; + type XcmExecuteFilter = All<(MultiLocation, Xcm)>; + type XcmExecutor = XcmExecutor; + type XcmTeleportFilter = (); + type XcmReserveTransferFilter = All<(MultiLocation, Vec)>; + type Weigher = FixedWeightBounds; +} + +pub struct AccountIdToMultiLocation; +impl Convert for AccountIdToMultiLocation { + fn convert(account: AccountId) -> MultiLocation { + X1(Junction::AccountId32 { + network: NetworkId::Any, + id: account.into(), + }) + } +} + +parameter_types! { + pub SelfLocation: MultiLocation = X2(Parent, Parachain(ParachainInfo::get().into())); +} + +impl orml_xtokens::Config for Runtime { + type Event = Event; + type Balance = Balance; + type CurrencyId = CurrencyId; + type CurrencyIdConvert = CurrencyIdConvert; + type AccountIdToMultiLocation = AccountIdToMultiLocation; + type SelfLocation = SelfLocation; + type XcmExecutor = XcmExecutor; + type Weigher = FixedWeightBounds; +} + +type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic; +type Block = frame_system::mocking::MockBlock; + +construct_runtime!( + pub enum Runtime where + Block = Block, + NodeBlock = Block, + UncheckedExtrinsic = UncheckedExtrinsic, + { + System: frame_system::{Pallet, Call, Storage, Config, Event}, + Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, + + ParachainInfo: parachain_info::{Pallet, Storage, Config}, + XcmpQueue: cumulus_pallet_xcmp_queue::{Pallet, Call, Storage, Event}, + DmpQueue: cumulus_pallet_dmp_queue::{Pallet, Call, Storage, Event}, + CumulusXcm: cumulus_pallet_xcm::{Pallet, Event, Origin}, + + Tokens: orml_tokens::{Pallet, Storage, Event, Config}, + XTokens: orml_xtokens::{Pallet, Storage, Call, Event}, + + PolkadotXcm: pallet_xcm::{Pallet, Call, Event, Origin}, + } +); diff --git a/xtokens/src/mock/relay.rs b/xtokens/src/mock/relay.rs new file mode 100644 index 000000000..ebb2b250a --- /dev/null +++ b/xtokens/src/mock/relay.rs @@ -0,0 +1,159 @@ +use frame_support::{ + construct_runtime, parameter_types, + traits::All, + weights::{IdentityFee, Weight}, +}; +use sp_core::H256; +use sp_runtime::{testing::Header, traits::IdentityLookup, AccountId32}; + +use cumulus_primitives_core::ParaId; +use polkadot_runtime_parachains::{configuration, origin, shared, ump}; +use xcm::v0::{MultiAsset, MultiLocation, NetworkId}; +use xcm_builder::{ + AccountId32Aliases, AllowTopLevelPaidExecutionFrom, ChildParachainAsNative, ChildParachainConvertsVia, + CurrencyAdapter as XcmCurrencyAdapter, FixedWeightBounds, IsConcrete, LocationInverter, SignedAccountId32AsNative, + SignedToAccountId32, SovereignSignedViaLocation, TakeWeightCredit, UsingComponents, +}; +use xcm_executor::{Config, XcmExecutor}; + +pub type AccountId = AccountId32; +pub type Balance = u128; + +parameter_types! { + pub const BlockHashCount: u64 = 250; +} + +impl frame_system::Config for Runtime { + type Origin = Origin; + type Call = Call; + type Index = u64; + type BlockNumber = u64; + type Hash = H256; + type Hashing = ::sp_runtime::traits::BlakeTwo256; + type AccountId = AccountId; + type Lookup = IdentityLookup; + type Header = Header; + type Event = Event; + type BlockHashCount = BlockHashCount; + type BlockWeights = (); + type BlockLength = (); + type Version = (); + type PalletInfo = PalletInfo; + type AccountData = pallet_balances::AccountData; + type OnNewAccount = (); + type OnKilledAccount = (); + type DbWeight = (); + type BaseCallFilter = (); + type SystemWeightInfo = (); + type SS58Prefix = (); + type OnSetCode = (); +} + +parameter_types! { + pub ExistentialDeposit: Balance = 1; + pub const MaxLocks: u32 = 50; + pub const MaxReserves: u32 = 50; +} + +impl pallet_balances::Config for Runtime { + type MaxLocks = MaxLocks; + type Balance = Balance; + type Event = Event; + type DustRemoval = (); + type ExistentialDeposit = ExistentialDeposit; + type AccountStore = System; + type WeightInfo = (); + type MaxReserves = MaxReserves; + type ReserveIdentifier = [u8; 8]; +} + +impl shared::Config for Runtime {} + +impl configuration::Config for Runtime {} + +parameter_types! { + pub const KsmLocation: MultiLocation = MultiLocation::Null; + pub const KusamaNetwork: NetworkId = NetworkId::Kusama; + pub Ancestry: MultiLocation = MultiLocation::Null; + pub UnitWeightCost: Weight = 1; +} + +pub type SovereignAccountOf = ( + ChildParachainConvertsVia, + AccountId32Aliases, +); + +pub type LocalAssetTransactor = + XcmCurrencyAdapter, SovereignAccountOf, AccountId, ()>; + +type LocalOriginConverter = ( + SovereignSignedViaLocation, + ChildParachainAsNative, + SignedAccountId32AsNative, +); + +parameter_types! { + pub const BaseXcmWeight: Weight = 10; +} + +pub type XcmRouter = super::RelayChainXcmRouter; +pub type Barrier = (TakeWeightCredit, AllowTopLevelPaidExecutionFrom>); + +pub struct XcmConfig; +impl Config for XcmConfig { + type Call = Call; + type XcmSender = XcmRouter; + type AssetTransactor = LocalAssetTransactor; + type OriginConverter = LocalOriginConverter; + type IsReserve = (); + type IsTeleporter = (); + type LocationInverter = LocationInverter; + type Barrier = Barrier; + type Weigher = FixedWeightBounds; + type Trader = UsingComponents, KsmLocation, AccountId, Balances, ()>; + type ResponseHandler = (); +} + +pub type LocalOriginToLocation = SignedToAccountId32; + +impl pallet_xcm::Config for Runtime { + type Event = Event; + type SendXcmOrigin = xcm_builder::EnsureXcmOrigin; + type XcmRouter = XcmRouter; + // Anyone can execute XCM messages locally... + type ExecuteXcmOrigin = xcm_builder::EnsureXcmOrigin; + type XcmExecuteFilter = (); + type XcmExecutor = XcmExecutor; + type XcmTeleportFilter = All<(MultiLocation, Vec)>; + type XcmReserveTransferFilter = All<(MultiLocation, Vec)>; + type Weigher = FixedWeightBounds; +} + +parameter_types! { + pub const FirstMessageFactorPercent: u64 = 100; +} + +impl ump::Config for Runtime { + type Event = Event; + type UmpSink = ump::XcmSink, Runtime>; + type FirstMessageFactorPercent = FirstMessageFactorPercent; +} + +impl origin::Config for Runtime {} + +type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic; +type Block = frame_system::mocking::MockBlock; + +construct_runtime!( + pub enum Runtime where + Block = Block, + NodeBlock = Block, + UncheckedExtrinsic = UncheckedExtrinsic, + { + System: frame_system::{Pallet, Call, Storage, Config, Event}, + Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, + ParasOrigin: origin::{Pallet, Origin}, + ParasUmp: ump::{Pallet, Call, Storage, Event}, + XcmPallet: pallet_xcm::{Pallet, Call, Storage, Event}, + } +); diff --git a/xtokens/src/tests.rs b/xtokens/src/tests.rs index a90ca0b32..5b944a8fc 100644 --- a/xtokens/src/tests.rs +++ b/xtokens/src/tests.rs @@ -5,7 +5,8 @@ use cumulus_primitives_core::ParaId; use frame_support::{assert_noop, assert_ok, traits::Currency}; use mock::*; use orml_traits::MultiCurrency; -use polkadot_parachain::primitives::{AccountIdConversion, Sibling}; +// use polkadot_parachain::primitives::{AccountIdConversion, Sibling}; +use polkadot_parachain::primitives::AccountIdConversion; use sp_runtime::AccountId32; use xcm::v0::{Junction, NetworkId}; use xcm_simulator::TestExt; @@ -14,277 +15,313 @@ fn para_a_account() -> AccountId32 { ParaId::from(1).into_account() } -fn para_b_account() -> AccountId32 { - ParaId::from(2).into_account() -} +// fn para_b_account() -> AccountId32 { +// ParaId::from(2).into_account() +// } -fn sibling_a_account() -> AccountId32 { - use sp_runtime::traits::AccountIdConversion; - Sibling::from(1).into_account() -} +// fn sibling_a_account() -> AccountId32 { +// use sp_runtime::traits::AccountIdConversion; +// Sibling::from(1).into_account() +// } -fn sibling_b_account() -> AccountId32 { - use sp_runtime::traits::AccountIdConversion; - Sibling::from(2).into_account() -} +// fn sibling_b_account() -> AccountId32 { +// use sp_runtime::traits::AccountIdConversion; +// Sibling::from(2).into_account() +// } -fn sibling_c_account() -> AccountId32 { - use sp_runtime::traits::AccountIdConversion; - Sibling::from(3).into_account() -} +// fn sibling_c_account() -> AccountId32 { +// use sp_runtime::traits::AccountIdConversion; +// Sibling::from(3).into_account() +// } #[test] fn send_relay_chain_asset_to_relay_chain() { - TestNetwork::reset(); + TestNet::reset(); - MockRelay::execute_with(|| { - let _ = RelayBalances::deposit_creating(¶_a_account(), 100); + Relay::execute_with(|| { + let _ = RelayBalances::deposit_creating(¶_a_account(), 1_000); }); ParaA::execute_with(|| { - assert_ok!(ParaAXtokens::transfer( + assert_ok!(ParaXTokens::transfer( Some(ALICE).into(), CurrencyId::R, - 30, + 500, ( Parent, Junction::AccountId32 { - network: NetworkId::Polkadot, + network: NetworkId::Kusama, id: BOB.into(), }, ) .into(), - )); - assert_eq!(ParaATokens::free_balance(CurrencyId::R, &ALICE), 70); - }); - - MockRelay::execute_with(|| { - assert_eq!(RelayBalances::free_balance(¶_a_account()), 70); - assert_eq!(RelayBalances::free_balance(&BOB), 30); - }); -} - -#[test] -fn send_relay_chain_asset_to_sibling() { - TestNetwork::reset(); - - MockRelay::execute_with(|| { - let _ = RelayBalances::deposit_creating(¶_a_account(), 100); - }); - - ParaA::execute_with(|| { - assert_ok!(ParaAXtokens::transfer( - Some(ALICE).into(), - CurrencyId::R, 30, - ( - Parent, - Parachain { id: 2 }, - Junction::AccountId32 { - network: NetworkId::Any, - id: BOB.into(), - }, - ) - .into(), )); - assert_eq!(ParaATokens::free_balance(CurrencyId::R, &ALICE), 70); - }); - - MockRelay::execute_with(|| { - assert_eq!(RelayBalances::free_balance(¶_a_account()), 70); - assert_eq!(RelayBalances::free_balance(¶_b_account()), 30); + assert_eq!(ParaTokens::free_balance(CurrencyId::R, &ALICE), 500); }); - ParaB::execute_with(|| { - assert_eq!(ParaBTokens::free_balance(CurrencyId::R, &BOB), 30); + Relay::execute_with(|| { + assert_eq!(RelayBalances::free_balance(¶_a_account()), 500); + assert_eq!(RelayBalances::free_balance(&BOB), 470); }); } #[test] -fn send_sibling_asset_to_reserve_sibling() { - TestNetwork::reset(); - - ParaA::execute_with(|| { - assert_ok!(ParaATokens::deposit(CurrencyId::B, &ALICE, 100)); - }); - - ParaB::execute_with(|| { - assert_ok!(ParaBTokens::deposit(CurrencyId::B, &sibling_a_account(), 100)); - }); +fn cannot_lost_fund_on_send_failed() { + TestNet::reset(); ParaA::execute_with(|| { - assert_ok!(ParaAXtokens::transfer( + assert_ok!(ParaXTokens::transfer( Some(ALICE).into(), - CurrencyId::B, - 30, + CurrencyId::R, + 500, ( Parent, - Parachain { id: 2 }, + Parachain(3), Junction::AccountId32 { - network: NetworkId::Any, + network: NetworkId::Kusama, id: BOB.into(), }, ) .into(), - )); - - assert_eq!(ParaATokens::free_balance(CurrencyId::B, &ALICE), 70); - }); - - ParaB::execute_with(|| { - assert_eq!(ParaBTokens::free_balance(CurrencyId::B, &sibling_a_account()), 70); - assert_eq!(ParaBTokens::free_balance(CurrencyId::B, &BOB), 30); - }); -} - -#[test] -fn send_sibling_asset_to_non_reserve_sibling() { - TestNetwork::reset(); - - ParaA::execute_with(|| { - assert_ok!(ParaATokens::deposit(CurrencyId::B, &ALICE, 100)); - }); - - ParaB::execute_with(|| { - assert_ok!(ParaBTokens::deposit(CurrencyId::B, &sibling_a_account(), 100)); - }); - - ParaA::execute_with(|| { - assert_ok!(ParaAXtokens::transfer( - Some(ALICE).into(), - CurrencyId::B, 30, - ( - Parent, - Parachain { id: 3 }, - Junction::AccountId32 { - network: NetworkId::Any, - id: BOB.into(), - }, - ) - .into(), )); - assert_eq!(ParaATokens::free_balance(CurrencyId::B, &ALICE), 70); - }); - - // check reserve accounts - ParaB::execute_with(|| { - assert_eq!(ParaBTokens::free_balance(CurrencyId::B, &sibling_a_account()), 70); - assert_eq!(ParaBTokens::free_balance(CurrencyId::B, &sibling_c_account()), 30); - }); + para::System::events().iter().any(|r| { + if let para::Event::XTokens(Event::::TransferFailed(_, _, _, _, _)) = r.event { + true + } else { + false + } + }); - ParaC::execute_with(|| { - assert_eq!(ParaCTokens::free_balance(CurrencyId::B, &BOB), 30); + assert_eq!(ParaTokens::free_balance(CurrencyId::R, &ALICE), 1_000); }); } -#[test] -fn send_self_parachain_asset_to_sibling() { - TestNetwork::reset(); - - ParaA::execute_with(|| { - assert_ok!(ParaATokens::deposit(CurrencyId::A, &ALICE, 100)); - - assert_ok!(ParaAXtokens::transfer( - Some(ALICE).into(), - CurrencyId::A, - 30, - ( - Parent, - Parachain { id: 2 }, - Junction::AccountId32 { - network: NetworkId::Any, - id: BOB.into(), - }, - ) - .into(), - )); - - assert_eq!(ParaATokens::free_balance(CurrencyId::A, &ALICE), 70); - assert_eq!(ParaATokens::free_balance(CurrencyId::A, &sibling_b_account()), 30); - }); - - ParaB::execute_with(|| { - para_b::System::events().iter().for_each(|r| { - println!(">>> {:?}", r.event); - }); - assert_eq!(ParaBTokens::free_balance(CurrencyId::A, &BOB), 30); - }); -} +// #[test] +// fn send_relay_chain_asset_to_sibling() { +// TestNet::reset(); + +// Relay::execute_with(|| { +// let _ = RelayBalances::deposit_creating(¶_a_account(), 100); +// }); + +// ParaA::execute_with(|| { +// assert_ok!(ParaXTokens::transfer( +// Some(ALICE).into(), +// CurrencyId::R, +// 30, +// ( +// Parent, +// Parachain { id: 2 }, +// Junction::AccountId32 { +// network: NetworkId::Any, +// id: BOB.into(), +// }, +// ) +// .into(), +// )); +// assert_eq!(ParaTokens::free_balance(CurrencyId::R, &ALICE), 70); +// }); + +// Relay::execute_with(|| { +// assert_eq!(RelayBalances::free_balance(¶_a_account()), 70); +// assert_eq!(RelayBalances::free_balance(¶_b_account()), 30); +// }); + +// ParaB::execute_with(|| { +// assert_eq!(ParaTokens::free_balance(CurrencyId::R, &BOB), 30); +// }); +// } + +// #[test] +// fn send_sibling_asset_to_reserve_sibling() { +// TestNet::reset(); + +// ParaA::execute_with(|| { +// assert_ok!(ParaTokens::deposit(CurrencyId::B, &ALICE, 100)); +// }); + +// ParaB::execute_with(|| { +// assert_ok!(ParaTokens::deposit(CurrencyId::B, &sibling_a_account(), 100)); +// }); + +// ParaA::execute_with(|| { +// assert_ok!(ParaXTokens::transfer( +// Some(ALICE).into(), +// CurrencyId::B, +// 30, +// ( +// Parent, +// Parachain { id: 2 }, +// Junction::AccountId32 { +// network: NetworkId::Any, +// id: BOB.into(), +// }, +// ) +// .into(), +// )); + +// assert_eq!(ParaTokens::free_balance(CurrencyId::B, &ALICE), 70); +// }); + +// ParaB::execute_with(|| { +// assert_eq!(ParaTokens::free_balance(CurrencyId::B, &sibling_a_account()), +// 70); assert_eq!(ParaTokens::free_balance(CurrencyId::B, &BOB), 30); +// }); +// } + +// #[test] +// fn send_sibling_asset_to_non_reserve_sibling() { +// TestNet::reset(); + +// ParaA::execute_with(|| { +// assert_ok!(ParaTokens::deposit(CurrencyId::B, &ALICE, 100)); +// }); + +// ParaB::execute_with(|| { +// assert_ok!(ParaTokens::deposit(CurrencyId::B, &sibling_a_account(), 100)); +// }); + +// ParaA::execute_with(|| { +// assert_ok!(ParaXTokens::transfer( +// Some(ALICE).into(), +// CurrencyId::B, +// 30, +// ( +// Parent, +// Parachain { id: 3 }, +// Junction::AccountId32 { +// network: NetworkId::Any, +// id: BOB.into(), +// }, +// ) +// .into(), +// )); +// assert_eq!(ParaTokens::free_balance(CurrencyId::B, &ALICE), 70); +// }); + +// // check reserve accounts +// ParaB::execute_with(|| { +// assert_eq!(ParaTokens::free_balance(CurrencyId::B, &sibling_a_account()), +// 70); assert_eq!(ParaTokens::free_balance(CurrencyId::B, +// &sibling_c_account()), 30); }); + +// ParaC::execute_with(|| { +// assert_eq!(ParaTokens::free_balance(CurrencyId::B, &BOB), 30); +// }); +// } + +// #[test] +// fn send_self_parachain_asset_to_sibling() { +// TestNet::reset(); + +// ParaA::execute_with(|| { +// assert_ok!(ParaTokens::deposit(CurrencyId::A, &ALICE, 100)); + +// assert_ok!(ParaXTokens::transfer( +// Some(ALICE).into(), +// CurrencyId::A, +// 30, +// ( +// Parent, +// Parachain { id: 2 }, +// Junction::AccountId32 { +// network: NetworkId::Any, +// id: BOB.into(), +// }, +// ) +// .into(), +// )); + +// assert_eq!(ParaTokens::free_balance(CurrencyId::A, &ALICE), 70); +// assert_eq!(ParaTokens::free_balance(CurrencyId::A, &sibling_b_account()), +// 30); }); + +// ParaB::execute_with(|| { +// para_b::System::events().iter().for_each(|r| { +// println!(">>> {:?}", r.event); +// }); +// assert_eq!(ParaTokens::free_balance(CurrencyId::A, &BOB), 30); +// }); +// } #[test] fn transfer_no_reserve_assets_fails() { - TestNetwork::reset(); + TestNet::reset(); ParaA::execute_with(|| { assert_noop!( - ParaAXtokens::transfer_multiasset( + ParaXTokens::transfer_multiasset( Some(ALICE).into(), MultiAsset::ConcreteFungible { id: GeneralKey("B".into()).into(), - amount: 1 + amount: 100 }, ( Parent, - Parachain { id: 2 }, + Parachain(2), Junction::AccountId32 { network: NetworkId::Any, id: BOB.into() } ) - .into() + .into(), + 50, ), - Error::::AssetHasNoReserve + Error::::AssetHasNoReserve ); }); } #[test] fn transfer_to_self_chain_fails() { - TestNetwork::reset(); + TestNet::reset(); ParaA::execute_with(|| { assert_noop!( - ParaAXtokens::transfer_multiasset( + ParaXTokens::transfer_multiasset( Some(ALICE).into(), MultiAsset::ConcreteFungible { - id: (Parent, Parachain { id: 1 }, GeneralKey("A".into())).into(), - amount: 1 + id: (Parent, Parachain(1), GeneralKey("A".into())).into(), + amount: 100 }, ( Parent, - Parachain { id: 1 }, + Parachain(1), Junction::AccountId32 { network: NetworkId::Any, id: BOB.into() } ) - .into() + .into(), + 50, ), - Error::::NotCrossChainTransfer + Error::::NotCrossChainTransfer ); }); } #[test] fn transfer_to_invalid_dest_fails() { - TestNetwork::reset(); + TestNet::reset(); ParaA::execute_with(|| { assert_noop!( - ParaAXtokens::transfer_multiasset( + ParaXTokens::transfer_multiasset( Some(ALICE).into(), MultiAsset::ConcreteFungible { - id: (Parent, Parachain { id: 1 }, GeneralKey("A".into())).into(), - amount: 1 + id: (Parent, Parachain(1), GeneralKey("A".into())).into(), + amount: 100, }, (Junction::AccountId32 { network: NetworkId::Any, id: BOB.into() }) - .into() + .into(), + 50, ), - Error::::InvalidDest + Error::::InvalidDest ); }); }