From 8ca4054375a44f98abdaa081fa42248948b8aad6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thoralf=20M=C3=BCller?= Date: Fri, 8 Dec 2023 15:19:03 +0100 Subject: [PATCH] Move OutputIdProof to block types --- sdk/src/types/api/core.rs | 77 +--------------- sdk/src/types/block/output/mod.rs | 17 ++-- sdk/src/types/block/output/output_id_proof.rs | 90 +++++++++++++++++++ .../operations/syncing/addresses/outputs.rs | 5 +- sdk/src/wallet/operations/syncing/mod.rs | 2 +- sdk/src/wallet/types/mod.rs | 4 +- 6 files changed, 103 insertions(+), 92 deletions(-) create mode 100644 sdk/src/types/block/output/output_id_proof.rs diff --git a/sdk/src/types/api/core.rs b/sdk/src/types/api/core.rs index ea8b859d6c..a6e093e80d 100644 --- a/sdk/src/types/api/core.rs +++ b/sdk/src/types/api/core.rs @@ -4,13 +4,11 @@ use alloc::{ boxed::Box, collections::{BTreeMap, BTreeSet}, - format, string::String, vec::Vec, }; use serde::{Deserialize, Serialize}; -use serde_json::Value; use crate::{ types::block::{ @@ -23,7 +21,7 @@ use crate::{ slot::{EpochIndex, SlotCommitment, SlotCommitmentId, SlotIndex}, BlockDto, BlockId, }, - utils::serde::{option_string, prefix_hex_bytes, string}, + utils::serde::{option_string, string}, }; /// Response of GET /api/core/v3/info. @@ -539,76 +537,3 @@ pub struct UtxoChangesResponse { // pub output: Output, // pub output_id_proof: OutputIdProof, // } - -/// The proof of the output identifier. -#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct OutputIdProof { - pub slot: SlotIndex, - pub output_index: u16, - pub transaction_commitment: String, - pub output_commitment_proof: OutputCommitmentProof, -} - -#[derive(Clone, Debug, Eq, PartialEq, Serialize)] -#[serde(untagged)] -pub enum OutputCommitmentProof { - HashableNode(HashableNode), - LeafHash(LeafHash), - ValueHash(ValueHash), -} - -impl<'de> Deserialize<'de> for OutputCommitmentProof { - fn deserialize>(d: D) -> Result { - let value = Value::deserialize(d)?; - Ok( - match value - .get("type") - .and_then(Value::as_u64) - .ok_or_else(|| serde::de::Error::custom("invalid output commitment proof type"))? - as u8 - { - 0 => Self::HashableNode( - serde_json::from_value::(value) - .map_err(|e| serde::de::Error::custom(format!("cannot deserialize hashable node: {e}")))?, - ), - 1 => Self::LeafHash( - serde_json::from_value::(value) - .map_err(|e| serde::de::Error::custom(format!("cannot deserialize leaf hash: {e}")))?, - ), - 2 => Self::ValueHash( - serde_json::from_value::(value) - .map_err(|e| serde::de::Error::custom(format!("cannot deserialize value hash: {e}")))?, - ), - _ => return Err(serde::de::Error::custom("invalid output commitment proof")), - }, - ) - } -} - -/// Node contains the hashes of the left and right children of a node in the tree. -#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)] -pub struct HashableNode { - #[serde(rename = "type")] - pub kind: u8, - pub l: Box, - pub r: Box, -} - -/// Leaf Hash contains the hash of a leaf in the tree. -#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)] -pub struct LeafHash { - #[serde(rename = "type")] - pub kind: u8, - #[serde(with = "prefix_hex_bytes")] - pub hash: [u8; 32], -} - -/// Value Hash contains the hash of the value for which the proof is being computed. -#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)] -pub struct ValueHash { - #[serde(rename = "type")] - pub kind: u8, - #[serde(with = "prefix_hex_bytes")] - pub hash: [u8; 32], -} diff --git a/sdk/src/types/block/output/mod.rs b/sdk/src/types/block/output/mod.rs index 06cec2e5e2..01945ecf00 100644 --- a/sdk/src/types/block/output/mod.rs +++ b/sdk/src/types/block/output/mod.rs @@ -7,6 +7,7 @@ mod delegation; mod metadata; mod native_token; mod output_id; +mod output_id_proof; mod state_transition; mod storage_score; mod token_scheme; @@ -50,17 +51,15 @@ pub(crate) use self::{ feature::{MetadataFeatureLength, TagFeatureLength}, native_token::NativeTokenCount, output_id::OutputIndex, + output_id_proof::OutputIdProof, unlock_condition::AddressUnlockCondition, }; -use crate::types::{ - api::core::OutputIdProof, - block::{ - address::Address, - protocol::{CommittableAgeRange, ProtocolParameters, WorkScore, WorkScoreParameters}, - semantic::SemanticValidationContext, - slot::SlotIndex, - Error, - }, +use crate::types::block::{ + address::Address, + protocol::{CommittableAgeRange, ProtocolParameters, WorkScore, WorkScoreParameters}, + semantic::SemanticValidationContext, + slot::SlotIndex, + Error, }; /// The maximum number of outputs of a transaction. diff --git a/sdk/src/types/block/output/output_id_proof.rs b/sdk/src/types/block/output/output_id_proof.rs new file mode 100644 index 0000000000..7f7bab6933 --- /dev/null +++ b/sdk/src/types/block/output/output_id_proof.rs @@ -0,0 +1,90 @@ +// Copyright 2023 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +use alloc::{boxed::Box, string::String}; + +#[cfg(feature = "serde")] +use {crate::utils::serde::prefix_hex_bytes, alloc::format, serde::de::Deserialize, serde_json::Value}; + +use crate::types::block::slot::SlotIndex; + +/// The proof of the output identifier. +#[derive(Clone, Debug, Eq, PartialEq)] +#[cfg_attr( + feature = "serde", + derive(serde::Serialize, serde::Deserialize), + serde(rename_all = "camelCase") +)] +pub struct OutputIdProof { + pub slot: SlotIndex, + pub output_index: u16, + pub transaction_commitment: String, + pub output_commitment_proof: OutputCommitmentProof, +} + +#[derive(Clone, Debug, Eq, PartialEq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize), serde(untagged))] +pub enum OutputCommitmentProof { + HashableNode(HashableNode), + LeafHash(LeafHash), + ValueHash(ValueHash), +} + +#[cfg(feature = "serde")] +impl<'de> Deserialize<'de> for OutputCommitmentProof { + fn deserialize>(d: D) -> Result { + let value = Value::deserialize(d)?; + Ok( + match value + .get("type") + .and_then(Value::as_u64) + .ok_or_else(|| serde::de::Error::custom("invalid output commitment proof type"))? + as u8 + { + 0 => Self::HashableNode( + serde_json::from_value::(value) + .map_err(|e| serde::de::Error::custom(format!("cannot deserialize hashable node: {e}")))?, + ), + 1 => Self::LeafHash( + serde_json::from_value::(value) + .map_err(|e| serde::de::Error::custom(format!("cannot deserialize leaf hash: {e}")))?, + ), + 2 => Self::ValueHash( + serde_json::from_value::(value) + .map_err(|e| serde::de::Error::custom(format!("cannot deserialize value hash: {e}")))?, + ), + _ => return Err(serde::de::Error::custom("invalid output commitment proof")), + }, + ) + } +} + +/// Node contains the hashes of the left and right children of a node in the tree. +#[derive(Clone, Debug, Eq, PartialEq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct HashableNode { + #[cfg_attr(feature = "serde", serde(rename = "type"))] + pub kind: u8, + pub l: Box, + pub r: Box, +} + +/// Leaf Hash contains the hash of a leaf in the tree. +#[derive(Clone, Debug, Eq, PartialEq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct LeafHash { + #[cfg_attr(feature = "serde", serde(rename = "type"))] + pub kind: u8, + #[cfg_attr(feature = "serde", serde(with = "prefix_hex_bytes"))] + pub hash: [u8; 32], +} + +/// Value Hash contains the hash of the value for which the proof is being computed. +#[derive(Clone, Debug, Eq, PartialEq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct ValueHash { + #[cfg_attr(feature = "serde", serde(rename = "type"))] + pub kind: u8, + #[cfg_attr(feature = "serde", serde(with = "prefix_hex_bytes"))] + pub hash: [u8; 32], +} diff --git a/sdk/src/wallet/operations/syncing/addresses/outputs.rs b/sdk/src/wallet/operations/syncing/addresses/outputs.rs index ee4640127b..1a3424fbd1 100644 --- a/sdk/src/wallet/operations/syncing/addresses/outputs.rs +++ b/sdk/src/wallet/operations/syncing/addresses/outputs.rs @@ -1,13 +1,10 @@ // Copyright 2022 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 -use std::collections::HashMap; - use instant::Instant; use crate::{ client::secret::SecretManage, - types::block::address::Address, wallet::{ constants::PARALLEL_REQUESTS_AMOUNT, task, @@ -25,7 +22,7 @@ where pub(crate) async fn get_outputs_from_address_output_ids( &self, addresses_with_unspent_outputs: Vec, - ) -> crate::wallet::Result<(Vec<(AddressWithUnspentOutputs, Vec)>)> { + ) -> crate::wallet::Result)>> { log::debug!("[SYNC] start get_outputs_from_address_output_ids"); let address_outputs_start_time = Instant::now(); diff --git a/sdk/src/wallet/operations/syncing/mod.rs b/sdk/src/wallet/operations/syncing/mod.rs index b4a0ca8379..b915ebf936 100644 --- a/sdk/src/wallet/operations/syncing/mod.rs +++ b/sdk/src/wallet/operations/syncing/mod.rs @@ -13,7 +13,7 @@ pub use self::options::SyncOptions; use crate::{ client::secret::SecretManage, types::block::{ - address::{AccountAddress, Address, Bech32Address, NftAddress, ToBech32Ext}, + address::{AccountAddress, Address, Bech32Address, NftAddress}, output::{FoundryId, Output, OutputId, OutputMetadata}, }, wallet::{ diff --git a/sdk/src/wallet/types/mod.rs b/sdk/src/wallet/types/mod.rs index b86f1ac41d..9c25c02b50 100644 --- a/sdk/src/wallet/types/mod.rs +++ b/sdk/src/wallet/types/mod.rs @@ -19,9 +19,9 @@ pub use self::{ use crate::{ client::secret::types::InputSigningData, types::{ - api::core::{OutputIdProof, OutputWithMetadataResponse}, + api::core::OutputWithMetadataResponse, block::{ - output::{Output, OutputId, OutputMetadata}, + output::{Output, OutputId, OutputIdProof, OutputMetadata}, payload::signed_transaction::{dto::SignedTransactionPayloadDto, SignedTransactionPayload, TransactionId}, protocol::{CommittableAgeRange, ProtocolParameters}, slot::SlotIndex,