espresso_types/v0/v0_1/
header.rs1use crate::NsTable;
2
3use super::{
4 BlockMerkleCommitment, BuilderSignature, FeeInfo, FeeMerkleCommitment, L1BlockInfo,
5 ResolvableChainConfig,
6};
7use alloy_compat::ethers_serde;
8use ark_serialize::CanonicalSerialize;
9use committable::{Commitment, Committable, RawCommitmentBuilder};
10use hotshot_types::{data::VidCommitment, utils::BuilderCommitment};
11use serde::{
12 de::{self, SeqAccess},
13 Deserialize, Serialize,
14};
15
16#[derive(Clone, Debug, Deserialize, Serialize, Hash, PartialEq, Eq)]
18pub struct Header {
19 pub(crate) chain_config: ResolvableChainConfig,
21 pub(crate) height: u64,
22 pub(crate) timestamp: u64,
23 pub(crate) l1_head: u64,
24 pub(crate) l1_finalized: Option<L1BlockInfo>,
25 pub(crate) payload_commitment: VidCommitment,
26 pub(crate) builder_commitment: BuilderCommitment,
27 pub(crate) ns_table: NsTable,
28 pub(crate) block_merkle_tree_root: BlockMerkleCommitment,
29 pub(crate) fee_merkle_tree_root: FeeMerkleCommitment,
30 pub(crate) fee_info: FeeInfo,
31 #[serde(with = "ethers_serde::option_signature")]
32 pub(crate) builder_signature: Option<BuilderSignature>,
33}
34
35macro_rules! element {
36 ($seq:expr, $field:ident) => {
37 $seq.next_element()?
38 .ok_or_else(|| de::Error::missing_field(stringify!($field)))?
39 };
40}
41
42impl Committable for Header {
43 fn commit(&self) -> Commitment<Self> {
44 let mut bmt_bytes = vec![];
45 self.block_merkle_tree_root
46 .serialize_with_mode(&mut bmt_bytes, ark_serialize::Compress::Yes)
47 .unwrap();
48 let mut fmt_bytes = vec![];
49 self.fee_merkle_tree_root
50 .serialize_with_mode(&mut fmt_bytes, ark_serialize::Compress::Yes)
51 .unwrap();
52
53 RawCommitmentBuilder::new(&Self::tag())
54 .field("chain_config", self.chain_config.commit())
55 .u64_field("height", self.height)
56 .u64_field("timestamp", self.timestamp)
57 .u64_field("l1_head", self.l1_head)
58 .optional("l1_finalized", &self.l1_finalized)
59 .constant_str("payload_commitment")
60 .fixed_size_bytes(self.payload_commitment.as_ref())
61 .constant_str("builder_commitment")
62 .fixed_size_bytes(self.builder_commitment.as_ref())
63 .field("ns_table", self.ns_table.commit())
64 .var_size_field("block_merkle_tree_root", &bmt_bytes)
65 .var_size_field("fee_merkle_tree_root", &fmt_bytes)
66 .field("fee_info", self.fee_info.commit())
67 .finalize()
68 }
69
70 fn tag() -> String {
71 "BLOCK".into()
74 }
75}
76
77impl Header {
78 pub fn deserialize_with_chain_config<'de, A>(
79 chain_config: ResolvableChainConfig,
80 mut seq: A,
81 ) -> Result<Header, A::Error>
82 where
83 A: SeqAccess<'de>,
84 {
85 let height = element!(seq, height);
86 let timestamp = element!(seq, timestamp);
87 let l1_head = element!(seq, l1_head);
88 let l1_finalized = element!(seq, l1_finalized);
89 let payload_commitment = element!(seq, payload_commitment);
90 let builder_commitment = element!(seq, builder_commitment);
91 let ns_table = element!(seq, ns_table);
92 let block_merkle_tree_root = element!(seq, block_merkle_tree_root);
93 let fee_merkle_tree_root = element!(seq, fee_merkle_tree_root);
94 let fee_info = element!(seq, fee_info);
95 let builder_signature = element!(seq, builder_signature);
96
97 Ok(Self {
98 chain_config,
99 height,
100 timestamp,
101 l1_head,
102 l1_finalized,
103 payload_commitment,
104 builder_commitment,
105 ns_table,
106 block_merkle_tree_root,
107 fee_merkle_tree_root,
108 fee_info,
109 builder_signature,
110 })
111 }
112}