ab_client_proof_of_time/
lib.rs

1//! Client-side proof of time implementation.
2
3pub mod source;
4pub mod verifier;
5
6use ab_core_primitives::pot::{PotOutput, PotParametersChange, PotSeed, SlotNumber};
7use parity_scale_codec::{Decode, Encode, MaxEncodedLen};
8use scale_info::TypeInfo;
9use std::num::NonZeroU32;
10
11/// Next slot input for proof of time evaluation
12#[derive(Debug, Copy, Clone, PartialEq, Eq, Decode, Encode, TypeInfo, MaxEncodedLen)]
13pub struct PotNextSlotInput {
14    /// Slot number
15    pub slot: SlotNumber,
16    /// Slot iterations for this slot
17    pub slot_iterations: NonZeroU32,
18    /// Seed for this slot
19    pub seed: PotSeed,
20}
21
22impl PotNextSlotInput {
23    /// Derive next slot input while taking parameters change into account.
24    ///
25    /// NOTE: `base_slot_iterations` doesn't have to be parent block, just something that is after
26    /// prior parameters change (if any) took effect, in most cases this value corresponds to parent
27    /// block's slot.
28    pub fn derive(
29        base_slot_iterations: NonZeroU32,
30        parent_slot: SlotNumber,
31        parent_output: PotOutput,
32        pot_parameters_change: &Option<PotParametersChange>,
33    ) -> Self {
34        let next_slot = parent_slot + SlotNumber::ONE;
35        let slot_iterations;
36        let seed;
37
38        // The change to number of iterations might have happened before `next_slot`
39        if let Some(parameters_change) = pot_parameters_change
40            && parameters_change.slot <= next_slot
41        {
42            slot_iterations = parameters_change.slot_iterations;
43            // Only if entropy injection happens exactly on next slot we need to mix it in
44            if parameters_change.slot == next_slot {
45                seed = parent_output.seed_with_entropy(&parameters_change.entropy);
46            } else {
47                seed = parent_output.seed();
48            }
49        } else {
50            slot_iterations = base_slot_iterations;
51            seed = parent_output.seed();
52        }
53
54        Self {
55            slot: next_slot,
56            slot_iterations,
57            seed,
58        }
59    }
60}