use move_core_types::{ident_str, identifier::IdentStr, language_storage::StructTag};
use serde::{Deserialize, Serialize};
use crate::{
IOTA_SYSTEM_ADDRESS,
base_types::ObjectID,
committee::EpochId,
error::IotaError,
governance::StakedIota,
id::UID,
object::{Data, Object},
};
pub const TIMELOCKED_STAKED_IOTA_MODULE_NAME: &IdentStr = ident_str!("timelocked_staking");
pub const TIMELOCKED_STAKED_IOTA_STRUCT_NAME: &IdentStr = ident_str!("TimelockedStakedIota");
#[derive(Debug, Serialize, Deserialize, Clone, Eq, PartialEq)]
pub struct TimelockedStakedIota {
id: UID,
staked_iota: StakedIota,
expiration_timestamp_ms: u64,
label: Option<String>,
}
impl TimelockedStakedIota {
pub fn type_() -> StructTag {
StructTag {
address: IOTA_SYSTEM_ADDRESS,
module: TIMELOCKED_STAKED_IOTA_MODULE_NAME.to_owned(),
name: TIMELOCKED_STAKED_IOTA_STRUCT_NAME.to_owned(),
type_params: vec![],
}
}
pub fn is_timelocked_staked_iota(s: &StructTag) -> bool {
s.address == IOTA_SYSTEM_ADDRESS
&& s.module.as_ident_str() == TIMELOCKED_STAKED_IOTA_MODULE_NAME
&& s.name.as_ident_str() == TIMELOCKED_STAKED_IOTA_STRUCT_NAME
&& s.type_params.is_empty()
}
pub fn id(&self) -> ObjectID {
self.id.id.bytes
}
pub fn pool_id(&self) -> ObjectID {
self.staked_iota.pool_id()
}
pub fn activation_epoch(&self) -> EpochId {
self.staked_iota.activation_epoch()
}
pub fn request_epoch(&self) -> EpochId {
self.staked_iota.activation_epoch().saturating_sub(1)
}
pub fn principal(&self) -> u64 {
self.staked_iota.principal()
}
pub fn expiration_timestamp_ms(&self) -> u64 {
self.expiration_timestamp_ms
}
pub fn label(&self) -> &Option<String> {
&self.label
}
}
impl TryFrom<&Object> for TimelockedStakedIota {
type Error = IotaError;
fn try_from(object: &Object) -> Result<Self, Self::Error> {
match &object.data {
Data::Move(o) => {
if o.type_().is_timelocked_staked_iota() {
return bcs::from_bytes(o.contents()).map_err(|err| IotaError::Type {
error: format!(
"Unable to deserialize TimelockedStakedIota object: {:?}",
err
),
});
}
}
Data::Package(_) => {}
}
Err(IotaError::Type {
error: format!("Object type is not a TimelockedStakedIota: {:?}", object),
})
}
}