ab_proof_of_space/
chia.rs1#[cfg(feature = "alloc")]
3use crate::TableGenerator;
4use crate::chiapos::Tables;
5#[cfg(feature = "alloc")]
6use crate::chiapos::TablesCache;
7use crate::{PosTableType, Table};
8use ab_core_primitives::pos::{PosProof, PosSeed};
9
10const K: u8 = PosProof::K;
11
12#[derive(Debug, Default, Clone)]
16#[cfg(feature = "alloc")]
17pub struct ChiaTableGenerator {
18 tables_cache: TablesCache<K>,
19}
20
21#[cfg(feature = "alloc")]
22impl TableGenerator<ChiaTable> for ChiaTableGenerator {
23 fn generate(&mut self, seed: &PosSeed) -> ChiaTable {
24 ChiaTable {
25 tables: Tables::<K>::create((*seed).into(), &mut self.tables_cache),
26 }
27 }
28
29 #[cfg(any(feature = "parallel", test))]
30 fn generate_parallel(&mut self, seed: &PosSeed) -> ChiaTable {
31 ChiaTable {
32 tables: Tables::<K>::create_parallel((*seed).into(), &mut self.tables_cache),
33 }
34 }
35}
36
37#[derive(Debug)]
41pub struct ChiaTable {
42 #[cfg(feature = "alloc")]
43 tables: Tables<K>,
44}
45
46impl ab_core_primitives::solutions::SolutionPotVerifier for ChiaTable {
47 fn is_proof_valid(seed: &PosSeed, challenge_index: u32, proof: &PosProof) -> bool {
48 let mut challenge = [0; 32];
49 challenge[..size_of::<u32>()].copy_from_slice(&challenge_index.to_le_bytes());
50 Tables::<K>::verify(**seed, &challenge, proof).is_some()
51 }
52}
53
54impl Table for ChiaTable {
55 const TABLE_TYPE: PosTableType = PosTableType::Chia;
56 #[cfg(feature = "alloc")]
57 type Generator = ChiaTableGenerator;
58
59 #[cfg(feature = "alloc")]
60 fn generate(seed: &PosSeed) -> ChiaTable {
61 Self {
62 tables: Tables::<K>::create_simple((*seed).into()),
63 }
64 }
65
66 #[cfg(all(feature = "alloc", any(feature = "parallel", test)))]
67 fn generate_parallel(seed: &PosSeed) -> ChiaTable {
68 Self {
69 tables: Tables::<K>::create_parallel((*seed).into(), &mut TablesCache::default()),
70 }
71 }
72
73 #[cfg(feature = "alloc")]
74 fn find_proof(&self, challenge_index: u32) -> Option<PosProof> {
75 let mut challenge = [0; 32];
76 challenge[..size_of::<u32>()].copy_from_slice(&challenge_index.to_le_bytes());
77
78 self.tables
79 .find_proof(&challenge)
80 .next()
81 .map(PosProof::from)
82 }
83
84 fn is_proof_valid(seed: &PosSeed, challenge_index: u32, proof: &PosProof) -> bool {
85 <Self as ab_core_primitives::solutions::SolutionPotVerifier>::is_proof_valid(
86 seed,
87 challenge_index,
88 proof,
89 )
90 }
91}
92
93#[cfg(all(feature = "alloc", test))]
94#[cfg(not(miri))]
95mod tests {
96 use super::*;
97
98 #[test]
99 fn basic() {
100 let seed = PosSeed::from([
101 35, 2, 52, 4, 51, 55, 23, 84, 91, 10, 111, 12, 13, 222, 151, 16, 228, 211, 254, 45, 92,
102 198, 204, 10, 9, 10, 11, 129, 139, 171, 15, 23,
103 ]);
104
105 let table = ChiaTable::generate(&seed);
106 let table_parallel = ChiaTable::generate_parallel(&seed);
107
108 assert!(table.find_proof(1232460437).is_none());
109 assert!(table_parallel.find_proof(1232460437).is_none());
110
111 {
112 let challenge_index = 600426542;
113 let proof = table.find_proof(challenge_index).unwrap();
114 assert_eq!(proof, table_parallel.find_proof(challenge_index).unwrap());
115 assert!(ChiaTable::is_proof_valid(&seed, challenge_index, &proof));
116 }
117 }
118}