1use std::{
5    fmt,
6    hash::{Hash, Hasher},
7};
8
9use consensus_config::{AuthorityIndex, DIGEST_LENGTH};
10use fastcrypto::hash::Digest;
11use serde::{Deserialize, Serialize};
12
13pub type Round = u32;
15
16pub type BlockTimestampMs = u64;
18
19pub type TransactionIndex = u16;
21
22pub const NUM_RESERVED_TRANSACTION_INDICES: TransactionIndex = 8;
24
25pub const PING_TRANSACTION_INDEX: TransactionIndex = TransactionIndex::MAX;
28
29#[derive(Clone, Copy, Serialize, Deserialize, Default, PartialEq, Eq, PartialOrd, Ord)]
32pub struct BlockRef {
33    pub round: Round,
34    pub author: AuthorityIndex,
35    pub digest: BlockDigest,
36}
37
38impl BlockRef {
39    pub const MIN: Self = Self {
40        round: 0,
41        author: AuthorityIndex::MIN,
42        digest: BlockDigest::MIN,
43    };
44
45    pub const MAX: Self = Self {
46        round: u32::MAX,
47        author: AuthorityIndex::MAX,
48        digest: BlockDigest::MAX,
49    };
50
51    pub fn new(round: Round, author: AuthorityIndex, digest: BlockDigest) -> Self {
52        Self {
53            round,
54            author,
55            digest,
56        }
57    }
58}
59
60impl fmt::Display for BlockRef {
61    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
62        write!(f, "B{}({},{})", self.round, self.author, self.digest)
63    }
64}
65
66impl fmt::Debug for BlockRef {
67    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
68        write!(f, "B{}({},{:?})", self.round, self.author, self.digest)
69    }
70}
71
72impl Hash for BlockRef {
73    fn hash<H: Hasher>(&self, state: &mut H) {
74        state.write(&self.digest.0[..8]);
75    }
76}
77
78#[derive(Clone, Copy, Serialize, Deserialize, Default, PartialEq, Eq, PartialOrd, Ord)]
84pub struct BlockDigest(pub [u8; consensus_config::DIGEST_LENGTH]);
85
86impl BlockDigest {
87    pub const MIN: Self = Self([u8::MIN; consensus_config::DIGEST_LENGTH]);
89    pub const MAX: Self = Self([u8::MAX; consensus_config::DIGEST_LENGTH]);
90}
91
92impl Hash for BlockDigest {
93    fn hash<H: Hasher>(&self, state: &mut H) {
94        state.write(&self.0[..8]);
95    }
96}
97
98impl From<BlockDigest> for Digest<{ DIGEST_LENGTH }> {
99    fn from(hd: BlockDigest) -> Self {
100        Digest::new(hd.0)
101    }
102}
103
104impl fmt::Display for BlockDigest {
105    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
106        write!(
107            f,
108            "{}",
109            base64::Engine::encode(&base64::engine::general_purpose::STANDARD, self.0)
110                .get(0..4)
111                .ok_or(fmt::Error)?
112        )
113    }
114}
115
116impl fmt::Debug for BlockDigest {
117    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
118        write!(
119            f,
120            "{}",
121            base64::Engine::encode(&base64::engine::general_purpose::STANDARD, self.0)
122        )
123    }
124}
125
126impl AsRef<[u8]> for BlockDigest {
127    fn as_ref(&self) -> &[u8] {
128        &self.0
129    }
130}