espresso_types/v0/header.rs
1use committable::Commitment;
2use serde::{Deserialize, Serialize};
3use vbs::version::Version;
4
5use crate::{
6 v0_1::{self, ChainConfig},
7 v0_2, v0_3, v0_99,
8};
9
10/// Each variant represents a specific minor version header.
11#[derive(Clone, Debug, Hash, PartialEq, Eq)]
12pub enum Header {
13 V1(v0_1::Header),
14 V2(v0_2::Header),
15 V3(v0_3::Header),
16 V99(v0_99::Header),
17}
18
19/// Enum to represent the first field of different versions of a header
20///
21/// In v1 headers, the first field is a ChainConfig, which contains either the chain config or its commitment.
22/// For versions > 0.1, the first field contains the version.
23///
24/// This enum has the same variant names and types in the same positions (0 and 1) as the Either enum,
25/// ensuring identical serialization and deserialization for the Left and Right variants.
26/// However, it will deserialize successfully in one additional case due to the Version variant.
27///
28/// Variants:
29/// - Left: Represents the ChainConfig variant in v1 headers.
30/// - Right: Represents the chain config commitment variant in v1 headers.
31/// - Version: Represents the versioned header for versions > 0.1.
32#[derive(Clone, Debug, Deserialize, Serialize)]
33pub(crate) enum EitherOrVersion {
34 Left(ChainConfig),
35 Right(Commitment<ChainConfig>),
36 Version(Version),
37}
38
39/// Headers with versions greater than 0.1 are serialized as `VersionedHeader` with the version field as `EitherOrVersion`.
40/// This ensures that the first field is deserialized as the `EitherOrVersion::Version` variant.
41/// This approach is necessary because `serde_flatten()` cannot be used with bincode,
42/// as bincode does not support the `deserialize_any()`.
43#[derive(Clone, Debug, Deserialize, Serialize)]
44pub struct VersionedHeader<Fields> {
45 pub(crate) version: EitherOrVersion,
46 pub(crate) fields: Fields,
47}