difftreelog
Scheduler sponsoring balance reserve
in: master
2 files changed
pallets/scheduler/src/lib.rsdiffbeforeafterboth78use up_sponsorship::SponsorshipHandler;78use up_sponsorship::SponsorshipHandler;79use scale_info::TypeInfo;79use scale_info::TypeInfo;80use sp_core::H160;80use sp_core::H160;81use frame_support::traits::NamedReservableCurrency;8283type ScheduledId = [u8; MAX_TASK_ID_LENGTH_IN_BYTES as usize];818482/// Our pallet's configuration trait. All our types and constants go in here. If the85/// Our pallet's configuration trait. All our types and constants go in here. If the83/// pallet is dependent on specific other pallets, then their configuration traits86/// pallet is dependent on specific other pallets, then their configuration traits97 /// The caller origin, overarching type of all pallets origins.100 /// The caller origin, overarching type of all pallets origins.98 type PalletsOrigin: From<system::RawOrigin<Self::AccountId>> + Codec + TypeInfo + Clone + Eq;101 type PalletsOrigin: From<system::RawOrigin<Self::AccountId>> + Codec + TypeInfo + Clone + Eq;102103 type Currency: NamedReservableCurrency<Self::AccountId, ReserveIdentifier = ScheduledId>;99104100 /// The aggregated call type.105 /// The aggregated call type.101 type Call: Parameter106 type Call: Parameter129 /// The type that encodes information that can be passed from pre_dispatch to post-dispatch.134 /// The type that encodes information that can be passed from pre_dispatch to post-dispatch.130 type Pre: Default + Codec + Clone + TypeInfo;135 type Pre: Default + Codec + Clone + TypeInfo;136137 fn reserve_balance(138 id: ScheduledId,139 sponsor: <T as frame_system::Config>::AccountId,140 call: <T as Config>::Call,141 count: u32,142 ) -> Result<(), DispatchError>;143144 fn pay_for_call(145 id: ScheduledId,146 sponsor: <T as frame_system::Config>::AccountId,147 call: <T as Config>::Call,148 ) -> Result<u128, DispatchError>;131149132 /// Resolve the call dispatch, including any post-dispatch operations.150 /// Resolve the call dispatch, including any post-dispatch operations.133 fn dispatch_call(151 fn dispatch_call(164#[derive(Clone, RuntimeDebug, Encode, Decode, TypeInfo)]182#[derive(Clone, RuntimeDebug, Encode, Decode, TypeInfo)]165pub struct Scheduled<Call, BlockNumber, PalletsOrigin, AccountId, PreDispatch> {183pub struct Scheduled<Call, BlockNumber, PalletsOrigin, AccountId, PreDispatch> {166 /// The unique identity for this task, if there is one.184 /// The unique identity for this task, if there is one.167 maybe_id: Option<Vec<u8>>,185 maybe_id: Option<ScheduledId>,168 /// This task's priority.186 /// This task's priority.169 priority: schedule::Priority,187 priority: schedule::Priority,170 /// The call to be dispatched.188 /// The call to be dispatched.197 >>>;215 >>>;198 216 199 /// Lookup from identity to the block number and index of the task.217 /// Lookup from identity to the block number and index of the task.200 Lookup: map hasher(twox_64_concat) Vec<u8> => Option<TaskAddress<T::BlockNumber>>;218 Lookup: map hasher(twox_64_concat) ScheduledId => Option<TaskAddress<T::BlockNumber>>;201 }219 }202}220}203221208 /// Canceled some task. \[when, index\]226 /// Canceled some task. \[when, index\]209 Canceled(BlockNumber, u32),227 Canceled(BlockNumber, u32),210 /// Dispatched some task. \[task, id, result\]228 /// Dispatched some task. \[task, id, result\]211 Dispatched(TaskAddress<BlockNumber>, Option<Vec<u8>>, DispatchResult),229 Dispatched(TaskAddress<BlockNumber>, Option<ScheduledId>, DispatchResult),212 }230 }213);231);214232285 /// # </weight>303 /// # </weight>286 #[weight = <T as Config>::WeightInfo::schedule_named(T::MaxScheduledPerBlock::get())]304 #[weight = <T as Config>::WeightInfo::schedule_named(T::MaxScheduledPerBlock::get())]287 fn schedule_named(origin,305 fn schedule_named(origin,288 id: Vec<u8>,306 id: ScheduledId,289 when: T::BlockNumber,307 when: T::BlockNumber,290 maybe_periodic: Option<schedule::Period<T::BlockNumber>>,308 maybe_periodic: Option<schedule::Period<T::BlockNumber>>,291 priority: schedule::Priority,309 priority: schedule::Priority,309 /// - Will use base weight of 100 which should be good for up to 30 scheduled calls327 /// - Will use base weight of 100 which should be good for up to 30 scheduled calls310 /// # </weight>328 /// # </weight>311 #[weight = <T as Config>::WeightInfo::cancel_named(T::MaxScheduledPerBlock::get())]329 #[weight = <T as Config>::WeightInfo::cancel_named(T::MaxScheduledPerBlock::get())]312 fn cancel_named(origin, id: Vec<u8>) {330 fn cancel_named(origin, id: ScheduledId) {313 T::ScheduleOrigin::ensure_origin(origin.clone())?;331 T::ScheduleOrigin::ensure_origin(origin.clone())?;314 let origin = <T as Config>::Origin::from(origin);332 let origin = <T as Config>::Origin::from(origin);315 Self::do_cancel_named(Some(origin.caller().clone()), id)?;333 Self::do_cancel_named(Some(origin.caller().clone()), id)?;341 /// # </weight>359 /// # </weight>342 #[weight = <T as Config>::WeightInfo::schedule_named(T::MaxScheduledPerBlock::get())]360 #[weight = <T as Config>::WeightInfo::schedule_named(T::MaxScheduledPerBlock::get())]343 fn schedule_named_after(origin,361 fn schedule_named_after(origin,344 id: Vec<u8>,362 id: ScheduledId,345 after: T::BlockNumber,363 after: T::BlockNumber,346 maybe_periodic: Option<schedule::Period<T::BlockNumber>>,364 maybe_periodic: Option<schedule::Period<T::BlockNumber>>,347 priority: schedule::Priority,365 priority: schedule::Priority,411 })429 })412 .filter_map(|(order, index, cumulative_weight, mut s)| {430 .filter_map(|(order, index, cumulative_weight, mut s)| {431432 // if call have id and periodic, it was be reserved 433 if s.maybe_id.is_some() && s.maybe_periodic.is_some()434 {435 let sender = ensure_signed(436 <<T as Config>::Origin as From<T::PalletsOrigin>>::from(s.origin.clone()).into(),437 )438 .unwrap_or_default();439 let who_will_pay = T::SponsorshipHandler::get_sponsor(&sender, &s.call.clone())440 .unwrap_or(sender.clone());441442 T::CallExecutor::pay_for_call(443 s.maybe_id.unwrap(),444 who_will_pay.clone(),445 s.call.clone(),446 );447 }448413 // We allow a scheduled call if:449 // We allow a scheduled call if:414 // - It's priority is `HARD_DEADLINE`450 // - It's priority is `HARD_DEADLINE`419 let r = T::CallExecutor::dispatch_call(s.pre_dispatch.clone(), s.call.clone());455 let r = T::CallExecutor::dispatch_call(s.pre_dispatch.clone(), s.call.clone());420456421 if let Err(_) = r {457 if let Err(_) = r {422 log::warn!(458 log::info!(423 target: "runtime::scheduler",459 target: "runtime::scheduler",424 "Warning: Scheduler has failed to execute a post-dispatch transaction. \460 "Warning: Scheduler has failed to execute a post-dispatch transaction. \425 This block might have become invalid.",461 This block might have become invalid.",486 }522 }487523488 fn do_schedule(524 fn do_schedule(489 maybe_id: Option<Vec<u8>>,525 maybe_id: Option<ScheduledId>,490 when: DispatchTime<T::BlockNumber>,526 when: DispatchTime<T::BlockNumber>,491 maybe_periodic: Option<schedule::Period<T::BlockNumber>>,527 maybe_periodic: Option<schedule::Period<T::BlockNumber>>,492 priority: schedule::Priority,528 priority: schedule::Priority,520556521 if let Some(periodic) = maybe_periodic {557 if let Some(periodic) = maybe_periodic {558559 // reserve balance for periodic execution 560 if maybe_id.is_some()561 { 562 let sender = ensure_signed(563 <<T as Config>::Origin as From<T::PalletsOrigin>>::from(origin.clone()).into(),564 )565 .unwrap_or_default();566 let who_will_pay = T::SponsorshipHandler::get_sponsor(&sender, &call.clone())567 .unwrap_or(sender.clone());522 for _i in 0..=periodic.1 {568 T::CallExecutor::reserve_balance(maybe_id.unwrap(), who_will_pay.clone(), call.clone(), periodic.1); 523 // displace to runtime and count the total required fee, then deduct. find a way to use OnChargePayment569 }524 // send constants and priority to runtime for fee computation, too. should create constants here or just declare them in runtime?570525 // roadblock - they will return on post_dispatch -- oh! tips?571 //for _i in 0..=periodic.1 {526 }572 // displace to runtime and count the total required fee, then deduct. find a way to use OnChargePayment573 // send constants and priority to runtime for fee computation, too. should create constants here or just declare them in runtime?574 // roadblock - they will return on post_dispatch -- oh! tips?575 //}527 }576 }528577529 let s = Some(Scheduled {578 let s = Some(Scheduled {623 }672 }624673625 fn do_schedule_named(674 fn do_schedule_named(626 id: Vec<u8>,675 id: ScheduledId,627 when: DispatchTime<T::BlockNumber>,676 when: DispatchTime<T::BlockNumber>,628 maybe_periodic: Option<schedule::Period<T::BlockNumber>>,677 maybe_periodic: Option<schedule::Period<T::BlockNumber>>,629 priority: schedule::Priority,678 priority: schedule::Priority,652 Ok(address)701 Ok(address)653 }702 }654703655 fn do_cancel_named(origin: Option<T::PalletsOrigin>, id: Vec<u8>) -> DispatchResult {704 fn do_cancel_named(origin: Option<T::PalletsOrigin>, id: ScheduledId) -> DispatchResult {656 Lookup::<T>::try_mutate_exists(id, |lookup| -> DispatchResult {705 Lookup::<T>::try_mutate_exists(id, |lookup| -> DispatchResult {657 if let Some((when, index)) = lookup.take() {706 if let Some((when, index)) = lookup.take() {658 let i = index as usize;707 let i = index as usize;684 }733 }685734686 fn do_reschedule_named(735 fn do_reschedule_named(687 id: Vec<u8>,736 id: ScheduledId,688 new_time: DispatchTime<T::BlockNumber>,737 new_time: DispatchTime<T::BlockNumber>,689 ) -> Result<TaskAddress<T::BlockNumber>, DispatchError> {738 ) -> Result<TaskAddress<T::BlockNumber>, DispatchError> {690 let new_time = Self::resolve_time(new_time)?;739 let new_time = Self::resolve_time(new_time)?;766 call: <T as Config>::Call,815 call: <T as Config>::Call,767 ) -> Result<Self::Address, ()> {816 ) -> Result<Self::Address, ()> {817818 let inner_id: ScheduledId = id.try_into().unwrap_or([0; MAX_TASK_ID_LENGTH_IN_BYTES as usize]);768 Self::do_schedule_named(id, when, maybe_periodic, priority, origin, call).map_err(|_| ())819 Self::do_schedule_named(inner_id, when, maybe_periodic, priority, origin, call).map_err(|_| ())769 }820 }770821771 fn cancel_named(id: Vec<u8>) -> Result<(), ()> {822 fn cancel_named(id: Vec<u8>) -> Result<(), ()> {823 let inner_id: ScheduledId = id.try_into().unwrap_or([0; MAX_TASK_ID_LENGTH_IN_BYTES as usize]);772 Self::do_cancel_named(None, id).map_err(|_| ())824 Self::do_cancel_named(None, inner_id).map_err(|_| ())773 }825 }774826775 fn reschedule_named(827 fn reschedule_named(776 id: Vec<u8>,828 id: Vec<u8>,777 when: DispatchTime<T::BlockNumber>,829 when: DispatchTime<T::BlockNumber>,778 ) -> Result<Self::Address, DispatchError> {830 ) -> Result<Self::Address, DispatchError> {831 let inner_id: ScheduledId = id.try_into().unwrap_or([0; MAX_TASK_ID_LENGTH_IN_BYTES as usize]);779 Self::do_reschedule_named(id, when)832 Self::do_reschedule_named(inner_id, when)780 }833 }781834782 fn next_dispatch_time(id: Vec<u8>) -> Result<T::BlockNumber, ()> {835 fn next_dispatch_time(id: Vec<u8>) -> Result<T::BlockNumber, ()> {836 let inner_id: ScheduledId = id.try_into().unwrap_or([0; MAX_TASK_ID_LENGTH_IN_BYTES as usize]);783 Lookup::<T>::get(id)837 Lookup::<T>::get(inner_id)784 .and_then(|(when, index)| Agenda::<T>::get(when).get(index as usize).map(|_| when))838 .and_then(|(when, index)| Agenda::<T>::get(when).get(index as usize).map(|_| when))785 .ok_or(())839 .ok_or(())786 }840 }runtime/src/lib.rsdiffbeforeafterboth393 // pub const ExistentialDeposit: u128 = 500;393 // pub const ExistentialDeposit: u128 = 500;394 pub const ExistentialDeposit: u128 = 0;394 pub const ExistentialDeposit: u128 = 0;395 pub const MaxLocks: u32 = 50;395 pub const MaxLocks: u32 = 50;396 pub const MaxReserves: u32 = 50;396}397}397398398impl pallet_balances::Config for Runtime {399impl pallet_balances::Config for Runtime {399 type MaxLocks = MaxLocks;400 type MaxLocks = MaxLocks;400 type MaxReserves = ();401 type MaxReserves = MaxReserves;401 type ReserveIdentifier = [u8; 8];402 type ReserveIdentifier = [u8; 16];402 /// The type for recording an account's balance.403 /// The type for recording an account's balance.403 type Balance = Balance;404 type Balance = Balance;404 /// The ubiquitous event type.405 /// The ubiquitous event type.819}820}821822823use frame_support::traits::NamedReservableCurrency;820824821pub struct SchedulerPaymentExecutor;825pub struct SchedulerPaymentExecutor;822impl<T: frame_system::Config + pallet_unq_scheduler::Config, SelfContainedSignedInfo>826impl<T: frame_system::Config + pallet_unq_scheduler::Config, SelfContainedSignedInfo>865 Ok(res)869 Ok(res)866 }870 }871872 fn reserve_balance(873 id: [u8; 16],874 sponsor: <T as frame_system::Config>::AccountId,875 call: <T as pallet_unq_scheduler::Config>::Call,876 count: u32,877 ) -> Result<(), DispatchError>878 {879 let dispatch_info = call.get_dispatch_info();880 let fee_charger = ChargeTransactionPayment::new(881 0882 );883 let pre = match fee_charger.pre_dispatch(&sponsor.clone().into(), &call.into(), &dispatch_info, 0) {884 Ok(p) => p,885 Err(_) => fail!("failed to get pre dispatch info")886 };887888 let count: u128 = count.into();889 let total_fee: u128 = pre.2.map(|imbalance| imbalance.peek()).unwrap() * count;890 <Balances as NamedReservableCurrency<AccountId>>::reserve_named(891 &id, 892 &(sponsor.into()), 893 total_fee)894 }895896 fn pay_for_call(897 id: [u8; 16],898 sponsor: <T as frame_system::Config>::AccountId,899 call: <T as pallet_unq_scheduler::Config>::Call,900 )901 -> Result<u128, DispatchError>902 {903 let dispatch_info = call.get_dispatch_info();904 let fee_charger = ChargeTransactionPayment::new(905 0906 );907 let pre = match fee_charger.pre_dispatch(&sponsor.clone().into(), &call.into(), &dispatch_info, 0) {908 Ok(p) => p,909 Err(_) => fail!("failed to get pre dispatch info")910 };911912 let single_fee: u128 = pre.2.map(|imbalance| imbalance.peek()).unwrap();913914 Ok(<Balances as NamedReservableCurrency<AccountId>>::unreserve_named(915 &id, 916 &(sponsor.into()), 917 single_fee))918 }867919868 fn pre_dispatch(920 fn pre_dispatch(869 signer: <T as frame_system::Config>::AccountId,921 signer: <T as frame_system::Config>::AccountId,893impl pallet_unq_scheduler::Config for Runtime {945impl pallet_unq_scheduler::Config for Runtime {894 type Event = Event;946 type Event = Event;895 type Origin = Origin;947 type Origin = Origin;948 type Currency = Balances;896 type PalletsOrigin = OriginCaller;949 type PalletsOrigin = OriginCaller;897 type Call = Call;950 type Call = Call;898 type MaximumWeight = MaximumSchedulerWeight;951 type MaximumWeight = MaximumSchedulerWeight;