use fvm_shared4::clock::{ChainEpoch, QuantSpec};
use serde::{Deserialize, Serialize};
#[derive(Default, Debug, Serialize, Deserialize, PartialEq, Eq, Copy, Clone)]
#[serde(rename_all = "PascalCase")]
pub struct DeadlineInfo {
pub current_epoch: ChainEpoch,
pub period_start: ChainEpoch,
pub index: u64,
pub open: ChainEpoch,
pub close: ChainEpoch,
pub challenge: ChainEpoch,
pub fault_cutoff: ChainEpoch,
#[serde(rename = "WPoStPeriodDeadlines")]
pub w_post_period_deadlines: u64,
#[serde(rename = "WPoStProvingPeriod")]
pub w_post_proving_period: ChainEpoch,
#[serde(rename = "WPoStChallengeWindow")]
pub w_post_challenge_window: ChainEpoch,
#[serde(rename = "WPoStChallengeLookback")]
pub w_post_challenge_lookback: ChainEpoch,
pub fault_declaration_cutoff: ChainEpoch,
}
impl DeadlineInfo {
#[allow(clippy::too_many_arguments)]
pub fn new(
period_start: ChainEpoch,
deadline_idx: u64,
current_epoch: ChainEpoch,
w_post_period_deadlines: u64,
w_post_proving_period: ChainEpoch,
w_post_challenge_window: ChainEpoch,
w_post_challenge_lookback: ChainEpoch,
fault_declaration_cutoff: ChainEpoch,
) -> Self {
if deadline_idx < w_post_period_deadlines {
let deadline_open = period_start + (deadline_idx as i64 * w_post_challenge_window);
Self {
current_epoch,
period_start,
index: deadline_idx,
open: deadline_open,
close: deadline_open + w_post_challenge_window,
challenge: deadline_open - w_post_challenge_lookback,
fault_cutoff: deadline_open - fault_declaration_cutoff,
w_post_period_deadlines,
w_post_proving_period,
w_post_challenge_window,
w_post_challenge_lookback,
fault_declaration_cutoff,
}
} else {
let after_last_deadline = period_start + w_post_proving_period;
Self {
current_epoch,
period_start,
index: deadline_idx,
open: after_last_deadline,
close: after_last_deadline,
challenge: after_last_deadline,
fault_cutoff: 0,
w_post_period_deadlines,
w_post_proving_period,
w_post_challenge_window,
w_post_challenge_lookback,
fault_declaration_cutoff,
}
}
}
pub fn period_started(&self) -> bool {
self.current_epoch >= self.period_start
}
pub fn period_elapsed(&self) -> bool {
self.current_epoch >= self.next_period_start()
}
pub fn period_end(&self) -> ChainEpoch {
self.period_start + self.w_post_proving_period - 1
}
pub fn next_period_start(&self) -> ChainEpoch {
self.period_start + self.w_post_proving_period
}
pub fn is_open(&self) -> bool {
self.current_epoch >= self.open && self.current_epoch < self.close
}
pub fn has_elapsed(&self) -> bool {
self.current_epoch >= self.close
}
pub fn last(&self) -> ChainEpoch {
self.close - 1
}
pub fn next_open(&self) -> ChainEpoch {
self.close
}
pub fn fault_cutoff_passed(&self) -> bool {
self.current_epoch >= self.fault_cutoff
}
pub fn next_not_elapsed(self) -> Self {
if !self.has_elapsed() {
return self;
}
let gap = self.current_epoch - self.close;
let delta_periods = 1 + gap / self.w_post_proving_period;
Self::new(
self.period_start + self.w_post_proving_period * delta_periods,
self.index,
self.current_epoch,
self.w_post_period_deadlines,
self.w_post_proving_period,
self.w_post_challenge_window,
self.w_post_challenge_lookback,
self.fault_declaration_cutoff,
)
}
pub fn quant_spec(&self) -> QuantSpec {
QuantSpec {
unit: self.w_post_proving_period,
offset: self.last(),
}
}
}