Skip to main content

subspace_proof_of_space/
pos_table.rs

1//! Proof of space that dispatches per sector between the old [`ChiaTable`] and the new
2//! [`ChiaV2Table`], so one farm can mix them across the migration cutover.
3
4use crate::chia::ChiaTable;
5use crate::chia_v2::ChiaV2Table;
6use crate::{PosTableType, Table, TableGenerator};
7use subspace_core_primitives::pos::{PosProof, PosSeed};
8use subspace_core_primitives::solutions::SolutionPotVerifier;
9
10/// Proof of space table generator dispatching between the old and new Chia implementations.
11#[derive(Debug, Clone)]
12pub enum PosTableGenerator {
13    /// Old (pre-cutover) implementation.
14    V1(<ChiaTable as Table>::Generator),
15    /// New (post-cutover) implementation.
16    V2(<ChiaV2Table as Table>::Generator),
17}
18
19impl Default for PosTableGenerator {
20    #[inline]
21    fn default() -> Self {
22        Self::V2(ChiaV2Table::generator())
23    }
24}
25
26impl PosTableGenerator {
27    /// Generator for a sector: the new implementation for post-cutover sectors, the old one
28    /// otherwise.
29    #[inline]
30    pub fn new(is_post_cutover: bool) -> Self {
31        if is_post_cutover {
32            Self::V2(ChiaV2Table::generator())
33        } else {
34            Self::V1(ChiaTable::generator())
35        }
36    }
37}
38
39impl TableGenerator<PosTable> for PosTableGenerator {
40    fn generate(&self, seed: &PosSeed) -> PosTable {
41        match self {
42            Self::V1(generator) => PosTable::V1(generator.generate(seed)),
43            Self::V2(generator) => PosTable::V2(generator.generate(seed)),
44        }
45    }
46
47    #[cfg(feature = "parallel")]
48    fn generate_parallel(&self, seed: &PosSeed) -> PosTable {
49        match self {
50            Self::V1(generator) => PosTable::V1(generator.generate_parallel(seed)),
51            Self::V2(generator) => PosTable::V2(generator.generate_parallel(seed)),
52        }
53    }
54}
55
56/// Proof of space table dispatching between the old and new Chia implementations.
57#[derive(Debug)]
58pub enum PosTable {
59    /// Old (pre-cutover) implementation.
60    V1(ChiaTable),
61    /// New (post-cutover) implementation.
62    V2(ChiaV2Table),
63}
64
65impl SolutionPotVerifier for PosTable {
66    fn is_proof_valid(seed: &PosSeed, challenge_index: u32, proof: &PosProof) -> bool {
67        // Both V1 and V2 proofs verify under ChiaTable.
68        <ChiaTable as SolutionPotVerifier>::is_proof_valid(seed, challenge_index, proof)
69    }
70}
71
72impl Table for PosTable {
73    const TABLE_TYPE: PosTableType = PosTableType::Chia;
74    type Generator = PosTableGenerator;
75
76    fn generator_for(is_post_cutover: bool) -> Self::Generator {
77        PosTableGenerator::new(is_post_cutover)
78    }
79
80    fn find_proof(&self, challenge_index: u32) -> Option<PosProof> {
81        match self {
82            Self::V1(table) => table.find_proof(challenge_index),
83            Self::V2(table) => table.find_proof(challenge_index),
84        }
85    }
86
87    fn is_proof_valid(seed: &PosSeed, challenge_index: u32, proof: &PosProof) -> bool {
88        <Self as SolutionPotVerifier>::is_proof_valid(seed, challenge_index, proof)
89    }
90}
91
92#[cfg(test)]
93mod tests;