Skip to content

Commit

Permalink
Add schedule_as into TaskScheduled event (#365)
Browse files Browse the repository at this point in the history
* Add schedule_as into TaskScheduled event

* Add schedule_as to TaskRescheduled event

* Add schedule_xcmp_through_proxy_works test

* Fix schedule_xcmp_through_proxy_works test

* Add schedule_xcmp_through_proxy_same_as_user_account test

* Rename user_account to delegator_account

* Modify the expect text in schedule_xcmp_through_proxy_works test
  • Loading branch information
imstar15 authored Jul 7, 2023
1 parent 450d44c commit 7f6a8b9
Show file tree
Hide file tree
Showing 5 changed files with 111 additions and 12 deletions.
4 changes: 2 additions & 2 deletions pallets/automation-time/src/benchmarking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,7 @@ benchmarks! {
let task_id = Pallet::<T>::generate_task_id(caller.clone(), provided_id.clone());
}: schedule_dynamic_dispatch_task(RawOrigin::Signed(caller.clone()), provided_id, schedule, Box::new(call))
verify {
assert_last_event::<T>(Event::TaskScheduled { who: caller, task_id: task_id }.into())
assert_last_event::<T>(Event::TaskScheduled { who: caller, task_id: task_id, schedule_as: None }.into())
}

schedule_dynamic_dispatch_task_full {
Expand All @@ -285,7 +285,7 @@ benchmarks! {
schedule_notify_tasks::<T>(caller.clone(), times, T::MaxTasksPerSlot::get() - 1);
}: schedule_dynamic_dispatch_task(RawOrigin::Signed(caller.clone()), provided_id, schedule, Box::new(call))
verify {
assert_last_event::<T>(Event::TaskScheduled { who: caller, task_id: task_id }.into())
assert_last_event::<T>(Event::TaskScheduled { who: caller, task_id: task_id, schedule_as: None }.into())
}

cancel_scheduled_task_full {
Expand Down
34 changes: 27 additions & 7 deletions pallets/automation-time/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,7 @@ pub mod pallet {
TaskScheduled {
who: AccountOf<T>,
task_id: TaskId<T>,
schedule_as: Option<AccountOf<T>>,
},
/// Cancelled a task.
TaskCancelled {
Expand Down Expand Up @@ -332,6 +333,7 @@ pub mod pallet {
TaskRescheduled {
who: AccountOf<T>,
task_id: TaskId<T>,
schedule_as: Option<AccountOf<T>>,
},
/// A recurring task was not rescheduled
TaskNotRescheduled {
Expand Down Expand Up @@ -1347,12 +1349,12 @@ pub mod pallet {
Ok(task_id)
})?;

let scheduler = match action {
Action::XCMP { schedule_as, .. } => schedule_as.unwrap_or(owner_id),
_ => owner_id,
let schedule_as = match action {
Action::XCMP { schedule_as, .. } => schedule_as,
_ => None,
};

Self::deposit_event(Event::<T>::TaskScheduled { who: scheduler, task_id });
Self::deposit_event(Event::<T>::TaskScheduled { who: owner_id, task_id, schedule_as });
Ok(())
}

Expand All @@ -1370,9 +1372,18 @@ pub mod pallet {
AccountTasks::<T>::remove(task.owner_id.clone(), task_id);
} else {
let owner_id = task.owner_id.clone();
let action = task.action.clone();
match Self::reschedule_existing_task(task_id, &mut task) {
Ok(_) => {
Self::deposit_event(Event::<T>::TaskRescheduled { who: owner_id, task_id });
let schedule_as = match action {
Action::XCMP { schedule_as, .. } => schedule_as,
_ => None,
};
Self::deposit_event(Event::<T>::TaskRescheduled {
who: owner_id,
task_id,
schedule_as,
});
},
Err(err) => {
Self::deposit_event(Event::<T>::TaskFailedToReschedule {
Expand Down Expand Up @@ -1401,9 +1412,18 @@ pub mod pallet {
})?;

let owner_id = task.owner_id.clone();
AccountTasks::<T>::insert(owner_id.clone(), task_id, task);
AccountTasks::<T>::insert(owner_id.clone(), task_id, task.clone());

Self::deposit_event(Event::<T>::TaskScheduled { who: owner_id, task_id });
let schedule_as = match task.action.clone() {
Action::XCMP { schedule_as, .. } => schedule_as.clone(),
_ => None,
};

Self::deposit_event(Event::<T>::TaskScheduled {
who: owner_id,
task_id,
schedule_as,
});
},
Schedule::Fixed { .. } => {},
}
Expand Down
9 changes: 8 additions & 1 deletion pallets/automation-time/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ pub type CurrencyId = u32;

pub const ALICE: [u8; 32] = [1u8; 32];
pub const BOB: [u8; 32] = [2u8; 32];
pub const DELEGATOR_ACCOUNT: [u8; 32] = [3u8; 32];
pub const PROXY_ACCOUNT: [u8; 32] = [4u8; 32];

pub const PARA_ID: u32 = 2000;
pub const NATIVE: CurrencyId = 0;

Expand Down Expand Up @@ -351,7 +354,11 @@ impl Convert<CurrencyId, Option<MultiLocation>> for MockTokenIdConvert {
pub struct MockEnsureProxy;
impl EnsureProxy<AccountId> for MockEnsureProxy {
fn ensure_ok(_delegator: AccountId, _delegatee: AccountId) -> Result<(), &'static str> {
Ok(())
if _delegator == DELEGATOR_ACCOUNT.into() && _delegatee == PROXY_ACCOUNT.into() {
Ok(())
} else {
Err("proxy error: expected `ProxyType::Any`")
}
}
}

Expand Down
74 changes: 73 additions & 1 deletion pallets/automation-time/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,77 @@ fn schedule_xcmp_works() {
})
}

#[test]
fn schedule_xcmp_through_proxy_works() {
new_test_ext(START_BLOCK_TIME).execute_with(|| {
let provided_id = vec![50];
let delegator_account = AccountId32::new(DELEGATOR_ACCOUNT);
let proxy_account = AccountId32::new(PROXY_ACCOUNT);
let call: Vec<u8> = vec![2, 4, 5];

// Funds including XCM fees
get_xcmp_funds(proxy_account.clone());

assert_ok!(AutomationTime::schedule_xcmp_task_through_proxy(
RuntimeOrigin::signed(proxy_account.clone()),
provided_id,
ScheduleParam::Fixed { execution_times: vec![SCHEDULED_TIME] },
PARA_ID.try_into().unwrap(),
NATIVE,
MultiLocation::new(1, X1(Parachain(PARA_ID.into()))).into(),
call.clone(),
Weight::from_ref_time(100_000),
delegator_account.clone(),
));

let tasks = AutomationTime::get_scheduled_tasks(SCHEDULED_TIME);
assert_eq!(tasks.is_some(), true);

let tasks = tasks.unwrap();
assert_eq!(tasks.tasks[0].0, proxy_account.clone());

// Find the TaskScheduled event in the event list and verify if the who within it is correct.
events()
.into_iter()
.find(|e| match e {
RuntimeEvent::AutomationTime(crate::Event::TaskScheduled {
who,
schedule_as,
..
}) if *who == proxy_account && *schedule_as == Some(delegator_account.clone()) => true,
_ => false,
})
.expect("TaskScheduled event should emit with 'who' being proxy_account, and 'schedule_as' being delegator_account.");
})
}

#[test]
fn schedule_xcmp_through_proxy_same_as_delegator_account() {
new_test_ext(START_BLOCK_TIME).execute_with(|| {
let provided_id = vec![50];
let delegator_account = AccountId32::new(ALICE);
let call: Vec<u8> = vec![2, 4, 5];

// Funds including XCM fees
get_xcmp_funds(delegator_account.clone());

assert_noop!(
AutomationTime::schedule_xcmp_task_through_proxy(
RuntimeOrigin::signed(delegator_account.clone()),
provided_id,
ScheduleParam::Fixed { execution_times: vec![SCHEDULED_TIME] },
PARA_ID.try_into().unwrap(),
NATIVE,
MultiLocation::new(1, X1(Parachain(PARA_ID.into()))).into(),
call.clone(),
Weight::from_ref_time(100_000),
delegator_account.clone(),
),
sp_runtime::DispatchError::Other("proxy error: expected `ProxyType::Any`"),
);
})
}

#[test]
fn schedule_xcmp_fails_if_not_enough_funds() {
new_test_ext(START_BLOCK_TIME).execute_with(|| {
Expand Down Expand Up @@ -1024,7 +1095,8 @@ mod extrinsics {
last_event(),
RuntimeEvent::AutomationTime(crate::Event::TaskScheduled {
who: account_id,
task_id
task_id,
schedule_as: None,
})
);
})
Expand Down
2 changes: 1 addition & 1 deletion pallets/automation-time/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ impl Schedule {
}

/// The struct that stores all information needed for a task.
#[derive(Debug, Encode, Decode, TypeInfo)]
#[derive(Debug, Encode, Decode, TypeInfo, Clone)]
#[scale_info(skip_type_params(MaxExecutionTimes))]
pub struct Task<AccountId, Balance, CurrencyId> {
pub owner_id: AccountId,
Expand Down

0 comments on commit 7f6a8b9

Please sign in to comment.