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