diff --git a/pallets/reversible-transfers/src/lib.rs b/pallets/reversible-transfers/src/lib.rs index 09f894a3..988d30bd 100644 --- a/pallets/reversible-transfers/src/lib.rs +++ b/pallets/reversible-transfers/src/lib.rs @@ -695,7 +695,6 @@ pub mod pallet { T::Scheduler::schedule_named( schedule_id, dispatch_time, - None, Default::default(), frame_support::dispatch::RawOrigin::Signed(Self::account_id()).into(), bounded_call, diff --git a/pallets/scheduler/README.md b/pallets/scheduler/README.md index 47f2e3df..8bc9ab29 100644 --- a/pallets/scheduler/README.md +++ b/pallets/scheduler/README.md @@ -23,7 +23,7 @@ then those filter will not be used when dispatching the schedule call. ### Dispatchable Functions -- `schedule` - schedule a dispatch, which may be periodic, to occur at a +- `schedule` - schedule a dispatch to occur at a specified block and with a specified priority. - `cancel` - cancel a scheduled dispatch, specified by block number and index. diff --git a/pallets/scheduler/src/benchmarking.rs b/pallets/scheduler/src/benchmarking.rs index 04488c1c..445fad7c 100644 --- a/pallets/scheduler/src/benchmarking.rs +++ b/pallets/scheduler/src/benchmarking.rs @@ -60,9 +60,8 @@ fn fill_schedule( let origin: ::PalletsOrigin = frame_system::RawOrigin::Root.into(); for i in 0..n { let call = make_call::(None); - let period = Some((BlockNumberOrTimestamp::BlockNumber((i + 100).into()), 100)); let name = u32_to_name(i); - Scheduler::::do_schedule_named(name, t, period, 0, origin.clone(), call)?; + Scheduler::::do_schedule_named(name, t, 0, origin.clone(), call)?; } ensure!( Agenda::::get(BlockNumberOrTimestamp::BlockNumber(when)).len() == n as usize, @@ -76,23 +75,18 @@ fn u32_to_name(i: u32) -> TaskName { } fn make_task( - periodic: bool, named: bool, signed: bool, maybe_lookup_len: Option, priority: Priority, ) -> ScheduledOf { let call = make_call::(maybe_lookup_len); - let maybe_periodic = match periodic { - true => Some((BlockNumberOrTimestamp::BlockNumber(100u32.into()), 100)), - false => None, - }; let maybe_id = match named { true => Some(u32_to_name(0)), false => None, }; let origin = make_origin::(signed); - Scheduled { maybe_id, priority, call, maybe_periodic, origin, _phantom: PhantomData } + Scheduled { maybe_id, priority, call, origin, _phantom: PhantomData } } fn bounded(len: u32) -> Option> { @@ -161,54 +155,31 @@ benchmarks! { assert_eq!(executed, 0); } - // `service_task` when the task is a non-periodic, non-named, non-fetched call which is not - // dispatched (e.g. due to being overweight). service_task_base { let now = BLOCK_NUMBER.into(); - let task = make_task::(false, false, false, None, 0); - // prevent any tasks from actually being executed as we only want the surrounding weight. + let task = make_task::(false, false, None, 0); let mut counter = WeightMeter::with_limit(Weight::zero()); }: { let result = Scheduler::::service_task(&mut counter, BlockNumberOrTimestamp::BlockNumber(now), BlockNumberOrTimestamp::BlockNumber(now), 0, true, task); } verify { - //assert_eq!(result, Ok(())); } - // `service_task` when the task is a non-periodic, non-named, fetched call (with a known - // preimage length) and which is not dispatched (e.g. due to being overweight). #[pov_mode = MaxEncodedLen { - // Use measured PoV size for the Preimages since we pass in a length witness. Preimage::PreimageFor: Measured }] service_task_fetched { let s in (BoundedInline::bound() as u32) .. (T::Preimages::MAX_LENGTH as u32); let now = BLOCK_NUMBER.into(); - let task = make_task::(false, false, false, Some(s), 0); - // prevent any tasks from actually being executed as we only want the surrounding weight. + let task = make_task::(false, false, Some(s), 0); let mut counter = WeightMeter::with_limit(Weight::zero()); }: { let result = Scheduler::::service_task(&mut counter, BlockNumberOrTimestamp::BlockNumber(now), BlockNumberOrTimestamp::BlockNumber(now), 0, true, task); } verify { } - // `service_task` when the task is a non-periodic, named, non-fetched call which is not - // dispatched (e.g. due to being overweight). service_task_named { let now = BLOCK_NUMBER.into(); - let task = make_task::(false, true, false, None, 0); - // prevent any tasks from actually being executed as we only want the surrounding weight. - let mut counter = WeightMeter::with_limit(Weight::zero()); - }: { - let result = Scheduler::::service_task(&mut counter, BlockNumberOrTimestamp::BlockNumber(now), BlockNumberOrTimestamp::BlockNumber(now), 0, true, task); - } verify { - } - - // `service_task` when the task is a periodic, non-named, non-fetched call which is not - // dispatched (e.g. due to being overweight). - service_task_periodic { - let now = BLOCK_NUMBER.into(); - let task = make_task::(true, false, false, None, 0); - // prevent any tasks from actually being executed as we only want the surrounding weight. + let task = make_task::(true, false, None, 0); let mut counter = WeightMeter::with_limit(Weight::zero()); }: { let result = Scheduler::::service_task(&mut counter, BlockNumberOrTimestamp::BlockNumber(now), BlockNumberOrTimestamp::BlockNumber(now), 0, true, task); @@ -240,13 +211,11 @@ benchmarks! { schedule { let s in 0 .. (T::MaxScheduledPerBlock::get() - 1); let when = BLOCK_NUMBER.into(); - let periodic = Some((BlockNumberOrTimestamp::BlockNumber(BlockNumberFor::::one()), 100)); let priority = 0; - // Essentially a no-op call. let call = Box::new(SystemCall::set_storage { items: vec![] }.into()); fill_schedule::(when, s)?; - }: _(RawOrigin::Root, when, periodic, priority, call) + }: _(RawOrigin::Root, when, priority, call) verify { ensure!( Agenda::::get(BlockNumberOrTimestamp::BlockNumber(when)).len() == (s + 1) as usize, @@ -283,13 +252,11 @@ benchmarks! { let s in 0 .. (T::MaxScheduledPerBlock::get() - 1); let id = u32_to_name(s); let when = BLOCK_NUMBER.into(); - let periodic = Some((BlockNumberOrTimestamp::BlockNumber(BlockNumberFor::::one()), 100)); let priority = 0; - // Essentially a no-op call. let call = Box::new(SystemCall::set_storage { items: vec![] }.into()); fill_schedule::(when, s)?; - }: _(RawOrigin::Root, id, when, periodic, priority, call) + }: _(RawOrigin::Root, id, when, priority, call) verify { ensure!( Agenda::::get(BlockNumberOrTimestamp::BlockNumber(when)).len() == (s + 1) as usize, diff --git a/pallets/scheduler/src/lib.rs b/pallets/scheduler/src/lib.rs index dfe7b2cd..95b28c71 100644 --- a/pallets/scheduler/src/lib.rs +++ b/pallets/scheduler/src/lib.rs @@ -88,7 +88,7 @@ use frame_system::{ pallet_prelude::BlockNumberFor, {self as system}, }; -use qp_scheduler::{BlockNumberOrTimestamp, DispatchTime, Period, ScheduleNamed}; +use qp_scheduler::{BlockNumberOrTimestamp, DispatchTime, ScheduleNamed}; use scale_info::TypeInfo; use sp_runtime::{ traits::{BadOrigin, Dispatchable, One, Saturating, Zero}, @@ -132,11 +132,9 @@ pub struct Scheduled priority: schedule::Priority, /// The call to be dispatched. call: Call, - /// If the call is periodic, then this points to the information concerning that. - maybe_periodic: Option>, /// The origin with which to dispatch the call. origin: PalletsOrigin, - _phantom: PhantomData, + _phantom: PhantomData<(AccountId, BlockNumber, Moment)>, } impl @@ -146,13 +144,12 @@ where PalletsOrigin: Clone, { /// Create a new task to be used for retry attempts of the original one. The cloned task will - /// have the same `priority`, `call` and `origin`, but will always be non-periodic and unnamed. + /// have the same `priority`, `call` and `origin`, but will always be unnamed. pub fn as_retry(&self) -> Self { Self { maybe_id: None, priority: self.priority, call: self.call.clone(), - maybe_periodic: None, origin: self.origin.clone(), _phantom: Default::default(), } @@ -169,7 +166,7 @@ pub type ScheduledOf = Scheduled< >; pub(crate) trait MarginalWeightInfo: WeightInfo { - fn service_task(maybe_lookup_len: Option, named: bool, periodic: bool) -> Weight { + fn service_task(maybe_lookup_len: Option, named: bool) -> Weight { let base = Self::service_task_base(); let mut total = match maybe_lookup_len { None => base, @@ -178,9 +175,6 @@ pub(crate) trait MarginalWeightInfo: WeightInfo { if named { total.saturating_accrue(Self::service_task_named().saturating_sub(base)); } - if periodic { - total.saturating_accrue(Self::service_task_periodic().saturating_sub(base)); - } total } } @@ -329,8 +323,6 @@ pub mod pallet { RetryCancelled { task: TaskAddressOf, id: Option }, /// The call for the provided hash was not found so the task has been aborted. CallUnavailable { task: TaskAddressOf, id: Option }, - /// The given task was unable to be renewed since the agenda is full at that block. - PeriodicFailed { task: TaskAddressOf, id: Option }, /// The given task was unable to be retried since the agenda is full at that block or there /// was not enough weight to reschedule it. RetryFailed { task: TaskAddressOf, id: Option }, @@ -389,13 +381,11 @@ pub mod pallet { #[pallet::call] impl Pallet { - /// Anonymously schedule a task. #[pallet::call_index(0)] #[pallet::weight(::WeightInfo::schedule(T::MaxScheduledPerBlock::get()))] pub fn schedule( origin: OriginFor, when: BlockNumberFor, - maybe_periodic: Option, T::Moment>>, priority: schedule::Priority, call: Box<::RuntimeCall>, ) -> DispatchResult { @@ -403,7 +393,6 @@ pub mod pallet { let origin = ::RuntimeOrigin::from(origin); Self::do_schedule( DispatchTime::At(when), - maybe_periodic, priority, origin.caller().clone(), T::Preimages::bound(*call)?, @@ -425,14 +414,12 @@ pub mod pallet { Ok(()) } - /// Schedule a named task. #[pallet::call_index(2)] #[pallet::weight(::WeightInfo::schedule_named(T::MaxScheduledPerBlock::get()))] pub fn schedule_named( origin: OriginFor, id: TaskName, when: BlockNumberFor, - maybe_periodic: Option, T::Moment>>, priority: schedule::Priority, call: Box<::RuntimeCall>, ) -> DispatchResult { @@ -441,7 +428,6 @@ pub mod pallet { Self::do_schedule_named( id, DispatchTime::At(when), - maybe_periodic, priority, origin.caller().clone(), T::Preimages::bound(*call)?, @@ -459,13 +445,11 @@ pub mod pallet { Ok(()) } - /// Anonymously schedule a task after a delay. #[pallet::call_index(4)] #[pallet::weight(::WeightInfo::schedule(T::MaxScheduledPerBlock::get()))] pub fn schedule_after( origin: OriginFor, after: BlockNumberOrTimestamp, T::Moment>, - maybe_periodic: Option, T::Moment>>, priority: schedule::Priority, call: Box<::RuntimeCall>, ) -> DispatchResult { @@ -473,7 +457,6 @@ pub mod pallet { let origin = ::RuntimeOrigin::from(origin); Self::do_schedule( DispatchTime::After(after), - maybe_periodic, priority, origin.caller().clone(), T::Preimages::bound(*call)?, @@ -481,14 +464,12 @@ pub mod pallet { Ok(()) } - /// Schedule a named task after a delay. #[pallet::call_index(5)] #[pallet::weight(::WeightInfo::schedule_named(T::MaxScheduledPerBlock::get()))] pub fn schedule_named_after( origin: OriginFor, id: TaskName, after: BlockNumberOrTimestamp, T::Moment>, - maybe_periodic: Option, T::Moment>>, priority: schedule::Priority, call: Box<::RuntimeCall>, ) -> DispatchResult { @@ -497,7 +478,6 @@ pub mod pallet { Self::do_schedule_named( id, DispatchTime::After(after), - maybe_periodic, priority, origin.caller().clone(), T::Preimages::bound(*call)?, @@ -510,10 +490,9 @@ pub mod pallet { /// succeeds. /// /// Tasks which need to be scheduled for a retry are still subject to weight metering and - /// agenda space, same as a regular task. If a periodic task fails, it will be scheduled - /// normally while the task is retrying. + /// agenda space, same as a regular task. /// - /// Tasks scheduled as a result of a retry for a periodic task are unnamed, non-periodic + /// Tasks scheduled as a result of a retry are unnamed /// clones of the original task. Their retry configuration will be derived from the /// original task's configuration, but will have a lower value for `remaining` than the /// original `total_retries`. @@ -547,10 +526,9 @@ pub mod pallet { /// it succeeds. /// /// Tasks which need to be scheduled for a retry are still subject to weight metering and - /// agenda space, same as a regular task. If a periodic task fails, it will be scheduled - /// normally while the task is retrying. + /// agenda space, same as a regular task. /// - /// Tasks scheduled as a result of a retry for a periodic task are unnamed, non-periodic + /// Tasks scheduled as a result of a retry are unnamed /// clones of the original task. Their retry configuration will be derived from the /// original task's configuration, but will have a lower value for `remaining` than the /// original `total_retries`. @@ -700,35 +678,17 @@ impl Pallet { fn do_schedule( when: DispatchTime, T::Moment>, - maybe_periodic: Option, T::Moment>>, priority: schedule::Priority, origin: T::PalletsOrigin, call: BoundedCallOf, ) -> Result, DispatchError> { let when = Self::resolve_time(when)?; - let lookup_hash = call.lookup_hash(); - - // sanitize maybe_periodic - let maybe_periodic = maybe_periodic - .filter(|p| p.1 > 1 && !p.0.is_zero()) - // Remove one from the number of repetitions since we will schedule one now. - .map(|(p, c)| (p, c - 1)); - let task = Scheduled { - maybe_id: None, - priority, - call, - maybe_periodic, - origin, - _phantom: PhantomData, - }; + let task = Scheduled { maybe_id: None, priority, call, origin, _phantom: PhantomData }; let res = Self::place_task(when, task).map_err(|x| x.0)?; - if let Some(hash) = lookup_hash { - // Request the call to be made available. T::Preimages::request(&hash); } - Ok(res) } @@ -785,41 +745,21 @@ impl Pallet { fn do_schedule_named( id: TaskName, when: DispatchTime, T::Moment>, - maybe_periodic: Option, T::Moment>>, priority: schedule::Priority, origin: T::PalletsOrigin, call: BoundedCallOf, ) -> Result, DispatchError> { - // ensure id it is unique if Lookup::::contains_key(&id) { return Err(Error::::FailedToSchedule.into()); } - let when = Self::resolve_time(when)?; - let lookup_hash = call.lookup_hash(); - - // sanitize maybe_periodic - let maybe_periodic = maybe_periodic - .filter(|p| p.1 > 1 && !p.0.is_zero()) - // Remove one from the number of repetitions since we will schedule one now. - .map(|(p, c)| (p, c - 1)); - - let task = Scheduled { - maybe_id: Some(id), - priority, - call, - maybe_periodic, - origin, - _phantom: Default::default(), - }; + let task = + Scheduled { maybe_id: Some(id), priority, call, origin, _phantom: Default::default() }; let res = Self::place_task(when, task).map_err(|x| x.0)?; - if let Some(hash) = lookup_hash { - // Request the call to be made available. T::Preimages::request(&hash); } - Ok(res) } @@ -1038,11 +978,9 @@ impl Pallet { Some(t) => t, }; - // Compute this task's base weight (varies by preimage lookup, name, periodicity). let base_weight = T::WeightInfo::service_task( task.call.lookup_len().map(|x| x as usize), task.maybe_id.is_some(), - task.maybe_periodic.is_some(), ); // If the block can't afford even the base cost, put the task back and stop. @@ -1090,7 +1028,6 @@ impl Pallet { /// This involves: /// - removing and potentially replacing the `Lookup` entry for the task. /// - realizing the task's call which can include a preimage lookup. - /// - Rescheduling the task for execution in a later agenda if periodic. /// Execute a single scheduled task. Returns Ok(()) on successful dispatch, or Err with /// the task back (Some) for retry / postponement, or None if permanently removed. fn service_task( @@ -1099,10 +1036,10 @@ impl Pallet { when: BlockNumberOrTimestampOf, agenda_index: u32, is_first: bool, - mut task: ScheduledOf, + task: ScheduledOf, ) -> Result<(), (ServiceTaskError, Option>)> { // Eagerly remove the name->address lookup. If the task succeeds or gets rescheduled - // periodically, the new address will be re-inserted by place_task. If it fails, + // via a retry, the new address will be re-inserted by place_task. If it fails, // the name is freed. if let Some(ref id) = task.maybe_id { Lookup::::remove(id); @@ -1126,25 +1063,18 @@ impl Pallet { let _ = weight.try_consume(T::WeightInfo::service_task( task.call.lookup_len().map(|x| x as usize), task.maybe_id.is_some(), - task.maybe_periodic.is_some(), )); return Err((Unavailable, Some(task))); }, }; - // Charge the weight for servicing this task (lookup, name handling, periodic logic). let _ = weight.try_consume(T::WeightInfo::service_task( lookup_len.map(|x| x as usize), task.maybe_id.is_some(), - task.maybe_periodic.is_some(), )); - // Attempt to dispatch the call. execute_dispatch checks whether the call's weight - // fits in the remaining block weight before dispatching. match Self::execute_dispatch(weight, task.origin.clone(), call) { - // Too heavy and this is the first task in the block -- if even an empty block - // can't fit it, it will never execute. Remove it permanently. Err(()) if is_first => { T::Preimages::drop(&task.call); Self::deposit_event(Event::PermanentlyOverweight { @@ -1153,14 +1083,9 @@ impl Pallet { }); Err((Unavailable, None)) }, - // Too heavy but not first -- a future block with less prior work might fit it. Err(()) => Err((Overweight, Some(task))), - - // Dispatch succeeded (result may still be a dispatch error like "threshold not met"). Ok(result) => { let failed = result.is_err(); - // Take the retry config (removes it from storage). We'll re-insert it at - // the new address if the task gets rescheduled. let maybe_retry_config = Retries::::take((when, agenda_index)); Self::deposit_event(Event::Dispatched { @@ -1169,54 +1094,13 @@ impl Pallet { result, }); - // If the dispatch returned an error and a retry is configured, schedule - // a retry attempt at the retry period offset. - match maybe_retry_config { - Some(retry_config) if failed => { + if let Some(retry_config) = maybe_retry_config { + if failed { Self::schedule_retry(weight, now, when, agenda_index, &task, retry_config); - }, - _ => {}, - } - - // Handle periodic rescheduling: if this task repeats, compute the next - // wake time and place a new copy in the agenda. - if let &Some((period, count)) = &task.maybe_periodic { - if count > 1 { - task.maybe_periodic = Some((period, count - 1)); - } else { - // Last repetition -- clear periodicity so it won't repeat again. - task.maybe_periodic = None; } - match now.saturating_add(&period) { - Ok(wake) => match Self::place_task(wake, task) { - Ok(new_address) => - // Carry the retry config forward to the new address. - if let Some(retry_config) = maybe_retry_config { - Retries::::insert(new_address, retry_config); - }, - Err((_, task)) => { - // Agenda at the target time is full. - T::Preimages::drop(&task.call); - Self::deposit_event(Event::PeriodicFailed { - task: (when, agenda_index), - id: task.maybe_id, - }); - }, - }, - // Period type mismatches execution domain (e.g. Timestamp period - // on a BlockNumber task). Cannot compute next wake time. - Err(_) => { - T::Preimages::drop(&task.call); - Self::deposit_event(Event::PeriodicFailed { - task: (when, agenda_index), - id: task.maybe_id, - }); - }, - } - } else { - // Non-periodic task -- release the preimage reference. - T::Preimages::drop(&task.call); } + + T::Preimages::drop(&task.call); Ok(()) }, } @@ -1327,6 +1211,11 @@ impl Pallet { } } +use schedule::v3::TaskName; + +// Shims for Substrate's v3 scheduler traits, required by pallet_referenda (external crate). +// Periodic scheduling is intentionally unsupported -- these impls exist solely to satisfy the +// trait bounds. Once pallet_referenda is forked locally, these can be removed entirely. impl schedule::v3::Anon, ::RuntimeCall, T::PalletsOrigin> for Pallet { @@ -1340,13 +1229,8 @@ impl schedule::v3::Anon, ::RuntimeCall origin: T::PalletsOrigin, call: BoundedCallOf, ) -> Result { - let periodic = if let Some(periodic) = maybe_periodic { - Some((BlockNumberOrTimestamp::BlockNumber(periodic.0), periodic.1)) - } else { - None - }; - - Self::do_schedule(when.into(), periodic, priority, origin, call) + assert!(maybe_periodic.is_none(), "Periodic scheduling is not supported"); + Self::do_schedule(when.into(), priority, origin, call) } fn cancel((when, index): Self::Address) -> Result<(), DispatchError> { @@ -1371,8 +1255,6 @@ impl schedule::v3::Anon, ::RuntimeCall } } -use schedule::v3::TaskName; - impl schedule::v3::Named, ::RuntimeCall, T::PalletsOrigin> for Pallet { @@ -1387,12 +1269,11 @@ impl schedule::v3::Named, ::RuntimeCal origin: T::PalletsOrigin, call: BoundedCallOf, ) -> Result { - let periodic = if let Some(periodic) = maybe_periodic { - Some((BlockNumberOrTimestamp::BlockNumber(periodic.0), periodic.1)) - } else { - None - }; - Self::do_schedule_named(id, when.into(), periodic, priority, origin, call) + assert!( + maybe_periodic.is_none(), + "Periodic scheduling is not supported for schedule named" + ); + Self::do_schedule_named(id, when.into(), priority, origin, call) } fn cancel_named(id: TaskName) -> Result<(), DispatchError> { @@ -1429,12 +1310,11 @@ impl fn schedule_named( id: TaskName, when: DispatchTime, T::Moment>, - maybe_periodic: Option, T::Moment>>, priority: schedule::Priority, origin: T::PalletsOrigin, call: BoundedCallOf, ) -> Result { - Self::do_schedule_named(id, when, maybe_periodic, priority, origin, call) + Self::do_schedule_named(id, when, priority, origin, call) } fn cancel_named(id: TaskName) -> Result<(), DispatchError> { diff --git a/pallets/scheduler/src/mock.rs b/pallets/scheduler/src/mock.rs index 947b9ce6..cf575a95 100644 --- a/pallets/scheduler/src/mock.rs +++ b/pallets/scheduler/src/mock.rs @@ -165,9 +165,6 @@ impl WeightInfo for TestWeightInfo { fn service_task_base() -> Weight { Weight::from_parts(0b0000_0100, 0) } - fn service_task_periodic() -> Weight { - Weight::from_parts(0b0000_1100, 0) - } fn service_task_named() -> Weight { Weight::from_parts(0b0001_0100, 0) } diff --git a/pallets/scheduler/src/tests.rs b/pallets/scheduler/src/tests.rs index e31cabcd..1708873c 100644 --- a/pallets/scheduler/src/tests.rs +++ b/pallets/scheduler/src/tests.rs @@ -43,7 +43,6 @@ fn basic_scheduling_works() { // Schedule call to be executed at the 4th block assert_ok!(Scheduler::do_schedule( DispatchTime::At(4), - None, 127, root(), Preimage::bound(call).unwrap() @@ -78,7 +77,7 @@ fn scheduling_with_preimages_works() { let hashed = Bounded::Lookup { hash, len }; // Schedule call to be executed at block 4 with the PreImage hash - assert_ok!(Scheduler::do_schedule(DispatchTime::At(4), None, 127, root(), hashed)); + assert_ok!(Scheduler::do_schedule(DispatchTime::At(4), 127, root(), hashed)); // Register preimage on chain assert_ok!(Preimage::note_preimage(RuntimeOrigin::signed(0), call.encode())); @@ -110,7 +109,6 @@ fn schedule_after_works() { // This will schedule the call 3 blocks after the next block... so block 3 + 3 = 6 assert_ok!(Scheduler::do_schedule( DispatchTime::After(BlockNumberOrTimestamp::BlockNumber(3)), - None, 127, root(), Preimage::bound(call).unwrap() @@ -133,7 +131,6 @@ fn schedule_after_zero_works() { assert!(!::BaseCallFilter::contains(&call)); assert_ok!(Scheduler::do_schedule( DispatchTime::After(BlockNumberOrTimestamp::BlockNumber(0)), - None, 127, root(), Preimage::bound(call).unwrap() @@ -146,38 +143,6 @@ fn schedule_after_zero_works() { }); } -#[test] -fn periodic_scheduling_works() { - new_test_ext().execute_with(|| { - // at #4, every 3 blocks, 3 times. - assert_ok!(Scheduler::do_schedule( - DispatchTime::At(4), - Some((BlockNumberOrTimestamp::BlockNumber(3), 3)), - 127, - root(), - Preimage::bound(RuntimeCall::Logger(logger::Call::log { - i: 42, - weight: Weight::from_parts(10, 0) - })) - .unwrap() - )); - run_to_block(3); - assert!(logger::log().is_empty()); - run_to_block(4); - assert_eq!(logger::log(), vec![(root(), 42u32)]); - run_to_block(6); - assert_eq!(logger::log(), vec![(root(), 42u32)]); - run_to_block(7); - assert_eq!(logger::log(), vec![(root(), 42u32), (root(), 42u32)]); - run_to_block(9); - assert_eq!(logger::log(), vec![(root(), 42u32), (root(), 42u32)]); - run_to_block(10); - assert_eq!(logger::log(), vec![(root(), 42u32), (root(), 42u32), (root(), 42u32)]); - run_to_block(100); - assert_eq!(logger::log(), vec![(root(), 42u32), (root(), 42u32), (root(), 42u32)]); - }); -} - #[test] fn retry_scheduling_works() { new_test_ext().execute_with(|| { @@ -186,7 +151,6 @@ fn retry_scheduling_works() { // task 42 at #4 assert_ok!(Scheduler::do_schedule( DispatchTime::At(4), - None, 127, root(), Preimage::bound(RuntimeCall::Logger(logger::Call::timed_log { @@ -253,7 +217,6 @@ fn named_retry_scheduling_works() { Scheduler::do_schedule_named( [1u8; 32], DispatchTime::At(4), - None, 127, root(), Preimage::bound(call).unwrap(), @@ -313,7 +276,6 @@ fn retry_scheduling_multiple_tasks_works() { // task 20 at #4 assert_ok!(Scheduler::do_schedule( DispatchTime::At(4), - None, 127, root(), Preimage::bound(RuntimeCall::Logger(logger::Call::timed_log { @@ -325,7 +287,6 @@ fn retry_scheduling_multiple_tasks_works() { // task 42 at #4 assert_ok!(Scheduler::do_schedule( DispatchTime::At(4), - None, 127, root(), Preimage::bound(RuntimeCall::Logger(logger::Call::timed_log { @@ -411,7 +372,6 @@ fn retry_scheduling_multiple_named_tasks_works() { assert_ok!(Scheduler::do_schedule_named( [20u8; 32], DispatchTime::At(4), - None, 127, root(), Preimage::bound(RuntimeCall::Logger(logger::Call::timed_log { @@ -424,7 +384,6 @@ fn retry_scheduling_multiple_named_tasks_works() { assert_ok!(Scheduler::do_schedule_named( [42u8; 32], DispatchTime::At(4), - None, 127, root(), Preimage::bound(RuntimeCall::Logger(logger::Call::timed_log { @@ -501,486 +460,6 @@ fn retry_scheduling_multiple_named_tasks_works() { }); } -#[test] -fn retry_scheduling_with_period_works() { - new_test_ext().execute_with(|| { - // tasks fail until we reach block 4 and after we're past block 8 - Threshold::::put((4, 8)); - // task 42 at #4, every 3 blocks, 6 times - assert_ok!(Scheduler::do_schedule( - DispatchTime::At(4), - Some((BlockNumberOrTimestamp::BlockNumber(3), 6)), - 127, - root(), - Preimage::bound(RuntimeCall::Logger(logger::Call::timed_log { - i: 42, - weight: Weight::from_parts(10, 0) - })) - .unwrap() - )); - - assert!(Agenda::::get(BlockNumberOrTimestamp::BlockNumber(4))[0].is_some()); - // 42 will be retried 10 times every 2 blocks - assert_ok!(Scheduler::set_retry( - root().into(), - (BlockNumberOrTimestamp::BlockNumber(4), 0), - 10, - BlockNumberOrTimestamp::BlockNumber(2) - )); - assert_eq!(Retries::::iter().count(), 1); - run_to_block(3); - assert!(logger::log().is_empty()); - assert!(Agenda::::get(BlockNumberOrTimestamp::BlockNumber(4))[0].is_some()); - // 42 runs successfully once, it will run again at block 7 - run_to_block(4); - assert!(Agenda::::get(BlockNumberOrTimestamp::BlockNumber(4)).is_empty()); - assert!(Agenda::::get(BlockNumberOrTimestamp::BlockNumber(7))[0].is_some()); - assert_eq!(Retries::::iter().count(), 1); - assert_eq!(logger::log(), vec![(root(), 42u32)]); - // nothing changed - run_to_block(6); - assert!(Agenda::::get(BlockNumberOrTimestamp::BlockNumber(7))[0].is_some()); - assert_eq!(logger::log(), vec![(root(), 42u32)]); - // 42 runs successfully again, it will run again at block 10 - run_to_block(7); - assert!(Agenda::::get(BlockNumberOrTimestamp::BlockNumber(7)).is_empty()); - assert!(Agenda::::get(BlockNumberOrTimestamp::BlockNumber(10))[0].is_some()); - assert_eq!(Retries::::iter().count(), 1); - assert_eq!(logger::log(), vec![(root(), 42u32), (root(), 42u32)]); - run_to_block(9); - assert!(Agenda::::get(BlockNumberOrTimestamp::BlockNumber(10))[0].is_some()); - assert_eq!(logger::log(), vec![(root(), 42u32), (root(), 42u32)]); - // 42 has 10 retries left out of a total of 10 - assert_eq!( - Retries::::get((BlockNumberOrTimestamp::BlockNumber(10), 0)) - .unwrap() - .remaining, - 10 - ); - // 42 will fail because we're outside the set threshold (block number in `4..8`), so it - // should be retried in 2 blocks (at block 12) - run_to_block(10); - // should be queued for the normal period of 3 blocks - assert!(Agenda::::get(BlockNumberOrTimestamp::BlockNumber(13))[0].is_some()); - // should also be queued to be retried in 2 blocks - assert!(Agenda::::get(BlockNumberOrTimestamp::BlockNumber(12))[0].is_some()); - // 42 has consumed one retry attempt - assert_eq!( - Retries::::get((BlockNumberOrTimestamp::BlockNumber(12), 0)) - .unwrap() - .remaining, - 9 - ); - assert_eq!( - Retries::::get((BlockNumberOrTimestamp::BlockNumber(13), 0)) - .unwrap() - .remaining, - 10 - ); - assert_eq!(Retries::::iter().count(), 2); - assert_eq!(logger::log(), vec![(root(), 42u32), (root(), 42u32)]); - // 42 will fail again - run_to_block(12); - // should still be queued for the normal period - assert!(Agenda::::get(BlockNumberOrTimestamp::BlockNumber(13))[0].is_some()); - // should be queued to be retried in 2 blocks - assert!(Agenda::::get(BlockNumberOrTimestamp::BlockNumber(14))[0].is_some()); - // 42 has consumed another retry attempt - assert_eq!( - Retries::::get((BlockNumberOrTimestamp::BlockNumber(14), 0)) - .unwrap() - .remaining, - 8 - ); - assert_eq!( - Retries::::get((BlockNumberOrTimestamp::BlockNumber(13), 0)) - .unwrap() - .remaining, - 10 - ); - assert_eq!(Retries::::iter().count(), 2); - assert_eq!(logger::log(), vec![(root(), 42u32), (root(), 42u32)]); - // 42 will fail for the regular periodic run - run_to_block(13); - // should still be queued for the normal period - assert!(Agenda::::get(BlockNumberOrTimestamp::BlockNumber(16))[0].is_some()); - // should still be queued to be retried next block - assert!(Agenda::::get(BlockNumberOrTimestamp::BlockNumber(14))[0].is_some()); - // 42 consumed another periodic run, which failed, so another retry is queued for block 15 - assert!(Agenda::::get(BlockNumberOrTimestamp::BlockNumber(16))[0] - .as_ref() - .unwrap() - .maybe_periodic - .is_some()); - assert!(Agenda::::get(BlockNumberOrTimestamp::BlockNumber(15))[0] - .as_ref() - .unwrap() - .maybe_periodic - .is_none()); - assert!(Agenda::::get(BlockNumberOrTimestamp::BlockNumber(14))[0] - .as_ref() - .unwrap() - .maybe_periodic - .is_none()); - assert_eq!(Retries::::iter().count(), 3); - assert!( - Retries::::get((BlockNumberOrTimestamp::BlockNumber(14), 0)) - .unwrap() - .remaining == 8 - ); - assert!( - Retries::::get((BlockNumberOrTimestamp::BlockNumber(15), 0)) - .unwrap() - .remaining == 9 - ); - assert!( - Retries::::get((BlockNumberOrTimestamp::BlockNumber(16), 0)) - .unwrap() - .remaining == 10 - ); - assert_eq!(logger::log(), vec![(root(), 42u32), (root(), 42u32)]); - // change the threshold to allow the task to succeed - Threshold::::put((14, 100)); - // first retry should now succeed - run_to_block(14); - assert!(Agenda::::get(BlockNumberOrTimestamp::BlockNumber(15))[0] - .as_ref() - .unwrap() - .maybe_periodic - .is_none()); - assert_eq!( - Agenda::::get(BlockNumberOrTimestamp::BlockNumber(16)) - .iter() - .filter(|entry| entry.is_some()) - .count(), - 1 - ); - assert!(Agenda::::get(BlockNumberOrTimestamp::BlockNumber(16))[0].is_some()); - assert_eq!( - Retries::::get((BlockNumberOrTimestamp::BlockNumber(15), 0)) - .unwrap() - .remaining, - 9 - ); - assert_eq!( - Retries::::get((BlockNumberOrTimestamp::BlockNumber(16), 0)) - .unwrap() - .remaining, - 10 - ); - assert_eq!(Retries::::iter().count(), 2); - assert_eq!(logger::log(), vec![(root(), 42u32), (root(), 42u32), (root(), 42u32)]); - // second retry should also succeed - run_to_block(15); - assert_eq!( - Agenda::::get(BlockNumberOrTimestamp::BlockNumber(16)) - .iter() - .filter(|entry| entry.is_some()) - .count(), - 1 - ); - assert!(Agenda::::get(BlockNumberOrTimestamp::BlockNumber(16))[0].is_some()); - assert!(Agenda::::get(BlockNumberOrTimestamp::BlockNumber(17)).is_empty()); - assert_eq!( - Retries::::get((BlockNumberOrTimestamp::BlockNumber(16), 0)) - .unwrap() - .remaining, - 10 - ); - assert_eq!(Retries::::iter().count(), 1); - assert_eq!( - logger::log(), - vec![(root(), 42u32), (root(), 42u32), (root(), 42u32), (root(), 42u32)] - ); - // normal periodic run on block 16 will succeed - run_to_block(16); - // next periodic run at block 19 - assert!(Agenda::::get(BlockNumberOrTimestamp::BlockNumber(19))[0].is_some()); - assert!(Agenda::::get(BlockNumberOrTimestamp::BlockNumber(18)).is_empty()); - assert!(Agenda::::get(BlockNumberOrTimestamp::BlockNumber(17)).is_empty()); - assert_eq!( - Retries::::get((BlockNumberOrTimestamp::BlockNumber(19), 0)) - .unwrap() - .remaining, - 10 - ); - assert_eq!(Retries::::iter().count(), 1); - assert_eq!( - logger::log(), - vec![ - (root(), 42u32), - (root(), 42u32), - (root(), 42u32), - (root(), 42u32), - (root(), 42u32) - ] - ); - // final periodic run on block 19 will succeed - run_to_block(19); - // next periodic run at block 19 - assert_eq!(Agenda::::iter().count(), 0); - assert_eq!(Retries::::iter().count(), 0); - assert_eq!( - logger::log(), - vec![ - (root(), 42u32), - (root(), 42u32), - (root(), 42u32), - (root(), 42u32), - (root(), 42u32), - (root(), 42u32) - ] - ); - }); -} - -#[test] -fn named_retry_scheduling_with_period_works() { - new_test_ext().execute_with(|| { - // tasks fail until we reach block 4 and after we're past block 8 - Threshold::::put((4, 8)); - // task 42 at #4, every 3 blocks, 6 times - assert_ok!(Scheduler::do_schedule_named( - [42u8; 32], - DispatchTime::At(4), - Some((BlockNumberOrTimestamp::BlockNumber(3), 6)), - 127, - root(), - Preimage::bound(RuntimeCall::Logger(logger::Call::timed_log { - i: 42, - weight: Weight::from_parts(10, 0) - })) - .unwrap() - )); - - assert!(Agenda::::get(BlockNumberOrTimestamp::BlockNumber(4))[0].is_some()); - // 42 will be retried 10 times every 2 blocks - assert_ok!(Scheduler::set_retry_named( - root().into(), - [42u8; 32], - 10, - BlockNumberOrTimestamp::BlockNumber(2) - )); - assert_eq!(Retries::::iter().count(), 1); - run_to_block(3); - assert!(logger::log().is_empty()); - assert!(Agenda::::get(BlockNumberOrTimestamp::BlockNumber(4))[0].is_some()); - // 42 runs successfully once, it will run again at block 7 - run_to_block(4); - assert!(Agenda::::get(BlockNumberOrTimestamp::BlockNumber(4)).is_empty()); - assert!(Agenda::::get(BlockNumberOrTimestamp::BlockNumber(7))[0].is_some()); - assert_eq!(Retries::::iter().count(), 1); - assert_eq!(logger::log(), vec![(root(), 42u32)]); - // nothing changed - run_to_block(6); - assert!(Agenda::::get(BlockNumberOrTimestamp::BlockNumber(7))[0].is_some()); - assert_eq!(logger::log(), vec![(root(), 42u32)]); - // 42 runs successfully again, it will run again at block 10 - run_to_block(7); - assert!(Agenda::::get(BlockNumberOrTimestamp::BlockNumber(7)).is_empty()); - assert!(Agenda::::get(BlockNumberOrTimestamp::BlockNumber(10))[0].is_some()); - assert_eq!(Retries::::iter().count(), 1); - assert_eq!(logger::log(), vec![(root(), 42u32), (root(), 42u32)]); - run_to_block(9); - assert!(Agenda::::get(BlockNumberOrTimestamp::BlockNumber(10))[0].is_some()); - assert_eq!(logger::log(), vec![(root(), 42u32), (root(), 42u32)]); - // 42 has 10 retries left out of a total of 10 - assert_eq!( - Retries::::get((BlockNumberOrTimestamp::BlockNumber(10), 0)) - .unwrap() - .remaining, - 10 - ); - // 42 will fail because we're outside the set threshold (block number in `4..8`), so it - // should be retried in 2 blocks (at block 12) - run_to_block(10); - // should be queued for the normal period of 3 blocks - assert!(Agenda::::get(BlockNumberOrTimestamp::BlockNumber(13))[0].is_some()); - // should also be queued to be retried in 2 blocks - assert!(Agenda::::get(BlockNumberOrTimestamp::BlockNumber(12))[0].is_some()); - // 42 has consumed one retry attempt - assert_eq!( - Retries::::get((BlockNumberOrTimestamp::BlockNumber(12), 0)) - .unwrap() - .remaining, - 9 - ); - assert_eq!( - Retries::::get((BlockNumberOrTimestamp::BlockNumber(13), 0)) - .unwrap() - .remaining, - 10 - ); - assert_eq!(Retries::::iter().count(), 2); - assert_eq!( - Lookup::::get([42u8; 32]).unwrap(), - (BlockNumberOrTimestamp::BlockNumber(13), 0) - ); - assert_eq!(logger::log(), vec![(root(), 42u32), (root(), 42u32)]); - // 42 will fail again - run_to_block(12); - // should still be queued for the normal period - assert!(Agenda::::get(BlockNumberOrTimestamp::BlockNumber(13))[0].is_some()); - // should be queued to be retried in 2 blocks - assert!(Agenda::::get(BlockNumberOrTimestamp::BlockNumber(14))[0].is_some()); - // 42 has consumed another retry attempt - assert_eq!( - Retries::::get((BlockNumberOrTimestamp::BlockNumber(14), 0)) - .unwrap() - .remaining, - 8 - ); - assert_eq!( - Retries::::get((BlockNumberOrTimestamp::BlockNumber(13), 0)) - .unwrap() - .remaining, - 10 - ); - assert_eq!(Retries::::iter().count(), 2); - assert_eq!(logger::log(), vec![(root(), 42u32), (root(), 42u32)]); - // 42 will fail for the regular periodic run - run_to_block(13); - // should still be queued for the normal period - assert!(Agenda::::get(BlockNumberOrTimestamp::BlockNumber(16))[0].is_some()); - // should still be queued to be retried next block - assert!(Agenda::::get(BlockNumberOrTimestamp::BlockNumber(14))[0].is_some()); - // 42 consumed another periodic run, which failed, so another retry is queued for block 15 - assert!(Agenda::::get(BlockNumberOrTimestamp::BlockNumber(16))[0] - .as_ref() - .unwrap() - .maybe_periodic - .is_some()); - assert!(Agenda::::get(BlockNumberOrTimestamp::BlockNumber(15))[0] - .as_ref() - .unwrap() - .maybe_periodic - .is_none()); - assert!(Agenda::::get(BlockNumberOrTimestamp::BlockNumber(14))[0] - .as_ref() - .unwrap() - .maybe_periodic - .is_none()); - assert_eq!(Retries::::iter().count(), 3); - assert!( - Retries::::get((BlockNumberOrTimestamp::BlockNumber(14), 0)) - .unwrap() - .remaining == 8 - ); - assert!( - Retries::::get((BlockNumberOrTimestamp::BlockNumber(15), 0)) - .unwrap() - .remaining == 9 - ); - assert!( - Retries::::get((BlockNumberOrTimestamp::BlockNumber(16), 0)) - .unwrap() - .remaining == 10 - ); - assert_eq!( - Lookup::::get([42u8; 32]).unwrap(), - (BlockNumberOrTimestamp::BlockNumber(16), 0) - ); - assert_eq!(logger::log(), vec![(root(), 42u32), (root(), 42u32)]); - // change the threshold to allow the task to succeed - Threshold::::put((14, 100)); - // first retry should now succeed - run_to_block(14); - assert!(Agenda::::get(BlockNumberOrTimestamp::BlockNumber(15))[0] - .as_ref() - .unwrap() - .maybe_periodic - .is_none()); - assert_eq!( - Agenda::::get(BlockNumberOrTimestamp::BlockNumber(16)) - .iter() - .filter(|entry| entry.is_some()) - .count(), - 1 - ); - assert!(Agenda::::get(BlockNumberOrTimestamp::BlockNumber(16))[0].is_some()); - assert_eq!( - Retries::::get((BlockNumberOrTimestamp::BlockNumber(15), 0)) - .unwrap() - .remaining, - 9 - ); - assert_eq!( - Retries::::get((BlockNumberOrTimestamp::BlockNumber(16), 0)) - .unwrap() - .remaining, - 10 - ); - assert_eq!(Retries::::iter().count(), 2); - assert_eq!(logger::log(), vec![(root(), 42u32), (root(), 42u32), (root(), 42u32)]); - // second retry should also succeed - run_to_block(15); - assert_eq!( - Agenda::::get(BlockNumberOrTimestamp::BlockNumber(16)) - .iter() - .filter(|entry| entry.is_some()) - .count(), - 1 - ); - assert!(Agenda::::get(BlockNumberOrTimestamp::BlockNumber(16))[0].is_some()); - assert!(Agenda::::get(BlockNumberOrTimestamp::BlockNumber(17)).is_empty()); - assert_eq!( - Retries::::get((BlockNumberOrTimestamp::BlockNumber(16), 0)) - .unwrap() - .remaining, - 10 - ); - assert_eq!(Retries::::iter().count(), 1); - assert_eq!( - Lookup::::get([42u8; 32]).unwrap(), - (BlockNumberOrTimestamp::BlockNumber(16), 0) - ); - assert_eq!( - logger::log(), - vec![(root(), 42u32), (root(), 42u32), (root(), 42u32), (root(), 42u32)] - ); - // normal periodic run on block 16 will succeed - run_to_block(16); - // next periodic run at block 19 - assert!(Agenda::::get(BlockNumberOrTimestamp::BlockNumber(19))[0].is_some()); - assert!(Agenda::::get(BlockNumberOrTimestamp::BlockNumber(18)).is_empty()); - assert!(Agenda::::get(BlockNumberOrTimestamp::BlockNumber(17)).is_empty()); - assert_eq!( - Retries::::get((BlockNumberOrTimestamp::BlockNumber(19), 0)) - .unwrap() - .remaining, - 10 - ); - assert_eq!(Retries::::iter().count(), 1); - assert_eq!( - logger::log(), - vec![ - (root(), 42u32), - (root(), 42u32), - (root(), 42u32), - (root(), 42u32), - (root(), 42u32) - ] - ); - // final periodic run on block 19 will succeed - run_to_block(19); - // next periodic run at block 19 - assert_eq!(Agenda::::iter().count(), 0); - assert_eq!(Retries::::iter().count(), 0); - assert_eq!(Lookup::::iter().count(), 0); - assert_eq!( - logger::log(), - vec![ - (root(), 42u32), - (root(), 42u32), - (root(), 42u32), - (root(), 42u32), - (root(), 42u32), - (root(), 42u32) - ] - ); - }); -} - #[test] fn retry_scheduling_expires() { new_test_ext().execute_with(|| { @@ -989,7 +468,6 @@ fn retry_scheduling_expires() { // task 42 at #4 assert_ok!(Scheduler::do_schedule( DispatchTime::At(4), - None, 127, root(), Preimage::bound(RuntimeCall::Logger(logger::Call::timed_log { @@ -1065,7 +543,6 @@ fn set_retry_bad_origin() { // task 42 at #4 with account 101 as origin assert_ok!(Scheduler::do_schedule( DispatchTime::At(4), - None, 127, RawOrigin::Signed(101).into(), Preimage::bound(RuntimeCall::Logger(logger::Call::timed_log { @@ -1094,7 +571,6 @@ fn set_named_retry_bad_origin() { assert_ok!(Scheduler::do_schedule_named( [42u8; 32], DispatchTime::At(4), - None, 127, RawOrigin::Signed(101).into(), Preimage::bound(RuntimeCall::Logger(logger::Call::timed_log { @@ -1122,7 +598,6 @@ fn set_retry_works() { // task 42 at #4 assert_ok!(Scheduler::do_schedule( DispatchTime::At(4), - None, 127, root(), Preimage::bound(RuntimeCall::Logger(logger::Call::timed_log { @@ -1158,7 +633,6 @@ fn set_named_retry_works() { assert_ok!(Scheduler::do_schedule_named( [42u8; 32], DispatchTime::At(4), - None, 127, root(), Preimage::bound(RuntimeCall::Logger(logger::Call::timed_log { @@ -1174,175 +648,17 @@ fn set_named_retry_works() { root().into(), [42u8; 32], 10, - BlockNumberOrTimestamp::BlockNumber(2) - )); - let address = Lookup::::get([42u8; 32]).unwrap(); - assert_eq!( - Retries::::get(address), - Some(RetryConfig { - total_retries: 10, - remaining: 10, - period: BlockNumberOrTimestamp::BlockNumber(2) - }) - ); - }); -} - -#[test] -fn retry_periodic_full_cycle() { - new_test_ext().execute_with(|| { - // tasks fail after we pass block 1000 - Threshold::::put((1, 1000)); - // task 42 at #4, every 100 blocks, 4 times - assert_ok!(Scheduler::do_schedule_named( - [42u8; 32], - DispatchTime::At(10), - Some((BlockNumberOrTimestamp::BlockNumber(100), 4)), - 127, - root(), - Preimage::bound(RuntimeCall::Logger(logger::Call::timed_log { - i: 42, - weight: Weight::from_parts(10, 0) - })) - .unwrap() - )); - - assert!(Agenda::::get(BlockNumberOrTimestamp::BlockNumber(10))[0].is_some()); - // 42 will be retried 2 times every block - assert_ok!(Scheduler::set_retry_named( - root().into(), - [42u8; 32], - 2, - BlockNumberOrTimestamp::BlockNumber(1) - )); - assert_eq!(Retries::::iter().count(), 1); - run_to_block(9); - assert!(logger::log().is_empty()); - assert!(Agenda::::get(BlockNumberOrTimestamp::BlockNumber(10))[0].is_some()); - // 42 runs successfully once, it will run again at block 110 - run_to_block(10); - assert!(Agenda::::get(BlockNumberOrTimestamp::BlockNumber(10)).is_empty()); - assert!(Agenda::::get(BlockNumberOrTimestamp::BlockNumber(110))[0].is_some()); - assert_eq!(Retries::::iter().count(), 1); - assert_eq!(logger::log(), vec![(root(), 42u32)]); - // nothing changed - run_to_block(109); - assert!(Agenda::::get(BlockNumberOrTimestamp::BlockNumber(110))[0].is_some()); - // original task still has 2 remaining retries - assert_eq!( - Retries::::get((BlockNumberOrTimestamp::BlockNumber(110), 0)) - .unwrap() - .remaining, - 2 - ); - assert_eq!(logger::log(), vec![(root(), 42u32)]); - // make 42 fail next block - Threshold::::put((1, 2)); - // 42 will fail because we're outside the set threshold (block number in `1..2`), so it - // should be retried next block (at block 111) - run_to_block(110); - // should be queued for the normal period of 100 blocks - assert!(Agenda::::get(BlockNumberOrTimestamp::BlockNumber(210))[0].is_some()); - // should also be queued to be retried next block - assert!(Agenda::::get(BlockNumberOrTimestamp::BlockNumber(111))[0].is_some()); - // 42 retry clone has consumed one retry attempt - assert_eq!( - Retries::::get((BlockNumberOrTimestamp::BlockNumber(111), 0)) - .unwrap() - .remaining, - 1 - ); - // 42 original task still has the original remaining attempts - assert_eq!( - Retries::::get((BlockNumberOrTimestamp::BlockNumber(210), 0)) - .unwrap() - .remaining, - 2 - ); - assert_eq!(Retries::::iter().count(), 2); - assert_eq!(logger::log(), vec![(root(), 42u32)]); - // 42 retry will fail again - run_to_block(111); - // should still be queued for the normal period - assert!(Agenda::::get(BlockNumberOrTimestamp::BlockNumber(210))[0].is_some()); - // should be queued to be retried next block - assert!(Agenda::::get(BlockNumberOrTimestamp::BlockNumber(112))[0].is_some()); - // 42 has consumed another retry attempt - assert_eq!( - Retries::::get((BlockNumberOrTimestamp::BlockNumber(210), 0)) - .unwrap() - .remaining, - 2 - ); - assert_eq!( - Retries::::get((BlockNumberOrTimestamp::BlockNumber(112), 0)) - .unwrap() - .remaining, - 0 - ); - assert_eq!(Retries::::iter().count(), 2); - assert_eq!(logger::log(), vec![(root(), 42u32)]); - // 42 retry will fail again - run_to_block(112); - // should still be queued for the normal period - assert!(Agenda::::get(BlockNumberOrTimestamp::BlockNumber(210))[0].is_some()); - // 42 retry clone ran out of retries, must have been evicted - assert_eq!(Agenda::::iter().count(), 1); - - // advance - run_to_block(209); - // should still be queued for the normal period - assert!(Agenda::::get(BlockNumberOrTimestamp::BlockNumber(210))[0].is_some()); - // 42 retry clone ran out of retries, must have been evicted - assert_eq!(Agenda::::iter().count(), 1); - // 42 should fail again and should spawn another retry clone - run_to_block(210); - // should be queued for the normal period of 100 blocks - assert!(Agenda::::get(BlockNumberOrTimestamp::BlockNumber(310))[0].is_some()); - // should also be queued to be retried next block - assert!(Agenda::::get(BlockNumberOrTimestamp::BlockNumber(211))[0].is_some()); - // 42 retry clone has consumed one retry attempt - assert_eq!( - Retries::::get((BlockNumberOrTimestamp::BlockNumber(211), 0)) - .unwrap() - .remaining, - 1 - ); - // 42 original task still has the original remaining attempts - assert_eq!( - Retries::::get((BlockNumberOrTimestamp::BlockNumber(310), 0)) - .unwrap() - .remaining, - 2 - ); - assert_eq!(Retries::::iter().count(), 2); - assert_eq!(logger::log(), vec![(root(), 42u32)]); - // make 42 run successfully again - Threshold::::put((1, 1000)); - // 42 retry clone should now succeed - run_to_block(211); - // should be queued for the normal period of 100 blocks - assert!(Agenda::::get(BlockNumberOrTimestamp::BlockNumber(310))[0].is_some()); - // retry was successful, retry task should have been discarded - assert_eq!(Agenda::::iter().count(), 1); - // 42 original task still has the original remaining attempts + BlockNumberOrTimestamp::BlockNumber(2) + )); + let address = Lookup::::get([42u8; 32]).unwrap(); assert_eq!( - Retries::::get((BlockNumberOrTimestamp::BlockNumber(310), 0)) - .unwrap() - .remaining, - 2 + Retries::::get(address), + Some(RetryConfig { + total_retries: 10, + remaining: 10, + period: BlockNumberOrTimestamp::BlockNumber(2) + }) ); - assert_eq!(Retries::::iter().count(), 1); - assert_eq!(logger::log(), vec![(root(), 42u32), (root(), 42u32)]); - - // fast forward to the last periodic run of 42 - run_to_block(310); - // 42 was successful, the period ended as this was the 4th scheduled periodic run so 42 must - // have been discarded - assert_eq!(Agenda::::iter().count(), 0); - // agenda is empty so no retries should exist - assert_eq!(Retries::::iter().count(), 0); - assert_eq!(logger::log(), vec![(root(), 42u32), (root(), 42u32), (root(), 42u32)]); }); } @@ -1355,7 +671,6 @@ fn reschedule_works() { assert_eq!( Scheduler::do_schedule( DispatchTime::At(4), - None, 127, root(), Preimage::bound(call).unwrap() @@ -1405,7 +720,6 @@ fn reschedule_named_works() { Scheduler::do_schedule_named( [1u8; 32], DispatchTime::At(4), - None, 127, root(), Preimage::bound(call).unwrap(), @@ -1438,62 +752,6 @@ fn reschedule_named_works() { }); } -#[test] -fn reschedule_named_periodic_works() { - new_test_ext().execute_with(|| { - let call = - RuntimeCall::Logger(LoggerCall::log { i: 42, weight: Weight::from_parts(10, 0) }); - assert!(!::BaseCallFilter::contains(&call)); - assert_eq!( - Scheduler::do_schedule_named( - [1u8; 32], - DispatchTime::At(4), - Some((BlockNumberOrTimestamp::BlockNumber(3), 3)), - 127, - root(), - Preimage::bound(call).unwrap(), - ) - .unwrap(), - (BlockNumberOrTimestamp::BlockNumber(4), 0) - ); - - run_to_block(3); - assert!(logger::log().is_empty()); - - assert_eq!( - Scheduler::do_reschedule_named([1u8; 32], DispatchTime::At(5)).unwrap(), - (BlockNumberOrTimestamp::BlockNumber(5), 0) - ); - assert_eq!( - Scheduler::do_reschedule_named([1u8; 32], DispatchTime::At(6)).unwrap(), - (BlockNumberOrTimestamp::BlockNumber(6), 0) - ); - - run_to_block(5); - assert!(logger::log().is_empty()); - - run_to_block(6); - assert_eq!(logger::log(), vec![(root(), 42u32)]); - - assert_eq!( - Scheduler::do_reschedule_named([1u8; 32], DispatchTime::At(10)).unwrap(), - (BlockNumberOrTimestamp::BlockNumber(10), 0) - ); - - run_to_block(9); - assert_eq!(logger::log(), vec![(root(), 42u32)]); - - run_to_block(10); - assert_eq!(logger::log(), vec![(root(), 42u32), (root(), 42u32)]); - - run_to_block(13); - assert_eq!(logger::log(), vec![(root(), 42u32), (root(), 42u32), (root(), 42u32)]); - - run_to_block(100); - assert_eq!(logger::log(), vec![(root(), 42u32), (root(), 42u32), (root(), 42u32)]); - }); -} - #[test] fn cancel_named_scheduling_works_with_normal_cancel() { new_test_ext().execute_with(|| { @@ -1501,7 +759,6 @@ fn cancel_named_scheduling_works_with_normal_cancel() { Scheduler::do_schedule_named( [1u8; 32], DispatchTime::At(4), - None, 127, root(), Preimage::bound(RuntimeCall::Logger(LoggerCall::log { @@ -1513,7 +770,6 @@ fn cancel_named_scheduling_works_with_normal_cancel() { .unwrap(); let i = Scheduler::do_schedule( DispatchTime::At(4), - None, 127, root(), Preimage::bound(RuntimeCall::Logger(LoggerCall::log { @@ -1532,62 +788,6 @@ fn cancel_named_scheduling_works_with_normal_cancel() { }); } -#[test] -fn cancel_named_periodic_scheduling_works() { - new_test_ext().execute_with(|| { - // at #4, every 3 blocks, 3 times. - Scheduler::do_schedule_named( - [1u8; 32], - DispatchTime::At(4), - Some((BlockNumberOrTimestamp::BlockNumber(3), 3)), - 127, - root(), - Preimage::bound(RuntimeCall::Logger(LoggerCall::log { - i: 42, - weight: Weight::from_parts(10, 0), - })) - .unwrap(), - ) - .unwrap(); - // same id results in error. - assert!(Scheduler::do_schedule_named( - [1u8; 32], - DispatchTime::At(4), - None, - 127, - root(), - Preimage::bound(RuntimeCall::Logger(LoggerCall::log { - i: 69, - weight: Weight::from_parts(10, 0) - })) - .unwrap(), - ) - .is_err()); - // different id is ok. - Scheduler::do_schedule_named( - [2u8; 32], - DispatchTime::At(8), - None, - 127, - root(), - Preimage::bound(RuntimeCall::Logger(LoggerCall::log { - i: 69, - weight: Weight::from_parts(10, 0), - })) - .unwrap(), - ) - .unwrap(); - run_to_block(3); - assert!(logger::log().is_empty()); - run_to_block(4); - assert_eq!(logger::log(), vec![(root(), 42u32)]); - run_to_block(6); - assert_ok!(Scheduler::do_cancel_named(None, [1u8; 32])); - run_to_block(100); - assert_eq!(logger::log(), vec![(root(), 42u32), (root(), 69u32)]); - }); -} - #[test] fn scheduler_respects_weight_limits() { let max_weight: Weight = ::MaximumWeight::get(); @@ -1595,7 +795,6 @@ fn scheduler_respects_weight_limits() { let call = RuntimeCall::Logger(LoggerCall::log { i: 42, weight: max_weight / 3 * 2 }); assert_ok!(Scheduler::do_schedule( DispatchTime::At(4), - None, 127, root(), Preimage::bound(call).unwrap(), @@ -1603,7 +802,6 @@ fn scheduler_respects_weight_limits() { let call = RuntimeCall::Logger(LoggerCall::log { i: 69, weight: max_weight / 3 * 2 }); assert_ok!(Scheduler::do_schedule( DispatchTime::At(4), - None, 127, root(), Preimage::bound(call).unwrap(), @@ -1624,7 +822,6 @@ fn retry_respects_weight_limits() { let call = RuntimeCall::Logger(LoggerCall::log { i: 42, weight: max_weight / 3 * 2 }); assert_ok!(Scheduler::do_schedule( DispatchTime::At(8), - None, 127, root(), Preimage::bound(call).unwrap(), @@ -1634,7 +831,6 @@ fn retry_respects_weight_limits() { let call = RuntimeCall::Logger(LoggerCall::timed_log { i: 20, weight: max_weight / 3 * 2 }); assert_ok!(Scheduler::do_schedule( DispatchTime::At(4), - None, 127, root(), Preimage::bound(call).unwrap(), @@ -1698,7 +894,6 @@ fn try_schedule_retry_respects_weight_limits() { let base_weight = ::WeightInfo::service_task( bounded.lookup_len().map(|x| x as usize), false, - false, ); // we make the call cost enough so that all checks have enough weight to run aside from // `try_schedule_retry` @@ -1709,7 +904,6 @@ fn try_schedule_retry_respects_weight_limits() { assert_ok!(Scheduler::do_schedule( DispatchTime::At(4), - None, 127, root(), Preimage::bound(call).unwrap(), @@ -1746,7 +940,6 @@ fn scheduler_removes_permanently_overweight_call() { let call = RuntimeCall::Logger(LoggerCall::log { i: 42, weight: max_weight }); assert_ok!(Scheduler::do_schedule( DispatchTime::At(4), - None, 127, root(), Preimage::bound(call).unwrap(), @@ -1764,98 +957,6 @@ fn scheduler_removes_permanently_overweight_call() { }); } -#[test] -fn scheduler_handles_periodic_failure() { - let max_weight: Weight = ::MaximumWeight::get(); - let max_per_block = ::MaxScheduledPerBlock::get(); - - new_test_ext().execute_with(|| { - let call = RuntimeCall::Logger(LoggerCall::log { i: 42, weight: (max_weight / 3) * 2 }); - let bound = Preimage::bound(call).unwrap(); - - assert_ok!(Scheduler::do_schedule( - DispatchTime::At(4), - Some((BlockNumberOrTimestamp::BlockNumber(4), u32::MAX)), - 127, - root(), - bound.clone(), - )); - // Executes 5 times till block 20. - run_to_block(20); - assert_eq!(logger::log().len(), 5); - - // Block 28 will already be full. - for _ in 0..max_per_block { - assert_ok!(Scheduler::do_schedule( - DispatchTime::At(28), - None, - 120, - root(), - bound.clone(), - )); - } - - // Going to block 24 will emit a `PeriodicFailed` event. - run_to_block(24); - assert_eq!(logger::log().len(), 6); - - assert_eq!( - System::events().last().unwrap().event, - crate::Event::PeriodicFailed { - task: (BlockNumberOrTimestamp::BlockNumber(24), 0), - id: None - } - .into(), - ); - }); -} - -#[test] -fn scheduler_handles_periodic_unavailable_preimage() { - let max_weight: Weight = ::MaximumWeight::get(); - - new_test_ext().execute_with(|| { - let call = RuntimeCall::Logger(LoggerCall::log { i: 42, weight: (max_weight / 3) * 2 }); - let hash = ::Hashing::hash_of(&call); - let len = call.using_encoded(|x| x.len()) as u32; - // Important to use here `Bounded::Lookup` to ensure that we request the hash. - let bound = Bounded::Lookup { hash, len }; - // The preimage isn't requested yet. - assert!(!Preimage::is_requested(&hash)); - - assert_ok!(Scheduler::do_schedule( - DispatchTime::At(4), - Some((BlockNumberOrTimestamp::BlockNumber(4), u32::MAX)), - 127, - root(), - bound.clone(), - )); - - // The preimage is requested. - assert!(Preimage::is_requested(&hash)); - - // Note the preimage. - assert_ok!(Preimage::note_preimage(RuntimeOrigin::signed(1), call.encode())); - - // Executes 1 times till block 4. - run_to_block(4); - assert_eq!(logger::log().len(), 1); - - // As the public api doesn't support to remove a noted preimage, we need to first unnote it - // and then request it again. Basically this should not happen in real life (whatever you - // call real life;). - Preimage::unnote(&hash); - Preimage::request(&hash); - - // Does not ever execute again. - run_to_block(100); - assert_eq!(logger::log().len(), 1); - - // The preimage is not requested anymore. - assert!(!Preimage::is_requested(&hash)); - }); -} - #[test] fn scheduler_respects_priority_ordering() { let max_weight: Weight = ::MaximumWeight::get(); @@ -1863,7 +964,6 @@ fn scheduler_respects_priority_ordering() { let call = RuntimeCall::Logger(LoggerCall::log { i: 42, weight: max_weight / 3 }); assert_ok!(Scheduler::do_schedule( DispatchTime::At(4), - None, 1, root(), Preimage::bound(call).unwrap(), @@ -1871,7 +971,6 @@ fn scheduler_respects_priority_ordering() { let call = RuntimeCall::Logger(LoggerCall::log { i: 69, weight: max_weight / 3 }); assert_ok!(Scheduler::do_schedule( DispatchTime::At(4), - None, 0, root(), Preimage::bound(call).unwrap(), @@ -1888,7 +987,6 @@ fn scheduler_respects_priority_ordering_with_soft_deadlines() { let call = RuntimeCall::Logger(LoggerCall::log { i: 42, weight: max_weight / 5 * 2 }); assert_ok!(Scheduler::do_schedule( DispatchTime::At(4), - None, 255, root(), Preimage::bound(call).unwrap(), @@ -1896,7 +994,6 @@ fn scheduler_respects_priority_ordering_with_soft_deadlines() { let call = RuntimeCall::Logger(LoggerCall::log { i: 69, weight: max_weight / 5 * 2 }); assert_ok!(Scheduler::do_schedule( DispatchTime::At(4), - None, 127, root(), Preimage::bound(call).unwrap(), @@ -1904,7 +1001,6 @@ fn scheduler_respects_priority_ordering_with_soft_deadlines() { let call = RuntimeCall::Logger(LoggerCall::log { i: 2600, weight: max_weight / 5 * 4 }); assert_ok!(Scheduler::do_schedule( DispatchTime::At(4), - None, 126, root(), Preimage::bound(call).unwrap(), @@ -1934,7 +1030,6 @@ fn on_initialize_weight_is_correct() { assert_ok!(Scheduler::do_schedule_named( [1u8; 32], DispatchTime::At(3), - None, 255, root(), Preimage::bound(call).unwrap(), @@ -1943,10 +1038,9 @@ fn on_initialize_weight_is_correct() { i: 42, weight: call_weight + Weight::from_parts(2, 0), }); - // Anon Periodic + // Anon assert_ok!(Scheduler::do_schedule( DispatchTime::At(2), - Some((BlockNumberOrTimestamp::BlockNumber(1000), 3)), 128, root(), Preimage::bound(call).unwrap(), @@ -1958,12 +1052,11 @@ fn on_initialize_weight_is_correct() { // Anon assert_ok!(Scheduler::do_schedule( DispatchTime::At(2), - None, 127, root(), Preimage::bound(call).unwrap(), )); - // Named Periodic + // Named let call = RuntimeCall::Logger(LoggerCall::log { i: 2600, weight: call_weight + Weight::from_parts(4, 0), @@ -1971,18 +1064,17 @@ fn on_initialize_weight_is_correct() { assert_ok!(Scheduler::do_schedule_named( [2u8; 32], DispatchTime::At(1), - Some((BlockNumberOrTimestamp::BlockNumber(1000), 3)), 126, root(), Preimage::bound(call).unwrap(), )); - // Will include the named periodic only + // Will include the named only assert_eq!( Scheduler::on_initialize(1), TestWeightInfo::service_agendas_base() + TestWeightInfo::service_agenda_base(1) + - ::service_task(None, true, true) + + ::service_task(None, true) + TestWeightInfo::execute_dispatch_unsigned() + call_weight + Weight::from_parts(4, 0) + Weight::from_parts(2, 0) // add for time based @@ -1990,15 +1082,15 @@ fn on_initialize_weight_is_correct() { assert_eq!(IncompleteBlockSince::::get(), None); assert_eq!(logger::log(), vec![(root(), 2600u32)]); - // Will include anon and anon periodic + // Will include both anon tasks assert_eq!( Scheduler::on_initialize(2), TestWeightInfo::service_agendas_base() + TestWeightInfo::service_agenda_base(2) + - ::service_task(None, false, true) + + ::service_task(None, false) + TestWeightInfo::execute_dispatch_unsigned() + call_weight + Weight::from_parts(3, 0) + - ::service_task(None, false, false) + + ::service_task(None, false) + TestWeightInfo::execute_dispatch_unsigned() + call_weight + Weight::from_parts(2, 0) + Weight::from_parts(2, 0) // add for time based @@ -2011,7 +1103,7 @@ fn on_initialize_weight_is_correct() { Scheduler::on_initialize(3), TestWeightInfo::service_agendas_base() + TestWeightInfo::service_agenda_base(1) + - ::service_task(None, true, false) + + ::service_task(None, true) + TestWeightInfo::execute_dispatch_unsigned() + call_weight + Weight::from_parts(1, 0) + Weight::from_parts(2, 0) // add for time based @@ -2044,10 +1136,8 @@ fn root_calls_works() { i: 42, weight: Weight::from_parts(10, 0), })); - assert_ok!( - Scheduler::schedule_named(RuntimeOrigin::root(), [1u8; 32], 4, None, 127, call,) - ); - assert_ok!(Scheduler::schedule(RuntimeOrigin::root(), 4, None, 127, call2)); + assert_ok!(Scheduler::schedule_named(RuntimeOrigin::root(), [1u8; 32], 4, 127, call,)); + assert_ok!(Scheduler::schedule(RuntimeOrigin::root(), 4, 127, call2)); run_to_block(3); // Scheduled calls are in the agenda. assert_eq!(Agenda::::get(BlockNumberOrTimestamp::BlockNumber(4)).len(), 2); @@ -2083,17 +1173,17 @@ fn fails_to_schedule_task_in_the_past() { })); assert_noop!( - Scheduler::schedule_named(RuntimeOrigin::root(), [1u8; 32], 2, None, 127, call1), + Scheduler::schedule_named(RuntimeOrigin::root(), [1u8; 32], 2, 127, call1), Error::::TargetBlockNumberInPast, ); assert_noop!( - Scheduler::schedule(RuntimeOrigin::root(), 2, None, 127, call2), + Scheduler::schedule(RuntimeOrigin::root(), 2, 127, call2), Error::::TargetBlockNumberInPast, ); assert_noop!( - Scheduler::schedule(RuntimeOrigin::root(), 3, None, 127, call3), + Scheduler::schedule(RuntimeOrigin::root(), 3, 127, call3), Error::::TargetBlockNumberInPast, ); }); @@ -2114,11 +1204,10 @@ fn should_use_origin() { system::RawOrigin::Signed(1).into(), [1u8; 32], 4, - None, 127, call, )); - assert_ok!(Scheduler::schedule(system::RawOrigin::Signed(1).into(), 4, None, 127, call2,)); + assert_ok!(Scheduler::schedule(system::RawOrigin::Signed(1).into(), 4, 127, call2,)); run_to_block(3); // Scheduled calls are in the agenda. assert_eq!(Agenda::::get(BlockNumberOrTimestamp::BlockNumber(4)).len(), 2); @@ -2147,18 +1236,11 @@ fn should_check_origin() { weight: Weight::from_parts(10, 0), })); assert_noop!( - Scheduler::schedule_named( - system::RawOrigin::Signed(2).into(), - [1u8; 32], - 4, - None, - 127, - call - ), + Scheduler::schedule_named(system::RawOrigin::Signed(2).into(), [1u8; 32], 4, 127, call), BadOrigin ); assert_noop!( - Scheduler::schedule(system::RawOrigin::Signed(2).into(), 4, None, 127, call2), + Scheduler::schedule(system::RawOrigin::Signed(2).into(), 4, 127, call2), BadOrigin ); }); @@ -2179,11 +1261,10 @@ fn should_check_origin_for_cancel() { system::RawOrigin::Signed(1).into(), [1u8; 32], 4, - None, 127, call, )); - assert_ok!(Scheduler::schedule(system::RawOrigin::Signed(1).into(), 4, None, 127, call2,)); + assert_ok!(Scheduler::schedule(system::RawOrigin::Signed(1).into(), 4, 127, call2,)); run_to_block(3); // Scheduled calls are in the agenda. assert_eq!(Agenda::::get(BlockNumberOrTimestamp::BlockNumber(4)).len(), 2); @@ -2228,7 +1309,6 @@ fn cancel_removes_retry_entry() { // task 20 at #4 assert_ok!(Scheduler::do_schedule( DispatchTime::At(4), - None, 127, root(), Preimage::bound(RuntimeCall::Logger(logger::Call::timed_log { @@ -2241,7 +1321,6 @@ fn cancel_removes_retry_entry() { assert_ok!(Scheduler::do_schedule_named( [1u8; 32], DispatchTime::At(4), - None, 127, root(), Preimage::bound(RuntimeCall::Logger(logger::Call::timed_log { @@ -2313,7 +1392,6 @@ fn cancel_retries_works() { // task 20 at #4 assert_ok!(Scheduler::do_schedule( DispatchTime::At(4), - None, 127, root(), Preimage::bound(RuntimeCall::Logger(logger::Call::timed_log { @@ -2326,7 +1404,6 @@ fn cancel_retries_works() { assert_ok!(Scheduler::do_schedule_named( [1u8; 32], DispatchTime::At(4), - None, 127, root(), Preimage::bound(RuntimeCall::Logger(logger::Call::timed_log { @@ -2382,15 +1459,9 @@ fn postponed_named_task_cannot_be_rescheduled() { let hashed = Bounded::Lookup { hash, len }; let name: [u8; 32] = hash.as_ref().try_into().unwrap(); - let address = Scheduler::do_schedule_named( - name, - DispatchTime::At(4), - None, - 127, - root(), - hashed.clone(), - ) - .unwrap(); + let address = + Scheduler::do_schedule_named(name, DispatchTime::At(4), 127, root(), hashed.clone()) + .unwrap(); assert!(Preimage::is_requested(&hash)); assert!(Lookup::::contains_key(name)); @@ -2424,7 +1495,6 @@ fn postponed_named_task_cannot_be_rescheduled() { maybe_id: Some(name), priority: 127, call: hashed, - maybe_periodic: None, origin: root().into(), _phantom: Default::default(), })] @@ -2986,7 +2056,6 @@ fn cancel_last_task_removes_agenda() { RuntimeCall::Logger(LoggerCall::log { i: 42, weight: Weight::from_parts(10, 0) }); let address = Scheduler::do_schedule( DispatchTime::At(when), - None, 127, root(), Preimage::bound(call.clone()).unwrap(), @@ -2994,7 +2063,6 @@ fn cancel_last_task_removes_agenda() { .unwrap(); let address2 = Scheduler::do_schedule( DispatchTime::At(when), - None, 127, root(), Preimage::bound(call).unwrap(), @@ -3021,7 +2089,6 @@ fn cancel_named_last_task_removes_agenda() { Scheduler::do_schedule_named( [1u8; 32], DispatchTime::At(when), - None, 127, root(), Preimage::bound(call.clone()).unwrap(), @@ -3030,7 +2097,6 @@ fn cancel_named_last_task_removes_agenda() { Scheduler::do_schedule_named( [2u8; 32], DispatchTime::At(when), - None, 127, root(), Preimage::bound(call).unwrap(), @@ -3056,7 +2122,6 @@ fn reschedule_last_task_removes_agenda() { RuntimeCall::Logger(LoggerCall::log { i: 42, weight: Weight::from_parts(10, 0) }); let address = Scheduler::do_schedule( DispatchTime::At(when), - None, 127, root(), Preimage::bound(call.clone()).unwrap(), @@ -3064,7 +2129,6 @@ fn reschedule_last_task_removes_agenda() { .unwrap(); let address2 = Scheduler::do_schedule( DispatchTime::At(when), - None, 127, root(), Preimage::bound(call).unwrap(), @@ -3094,7 +2158,6 @@ fn reschedule_named_last_task_removes_agenda() { Scheduler::do_schedule_named( [1u8; 32], DispatchTime::At(when), - None, 127, root(), Preimage::bound(call.clone()).unwrap(), @@ -3103,7 +2166,6 @@ fn reschedule_named_last_task_removes_agenda() { Scheduler::do_schedule_named( [2u8; 32], DispatchTime::At(when), - None, 127, root(), Preimage::bound(call).unwrap(), @@ -3180,7 +2242,6 @@ fn time_based_agenda_is_processed_correctly() { assert_ok!(Scheduler::schedule_after( RuntimeOrigin::root(), BlockNumberOrTimestamp::Timestamp(schedule_time_ms), - None, 0, Box::new(RuntimeCall::Logger(LoggerCall::log { i: 1, @@ -3217,7 +2278,6 @@ fn time_based_agenda_prevents_bucket_skipping_after_time_skip() { assert_ok!(Scheduler::schedule_after( RuntimeOrigin::root(), BlockNumberOrTimestamp::Timestamp(schedule_time_ms), - None, 0, Box::new(RuntimeCall::Logger(LoggerCall::log { i: 1, @@ -3228,7 +2288,6 @@ fn time_based_agenda_prevents_bucket_skipping_after_time_skip() { assert_ok!(Scheduler::schedule_after( RuntimeOrigin::root(), BlockNumberOrTimestamp::Timestamp(schedule_time_ms_2), - None, 0, Box::new(RuntimeCall::Logger(LoggerCall::log { i: 2, @@ -3285,8 +2344,7 @@ fn timestamp_scheduler_respects_weight_limits() { let call = RuntimeCall::Logger(LoggerCall::log { i: 42, weight: max_weight / 3 * 2 }); assert_ok!(Scheduler::schedule_after( RuntimeOrigin::root(), - BlockNumberOrTimestamp::Timestamp(15000), // Will be scheduled in bucket 20000 - None, + BlockNumberOrTimestamp::Timestamp(15000), 127, Box::new(call), )); @@ -3294,8 +2352,7 @@ fn timestamp_scheduler_respects_weight_limits() { let call = RuntimeCall::Logger(LoggerCall::log { i: 69, weight: max_weight / 3 * 2 }); assert_ok!(Scheduler::schedule_after( RuntimeOrigin::root(), - BlockNumberOrTimestamp::Timestamp(15000), // Will be scheduled in bucket 20000 - None, + BlockNumberOrTimestamp::Timestamp(15000), 127, Box::new(call), )); @@ -3330,7 +2387,6 @@ fn timestamp_scheduler_removes_permanently_overweight_call() { assert_ok!(Scheduler::schedule_after( RuntimeOrigin::root(), BlockNumberOrTimestamp::Timestamp(15000), - None, 127, Box::new(call), )); @@ -3368,39 +2424,33 @@ fn timestamp_on_initialize_weight_is_correct() { assert_ok!(Scheduler::schedule_named_after( RuntimeOrigin::root(), [2u8; 32], - BlockNumberOrTimestamp::Timestamp(5000), // Bucket 10000 - Some((BlockNumberOrTimestamp::Timestamp(1000000), 3)), + BlockNumberOrTimestamp::Timestamp(5000), 126, Box::new(call_a), )); - // Task B: i=69, scheduled for bucket 20000 (timestamp 15000 -> bucket 20000) let call_b = RuntimeCall::Logger(LoggerCall::log { i: 69, weight: call_weight + Weight::from_parts(3, 0), }); assert_ok!(Scheduler::schedule_after( RuntimeOrigin::root(), - BlockNumberOrTimestamp::Timestamp(15000), // Bucket 20000 - None, + BlockNumberOrTimestamp::Timestamp(15000), 127, Box::new(call_b), )); - // Task C: i=42, scheduled for bucket 20000 (timestamp 15000 -> bucket 20000) let call_c = RuntimeCall::Logger(LoggerCall::log { i: 42, weight: call_weight + Weight::from_parts(2, 0), }); assert_ok!(Scheduler::schedule_after( RuntimeOrigin::root(), - BlockNumberOrTimestamp::Timestamp(15000), // Bucket 20000 - Some((BlockNumberOrTimestamp::Timestamp(1000000), 3)), + BlockNumberOrTimestamp::Timestamp(15000), 128, Box::new(call_c), )); - // Task D: i=3, scheduled for bucket 30000 (timestamp 25000 -> bucket 30000) let call_d = RuntimeCall::Logger(LoggerCall::log { i: 3, weight: call_weight + Weight::from_parts(1, 0), @@ -3408,8 +2458,7 @@ fn timestamp_on_initialize_weight_is_correct() { assert_ok!(Scheduler::schedule_named_after( RuntimeOrigin::root(), [1u8; 32], - BlockNumberOrTimestamp::Timestamp(25000), // Bucket 30000 - None, + BlockNumberOrTimestamp::Timestamp(25000), 255, Box::new(call_d), )); @@ -3510,7 +2559,6 @@ fn timestamp_incomplete_processing_across_multiple_buckets() { BlockNumberOrTimestamp::Timestamp(15000 + (i as u64) * 10000), /* Buckets 20000, * 30000, 40000, * 50000, 60000 */ - None, 127, Box::new(call), )); @@ -3765,14 +2813,12 @@ fn weight_exhaustion_preserves_remaining_tasks() { assert_ok!(Scheduler::do_schedule( DispatchTime::At(4), - None, 127, root(), Preimage::bound(call1).unwrap(), )); assert_ok!(Scheduler::do_schedule( DispatchTime::At(4), - None, 128, root(), Preimage::bound(call2).unwrap(), @@ -3813,7 +2859,6 @@ fn cancel_named_without_origin_cleans_up_retries() { assert_ok!(Scheduler::do_schedule_named( [1u8; 32], DispatchTime::At(4), - None, 127, root(), Preimage::bound(call).unwrap(), @@ -3847,35 +2892,6 @@ fn cancel_named_without_origin_cleans_up_retries() { }); } -/// A periodic task whose period type mismatches the execution domain (e.g. Timestamp period -/// on a BlockNumber task) emits PeriodicFailed and does not leave orphaned agenda entries. -#[test] -fn periodic_type_mismatch_emits_failure_event() { - new_test_ext().execute_with(|| { - let call = - RuntimeCall::Logger(LoggerCall::log { i: 42, weight: Weight::from_parts(10, 0) }); - assert_ok!(Scheduler::do_schedule( - DispatchTime::At(4), - Some((BlockNumberOrTimestamp::Timestamp(3000u64), 3)), - 127, - root(), - Preimage::bound(call).unwrap(), - )); - - run_to_block(4); - assert_eq!(logger::log(), vec![(root(), 42u32)]); - assert_eq!(Agenda::::iter().count(), 0, "Task should not be rescheduled"); - - let has_periodic_failed = System::events().iter().any(|e| { - matches!(e.event, RuntimeEvent::Scheduler(crate::Event::PeriodicFailed { .. })) - }); - assert!( - has_periodic_failed, - "PeriodicFailed event must be emitted on type-mismatch reschedule" - ); - }); -} - /// A retry whose period type mismatches the task domain (e.g. Timestamp retry period on a /// BlockNumber task) emits RetryFailed rather than silently dropping the retry. #[test] @@ -3887,7 +2903,6 @@ fn mismatched_retry_period_emits_failure_event() { RuntimeCall::Logger(LoggerCall::timed_log { i: 42, weight: Weight::from_parts(10, 0) }); assert_ok!(Scheduler::do_schedule( DispatchTime::At(4), - None, 127, root(), Preimage::bound(call).unwrap(), @@ -3935,7 +2950,6 @@ fn permanently_overweight_task_is_removed() { let call = RuntimeCall::Logger(LoggerCall::log { i: 42, weight: max_weight }); assert_ok!(Scheduler::do_schedule( DispatchTime::At(4), - None, 127, root(), Preimage::bound(call).unwrap(), diff --git a/pallets/scheduler/src/traits.rs b/pallets/scheduler/src/traits.rs index f8852efd..c34c1fb4 100644 --- a/pallets/scheduler/src/traits.rs +++ b/pallets/scheduler/src/traits.rs @@ -15,25 +15,20 @@ pub trait ScheduleNamed { /// The type of the hash function used for hashing. type Hasher: Hash; - /// Schedule a task with a name, dispatch time, and optional periodicity. fn schedule_named( id: TaskName, when: DispatchTime, - maybe_periodic: Option>, priority: schedule::Priority, origin: Origin, call: Bounded, ) -> Result; - /// Schedule a task with a name, dispatch time, and optional periodicity. fn cancel_named(id: TaskName) -> Result<(), DispatchError>; - /// Reschedule a task with a name, dispatch time, and optional periodicity. fn reschedule_named( id: TaskName, when: DispatchTime, ) -> Result; - /// Get the approximate dispatch block number for a task with a name. fn next_dispatch_time(id: TaskName) -> Result; } diff --git a/pallets/scheduler/src/weights.rs b/pallets/scheduler/src/weights.rs index 5de08549..8dc52f91 100644 --- a/pallets/scheduler/src/weights.rs +++ b/pallets/scheduler/src/weights.rs @@ -56,7 +56,6 @@ pub trait WeightInfo { fn service_task_base() -> Weight; fn service_task_fetched(s: u32, ) -> Weight; fn service_task_named() -> Weight; - fn service_task_periodic() -> Weight; fn execute_dispatch_signed() -> Weight; fn execute_dispatch_unsigned() -> Weight; fn schedule(s: u32, ) -> Weight; @@ -134,13 +133,6 @@ impl WeightInfo for SubstrateWeight { Weight::from_parts(4_000_000, 0) .saturating_add(T::DbWeight::get().writes(1_u64)) } - fn service_task_periodic() -> Weight { - // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 2_000_000 picoseconds. - Weight::from_parts(3_000_000, 0) - } fn execute_dispatch_signed() -> Weight { // Proof Size summary in bytes: // Measured: `0` @@ -362,13 +354,6 @@ impl WeightInfo for () { Weight::from_parts(4_000_000, 0) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - fn service_task_periodic() -> Weight { - // Proof Size summary in bytes: - // Measured: `0` - // Estimated: `0` - // Minimum execution time: 2_000_000 picoseconds. - Weight::from_parts(3_000_000, 0) - } fn execute_dispatch_signed() -> Weight { // Proof Size summary in bytes: // Measured: `0` diff --git a/primitives/scheduler/src/lib.rs b/primitives/scheduler/src/lib.rs index d5b02754..9a35049e 100644 --- a/primitives/scheduler/src/lib.rs +++ b/primitives/scheduler/src/lib.rs @@ -16,11 +16,6 @@ use sp_runtime::{ DispatchError, RuntimeDebug, }; -/// Information relating to the period of a scheduled task. First item is the length of the -/// period and the second is the number of times it should be executed in total before the task -/// is considered finished and removed. -pub type Period = (BlockNumberOrTimestamp, u32); - /// Error type for incompatible types in saturating_add #[derive(Debug, PartialEq, Eq)] pub struct IncompatibleTypesError; @@ -142,20 +137,16 @@ pub trait ScheduleNamed { /// The type of the hash function used for hashing. type Hasher: Hash; - /// Schedule a task with a name, dispatch time, and optional periodicity. fn schedule_named( id: TaskName, when: DispatchTime, - maybe_periodic: Option>, priority: schedule::Priority, origin: Origin, call: Bounded, ) -> Result; - /// Schedule a task with a name, dispatch time, and optional periodicity. fn cancel_named(id: TaskName) -> Result<(), DispatchError>; - /// Reschedule a task with a name, dispatch time, and optional periodicity. fn reschedule_named( id: TaskName, when: DispatchTime, diff --git a/runtime/tests/governance/engine.rs b/runtime/tests/governance/engine.rs index f14cd296..fe732f73 100644 --- a/runtime/tests/governance/engine.rs +++ b/runtime/tests/governance/engine.rs @@ -216,7 +216,6 @@ mod tests { assert_ok!(Scheduler::schedule( RuntimeOrigin::root(), when, - None, 127, Box::new(transfer_call), ));