From 4e21cd4d38d22fd3080850ccb065b8d88f3a84b0 Mon Sep 17 00:00:00 2001 From: Chloe Martin Date: Wed, 30 Oct 2024 08:22:13 -0400 Subject: [PATCH 1/3] chore: Make more fields public and refactor some signature code --- crates/iota-rust-sdk/src/types/checkpoint.rs | 2 +- crates/iota-rust-sdk/src/types/crypto/mod.rs | 17 + .../src/types/crypto/multisig.rs | 28 +- .../iota-rust-sdk/src/types/crypto/passkey.rs | 34 +- .../src/types/crypto/signature.rs | 463 +++++++++--------- .../iota-rust-sdk/src/types/crypto/zklogin.rs | 25 +- crates/iota-rust-sdk/src/types/events.rs | 2 +- .../src/types/execution_status.rs | 10 +- crates/iota-rust-sdk/src/types/mod.rs | 26 +- crates/iota-rust-sdk/src/types/object.rs | 46 +- .../src/types/transaction/mod.rs | 14 +- .../iota-rust-sdk/src/types/type_tag/mod.rs | 2 +- 12 files changed, 357 insertions(+), 312 deletions(-) diff --git a/crates/iota-rust-sdk/src/types/checkpoint.rs b/crates/iota-rust-sdk/src/types/checkpoint.rs index 1f6edeb..f0a9e00 100644 --- a/crates/iota-rust-sdk/src/types/checkpoint.rs +++ b/crates/iota-rust-sdk/src/types/checkpoint.rs @@ -119,7 +119,7 @@ pub struct SignedCheckpointSummary { #[cfg_attr(test, derive(test_strategy::Arbitrary))] pub struct CheckpointContents( #[cfg_attr(test, any(proptest::collection::size_range(0..=2).lift()))] - Vec, + pub Vec, ); #[derive(Clone, Debug, PartialEq, Eq)] diff --git a/crates/iota-rust-sdk/src/types/crypto/mod.rs b/crates/iota-rust-sdk/src/types/crypto/mod.rs index 3e3d6ea..e290755 100644 --- a/crates/iota-rust-sdk/src/types/crypto/mod.rs +++ b/crates/iota-rust-sdk/src/types/crypto/mod.rs @@ -26,6 +26,23 @@ pub use zklogin::{ ZkLoginInputs, ZkLoginProof, ZkLoginPublicIdentifier, }; +#[derive(Debug)] +pub struct SignatureFromBytesError(String); + +impl SignatureFromBytesError { + fn new(msg: impl core::fmt::Display) -> Self { + Self(msg.to_string()) + } +} + +impl core::fmt::Display for SignatureFromBytesError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "error deserializing bytes: {}", self.0) + } +} + +impl std::error::Error for SignatureFromBytesError {} + // Implement various base64 fixed-size array helpers // diff --git a/crates/iota-rust-sdk/src/types/crypto/multisig.rs b/crates/iota-rust-sdk/src/types/crypto/multisig.rs index d99be4c..ea38382 100644 --- a/crates/iota-rust-sdk/src/types/crypto/multisig.rs +++ b/crates/iota-rust-sdk/src/types/crypto/multisig.rs @@ -132,7 +132,10 @@ mod serialization { use serde_with::{Bytes, DeserializeAs}; use super::*; - use crate::types::{Ed25519PublicKey, Secp256k1PublicKey, Secp256r1PublicKey, SignatureScheme}; + use crate::types::{ + Ed25519PublicKey, Secp256k1PublicKey, Secp256r1PublicKey, SignatureScheme, + crypto::SignatureFromBytesError, + }; #[derive(serde_derive::Deserialize)] pub struct Multisig { @@ -203,24 +206,23 @@ mod serialization { }) } else { let bytes: Cow<'de, [u8]> = Bytes::deserialize_as(deserializer)?; - Self::from_serialized_bytes(bytes) + Self::from_serialized_bytes(bytes).map_err(serde::de::Error::custom) } } } impl MultisigAggregatedSignature { - pub(crate) fn from_serialized_bytes, E: serde::de::Error>( - bytes: T, - ) -> Result { + pub fn from_serialized_bytes( + bytes: impl AsRef<[u8]>, + ) -> Result { let bytes = bytes.as_ref(); - let flag = SignatureScheme::from_byte( - *bytes - .first() - .ok_or_else(|| serde::de::Error::custom("missing signature scheme flag"))?, - ) - .map_err(serde::de::Error::custom)?; + let flag = + SignatureScheme::from_byte(*bytes.first().ok_or_else(|| { + SignatureFromBytesError::new("missing signature scheme flag") + })?) + .map_err(SignatureFromBytesError::new)?; if flag != SignatureScheme::Multisig { - return Err(serde::de::Error::custom("invalid multisig flag")); + return Err(SignatureFromBytesError::new("invalid multisig flag")); } let bcs_bytes = &bytes[1..]; @@ -231,7 +233,7 @@ mod serialization { committee: multisig.committee, }) } else { - Err(serde::de::Error::custom("invalid multisig")) + Err(SignatureFromBytesError::new("invalid multisig")) } } } diff --git a/crates/iota-rust-sdk/src/types/crypto/passkey.rs b/crates/iota-rust-sdk/src/types/crypto/passkey.rs index 9a6fad9..da6453d 100644 --- a/crates/iota-rust-sdk/src/types/crypto/passkey.rs +++ b/crates/iota-rust-sdk/src/types/crypto/passkey.rs @@ -53,7 +53,7 @@ mod serialization { use serde_with::{Bytes, DeserializeAs}; use super::*; - use crate::types::{SignatureScheme, SimpleSignature}; + use crate::types::{SignatureScheme, SimpleSignature, crypto::SignatureFromBytesError}; #[derive(serde::Serialize)] struct AuthenticatorRef<'a> { @@ -121,23 +121,24 @@ mod serialization { let bytes: Cow<'de, [u8]> = Bytes::deserialize_as(deserializer)?; Self::from_serialized_bytes(bytes) } + .map_err(serde::de::Error::custom) } } impl PasskeyAuthenticator { - fn try_from_raw( + fn try_from_raw( Authenticator { authenticator_data, client_data_json, signature, }: Authenticator, - ) -> Result { + ) -> Result { let SimpleSignature::Secp256r1 { signature, public_key, } = signature else { - return Err(serde::de::Error::custom( + return Err(SignatureFromBytesError::new( "expected passkey with secp256r1 signature", )); }; @@ -146,7 +147,7 @@ mod serialization { ty: _, challenge, origin: _, - } = serde_json::from_str(&client_data_json).map_err(serde::de::Error::custom)?; + } = serde_json::from_str(&client_data_json).map_err(SignatureFromBytesError::new)?; // challenge is 3 byte intent | 32 byte hash let mut challenge_buf = [0; 3 + Digest::LENGTH]; @@ -158,7 +159,7 @@ mod serialization { &mut challenge_buf, ) .map_err(|e| { - serde::de::Error::custom(format!( + SignatureFromBytesError::new(format!( "unable to decode base64urlunpadded into 3-byte intent and 32-byte digest: {e}" )) })?; @@ -176,22 +177,21 @@ mod serialization { }) } - pub(crate) fn from_serialized_bytes, E: serde::de::Error>( - bytes: T, - ) -> Result { + pub fn from_serialized_bytes( + bytes: impl AsRef<[u8]>, + ) -> Result { let bytes = bytes.as_ref(); - let flag = SignatureScheme::from_byte( - *bytes - .first() - .ok_or_else(|| serde::de::Error::custom("missing signature scheme flag"))?, - ) - .map_err(serde::de::Error::custom)?; + let flag = + SignatureScheme::from_byte(*bytes.first().ok_or_else(|| { + SignatureFromBytesError::new("missing signature scheme flag") + })?) + .map_err(SignatureFromBytesError::new)?; if flag != SignatureScheme::Passkey { - return Err(serde::de::Error::custom("invalid passkey flag")); + return Err(SignatureFromBytesError::new("invalid passkey flag")); } let bcs_bytes = &bytes[1..]; - let authenticator = bcs::from_bytes(bcs_bytes).map_err(serde::de::Error::custom)?; + let authenticator = bcs::from_bytes(bcs_bytes).map_err(SignatureFromBytesError::new)?; Self::try_from_raw(authenticator) } diff --git a/crates/iota-rust-sdk/src/types/crypto/signature.rs b/crates/iota-rust-sdk/src/types/crypto/signature.rs index dced092..dac9948 100644 --- a/crates/iota-rust-sdk/src/types/crypto/signature.rs +++ b/crates/iota-rust-sdk/src/types/crypto/signature.rs @@ -36,228 +36,6 @@ impl SimpleSignature { } } -impl SimpleSignature { - #[cfg(feature = "serde")] - #[cfg_attr(doc_cfg, doc(cfg(feature = "serde")))] - fn from_serialized_bytes, E: serde::de::Error>(bytes: T) -> Result { - let bytes = bytes.as_ref(); - let flag = SignatureScheme::from_byte( - *bytes - .first() - .ok_or_else(|| serde::de::Error::custom("missing signature scheme flag"))?, - ) - .map_err(serde::de::Error::custom)?; - match flag { - SignatureScheme::Ed25519 => { - let expected_length = 1 + Ed25519Signature::LENGTH + Ed25519PublicKey::LENGTH; - - if bytes.len() != expected_length { - return Err(serde::de::Error::custom("invalid ed25519 signature")); - } - - let mut signature = [0; Ed25519Signature::LENGTH]; - signature.copy_from_slice(&bytes[1..(1 + Ed25519Signature::LENGTH)]); - - let mut public_key = [0; Ed25519PublicKey::LENGTH]; - public_key.copy_from_slice(&bytes[(1 + Ed25519Signature::LENGTH)..]); - - Ok(SimpleSignature::Ed25519 { - signature: Ed25519Signature::new(signature), - public_key: Ed25519PublicKey::new(public_key), - }) - } - SignatureScheme::Secp256k1 => { - let expected_length = 1 + Secp256k1Signature::LENGTH + Secp256k1PublicKey::LENGTH; - - if bytes.len() != expected_length { - return Err(serde::de::Error::custom("invalid secp25k1 signature")); - } - - let mut signature = [0; Secp256k1Signature::LENGTH]; - signature.copy_from_slice(&bytes[1..(1 + Secp256k1Signature::LENGTH)]); - - let mut public_key = [0; Secp256k1PublicKey::LENGTH]; - public_key.copy_from_slice(&bytes[(1 + Secp256k1Signature::LENGTH)..]); - - Ok(SimpleSignature::Secp256k1 { - signature: Secp256k1Signature::new(signature), - public_key: Secp256k1PublicKey::new(public_key), - }) - } - SignatureScheme::Secp256r1 => { - let expected_length = 1 + Secp256r1Signature::LENGTH + Secp256r1PublicKey::LENGTH; - - if bytes.len() != expected_length { - return Err(serde::de::Error::custom("invalid secp25r1 signature")); - } - - let mut signature = [0; Secp256r1Signature::LENGTH]; - signature.copy_from_slice(&bytes[1..(1 + Secp256r1Signature::LENGTH)]); - - let mut public_key = [0; Secp256r1PublicKey::LENGTH]; - public_key.copy_from_slice(&bytes[(1 + Secp256r1Signature::LENGTH)..]); - - Ok(SimpleSignature::Secp256r1 { - signature: Secp256r1Signature::new(signature), - public_key: Secp256r1PublicKey::new(public_key), - }) - } - SignatureScheme::Multisig - | SignatureScheme::Bls12381 - | SignatureScheme::ZkLogin - | SignatureScheme::Passkey => Err(serde::de::Error::custom("invalid signature scheme")), - } - } -} - -#[cfg(feature = "serde")] -#[cfg_attr(doc_cfg, doc(cfg(feature = "serde")))] -impl serde::Serialize for SimpleSignature { - fn serialize(&self, serializer: S) -> Result - where - S: serde::Serializer, - { - #[derive(serde_derive::Serialize)] - #[serde(tag = "scheme")] - #[serde(rename_all = "lowercase")] - enum Sig<'a> { - Ed25519 { - signature: &'a Ed25519Signature, - public_key: &'a Ed25519PublicKey, - }, - Secp256k1 { - signature: &'a Secp256k1Signature, - public_key: &'a Secp256k1PublicKey, - }, - Secp256r1 { - signature: &'a Secp256r1Signature, - public_key: &'a Secp256r1PublicKey, - }, - } - - if serializer.is_human_readable() { - let sig = match self { - SimpleSignature::Ed25519 { - signature, - public_key, - } => Sig::Ed25519 { - signature, - public_key, - }, - SimpleSignature::Secp256k1 { - signature, - public_key, - } => Sig::Secp256k1 { - signature, - public_key, - }, - SimpleSignature::Secp256r1 { - signature, - public_key, - } => Sig::Secp256r1 { - signature, - public_key, - }, - }; - - sig.serialize(serializer) - } else { - match self { - SimpleSignature::Ed25519 { - signature, - public_key, - } => { - let mut buf = [0; 1 + Ed25519Signature::LENGTH + Ed25519PublicKey::LENGTH]; - buf[0] = SignatureScheme::Ed25519 as u8; - buf[1..(1 + Ed25519Signature::LENGTH)].copy_from_slice(signature.as_ref()); - buf[(1 + Ed25519Signature::LENGTH)..].copy_from_slice(public_key.as_ref()); - - serializer.serialize_bytes(&buf) - } - SimpleSignature::Secp256k1 { - signature, - public_key, - } => { - let mut buf = [0; 1 + Secp256k1Signature::LENGTH + Secp256k1PublicKey::LENGTH]; - buf[0] = SignatureScheme::Secp256k1 as u8; - buf[1..(1 + Secp256k1Signature::LENGTH)].copy_from_slice(signature.as_ref()); - buf[(1 + Secp256k1Signature::LENGTH)..].copy_from_slice(public_key.as_ref()); - - serializer.serialize_bytes(&buf) - } - SimpleSignature::Secp256r1 { - signature, - public_key, - } => { - let mut buf = [0; 1 + Secp256r1Signature::LENGTH + Secp256r1PublicKey::LENGTH]; - buf[0] = SignatureScheme::Secp256r1 as u8; - buf[1..(1 + Secp256r1Signature::LENGTH)].copy_from_slice(signature.as_ref()); - buf[(1 + Secp256r1Signature::LENGTH)..].copy_from_slice(public_key.as_ref()); - - serializer.serialize_bytes(&buf) - } - } - } - } -} - -#[cfg(feature = "serde")] -#[cfg_attr(doc_cfg, doc(cfg(feature = "serde")))] -impl<'de> serde::Deserialize<'de> for SimpleSignature { - fn deserialize(deserializer: D) -> Result - where - D: serde::Deserializer<'de>, - { - #[derive(serde_derive::Deserialize)] - #[serde(tag = "scheme")] - #[serde(rename_all = "lowercase")] - enum Sig { - Ed25519 { - signature: Ed25519Signature, - public_key: Ed25519PublicKey, - }, - Secp256k1 { - signature: Secp256k1Signature, - public_key: Secp256k1PublicKey, - }, - Secp256r1 { - signature: Secp256r1Signature, - public_key: Secp256r1PublicKey, - }, - } - - if deserializer.is_human_readable() { - let sig = Sig::deserialize(deserializer)?; - Ok(match sig { - Sig::Ed25519 { - signature, - public_key, - } => SimpleSignature::Ed25519 { - signature, - public_key, - }, - Sig::Secp256k1 { - signature, - public_key, - } => SimpleSignature::Secp256k1 { - signature, - public_key, - }, - Sig::Secp256r1 { - signature, - public_key, - } => SimpleSignature::Secp256r1 { - signature, - public_key, - }, - }) - } else { - let bytes: std::borrow::Cow<'de, [u8]> = std::borrow::Cow::deserialize(deserializer)?; - Self::from_serialized_bytes(bytes) - } - } -} - #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(test, derive(test_strategy::Arbitrary))] #[repr(u8)] @@ -365,6 +143,235 @@ impl UserSignature { #[cfg_attr(doc_cfg, doc(cfg(feature = "serde")))] mod serialization { use super::*; + use crate::types::crypto::SignatureFromBytesError; + + impl SimpleSignature { + pub fn from_serialized_bytes( + bytes: impl AsRef<[u8]>, + ) -> Result { + let bytes = bytes.as_ref(); + let flag = + SignatureScheme::from_byte(*bytes.first().ok_or_else(|| { + SignatureFromBytesError::new("missing signature scheme flag") + })?) + .map_err(SignatureFromBytesError::new)?; + match flag { + SignatureScheme::Ed25519 => { + let expected_length = 1 + Ed25519Signature::LENGTH + Ed25519PublicKey::LENGTH; + + if bytes.len() != expected_length { + return Err(SignatureFromBytesError::new("invalid ed25519 signature")); + } + + let mut signature = [0; Ed25519Signature::LENGTH]; + signature.copy_from_slice(&bytes[1..(1 + Ed25519Signature::LENGTH)]); + + let mut public_key = [0; Ed25519PublicKey::LENGTH]; + public_key.copy_from_slice(&bytes[(1 + Ed25519Signature::LENGTH)..]); + + Ok(SimpleSignature::Ed25519 { + signature: Ed25519Signature::new(signature), + public_key: Ed25519PublicKey::new(public_key), + }) + } + SignatureScheme::Secp256k1 => { + let expected_length = + 1 + Secp256k1Signature::LENGTH + Secp256k1PublicKey::LENGTH; + + if bytes.len() != expected_length { + return Err(SignatureFromBytesError::new("invalid secp25k1 signature")); + } + + let mut signature = [0; Secp256k1Signature::LENGTH]; + signature.copy_from_slice(&bytes[1..(1 + Secp256k1Signature::LENGTH)]); + + let mut public_key = [0; Secp256k1PublicKey::LENGTH]; + public_key.copy_from_slice(&bytes[(1 + Secp256k1Signature::LENGTH)..]); + + Ok(SimpleSignature::Secp256k1 { + signature: Secp256k1Signature::new(signature), + public_key: Secp256k1PublicKey::new(public_key), + }) + } + SignatureScheme::Secp256r1 => { + let expected_length = + 1 + Secp256r1Signature::LENGTH + Secp256r1PublicKey::LENGTH; + + if bytes.len() != expected_length { + return Err(SignatureFromBytesError::new("invalid secp25r1 signature")); + } + + let mut signature = [0; Secp256r1Signature::LENGTH]; + signature.copy_from_slice(&bytes[1..(1 + Secp256r1Signature::LENGTH)]); + + let mut public_key = [0; Secp256r1PublicKey::LENGTH]; + public_key.copy_from_slice(&bytes[(1 + Secp256r1Signature::LENGTH)..]); + + Ok(SimpleSignature::Secp256r1 { + signature: Secp256r1Signature::new(signature), + public_key: Secp256r1PublicKey::new(public_key), + }) + } + SignatureScheme::Multisig + | SignatureScheme::Bls12381 + | SignatureScheme::ZkLogin + | SignatureScheme::Passkey => { + Err(SignatureFromBytesError::new("invalid signature scheme")) + } + } + } + } + + impl serde::Serialize for SimpleSignature { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + #[derive(serde_derive::Serialize)] + #[serde(tag = "scheme")] + #[serde(rename_all = "lowercase")] + enum Sig<'a> { + Ed25519 { + signature: &'a Ed25519Signature, + public_key: &'a Ed25519PublicKey, + }, + Secp256k1 { + signature: &'a Secp256k1Signature, + public_key: &'a Secp256k1PublicKey, + }, + Secp256r1 { + signature: &'a Secp256r1Signature, + public_key: &'a Secp256r1PublicKey, + }, + } + + if serializer.is_human_readable() { + let sig = match self { + SimpleSignature::Ed25519 { + signature, + public_key, + } => Sig::Ed25519 { + signature, + public_key, + }, + SimpleSignature::Secp256k1 { + signature, + public_key, + } => Sig::Secp256k1 { + signature, + public_key, + }, + SimpleSignature::Secp256r1 { + signature, + public_key, + } => Sig::Secp256r1 { + signature, + public_key, + }, + }; + + sig.serialize(serializer) + } else { + match self { + SimpleSignature::Ed25519 { + signature, + public_key, + } => { + let mut buf = [0; 1 + Ed25519Signature::LENGTH + Ed25519PublicKey::LENGTH]; + buf[0] = SignatureScheme::Ed25519 as u8; + buf[1..(1 + Ed25519Signature::LENGTH)].copy_from_slice(signature.as_ref()); + buf[(1 + Ed25519Signature::LENGTH)..].copy_from_slice(public_key.as_ref()); + + serializer.serialize_bytes(&buf) + } + SimpleSignature::Secp256k1 { + signature, + public_key, + } => { + let mut buf = + [0; 1 + Secp256k1Signature::LENGTH + Secp256k1PublicKey::LENGTH]; + buf[0] = SignatureScheme::Secp256k1 as u8; + buf[1..(1 + Secp256k1Signature::LENGTH)] + .copy_from_slice(signature.as_ref()); + buf[(1 + Secp256k1Signature::LENGTH)..] + .copy_from_slice(public_key.as_ref()); + + serializer.serialize_bytes(&buf) + } + SimpleSignature::Secp256r1 { + signature, + public_key, + } => { + let mut buf = + [0; 1 + Secp256r1Signature::LENGTH + Secp256r1PublicKey::LENGTH]; + buf[0] = SignatureScheme::Secp256r1 as u8; + buf[1..(1 + Secp256r1Signature::LENGTH)] + .copy_from_slice(signature.as_ref()); + buf[(1 + Secp256r1Signature::LENGTH)..] + .copy_from_slice(public_key.as_ref()); + + serializer.serialize_bytes(&buf) + } + } + } + } + } + + impl<'de> serde::Deserialize<'de> for SimpleSignature { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + #[derive(serde_derive::Deserialize)] + #[serde(tag = "scheme")] + #[serde(rename_all = "lowercase")] + enum Sig { + Ed25519 { + signature: Ed25519Signature, + public_key: Ed25519PublicKey, + }, + Secp256k1 { + signature: Secp256k1Signature, + public_key: Secp256k1PublicKey, + }, + Secp256r1 { + signature: Secp256r1Signature, + public_key: Secp256r1PublicKey, + }, + } + + if deserializer.is_human_readable() { + let sig = Sig::deserialize(deserializer)?; + Ok(match sig { + Sig::Ed25519 { + signature, + public_key, + } => SimpleSignature::Ed25519 { + signature, + public_key, + }, + Sig::Secp256k1 { + signature, + public_key, + } => SimpleSignature::Secp256k1 { + signature, + public_key, + }, + Sig::Secp256r1 { + signature, + public_key, + } => SimpleSignature::Secp256r1 { + signature, + public_key, + }, + }) + } else { + let bytes: std::borrow::Cow<'de, [u8]> = + std::borrow::Cow::deserialize(deserializer)?; + Self::from_serialized_bytes(bytes).map_err(serde::de::Error::custom) + } + } + } #[derive(serde_derive::Serialize)] #[serde(tag = "scheme", rename_all = "lowercase")] @@ -512,22 +519,26 @@ mod serialization { SignatureScheme::Ed25519 | SignatureScheme::Secp256k1 | SignatureScheme::Secp256r1 => { - let simple = SimpleSignature::from_serialized_bytes(bytes)?; + let simple = SimpleSignature::from_serialized_bytes(bytes) + .map_err(serde::de::Error::custom)?; Ok(Self::Simple(simple)) } SignatureScheme::Multisig => { - let multisig = MultisigAggregatedSignature::from_serialized_bytes(bytes)?; + let multisig = MultisigAggregatedSignature::from_serialized_bytes(bytes) + .map_err(serde::de::Error::custom)?; Ok(Self::Multisig(multisig)) } SignatureScheme::Bls12381 => Err(serde::de::Error::custom( "bls not supported for user signatures", )), SignatureScheme::ZkLogin => { - let zklogin = ZkLoginAuthenticator::from_serialized_bytes(bytes)?; + let zklogin = ZkLoginAuthenticator::from_serialized_bytes(bytes) + .map_err(serde::de::Error::custom)?; Ok(Self::ZkLogin(Box::new(zklogin))) } SignatureScheme::Passkey => { - let passkey = PasskeyAuthenticator::from_serialized_bytes(bytes)?; + let passkey = PasskeyAuthenticator::from_serialized_bytes(bytes) + .map_err(serde::de::Error::custom)?; Ok(Self::Passkey(passkey)) } } diff --git a/crates/iota-rust-sdk/src/types/crypto/zklogin.rs b/crates/iota-rust-sdk/src/types/crypto/zklogin.rs index 35b4e67..88820fb 100644 --- a/crates/iota-rust-sdk/src/types/crypto/zklogin.rs +++ b/crates/iota-rust-sdk/src/types/crypto/zklogin.rs @@ -253,7 +253,7 @@ mod serialization { use serde_with::{Bytes, DeserializeAs, SerializeAs}; use super::*; - use crate::types::SignatureScheme; + use crate::types::{SignatureScheme, crypto::SignatureFromBytesError}; // Serialized format is: iss_bytes_len || iss_bytes || // padded_32_byte_address_seed. @@ -382,24 +382,23 @@ mod serialization { }) } else { let bytes: Cow<'de, [u8]> = Bytes::deserialize_as(deserializer)?; - Self::from_serialized_bytes(bytes) + Self::from_serialized_bytes(bytes).map_err(serde::de::Error::custom) } } } impl ZkLoginAuthenticator { - pub(crate) fn from_serialized_bytes, E: serde::de::Error>( - bytes: T, - ) -> Result { + pub fn from_serialized_bytes( + bytes: impl AsRef<[u8]>, + ) -> Result { let bytes = bytes.as_ref(); - let flag = SignatureScheme::from_byte( - *bytes - .first() - .ok_or_else(|| serde::de::Error::custom("missing signature scheme flag"))?, - ) - .map_err(serde::de::Error::custom)?; + let flag = + SignatureScheme::from_byte(*bytes.first().ok_or_else(|| { + SignatureFromBytesError::new("missing signature scheme flag") + })?) + .map_err(SignatureFromBytesError::new)?; if flag != SignatureScheme::ZkLogin { - return Err(serde::de::Error::custom("invalid zklogin flag")); + return Err(SignatureFromBytesError::new("invalid zklogin flag")); } let bcs_bytes = &bytes[1..]; @@ -407,7 +406,7 @@ mod serialization { inputs, max_epoch, signature, - } = bcs::from_bytes(bcs_bytes).map_err(serde::de::Error::custom)?; + } = bcs::from_bytes(bcs_bytes).map_err(SignatureFromBytesError::new)?; Ok(Self { inputs, max_epoch, diff --git a/crates/iota-rust-sdk/src/types/events.rs b/crates/iota-rust-sdk/src/types/events.rs index 601c75c..41cb858 100644 --- a/crates/iota-rust-sdk/src/types/events.rs +++ b/crates/iota-rust-sdk/src/types/events.rs @@ -7,7 +7,7 @@ use super::{Address, Identifier, ObjectId, StructTag, TypeTag}; )] #[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] #[cfg_attr(test, derive(test_strategy::Arbitrary))] -pub struct TransactionEvents(Vec); +pub struct TransactionEvents(pub Vec); /// Specific type of event #[derive(PartialEq, Eq, Debug, Clone)] diff --git a/crates/iota-rust-sdk/src/types/execution_status.rs b/crates/iota-rust-sdk/src/types/execution_status.rs index bf07616..67ef4e6 100644 --- a/crates/iota-rust-sdk/src/types/execution_status.rs +++ b/crates/iota-rust-sdk/src/types/execution_status.rs @@ -147,7 +147,7 @@ pub enum ExecutionError { CertificateDenied, /// Iota Move Bytecode verification timed out. - IotaMoveVerificationTimedout, + IotaMoveVerificationTimeout, /// The requested shared object operation is not allowed SharedObjectOperationNotAllowed, @@ -650,7 +650,7 @@ mod serialization { max_object_size, }, Self::CertificateDenied => ReadableExecutionError::CertificateDenied, - Self::IotaMoveVerificationTimedout => { + Self::IotaMoveVerificationTimeout => { ReadableExecutionError::IotaMoveVerificationTimedout } Self::SharedObjectOperationNotAllowed => { @@ -759,7 +759,7 @@ mod serialization { max_object_size, }, Self::CertificateDenied => BinaryExecutionError::CertificateDenied, - Self::IotaMoveVerificationTimedout => { + Self::IotaMoveVerificationTimeout => { BinaryExecutionError::IotaMoveVerificationTimedout } Self::SharedObjectOperationNotAllowed => { @@ -882,7 +882,7 @@ mod serialization { }, ReadableExecutionError::CertificateDenied => Self::CertificateDenied, ReadableExecutionError::IotaMoveVerificationTimedout => { - Self::IotaMoveVerificationTimedout + Self::IotaMoveVerificationTimeout } ReadableExecutionError::SharedObjectOperationNotAllowed => { Self::SharedObjectOperationNotAllowed @@ -988,7 +988,7 @@ mod serialization { }, BinaryExecutionError::CertificateDenied => Self::CertificateDenied, BinaryExecutionError::IotaMoveVerificationTimedout => { - Self::IotaMoveVerificationTimedout + Self::IotaMoveVerificationTimeout } BinaryExecutionError::SharedObjectOperationNotAllowed => { Self::SharedObjectOperationNotAllowed diff --git a/crates/iota-rust-sdk/src/types/mod.rs b/crates/iota-rust-sdk/src/types/mod.rs index 578a55a..07b9f7c 100644 --- a/crates/iota-rust-sdk/src/types/mod.rs +++ b/crates/iota-rust-sdk/src/types/mod.rs @@ -1,17 +1,17 @@ -mod address; -mod checkpoint; -mod crypto; -mod digest; -mod effects; -mod events; -mod execution_status; +pub mod address; +pub mod checkpoint; +pub mod crypto; +pub mod digest; +pub mod effects; +pub mod events; +pub mod execution_status; pub mod framework; -mod gas; -mod object; -mod object_id; -mod transaction; -mod type_tag; -mod u256; +pub mod gas; +pub mod object; +pub mod object_id; +pub mod transaction; +pub mod type_tag; +pub mod u256; pub use address::Address; pub use checkpoint::{ diff --git a/crates/iota-rust-sdk/src/types/object.rs b/crates/iota-rust-sdk/src/types/object.rs index b92c872..50937ac 100644 --- a/crates/iota-rust-sdk/src/types/object.rs +++ b/crates/iota-rust-sdk/src/types/object.rs @@ -104,7 +104,7 @@ pub enum ObjectData { )] #[cfg_attr(test, derive(test_strategy::Arbitrary))] pub struct MovePackage { - id: ObjectId, + pub id: ObjectId, /// Most move packages are uniquely identified by their ID (i.e. there is /// only one version per ID), but the version is still stored because /// one package may be an upgrade of another (at a different ID), in @@ -117,7 +117,7 @@ pub struct MovePackage { /// In all cases, packages are referred to by move calls using just their /// ID, and they are always loaded at their latest version. #[cfg_attr(feature = "serde", serde(with = "crate::_serde::ReadableDisplay"))] - version: Version, + pub version: Version, #[cfg_attr( feature = "serde", @@ -129,11 +129,11 @@ pub struct MovePackage { proptest::collection::btree_map(proptest::arbitrary::any::(), proptest::collection::vec(proptest::arbitrary::any::(), 0..=1024), 0..=5) ) )] - modules: BTreeMap>, + pub modules: BTreeMap>, /// Maps struct/module to a package version where it was first defined, /// stored as a vector for simple serialization and deserialization. - type_origin_table: Vec, + pub type_origin_table: Vec, // For each dependency, maps original package ID to the info about the (upgraded) dependency // version that this package is using @@ -143,7 +143,7 @@ pub struct MovePackage { proptest::collection::btree_map(proptest::arbitrary::any::(), proptest::arbitrary::any::(), 0..=5) ) )] - linkage_table: BTreeMap, + pub linkage_table: BTreeMap, } /// Identifies a struct and the module it was defined in @@ -189,23 +189,39 @@ pub struct MoveStruct { feature = "serde", serde(with = "::serde_with::As::") )] - pub(crate) type_: StructTag, + pub type_: StructTag, /// DEPRECATED this field is no longer used to determine whether a tx can /// transfer this object. Instead, it is always calculated from the /// objects type when loaded in execution - has_public_transfer: bool, + pub has_public_transfer: bool, /// Number that increases each time a tx takes this object as a mutable /// input This is a lamport timestamp, not a sequentially increasing /// version #[cfg_attr(feature = "serde", serde(with = "crate::_serde::ReadableDisplay"))] - version: Version, + pub version: Version, /// BCS bytes of a Move struct value #[cfg_attr( feature = "serde", serde(with = "::serde_with::As::<::serde_with::Bytes>") )] #[cfg_attr(test, any(proptest::collection::size_range(32..=1024).lift()))] - pub(crate) contents: Vec, + pub contents: Vec, +} + +impl MoveStruct { + pub fn new( + type_: StructTag, + has_public_transfer: bool, + version: Version, + contents: Vec, + ) -> Self { + Self { + type_, + has_public_transfer, + version, + contents, + } + } } /// Type of a Iota object @@ -221,15 +237,15 @@ pub enum ObjectType { #[cfg_attr(test, derive(test_strategy::Arbitrary))] pub struct Object { /// The meat of the object - pub(crate) data: ObjectData, + pub data: ObjectData, /// The owner that unlocks this object - owner: Owner, + pub owner: Owner, /// The digest of the transaction that created or last mutated this object - previous_transaction: TransactionDigest, + pub previous_transaction: TransactionDigest, /// The amount of IOTA we would rebate if this object gets deleted. /// This number is re-calculated each time the object is mutated based on /// the present storage gas price. - storage_rebate: u64, + pub storage_rebate: u64, } impl Object { @@ -272,8 +288,8 @@ fn id_opt(contents: &[u8]) -> Option { #[derive(Clone, Debug, PartialEq, Eq)] #[cfg_attr(test, derive(test_strategy::Arbitrary))] pub struct GenesisObject { - data: ObjectData, - owner: Owner, + pub data: ObjectData, + pub owner: Owner, } impl GenesisObject { diff --git a/crates/iota-rust-sdk/src/types/transaction/mod.rs b/crates/iota-rust-sdk/src/types/transaction/mod.rs index c530eb1..0676e34 100644 --- a/crates/iota-rust-sdk/src/types/transaction/mod.rs +++ b/crates/iota-rust-sdk/src/types/transaction/mod.rs @@ -227,9 +227,9 @@ pub enum ConsensusDeterminedVersionAssignments { #[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] #[cfg_attr(test, derive(test_strategy::Arbitrary))] pub struct CancelledTransaction { - digest: TransactionDigest, + pub digest: TransactionDigest, #[cfg_attr(test, any(proptest::collection::size_range(0..=2).lift()))] - version_assignments: Vec, + pub version_assignments: Vec, } #[derive(Clone, Debug, PartialEq, Eq)] @@ -240,10 +240,10 @@ pub struct CancelledTransaction { #[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] #[cfg_attr(test, derive(test_strategy::Arbitrary))] pub struct VersionAssignment { - object_id: ObjectId, + pub object_id: ObjectId, #[cfg_attr(feature = "serde", serde(with = "crate::_serde::ReadableDisplay"))] #[cfg_attr(feature = "schemars", schemars(with = "crate::_schemars::U64"))] - version: Version, + pub version: Version, } #[derive(Clone, Debug, PartialEq, Eq)] @@ -336,7 +336,7 @@ pub struct ChangeEpoch { pub struct SystemPackage { #[cfg_attr(feature = "serde", serde(with = "crate::_serde::ReadableDisplay"))] #[cfg_attr(feature = "schemars", schemars(with = "crate::_schemars::U64"))] - version: Version, + pub version: Version, #[cfg_attr( feature = "serde", serde( @@ -345,8 +345,8 @@ pub struct SystemPackage { )] #[cfg_attr(feature = "schemars", schemars(with = "Vec"))] #[cfg_attr(test, any(proptest::collection::size_range(0..=2).lift()))] - modules: Vec>, - dependencies: Vec, + pub modules: Vec>, + pub dependencies: Vec, } #[derive(Clone, Debug, PartialEq, Eq)] diff --git a/crates/iota-rust-sdk/src/types/type_tag/mod.rs b/crates/iota-rust-sdk/src/types/type_tag/mod.rs index 8bd5aac..83d0ac3 100644 --- a/crates/iota-rust-sdk/src/types/type_tag/mod.rs +++ b/crates/iota-rust-sdk/src/types/type_tag/mod.rs @@ -77,7 +77,7 @@ pub struct Identifier( ); impl Identifier { - pub fn new>(identifier: T) -> Result { + pub fn new(identifier: impl AsRef) -> Result { parse::parse_identifier(identifier.as_ref()) .map(|ident| Self(ident.into())) .map_err(|_| TypeParseError) From 29ba58ba3486419f5f7a456d5fd66d2b5e7bd3a7 Mon Sep 17 00:00:00 2001 From: Chloe Martin Date: Wed, 30 Oct 2024 09:04:12 -0400 Subject: [PATCH 2/3] cleanup --- crates/iota-rust-sdk/src/types/crypto/mod.rs | 4 ++++ crates/iota-rust-sdk/src/types/object.rs | 16 ---------------- .../iota-rust-sdk/src/types/transaction/mod.rs | 8 +++++--- 3 files changed, 9 insertions(+), 19 deletions(-) diff --git a/crates/iota-rust-sdk/src/types/crypto/mod.rs b/crates/iota-rust-sdk/src/types/crypto/mod.rs index e290755..6485fd5 100644 --- a/crates/iota-rust-sdk/src/types/crypto/mod.rs +++ b/crates/iota-rust-sdk/src/types/crypto/mod.rs @@ -26,21 +26,25 @@ pub use zklogin::{ ZkLoginInputs, ZkLoginProof, ZkLoginPublicIdentifier, }; +#[cfg(feature = "serde")] #[derive(Debug)] pub struct SignatureFromBytesError(String); +#[cfg(feature = "serde")] impl SignatureFromBytesError { fn new(msg: impl core::fmt::Display) -> Self { Self(msg.to_string()) } } +#[cfg(feature = "serde")] impl core::fmt::Display for SignatureFromBytesError { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(f, "error deserializing bytes: {}", self.0) } } +#[cfg(feature = "serde")] impl std::error::Error for SignatureFromBytesError {} // Implement various base64 fixed-size array helpers diff --git a/crates/iota-rust-sdk/src/types/object.rs b/crates/iota-rust-sdk/src/types/object.rs index 50937ac..d94704a 100644 --- a/crates/iota-rust-sdk/src/types/object.rs +++ b/crates/iota-rust-sdk/src/types/object.rs @@ -208,22 +208,6 @@ pub struct MoveStruct { pub contents: Vec, } -impl MoveStruct { - pub fn new( - type_: StructTag, - has_public_transfer: bool, - version: Version, - contents: Vec, - ) -> Self { - Self { - type_, - has_public_transfer, - version, - contents, - } - } -} - /// Type of a Iota object #[derive(Clone, Ord, PartialOrd, Eq, PartialEq, Debug)] pub enum ObjectType { diff --git a/crates/iota-rust-sdk/src/types/transaction/mod.rs b/crates/iota-rust-sdk/src/types/transaction/mod.rs index 0676e34..ab43ed9 100644 --- a/crates/iota-rust-sdk/src/types/transaction/mod.rs +++ b/crates/iota-rust-sdk/src/types/transaction/mod.rs @@ -1,7 +1,7 @@ use super::{ - Address, CheckpointTimestamp, ConsensusCommitDigest, EpochId, GenesisObject, Identifier, Jwk, - JwkId, ObjectId, ObjectReference, ProtocolVersion, TransactionDigest, TypeTag, UserSignature, - Version, + Address, CheckpointTimestamp, ConsensusCommitDigest, EpochId, Event, GenesisObject, Identifier, + Jwk, JwkId, ObjectId, ObjectReference, ProtocolVersion, TransactionDigest, TypeTag, + UserSignature, Version, }; #[cfg(feature = "serde")] @@ -359,6 +359,8 @@ pub struct SystemPackage { pub struct GenesisTransaction { #[cfg_attr(test, any(proptest::collection::size_range(0..=2).lift()))] pub objects: Vec, + #[cfg_attr(test, any(proptest::collection::size_range(0..=2).lift()))] + pub events: Vec, } /// A series of commands where the results of one command can be used in future From 29600a1d17059be15ca4ad31aab9c93dffd284e9 Mon Sep 17 00:00:00 2001 From: Chloe Martin Date: Wed, 30 Oct 2024 09:12:14 -0400 Subject: [PATCH 3/3] more renames --- crates/iota-rust-sdk/src/types/execution_status.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/crates/iota-rust-sdk/src/types/execution_status.rs b/crates/iota-rust-sdk/src/types/execution_status.rs index 67ef4e6..f111140 100644 --- a/crates/iota-rust-sdk/src/types/execution_status.rs +++ b/crates/iota-rust-sdk/src/types/execution_status.rs @@ -453,7 +453,7 @@ mod serialization { max_object_size: u64, }, CertificateDenied, - IotaMoveVerificationTimedout, + IotaMoveVerificationTimeout, SharedObjectOperationNotAllowed, InputObjectDeleted, ExecutionCancelledDueToSharedObjectCongestion { @@ -536,7 +536,7 @@ mod serialization { max_object_size: u64, }, CertificateDenied, - IotaMoveVerificationTimedout, + IotaMoveVerificationTimeout, SharedObjectOperationNotAllowed, InputObjectDeleted, ExecutionCancelledDueToSharedObjectCongestion { @@ -651,7 +651,7 @@ mod serialization { }, Self::CertificateDenied => ReadableExecutionError::CertificateDenied, Self::IotaMoveVerificationTimeout => { - ReadableExecutionError::IotaMoveVerificationTimedout + ReadableExecutionError::IotaMoveVerificationTimeout } Self::SharedObjectOperationNotAllowed => { ReadableExecutionError::SharedObjectOperationNotAllowed @@ -760,7 +760,7 @@ mod serialization { }, Self::CertificateDenied => BinaryExecutionError::CertificateDenied, Self::IotaMoveVerificationTimeout => { - BinaryExecutionError::IotaMoveVerificationTimedout + BinaryExecutionError::IotaMoveVerificationTimeout } Self::SharedObjectOperationNotAllowed => { BinaryExecutionError::SharedObjectOperationNotAllowed @@ -881,7 +881,7 @@ mod serialization { max_object_size, }, ReadableExecutionError::CertificateDenied => Self::CertificateDenied, - ReadableExecutionError::IotaMoveVerificationTimedout => { + ReadableExecutionError::IotaMoveVerificationTimeout => { Self::IotaMoveVerificationTimeout } ReadableExecutionError::SharedObjectOperationNotAllowed => { @@ -987,7 +987,7 @@ mod serialization { max_object_size, }, BinaryExecutionError::CertificateDenied => Self::CertificateDenied, - BinaryExecutionError::IotaMoveVerificationTimedout => { + BinaryExecutionError::IotaMoveVerificationTimeout => { Self::IotaMoveVerificationTimeout } BinaryExecutionError::SharedObjectOperationNotAllowed => {