cardano_sdk/chain/
header.rs

1use crate::protocol::Point;
2
3use super::byron;
4use super::common::*;
5use super::hash::HeaderHash;
6use cbored::CborRepr;
7use cbored::Encode;
8use cryptoxide::hashing::blake2b_256;
9
10#[derive(Clone, Debug, PartialEq, Eq)]
11pub enum Header {
12    Shelley(HeaderShelley),
13    Vasil(HeaderVasil),
14}
15
16#[derive(Clone, Debug, PartialEq, Eq)]
17pub enum HeaderCompat {
18    Byron(byron::Header),
19    Shelley(HeaderShelley),
20    Vasil(HeaderVasil),
21}
22
23#[derive(Clone, Debug, PartialEq, Eq)]
24pub enum HeaderRef<'a> {
25    Shelley(&'a HeaderShelley),
26    Vasil(&'a HeaderVasil),
27}
28
29#[derive(Clone, Debug, CborRepr, PartialEq, Eq)]
30#[cborrepr(structure = "array")]
31pub struct HeaderShelley {
32    pub body: HeaderBodyShelley,
33    pub sig: Bytes,
34}
35
36#[derive(Clone, Debug, CborRepr, PartialEq, Eq)]
37#[cborrepr(structure = "array")]
38pub struct HeaderVasil {
39    pub body: HeaderBodyVasil,
40    pub sig: Bytes,
41}
42
43#[derive(Clone, Debug, CborRepr, PartialEq, Eq)]
44#[cborrepr(structure = "array")]
45pub struct HeaderBodyShelley {
46    pub block_number: u64,
47    pub slot: u64,
48    pub prev_hash: Nullable<HeaderHash>,
49    pub issuer_vkey: Bytes,
50    pub vrf_vkey: Bytes,
51    pub nonce_vrf: VrfCert,
52    pub leader_vrf: VrfCert,
53    pub block_body_size: u64,
54    pub block_body_hash: Bytes,
55    pub op_cert_hot_vkey: Bytes,
56    pub op_cert_sequence_number: u64,
57    pub op_cert_kes_period: u64,
58    pub op_cert_sigma: Bytes,
59    pub protocol_version_major: u64,
60    pub protocol_version_minor: u64,
61}
62
63#[derive(Clone, Debug, CborRepr, PartialEq, Eq)]
64#[cborrepr(structure = "array")]
65pub struct HeaderBodyVasil {
66    pub block_number: u64,
67    pub slot: u64,
68    pub prev_hash: Nullable<HeaderHash>,
69    pub issuer_vkey: Bytes,
70    pub vrf_vkey: Bytes,
71    pub vrf: VrfCert,
72    pub block_body_size: u64,
73    pub block_body_hash: Bytes,
74    pub op_cert: OpCert,
75    pub protocol_version: ProtocolVersion,
76}
77
78#[derive(Clone, Debug, CborRepr, PartialEq, Eq)]
79#[cborrepr(structure = "array")]
80pub struct ProtocolVersion {
81    pub major: u64,
82    pub minor: u64,
83}
84
85#[derive(Clone, Debug, CborRepr, PartialEq, Eq)]
86#[cborrepr(structure = "array")]
87pub struct OpCert {
88    pub hot_vkey: Bytes,
89    pub sequence_number: u64,
90    pub kes_period: u64,
91    pub sigma: Bytes,
92}
93
94#[derive(Clone, Debug, CborRepr, PartialEq, Eq)]
95#[cborrepr(structure = "array")]
96pub struct VrfCert {
97    pub cert: Bytes,
98    pub proof: Bytes,
99}
100
101impl HeaderVasil {
102    pub fn hash(&self) -> HeaderHash {
103        let mut writer = cbored::Writer::new();
104        self.encode(&mut writer);
105        let data = writer.finalize();
106        HeaderHash(blake2b_256(&data))
107    }
108
109    pub fn point(&self) -> Point {
110        Point::BlockHeader {
111            slot_nb: self.body.slot,
112            hash: self.hash(),
113        }
114    }
115}
116
117impl HeaderShelley {
118    pub fn hash(&self) -> HeaderHash {
119        let mut writer = cbored::Writer::new();
120        self.encode(&mut writer);
121        let data = writer.finalize();
122        HeaderHash(blake2b_256(&data))
123    }
124
125    pub fn point(&self) -> Point {
126        Point::BlockHeader {
127            slot_nb: self.body.slot,
128            hash: self.hash(),
129        }
130    }
131}
132
133impl Header {
134    pub fn hash(&self) -> HeaderHash {
135        match self {
136            Header::Shelley(h) => h.hash(),
137            Header::Vasil(h) => h.hash(),
138        }
139    }
140    pub fn point(&self) -> Point {
141        match self {
142            Header::Shelley(h) => h.point(),
143            Header::Vasil(h) => h.point(),
144        }
145    }
146    pub fn block_number(&self) -> u64 {
147        match self {
148            Header::Shelley(h) => h.body.block_number,
149            Header::Vasil(h) => h.body.block_number,
150        }
151    }
152    pub fn prev_hash(&self) -> &Nullable<HeaderHash> {
153        match self {
154            Header::Shelley(h) => &h.body.prev_hash,
155            Header::Vasil(h) => &h.body.prev_hash,
156        }
157    }
158    pub fn slot(&self) -> u64 {
159        match self {
160            Header::Shelley(h) => h.body.slot,
161            Header::Vasil(h) => h.body.slot,
162        }
163    }
164}
165
166impl HeaderCompat {
167    pub fn hash(&self) -> HeaderHash {
168        match self {
169            Self::Byron(h) => h.hash(),
170            Self::Shelley(h) => h.hash(),
171            Self::Vasil(h) => h.hash(),
172        }
173    }
174
175    pub fn point(&self) -> Point {
176        let h = self.hash();
177        Point::BlockHeader {
178            slot_nb: 0,
179            hash: h,
180        }
181    }
182
183    pub fn block_number(&self) -> u64 {
184        match self {
185            Self::Byron(h) => h.consensus.chain_difficulty.0,
186            Self::Shelley(h) => h.body.block_number,
187            Self::Vasil(h) => h.body.block_number,
188        }
189    }
190}
191
192impl<'a> HeaderRef<'a> {
193    pub fn hash(&self) -> HeaderHash {
194        match self {
195            HeaderRef::Shelley(h) => h.hash(),
196            HeaderRef::Vasil(h) => h.hash(),
197        }
198    }
199    pub fn point(&self) -> Point {
200        match self {
201            HeaderRef::Shelley(h) => h.point(),
202            HeaderRef::Vasil(h) => h.point(),
203        }
204    }
205    pub fn block_number(&self) -> u64 {
206        match self {
207            HeaderRef::Shelley(h) => h.body.block_number,
208            HeaderRef::Vasil(h) => h.body.block_number,
209        }
210    }
211    pub fn slot(&self) -> u64 {
212        match self {
213            HeaderRef::Shelley(h) => h.body.slot,
214            HeaderRef::Vasil(h) => h.body.slot,
215        }
216    }
217    pub fn prev_hash(&self) -> &Nullable<HeaderHash> {
218        match self {
219            HeaderRef::Shelley(h) => &h.body.prev_hash,
220            HeaderRef::Vasil(h) => &h.body.prev_hash,
221        }
222    }
223}
224
225impl From<HeaderVasil> for Header {
226    fn from(h: HeaderVasil) -> Header {
227        Header::Vasil(h)
228    }
229}
230
231impl From<HeaderShelley> for Header {
232    fn from(h: HeaderShelley) -> Header {
233        Header::Shelley(h)
234    }
235}