casper_types/
block_time.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
use alloc::vec::Vec;

use crate::{
    bytesrepr::{Error, FromBytes, ToBytes, U64_SERIALIZED_LENGTH},
    CLType, CLTyped, TimeDiff, Timestamp,
};

#[cfg(feature = "datasize")]
use datasize::DataSize;
#[cfg(feature = "json-schema")]
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};

/// The number of bytes in a serialized [`BlockTime`].
pub const BLOCKTIME_SERIALIZED_LENGTH: usize = U64_SERIALIZED_LENGTH;

/// Holds epoch type.
#[derive(Debug, Copy, Clone, PartialEq, Eq, Default)]
pub struct HoldsEpoch(Option<u64>);

impl HoldsEpoch {
    /// No epoch is applicable.
    pub const NOT_APPLICABLE: HoldsEpoch = HoldsEpoch(None);

    /// Instance from block time.
    pub fn from_block_time(block_time: BlockTime, hold_internal: TimeDiff) -> Self {
        HoldsEpoch(Some(
            block_time.value().saturating_sub(hold_internal.millis()),
        ))
    }

    /// Instance from timestamp.
    pub fn from_timestamp(timestamp: Timestamp, hold_internal: TimeDiff) -> Self {
        HoldsEpoch(Some(
            timestamp.millis().saturating_sub(hold_internal.millis()),
        ))
    }

    /// Instance from milliseconds.
    pub fn from_millis(timestamp_millis: u64, hold_internal_millis: u64) -> Self {
        HoldsEpoch(Some(timestamp_millis.saturating_sub(hold_internal_millis)))
    }

    /// Returns the inner value.
    pub fn value(&self) -> Option<u64> {
        self.0
    }
}

/// A newtype wrapping a [`u64`] which represents the block time.
#[cfg_attr(feature = "datasize", derive(DataSize))]
#[cfg_attr(feature = "json-schema", derive(JsonSchema))]
#[derive(
    Clone, Copy, Default, Debug, PartialEq, Eq, Ord, PartialOrd, Hash, Serialize, Deserialize,
)]
pub struct BlockTime(u64);

impl BlockTime {
    /// Constructs a `BlockTime`.
    pub const fn new(value: u64) -> Self {
        BlockTime(value)
    }

    /// Saturating integer subtraction. Computes `self - other`, saturating at `0` instead of
    /// overflowing.
    #[must_use]
    pub fn saturating_sub(self, other: BlockTime) -> Self {
        BlockTime(self.0.saturating_sub(other.0))
    }

    /// Returns inner value.
    pub fn value(&self) -> u64 {
        self.0
    }
}

impl From<BlockTime> for u64 {
    fn from(blocktime: BlockTime) -> Self {
        blocktime.0
    }
}

impl From<BlockTime> for Timestamp {
    fn from(value: BlockTime) -> Self {
        Timestamp::from(value.0)
    }
}

impl From<u64> for BlockTime {
    fn from(value: u64) -> Self {
        BlockTime(value)
    }
}

impl From<Timestamp> for BlockTime {
    fn from(value: Timestamp) -> Self {
        BlockTime(value.millis())
    }
}

impl ToBytes for BlockTime {
    fn to_bytes(&self) -> Result<Vec<u8>, Error> {
        self.0.to_bytes()
    }

    fn serialized_length(&self) -> usize {
        BLOCKTIME_SERIALIZED_LENGTH
    }
}

impl FromBytes for BlockTime {
    fn from_bytes(bytes: &[u8]) -> Result<(Self, &[u8]), Error> {
        let (time, rem) = FromBytes::from_bytes(bytes)?;
        Ok((BlockTime::new(time), rem))
    }
}

impl CLTyped for BlockTime {
    fn cl_type() -> CLType {
        CLType::U64
    }
}