1pub mod v1;
2pub mod v2;
3
4use std::fmt::{self, Display, Formatter};
5
6use schemars::JsonSchema;
7use serde::{Deserialize, Serialize};
8
9use casper_hashing::Digest;
10use casper_types::{
11 bytesrepr::{self, ToBytes},
12 crypto::PublicKey,
13 EraId, ProtocolVersion,
14};
15
16#[cfg(doc)]
17use crate::types::{validate_block_hashes_v1, validate_block_hashes_v2};
18use crate::types::{DeployHash, EraEnd, Proof, Timestamp};
19
20#[derive(
30 Copy,
31 Clone,
32 Default,
33 PartialOrd,
34 Ord,
35 PartialEq,
36 Eq,
37 Hash,
38 Serialize,
39 Deserialize,
40 Debug,
41 JsonSchema,
42)]
43#[serde(deny_unknown_fields)]
44pub struct BlockHash(Digest);
45
46impl BlockHash {
47 pub fn new(digest: Digest) -> Self {
49 BlockHash(digest)
50 }
51
52 pub fn inner(&self) -> Digest {
54 self.0
55 }
56}
57
58impl Display for BlockHash {
59 fn fmt(&self, formatter: &mut Formatter) -> fmt::Result {
60 write!(formatter, "{}", self.0)
61 }
62}
63
64impl ToBytes for BlockHash {
65 fn write_bytes(&self, buffer: &mut Vec<u8>) -> Result<(), bytesrepr::Error> {
66 self.0.write_bytes(buffer)
67 }
68
69 fn to_bytes(&self) -> Result<Vec<u8>, bytesrepr::Error> {
70 self.0.to_bytes()
71 }
72
73 fn serialized_length(&self) -> usize {
74 self.0.serialized_length()
75 }
76}
77
78#[derive(Clone, PartialOrd, Ord, PartialEq, Eq, Hash, Serialize, Deserialize, Debug)]
80#[serde(deny_unknown_fields)]
81pub struct BlockHeader {
82 parent_hash: BlockHash,
83 state_root_hash: Digest,
84 body_hash: Digest,
85 random_bit: bool,
86 accumulated_seed: Digest,
87 era_end: Option<EraEnd>,
88 timestamp: Timestamp,
89 era_id: EraId,
90 height: u64,
91 protocol_version: ProtocolVersion,
92}
93
94impl BlockHeader {
95 pub fn parent_hash(&self) -> BlockHash {
97 self.parent_hash
98 }
99
100 pub fn state_root_hash(&self) -> Digest {
102 self.state_root_hash
103 }
104
105 pub fn body_hash(&self) -> Digest {
112 self.body_hash
113 }
114
115 pub fn random_bit(&self) -> bool {
117 self.random_bit
118 }
119
120 pub fn accumulated_seed(&self) -> Digest {
122 self.accumulated_seed
123 }
124
125 pub fn era_end(&self) -> Option<&EraEnd> {
128 self.era_end.as_ref()
129 }
130
131 pub fn timestamp(&self) -> Timestamp {
133 self.timestamp
134 }
135
136 pub fn era_id(&self) -> EraId {
138 self.era_id
139 }
140
141 pub fn height(&self) -> u64 {
143 self.height
144 }
145
146 pub fn protocol_version(&self) -> ProtocolVersion {
148 self.protocol_version
149 }
150}
151
152impl Display for BlockHeader {
153 fn fmt(&self, formatter: &mut Formatter) -> fmt::Result {
154 write!(
155 formatter,
156 "block header {{ parent hash {}, post-state hash {}, body hash {}, \
157 random bit {}, accumulated seed {}, timestamp {} }}",
158 self.parent_hash.0,
159 self.state_root_hash,
160 self.body_hash,
161 self.random_bit,
162 self.accumulated_seed,
163 self.timestamp,
164 )?;
165 if let Some(era_end) = &self.era_end {
166 write!(formatter, ", era_end {}", era_end)?;
167 }
168 Ok(())
169 }
170}
171
172impl ToBytes for BlockHeader {
173 fn write_bytes(&self, buffer: &mut Vec<u8>) -> Result<(), bytesrepr::Error> {
174 self.parent_hash.write_bytes(buffer)?;
175 self.state_root_hash.write_bytes(buffer)?;
176 self.body_hash.write_bytes(buffer)?;
177 self.random_bit.write_bytes(buffer)?;
178 self.accumulated_seed.write_bytes(buffer)?;
179 self.era_end.write_bytes(buffer)?;
180 self.timestamp.write_bytes(buffer)?;
181 self.era_id.write_bytes(buffer)?;
182 self.height.write_bytes(buffer)?;
183 self.protocol_version.write_bytes(buffer)
184 }
185
186 fn to_bytes(&self) -> Result<Vec<u8>, bytesrepr::Error> {
187 let mut buffer = vec![];
188 self.write_bytes(&mut buffer)?;
189 Ok(buffer)
190 }
191
192 fn serialized_length(&self) -> usize {
193 self.parent_hash.serialized_length()
194 + self.state_root_hash.serialized_length()
195 + self.body_hash.serialized_length()
196 + self.random_bit.serialized_length()
197 + self.accumulated_seed.serialized_length()
198 + self.era_end.serialized_length()
199 + self.timestamp.serialized_length()
200 + self.era_id.serialized_length()
201 + self.height.serialized_length()
202 + self.protocol_version.serialized_length()
203 }
204}
205
206#[derive(Clone, PartialOrd, Ord, PartialEq, Eq, Hash, Serialize, Deserialize, Debug)]
208#[serde(deny_unknown_fields)]
209pub struct BlockBody {
210 proposer: PublicKey,
211 deploy_hashes: Vec<DeployHash>,
212 transfer_hashes: Vec<DeployHash>,
213}
214
215impl BlockBody {
216 pub fn proposer(&self) -> &PublicKey {
218 &self.proposer
219 }
220
221 pub fn deploy_hashes(&self) -> impl Iterator<Item = &DeployHash> {
223 self.deploy_hashes.iter()
224 }
225
226 pub fn transfer_hashes(&self) -> impl Iterator<Item = &DeployHash> {
228 self.transfer_hashes.iter()
229 }
230}
231
232impl Display for BlockBody {
233 fn fmt(&self, formatter: &mut Formatter) -> fmt::Result {
234 write!(formatter, "{:?}", self)
235 }
236}
237
238impl ToBytes for BlockBody {
239 fn write_bytes(&self, buffer: &mut Vec<u8>) -> Result<(), bytesrepr::Error> {
240 self.proposer.write_bytes(buffer)?;
241 self.deploy_hashes.write_bytes(buffer)?;
242 self.transfer_hashes.write_bytes(buffer)
243 }
244
245 fn to_bytes(&self) -> Result<Vec<u8>, bytesrepr::Error> {
246 let mut buffer = vec![];
247 self.write_bytes(&mut buffer)?;
248 Ok(buffer)
249 }
250
251 fn serialized_length(&self) -> usize {
252 self.proposer.serialized_length()
253 + self.deploy_hashes.serialized_length()
254 + self.transfer_hashes.serialized_length()
255 }
256}
257
258#[derive(Clone, PartialOrd, Ord, PartialEq, Eq, Hash, Serialize, Deserialize, Debug)]
260#[serde(deny_unknown_fields)]
261pub struct Block {
262 hash: BlockHash,
263 header: BlockHeader,
264 body: BlockBody,
265 proofs: Vec<Proof>,
266}
267
268impl Block {
269 pub fn hash(&self) -> &BlockHash {
276 &self.hash
277 }
278
279 pub fn header(&self) -> &BlockHeader {
281 &self.header
282 }
283
284 pub fn body(&self) -> &BlockBody {
286 &self.body
287 }
288
289 pub fn proofs(&self) -> impl Iterator<Item = &Proof> {
291 self.proofs.iter()
292 }
293}
294
295impl Display for Block {
296 fn fmt(&self, formatter: &mut Formatter<'_>) -> fmt::Result {
297 write!(
298 formatter,
299 "block {{ {}, parent hash {}, post-state hash {}, body hash {}, \
300 random bit {}, timestamp {}, {}, height {}, protocol version: {} }}",
301 self.hash,
302 self.header.parent_hash,
303 self.header.state_root_hash,
304 self.header.body_hash,
305 self.header.random_bit,
306 self.header.timestamp,
307 self.header.era_id,
308 self.header.height,
309 self.header.protocol_version
310 )?;
311 if let Some(era_end) = &self.header.era_end {
312 write!(formatter, ", era-end: {}", era_end)?;
313 }
314 Ok(())
315 }
316}
317
318impl ToBytes for Block {
319 fn write_bytes(&self, buffer: &mut Vec<u8>) -> Result<(), bytesrepr::Error> {
320 self.hash.write_bytes(buffer)?;
322 self.header.write_bytes(buffer)?;
323 self.body.write_bytes(buffer)
324 }
325
326 fn to_bytes(&self) -> Result<Vec<u8>, bytesrepr::Error> {
327 let mut buffer = vec![];
328 self.write_bytes(&mut buffer)?;
329 Ok(buffer)
330 }
331
332 fn serialized_length(&self) -> usize {
333 self.hash.serialized_length()
334 + self.header.serialized_length()
335 + self.body.serialized_length()
336 }
337}
338
339#[derive(Clone, Copy, Default, Eq, JsonSchema, Serialize, Deserialize, Debug, PartialEq)]
341pub struct BlockHashAndHeight {
342 #[schemars(description = "The hash of this deploy's block.")]
344 pub block_hash: BlockHash,
345 #[schemars(description = "The height of this deploy's block.")]
347 pub block_height: u64,
348}