casper_types/
block_time.rs

1use alloc::vec::Vec;
2
3use crate::{
4    bytesrepr::{Error, FromBytes, ToBytes, U64_SERIALIZED_LENGTH},
5    CLType, CLTyped, TimeDiff, Timestamp,
6};
7
8#[cfg(feature = "datasize")]
9use datasize::DataSize;
10#[cfg(feature = "json-schema")]
11use schemars::JsonSchema;
12use serde::{Deserialize, Serialize};
13
14/// The number of bytes in a serialized [`BlockTime`].
15pub const BLOCKTIME_SERIALIZED_LENGTH: usize = U64_SERIALIZED_LENGTH;
16
17/// Holds epoch type.
18#[derive(Debug, Copy, Clone, PartialEq, Eq, Default)]
19pub struct HoldsEpoch(Option<u64>);
20
21impl HoldsEpoch {
22    /// No epoch is applicable.
23    pub const NOT_APPLICABLE: HoldsEpoch = HoldsEpoch(None);
24
25    /// Instance from block time.
26    pub fn from_block_time(block_time: BlockTime, hold_internal: TimeDiff) -> Self {
27        HoldsEpoch(Some(
28            block_time.value().saturating_sub(hold_internal.millis()),
29        ))
30    }
31
32    /// Instance from timestamp.
33    pub fn from_timestamp(timestamp: Timestamp, hold_internal: TimeDiff) -> Self {
34        HoldsEpoch(Some(
35            timestamp.millis().saturating_sub(hold_internal.millis()),
36        ))
37    }
38
39    /// Instance from milliseconds.
40    pub fn from_millis(timestamp_millis: u64, hold_internal_millis: u64) -> Self {
41        HoldsEpoch(Some(timestamp_millis.saturating_sub(hold_internal_millis)))
42    }
43
44    /// Returns the inner value.
45    pub fn value(&self) -> Option<u64> {
46        self.0
47    }
48}
49
50/// A newtype wrapping a [`u64`] which represents the block time.
51#[cfg_attr(feature = "datasize", derive(DataSize))]
52#[cfg_attr(feature = "json-schema", derive(JsonSchema))]
53#[derive(
54    Clone, Copy, Default, Debug, PartialEq, Eq, Ord, PartialOrd, Hash, Serialize, Deserialize,
55)]
56pub struct BlockTime(u64);
57
58impl BlockTime {
59    /// Constructs a `BlockTime`.
60    pub const fn new(value: u64) -> Self {
61        BlockTime(value)
62    }
63
64    /// Saturating integer subtraction. Computes `self - other`, saturating at `0` instead of
65    /// overflowing.
66    #[must_use]
67    pub fn saturating_sub(self, other: BlockTime) -> Self {
68        BlockTime(self.0.saturating_sub(other.0))
69    }
70
71    /// Returns inner value.
72    pub fn value(&self) -> u64 {
73        self.0
74    }
75}
76
77impl From<BlockTime> for u64 {
78    fn from(blocktime: BlockTime) -> Self {
79        blocktime.0
80    }
81}
82
83impl From<BlockTime> for Timestamp {
84    fn from(value: BlockTime) -> Self {
85        Timestamp::from(value.0)
86    }
87}
88
89impl From<u64> for BlockTime {
90    fn from(value: u64) -> Self {
91        BlockTime(value)
92    }
93}
94
95impl From<Timestamp> for BlockTime {
96    fn from(value: Timestamp) -> Self {
97        BlockTime(value.millis())
98    }
99}
100
101impl ToBytes for BlockTime {
102    fn to_bytes(&self) -> Result<Vec<u8>, Error> {
103        self.0.to_bytes()
104    }
105
106    fn serialized_length(&self) -> usize {
107        BLOCKTIME_SERIALIZED_LENGTH
108    }
109}
110
111impl FromBytes for BlockTime {
112    fn from_bytes(bytes: &[u8]) -> Result<(Self, &[u8]), Error> {
113        let (time, rem) = FromBytes::from_bytes(bytes)?;
114        Ok((BlockTime::new(time), rem))
115    }
116}
117
118impl CLTyped for BlockTime {
119    fn cl_type() -> CLType {
120        CLType::U64
121    }
122}