1use move_core_types::ident_str;
5use move_core_types::identifier::IdentStr;
6use move_core_types::language_storage::StructTag;
7
8use crate::SUI_SYSTEM_ADDRESS;
9use crate::balance::Balance;
10use crate::base_types::ObjectID;
11use crate::committee::EpochId;
12use crate::error::{SuiError, SuiErrorKind};
13use crate::gas_coin::MIST_PER_SUI;
14use crate::id::{ID, UID};
15use crate::object::{Data, Object};
16use serde::Deserialize;
17use serde::Serialize;
18
19pub const MAX_VALIDATOR_COUNT: u64 = 150;
24
25#[deprecated(note = "SIP-39 removes min barreier for joining the validator set")]
26pub const MIN_VALIDATOR_JOINING_STAKE_MIST: u64 = 30_000_000 * MIST_PER_SUI;
30
31#[deprecated(note = "SIP-39 removes low barreier for joining the validator set")]
32pub const VALIDATOR_LOW_STAKE_THRESHOLD_MIST: u64 = 20_000_000 * MIST_PER_SUI;
40
41#[deprecated(note = "SIP-39 removes very low barreier for joining the validator set")]
42pub const VALIDATOR_VERY_LOW_STAKE_THRESHOLD_MIST: u64 = 15_000_000 * MIST_PER_SUI;
47
48pub const SIP_39_PHASE_LENGTH: u64 = 14;
50
51pub const VALIDATOR_MIN_POWER_PHASE_1: u64 = 12;
56
57pub const VALIDATOR_LOW_POWER_PHASE_1: u64 = 8;
61
62pub const VALIDATOR_VERY_LOW_POWER_PHASE_1: u64 = 4;
66
67pub const VALIDATOR_MIN_POWER_PHASE_2: u64 = 6;
72
73pub const VALIDATOR_LOW_POWER_PHASE_2: u64 = 4;
77
78pub const VALIDATOR_VERY_LOW_POWER_PHASE_2: u64 = 2;
82
83pub const VALIDATOR_MIN_POWER_PHASE_3: u64 = 3;
88
89pub const VALIDATOR_LOW_POWER_PHASE_3: u64 = 2;
93
94pub const VALIDATOR_VERY_LOW_POWER_PHASE_3: u64 = 1;
98
99pub const VALIDATOR_LOW_STAKE_GRACE_PERIOD: u64 = 7;
102
103pub const STAKING_POOL_MODULE_NAME: &IdentStr = ident_str!("staking_pool");
104pub const STAKED_SUI_STRUCT_NAME: &IdentStr = ident_str!("StakedSui");
105
106pub const ADD_STAKE_MUL_COIN_FUN_NAME: &IdentStr = ident_str!("request_add_stake_mul_coin");
107pub const ADD_STAKE_FUN_NAME: &IdentStr = ident_str!("request_add_stake");
108pub const WITHDRAW_STAKE_FUN_NAME: &IdentStr = ident_str!("request_withdraw_stake");
109
110#[derive(Debug, Serialize, Deserialize, Clone, Eq, PartialEq)]
111pub struct StakedSui {
112    id: UID,
113    pool_id: ID,
114    stake_activation_epoch: u64,
115    principal: Balance,
116}
117
118impl StakedSui {
119    pub fn type_() -> StructTag {
120        StructTag {
121            address: SUI_SYSTEM_ADDRESS,
122            module: STAKING_POOL_MODULE_NAME.to_owned(),
123            name: STAKED_SUI_STRUCT_NAME.to_owned(),
124            type_params: vec![],
125        }
126    }
127
128    pub fn is_staked_sui(s: &StructTag) -> bool {
129        s.address == SUI_SYSTEM_ADDRESS
130            && s.module.as_ident_str() == STAKING_POOL_MODULE_NAME
131            && s.name.as_ident_str() == STAKED_SUI_STRUCT_NAME
132            && s.type_params.is_empty()
133    }
134
135    pub fn id(&self) -> ObjectID {
136        self.id.id.bytes
137    }
138
139    pub fn pool_id(&self) -> ObjectID {
140        self.pool_id.bytes
141    }
142
143    pub fn activation_epoch(&self) -> EpochId {
144        self.stake_activation_epoch
145    }
146
147    pub fn request_epoch(&self) -> EpochId {
148        self.stake_activation_epoch.saturating_sub(1)
150    }
151
152    pub fn principal(&self) -> u64 {
153        self.principal.value()
154    }
155}
156
157impl TryFrom<&Object> for StakedSui {
158    type Error = SuiError;
159    fn try_from(object: &Object) -> Result<Self, Self::Error> {
160        match &object.data {
161            Data::Move(o) => {
162                if o.type_().is_staked_sui() {
163                    return bcs::from_bytes(o.contents()).map_err(|err| {
164                        SuiErrorKind::TypeError {
165                            error: format!("Unable to deserialize StakedSui object: {:?}", err),
166                        }
167                        .into()
168                    });
169                }
170            }
171            Data::Package(_) => {}
172        }
173
174        Err(SuiErrorKind::TypeError {
175            error: format!("Object type is not a StakedSui: {:?}", object),
176        }
177        .into())
178    }
179}