dpp/block/extended_epoch_info/
mod.rs1pub mod v0;
2
3use crate::block::epoch::EpochIndex;
4use crate::block::extended_epoch_info::v0::{ExtendedEpochInfoV0, ExtendedEpochInfoV0Getters};
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::util::deserializer::ProtocolVersion;
11use bincode::{Decode, DecodeUntrusted, Encode};
12use derive_more::From;
13use platform_serialization_derive::{
14 PlatformDeserializeTrusted, PlatformDeserializeUntrusted, PlatformSerialize,
15};
16use serde::{Deserialize, Serialize};
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 Serialize,
26 Deserialize,
27 Encode,
28 Decode,
29 PlatformSerialize,
30 PlatformDeserializeTrusted,
31 PlatformDeserializeUntrusted,
32 From,
33 DecodeUntrusted,
34)]
35#[platform_serialize(unversioned)] #[serde(tag = "$formatVersion")]
37pub enum ExtendedEpochInfo {
38 #[serde(rename = "0")]
39 V0(ExtendedEpochInfoV0),
40}
41
42impl ExtendedEpochInfoV0Getters for ExtendedEpochInfo {
43 fn index(&self) -> EpochIndex {
44 match self {
45 ExtendedEpochInfo::V0(v0) => v0.index,
46 }
47 }
48
49 fn first_block_time(&self) -> u64 {
50 match self {
51 ExtendedEpochInfo::V0(v0) => v0.first_block_time,
52 }
53 }
54
55 fn first_block_height(&self) -> u64 {
56 match self {
57 ExtendedEpochInfo::V0(v0) => v0.first_block_height,
58 }
59 }
60
61 fn first_core_block_height(&self) -> u32 {
62 match self {
63 ExtendedEpochInfo::V0(v0) => v0.first_core_block_height,
64 }
65 }
66
67 fn fee_multiplier_permille(&self) -> u64 {
68 match self {
69 ExtendedEpochInfo::V0(v0) => v0.fee_multiplier_permille,
70 }
71 }
72
73 fn protocol_version(&self) -> ProtocolVersion {
74 match self {
75 ExtendedEpochInfo::V0(v0) => v0.protocol_version,
76 }
77 }
78}
79
80#[cfg(all(test, feature = "json-conversion"))]
81mod tests {
82 use super::*;
83 use crate::serialization::JsonConvertible;
84
85 #[test]
86 fn extended_epoch_info_json_round_trip() {
87 let info = ExtendedEpochInfo::V0(ExtendedEpochInfoV0 {
88 index: 5,
89 first_block_time: 1_700_000_000_000u64,
90 first_block_height: 500_000u64,
91 first_core_block_height: 800_000u32,
92 fee_multiplier_permille: 1_500u64,
93 protocol_version: 4,
94 });
95
96 let json = info.to_json().expect("to_json should succeed");
97 assert!(json["firstBlockTime"].is_number());
98 assert_eq!(json["firstBlockTime"].as_u64().unwrap(), 1700000000000);
99 assert!(json["firstBlockHeight"].is_number());
100 assert_eq!(json["firstBlockHeight"].as_u64().unwrap(), 500000);
101 assert!(json["feeMultiplierPermille"].is_number());
102 assert_eq!(json["feeMultiplierPermille"].as_u64().unwrap(), 1500);
103 assert!(json["firstCoreBlockHeight"].is_number());
104 assert_eq!(json["firstCoreBlockHeight"].as_u64().unwrap(), 800_000);
105 assert!(json["protocolVersion"].is_number());
106 assert_eq!(json["protocolVersion"].as_u64().unwrap(), 4);
107
108 let restored = ExtendedEpochInfo::from_json(json).expect("from_json should succeed");
109 assert_eq!(info, restored);
110 }
111
112 #[test]
113 fn extended_epoch_info_value_round_trip() {
114 let info = ExtendedEpochInfo::V0(ExtendedEpochInfoV0 {
115 index: 10,
116 first_block_time: u64::MAX,
117 first_block_height: 0,
118 first_core_block_height: u32::MAX,
119 fee_multiplier_permille: 1_000,
120 protocol_version: 1,
121 });
122
123 let obj = info.to_object().expect("to_object should succeed");
124 let restored = ExtendedEpochInfo::from_object(obj).expect("from_object should succeed");
125 assert_eq!(info, restored);
126 }
127}
128
129#[cfg(all(
132 test,
133 feature = "json-conversion",
134 feature = "value-conversion",
135 feature = "serde-conversion"
136))]
137mod json_convertible_tests_extendedepochinfo {
138 use super::*;
139 use crate::block::extended_epoch_info::v0::ExtendedEpochInfoV0;
140 use platform_value::platform_value;
141 use serde_json::json;
142
143 fn fixture() -> ExtendedEpochInfo {
144 ExtendedEpochInfo::V0(ExtendedEpochInfoV0 {
145 index: 7,
146 first_block_time: 1_700_000_000_000,
147 first_block_height: 100,
148 first_core_block_height: 50,
149 fee_multiplier_permille: 1500,
150 protocol_version: 9,
151 })
152 }
153
154 #[test]
155 fn json_round_trip_with_full_wire_shape() {
156 use crate::serialization::JsonConvertible;
157 let original = fixture();
158 let json = original.to_json().expect("to_json");
159 assert_eq!(
164 json,
165 json!({
166 "$formatVersion": "0",
167 "index": 7,
168 "firstBlockTime": 1_700_000_000_000_u64,
169 "firstBlockHeight": 100,
170 "firstCoreBlockHeight": 50,
171 "feeMultiplierPermille": 1500,
172 "protocolVersion": 9,
173 })
174 );
175 let recovered = ExtendedEpochInfo::from_json(json).expect("from_json");
176 assert_eq!(original, recovered);
177 }
178
179 #[test]
180 fn value_round_trip_with_full_wire_shape() {
181 use crate::serialization::ValueConvertible;
182 let original = fixture();
183 let value = original.to_object().expect("to_object");
184 assert_eq!(
187 value,
188 platform_value!({
189 "$formatVersion": "0",
190 "index": 7u16,
191 "firstBlockTime": 1_700_000_000_000_u64,
192 "firstBlockHeight": 100u64,
193 "firstCoreBlockHeight": 50u32,
194 "feeMultiplierPermille": 1500u64,
195 "protocolVersion": 9u32,
196 })
197 );
198 let recovered = ExtendedEpochInfo::from_object(value).expect("from_object");
199 assert_eq!(original, recovered);
200 }
201}