subspace_core_primitives/
pos.rs

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