sc_proof_of_time/source/
timekeeper.rs1use crate::source::state::PotState;
2use crate::verifier::PotVerifier;
3use futures::channel::mpsc;
4use futures::executor::block_on;
5use futures::SinkExt;
6use sp_consensus_slots::Slot;
7use std::num::NonZeroU32;
8use std::sync::Arc;
9use subspace_core_primitives::pot::{PotCheckpoints, PotSeed};
10use subspace_proof_of_time::PotError;
11use tracing::{debug, trace};
12
13pub(super) struct TimekeeperProof {
15 pub(super) slot: Slot,
17 pub(super) seed: PotSeed,
19 pub(super) slot_iterations: NonZeroU32,
21 pub(super) checkpoints: PotCheckpoints,
23}
24
25pub(super) fn run_timekeeper(
27 state: Arc<PotState>,
28 pot_verifier: PotVerifier,
29 mut proofs_sender: mpsc::Sender<TimekeeperProof>,
30) -> Result<(), PotError> {
31 let mut next_slot_input = state.next_slot_input();
32
33 loop {
34 trace!(
35 "Proving for slot {} with {} iterations",
36 next_slot_input.slot,
37 next_slot_input.slot_iterations
38 );
39 let checkpoints =
40 subspace_proof_of_time::prove(next_slot_input.seed, next_slot_input.slot_iterations)?;
41
42 let proof = TimekeeperProof {
43 seed: next_slot_input.seed,
44 slot_iterations: next_slot_input.slot_iterations,
45 slot: next_slot_input.slot,
46 checkpoints,
47 };
48
49 pot_verifier.inject_verified_checkpoints(
50 next_slot_input.seed,
51 next_slot_input.slot_iterations,
52 checkpoints,
53 );
54
55 next_slot_input = state
56 .try_extend(
57 next_slot_input,
58 next_slot_input.slot,
59 checkpoints.output(),
60 None,
61 )
62 .unwrap_or_else(|next_slot_input| next_slot_input);
63
64 if let Err(error) = proofs_sender.try_send(proof) {
65 if let Err(error) = block_on(proofs_sender.send(error.into_inner())) {
66 debug!(%error, "Couldn't send checkpoints, channel is closed");
67 return Ok(());
68 }
69 }
70 }
71}