sp_consensus_slots/
lib.rs1#![cfg_attr(not(feature = "std"), no_std)]
21
22use codec::{Decode, DecodeWithMemTracking, Encode, MaxEncodedLen};
23use scale_info::TypeInfo;
24use sp_timestamp::Timestamp;
25
26#[derive(
28 Debug,
29 Encode,
30 MaxEncodedLen,
31 Decode,
32 DecodeWithMemTracking,
33 Eq,
34 Clone,
35 Copy,
36 Default,
37 Ord,
38 Hash,
39 TypeInfo,
40)]
41#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
42#[repr(transparent)]
43pub struct Slot(u64);
44
45impl core::ops::Deref for Slot {
46 type Target = u64;
47
48 fn deref(&self) -> &u64 {
49 &self.0
50 }
51}
52
53impl core::ops::Add for Slot {
54 type Output = Self;
55
56 fn add(self, other: Self) -> Self {
57 Self(self.0 + other.0)
58 }
59}
60
61impl core::ops::Sub for Slot {
62 type Output = Self;
63
64 fn sub(self, other: Self) -> Self {
65 Self(self.0 - other.0)
66 }
67}
68
69impl core::ops::AddAssign for Slot {
70 fn add_assign(&mut self, rhs: Self) {
71 self.0 += rhs.0
72 }
73}
74
75impl core::ops::SubAssign for Slot {
76 fn sub_assign(&mut self, rhs: Self) {
77 self.0 -= rhs.0
78 }
79}
80
81impl core::ops::Add<u64> for Slot {
82 type Output = Self;
83
84 fn add(self, other: u64) -> Self {
85 Self(self.0 + other)
86 }
87}
88
89impl<T: Into<u64> + Copy> core::cmp::PartialEq<T> for Slot {
90 fn eq(&self, eq: &T) -> bool {
91 self.0 == (*eq).into()
92 }
93}
94
95impl<T: Into<u64> + Copy> core::cmp::PartialOrd<T> for Slot {
96 fn partial_cmp(&self, other: &T) -> Option<core::cmp::Ordering> {
97 self.0.partial_cmp(&(*other).into())
98 }
99}
100
101impl Slot {
102 pub const fn from_timestamp(timestamp: Timestamp, slot_duration: SlotDuration) -> Self {
104 Slot(timestamp.as_millis() / slot_duration.as_millis())
105 }
106
107 pub fn timestamp(&self, slot_duration: SlotDuration) -> Option<Timestamp> {
111 slot_duration.as_millis().checked_mul(self.0).map(Timestamp::new)
112 }
113
114 pub fn saturating_add<T: Into<u64>>(self, rhs: T) -> Self {
116 Self(self.0.saturating_add(rhs.into()))
117 }
118
119 pub fn saturating_sub<T: Into<u64>>(self, rhs: T) -> Self {
121 Self(self.0.saturating_sub(rhs.into()))
122 }
123}
124
125#[cfg(feature = "std")]
126impl std::fmt::Display for Slot {
127 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
128 write!(f, "{}", self.0)
129 }
130}
131
132impl From<u64> for Slot {
133 fn from(slot: u64) -> Slot {
134 Slot(slot)
135 }
136}
137
138impl From<Slot> for u64 {
139 fn from(slot: Slot) -> u64 {
140 slot.0
141 }
142}
143
144#[derive(
146 Clone,
147 Copy,
148 Debug,
149 Encode,
150 Decode,
151 MaxEncodedLen,
152 Hash,
153 PartialOrd,
154 Ord,
155 PartialEq,
156 Eq,
157 TypeInfo,
158)]
159#[repr(transparent)]
160pub struct SlotDuration(u64);
161
162impl SlotDuration {
163 pub const fn from_millis(millis: u64) -> Self {
165 Self(millis)
166 }
167}
168
169impl SlotDuration {
170 pub const fn as_millis(&self) -> u64 {
172 self.0
173 }
174}
175
176#[cfg(feature = "std")]
177impl SlotDuration {
178 pub const fn as_duration(&self) -> core::time::Duration {
180 core::time::Duration::from_millis(self.0)
181 }
182}
183
184#[derive(Clone, Debug, Decode, DecodeWithMemTracking, Encode, PartialEq, TypeInfo, Eq)]
189pub struct EquivocationProof<Header, Id> {
190 pub offender: Id,
192 pub slot: Slot,
194 pub first_header: Header,
196 pub second_header: Header,
198}