ab_core_primitives/
pos.rs

1//! Proof of space-related data structures.
2
3use crate::hashes::Blake3Hash;
4use ab_io_type::trivial_type::TrivialType;
5use core::fmt;
6use derive_more::{Deref, DerefMut, From, Into};
7#[cfg(feature = "scale-codec")]
8use parity_scale_codec::{Decode, Encode, MaxEncodedLen};
9#[cfg(feature = "scale-codec")]
10use scale_info::TypeInfo;
11#[cfg(feature = "serde")]
12use serde::{Deserialize, Serialize};
13#[cfg(feature = "serde")]
14use serde::{Deserializer, Serializer};
15#[cfg(feature = "serde")]
16use serde_big_array::BigArray;
17
18/// Proof of space seed.
19#[derive(Copy, Clone, Eq, PartialEq, Deref, From, Into)]
20pub struct PosSeed([u8; PosSeed::SIZE]);
21
22impl fmt::Debug for PosSeed {
23    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
24        for byte in self.0 {
25            write!(f, "{byte:02x}")?;
26        }
27        Ok(())
28    }
29}
30
31impl PosSeed {
32    /// Size of proof of space seed in bytes.
33    pub const SIZE: usize = 32;
34}
35
36/// Proof of space proof bytes.
37#[derive(Copy, Clone, Eq, PartialEq, Deref, DerefMut, From, Into, TrivialType)]
38#[cfg_attr(
39    feature = "scale-codec",
40    derive(Encode, Decode, TypeInfo, MaxEncodedLen)
41)]
42#[repr(C)]
43pub struct PosProof([u8; PosProof::SIZE]);
44
45impl fmt::Debug for PosProof {
46    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
47        for byte in self.0 {
48            write!(f, "{byte:02x}")?;
49        }
50        Ok(())
51    }
52}
53
54#[cfg(feature = "serde")]
55#[derive(Serialize, Deserialize)]
56#[serde(transparent)]
57struct PosProofBinary(#[serde(with = "BigArray")] [u8; PosProof::SIZE]);
58
59#[cfg(feature = "serde")]
60#[derive(Serialize, Deserialize)]
61#[serde(transparent)]
62struct PosProofHex(#[serde(with = "hex")] [u8; PosProof::SIZE]);
63
64#[cfg(feature = "serde")]
65impl Serialize for PosProof {
66    #[inline]
67    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
68    where
69        S: Serializer,
70    {
71        if serializer.is_human_readable() {
72            PosProofHex(self.0).serialize(serializer)
73        } else {
74            PosProofBinary(self.0).serialize(serializer)
75        }
76    }
77}
78
79#[cfg(feature = "serde")]
80impl<'de> Deserialize<'de> for PosProof {
81    #[inline]
82    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
83    where
84        D: Deserializer<'de>,
85    {
86        Ok(Self(if deserializer.is_human_readable() {
87            PosProofHex::deserialize(deserializer)?.0
88        } else {
89            PosProofBinary::deserialize(deserializer)?.0
90        }))
91    }
92}
93
94impl Default for PosProof {
95    #[inline]
96    fn default() -> Self {
97        Self([0; Self::SIZE])
98    }
99}
100
101impl PosProof {
102    /// Constant K used for proof of space
103    pub const K: u8 = 20;
104    /// Size of proof of space proof in bytes.
105    pub const SIZE: usize = Self::K as usize * 8;
106
107    /// Proof hash.
108    pub fn hash(&self) -> Blake3Hash {
109        blake3::hash(&self.0).into()
110    }
111}