espresso_types/v0/v0_1/
header.rs

1use 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/// A header is like a [`Block`] with the body replaced by a digest.
17#[derive(Clone, Debug, Deserialize, Serialize, Hash, PartialEq, Eq)]
18pub struct Header {
19    /// A commitment to a ChainConfig or a full ChainConfig.
20    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        // We use the tag "BLOCK" since blocks are identified by the hash of their header. This will
72        // thus be more intuitive to users than "HEADER".
73        "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}