dpp/block/extended_block_info/
mod.rs1use crate::block::block_info::BlockInfo;
2use crate::block::extended_block_info::v0::{
3 ExtendedBlockInfoV0, ExtendedBlockInfoV0Getters, ExtendedBlockInfoV0Setters,
4};
5use crate::protocol_error::ProtocolError;
6#[cfg(feature = "json-conversion")]
7use crate::serialization::JsonConvertible;
8#[cfg(feature = "value-conversion")]
9use crate::serialization::ValueConvertible;
10use crate::version::FeatureVersion;
11use bincode::{Decode, Encode};
12use derive_more::From;
13use platform_serialization_derive::{PlatformDeserialize, PlatformSerialize};
14use serde::{Deserialize, Serialize};
15
16pub mod v0;
17
18#[cfg_attr(feature = "json-conversion", derive(JsonConvertible))]
20#[cfg_attr(feature = "value-conversion", derive(ValueConvertible))]
21#[derive(
22 Clone,
23 Debug,
24 PartialEq,
25 Eq,
26 Serialize,
27 Deserialize,
28 Encode,
29 Decode,
30 PlatformSerialize,
31 PlatformDeserialize,
32 From,
33)]
34#[platform_serialize(unversioned)] #[serde(tag = "$formatVersion")]
36pub enum ExtendedBlockInfo {
37 #[serde(rename = "0")]
38 V0(ExtendedBlockInfoV0),
39}
40
41impl ExtendedBlockInfo {
42 pub fn version(&self) -> FeatureVersion {
45 match self {
46 ExtendedBlockInfo::V0(_) => 0,
47 }
48 }
49}
50
51impl ExtendedBlockInfoV0Getters for ExtendedBlockInfo {
52 fn basic_info(&self) -> &BlockInfo {
53 match self {
54 ExtendedBlockInfo::V0(v0) => &v0.basic_info,
55 }
56 }
57
58 fn basic_info_mut(&mut self) -> &mut BlockInfo {
59 match self {
60 ExtendedBlockInfo::V0(v0) => &mut v0.basic_info,
61 }
62 }
63
64 fn basic_info_owned(self) -> BlockInfo {
65 match self {
66 ExtendedBlockInfo::V0(v0) => v0.basic_info,
67 }
68 }
69
70 fn app_hash(&self) -> &[u8; 32] {
71 match self {
72 ExtendedBlockInfo::V0(v0) => &v0.app_hash,
73 }
74 }
75
76 fn quorum_hash(&self) -> &[u8; 32] {
77 match self {
78 ExtendedBlockInfo::V0(v0) => &v0.quorum_hash,
79 }
80 }
81
82 fn proposer_pro_tx_hash(&self) -> &[u8; 32] {
83 match self {
84 ExtendedBlockInfo::V0(v0) => &v0.proposer_pro_tx_hash,
85 }
86 }
87
88 fn block_id_hash(&self) -> &[u8; 32] {
89 match self {
90 ExtendedBlockInfo::V0(v0) => &v0.block_id_hash,
91 }
92 }
93
94 fn signature(&self) -> &[u8; 96] {
95 match self {
96 ExtendedBlockInfo::V0(v0) => &v0.signature,
97 }
98 }
99
100 fn round(&self) -> u32 {
101 match self {
102 ExtendedBlockInfo::V0(v0) => v0.round,
103 }
104 }
105}
106
107impl ExtendedBlockInfoV0Setters for ExtendedBlockInfo {
108 fn set_basic_info(&mut self, info: BlockInfo) {
109 match self {
110 ExtendedBlockInfo::V0(v0) => {
111 v0.set_basic_info(info);
112 }
113 }
114 }
115
116 fn set_app_hash(&mut self, hash: [u8; 32]) {
117 match self {
118 ExtendedBlockInfo::V0(v0) => {
119 v0.set_app_hash(hash);
120 }
121 }
122 }
123
124 fn set_quorum_hash(&mut self, hash: [u8; 32]) {
125 match self {
126 ExtendedBlockInfo::V0(v0) => {
127 v0.set_quorum_hash(hash);
128 }
129 }
130 }
131
132 fn set_signature(&mut self, signature: [u8; 96]) {
133 match self {
134 ExtendedBlockInfo::V0(v0) => {
135 v0.set_signature(signature);
136 }
137 }
138 }
139
140 fn set_round(&mut self, round: u32) {
141 match self {
142 ExtendedBlockInfo::V0(v0) => {
143 v0.set_round(round);
144 }
145 }
146 }
147}
148
149#[cfg(test)]
150mod tests {
151 use super::*;
152 use crate::block::block_info::BlockInfo;
153 use crate::serialization::{PlatformDeserializable, PlatformSerializable};
154
155 #[test]
156 fn test_extended_block_info_bincode() {
157 let block_info: ExtendedBlockInfo = ExtendedBlockInfoV0 {
158 basic_info: BlockInfo::default(),
159 app_hash: [1; 32],
160 quorum_hash: [2; 32],
161 block_id_hash: [3; 32],
162 proposer_pro_tx_hash: [4; 32],
163 signature: [3; 96],
164 round: 1,
165 }
166 .into();
167
168 let encoded =
170 PlatformSerializable::serialize_to_bytes(&block_info).expect("expected to serialize");
171
172 let decoded: ExtendedBlockInfo = PlatformDeserializable::deserialize_from_bytes(&encoded)
174 .expect("expected to deserialize");
175
176 assert_eq!(block_info, decoded);
177 }
178}
179
180#[cfg(all(
183 test,
184 feature = "json-conversion",
185 feature = "value-conversion",
186 feature = "serde-conversion"
187))]
188mod json_convertible_tests_extendedblockinfo {
189 use super::*;
190 use crate::block::block_info::BlockInfo;
191 use crate::block::extended_block_info::v0::ExtendedBlockInfoV0;
192 use platform_value::platform_value;
193 use serde_json::json;
194
195 fn fixture() -> ExtendedBlockInfo {
196 ExtendedBlockInfo::V0(ExtendedBlockInfoV0 {
197 basic_info: BlockInfo::default(),
198 app_hash: [0x11; 32],
199 quorum_hash: [0x22; 32],
200 block_id_hash: [0x33; 32],
201 proposer_pro_tx_hash: [0x44; 32],
202 signature: [0x55; 96],
203 round: 3,
204 })
205 }
206
207 #[test]
208 fn json_round_trip_with_full_wire_shape() {
209 use crate::serialization::JsonConvertible;
210 let original = fixture();
211 let json = original.to_json().expect("to_json");
212 assert_eq!(
218 json,
219 json!({
220 "$formatVersion": "0",
221 "basicInfo": {
222 "timeMs": 0,
223 "height": 0,
224 "coreHeight": 0,
225 "epoch": {"index": 0},
226 },
227 "appHash": "ERERERERERERERERERERERERERERERERERERERERERE=",
228 "quorumHash": "IiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiI=",
229 "blockIdHash": "MzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzM=",
230 "proposerProTxHash": "REREREREREREREREREREREREREREREREREREREREREQ=",
231 "signature": "VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV",
232 "round": 3,
233 })
234 );
235 let recovered = ExtendedBlockInfo::from_json(json).expect("from_json");
236 assert_eq!(original, recovered);
237 }
238
239 #[test]
240 fn value_round_trip_with_full_wire_shape() {
241 use crate::serialization::ValueConvertible;
242 use platform_value::Value;
243 let original = fixture();
244 let value = original.to_object().expect("to_object");
245 assert_eq!(
249 value,
250 platform_value!({
251 "$formatVersion": "0",
252 "basicInfo": {
253 "timeMs": 0u64,
254 "height": 0u64,
255 "coreHeight": 0u32,
256 "epoch": {"index": 0u16},
257 },
258 "appHash": Value::Bytes32([0x11; 32]),
259 "quorumHash": Value::Bytes32([0x22; 32]),
260 "blockIdHash": Value::Bytes32([0x33; 32]),
261 "proposerProTxHash": Value::Bytes32([0x44; 32]),
262 "signature": Value::Bytes(vec![0x55; 96]),
263 "round": 3u32,
264 })
265 );
266 let recovered = ExtendedBlockInfo::from_object(value).expect("from_object");
267 assert_eq!(original, recovered);
268 }
269}