Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(genesis-geremony): fix examine-genesis-checkpoint #4829

Merged
merged 14 commits into from
Jan 28, 2025
Merged
16 changes: 15 additions & 1 deletion crates/iota-genesis-builder/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -149,11 +149,25 @@ impl Builder {
}
}

/// Return an iterator of migration objects if this genesis is with
/// migration objects.
pub fn tx_migration_objects(&self) -> impl Iterator<Item = Object> + '_ {
self.migration_tx_data
.as_ref()
.map(|tx_data| tx_data.get_objects())
.into_iter()
.flatten()
}

/// Set the genesis delegation to be a `OneToAll` kind and set the
/// delegator address.
pub fn with_delegator(mut self, delegator: IotaAddress) -> Self {
self.delegation = Some(GenesisDelegation::OneToAll(delegator));
self
}

/// Set the genesis delegation to be a `ManyToMany` kind and set the
/// delegator map.
pub fn with_delegations(mut self, delegations: Delegations) -> Self {
self.delegation = Some(GenesisDelegation::ManyToMany(delegations));
self
Expand Down Expand Up @@ -259,7 +273,7 @@ impl Builder {
self.built_genesis.clone()
}

fn load_migration_sources(&mut self) -> anyhow::Result<()> {
pub fn load_migration_sources(&mut self) -> anyhow::Result<()> {
for source in &self.migration_sources {
tracing::info!("Adding migration objects from {:?}", source);
self.migration_objects
Expand Down
29 changes: 28 additions & 1 deletion crates/iota-types/src/base_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ use crate::{
object::{Object, Owner},
parse_iota_struct_tag,
signature::GenericSignature,
stardust::output::Nft,
stardust::output::{AliasOutput, BasicOutput, Nft, NftOutput},
timelock::{
timelock::{self, TimeLock},
timelocked_staked_iota::TimelockedStakedIota,
Expand Down Expand Up @@ -380,6 +380,33 @@ impl MoveObjectType {
}
}

pub fn is_alias_output(&self) -> bool {
match &self.0 {
MoveObjectType_::GasCoin | MoveObjectType_::StakedIota | MoveObjectType_::Coin(_) => {
false
}
MoveObjectType_::Other(s) => AliasOutput::is_alias_output(s),
}
}

pub fn is_basic_output(&self) -> bool {
match &self.0 {
MoveObjectType_::GasCoin | MoveObjectType_::StakedIota | MoveObjectType_::Coin(_) => {
false
}
MoveObjectType_::Other(s) => BasicOutput::is_basic_output(s),
}
}

pub fn is_nft_output(&self) -> bool {
match &self.0 {
MoveObjectType_::GasCoin | MoveObjectType_::StakedIota | MoveObjectType_::Coin(_) => {
false
}
MoveObjectType_::Other(s) => NftOutput::is_nft_output(s),
}
}

Alex6323 marked this conversation as resolved.
Show resolved Hide resolved
pub fn try_extract_field_name(&self, type_: &DynamicFieldType) -> IotaResult<TypeTag> {
match &self.0 {
MoveObjectType_::GasCoin | MoveObjectType_::StakedIota | MoveObjectType_::Coin(_) => {
Expand Down
38 changes: 35 additions & 3 deletions crates/iota-types/src/stardust/output/alias.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,11 @@ use serde::{Deserialize, Serialize};
use serde_with::serde_as;

use crate::{
STARDUST_PACKAGE_ID, TypeTag,
STARDUST_ADDRESS, TypeTag,
balance::Balance,
base_types::{IotaAddress, ObjectID, SequenceNumber, TxContext},
collection_types::Bag,
error::IotaError,
id::UID,
object::{Data, MoveObject, Object, Owner},
stardust::{coin_type::CoinType, stardust_to_iota_address},
Expand Down Expand Up @@ -54,7 +55,7 @@ impl Alias {
/// [`Alias`] in its move package.
pub fn tag() -> StructTag {
StructTag {
address: STARDUST_PACKAGE_ID.into(),
address: STARDUST_ADDRESS,
module: ALIAS_MODULE_NAME.to_owned(),
name: ALIAS_STRUCT_NAME.to_owned(),
type_params: Vec::new(),
Expand Down Expand Up @@ -154,7 +155,7 @@ impl AliasOutput {
/// [`AliasOutput`] in its move package.
pub fn tag(type_param: TypeTag) -> StructTag {
StructTag {
address: STARDUST_PACKAGE_ID.into(),
address: STARDUST_ADDRESS,
module: ALIAS_OUTPUT_MODULE_NAME.to_owned(),
name: ALIAS_OUTPUT_STRUCT_NAME.to_owned(),
type_params: vec![type_param],
Expand Down Expand Up @@ -201,4 +202,35 @@ impl AliasOutput {

Ok(move_alias_output_object)
}

/// Create an `AliasOutput` from BCS bytes.
pub fn from_bcs_bytes(content: &[u8]) -> Result<Self, IotaError> {
bcs::from_bytes(content).map_err(|err| IotaError::ObjectDeserialization {
error: format!("Unable to deserialize AliasOutput object: {:?}", err),
})
}

pub fn is_alias_output(s: &StructTag) -> bool {
s.address == STARDUST_ADDRESS
&& s.module.as_ident_str() == ALIAS_OUTPUT_MODULE_NAME
&& s.name.as_ident_str() == ALIAS_OUTPUT_STRUCT_NAME
}
}

impl TryFrom<&Object> for AliasOutput {
type Error = IotaError;
fn try_from(object: &Object) -> Result<Self, Self::Error> {
match &object.data {
Data::Move(o) => {
if o.type_().is_alias_output() {
return AliasOutput::from_bcs_bytes(o.contents());
}
}
Data::Package(_) => {}
}

Err(IotaError::Type {
error: format!("Object type is not an AliasOutput: {:?}", object),
})
}
}
37 changes: 35 additions & 2 deletions crates/iota-types/src/stardust/output/basic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,12 @@ use super::unlock_conditions::{
ExpirationUnlockCondition, StorageDepositReturnUnlockCondition, TimelockUnlockCondition,
};
use crate::{
STARDUST_PACKAGE_ID, TypeTag,
STARDUST_ADDRESS, TypeTag,
balance::Balance,
base_types::{IotaAddress, MoveObjectType, ObjectID, SequenceNumber, TxContext},
coin::Coin,
collection_types::Bag,
error::IotaError,
id::UID,
object::{Data, MoveObject, Object, Owner},
stardust::{coin_type::CoinType, stardust_to_iota_address},
Expand Down Expand Up @@ -108,7 +109,7 @@ impl BasicOutput {
/// Returns the struct tag of the BasicOutput struct
pub fn tag(type_param: TypeTag) -> StructTag {
StructTag {
address: STARDUST_PACKAGE_ID.into(),
address: STARDUST_ADDRESS,
module: BASIC_OUTPUT_MODULE_NAME.to_owned(),
name: BASIC_OUTPUT_STRUCT_NAME.to_owned(),
type_params: vec![type_param],
Expand Down Expand Up @@ -181,6 +182,20 @@ impl BasicOutput {
coin_type,
)
}

/// Create a `BasicOutput` from BCS bytes.
pub fn from_bcs_bytes(content: &[u8]) -> Result<Self, IotaError> {
bcs::from_bytes(content).map_err(|err| IotaError::ObjectDeserialization {
error: format!("Unable to deserialize BasicOutput object: {:?}", err),
})
}

/// Whether the given `StructTag` represents a `BasicOutput`.
pub fn is_basic_output(s: &StructTag) -> bool {
s.address == STARDUST_ADDRESS
&& s.module.as_ident_str() == BASIC_OUTPUT_MODULE_NAME
&& s.name.as_ident_str() == BASIC_OUTPUT_STRUCT_NAME
}
}

pub(crate) fn create_coin(
Expand Down Expand Up @@ -209,3 +224,21 @@ pub(crate) fn create_coin(
tx_context.digest(),
))
}

impl TryFrom<&Object> for BasicOutput {
type Error = IotaError;
fn try_from(object: &Object) -> Result<Self, Self::Error> {
match &object.data {
Data::Move(o) => {
if o.type_().is_basic_output() {
return BasicOutput::from_bcs_bytes(o.contents());
}
}
Data::Package(_) => {}
}

Err(IotaError::Type {
error: format!("Object type is not a BasicOutput: {:?}", object),
})
}
}
38 changes: 35 additions & 3 deletions crates/iota-types/src/stardust/output/nft.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,11 @@ use super::unlock_conditions::{
ExpirationUnlockCondition, StorageDepositReturnUnlockCondition, TimelockUnlockCondition,
};
use crate::{
STARDUST_PACKAGE_ID, TypeTag,
STARDUST_ADDRESS, TypeTag,
balance::Balance,
base_types::{IotaAddress, ObjectID, SequenceNumber, TxContext},
collection_types::{Bag, Entry, VecMap},
error::IotaError,
id::UID,
object::{Data, MoveObject, Object, Owner},
stardust::{coin_type::CoinType, stardust_to_iota_address},
Expand Down Expand Up @@ -261,7 +262,7 @@ impl Nft {
/// [`Nft`] in its move package.
pub fn tag() -> StructTag {
StructTag {
address: STARDUST_PACKAGE_ID.into(),
address: STARDUST_ADDRESS,
module: NFT_MODULE_NAME.to_owned(),
name: NFT_STRUCT_NAME.to_owned(),
type_params: Vec::new(),
Expand Down Expand Up @@ -404,7 +405,7 @@ impl NftOutput {
/// [`NftOutput`] in its move package.
pub fn tag(type_param: TypeTag) -> StructTag {
StructTag {
address: STARDUST_PACKAGE_ID.into(),
address: STARDUST_ADDRESS,
module: NFT_OUTPUT_MODULE_NAME.to_owned(),
name: NFT_OUTPUT_STRUCT_NAME.to_owned(),
type_params: vec![type_param],
Expand Down Expand Up @@ -469,4 +470,35 @@ impl NftOutput {

Ok(move_nft_output_object)
}

/// Create an `NftOutput` from BCS bytes.
pub fn from_bcs_bytes(content: &[u8]) -> Result<Self, IotaError> {
bcs::from_bytes(content).map_err(|err| IotaError::ObjectDeserialization {
error: format!("Unable to deserialize NftOutput object: {:?}", err),
})
}

pub fn is_nft_output(s: &StructTag) -> bool {
s.address == STARDUST_ADDRESS
&& s.module.as_ident_str() == NFT_OUTPUT_MODULE_NAME
&& s.name.as_ident_str() == NFT_OUTPUT_STRUCT_NAME
}
}

impl TryFrom<&Object> for NftOutput {
type Error = IotaError;
fn try_from(object: &Object) -> Result<Self, Self::Error> {
match &object.data {
Data::Move(o) => {
if o.type_().is_nft_output() {
return NftOutput::from_bcs_bytes(o.contents());
}
}
Data::Package(_) => {}
}

Err(IotaError::Type {
error: format!("Object type is not a NftOutput: {:?}", object),
})
}
}
47 changes: 44 additions & 3 deletions crates/iota-types/src/timelock/timelock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ use crate::{
IOTA_FRAMEWORK_ADDRESS,
balance::Balance,
base_types::{IotaAddress, MoveObjectType, ObjectID, SequenceNumber, TxContext},
error::ExecutionError,
error::{ExecutionError, IotaError},
gas_coin::GasCoin,
id::UID,
object::{Data, MoveObject, Object, Owner},
};
Expand Down Expand Up @@ -202,8 +203,10 @@ where
T: Serialize + Deserialize<'de>,
{
/// Create a `TimeLock` from BCS bytes.
pub fn from_bcs_bytes(content: &'de [u8]) -> Result<Self, bcs::Error> {
bcs::from_bytes(content)
pub fn from_bcs_bytes(content: &'de [u8]) -> Result<Self, IotaError> {
bcs::from_bytes(content).map_err(|err| IotaError::ObjectDeserialization {
error: format!("Unable to deserialize TimeLock object: {:?}", err),
})
}

/// Serialize a `TimeLock` as a `Vec<u8>` of BCS.
Expand Down Expand Up @@ -234,3 +237,41 @@ pub fn is_timelocked_balance(other: &StructTag) -> bool {
_ => false,
}
}

/// Is this other StructTag representing a `TimeLock<Balance<IOTA>>`?
pub fn is_timelocked_gas_balance(other: &StructTag) -> bool {
if !is_timelock(other) {
return false;
}

if other.type_params.len() != 1 {
return false;
}

match &other.type_params[0] {
TypeTag::Struct(tag) => GasCoin::is_gas_balance(tag),
_ => false,
}
}

impl<'de, T> TryFrom<&'de Object> for TimeLock<T>
where
T: Serialize + Deserialize<'de>,
{
type Error = IotaError;

fn try_from(object: &'de Object) -> Result<Self, Self::Error> {
match &object.data {
Data::Move(o) => {
if o.type_().is_timelock() {
return TimeLock::from_bcs_bytes(o.contents());
}
}
Data::Package(_) => {}
}

Err(IotaError::Type {
error: format!("Object type is not a TimeLock: {:?}", object),
})
}
}
2 changes: 1 addition & 1 deletion crates/iota/src/genesis_ceremony.rs
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,7 @@ pub async fn run(cmd: Ceremony) -> Result<()> {
));
};

examine_genesis_checkpoint(unsigned_genesis);
examine_genesis_checkpoint(unsigned_genesis, builder.tx_migration_objects());
}

CeremonyCommand::VerifyAndSign { key_file } => {
Expand Down
Loading
Loading