1use alloc::{
2 string::{String, ToString},
3 vec::Vec,
4};
5use borsh::{BorshDeserialize, BorshSerialize};
6use serde::{
7 de::{self, Visitor},
8 Deserialize, Serialize,
9};
10#[cfg(feature = "full")]
11use sha3::Digest;
12
13use crate::*;
14
15#[derive(BorshSerialize, BorshDeserialize, Debug, Clone, Deserialize, Serialize, PartialEq, Eq)]
16pub struct RewardsClaim {
17 block_heights: Vec<BlockHeight>,
18}
19
20#[derive(BorshSerialize, BorshDeserialize, Debug, Clone, Deserialize, Serialize, PartialEq, Eq)]
22pub enum StakingAction {
23 Stake {
24 amount: u128,
25 },
26 Delegate {
27 validator: ValidatorPublicKey,
28 },
29 Distribute {
30 claim: RewardsClaim,
31 },
32
33 DepositForFees {
35 holder: ValidatorPublicKey,
36 amount: u128,
37 },
38}
39
40impl ContractAction for StakingAction {
41 fn as_blob(
42 &self,
43 contract_name: ContractName,
44 caller: Option<BlobIndex>,
45 callees: Option<Vec<BlobIndex>>,
46 ) -> Blob {
47 Blob {
48 contract_name,
49 data: BlobData::from(StructuredBlobData {
50 caller,
51 callees,
52 parameters: self.clone(),
53 }),
54 }
55 }
56}
57
58#[derive(
59 Clone, BorshSerialize, BorshDeserialize, Default, Eq, PartialEq, Hash, PartialOrd, Ord,
60)]
61pub struct ValidatorPublicKey(pub Vec<u8>);
62
63impl ValidatorPublicKey {
64 pub fn new_for_tests(str: &str) -> Self {
65 Self(str.as_bytes().to_vec())
66 }
67}
68
69#[cfg(feature = "full")]
70impl utoipa::PartialSchema for ValidatorPublicKey {
71 fn schema() -> utoipa::openapi::RefOr<utoipa::openapi::schema::Schema> {
72 String::schema()
73 }
74}
75
76#[cfg(feature = "full")]
77impl utoipa::ToSchema for ValidatorPublicKey {}
78
79impl Serialize for ValidatorPublicKey {
80 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
81 where
82 S: serde::Serializer,
83 {
84 serializer.serialize_str(hex::encode(&self.0).as_str())
85 }
86}
87
88impl<'de> Deserialize<'de> for ValidatorPublicKey {
89 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
90 where
91 D: serde::Deserializer<'de>,
92 {
93 struct ValidatorPublicKeyVisitor;
94
95 impl Visitor<'_> for ValidatorPublicKeyVisitor {
96 type Value = ValidatorPublicKey;
97
98 fn expecting(&self, formatter: &mut core::fmt::Formatter) -> core::fmt::Result {
99 formatter.write_str("a hex string representing a ValidatorPublicKey")
100 }
101
102 fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
103 where
104 E: de::Error,
105 {
106 let bytes = hex::decode(value).map_err(de::Error::custom)?;
107 Ok(ValidatorPublicKey(bytes))
108 }
109 }
110
111 deserializer.deserialize_str(ValidatorPublicKeyVisitor)
112 }
113}
114
115impl core::fmt::Debug for ValidatorPublicKey {
116 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
117 f.debug_tuple("ValidatorPubK")
118 .field(&hex::encode(
119 self.0.get(..HASH_DISPLAY_SIZE).unwrap_or(&self.0),
120 ))
121 .finish()
122 }
123}
124
125impl core::fmt::Display for ValidatorPublicKey {
126 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
127 write!(
128 f,
129 "{}",
130 &hex::encode(self.0.get(..HASH_DISPLAY_SIZE).unwrap_or(&self.0),)
131 )
132 }
133}
134
135#[derive(
136 Clone,
137 Debug,
138 BorshSerialize,
139 BorshDeserialize,
140 Serialize,
141 Deserialize,
142 PartialEq,
143 Eq,
144 Hash,
145 Ord,
146 PartialOrd,
147)]
148#[serde(try_from = "String", into = "String")]
149pub struct LaneId {
150 pub operator: ValidatorPublicKey,
151 pub suffix: String,
152}
153
154pub type LaneSuffix = String;
155
156#[cfg(feature = "full")]
157impl utoipa::PartialSchema for LaneId {
158 fn schema() -> utoipa::openapi::RefOr<utoipa::openapi::schema::Schema> {
159 String::schema()
160 }
161}
162
163#[cfg(feature = "full")]
164impl utoipa::ToSchema for LaneId {}
165
166impl Default for LaneId {
167 fn default() -> Self {
168 LaneId::with_suffix(ValidatorPublicKey::default(), LaneId::DEFAULT_SUFFIX)
169 }
170}
171
172impl LaneId {
173 pub const DEFAULT_SUFFIX: &'static str = "default";
174
175 pub fn new(operator: ValidatorPublicKey) -> Self {
176 Self::with_suffix(operator, Self::DEFAULT_SUFFIX)
177 }
178
179 pub fn with_suffix(operator: ValidatorPublicKey, suffix: impl Into<String>) -> Self {
180 Self {
181 operator,
182 suffix: suffix.into(),
183 }
184 }
185
186 pub fn operator(&self) -> &ValidatorPublicKey {
187 &self.operator
188 }
189
190 pub fn suffix(&self) -> &str {
191 &self.suffix
192 }
193
194 pub fn to_bytes(&self) -> Vec<u8> {
195 let mut bytes = Vec::with_capacity(self.operator.0.len() + 1 + self.suffix.len());
196 bytes.extend_from_slice(&self.operator.0);
197 bytes.push(b'-');
198 bytes.extend_from_slice(self.suffix.as_bytes());
199 bytes
200 }
201
202 #[cfg(feature = "full")]
203 pub fn update_hasher<D: Digest>(&self, hasher: &mut D) {
204 hasher.update(&self.operator.0);
205 hasher.update(b"-");
206 hasher.update(self.suffix.as_bytes());
207 }
208
209 pub fn parse(value: &str) -> Result<Self, String> {
210 if let Some((hex_part, suffix)) = value.split_once('-') {
211 if suffix.is_empty() {
212 return Err("LaneId suffix cannot be empty".to_string());
213 }
214 let bytes = hex::decode(hex_part).map_err(|e| e.to_string())?;
215 Ok(LaneId::with_suffix(ValidatorPublicKey(bytes), suffix))
216 } else {
217 let bytes = hex::decode(value).map_err(|e| e.to_string())?;
218 Ok(LaneId::with_suffix(
219 ValidatorPublicKey(bytes),
220 LaneId::DEFAULT_SUFFIX,
221 ))
222 }
223 }
224}
225
226impl From<ValidatorPublicKey> for LaneId {
227 fn from(value: ValidatorPublicKey) -> Self {
228 LaneId::new(value)
229 }
230}
231
232impl core::str::FromStr for LaneId {
233 type Err = String;
234
235 fn from_str(value: &str) -> Result<Self, Self::Err> {
236 Self::parse(value)
237 }
238}
239
240impl TryFrom<String> for LaneId {
241 type Error = String;
242
243 fn try_from(value: String) -> Result<Self, Self::Error> {
244 Self::parse(&value)
245 }
246}
247
248impl From<LaneId> for String {
249 fn from(value: LaneId) -> Self {
250 value.to_string()
251 }
252}
253
254impl core::fmt::Display for LaneId {
255 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
256 write!(f, "{}-{}", hex::encode(&self.operator.0), self.suffix)
257 }
258}
259
260#[derive(
262 Debug,
263 Clone,
264 Copy,
265 Default,
266 BorshSerialize,
267 BorshDeserialize,
268 Eq,
269 PartialEq,
270 Serialize,
271 Deserialize,
272 PartialOrd,
273 Ord,
274)]
275#[cfg_attr(feature = "full", derive(utoipa::ToSchema))]
276pub struct LaneBytesSize(pub u64); impl core::ops::Add<usize> for LaneBytesSize {
279 type Output = Self;
280 fn add(self, other: usize) -> Self {
281 LaneBytesSize(self.0 + other as u64)
282 }
283}
284
285impl core::fmt::Display for LaneBytesSize {
286 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
287 if self.0 < 1024 {
288 write!(f, "{} B", self.0)
289 } else if self.0 < 1024 * 1024 {
290 write!(f, "{} KB", self.0 / 1024)
291 } else if self.0 < 1024 * 1024 * 1024 {
292 write!(f, "{} MB", self.0 / (1024 * 1024))
293 } else if self.0 < 1024 * 1024 * 1024 * 1024 {
294 write!(f, "{} GB", self.0 / (1024 * 1024 * 1024))
295 } else {
296 write!(f, "{} TB", self.0 / (1024 * 1024 * 1024 * 1024))
297 }
298 }
299}