dpp/block/finalized_epoch_info/
mod.rs

1mod getters;
2pub mod v0;
3
4use crate::block::finalized_epoch_info::v0::FinalizedEpochInfoV0;
5use crate::protocol_error::ProtocolError;
6#[cfg(feature = "json-conversion")]
7use crate::serialization::JsonConvertible;
8#[cfg(feature = "value-conversion")]
9use crate::serialization::ValueConvertible;
10use bincode::{Decode, Encode};
11use derive_more::From;
12use platform_serialization_derive::{PlatformDeserialize, PlatformSerialize};
13use serde::{Deserialize, Serialize};
14
15/// Finalized Epoch information
16#[cfg_attr(feature = "json-conversion", derive(JsonConvertible))]
17#[cfg_attr(feature = "value-conversion", derive(ValueConvertible))]
18#[derive(
19    Clone,
20    Debug,
21    PartialEq,
22    Serialize,
23    Deserialize,
24    Encode,
25    Decode,
26    PlatformSerialize,
27    PlatformDeserialize,
28    From,
29)]
30#[platform_serialize(unversioned)] //versioned directly, no need to use platform_version
31#[serde(tag = "$formatVersion")]
32pub enum FinalizedEpochInfo {
33    #[serde(rename = "0")]
34    V0(FinalizedEpochInfoV0),
35}
36
37#[cfg(all(test, feature = "json-conversion"))]
38mod tests {
39    use super::*;
40    use crate::serialization::JsonConvertible;
41    use platform_value::Identifier;
42    use std::collections::BTreeMap;
43
44    #[test]
45    fn finalized_epoch_info_json_round_trip() {
46        let proposer_id = Identifier::from([1u8; 32]);
47        let mut block_proposers = BTreeMap::new();
48        block_proposers.insert(proposer_id, 42u64);
49
50        let info = FinalizedEpochInfo::V0(FinalizedEpochInfoV0 {
51            first_block_time: 1_700_000_000_000u64,
52            first_block_height: 100_000u64,
53            total_blocks_in_epoch: 2_000u64,
54            first_core_block_height: 500_000u32,
55            next_epoch_start_core_block_height: 500_200u32,
56            total_processing_fees: 1_000_000u64,
57            total_distributed_storage_fees: 500_000u64,
58            total_created_storage_fees: 600_000u64,
59            core_block_rewards: 10_000_000u64,
60            block_proposers,
61            fee_multiplier_permille: 1_000u64,
62            protocol_version: 3,
63        });
64
65        let json = info.to_json().expect("to_json should succeed");
66        assert!(json["firstBlockTime"].is_number());
67        assert!(json["firstBlockHeight"].is_number());
68        assert!(json["totalBlocksInEpoch"].is_number());
69        assert!(json["totalProcessingFees"].is_number());
70        assert!(json["feeMultiplierPermille"].is_number());
71        assert!(json["firstCoreBlockHeight"].is_number());
72        assert!(json["nextEpochStartCoreBlockHeight"].is_number());
73
74        let proposers = json["blockProposers"]
75            .as_object()
76            .expect("blockProposers should be an object");
77        assert_eq!(proposers.len(), 1);
78
79        let expected_base58 =
80            proposer_id.to_string(platform_value::string_encoding::Encoding::Base58);
81        assert!(
82            proposers.contains_key(&expected_base58),
83            "Expected key {} in blockProposers, got keys: {:?}",
84            expected_base58,
85            proposers.keys().collect::<Vec<_>>()
86        );
87
88        let value = &proposers[&expected_base58];
89        assert!(value.is_number());
90        assert_eq!(value.as_u64().unwrap(), 42);
91
92        let restored = FinalizedEpochInfo::from_json(json).expect("from_json should succeed");
93        assert_eq!(info, restored);
94    }
95
96    #[test]
97    fn finalized_epoch_info_value_round_trip_empty_proposers() {
98        let info = FinalizedEpochInfo::V0(FinalizedEpochInfoV0 {
99            first_block_time: 1_000_000u64,
100            first_block_height: 10_000u64,
101            total_blocks_in_epoch: 500u64,
102            first_core_block_height: 50_000u32,
103            next_epoch_start_core_block_height: 50_200u32,
104            total_processing_fees: 100u64,
105            total_distributed_storage_fees: 50u64,
106            total_created_storage_fees: 60u64,
107            core_block_rewards: 1_000u64,
108            block_proposers: BTreeMap::new(),
109            fee_multiplier_permille: 1_000u64,
110            protocol_version: 2,
111        });
112
113        let obj = info.to_object().expect("to_object should succeed");
114        let restored = FinalizedEpochInfo::from_object(obj).expect("from_object should succeed");
115        assert_eq!(info, restored);
116    }
117}