Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions crates/iota-sdk-types/src/move_package.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@

use std::collections::BTreeMap;

#[cfg(feature = "hash")]
use crate::hash::Hasher;
use crate::{
Digest, ExecutionError, Identifier, ObjectId,
hash::Hasher,
version::{Version, VersionError},
};

Expand Down Expand Up @@ -137,7 +138,7 @@ pub struct TypeOrigin {
/// The name of the data type. Either refers to an enum or a struct
/// identifier.
// `struct_name` alias to support backwards compatibility with the old name
#[serde(alias = "struct_name")]
#[cfg_attr(feature = "serde", serde(alias = "struct_name"))]
pub datatype_name: Identifier,
/// ID of the package, where the given type first appeared.
pub package: ObjectId,
Expand Down Expand Up @@ -237,6 +238,7 @@ impl MovePackage {
}

/// Calculate the digest of the [MovePackage].
#[cfg(feature = "hash")]
pub fn digest(&self) -> Digest {
Self::compute_digest_for_modules_and_deps(
self.modules.values(),
Expand All @@ -249,6 +251,7 @@ impl MovePackage {
/// It is important that this function is shared across both the calculation
/// of the digest for the package, and the calculation of the digest
/// on-chain.
#[cfg(feature = "hash")]
pub fn compute_digest_for_modules_and_deps<'a>(
modules: impl IntoIterator<Item = &'a Vec<u8>>,
object_ids: impl IntoIterator<Item = &'a ObjectId>,
Expand Down
252 changes: 244 additions & 8 deletions crates/iota-sdk-types/src/transaction/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1305,7 +1305,7 @@ impl SharedObjectReference {
/// command-make-move-vector = %x05 make-move-vector
/// command-upgrade = %x06 upgrade
/// ```
#[derive(Clone, Debug, PartialEq, Eq)]
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(
feature = "schemars",
derive(schemars::JsonSchema),
Expand Down Expand Up @@ -1355,6 +1355,234 @@ impl Command {
MakeMoveVector,
Upgrade,
);

pub fn move_call(
package: ObjectId,
module: Identifier,
function: Identifier,
type_arguments: Vec<TypeTag>,
arguments: Vec<Argument>,
) -> Self {
Command::MoveCall(MoveCall {
package,
module,
function,
type_arguments,
arguments,
})
}

pub fn transfer_objects(objects: Vec<Argument>, address: Argument) -> Self {
Command::TransferObjects(TransferObjects { objects, address })
}

pub fn split_coins(coin: Argument, amounts: Vec<Argument>) -> Self {
Command::SplitCoins(SplitCoins { coin, amounts })
}

pub fn merge_coins(coin: Argument, coins_to_merge: Vec<Argument>) -> Self {
Command::MergeCoins(MergeCoins {
coin,
coins_to_merge,
})
}

pub fn publish(modules: Vec<Vec<u8>>, dependencies: Vec<ObjectId>) -> Self {
Command::Publish(Publish {
modules,
dependencies,
})
}

pub fn make_move_vector(type_: Option<TypeTag>, elements: Vec<Argument>) -> Self {
Command::MakeMoveVector(MakeMoveVector { type_, elements })
}

pub fn upgrade(
modules: Vec<Vec<u8>>,
dependencies: Vec<ObjectId>,
package: ObjectId,
ticket: Argument,
) -> Self {
Command::Upgrade(Upgrade {
modules,
dependencies,
package,
ticket,
})
}

pub fn non_system_packages_to_be_published(&self) -> Option<&Vec<Vec<u8>>> {
match self {
Command::Publish(cmd) => Some(&cmd.modules),
Command::Upgrade(cmd) => Some(&cmd.modules),
Command::MoveCall(_)
| Command::TransferObjects(_)
| Command::SplitCoins(_)
| Command::MergeCoins(_)
| Command::MakeMoveVector(_) => None,
}
}

pub fn is_input_arg_used(&self, input_arg: u16) -> bool {
Comment on lines +1415 to +1427
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add some comments like
/// If this is a Publish or Upgrade command, return the modules to
/// publish. Returns None for all other command types.

/// Returns `true` if the command uses an input argument at the given index.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is another one of those methods I think should be defined locally, unless this is somehow used everywhere

match self {
Command::MoveCall(c) => c.is_input_arg_used(input_arg),
Command::TransferObjects(TransferObjects {
objects: args,
address: arg,
})
| Command::MergeCoins(MergeCoins {
coins_to_merge: args,
coin: arg,
})
| Command::SplitCoins(SplitCoins {
amounts: args,
coin: arg,
}) => args
.iter()
.chain(iter::once(arg))
.any(|arg| matches!(arg, Argument::Input(input) if *input == input_arg)),
Command::MakeMoveVector(MakeMoveVector { elements, .. }) => elements
.iter()
.any(|arg| matches!(arg, Argument::Input(input) if *input == input_arg)),
Command::Upgrade(Upgrade { ticket, .. }) => {
matches!(ticket, Argument::Input(input) if *input == input_arg)
}
Command::Publish(_) => false,
}
}
}

pub fn write_sep<T: core::fmt::Display>(
f: &mut core::fmt::Formatter<'_>,
items: impl IntoIterator<Item = T>,
delimiters: Option<(&str, &str)>,
sep: &str,
) -> std::fmt::Result {
let mut xs = items.into_iter();
let Some(x) = xs.next() else {
return Ok(());
};
if let Some((l, _)) = delimiters {
write!(f, "{l}")?;
}
write!(f, "{x}")?;
for x in xs {
write!(f, "{sep}{x}")?;
}
if let Some((_, r)) = delimiters {
write!(f, "{r}")?;
}
Ok(())
}

impl core::fmt::Display for MoveCall {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> std::fmt::Result {
let Self {
package,
module,
function,
type_arguments,
arguments,
} = self;
write!(f, "MoveCall(")?;
write!(f, "{package}::{module}::{function}")?;
if !type_arguments.is_empty() {
write_sep(f, type_arguments, Some(("<", ">")), ",")?;
}
write_sep(f, arguments, Some(("(", ")")), ",")?;
write!(f, ")")
}
}

impl core::fmt::Display for TransferObjects {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> std::fmt::Result {
let Self { objects, address } = self;

write!(f, "TransferObjects(")?;
write_sep(f, objects, Some(("[", "]")), ",")?;
write!(f, ",{address})")
}
}

impl core::fmt::Display for SplitCoins {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> std::fmt::Result {
let Self { coin, amounts } = self;

write!(f, "SplitCoins({coin},")?;
write_sep(f, amounts, Some(("[", "]")), ",")?;
write!(f, ")")
}
}

impl core::fmt::Display for MergeCoins {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> std::fmt::Result {
let Self {
coin,
coins_to_merge,
} = self;

write!(f, "MergeCoins({coin},")?;
write_sep(f, coins_to_merge, Some(("[", "]")), ",")?;
write!(f, ")")
}
}

impl core::fmt::Display for Publish {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> std::fmt::Result {
let Self { dependencies, .. } = self;

write!(f, "Publish(_,")?;
write_sep(f, dependencies, Some(("[", "]")), ",")?;
write!(f, ")")
}
}

impl core::fmt::Display for MakeMoveVector {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> std::fmt::Result {
let Self { type_, elements } = self;

write!(f, "MakeMoveVector(")?;
if let Some(ty) = type_ {
write!(f, "Some({ty})")?;
} else {
write!(f, "None")?;
}
write!(f, ",")?;
write_sep(f, elements, Some(("[", "]")), ",")?;
write!(f, ")")
}
}

impl core::fmt::Display for Upgrade {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> std::fmt::Result {
let Self {
dependencies,
package,
ticket,
..
} = self;

write!(f, "Upgrade(_,")?;
write_sep(f, dependencies, Some(("[", "]")), ",")?;
write!(f, ", {package}")?;
write!(f, ", {ticket}")?;
write!(f, ")")
}
}

impl core::fmt::Display for Command {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Command::MoveCall(cmd) => write!(f, "{cmd}"),
Command::TransferObjects(cmd) => write!(f, "{cmd}"),
Command::SplitCoins(cmd) => write!(f, "{cmd}"),
Command::MergeCoins(cmd) => write!(f, "{cmd}"),
Command::Publish(cmd) => write!(f, "{cmd}"),
Command::MakeMoveVector(cmd) => write!(f, "{cmd}"),
Command::Upgrade(cmd) => write!(f, "{cmd}"),
}
}
}

/// Command to transfer ownership of a set of objects to an address
Expand All @@ -1366,7 +1594,7 @@ impl Command {
/// ```text
/// transfer-objects = (vector argument) argument
/// ```
#[derive(Clone, Debug, PartialEq, Eq)]
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
Expand All @@ -1387,7 +1615,7 @@ pub struct TransferObjects {
/// ```text
/// split-coins = argument (vector argument)
/// ```
#[derive(Clone, Debug, PartialEq, Eq)]
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
Expand All @@ -1408,7 +1636,7 @@ pub struct SplitCoins {
/// ```text
/// merge-coins = argument (vector argument)
/// ```
#[derive(Clone, Debug, PartialEq, Eq)]
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(
feature = "serde",
derive(serde::Serialize, serde::Deserialize),
Expand Down Expand Up @@ -1436,7 +1664,7 @@ pub struct MergeCoins {
/// publish = (vector bytes) ; the serialized move modules
/// (vector object-id) ; the set of package dependencies
/// ```
#[derive(Clone, Debug, PartialEq, Eq)]
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
Expand All @@ -1463,7 +1691,7 @@ pub struct Publish {
/// ```text
/// make-move-vector = (option type-tag) (vector argument)
/// ```
#[derive(Clone, Debug, PartialEq, Eq)]
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
Expand Down Expand Up @@ -1491,7 +1719,7 @@ pub struct MakeMoveVector {
/// object-id ; package-id of the package
/// argument ; upgrade ticket
/// ```
#[derive(Clone, Debug, PartialEq, Eq)]
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
Expand Down Expand Up @@ -1626,7 +1854,7 @@ impl Argument {
/// (vector type-tag) ; type arguments, if any
/// (vector argument) ; input arguments
/// ```
#[derive(Clone, Debug, PartialEq, Eq)]
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(
feature = "serde",
derive(serde::Serialize, serde::Deserialize),
Expand All @@ -1648,3 +1876,11 @@ pub struct MoveCall {
#[cfg_attr(feature = "proptest", any(proptest::collection::size_range(0..=2).lift()))]
pub arguments: Vec<Argument>,
}

impl MoveCall {
fn is_input_arg_used(&self, arg: u16) -> bool {
self.arguments
.iter()
.any(|a| matches!(a, Argument::Input(inp) if *inp == arg))
}
}
2 changes: 2 additions & 0 deletions crates/iota-sdk-types/src/transaction/serialization.rs
Original file line number Diff line number Diff line change
Expand Up @@ -717,6 +717,7 @@ mod command {
}

#[derive(serde::Serialize)]
#[serde(rename = "Command")]
enum BinaryCommandRef<'a> {
MoveCall(&'a MoveCall),
TransferObjects(&'a TransferObjects),
Expand All @@ -728,6 +729,7 @@ mod command {
}

#[derive(serde::Deserialize)]
#[serde(rename = "Command")]
enum BinaryCommand {
MoveCall(MoveCall),
TransferObjects(TransferObjects),
Expand Down