chik_protocol/
proof_of_space.rs1use crate::bytes::{Bytes, Bytes32};
2use chik_bls::G1Element;
3use chik_streamable_macro::streamable;
4
5#[streamable]
6pub struct ProofOfSpace {
7 challenge: Bytes32,
8 pool_public_key: Option<G1Element>,
9 pool_contract_puzzle_hash: Option<Bytes32>,
10 plot_public_key: G1Element,
11 version_and_size: u8,
12 proof: Bytes,
13}
14
15#[derive(Debug, PartialEq)]
16pub enum PlotSize {
17 V1(u8),
18 V2(u8),
19}
20
21impl ProofOfSpace {
22 pub fn size(&self) -> PlotSize {
23 if (self.version_and_size & 0x80) == 0 {
24 PlotSize::V1(self.version_and_size)
25 } else {
26 PlotSize::V2(self.version_and_size & 0x7f)
27 }
28 }
29}
30
31#[cfg(feature = "py-bindings")]
32use pyo3::prelude::*;
33
34#[cfg(feature = "py-bindings")]
35#[pymethods]
36impl ProofOfSpace {
37 fn size_v1(&self) -> Option<u8> {
38 match self.size() {
39 PlotSize::V1(s) => Some(s),
40 PlotSize::V2(_) => None,
41 }
42 }
43
44 fn size_v2(&self) -> Option<u8> {
45 match self.size() {
46 PlotSize::V1(_) => None,
47 PlotSize::V2(s) => Some(s),
48 }
49 }
50}
51
52#[cfg(test)]
53#[allow(clippy::needless_pass_by_value)]
54mod tests {
55 use super::*;
56 use rstest::rstest;
57
58 #[rstest]
59 #[case(0x00, PlotSize::V1(0))]
60 #[case(0x01, PlotSize::V1(1))]
61 #[case(0x08, PlotSize::V1(8))]
62 #[case(0x7f, PlotSize::V1(0x7f))]
63 #[case(0x80, PlotSize::V2(0))]
64 #[case(0x81, PlotSize::V2(1))]
65 #[case(0x80 + 28, PlotSize::V2(28))]
66 #[case(0x80 + 30, PlotSize::V2(30))]
67 #[case(0x80 + 32, PlotSize::V2(32))]
68 #[case(0xff, PlotSize::V2(0x7f))]
69 fn proof_of_space_size(#[case] size_field: u8, #[case] expect: PlotSize) {
70 let pos = ProofOfSpace::new(
71 Bytes32::from(b"abababababababababababababababab"),
72 None,
73 None,
74 G1Element::default(),
75 size_field,
76 Bytes::from(vec![]),
77 );
78
79 assert_eq!(pos.size(), expect);
80 }
81}