iota_types/
governance.rs

1// Copyright (c) Mysten Labs, Inc.
2// Modifications Copyright (c) 2024 IOTA Stiftung
3// SPDX-License-Identifier: Apache-2.0
4
5use move_core_types::{ident_str, identifier::IdentStr, language_storage::StructTag};
6use serde::{Deserialize, Serialize};
7
8use crate::{
9    IOTA_SYSTEM_ADDRESS,
10    balance::Balance,
11    base_types::ObjectID,
12    committee::EpochId,
13    error::IotaError,
14    gas_coin::NANOS_PER_IOTA,
15    id::{ID, UID},
16    object::{Data, Object},
17};
18
19/// Maximum number of active validators at any moment.
20/// We do not allow the number of validators in any epoch to go above this.
21pub const MAX_VALIDATOR_COUNT: u64 = 150;
22
23/// Lower-bound on the amount of stake required to become a validator.
24///
25/// 2 million IOTA
26pub const MIN_VALIDATOR_JOINING_STAKE_NANOS: u64 = 2_000_000 * NANOS_PER_IOTA;
27
28/// Validators with stake amount below `validator_low_stake_threshold` are
29/// considered to have low stake and will be escorted out of the validator set
30/// after being below this threshold for more than
31/// `validator_low_stake_grace_period` number of epochs.
32///
33/// 1.5 million IOTA
34pub const VALIDATOR_LOW_STAKE_THRESHOLD_NANOS: u64 = 1_500_000 * NANOS_PER_IOTA;
35
36/// Validators with stake below `validator_very_low_stake_threshold` will be
37/// removed immediately at epoch change, no grace period.
38///
39/// 1 million IOTA
40pub const VALIDATOR_VERY_LOW_STAKE_THRESHOLD_NANOS: u64 = 1_000_000 * NANOS_PER_IOTA;
41
42/// A validator can have stake below `validator_low_stake_threshold`
43/// for this many epochs before being kicked out.
44pub const VALIDATOR_LOW_STAKE_GRACE_PERIOD: u64 = 7;
45
46pub const STAKING_POOL_MODULE_NAME: &IdentStr = ident_str!("staking_pool");
47pub const STAKED_IOTA_STRUCT_NAME: &IdentStr = ident_str!("StakedIota");
48
49pub const ADD_STAKE_MUL_COIN_FUN_NAME: &IdentStr = ident_str!("request_add_stake_mul_coin");
50pub const ADD_STAKE_FUN_NAME: &IdentStr = ident_str!("request_add_stake");
51pub const WITHDRAW_STAKE_FUN_NAME: &IdentStr = ident_str!("request_withdraw_stake");
52
53#[derive(Debug, Serialize, Deserialize, Clone, Eq, PartialEq)]
54pub struct StakedIota {
55    id: UID,
56    pool_id: ID,
57    stake_activation_epoch: u64,
58    principal: Balance,
59}
60
61impl StakedIota {
62    pub fn type_() -> StructTag {
63        StructTag {
64            address: IOTA_SYSTEM_ADDRESS,
65            module: STAKING_POOL_MODULE_NAME.to_owned(),
66            name: STAKED_IOTA_STRUCT_NAME.to_owned(),
67            type_params: vec![],
68        }
69    }
70
71    pub fn is_staked_iota(s: &StructTag) -> bool {
72        s.address == IOTA_SYSTEM_ADDRESS
73            && s.module.as_ident_str() == STAKING_POOL_MODULE_NAME
74            && s.name.as_ident_str() == STAKED_IOTA_STRUCT_NAME
75            && s.type_params.is_empty()
76    }
77
78    pub fn id(&self) -> ObjectID {
79        self.id.id.bytes
80    }
81
82    pub fn pool_id(&self) -> ObjectID {
83        self.pool_id.bytes
84    }
85
86    pub fn activation_epoch(&self) -> EpochId {
87        self.stake_activation_epoch
88    }
89
90    pub fn request_epoch(&self) -> EpochId {
91        // TODO: this might change when we implement warm up period.
92        self.stake_activation_epoch.saturating_sub(1)
93    }
94
95    pub fn principal(&self) -> u64 {
96        self.principal.value()
97    }
98}
99
100impl TryFrom<&Object> for StakedIota {
101    type Error = IotaError;
102    fn try_from(object: &Object) -> Result<Self, Self::Error> {
103        match &object.data {
104            Data::Move(o) => {
105                if o.type_().is_staked_iota() {
106                    return bcs::from_bytes(o.contents()).map_err(|err| IotaError::Type {
107                        error: format!("Unable to deserialize StakedIota object: {:?}", err),
108                    });
109                }
110            }
111            Data::Package(_) => {}
112        }
113
114        Err(IotaError::Type {
115            error: format!("Object type is not a StakedIota: {:?}", object),
116        })
117    }
118}