Skip to content
This repository has been archived by the owner on Feb 21, 2024. It is now read-only.

Commit

Permalink
check schedule on report (simplify)
Browse files Browse the repository at this point in the history
range() instead of normalization with overcomplex second struct
  • Loading branch information
gitsimon committed Jan 16, 2023
1 parent bde80c6 commit a5f1d42
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 53 deletions.
3 changes: 1 addition & 2 deletions pallets/acurast/common/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -280,9 +280,8 @@ tests! {

fn test_schedule_overlaps(schedule: Schedule, start_delay: u64, ranges: Vec<((u64, u64), bool)>) {
for (range, exp) in ranges.iter() {
let normalized_schedule = &schedule.normalize(start_delay).unwrap();
assert_eq!(
&normalized_schedule.overlaps(range.0, range.1).unwrap(),
&schedule.overlaps(start_delay, range.0, range.1).unwrap(),
exp,
"{:?}.overlaps(start_delay: {}, range, ({}, {})) != {}",
schedule,
Expand Down
71 changes: 28 additions & 43 deletions pallets/acurast/common/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,41 +112,6 @@ pub struct Schedule {
pub max_start_delay: u64,
}

#[derive(RuntimeDebug, Encode, Decode, TypeInfo, Clone, Eq, PartialEq)]
#[non_exhaustive]
pub struct NormalizedSchedule(pub Schedule);

impl NormalizedSchedule {
pub fn overlaps(&self, a: u64, b: u64) -> Option<bool> {
if a == b
|| self.0.start_time == self.0.end_time
|| b <= self.0.start_time
|| a >= self.0.end_time
{
return Some(false);
}

// if range starts before we can pretend it only starts at self.0 `start_time`
let relative_a = a
.checked_sub(self.0.start_time)
.or(Some(self.0.start_time))?;

if let Some(relative_b) = b.checked_sub(self.0.start_time) {
let _b = relative_b % self.0.interval;
let (a, b) = (
relative_a % self.0.interval,
if _b == 0 { self.0.interval } else { _b },
);
// b > a from here

let l = b.checked_sub(a)?;
Some(a < self.0.duration || l >= self.0.interval)
} else {
Some(false)
}
}
}

impl Schedule {
/// The number of executions in the [`Schedule`] which corresponds to the length of [`Schedule::iter()`].
pub fn execution_count(&self) -> u64 {
Expand Down Expand Up @@ -174,11 +139,11 @@ impl Schedule {
})
}

/// Normalizes a schedule to zero `start_delay` and `end_time` being exact end of last exeuction.
/// Range of a schedule from first execution's start to end of last execution, respecting `start_delay`.
///
/// Example:
/// ___□□■■_□□■■_□□■■__ -> _____■■___■■___■■
pub fn normalize(&self, start_delay: u64) -> Option<NormalizedSchedule> {
/// ___□□■■_□□■■_□□■■__.range(2) -> (3, 17)
pub fn range(&self, start_delay: u64) -> Option<(u64, u64)> {
let actual_start = self.start_time.checked_add(start_delay)?;
let count = self.execution_count();
let actual_end = if count > 0 {
Expand All @@ -188,11 +153,31 @@ impl Schedule {
} else {
actual_start
};
Some(NormalizedSchedule(Schedule {
start_time: actual_start,
end_time: actual_end,
..self.clone()
}))
Some((actual_start, actual_end))
}

pub fn overlaps(&self, start_delay: u64, a: u64, b: u64) -> Option<bool> {
let (start, end) = self.range(start_delay)?;
if a == b || start == end || b <= start || a >= end {
return Some(false);
}

// if query interval `[a, b]` starts before, we can pretend it only starts at `start`
let relative_a = a.checked_sub(start).or(Some(start))?;

if let Some(relative_b) = b.checked_sub(start) {
let _b = relative_b % self.interval;
let (a, b) = (
relative_a % self.interval,
if _b == 0 { self.interval } else { _b },
);
// b > a from here

let l = b.checked_sub(a)?;
Some(a < self.duration || l >= self.interval)
} else {
Some(false)
}
}
}

Expand Down
9 changes: 3 additions & 6 deletions pallets/marketplace/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -411,18 +411,15 @@ pub mod pallet {
let registration = <StoredJobRegistration<T>>::get(&job_id.0, &job_id.1)
.ok_or(pallet_acurast::Error::<T>::JobRegistrationNotFound)?;

let normalized_schedule = registration
.schedule
.normalize(assignment.start_delay)
.ok_or(Error::<T>::CalculationOverflow)?;
let now = Self::now()?;
let now_max = now
.checked_add(T::ReportTolerance::get())
.ok_or(Error::<T>::CalculationOverflow)?;

ensure!(
normalized_schedule
.overlaps(now, now_max)
registration
.schedule
.overlaps(assignment.start_delay, now, now_max)
.ok_or(Error::<T>::CalculationOverflow)?,
Error::<T>::ReportOutsideSchedule
);
Expand Down
4 changes: 2 additions & 2 deletions pallets/marketplace/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ fn test_match() {
);

// pretend time moved on
later(registration.schedule.normalize(0).unwrap().0.end_time - 2000);
later(registration.schedule.range(0).unwrap().1 - 2000);
assert_eq!(3, System::block_number());

assert_ok!(AcurastMarketplace::report(
Expand Down Expand Up @@ -472,7 +472,7 @@ fn test_more_reports_than_expected() {
));

// third report is illegal!
later(registration.schedule.normalize(0).unwrap().0.end_time + 1000);
later(registration.schedule.range(0).unwrap().1 + 1000);
assert_err!(
AcurastMarketplace::report(
RuntimeOrigin::signed(processor_account_id()).into(),
Expand Down

0 comments on commit a5f1d42

Please sign in to comment.