subspace_core_primitives/
pos.rs

1//! Proof of space-related data structures.
2
3use crate::hashes::{Blake3Hash, blake3_hash};
4use core::fmt;
5use derive_more::{Deref, DerefMut, From, Into};
6use parity_scale_codec::{Decode, DecodeWithMemTracking, 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,
33    Clone,
34    Eq,
35    PartialEq,
36    Deref,
37    DerefMut,
38    From,
39    Into,
40    Encode,
41    Decode,
42    TypeInfo,
43    MaxEncodedLen,
44    DecodeWithMemTracking,
45)]
46pub struct PosProof([u8; PosProof::SIZE]);
47
48impl fmt::Debug for PosProof {
49    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
50        write!(f, "{}", hex::encode(self.0))
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)
110    }
111}