Skip to content

Commit

Permalink
add tests for XTokensTaskHooks
Browse files Browse the repository at this point in the history
  • Loading branch information
wangjj9219 committed Mar 25, 2024
1 parent be4e526 commit face78f
Show file tree
Hide file tree
Showing 3 changed files with 224 additions and 26 deletions.
13 changes: 7 additions & 6 deletions delay-tasks/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ use orml_traits::{
task::{DelayTaskHooks, DelayTasksManager, DispatchableTask},
MultiCurrency, NamedMultiReservableCurrency,
};
use orml_xtokens::XtokensTask;
use parity_scale_codec::FullCodec;
use scale_info::TypeInfo;
use sp_runtime::{
Expand Down Expand Up @@ -271,17 +272,17 @@ pub mod module {
}

pub struct DelayedXtokensTaskHooks<T>(PhantomData<T>);
impl<T: Config + orml_xtokens::Config> DelayTaskHooks<orml_xtokens::XtokensTask<T>> for DelayedXtokensTaskHooks<T>
impl<T: Config + orml_xtokens::Config> DelayTaskHooks<XtokensTask<T>> for DelayedXtokensTaskHooks<T>
where
<T as Config>::Currency: MultiCurrency<
T::AccountId,
CurrencyId = <T as orml_xtokens::Config>::CurrencyId,
Balance = <T as orml_xtokens::Config>::Balance,
>,
{
fn pre_delay(task: &orml_xtokens::XtokensTask<T>) -> DispatchResult {
fn pre_delay(task: &XtokensTask<T>) -> DispatchResult {
match task {
orml_xtokens::XtokensTask::<T>::TransferAssets { who, assets, .. } => {
XtokensTask::<T>::TransferAssets { who, assets, .. } => {
let asset_len = assets.len();
for i in 0..asset_len {
let asset = assets.get(i).ok_or(Error::<T>::AssetIndexNonExistent)?;
Expand All @@ -303,9 +304,9 @@ pub mod module {
Ok(())
}

fn pre_delayed_execute(task: &orml_xtokens::XtokensTask<T>) -> DispatchResult {
fn pre_delayed_execute(task: &XtokensTask<T>) -> DispatchResult {
match task {
orml_xtokens::XtokensTask::<T>::TransferAssets { who, assets, .. } => {
XtokensTask::<T>::TransferAssets { who, assets, .. } => {
let asset_len = assets.len();
for i in 0..asset_len {
let asset = assets.get(i).ok_or(Error::<T>::AssetIndexNonExistent)?;
Expand All @@ -327,7 +328,7 @@ pub mod module {
Ok(())
}

fn pre_cancel(task: &orml_xtokens::XtokensTask<T>) -> DispatchResult {
fn pre_cancel(task: &XtokensTask<T>) -> DispatchResult {
Self::pre_delayed_execute(task)
}
}
Expand Down
106 changes: 86 additions & 20 deletions delay-tasks/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,13 @@
use super::*;
use frame_support::{
construct_runtime, derive_impl, parameter_types,
traits::{ConstU128, EqualPrivilegeOnly, Everything},
traits::{EqualPrivilegeOnly, Everything},
};
use frame_system::EnsureRoot;
use orml_traits::{define_combined_task_and_bind_delay_hooks, parameter_type_with_key, task::TaskResult};
use orml_traits::{
define_combined_task_and_bind_delay_hooks, location::AbsoluteReserveProvider, parameter_type_with_key,
task::TaskResult,
};
use serde::{Deserialize, Serialize};
use sp_runtime::{traits::IdentityLookup, AccountId32, BuildStorage, DispatchError};
use sp_std::cell::RefCell;
Expand All @@ -29,23 +32,6 @@ impl frame_system::Config for Runtime {
type AccountId = AccountId;
type Lookup = IdentityLookup<Self::AccountId>;
type Block = Block;
type AccountData = pallet_balances::AccountData<Balance>;
}

impl pallet_balances::Config for Runtime {
type MaxLocks = ConstU32<50>;
type Balance = Balance;
type RuntimeEvent = RuntimeEvent;
type DustRemoval = ();
type ExistentialDeposit = ConstU128<1>;
type AccountStore = System;
type WeightInfo = ();
type MaxReserves = ConstU32<50>;
type ReserveIdentifier = [u8; 8];
type RuntimeHoldReason = RuntimeHoldReason;
type RuntimeFreezeReason = RuntimeFreezeReason;
type FreezeIdentifier = [u8; 8];
type MaxFreezes = ();
}

impl pallet_preimage::Config for Runtime {
Expand Down Expand Up @@ -181,6 +167,85 @@ impl orml_tokens::Config for Runtime {
type DustRemovalWhitelist = Everything;
}

parameter_types! {
pub SelfLocation: Location = Location::new(1, [Parachain(2000)]);
}

pub struct AccountIdToLocation;
impl Convert<AccountId, Location> for AccountIdToLocation {
fn convert(account: AccountId) -> Location {
[Junction::AccountId32 {
network: None,
id: account.into(),
}]
.into()
}
}

parameter_type_with_key! {
pub ParachainMinFee: |location: Location| -> Option<u128> {
#[allow(clippy::match_ref_pats)] // false positive
match (location.parents, location.first_interior()) {
(1, Some(Parachain(3))) => Some(100),
_ => None,
}
};
}

pub enum Weightless {}
impl PreparedMessage for Weightless {
fn weight_of(&self) -> Weight {
unreachable!()
}
}

pub struct MockExec;
impl ExecuteXcm<RuntimeCall> for MockExec {
type Prepared = Weightless;

fn prepare(_message: Xcm<RuntimeCall>) -> Result<Self::Prepared, Xcm<RuntimeCall>> {
unreachable!()
}

fn execute(_origin: impl Into<Location>, _pre: Weightless, _hash: &mut XcmHash, _weight_credit: Weight) -> Outcome {
unreachable!()
}

fn charge_fees(_location: impl Into<Location>, _fees: Assets) -> XcmResult {
Err(XcmError::Unimplemented)
}
}

parameter_types! {
pub UniversalLocation: InteriorLocation = Here;
pub const UnitWeightCost: Weight = Weight::from_parts(10, 10);
pub const BaseXcmWeight: Weight = Weight::from_parts(100_000_000, 100_000_000);
pub const MaxInstructions: u32 = 100;
pub const MaxAssetsIntoHolding: u32 = 64;
pub const MaxAssetsForTransfer: usize = 2;
}

impl orml_xtokens::Config for Runtime {
type RuntimeEvent = RuntimeEvent;
type Balance = Balance;
type CurrencyId = CurrencyId;
type CurrencyIdConvert = CurrencyIdConvert;
type AccountIdToLocation = AccountIdToLocation;
type SelfLocation = SelfLocation;
type XcmExecutor = MockExec;
type Weigher = xcm_builder::FixedWeightBounds<UnitWeightCost, RuntimeCall, MaxInstructions>;
type BaseXcmWeight = BaseXcmWeight;
type UniversalLocation = UniversalLocation;
type MaxAssetsForTransfer = MaxAssetsForTransfer;
type MinXcmFee = ParachainMinFee;
type LocationsFilter = Everything;
type ReserveProvider = AbsoluteReserveProvider;
type RateLimiter = ();
type RateLimiterId = ();
type Task = MockTaskType;
type DelayTasks = DelayTasks;
}

thread_local! {
pub static DISPATCH_SUCCEEDED: RefCell<u32> = RefCell::new(0);
pub static DISPATCH_FAILED: RefCell<u32> = RefCell::new(0);
Expand Down Expand Up @@ -325,6 +390,7 @@ define_combined_task_and_bind_delay_hooks! {
FailPreDelay(FailPreDelayTask, FailPreDelayTaskHook),
FailPreDelayedExecute(FailPreDelayedExecuteTask, FailPreDelayedExecuteTaskHook),
FailPreCancel(FailPreCancelTask, FailPreCancelTaskHook),
Xtokens(XtokensTask<Runtime>, DelayedXtokensTaskHooks<Runtime>),
}
}

Expand Down Expand Up @@ -356,7 +422,7 @@ construct_runtime!(
Scheduler: pallet_scheduler,
Preimage: pallet_preimage,
Tokens: orml_tokens,
Balances: pallet_balances,
XTokens: orml_xtokens,
}
);

Expand Down
131 changes: 131 additions & 0 deletions delay-tasks/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -301,3 +301,134 @@ fn do_delayed_execute_work() {
assert_eq!(PRE_DELAYED_EXECUTE_SUCCEEDED.with(|v| *v.borrow()), 2);
});
}

#[test]
fn delayed_xtokens_task_hooks_work() {
ExtBuilder::default().build().execute_with(|| {
let assets: Assets = Assets::from(vec![
(Location::parent(), 1000).into(),
(
(
Parent,
Parachain(1),
Junction::from(BoundedVec::try_from(b"A".to_vec()).unwrap()),
),
2000,
)
.into(),
(
(
Parent,
Parachain(2),
Junction::from(BoundedVec::try_from(b"B".to_vec()).unwrap()),
),
3000,
)
.into(),
]);
let fee: Asset = (Location::parent(), 1000).into();
let dest: Location = (
Parent,
Parachain(2),
Junction::AccountId32 {
network: None,
id: BOB.into(),
},
)
.into();
let task = XtokensTask::<Runtime>::TransferAssets {
who: ALICE,
assets,
fee,
dest,
dest_weight_limit: WeightLimit::Unlimited,
};

assert_ok!(Tokens::deposit(CurrencyId::R, &ALICE, 3000));
assert_ok!(Tokens::deposit(CurrencyId::A, &ALICE, 3000));
assert_ok!(Tokens::deposit(CurrencyId::B, &ALICE, 3000));
assert_eq!(Tokens::free_balance(CurrencyId::R, &ALICE), 3000);
assert_eq!(Tokens::free_balance(CurrencyId::A, &ALICE), 3000);
assert_eq!(Tokens::free_balance(CurrencyId::B, &ALICE), 3000);
assert_eq!(
Tokens::reserved_balance_named(&ReserveId::get(), CurrencyId::R, &ALICE),
0
);
assert_eq!(
Tokens::reserved_balance_named(&ReserveId::get(), CurrencyId::A, &ALICE),
0
);
assert_eq!(
Tokens::reserved_balance_named(&ReserveId::get(), CurrencyId::B, &ALICE),
0
);

assert_ok!(DelayedXtokensTaskHooks::<Runtime>::pre_delay(&task));
assert_eq!(Tokens::free_balance(CurrencyId::R, &ALICE), 2000);
assert_eq!(Tokens::free_balance(CurrencyId::A, &ALICE), 1000);
assert_eq!(Tokens::free_balance(CurrencyId::B, &ALICE), 0);
assert_eq!(
Tokens::reserved_balance_named(&ReserveId::get(), CurrencyId::R, &ALICE),
1000
);
assert_eq!(
Tokens::reserved_balance_named(&ReserveId::get(), CurrencyId::A, &ALICE),
2000
);
assert_eq!(
Tokens::reserved_balance_named(&ReserveId::get(), CurrencyId::B, &ALICE),
3000
);

assert_ok!(DelayedXtokensTaskHooks::<Runtime>::pre_delayed_execute(&task));
assert_eq!(Tokens::free_balance(CurrencyId::R, &ALICE), 3000);
assert_eq!(Tokens::free_balance(CurrencyId::A, &ALICE), 3000);
assert_eq!(Tokens::free_balance(CurrencyId::B, &ALICE), 3000);
assert_eq!(
Tokens::reserved_balance_named(&ReserveId::get(), CurrencyId::R, &ALICE),
0
);
assert_eq!(
Tokens::reserved_balance_named(&ReserveId::get(), CurrencyId::A, &ALICE),
0
);
assert_eq!(
Tokens::reserved_balance_named(&ReserveId::get(), CurrencyId::B, &ALICE),
0
);

assert_ok!(DelayedXtokensTaskHooks::<Runtime>::pre_delay(&task));
assert_eq!(Tokens::free_balance(CurrencyId::R, &ALICE), 2000);
assert_eq!(Tokens::free_balance(CurrencyId::A, &ALICE), 1000);
assert_eq!(Tokens::free_balance(CurrencyId::B, &ALICE), 0);
assert_eq!(
Tokens::reserved_balance_named(&ReserveId::get(), CurrencyId::R, &ALICE),
1000
);
assert_eq!(
Tokens::reserved_balance_named(&ReserveId::get(), CurrencyId::A, &ALICE),
2000
);
assert_eq!(
Tokens::reserved_balance_named(&ReserveId::get(), CurrencyId::B, &ALICE),
3000
);

assert_ok!(DelayedXtokensTaskHooks::<Runtime>::pre_cancel(&task));
assert_eq!(Tokens::free_balance(CurrencyId::R, &ALICE), 3000);
assert_eq!(Tokens::free_balance(CurrencyId::A, &ALICE), 3000);
assert_eq!(Tokens::free_balance(CurrencyId::B, &ALICE), 3000);
assert_eq!(
Tokens::reserved_balance_named(&ReserveId::get(), CurrencyId::R, &ALICE),
0
);
assert_eq!(
Tokens::reserved_balance_named(&ReserveId::get(), CurrencyId::A, &ALICE),
0
);
assert_eq!(
Tokens::reserved_balance_named(&ReserveId::get(), CurrencyId::B, &ALICE),
0
);
});
}

0 comments on commit face78f

Please sign in to comment.