casper_types/chainspec/
activation_point.rs1use std::fmt::{self, Display, Formatter};
2
3#[cfg(feature = "datasize")]
4use datasize::DataSize;
5#[cfg(any(feature = "testing", test))]
6use rand::Rng;
7#[cfg(feature = "json-schema")]
8use schemars::JsonSchema;
9use serde::{Deserialize, Serialize};
10
11#[cfg(any(feature = "testing", test))]
12use crate::testing::TestRng;
13use crate::{
14 bytesrepr::{self, FromBytes, ToBytes, U8_SERIALIZED_LENGTH},
15 EraId, TimeDiff, Timestamp,
16};
17
18const ERA_ID_TAG: u8 = 0;
19const GENESIS_TAG: u8 = 1;
20
21#[derive(Copy, Clone, PartialEq, Eq, Serialize, Deserialize, Debug)]
23#[cfg_attr(feature = "datasize", derive(DataSize))]
24#[cfg_attr(feature = "json-schema", derive(JsonSchema))]
25#[serde(untagged)]
26pub enum ActivationPoint {
27 EraId(EraId),
29 Genesis(Timestamp),
31}
32
33impl ActivationPoint {
34 pub fn should_upgrade(&self, era_being_deactivated: &EraId) -> bool {
37 match self {
38 ActivationPoint::EraId(era_id) => era_being_deactivated.successor() >= *era_id,
39 ActivationPoint::Genesis(_) => false,
40 }
41 }
42
43 pub fn era_id(&self) -> EraId {
45 match self {
46 ActivationPoint::EraId(era_id) => *era_id,
47 ActivationPoint::Genesis(_) => EraId::from(0),
48 }
49 }
50
51 pub fn genesis_timestamp(&self) -> Option<Timestamp> {
53 match self {
54 ActivationPoint::EraId(_) => None,
55 ActivationPoint::Genesis(timestamp) => Some(*timestamp),
56 }
57 }
58
59 #[cfg(any(feature = "testing", test))]
61 pub fn random(rng: &mut TestRng) -> Self {
62 if rng.gen() {
63 ActivationPoint::EraId(EraId::random(rng))
64 } else {
65 ActivationPoint::Genesis(Timestamp::random(rng))
66 }
67 }
68}
69
70impl Default for ActivationPoint {
71 fn default() -> Self {
72 ActivationPoint::Genesis(Timestamp::now().saturating_add(TimeDiff::from_seconds(15)))
73 }
74}
75
76impl Display for ActivationPoint {
77 fn fmt(&self, formatter: &mut Formatter<'_>) -> fmt::Result {
78 match self {
79 ActivationPoint::EraId(era_id) => write!(formatter, "activation point {}", era_id),
80 ActivationPoint::Genesis(timestamp) => {
81 write!(formatter, "activation point {}", timestamp)
82 }
83 }
84 }
85}
86
87impl ToBytes for ActivationPoint {
88 fn to_bytes(&self) -> Result<Vec<u8>, bytesrepr::Error> {
89 match self {
90 ActivationPoint::EraId(era_id) => {
91 let mut buffer = vec![ERA_ID_TAG];
92 buffer.extend(era_id.to_bytes()?);
93 Ok(buffer)
94 }
95 ActivationPoint::Genesis(timestamp) => {
96 let mut buffer = vec![GENESIS_TAG];
97 buffer.extend(timestamp.to_bytes()?);
98 Ok(buffer)
99 }
100 }
101 }
102
103 fn serialized_length(&self) -> usize {
104 U8_SERIALIZED_LENGTH
105 + match self {
106 ActivationPoint::EraId(era_id) => era_id.serialized_length(),
107 ActivationPoint::Genesis(timestamp) => timestamp.serialized_length(),
108 }
109 }
110}
111
112impl FromBytes for ActivationPoint {
113 fn from_bytes(bytes: &[u8]) -> Result<(Self, &[u8]), bytesrepr::Error> {
114 let (tag, remainder) = u8::from_bytes(bytes)?;
115 match tag {
116 ERA_ID_TAG => {
117 let (era_id, remainder) = EraId::from_bytes(remainder)?;
118 Ok((ActivationPoint::EraId(era_id), remainder))
119 }
120 GENESIS_TAG => {
121 let (timestamp, remainder) = Timestamp::from_bytes(remainder)?;
122 Ok((ActivationPoint::Genesis(timestamp), remainder))
123 }
124 _ => Err(bytesrepr::Error::Formatting),
125 }
126 }
127}