casper_types/block/
block_body.rs1mod block_body_v1;
2mod block_body_v2;
3
4pub use block_body_v1::BlockBodyV1;
5pub use block_body_v2::BlockBodyV2;
6
7use alloc::vec::Vec;
8use core::fmt::{self, Display, Formatter};
9
10#[cfg(feature = "datasize")]
11use datasize::DataSize;
12use serde::{Deserialize, Serialize};
13
14use crate::bytesrepr::{self, FromBytes, ToBytes, U8_SERIALIZED_LENGTH};
15
16const TAG_LENGTH: usize = U8_SERIALIZED_LENGTH;
17
18pub const BLOCK_BODY_V1_TAG: u8 = 0;
20pub const BLOCK_BODY_V2_TAG: u8 = 1;
22
23#[cfg_attr(feature = "datasize", derive(DataSize))]
26#[cfg_attr(any(feature = "testing", test), derive(PartialEq))]
27#[derive(Clone, Serialize, Deserialize, Debug)]
28#[allow(clippy::large_enum_variant)]
29pub enum BlockBody {
30 #[serde(rename = "Version1")]
32 V1(BlockBodyV1),
33 #[serde(rename = "Version2")]
36 V2(BlockBodyV2),
37}
38
39impl Display for BlockBody {
40 fn fmt(&self, formatter: &mut Formatter) -> fmt::Result {
41 match self {
42 BlockBody::V1(v1) => Display::fmt(&v1, formatter),
43 BlockBody::V2(v2) => Display::fmt(&v2, formatter),
44 }
45 }
46}
47
48impl From<BlockBodyV1> for BlockBody {
49 fn from(body: BlockBodyV1) -> Self {
50 BlockBody::V1(body)
51 }
52}
53
54impl From<&BlockBodyV2> for BlockBody {
55 fn from(body: &BlockBodyV2) -> Self {
56 BlockBody::V2(body.clone())
57 }
58}
59
60impl ToBytes for BlockBody {
61 fn to_bytes(&self) -> Result<Vec<u8>, bytesrepr::Error> {
62 let mut buffer = bytesrepr::allocate_buffer(self)?;
63 match self {
64 BlockBody::V1(v1) => {
65 buffer.insert(0, BLOCK_BODY_V1_TAG);
66 buffer.extend(v1.to_bytes()?);
67 }
68 BlockBody::V2(v2) => {
69 buffer.insert(0, BLOCK_BODY_V2_TAG);
70 buffer.extend(v2.to_bytes()?);
71 }
72 }
73 Ok(buffer)
74 }
75
76 fn serialized_length(&self) -> usize {
77 TAG_LENGTH
78 + match self {
79 BlockBody::V1(v1) => v1.serialized_length(),
80 BlockBody::V2(v2) => v2.serialized_length(),
81 }
82 }
83}
84
85impl FromBytes for BlockBody {
86 fn from_bytes(bytes: &[u8]) -> Result<(Self, &[u8]), bytesrepr::Error> {
87 let (tag, remainder) = u8::from_bytes(bytes)?;
88 match tag {
89 BLOCK_BODY_V1_TAG => {
90 let (body, remainder): (BlockBodyV1, _) = FromBytes::from_bytes(remainder)?;
91 Ok((Self::V1(body), remainder))
92 }
93 BLOCK_BODY_V2_TAG => {
94 let (body, remainder): (BlockBodyV2, _) = FromBytes::from_bytes(remainder)?;
95 Ok((Self::V2(body), remainder))
96 }
97 _ => Err(bytesrepr::Error::Formatting),
98 }
99 }
100}
101
102#[cfg(test)]
103mod tests {
104 use crate::{bytesrepr, testing::TestRng, TestBlockBuilder, TestBlockV1Builder};
105
106 #[test]
107 fn bytesrepr_roundtrip() {
108 let rng = &mut TestRng::new();
109
110 let block_body_v1 = TestBlockV1Builder::new().build_versioned(rng).clone_body();
111 bytesrepr::test_serialization_roundtrip(&block_body_v1);
112
113 let block_body_v2 = TestBlockBuilder::new().build_versioned(rng).clone_body();
114 bytesrepr::test_serialization_roundtrip(&block_body_v2);
115 }
116}