Skip to main content

hyli_model/
staking.rs

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/// Enum representing the actions that can be performed by the Staking contract.
21#[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    /// Fees are deposited by the validators to be distributed to the bonded validators
34    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// Cumulative size of the lane from the beginning
261#[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); // 16M Terabytes, is it enough ?
277
278impl 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}