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}