espresso_types/v0/v0_5/
header.rs1use ark_serialize::CanonicalSerialize;
2use committable::{Commitment, Committable, RawCommitmentBuilder};
3use hotshot_types::{data::VidCommitment, utils::BuilderCommitment};
4use serde::{Deserialize, Deserializer, Serialize, Serializer};
5
6use super::{
7 BlockMerkleCommitment, BuilderSignature, FeeInfo, FeeMerkleCommitment, L1BlockInfo,
8 ResolvableChainConfig,
9};
10use crate::{
11 NsTable, TimestampMillis,
12 v0::impls::StakeTableHash,
13 v0_3::RewardAmount,
14 v0_4::RewardMerkleCommitmentV2,
15 v0_5::{LeaderCounts, MAX_VALIDATORS},
16};
17
18mod leader_counts_serde {
19 use super::*;
20
21 pub fn serialize<S>(counts: &LeaderCounts, serializer: S) -> Result<S::Ok, S::Error>
22 where
23 S: Serializer,
24 {
25 counts.as_slice().serialize(serializer)
26 }
27
28 pub fn deserialize<'de, D>(deserializer: D) -> Result<LeaderCounts, D::Error>
29 where
30 D: Deserializer<'de>,
31 {
32 let vec: Vec<u16> = Vec::deserialize(deserializer)?;
33 if vec.len() != MAX_VALIDATORS {
34 return Err(serde::de::Error::custom(format!(
35 "expected {} elements, got {}",
36 MAX_VALIDATORS,
37 vec.len()
38 )));
39 }
40 let mut arr = [0u16; MAX_VALIDATORS];
41 arr.copy_from_slice(&vec);
42 Ok(arr)
43 }
44}
45
46#[derive(Clone, Debug, Deserialize, Serialize, Hash, PartialEq, Eq)]
53pub struct Header {
54 pub(crate) chain_config: ResolvableChainConfig,
56 pub(crate) height: u64,
57 pub(crate) timestamp: u64,
58 pub(crate) timestamp_millis: TimestampMillis,
59 pub(crate) l1_head: u64,
60 pub(crate) l1_finalized: Option<L1BlockInfo>,
61 pub(crate) payload_commitment: VidCommitment,
62 pub(crate) builder_commitment: BuilderCommitment,
63 pub(crate) ns_table: NsTable,
64 pub(crate) block_merkle_tree_root: BlockMerkleCommitment,
65 pub(crate) fee_merkle_tree_root: FeeMerkleCommitment,
66 pub(crate) fee_info: FeeInfo,
67 pub(crate) builder_signature: Option<BuilderSignature>,
68 pub(crate) reward_merkle_tree_root: RewardMerkleCommitmentV2,
69 pub(crate) total_reward_distributed: RewardAmount,
70 pub(crate) next_stake_table_hash: Option<StakeTableHash>,
71 #[serde(with = "leader_counts_serde")]
75 pub(crate) leader_counts: LeaderCounts,
76}
77
78impl Committable for Header {
79 fn commit(&self) -> Commitment<Self> {
80 let mut bmt_bytes = vec![];
81 self.block_merkle_tree_root
82 .serialize_with_mode(&mut bmt_bytes, ark_serialize::Compress::Yes)
83 .unwrap();
84 let mut fmt_bytes = vec![];
85 self.fee_merkle_tree_root
86 .serialize_with_mode(&mut fmt_bytes, ark_serialize::Compress::Yes)
87 .unwrap();
88
89 let mut rwd_bytes = vec![];
90 self.reward_merkle_tree_root
91 .serialize_with_mode(&mut rwd_bytes, ark_serialize::Compress::Yes)
92 .unwrap();
93
94 let leader_counts_bytes: Vec<u8> = self
95 .leader_counts
96 .iter()
97 .flat_map(|&count| count.to_le_bytes())
98 .collect();
99
100 let mut cb = RawCommitmentBuilder::new(&Self::tag())
101 .field("chain_config", self.chain_config.commit())
102 .u64_field("height", self.height)
103 .u64_field("timestamp", self.timestamp)
104 .u64_field("timestamp_millis", self.timestamp_millis.u64())
105 .u64_field("l1_head", self.l1_head)
106 .optional("l1_finalized", &self.l1_finalized)
107 .constant_str("payload_commitment")
108 .fixed_size_bytes(self.payload_commitment.as_ref())
109 .constant_str("builder_commitment")
110 .fixed_size_bytes(self.builder_commitment.as_ref())
111 .field("ns_table", self.ns_table.commit())
112 .var_size_field("block_merkle_tree_root", &bmt_bytes)
113 .var_size_field("fee_merkle_tree_root", &fmt_bytes)
114 .field("fee_info", self.fee_info.commit())
115 .var_size_field("reward_merkle_tree_root", &rwd_bytes)
116 .var_size_field(
117 "total_reward_distributed",
118 &self.total_reward_distributed.to_fixed_bytes(),
119 )
120 .var_size_field("leader_counts", &leader_counts_bytes);
121
122 if let Some(next_stake_table_hash) = self.next_stake_table_hash {
123 cb = cb.field("next_stake_table_hash", next_stake_table_hash);
124 }
125
126 cb.finalize()
127 }
128
129 fn tag() -> String {
130 crate::v0_1::Header::tag()
131 }
132}