diff --git a/pallets/storage-provider/src/deadline.rs b/pallets/storage-provider/src/deadline.rs index ce8689870..6baf90fd5 100644 --- a/pallets/storage-provider/src/deadline.rs +++ b/pallets/storage-provider/src/deadline.rs @@ -664,7 +664,7 @@ where let (open_at, close_at, challenge, fault_cutoff) = if idx_converted < period_deadlines { let open_at = period_start + (idx_converted * w_post_challenge_window); let close_at = open_at + w_post_challenge_window; - let challenge = period_start - w_post_challenge_lookback; + let challenge = open_at - w_post_challenge_lookback; let fault_cutoff = open_at - fault_declaration_cutoff; (open_at, close_at, challenge, fault_cutoff) } else { @@ -720,18 +720,22 @@ where self.block_number >= self.fault_cutoff } - /// Returns the next deadline that has not yet elapsed. + /// Calculates the deadline information in the next proving period. /// - /// If the current deadline has not elapsed yet then it returns the current deadline. - /// Otherwise it calculates the next period start by getting the gap between the current block number and the closing block number - /// and adding 1. Making sure it is a multiple of proving period by dividing by `w_post_proving_period`. - pub fn next_not_elapsed(self) -> Result { - if !self.has_elapsed() { - return Ok(self); - } - - // has elapsed, advance by some multiples of w_post_proving_period - let gap = self.block_number - self.close_at; + /// ### Example 1 + /// Current Block = 110 + /// [self.open_at, self.close_at] = [100, 120] + /// Proving Periods: [100; 160), [160; 220), [220, 280) + /// next() -> + /// + /// ### Example 2 + /// Current Block = 162 + /// [self.open_at, self.close_at] = [100, 120] + /// Proving Periods: [100; 160), [160; 220), [220, 280) + /// next() -> [240, 260) + /// + pub fn next(self) -> Result { + let gap = self.block_number - self.period_start; let delta_periods = BlockNumber::one() + gap / self.w_post_proving_period; Self::new( @@ -745,6 +749,28 @@ where self.fault_declaration_cutoff, ) } + + /// Returns the next deadline that has not yet elapsed. + /// + /// If the current deadline has not elapsed yet then it returns the current deadline. + pub fn next_not_elapsed(self) -> Result { + if !self.has_elapsed() { + return Ok(self); + } + + self.next() + } + + /// Returns the next deadline that has not yet been opened nor closed. + /// + /// If the current deadline has not opened yet then it returns the current deadline. + pub fn next_not_opened(self) -> Result { + if !self.is_open() && !self.has_elapsed() { + return Ok(self); + } + + self.next() + } } /// Returns true if the deadline at the given index is currently mutable. diff --git a/pallets/storage-provider/src/lib.rs b/pallets/storage-provider/src/lib.rs index 115bd6510..914733183 100644 --- a/pallets/storage-provider/src/lib.rs +++ b/pallets/storage-provider/src/lib.rs @@ -1098,7 +1098,7 @@ pub mod pallet { }) } - /// Gets the current deadline of the storage provider. + /// Gets the next, not yet opened, deadline of the storage provider. /// /// If there is no Storage Provider of given AccountId returns [`Option::None`]. /// May exceptionally return [`Option::None`] when @@ -1120,6 +1120,7 @@ pub mod pallet { T::WPoStChallengeLookBack::get(), T::FaultDeclarationCutoff::get(), ) + .and_then(DeadlineInfo::next_not_opened) .ok()?; Some(ExternalDeadlineInfo { diff --git a/pallets/storage-provider/src/tests/deadline.rs b/pallets/storage-provider/src/tests/deadline.rs new file mode 100644 index 000000000..763e26657 --- /dev/null +++ b/pallets/storage-provider/src/tests/deadline.rs @@ -0,0 +1,61 @@ +use crate::deadline::DeadlineInfo; + +fn default_deadline() -> DeadlineInfo { + let block_number = 112; + let period_start = 100; + let deadline_index = 0; + let period_deadlines = 3; + let proving_period = 60; + let challenge_window = 20; + let challenge_lookback = 20; + let cutoff = 5; + + DeadlineInfo::::new( + block_number, + period_start, + deadline_index, + period_deadlines, + proving_period, + challenge_window, + challenge_lookback, + cutoff, + ) + .unwrap() +} + +#[test] +fn calculates_next_deadline_when_its_open() { + let deadline_info = default_deadline(); + assert_eq!(deadline_info.is_open(), true); + + let next = deadline_info.next().unwrap(); + + assert_eq!(next.open_at, 160); + assert_eq!(next.close_at, 180); +} + +#[test] +fn calculates_next_deadline_when_its_elapsed() { + let mut deadline_info = default_deadline(); + deadline_info.block_number = 121; + assert_eq!(deadline_info.is_open(), false); + assert_eq!(deadline_info.has_elapsed(), true); + + let next = deadline_info.next().unwrap(); + + assert_eq!(next.open_at, 160); + assert_eq!(next.close_at, 180); +} + +#[test] +fn calculates_next_deadline_when_its_2_proving_periods_behind() { + let mut deadline_info = default_deadline(); + deadline_info.block_number = 162; + assert_eq!(deadline_info.is_open(), false); + assert_eq!(deadline_info.has_elapsed(), true); + + let next = deadline_info.next().unwrap(); + + assert_eq!(next.open_at, 220); + assert_eq!(next.close_at, 240); +} diff --git a/pallets/storage-provider/src/tests/mod.rs b/pallets/storage-provider/src/tests/mod.rs index e3e2396a6..9c93104a2 100644 --- a/pallets/storage-provider/src/tests/mod.rs +++ b/pallets/storage-provider/src/tests/mod.rs @@ -38,6 +38,7 @@ use crate::{ sector::SectorPreCommitInfo, }; +mod deadline; mod declare_faults; mod declare_faults_recovered; mod expiration_queue; diff --git a/storage-provider/server/src/pipeline/mod.rs b/storage-provider/server/src/pipeline/mod.rs index 3c197408a..07d98922e 100644 --- a/storage-provider/server/src/pipeline/mod.rs +++ b/storage-provider/server/src/pipeline/mod.rs @@ -565,7 +565,7 @@ async fn prove_commit( Ok(()) } -#[tracing::instrument(skip_all, fields(sector_number))] +#[tracing::instrument(skip_all, fields(deadline_index))] async fn submit_windowed_post( state: Arc, deadline_index: u64, @@ -580,10 +580,15 @@ async fn submit_windowed_post( return Err(PipelineError::DeadlineNotFound); }; - tracing::info!("Wait for block {} for deadline challenge", deadline.start,); + tracing::debug!("Deadline Info: {:?}", deadline); + tracing::info!( + "Wait for challenge_block {}, start: {}, for deadline challenge", + deadline.challenge_block, + deadline.start + ); state .xt_client - .wait_for_height(deadline.challenge_block, true) + .wait_for_height(deadline.start, true) .await?; tracing::info!("Waiting finished, let's go"); @@ -616,7 +621,8 @@ async fn submit_windowed_post( todo!("I don't know what to do: polka-storage#595"); } if deadline_state.partitions.len() == 0 { - tracing::warn!("I'm not implemented. Waiting for polka-storage#621"); + tracing::info!("There are not partitions in this deadline yet. Nothing to prove here."); + schedule_post(state, deadline_index)?; return Ok(()); } @@ -626,6 +632,12 @@ async fn submit_windowed_post( .first_key_value() .expect("1 partition to be there"); + if sectors.len() == 0 { + tracing::info!("Every sector expired... Nothing to prove here."); + schedule_post(state, deadline_index)?; + return Ok(()); + } + let mut replicas = Vec::new(); for sector_number in sectors { let sector = state @@ -660,6 +672,7 @@ async fn submit_windowed_post( }; let proofs = handle.await??; + // TODO(@th7nder,#595,06/12/2024): how many proofs are for how many partitions and why // don't now why yet, need to figure this out let proof: SubstrateProof = proofs[0] .clone() @@ -700,7 +713,8 @@ async fn submit_windowed_post( tracing::info!("Successfully submitted PoSt on-chain: {:?}", posts); - // TODO(@th7nder,#621,02/12/2024): reschedule Windowed PoSt for the next proving period. + schedule_post(state, deadline_index)?; + Ok(()) } @@ -709,18 +723,25 @@ async fn schedule_posts(state: Arc) -> Result<(), PipelineError> let proving_period = state.xt_client.proving_period_info()?; for deadline_index in 0..proving_period.deadlines { - state - .pipeline_sender - .send(PipelineMessage::SubmitWindowedPoStMessage( - SubmitWindowedPoStMessage { deadline_index }, - )) - .map_err(|err| { - tracing::error!(%err, "failed to send a messsage to the pipeline"); - PipelineError::SchedulingError - })?; - - tracing::info!("Scheduled Windowed PoSt for deadline: {}", deadline_index); + schedule_post(state.clone(), deadline_index)?; } Ok(()) } + +#[tracing::instrument(skip_all, fields(deadline_index))] +fn schedule_post(state: Arc, deadline_index: u64) -> Result<(), PipelineError> { + state + .pipeline_sender + .send(PipelineMessage::SubmitWindowedPoStMessage( + SubmitWindowedPoStMessage { deadline_index }, + )) + .map_err(|err| { + tracing::error!(%err, "failed to send a messsage to the pipeline"); + PipelineError::SchedulingError + })?; + + tracing::info!("Scheduled Windowed PoSt for deadline: {}", deadline_index); + + Ok(()) +}