casper_types/chainspec/
protocol_config.rs1#[cfg(feature = "datasize")]
2use datasize::DataSize;
3#[cfg(any(feature = "testing", test))]
4use rand::Rng;
5use serde::{Deserialize, Serialize};
6use std::{collections::BTreeMap, str::FromStr};
7
8#[cfg(any(feature = "testing", test))]
9use crate::testing::TestRng;
10use crate::{
11 bytesrepr::{self, FromBytes, ToBytes},
12 Key, ProtocolVersion, StoredValue, Timestamp,
13};
14
15use crate::{ActivationPoint, GlobalStateUpdate};
16
17#[derive(Clone, PartialEq, Eq, Serialize, Deserialize, Debug)]
19#[cfg_attr(feature = "datasize", derive(DataSize))]
20pub struct ProtocolConfig {
21 #[cfg_attr(feature = "datasize", data_size(skip))]
23 pub version: ProtocolVersion,
24 pub hard_reset: bool,
27 pub activation_point: ActivationPoint,
29 pub global_state_update: Option<GlobalStateUpdate>,
32}
33
34impl ProtocolConfig {
35 pub(crate) fn get_update_mapping(
38 &self,
39 ) -> Result<BTreeMap<Key, StoredValue>, bytesrepr::Error> {
40 let state_update = match &self.global_state_update {
41 Some(GlobalStateUpdate { entries, .. }) => entries,
42 None => return Ok(BTreeMap::default()),
43 };
44 let mut update_mapping = BTreeMap::new();
45 for (key, stored_value_bytes) in state_update {
46 let stored_value = bytesrepr::deserialize(stored_value_bytes.clone().into())?;
47 update_mapping.insert(*key, stored_value);
48 }
49 Ok(update_mapping)
50 }
51
52 #[cfg(any(feature = "testing", test))]
54 pub fn random(rng: &mut TestRng) -> Self {
55 let protocol_version = ProtocolVersion::from_parts(
56 rng.gen_range(0..10),
57 rng.gen::<u8>() as u32,
58 rng.gen::<u8>() as u32,
59 );
60 let activation_point = ActivationPoint::random(rng);
61
62 ProtocolConfig {
63 version: protocol_version,
64 hard_reset: rng.gen(),
65 activation_point,
66 global_state_update: None,
67 }
68 }
69}
70
71impl ToBytes for ProtocolConfig {
72 fn to_bytes(&self) -> Result<Vec<u8>, bytesrepr::Error> {
73 let mut buffer = bytesrepr::allocate_buffer(self)?;
74 buffer.extend(self.version.to_string().to_bytes()?);
75 buffer.extend(self.hard_reset.to_bytes()?);
76 buffer.extend(self.activation_point.to_bytes()?);
77 buffer.extend(self.global_state_update.to_bytes()?);
78 Ok(buffer)
79 }
80
81 fn serialized_length(&self) -> usize {
82 self.version.to_string().serialized_length()
83 + self.hard_reset.serialized_length()
84 + self.activation_point.serialized_length()
85 + self.global_state_update.serialized_length()
86 }
87}
88
89impl FromBytes for ProtocolConfig {
90 fn from_bytes(bytes: &[u8]) -> Result<(Self, &[u8]), bytesrepr::Error> {
91 let (protocol_version_string, remainder) = String::from_bytes(bytes)?;
92 let version = ProtocolVersion::from_str(&protocol_version_string)
93 .map_err(|_| bytesrepr::Error::Formatting)?;
94 let (hard_reset, remainder) = bool::from_bytes(remainder)?;
95 let (activation_point, remainder) = ActivationPoint::from_bytes(remainder)?;
96 let (global_state_update, remainder) = Option::<GlobalStateUpdate>::from_bytes(remainder)?;
97 let protocol_config = ProtocolConfig {
98 version,
99 hard_reset,
100 activation_point,
101 global_state_update,
102 };
103 Ok((protocol_config, remainder))
104 }
105}
106
107impl Default for ProtocolConfig {
108 fn default() -> Self {
109 ProtocolConfig {
110 activation_point: ActivationPoint::Genesis(Timestamp::now()),
111 global_state_update: None,
112 hard_reset: true,
113 version: ProtocolVersion::V2_0_0,
114 }
115 }
116}
117
118#[cfg(test)]
119mod tests {
120 use super::*;
121 use rand::SeedableRng;
122
123 #[test]
124 fn activation_point_bytesrepr_roundtrip() {
125 let mut rng = TestRng::from_entropy();
126 let activation_point = ActivationPoint::random(&mut rng);
127 bytesrepr::test_serialization_roundtrip(&activation_point);
128 }
129
130 #[test]
131 fn protocol_config_bytesrepr_roundtrip() {
132 let mut rng = TestRng::from_entropy();
133 let config = ProtocolConfig::random(&mut rng);
134 bytesrepr::test_serialization_roundtrip(&config);
135 }
136}