Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove schedule native transfer #377

Merged
merged 22 commits into from
Jul 7, 2023
Merged
Show file tree
Hide file tree
Changes from 15 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ Here we are using [a copy of Mangata’s code](https://github.com/OAK-Foundation
First, clone and compile the code with `mangata-rococo` feature for a parachain.

```
git clone --branch feature/compound https://github.com/OAK-Foundation/mangata-node/tree/automation-demo
git clone --branch automation-demo https://github.com/OAK-Foundation/mangata-node

cd mangata-node

Expand Down
104 changes: 2 additions & 102 deletions pallets/automation-time/src/benchmarking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,30 +64,6 @@ fn schedule_notify_tasks<T: Config>(owner: T::AccountId, times: Vec<u64>, count:
provided_id
}

fn schedule_transfer_tasks<T: Config>(owner: T::AccountId, time: u64, count: u32) -> Vec<u8> {
let time_moment: u32 = time.saturated_into();
Timestamp::<T>::set_timestamp(time_moment.into());
let recipient: T::AccountId = account("recipient", 0, SEED);
let amount: BalanceOf<T> = T::Currency::minimum_balance().saturating_mul(ED_MULTIPLIER.into());
let mut provided_id = vec![0u8];

for _ in 0..count {
provided_id = increment_provided_id(provided_id);
let task = TaskOf::<T>::create_native_transfer_task::<T>(
owner.clone(),
provided_id.clone(),
vec![time],
recipient.clone(),
amount.clone(),
)
.unwrap();
let task_id = AutomationTime::<T>::schedule_task(&task, provided_id.clone()).unwrap();
<AccountTasks<T>>::insert(owner.clone(), task_id, task);
}

provided_id
}

fn schedule_xcmp_tasks<T: Config>(owner: T::AccountId, times: Vec<u64>, count: u32) -> Vec<u8> {
let transfer_amount = T::Currency::minimum_balance().saturating_mul(ED_MULTIPLIER.into());
T::Currency::deposit_creating(
Expand Down Expand Up @@ -162,33 +138,6 @@ fn increment_provided_id(mut provided_id: Vec<u8>) -> Vec<u8> {
}

benchmarks! {
schedule_notify_task_empty {
let caller: T::AccountId = account("caller", 0, SEED);
let time: u64 = 7200;
let time_moment: u32 = time.try_into().unwrap();
Timestamp::<T>::set_timestamp(time_moment.into());
let transfer_amount = T::Currency::minimum_balance().saturating_mul(ED_MULTIPLIER.into());
T::Currency::deposit_creating(&caller, transfer_amount.clone().saturating_mul(DEPOSIT_MULTIPLIER.into()));
}: schedule_notify_task(RawOrigin::Signed(caller), vec![10], vec![time], vec![4, 5])

schedule_notify_task_full {
let v in 1 .. T::MaxExecutionTimes::get();

let caller: T::AccountId = account("caller", 0, SEED);
let time: u64 = 7200;

let mut times: Vec<u64> = vec![];
for i in 0..v {
let hour: u64 = (3600 * (i + 1)).try_into().unwrap();
times.push(hour);
}

let mut provided_id = schedule_notify_tasks::<T>(caller.clone(), times.clone(), T::MaxTasksPerSlot::get() - 1);
provided_id = increment_provided_id(provided_id);
let transfer_amount = T::Currency::minimum_balance().saturating_mul(ED_MULTIPLIER.into());
T::Currency::deposit_creating(&caller, transfer_amount.clone().saturating_mul(DEPOSIT_MULTIPLIER.into()));
}: schedule_notify_task(RawOrigin::Signed(caller), provided_id, times, vec![4, 5])

schedule_xcmp_task_full {
let v in 1..T::MaxExecutionTimes::get();

Expand Down Expand Up @@ -222,34 +171,6 @@ benchmarks! {
let _ = T::MultiCurrency::deposit(currency_id.into(), &caller, foreign_currency_amount);
}: schedule_xcmp_task(RawOrigin::Signed(caller), provided_id, schedule, para_id.into(), currency_id, asset_location.into(), call, Weight::from_ref_time(1_000))

schedule_native_transfer_task_empty{
let caller: T::AccountId = account("caller", 0, SEED);
let recipient: T::AccountId = account("to", 0, SEED);
let time: u64 = 7200;
let transfer_amount = T::Currency::minimum_balance().saturating_mul(ED_MULTIPLIER.into());
let time_moment: u32 = time.try_into().unwrap();
Timestamp::<T>::set_timestamp(time_moment.into());
T::Currency::deposit_creating(&caller, transfer_amount.clone().saturating_mul(DEPOSIT_MULTIPLIER.into()));
}: schedule_native_transfer_task(RawOrigin::Signed(caller), vec![10], vec![time], recipient, transfer_amount)

schedule_native_transfer_task_full{
let v in 1 .. T::MaxExecutionTimes::get();

let caller: T::AccountId = account("caller", 0, SEED);
let recipient: T::AccountId = account("to", 0, SEED);
let transfer_amount = T::Currency::minimum_balance().saturating_mul(ED_MULTIPLIER.into());
T::Currency::deposit_creating(&caller, transfer_amount.clone().saturating_mul(DEPOSIT_MULTIPLIER.into()));

let mut times: Vec<u64> = vec![];
for i in 0..v {
let hour: u64 = (3600 * (i + 1)).try_into().unwrap();
times.push(hour);
}

let mut provided_id = schedule_notify_tasks::<T>(caller.clone(), times.clone(), T::MaxTasksPerSlot::get() - 1);
provided_id = increment_provided_id(provided_id);
}: schedule_native_transfer_task(RawOrigin::Signed(caller), provided_id, times, recipient, transfer_amount)

schedule_auto_compound_delegated_stake_task_full {
let task_weight = <T as Config>::WeightInfo::run_auto_compound_delegated_stake_task().ref_time();
let max_tasks_per_slot_by_weight: u32 = (T::MaxWeightPerSlot::get() / task_weight as u128).try_into().unwrap();
Expand Down Expand Up @@ -356,22 +277,6 @@ benchmarks! {
assert_last_event::<T>(Event::Notify{ message }.into())
}

run_native_transfer_task {
let starting_multiplier: u32 = 20;
let amount_starting: BalanceOf<T> = T::Currency::minimum_balance().saturating_mul(starting_multiplier.into());
let caller: T::AccountId = account("caller", 0, SEED);
T::Currency::deposit_creating(&caller, amount_starting.clone().saturating_mul(DEPOSIT_MULTIPLIER.into()));
let time: u64 = 10800;
let recipient: T::AccountId = account("recipient", 0, SEED);
let amount_transferred: BalanceOf<T> = T::Currency::minimum_balance().saturating_mul(ED_MULTIPLIER.into());

let provided_id = schedule_transfer_tasks::<T>(caller.clone(), time, 1);
let task_id = Pallet::<T>::generate_task_id(caller.clone(), provided_id);
}: { AutomationTime::<T>::run_native_transfer_task(caller, recipient, amount_transferred, task_id) }
verify {
assert_last_event::<T>(Event::SuccessfullyTransferredFunds{ task_id }.into())
}

run_xcmp_task {
let caller: T::AccountId = account("caller", 0, SEED);
let currency_id: T::CurrencyId = T::GetNativeCurrencyId::get();
Expand Down Expand Up @@ -478,16 +383,11 @@ benchmarks! {
let weight_left = Weight::from_ref_time(500_000_000_000);
let mut task_ids = vec![];
let caller: T::AccountId = account("caller", 0, SEED);
let time = 10800;
let recipient: T::AccountId = account("to", 0, SEED);
let starting_multiplier: u32 = 20;
let transfer_amount = T::Currency::minimum_balance().saturating_mul(ED_MULTIPLIER.into());
let starting_amount = T::Currency::minimum_balance().saturating_mul(starting_multiplier.into());
T::Currency::deposit_creating(&caller, starting_amount.clone().saturating_mul(DEPOSIT_MULTIPLIER.into()));
let execution_time = 10800;

for i in 0..v {
let provided_id: Vec<u8> = vec![i.saturated_into::<u8>()];
let task = TaskOf::<T>::create_native_transfer_task::<T>(caller.clone(), provided_id.clone(), vec![time], recipient.clone(), transfer_amount.clone()).unwrap();
let task = TaskOf::<T>::create_event_task::<T>(caller.clone(), provided_id.clone(), vec![execution_time], vec![65, 65.saturating_add(i as u8)]).unwrap();
let task_id = AutomationTime::<T>::schedule_task(&task, provided_id).unwrap();
<AccountTasks<T>>::insert(caller.clone(), task_id, task);
task_ids.push((caller.clone(), task_id))
Expand Down
1 change: 1 addition & 0 deletions pallets/automation-time/src/fees.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ where

// Manually check for ExistenceRequirement since MultiCurrency doesn't currently support it
let free_balance = T::MultiCurrency::free_balance(self.currency_id, &self.owner);

free_balance
.checked_sub(&fee)
.ok_or(DispatchError::Token(BelowMinimum))?
Expand Down
99 changes: 6 additions & 93 deletions pallets/automation-time/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -349,112 +349,21 @@ pub mod pallet {

#[pallet::hooks]
impl<T: Config> Hooks<BlockNumberFor<T>> for Pallet<T> {
fn on_initialize(_: T::BlockNumber) -> Weight {
fn on_initialize(_block: T::BlockNumber) -> Weight {
if Self::is_shutdown() == true {
return T::DbWeight::get().reads(1u64)
}

let max_weight: Weight = Weight::from_ref_time(
T::MaxWeightPercentage::get().mul_floor(T::MaxBlockWeight::get()),
);

Self::trigger_tasks(max_weight)
}
}

#[pallet::call]
impl<T: Config> Pallet<T> {
/// Schedule a task to fire an event with a custom message.
///
/// Before the task can be scheduled the task must past validation checks.
/// * The transaction is signed
/// * The provided_id's length > 0
/// * The message's length > 0
/// * The times are valid
///
/// # Parameters
/// * `provided_id`: An id provided by the user. This id must be unique for the user.
/// * `execution_times`: The list of unix standard times in seconds for when the task should run.
/// * `message`: The message you want the event to have.
///
/// # Errors
/// * `InvalidTime`: Time must end in a whole hour.
/// * `PastTime`: Time must be in the future.
/// * `EmptyMessage`: The message cannot be empty.
/// * `DuplicateTask`: There can be no duplicate tasks.
/// * `TimeTooFarOut`: Execution time or frequency are past the max time horizon.
/// * `TimeSlotFull`: Time slot is full. No more tasks can be scheduled for this time.
#[pallet::call_index(0)]
#[pallet::weight(<T as Config>::WeightInfo::schedule_notify_task_full(execution_times.len().try_into().unwrap()))]
pub fn schedule_notify_task(
origin: OriginFor<T>,
provided_id: Vec<u8>,
execution_times: Vec<UnixTime>,
message: Vec<u8>,
) -> DispatchResult {
let who = ensure_signed(origin)?;
if message.len() == 0 {
Err(Error::<T>::EmptyMessage)?
}

let schedule = Schedule::new_fixed_schedule::<T>(execution_times)?;
Self::validate_and_schedule_task(
Action::Notify { message },
who,
provided_id,
schedule,
)?;
Ok(().into())
}

/// Schedule a task to transfer native token balance from sender to recipient.
///
/// Before the task can be scheduled the task must past validation checks.
/// * The transaction is signed
/// * The provided_id's length > 0
/// * The times are valid
/// * Larger transfer amount than the acceptable minimum
/// * Transfer to account other than to self
///
/// # Parameters
/// * `provided_id`: An id provided by the user. This id must be unique for the user.
/// * `execution_times`: The list of unix standard times in seconds for when the task should run.
/// * `recipient_id`: Account ID of the recipient.
/// * `amount`: Amount of balance to transfer.
///
/// # Errors
/// * `InvalidTime`: Time must end in a whole hour.
/// * `PastTime`: Time must be in the future.
/// * `DuplicateTask`: There can be no duplicate tasks.
/// * `TimeTooFarOut`: Execution time or frequency are past the max time horizon.
/// * `TimeSlotFull`: Time slot is full. No more tasks can be scheduled for this time.
/// * `InvalidAmount`: Amount has to be larger than 0.1 OAK.
/// * `TransferToSelf`: Sender cannot transfer money to self.
#[pallet::call_index(1)]
#[pallet::weight(<T as Config>::WeightInfo::schedule_native_transfer_task_full(execution_times.len().try_into().unwrap()))]
pub fn schedule_native_transfer_task(
origin: OriginFor<T>,
provided_id: Vec<u8>,
execution_times: Vec<UnixTime>,
recipient_id: AccountOf<T>,
#[pallet::compact] amount: BalanceOf<T>,
) -> DispatchResult {
let who = ensure_signed(origin)?;

// check for greater than existential deposit
if amount < T::Currency::minimum_balance() {
Err(<Error<T>>::InvalidAmount)?
}
// check not sent to self
if who == recipient_id {
Err(<Error<T>>::TransferToSelf)?
}
let action =
Action::NativeTransfer { sender: who.clone(), recipient: recipient_id, amount };
let schedule = Schedule::new_fixed_schedule::<T>(execution_times)?;
Self::validate_and_schedule_task(action, who, provided_id, schedule)?;
Ok(().into())
}

/// Schedule a task through XCMP to fire an XCMP message with a provided call.
///
/// Before the task can be scheduled the task must past validation checks.
Expand Down Expand Up @@ -724,6 +633,7 @@ pub mod pallet {
// It might take multiple blocks to fully catch up, so we limit update to a max weight.
let max_update_weight: Weight =
Weight::from_ref_time(T::UpdateQueueRatio::get().mul_floor(weight_left.ref_time()));

let update_weight = Self::update_task_queue(max_update_weight);

weight_left = weight_left.saturating_sub(update_weight);
Expand All @@ -732,6 +642,7 @@ pub mod pallet {
let run_task_weight = <T as Config>::WeightInfo::run_tasks_many_found(1)
.saturating_add(T::DbWeight::get().reads(1u64))
.saturating_add(T::DbWeight::get().writes(1u64));

if weight_left.ref_time() < run_task_weight.ref_time() {
return weight_left
}
Expand Down Expand Up @@ -793,6 +704,7 @@ pub mod pallet {
last_missed_slot,
missed_queue_allotted_weight,
);

LastTimeSlot::<T>::put((updated_last_time_slot, updated_last_missed_slot));
total_weight = total_weight
.saturating_add(missed_queue_update_weight)
Expand Down Expand Up @@ -1052,6 +964,7 @@ pub mod pallet {
/// Fire the notify event with the custom message.
pub fn run_notify_task(message: Vec<u8>) -> (Weight, Option<DispatchError>) {
Self::deposit_event(Event::Notify { message });

(<T as Config>::WeightInfo::run_notify_task(), None)
}

Expand Down
Loading