diff --git a/Cargo.lock b/Cargo.lock index 0e1bd2ff89..d3fcf37ed6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2124,8 +2124,7 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "packable" version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbe35ea7a5959be5a87d24bcb31ed984580d9cd321c264c266818fff8cd47b3d" +source = "git+https://github.com/iotaledger/common-rs?rev=c72287fa24254b349f6e935b847485b0be141557#c72287fa24254b349f6e935b847485b0be141557" dependencies = [ "autocfg", "packable-derive", @@ -2136,8 +2135,7 @@ dependencies = [ [[package]] name = "packable-derive" version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "858971e010057f7bcae183e545085b83d41280ca8abe0333613a7135fbb54430" +source = "git+https://github.com/iotaledger/common-rs?rev=c72287fa24254b349f6e935b847485b0be141557#c72287fa24254b349f6e935b847485b0be141557" dependencies = [ "proc-macro-crate 1.3.1", "proc-macro-error", diff --git a/bindings/core/Cargo.toml b/bindings/core/Cargo.toml index ebee17c2d2..3f7cb46e08 100644 --- a/bindings/core/Cargo.toml +++ b/bindings/core/Cargo.toml @@ -23,7 +23,7 @@ iota-crypto = { version = "0.23.0", default-features = false, features = [ "bip44", ] } log = { version = "0.4.20", default-features = false } -packable = { version = "0.10.0", default-features = false } +packable = { git = "https://github.com/iotaledger/common-rs", rev = "c72287fa24254b349f6e935b847485b0be141557", default-features = false } prefix-hex = { version = "0.7.1", default-features = false } primitive-types = { version = "0.12.2", default-features = false } serde = { version = "1.0.193", default-features = false } diff --git a/bindings/core/src/method/wallet.rs b/bindings/core/src/method/wallet.rs index 0ed337c3f4..91802dec34 100644 --- a/bindings/core/src/method/wallet.rs +++ b/bindings/core/src/method/wallet.rs @@ -8,12 +8,12 @@ use crypto::keys::bip44::Bip44; use derivative::Derivative; #[cfg(feature = "events")] use iota_sdk::wallet::events::types::{WalletEvent, WalletEventType}; -#[cfg(feature = "participation")] -use iota_sdk::{ - client::node_manager::node::Node, - types::api::plugins::participation::types::{ParticipationEventId, ParticipationEventType}, - wallet::types::participation::ParticipationEventRegistrationOptions, -}; +// #[cfg(feature = "participation")] +// use iota_sdk::{ +// client::node_manager::node::Node, +// types::api::plugins::participation::types::{ParticipationEventId, ParticipationEventType}, +// wallet::types::participation::ParticipationEventRegistrationOptions, +// }; use iota_sdk::{ client::{ api::{input_selection::Burn, PreparedTransactionDataDto, SignedTransactionDataDto}, @@ -122,12 +122,12 @@ pub enum WalletMethod { /// Expected response: [`SentTransaction`](crate::Response::SentTransaction) #[serde(rename_all = "camelCase")] ClaimOutputs { output_ids_to_claim: Vec }, - /// Removes a previously registered participation event from local storage. - /// Expected response: [`Ok`](crate::Response::Ok) - #[cfg(feature = "participation")] - #[cfg_attr(docsrs, doc(cfg(feature = "participation")))] - #[serde(rename_all = "camelCase")] - DeregisterParticipationEvent { event_id: ParticipationEventId }, + // /// Removes a previously registered participation event from local storage. + // /// Expected response: [`Ok`](crate::Response::Ok) + // #[cfg(feature = "participation")] + // #[cfg_attr(docsrs, doc(cfg(feature = "participation")))] + // #[serde(rename_all = "camelCase")] + // DeregisterParticipationEvent { event_id: ParticipationEventId }, /// Get the wallet address. /// Expected response: [`Address`](crate::Response::Address) GetAddress, @@ -147,48 +147,48 @@ pub enum WalletMethod { /// Expected response: [`OutputData`](crate::Response::OutputData) #[serde(rename_all = "camelCase")] GetOutput { output_id: OutputId }, - /// Expected response: [`ParticipationEvent`](crate::Response::ParticipationEvent) - #[cfg(feature = "participation")] - #[cfg_attr(docsrs, doc(cfg(feature = "participation")))] - #[serde(rename_all = "camelCase")] - GetParticipationEvent { event_id: ParticipationEventId }, - /// Expected response: [`ParticipationEventIds`](crate::Response::ParticipationEventIds) - #[cfg(feature = "participation")] - #[cfg_attr(docsrs, doc(cfg(feature = "participation")))] - #[serde(rename_all = "camelCase")] - GetParticipationEventIds { - node: Node, - event_type: Option, - }, - /// Expected response: - /// [`ParticipationEventStatus`](crate::Response::ParticipationEventStatus) - #[cfg(feature = "participation")] - #[cfg_attr(docsrs, doc(cfg(feature = "participation")))] - #[serde(rename_all = "camelCase")] - GetParticipationEventStatus { event_id: ParticipationEventId }, - /// Expected response: [`ParticipationEvents`](crate::Response::ParticipationEvents) - #[cfg(feature = "participation")] - #[cfg_attr(docsrs, doc(cfg(feature = "participation")))] - GetParticipationEvents, - /// Calculates a participation overview for the wallet. If event_ids are provided, only return outputs and tracked - /// participations for them. - /// Expected response: [`ParticipationOverview`](crate::Response::ParticipationOverview) - #[cfg(feature = "participation")] - #[cfg_attr(docsrs, doc(cfg(feature = "participation")))] - #[serde(rename_all = "camelCase")] - GetParticipationOverview { - event_ids: Option>, - }, + // /// Expected response: [`ParticipationEvent`](crate::Response::ParticipationEvent) + // #[cfg(feature = "participation")] + // #[cfg_attr(docsrs, doc(cfg(feature = "participation")))] + // #[serde(rename_all = "camelCase")] + // GetParticipationEvent { event_id: ParticipationEventId }, + // /// Expected response: [`ParticipationEventIds`](crate::Response::ParticipationEventIds) + // #[cfg(feature = "participation")] + // #[cfg_attr(docsrs, doc(cfg(feature = "participation")))] + // #[serde(rename_all = "camelCase")] + // GetParticipationEventIds { + // node: Node, + // event_type: Option, + // }, + // /// Expected response: + // /// [`ParticipationEventStatus`](crate::Response::ParticipationEventStatus) + // #[cfg(feature = "participation")] + // #[cfg_attr(docsrs, doc(cfg(feature = "participation")))] + // #[serde(rename_all = "camelCase")] + // GetParticipationEventStatus { event_id: ParticipationEventId }, + // /// Expected response: [`ParticipationEvents`](crate::Response::ParticipationEvents) + // #[cfg(feature = "participation")] + // #[cfg_attr(docsrs, doc(cfg(feature = "participation")))] + // GetParticipationEvents, + // /// Calculates a participation overview for the wallet. If event_ids are provided, only return outputs and + // tracked /// participations for them. + // /// Expected response: [`ParticipationOverview`](crate::Response::ParticipationOverview) + // #[cfg(feature = "participation")] + // #[cfg_attr(docsrs, doc(cfg(feature = "participation")))] + // #[serde(rename_all = "camelCase")] + // GetParticipationOverview { + // event_ids: Option>, + // }, /// Get the [`TransactionWithMetadata`](iota_sdk::wallet::types::TransactionWithMetadata) of a transaction stored /// in the wallet. /// Expected response: [`Transaction`](crate::Response::Transaction) #[serde(rename_all = "camelCase")] GetTransaction { transaction_id: TransactionId }, - /// Get the wallet's total voting power (voting or NOT voting). - /// Expected response: [`VotingPower`](crate::Response::VotingPower) - #[cfg(feature = "participation")] - #[cfg_attr(docsrs, doc(cfg(feature = "participation")))] - GetVotingPower, + // /// Get the wallet's total voting power (voting or NOT voting). + // /// Expected response: [`VotingPower`](crate::Response::VotingPower) + // #[cfg(feature = "participation")] + // #[cfg_attr(docsrs, doc(cfg(feature = "participation")))] + // GetVotingPower, /// Returns the implicit account creation address of the wallet if it is Ed25519 based. /// Expected response: [`Bech32Address`](crate::Response::Bech32Address) ImplicitAccountCreationAddress, @@ -246,26 +246,26 @@ pub enum WalletMethod { params: CreateNativeTokenParams, options: Option, }, - /// Reduces a wallet's "voting power" by a given amount. - /// This will stop voting, but the voting data isn't lost and calling `Vote` without parameters will revote. - /// Expected response: [`PreparedTransaction`](crate::Response::PreparedTransaction) - #[cfg(feature = "participation")] - #[cfg_attr(docsrs, doc(cfg(feature = "participation")))] - PrepareDecreaseVotingPower { - #[serde(with = "iota_sdk::utils::serde::string")] - amount: u64, - }, - /// Designates a given amount of tokens towards a wallet's "voting power" by creating a - /// special output, which is really a basic one with some metadata. - /// This will stop voting in most cases (if there is a remainder output), but the voting data isn't lost and - /// calling `Vote` without parameters will revote. Expected response: - /// Expected response: [`PreparedTransaction`](crate::Response::PreparedTransaction) - #[cfg(feature = "participation")] - #[cfg_attr(docsrs, doc(cfg(feature = "participation")))] - PrepareIncreaseVotingPower { - #[serde(with = "iota_sdk::utils::serde::string")] - amount: u64, - }, + // /// Reduces a wallet's "voting power" by a given amount. + // /// This will stop voting, but the voting data isn't lost and calling `Vote` without parameters will revote. + // /// Expected response: [`PreparedTransaction`](crate::Response::PreparedTransaction) + // #[cfg(feature = "participation")] + // #[cfg_attr(docsrs, doc(cfg(feature = "participation")))] + // PrepareDecreaseVotingPower { + // #[serde(with = "iota_sdk::utils::serde::string")] + // amount: u64, + // }, + // /// Designates a given amount of tokens towards a wallet's "voting power" by creating a + // /// special output, which is really a basic one with some metadata. + // /// This will stop voting in most cases (if there is a remainder output), but the voting data isn't lost and + // /// calling `Vote` without parameters will revote. Expected response: + // /// Expected response: [`PreparedTransaction`](crate::Response::PreparedTransaction) + // #[cfg(feature = "participation")] + // #[cfg_attr(docsrs, doc(cfg(feature = "participation")))] + // PrepareIncreaseVotingPower { + // #[serde(with = "iota_sdk::utils::serde::string")] + // amount: u64, + // }, /// Prepare to melt native tokens. This happens with the foundry output which minted them, by increasing it's /// `melted_tokens` field. /// Expected response: [`PreparedTransaction`](crate::Response::PreparedTransaction) @@ -318,36 +318,36 @@ pub enum WalletMethod { params: Vec, options: Option, }, - /// Stop participating for an event. - /// Expected response: [`PreparedTransaction`](crate::Response::PreparedTransaction) - #[cfg(feature = "participation")] - #[cfg_attr(docsrs, doc(cfg(feature = "participation")))] - #[serde(rename_all = "camelCase")] - PrepareStopParticipating { event_id: ParticipationEventId }, + // /// Stop participating for an event. + // /// Expected response: [`PreparedTransaction`](crate::Response::PreparedTransaction) + // #[cfg(feature = "participation")] + // #[cfg_attr(docsrs, doc(cfg(feature = "participation")))] + // #[serde(rename_all = "camelCase")] + // PrepareStopParticipating { event_id: ParticipationEventId }, /// Prepare transaction. /// Expected response: [`PreparedTransaction`](crate::Response::PreparedTransaction) PrepareTransaction { outputs: Vec, options: Option, }, - /// Vote for a participation event. - /// Expected response: [`PreparedTransaction`](crate::Response::PreparedTransaction) - #[cfg(feature = "participation")] - #[cfg_attr(docsrs, doc(cfg(feature = "participation")))] - #[serde(rename_all = "camelCase")] - PrepareVote { - event_id: Option, - answers: Option>, - }, - /// Stores participation information locally and returns the event. - /// - /// This will NOT store the node url and auth inside the client options. - /// Expected response: [`ParticipationEvents`](crate::Response::ParticipationEvents) - #[cfg(feature = "participation")] - #[cfg_attr(docsrs, doc(cfg(feature = "participation")))] - RegisterParticipationEvents { - options: ParticipationEventRegistrationOptions, - }, + // /// Vote for a participation event. + // /// Expected response: [`PreparedTransaction`](crate::Response::PreparedTransaction) + // #[cfg(feature = "participation")] + // #[cfg_attr(docsrs, doc(cfg(feature = "participation")))] + // #[serde(rename_all = "camelCase")] + // PrepareVote { + // event_id: Option, + // answers: Option>, + // }, + // /// Stores participation information locally and returns the event. + // /// + // /// This will NOT store the node url and auth inside the client options. + // /// Expected response: [`ParticipationEvents`](crate::Response::ParticipationEvents) + // #[cfg(feature = "participation")] + // #[cfg_attr(docsrs, doc(cfg(feature = "participation")))] + // RegisterParticipationEvents { + // options: ParticipationEventRegistrationOptions, + // }, /// Reissues a transaction sent from the wallet for a provided transaction id until it's /// included (referenced by a milestone). Returns the included block id. /// Expected response: [`BlockId`](crate::Response::BlockId) diff --git a/bindings/core/src/method_handler/wallet.rs b/bindings/core/src/method_handler/wallet.rs index 3b088222e0..a574bca7a1 100644 --- a/bindings/core/src/method_handler/wallet.rs +++ b/bindings/core/src/method_handler/wallet.rs @@ -138,11 +138,11 @@ pub(crate) async fn call_wallet_method_internal(wallet: &Wallet, method: WalletM let transaction = wallet.claim_outputs(output_ids_to_claim.to_vec()).await?; Response::SentTransaction(TransactionWithMetadataDto::from(&transaction)) } - #[cfg(feature = "participation")] - WalletMethod::DeregisterParticipationEvent { event_id } => { - wallet.deregister_participation_event(&event_id).await?; - Response::Ok - } + // #[cfg(feature = "participation")] + // WalletMethod::DeregisterParticipationEvent { event_id } => { + // wallet.deregister_participation_event(&event_id).await?; + // Response::Ok + // } WalletMethod::GetAddress => { let address = wallet.address().await; Response::Address(address) @@ -163,31 +163,31 @@ pub(crate) async fn call_wallet_method_internal(wallet: &Wallet, method: WalletM WalletMethod::GetOutput { output_id } => { Response::OutputData(wallet.data().await.get_output(&output_id).cloned().map(Box::new)) } - #[cfg(feature = "participation")] - WalletMethod::GetParticipationEvent { event_id } => { - let event_and_nodes = wallet.get_participation_event(event_id).await?; - Response::ParticipationEvent(event_and_nodes) - } - #[cfg(feature = "participation")] - WalletMethod::GetParticipationEventIds { node, event_type } => { - let event_ids = wallet.get_participation_event_ids(&node, event_type).await?; - Response::ParticipationEventIds(event_ids) - } - #[cfg(feature = "participation")] - WalletMethod::GetParticipationEventStatus { event_id } => { - let event_status = wallet.get_participation_event_status(&event_id).await?; - Response::ParticipationEventStatus(event_status) - } - #[cfg(feature = "participation")] - WalletMethod::GetParticipationEvents => { - let events = wallet.get_participation_events().await?; - Response::ParticipationEvents(events) - } - #[cfg(feature = "participation")] - WalletMethod::GetParticipationOverview { event_ids } => { - let overview = wallet.get_participation_overview(event_ids).await?; - Response::ParticipationOverview(overview) - } + // #[cfg(feature = "participation")] + // WalletMethod::GetParticipationEvent { event_id } => { + // let event_and_nodes = wallet.get_participation_event(event_id).await?; + // Response::ParticipationEvent(event_and_nodes) + // } + // #[cfg(feature = "participation")] + // WalletMethod::GetParticipationEventIds { node, event_type } => { + // let event_ids = wallet.get_participation_event_ids(&node, event_type).await?; + // Response::ParticipationEventIds(event_ids) + // } + // #[cfg(feature = "participation")] + // WalletMethod::GetParticipationEventStatus { event_id } => { + // let event_status = wallet.get_participation_event_status(&event_id).await?; + // Response::ParticipationEventStatus(event_status) + // } + // #[cfg(feature = "participation")] + // WalletMethod::GetParticipationEvents => { + // let events = wallet.get_participation_events().await?; + // Response::ParticipationEvents(events) + // } + // #[cfg(feature = "participation")] + // WalletMethod::GetParticipationOverview { event_ids } => { + // let overview = wallet.get_participation_overview(event_ids).await?; + // Response::ParticipationOverview(overview) + // } WalletMethod::GetTransaction { transaction_id } => Response::Transaction( wallet .data() @@ -196,11 +196,11 @@ pub(crate) async fn call_wallet_method_internal(wallet: &Wallet, method: WalletM .map(TransactionWithMetadataDto::from) .map(Box::new), ), - #[cfg(feature = "participation")] - WalletMethod::GetVotingPower => { - let voting_power = wallet.get_voting_power().await?; - Response::VotingPower(voting_power.to_string()) - } + // #[cfg(feature = "participation")] + // WalletMethod::GetVotingPower => { + // let voting_power = wallet.get_voting_power().await?; + // Response::VotingPower(voting_power.to_string()) + // } WalletMethod::ImplicitAccountCreationAddress => { let implicit_account_creation_address = wallet.implicit_account_creation_address().await?; Response::Bech32Address(implicit_account_creation_address) @@ -273,11 +273,11 @@ pub(crate) async fn call_wallet_method_internal(wallet: &Wallet, method: WalletM let data = wallet.prepare_melt_native_token(token_id, melt_amount, options).await?; Response::PreparedTransaction(PreparedTransactionDataDto::from(&data)) } - #[cfg(feature = "participation")] - WalletMethod::PrepareDecreaseVotingPower { amount } => { - let data = wallet.prepare_decrease_voting_power(amount).await?; - Response::PreparedTransaction(PreparedTransactionDataDto::from(&data)) - } + // #[cfg(feature = "participation")] + // WalletMethod::PrepareDecreaseVotingPower { amount } => { + // let data = wallet.prepare_decrease_voting_power(amount).await?; + // Response::PreparedTransaction(PreparedTransactionDataDto::from(&data)) + // } WalletMethod::PrepareMintNativeToken { token_id, mint_amount, @@ -286,11 +286,11 @@ pub(crate) async fn call_wallet_method_internal(wallet: &Wallet, method: WalletM let data = wallet.prepare_mint_native_token(token_id, mint_amount, options).await?; Response::PreparedTransaction(PreparedTransactionDataDto::from(&data)) } - #[cfg(feature = "participation")] - WalletMethod::PrepareIncreaseVotingPower { amount } => { - let data = wallet.prepare_increase_voting_power(amount).await?; - Response::PreparedTransaction(PreparedTransactionDataDto::from(&data)) - } + // #[cfg(feature = "participation")] + // WalletMethod::PrepareIncreaseVotingPower { amount } => { + // let data = wallet.prepare_increase_voting_power(amount).await?; + // Response::PreparedTransaction(PreparedTransactionDataDto::from(&data)) + // } WalletMethod::PrepareMintNfts { params, options } => { let data = wallet.prepare_mint_nfts(params, options).await?; Response::PreparedTransaction(PreparedTransactionDataDto::from(&data)) @@ -318,25 +318,25 @@ pub(crate) async fn call_wallet_method_internal(wallet: &Wallet, method: WalletM let data = wallet.prepare_send_nft(params.clone(), options).await?; Response::PreparedTransaction(PreparedTransactionDataDto::from(&data)) } - #[cfg(feature = "participation")] - WalletMethod::PrepareStopParticipating { event_id } => { - let data = wallet.prepare_stop_participating(event_id).await?; - Response::PreparedTransaction(PreparedTransactionDataDto::from(&data)) - } + // #[cfg(feature = "participation")] + // WalletMethod::PrepareStopParticipating { event_id } => { + // let data = wallet.prepare_stop_participating(event_id).await?; + // Response::PreparedTransaction(PreparedTransactionDataDto::from(&data)) + // } WalletMethod::PrepareTransaction { outputs, options } => { let data = wallet.prepare_transaction(outputs, options).await?; Response::PreparedTransaction(PreparedTransactionDataDto::from(&data)) } - #[cfg(feature = "participation")] - WalletMethod::PrepareVote { event_id, answers } => { - let data = wallet.prepare_vote(event_id, answers).await?; - Response::PreparedTransaction(PreparedTransactionDataDto::from(&data)) - } - #[cfg(feature = "participation")] - WalletMethod::RegisterParticipationEvents { options } => { - let events = wallet.register_participation_events(&options).await?; - Response::ParticipationEvents(events) - } + // #[cfg(feature = "participation")] + // WalletMethod::PrepareVote { event_id, answers } => { + // let data = wallet.prepare_vote(event_id, answers).await?; + // Response::PreparedTransaction(PreparedTransactionDataDto::from(&data)) + // } + // #[cfg(feature = "participation")] + // WalletMethod::RegisterParticipationEvents { options } => { + // let events = wallet.register_participation_events(&options).await?; + // Response::ParticipationEvents(events) + // } WalletMethod::ReissueTransactionUntilIncluded { transaction_id, interval, diff --git a/cli/src/wallet_cli/mod.rs b/cli/src/wallet_cli/mod.rs index dedccc8d8c..c4ffc77939 100644 --- a/cli/src/wallet_cli/mod.rs +++ b/cli/src/wallet_cli/mod.rs @@ -10,17 +10,14 @@ use colored::Colorize; use iota_sdk::{ client::request_funds_from_faucet, crypto::signatures::ed25519::PublicKey, - types::{ - api::plugins::participation::types::ParticipationEventId, - block::{ - address::Bech32Address, - output::{ - unlock_condition::AddressUnlockCondition, AccountId, BasicOutputBuilder, FoundryId, NativeToken, - NativeTokensBuilder, NftId, Output, OutputId, TokenId, - }, - payload::signed_transaction::TransactionId, - slot::SlotIndex, + types::block::{ + address::Bech32Address, + output::{ + unlock_condition::AddressUnlockCondition, AccountId, BasicOutputBuilder, FoundryId, NativeToken, + NativeTokensBuilder, NftId, Output, OutputId, TokenId, }, + payload::signed_transaction::TransactionId, + slot::SlotIndex, }, utils::ConvertTo, wallet::{ @@ -238,40 +235,40 @@ pub enum WalletCommand { }, /// List the unspent outputs. UnspentOutputs, - /// Cast votes for an event. - Vote { - /// Event ID for which to cast votes, e.g. 0xdc049a721dc65ec342f836c876ec15631ed915cd55213cee39e8d1c821c751f2. - event_id: ParticipationEventId, - /// Answers to the event questions. - answers: Vec, - }, - /// Stop participating to an event. - StopParticipating { - /// Event ID for which to stop participation, e.g. - /// 0xdc049a721dc65ec342f836c876ec15631ed915cd55213cee39e8d1c821c751f2. - event_id: ParticipationEventId, - }, - /// Get the participation overview of the wallet. - ParticipationOverview { - /// Event IDs for which to get the participation overview, e.g. - /// 0xdc049a721dc65ec342f836c876ec15631ed915cd55213cee39e8d1c821c751f2... - #[arg(short, long, num_args = 1.., value_delimiter = ' ')] - event_ids: Vec, - }, - /// Get the voting power of the wallet. - VotingPower, - /// Increase the voting power of the wallet. - IncreaseVotingPower { - /// Amount to increase the voting power by, e.g. 100. - amount: u64, - }, - /// Decrease the voting power of the wallet. - DecreaseVotingPower { - /// Amount to decrease the voting power by, e.g. 100. - amount: u64, - }, - /// Get the voting output of the wallet. - VotingOutput, + // /// Cast votes for an event. + // Vote { + // /// Event ID for which to cast votes, e.g. + // 0xdc049a721dc65ec342f836c876ec15631ed915cd55213cee39e8d1c821c751f2. event_id: ParticipationEventId, + // /// Answers to the event questions. + // answers: Vec, + // }, + // /// Stop participating to an event. + // StopParticipating { + // /// Event ID for which to stop participation, e.g. + // /// 0xdc049a721dc65ec342f836c876ec15631ed915cd55213cee39e8d1c821c751f2. + // event_id: ParticipationEventId, + // }, + // /// Get the participation overview of the wallet. + // ParticipationOverview { + // /// Event IDs for which to get the participation overview, e.g. + // /// 0xdc049a721dc65ec342f836c876ec15631ed915cd55213cee39e8d1c821c751f2... + // #[arg(short, long, num_args = 1.., value_delimiter = ' ')] + // event_ids: Vec, + // }, + // /// Get the voting power of the wallet. + // VotingPower, + // /// Increase the voting power of the wallet. + // IncreaseVotingPower { + // /// Amount to increase the voting power by, e.g. 100. + // amount: u64, + // }, + // /// Decrease the voting power of the wallet. + // DecreaseVotingPower { + // /// Amount to decrease the voting power by, e.g. 100. + // amount: u64, + // }, + // /// Get the voting output of the wallet. + // VotingOutput, } /// Select by transaction ID or list index @@ -887,80 +884,80 @@ pub async fn unspent_outputs_command(wallet: &Wallet) -> Result<(), Error> { ) } -pub async fn vote_command(wallet: &Wallet, event_id: ParticipationEventId, answers: Vec) -> Result<(), Error> { - let transaction = wallet.vote(Some(event_id), Some(answers)).await?; +// pub async fn vote_command(wallet: &Wallet, event_id: ParticipationEventId, answers: Vec) -> Result<(), Error> { +// let transaction = wallet.vote(Some(event_id), Some(answers)).await?; - println_log_info!( - "Voting transaction sent:\n{:?}\n{:?}", - transaction.transaction_id, - transaction.block_id - ); +// println_log_info!( +// "Voting transaction sent:\n{:?}\n{:?}", +// transaction.transaction_id, +// transaction.block_id +// ); - Ok(()) -} +// Ok(()) +// } -pub async fn stop_participating_command(wallet: &Wallet, event_id: ParticipationEventId) -> Result<(), Error> { - let transaction = wallet.stop_participating(event_id).await?; +// pub async fn stop_participating_command(wallet: &Wallet, event_id: ParticipationEventId) -> Result<(), Error> { +// let transaction = wallet.stop_participating(event_id).await?; - println_log_info!( - "Stop participating transaction sent:\n{:?}\n{:?}", - transaction.transaction_id, - transaction.block_id - ); +// println_log_info!( +// "Stop participating transaction sent:\n{:?}\n{:?}", +// transaction.transaction_id, +// transaction.block_id +// ); - Ok(()) -} +// Ok(()) +// } -pub async fn participation_overview_command( - wallet: &Wallet, - event_ids: Option>, -) -> Result<(), Error> { - let participation_overview = wallet.get_participation_overview(event_ids).await?; +// pub async fn participation_overview_command( +// wallet: &Wallet, +// event_ids: Option>, +// ) -> Result<(), Error> { +// let participation_overview = wallet.get_participation_overview(event_ids).await?; - println_log_info!("Participation overview: {participation_overview:?}"); +// println_log_info!("Participation overview: {participation_overview:?}"); - Ok(()) -} +// Ok(()) +// } -pub async fn voting_power_command(wallet: &Wallet) -> Result<(), Error> { - let voting_power = wallet.get_voting_power().await?; +// pub async fn voting_power_command(wallet: &Wallet) -> Result<(), Error> { +// let voting_power = wallet.get_voting_power().await?; - println_log_info!("Voting power: {voting_power}"); +// println_log_info!("Voting power: {voting_power}"); - Ok(()) -} +// Ok(()) +// } -pub async fn increase_voting_power_command(wallet: &Wallet, amount: u64) -> Result<(), Error> { - let transaction = wallet.increase_voting_power(amount).await?; +// pub async fn increase_voting_power_command(wallet: &Wallet, amount: u64) -> Result<(), Error> { +// let transaction = wallet.increase_voting_power(amount).await?; - println_log_info!( - "Increase voting power transaction sent:\n{:?}\n{:?}", - transaction.transaction_id, - transaction.block_id - ); +// println_log_info!( +// "Increase voting power transaction sent:\n{:?}\n{:?}", +// transaction.transaction_id, +// transaction.block_id +// ); - Ok(()) -} +// Ok(()) +// } -pub async fn decrease_voting_power_command(wallet: &Wallet, amount: u64) -> Result<(), Error> { - let transaction = wallet.decrease_voting_power(amount).await?; +// pub async fn decrease_voting_power_command(wallet: &Wallet, amount: u64) -> Result<(), Error> { +// let transaction = wallet.decrease_voting_power(amount).await?; - println_log_info!( - "Decrease voting power transaction sent:\n{:?}\n{:?}", - transaction.transaction_id, - transaction.block_id - ); +// println_log_info!( +// "Decrease voting power transaction sent:\n{:?}\n{:?}", +// transaction.transaction_id, +// transaction.block_id +// ); - Ok(()) -} +// Ok(()) +// } -pub async fn voting_output_command(wallet: &Wallet) -> Result<(), Error> { - let output = wallet.get_voting_output().await?; +// pub async fn voting_output_command(wallet: &Wallet) -> Result<(), Error> { +// let output = wallet.get_voting_output().await?; - println_log_info!("Voting output: {output:?}"); +// println_log_info!("Voting output: {output:?}"); - Ok(()) -} +// Ok(()) +// } async fn print_wallet_address(wallet: &Wallet) -> Result<(), Error> { let address = wallet.address().await; @@ -1208,22 +1205,22 @@ pub async fn prompt_internal( transactions_command(wallet, show_details).await } WalletCommand::UnspentOutputs => unspent_outputs_command(wallet).await, - WalletCommand::Vote { event_id, answers } => vote_command(wallet, event_id, answers).await, - WalletCommand::StopParticipating { event_id } => { - stop_participating_command(wallet, event_id).await - } - WalletCommand::ParticipationOverview { event_ids } => { - let event_ids = (!event_ids.is_empty()).then_some(event_ids); - participation_overview_command(wallet, event_ids).await - } - WalletCommand::VotingPower => voting_power_command(wallet).await, - WalletCommand::IncreaseVotingPower { amount } => { - increase_voting_power_command(wallet, amount).await - } - WalletCommand::DecreaseVotingPower { amount } => { - decrease_voting_power_command(wallet, amount).await - } - WalletCommand::VotingOutput => voting_output_command(wallet).await, + // WalletCommand::Vote { event_id, answers } => vote_command(wallet, event_id, answers).await, + // WalletCommand::StopParticipating { event_id } => { + // stop_participating_command(wallet, event_id).await + // } + // WalletCommand::ParticipationOverview { event_ids } => { + // let event_ids = (!event_ids.is_empty()).then_some(event_ids); + // participation_overview_command(wallet, event_ids).await + // } + // WalletCommand::VotingPower => voting_power_command(wallet).await, + // WalletCommand::IncreaseVotingPower { amount } => { + // increase_voting_power_command(wallet, amount).await + // } + // WalletCommand::DecreaseVotingPower { amount } => { + // decrease_voting_power_command(wallet, amount).await + // } + // WalletCommand::VotingOutput => voting_output_command(wallet).await, } .unwrap_or_else(|err| { println_log_error!("{err}"); diff --git a/sdk/Cargo.toml b/sdk/Cargo.toml index 250f10bb85..1467bc0d1a 100644 --- a/sdk/Cargo.toml +++ b/sdk/Cargo.toml @@ -45,7 +45,7 @@ iota-crypto = { version = "0.23.0", default-features = false, features = [ "secp256k1", ] } iterator-sorted = { version = "0.1.0", default-features = false } -packable = { version = "0.10.0", default-features = false, features = [ +packable = { git = "https://github.com/iotaledger/common-rs", rev = "c72287fa24254b349f6e935b847485b0be141557", default-features = false, features = [ "primitive-types", ] } paste = { version = "1.0.14", default-features = false } @@ -639,10 +639,10 @@ name = "wallet_ledger_nano" path = "examples/wallet/ledger_nano.rs" required-features = ["wallet", "ledger_nano"] -[[example]] -name = "wallet_participation" -path = "examples/wallet/participation.rs" -required-features = ["wallet", "participation"] +# [[example]] +# name = "wallet_participation" +# path = "examples/wallet/participation.rs" +# required-features = ["wallet", "participation"] [[example]] name = "logger" diff --git a/sdk/examples/client/output/build_account_output.rs b/sdk/examples/client/output/build_account_output.rs index c575d37960..82f84888ea 100644 --- a/sdk/examples/client/output/build_account_output.rs +++ b/sdk/examples/client/output/build_account_output.rs @@ -49,9 +49,11 @@ async fn main() -> Result<()> { // Account id needs to be null the first time let account_output = AccountOutputBuilder::new_with_minimum_amount(storage_score_params, AccountId::null()) .add_feature(SenderFeature::new(address.clone())) - .add_feature(MetadataFeature::new(metadata)?) + // TODO: enable again when MetadataFeature is cleared up + // .add_feature(MetadataFeature::new(metadata)?) .add_immutable_feature(IssuerFeature::new(address.clone())) - .add_immutable_feature(MetadataFeature::new(metadata)?) + // TODO: enable again when MetadataFeature is cleared up + // .add_immutable_feature(MetadataFeature::new(metadata)?) .add_unlock_condition(AddressUnlockCondition::new(address)) .finish_output()?; diff --git a/sdk/examples/client/output/build_basic_output.rs b/sdk/examples/client/output/build_basic_output.rs index 37102b74c2..e5bc294d7d 100644 --- a/sdk/examples/client/output/build_basic_output.rs +++ b/sdk/examples/client/output/build_basic_output.rs @@ -41,11 +41,12 @@ async fn main() -> Result<()> { let outputs = [ // most simple output basic_output_builder.clone().finish_output()?, - // with metadata feature block - basic_output_builder - .clone() - .add_feature(MetadataFeature::new(METADATA)?) - .finish_output()?, + // TODO: enable again when MetadataFeature is cleared up + // // with metadata feature block + // basic_output_builder + // .clone() + // .add_feature(MetadataFeature::new(METADATA)?) + // .finish_output()?, // with storage deposit return basic_output_builder .clone() diff --git a/sdk/examples/client/output/build_nft_output.rs b/sdk/examples/client/output/build_nft_output.rs index 3fedaf5532..5328edd896 100644 --- a/sdk/examples/client/output/build_nft_output.rs +++ b/sdk/examples/client/output/build_nft_output.rs @@ -63,10 +63,12 @@ async fn main() -> Result<()> { let nft_output = NftOutputBuilder::new_with_minimum_amount(storage_score_params, NftId::null()) .add_unlock_condition(AddressUnlockCondition::new(address.clone())) .add_feature(SenderFeature::new(address.clone())) - .add_feature(MetadataFeature::new(MUTABLE_METADATA)?) + // TODO: enable again when MetadataFeature is cleared up + // .add_feature(MetadataFeature::new(MUTABLE_METADATA)?) .add_feature(TagFeature::new(TAG)?) .add_immutable_feature(IssuerFeature::new(address)) - .add_immutable_feature(MetadataFeature::new(tip_27_immutable_metadata)?) + // TODO: enable again when MetadataFeature is cleared up + // .add_immutable_feature(MetadataFeature::new(tip_27_immutable_metadata)?) .finish_output()?; println!("{nft_output:#?}"); diff --git a/sdk/examples/how_tos/outputs/features.rs b/sdk/examples/how_tos/outputs/features.rs index 78d991872f..5001088824 100644 --- a/sdk/examples/how_tos/outputs/features.rs +++ b/sdk/examples/how_tos/outputs/features.rs @@ -53,16 +53,17 @@ async fn main() -> Result<()> { .clone() .add_immutable_feature(IssuerFeature::new(address)) .finish_output()?, - // with metadata feature block - nft_output_builder - .clone() - .add_feature(MetadataFeature::new("Hello, World!")?) - .finish_output()?, - // with immutable metadata feature block - nft_output_builder - .clone() - .add_immutable_feature(MetadataFeature::new("Hello, World!")?) - .finish_output()?, + // TODO: enable again when MetadataFeature is cleared up + // // with metadata feature block + // nft_output_builder + // .clone() + // .add_feature(MetadataFeature::new("Hello, World!")?) + // .finish_output()?, + // // with immutable metadata feature block + // nft_output_builder + // .clone() + // .add_immutable_feature(MetadataFeature::new("Hello, World!")?) + // .finish_output()?, // with tag feature nft_output_builder .add_feature(TagFeature::new("Hello, World!")?) diff --git a/sdk/src/types/block/error.rs b/sdk/src/types/block/error.rs index ee8d5b44c8..593561268f 100644 --- a/sdk/src/types/block/error.rs +++ b/sdk/src/types/block/error.rs @@ -18,7 +18,8 @@ use crate::types::block::{ output::{ feature::{BlockIssuerKeyCount, FeatureCount}, unlock_condition::UnlockConditionCount, - AccountId, AnchorId, ChainId, MetadataFeatureLength, NativeTokenCount, NftId, OutputIndex, TagFeatureLength, + AccountId, AnchorId, ChainId, MetadataFeatureKeyLength, MetadataFeatureLength, MetadataFeatureValueLength, + NativeTokenCount, NftId, OutputIndex, TagFeatureLength, }, payload::{ tagged_data::{TagLength, TaggedDataLength}, @@ -56,6 +57,7 @@ pub enum Error { InvalidAccountIndex(>::Error), InvalidAnchorIndex(>::Error), InvalidBlockBodyKind(u8), + InvalidMetadataKeyBytes(Vec), InvalidRewardInputIndex(>::Error), InvalidStorageDepositAmount(u64), /// Invalid transaction failure reason byte. @@ -104,7 +106,10 @@ pub enum Error { }, InvalidBlockLength(usize), InvalidManaValue(u64), + InvalidMetadataFeature(String), InvalidMetadataFeatureLength(>::Error), + InvalidMetadataFeatureKeyLength(>::Error), + InvalidMetadataFeatureValueLength(>::Error), InvalidNativeTokenCount(>::Error), InvalidNetworkName(FromUtf8Error), InvalidManaDecayFactors, @@ -249,6 +254,7 @@ impl fmt::Display for Error { write!(f, "invalid capability byte at index {index}: {byte:x}") } Self::InvalidBlockBodyKind(k) => write!(f, "invalid block body kind: {k}"), + Self::InvalidMetadataKeyBytes(b) => write!(f, "invalid metadata key bytes: {b:?}"), Self::InvalidRewardInputIndex(idx) => write!(f, "invalid reward input index: {idx}"), Self::InvalidStorageDepositAmount(amount) => { write!(f, "invalid storage deposit amount: {amount}") @@ -303,9 +309,18 @@ impl fmt::Display for Error { Self::InvalidInputOutputIndex(index) => write!(f, "invalid input or output index: {index}"), Self::InvalidBlockLength(length) => write!(f, "invalid block length {length}"), Self::InvalidManaValue(mana) => write!(f, "invalid mana value: {mana}"), + Self::InvalidMetadataFeature(e) => { + write!(f, "invalid metadata feature: {e}") + } Self::InvalidMetadataFeatureLength(length) => { write!(f, "invalid metadata feature length: {length}") } + Self::InvalidMetadataFeatureKeyLength(length) => { + write!(f, "invalid metadata feature key length: {length}") + } + Self::InvalidMetadataFeatureValueLength(length) => { + write!(f, "invalid metadata feature value length: {length}") + } Self::InvalidNativeTokenCount(count) => write!(f, "invalid native token count: {count}"), Self::InvalidNetworkName(err) => write!(f, "invalid network name: {err}"), Self::InvalidManaDecayFactors => write!(f, "invalid mana decay factors"), diff --git a/sdk/src/types/block/output/feature/metadata.rs b/sdk/src/types/block/output/feature/metadata.rs index 434235ff5b..df75d16a69 100644 --- a/sdk/src/types/block/output/feature/metadata.rs +++ b/sdk/src/types/block/output/feature/metadata.rs @@ -1,24 +1,52 @@ // Copyright 2021-2022 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 -use alloc::{boxed::Box, string::String, vec::Vec}; -use core::{ops::RangeInclusive, str::FromStr}; +use alloc::{collections::BTreeMap, string::String, vec::Vec}; +use core::ops::{Deref, RangeInclusive}; -use packable::{bounded::BoundedU16, prefix::BoxedSlicePrefix}; +use packable::{ + bounded::{BoundedU16, BoundedU8}, + prefix::{BTreeMapPrefix, BoxedSlicePrefix}, +}; use crate::types::block::{output::StorageScore, protocol::WorkScore, Error}; pub(crate) type MetadataFeatureLength = BoundedU16<{ *MetadataFeature::LENGTH_RANGE.start() }, { *MetadataFeature::LENGTH_RANGE.end() }>; +pub(crate) type MetadataFeatureKeyLength = BoundedU8<1, { u8::MAX }>; +pub(crate) type MetadataFeatureValueLength = BoundedU16<0, { u16::MAX }>; + /// Defines metadata, arbitrary binary data, that will be stored in the output. #[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Hash, packable::Packable)] -#[packable(unpack_error = Error, with = |err| Error::InvalidMetadataFeatureLength(err.into_prefix_err().into()))] +#[packable(unpack_error = Error, with = |err| Error::InvalidMetadataFeature(err.to_string()))] pub struct MetadataFeature( // Binary data. - pub(crate) BoxedSlicePrefix, + #[packable(verify_with = verify_keys_packable)] + pub(crate) BTreeMapPrefix< + BoxedSlicePrefix, + BoxedSlicePrefix, + MetadataFeatureLength, + >, ); +fn verify_keys_packable( + map: &BTreeMapPrefix< + BoxedSlicePrefix, + BoxedSlicePrefix, + MetadataFeatureLength, + >, +) -> Result<(), Error> { + if VERIFY { + for key in map.keys() { + if !key.is_ascii() { + return Err(Error::InvalidMetadataKeyBytes(key.to_vec())); + } + } + } + Ok(()) +} + impl MetadataFeature { /// The [`Feature`](crate::types::block::output::Feature) kind of [`MetadataFeature`]. pub const KIND: u8 = 2; @@ -27,14 +55,22 @@ impl MetadataFeature { /// Creates a new [`MetadataFeature`]. #[inline(always)] - pub fn new(data: impl Into>) -> Result { - Self::try_from(data.into()) + pub fn new(data: BTreeMap, Vec>) -> Result { + for key in data.keys() { + if !key.is_ascii() { + return Err(Error::InvalidMetadataKeyBytes(key.to_vec())); + } + } + Self::try_from(data) } /// Returns the data. #[inline(always)] - pub fn data(&self) -> &[u8] { - &self.0 + pub fn data( + &self, + ) -> &BTreeMap, BoxedSlicePrefix> + { + self.0.deref() } } @@ -42,62 +78,53 @@ impl StorageScore for MetadataFeature {} impl WorkScore for MetadataFeature {} -macro_rules! impl_from_vec { - ($type:ty) => { - impl TryFrom<$type> for MetadataFeature { - type Error = Error; +impl TryFrom, Vec>> for MetadataFeature { + type Error = Error; - fn try_from(value: $type) -> Result { - Vec::::from(value).try_into() + fn try_from(data: BTreeMap, Vec>) -> Result { + let mut res = BTreeMap::< + BoxedSlicePrefix, + BoxedSlicePrefix, + >::new(); + for (k, v) in data { + if !k.is_ascii() { + return Err(Error::InvalidMetadataKeyBytes(k.to_vec())); } + res.insert( + k.into_boxed_slice() + .try_into() + .map_err(Error::InvalidMetadataFeatureKeyLength)?, + v.into_boxed_slice() + .try_into() + .map_err(Error::InvalidMetadataFeatureValueLength)?, + ); } - }; -} -impl_from_vec!(&str); -impl_from_vec!(String); -impl_from_vec!(&[u8]); - -impl TryFrom<[u8; N]> for MetadataFeature { - type Error = Error; - - fn try_from(value: [u8; N]) -> Result { - value.to_vec().try_into() - } -} - -impl TryFrom> for MetadataFeature { - type Error = Error; - - fn try_from(data: Vec) -> Result { - data.into_boxed_slice().try_into() - } -} - -impl TryFrom> for MetadataFeature { - type Error = Error; - - fn try_from(data: Box<[u8]>) -> Result { - data.try_into().map(Self).map_err(Error::InvalidMetadataFeatureLength) - } -} - -impl FromStr for MetadataFeature { - type Err = Error; - - fn from_str(s: &str) -> Result { - Self::new(prefix_hex::decode::>(s).map_err(Error::Hex)?) + Ok(Self(res.try_into().map_err(Error::InvalidMetadataFeatureLength)?)) } } impl core::fmt::Display for MetadataFeature { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - write!(f, "{}", prefix_hex::encode(self.data())) + write!( + f, + "{:?}", + self.0 + .keys() + // Safe to unwrap, keys must be ascii + .map(|k| alloc::str::from_utf8(k).unwrap()) + .collect::>() + ) } } impl core::fmt::Debug for MetadataFeature { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - write!(f, "MetadataFeature({self})") + let dbg_map: BTreeMap<&str, String> = self + .0 + .iter() + .map(|(k, v)| (alloc::str::from_utf8(k).unwrap(), prefix_hex::encode(v.as_ref()))) + .collect(); + write!(f, "MetadataFeature({dbg_map:?})") } } @@ -434,35 +461,74 @@ pub(crate) mod irc_30 { #[cfg(feature = "serde")] pub(crate) mod dto { - use alloc::borrow::Cow; + use alloc::collections::BTreeMap; - use serde::{Deserialize, Serialize}; + use serde::{de, Deserialize, Deserializer, Serialize}; + use serde_json::Value; use super::*; - use crate::utils::serde::cow_boxed_slice_prefix_hex_bytes; - #[derive(Serialize, Deserialize)] - struct MetadataFeatureDto<'a> { + #[derive(Serialize)] + struct MetadataFeatureDto { #[serde(rename = "type")] kind: u8, - #[serde(with = "cow_boxed_slice_prefix_hex_bytes")] - data: Cow<'a, BoxedSlicePrefix>, + entries: BTreeMap, } - impl<'a> From<&'a MetadataFeature> for MetadataFeatureDto<'a> { - fn from(value: &'a MetadataFeature) -> Self { + impl<'de> Deserialize<'de> for MetadataFeature { + fn deserialize>(d: D) -> Result { + let value = Value::deserialize(d)?; + Ok( + match value + .get("type") + .and_then(Value::as_u64) + .ok_or_else(|| de::Error::custom("invalid metadata type"))? as u8 + { + Self::KIND => { + let map: BTreeMap = serde_json::from_value( + value + .get("entries") + .ok_or_else(|| de::Error::custom("missing metadata entries"))? + .clone(), + ) + .map_err(|e| de::Error::custom(format!("cannot deserialize metadata feature: {e}")))?; + + Self::try_from( + map.into_iter() + .map(|(key, value)| Ok((key.into_bytes(), prefix_hex::decode::>(value)?))) + .collect::, Vec>, prefix_hex::Error>>() + .map_err(de::Error::custom)?, + ) + .map_err(de::Error::custom)? + } + _ => return Err(de::Error::custom("invalid metadata feature")), + }, + ) + } + } + + impl From<&MetadataFeature> for MetadataFeatureDto { + fn from(value: &MetadataFeature) -> Self { + let mut entries = BTreeMap::new(); + for (k, v) in value.0.iter() { + entries.insert( + // Safe to unwrap, keys must be ascii + alloc::str::from_utf8(k.as_ref()).expect("invalid ascii").to_string(), + prefix_hex::encode(v.as_ref()), + ); + } Self { kind: MetadataFeature::KIND, - data: Cow::Borrowed(&value.0), + entries, } } } - - impl<'a> From> for MetadataFeature { - fn from(value: MetadataFeatureDto<'a>) -> Self { - Self(value.data.into_owned()) + impl Serialize for MetadataFeature { + fn serialize(&self, s: S) -> Result + where + S: serde::Serializer, + { + MetadataFeatureDto::from(self).serialize(s) } } - - crate::impl_serde_typed_dto!(MetadataFeature, MetadataFeatureDto<'_>, "metadata feature"); } diff --git a/sdk/src/types/block/output/feature/mod.rs b/sdk/src/types/block/output/feature/mod.rs index eed47ced38..d07c2f4618 100644 --- a/sdk/src/types/block/output/feature/mod.rs +++ b/sdk/src/types/block/output/feature/mod.rs @@ -20,7 +20,11 @@ use packable::{bounded::BoundedU8, prefix::BoxedSlicePrefix, Packable}; pub use self::metadata::irc_27::{Attribute, Irc27Metadata}; #[cfg(feature = "irc_30")] pub use self::metadata::irc_30::Irc30Metadata; -pub(crate) use self::{block_issuer::BlockIssuerKeyCount, metadata::MetadataFeatureLength, tag::TagFeatureLength}; +pub(crate) use self::{ + block_issuer::BlockIssuerKeyCount, + metadata::{MetadataFeatureKeyLength, MetadataFeatureLength, MetadataFeatureValueLength}, + tag::TagFeatureLength, +}; pub use self::{ block_issuer::{BlockIssuerFeature, BlockIssuerKey, BlockIssuerKeys, Ed25519BlockIssuerKey}, issuer::IssuerFeature, diff --git a/sdk/src/types/block/output/mod.rs b/sdk/src/types/block/output/mod.rs index 501a2b93d1..d1ae55bc1b 100644 --- a/sdk/src/types/block/output/mod.rs +++ b/sdk/src/types/block/output/mod.rs @@ -49,7 +49,7 @@ pub use self::{ unlock_condition::{UnlockCondition, UnlockConditions}, }; pub(crate) use self::{ - feature::{MetadataFeatureLength, TagFeatureLength}, + feature::{MetadataFeatureKeyLength, MetadataFeatureLength, MetadataFeatureValueLength, TagFeatureLength}, native_token::NativeTokenCount, output_id::OutputIndex, unlock_condition::AddressUnlockCondition, diff --git a/sdk/src/types/block/rand/output/feature.rs b/sdk/src/types/block/rand/output/feature.rs index 57a8fdd609..e5c6615123 100644 --- a/sdk/src/types/block/rand/output/feature.rs +++ b/sdk/src/types/block/rand/output/feature.rs @@ -1,7 +1,13 @@ // Copyright 2021 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 -use alloc::{collections::BTreeSet, vec::Vec}; +use alloc::{ + collections::{BTreeMap, BTreeSet}, + vec::Vec, +}; +use core::ops::Range; + +use rand::distributions::{Alphanumeric, DistString}; use crate::types::block::{ output::feature::{ @@ -29,8 +35,38 @@ pub fn rand_issuer_feature() -> IssuerFeature { /// Generates a random [`MetadataFeature`]. pub fn rand_metadata_feature() -> MetadataFeature { - let bytes = rand_bytes(rand_number_range(MetadataFeature::LENGTH_RANGE) as usize); - MetadataFeature::new(bytes).unwrap() + let mut map = BTreeMap::new(); + let mut total_size = 0; + for _ in 0..10 { + if total_size >= *MetadataFeature::LENGTH_RANGE.end() as usize - u8::MAX as usize { + break; + } + // Key length + total_size += 1; + let key = Alphanumeric.sample_string( + &mut rand::thread_rng(), + rand_number_range(Range { + start: 1, + end: u8::MAX.into(), + }), + ); + total_size += key.as_bytes().len(); + + if total_size >= *MetadataFeature::LENGTH_RANGE.end() as usize - 2 { + break; + } + // Value length + total_size += 2; + let bytes = rand_bytes(rand_number_range(Range { + start: 0, + end: *MetadataFeature::LENGTH_RANGE.end() as usize - total_size, + }) as usize); + total_size += bytes.len(); + + map.insert(key.into(), bytes); + } + + MetadataFeature::new(map).unwrap() } /// Generates a random [`TagFeature`]. diff --git a/sdk/src/types/fuzz/Cargo.toml b/sdk/src/types/fuzz/Cargo.toml index be3e427c35..c4f9eee680 100644 --- a/sdk/src/types/fuzz/Cargo.toml +++ b/sdk/src/types/fuzz/Cargo.toml @@ -12,7 +12,7 @@ cargo-fuzz = true iota-types = { path = "..", default-features = false } libfuzzer-sys = { version = "0.4.7", default-features = false } -packable = { version = "0.10.0", default-features = false } +packable = { git = "https://github.com/iotaledger/common-rs", rev = "c72287fa24254b349f6e935b847485b0be141557", default-features = false } # Prevent this from interfering with workspaces [workspace] diff --git a/sdk/src/wallet/operations/balance.rs b/sdk/src/wallet/operations/balance.rs index 8723878780..08e1b56eb0 100644 --- a/sdk/src/wallet/operations/balance.rs +++ b/sdk/src/wallet/operations/balance.rs @@ -299,17 +299,19 @@ where } }); - let metadata = wallet_data - .native_token_foundries - .get(&FoundryId::from(*native_token.token_id())) - .and_then(|foundry| foundry.immutable_features().metadata()) - .cloned(); + // TODO: enable again when MetadataFeature is cleared up + // let metadata = wallet_data + // .native_token_foundries + // .get(&FoundryId::from(*native_token.token_id())) + // .and_then(|foundry| foundry.immutable_features().metadata()) + // .cloned(); balance.native_tokens.push(NativeTokensBalance { token_id: *native_token.token_id(), total: native_token.amount(), available: native_token.amount() - *locked_native_token_amount.unwrap_or(&U256::from(0u8)), - metadata, + // TODO: enable again when MetadataFeature is cleared up + // metadata, }) } diff --git a/sdk/src/wallet/operations/output_consolidation.rs b/sdk/src/wallet/operations/output_consolidation.rs index 7fae58242d..0046592c8f 100644 --- a/sdk/src/wallet/operations/output_consolidation.rs +++ b/sdk/src/wallet/operations/output_consolidation.rs @@ -130,8 +130,8 @@ where /// Prepares the transaction for [Wallet::consolidate_outputs()]. pub async fn prepare_consolidate_outputs(&self, params: ConsolidationParams) -> Result { log::debug!("[OUTPUT_CONSOLIDATION] prepare consolidating outputs if needed"); - #[cfg(feature = "participation")] - let voting_output = self.get_voting_output().await?; + // #[cfg(feature = "participation")] + // let voting_output = self.get_voting_output().await?; let slot_index = self.client().get_slot_index().await?; let mut outputs_to_consolidate = Vec::new(); let wallet_data = self.data().await; @@ -139,13 +139,13 @@ where let wallet_address = wallet_data.address.clone(); for (output_id, output_data) in &wallet_data.unspent_outputs { - #[cfg(feature = "participation")] - if let Some(ref voting_output) = voting_output { - // Remove voting output from inputs, because we want to keep its features and not consolidate it. - if output_data.output_id == voting_output.output_id { - continue; - } - } + // #[cfg(feature = "participation")] + // if let Some(ref voting_output) = voting_output { + // // Remove voting output from inputs, because we want to keep its features and not consolidate it. + // if output_data.output_id == voting_output.output_id { + // continue; + // } + // } let is_locked_output = wallet_data.locked_outputs.contains(output_id); let should_consolidate_output = self diff --git a/sdk/src/wallet/operations/participation/mod.rs b/sdk/src/wallet/operations/participation/mod.rs index 481881c214..152e6555e9 100644 --- a/sdk/src/wallet/operations/participation/mod.rs +++ b/sdk/src/wallet/operations/participation/mod.rs @@ -8,24 +8,24 @@ // address. // If the user has designated funds to vote with, the resulting output MUST NOT be used for input selection. -pub(crate) mod event; -pub(crate) mod voting; -pub(crate) mod voting_power; +// pub(crate) mod event; +// pub(crate) mod voting; +// pub(crate) mod voting_power; -use std::collections::{hash_map::Entry, HashMap, HashSet}; +use std::collections::HashMap; use serde::{Deserialize, Serialize}; use crate::{ - client::{node_manager::node::Node, secret::SecretManage, Client}, + client::{node_manager::node::Node, secret::SecretManage}, types::{ api::plugins::participation::{ responses::TrackedParticipation, - types::{ParticipationEventData, ParticipationEventId, Participations, PARTICIPATION_TAG}, + types::{ParticipationEventData, ParticipationEventId, PARTICIPATION_TAG}, }, block::output::{unlock_condition::UnlockCondition, Output, OutputId}, }, - wallet::{core::WalletData, task, types::OutputData, Result, Wallet}, + wallet::{core::WalletData, types::OutputData, Result, Wallet}, }; /// An object containing an account's entire participation overview. @@ -51,174 +51,175 @@ where crate::wallet::Error: From, crate::client::Error: From, { - /// Calculates the voting overview of a wallet. If event_ids are provided, only return outputs and tracked - /// participations for them. - pub async fn get_participation_overview( - &self, - event_ids: Option>, - ) -> Result { - log::debug!("[get_participation_overview]"); - // TODO: Could use the address endpoint in the future when https://github.com/iotaledger/inx-participation/issues/50 is done. + // /// Calculates the voting overview of a wallet. If event_ids are provided, only return outputs and tracked + // /// participations for them. + // pub async fn get_participation_overview( + // &self, + // event_ids: Option>, + // ) -> Result { + // log::debug!("[get_participation_overview]"); + // // TODO: Could use the address endpoint in the future when https://github.com/iotaledger/inx-participation/issues/50 is done. - let mut spent_cached_outputs = self - .storage_manager - .read() - .await - .get_cached_participation_output_status() - .await?; - let restored_spent_cached_outputs_len = spent_cached_outputs.len(); - log::debug!( - "[get_participation_overview] restored_spent_cached_outputs_len: {}", - restored_spent_cached_outputs_len - ); - let wallet_data = self.data().await; - let participation_outputs = wallet_data.outputs().values().filter(|output_data| { - is_valid_participation_output(&output_data.output) - // Check that the metadata exists, because otherwise we aren't participating for anything - && output_data.output.features().and_then(|f| f.metadata()).is_some() - // Don't add spent cached outputs, we have their data already and it can't change anymore - && !spent_cached_outputs.contains_key(&output_data.output_id) - }); + // let mut spent_cached_outputs = self + // .storage_manager + // .read() + // .await + // .get_cached_participation_output_status() + // .await?; + // let restored_spent_cached_outputs_len = spent_cached_outputs.len(); + // log::debug!( + // "[get_participation_overview] restored_spent_cached_outputs_len: {}", + // restored_spent_cached_outputs_len + // ); + // let wallet_data = self.data().await; + // let participation_outputs = wallet_data.outputs().values().filter(|output_data| { + // is_valid_participation_output(&output_data.output) + // // Check that the metadata exists, because otherwise we aren't participating for anything + // && output_data.output.features().and_then(|f| f.metadata()).is_some() + // // Don't add spent cached outputs, we have their data already and it can't change anymore + // && !spent_cached_outputs.contains_key(&output_data.output_id) + // }); - let mut events = HashMap::new(); - let mut spent_outputs = HashSet::new(); - for output_data in participation_outputs { - // PANIC: the filter already checks that the metadata exists. - let metadata = output_data.output.features().and_then(|f| f.metadata()).unwrap(); - if let Ok(participations) = Participations::from_bytes(&mut metadata.data()) { - for participation in participations.participations { - // Skip events that aren't in `event_ids` if not None - if let Some(event_ids) = event_ids.as_ref() { - if !event_ids.contains(&participation.event_id) { - continue; - } - } - match events.entry(participation.event_id) { - Entry::Vacant(entry) => { - entry.insert(vec![output_data.output_id]); - } - Entry::Occupied(mut entry) => { - entry.get_mut().push(output_data.output_id); - } - } - if output_data.is_spent { - spent_outputs.insert(output_data.output_id); - } - } - }; - } + // let mut events = HashMap::new(); + // let mut spent_outputs = HashSet::new(); + // for output_data in participation_outputs { + // // PANIC: the filter already checks that the metadata exists. + // let metadata = output_data.output.features().and_then(|f| f.metadata()).unwrap(); + // if let Ok(participations) = Participations::from_bytes(&mut metadata.data()) { + // for participation in participations.participations { + // // Skip events that aren't in `event_ids` if not None + // if let Some(event_ids) = event_ids.as_ref() { + // if !event_ids.contains(&participation.event_id) { + // continue; + // } + // } + // match events.entry(participation.event_id) { + // Entry::Vacant(entry) => { + // entry.insert(vec![output_data.output_id]); + // } + // Entry::Occupied(mut entry) => { + // entry.get_mut().push(output_data.output_id); + // } + // } + // if output_data.is_spent { + // spent_outputs.insert(output_data.output_id); + // } + // } + // }; + // } - let mut participations: HashMap> = HashMap::new(); + // let mut participations: HashMap> = + // HashMap::new(); - // Add cached data - for (output_id, output_status_response) in &spent_cached_outputs { - for (event_id, participation) in &output_status_response.participations { - // Skip events that aren't in `event_ids` if not None - if let Some(event_ids) = event_ids.as_ref() { - if !event_ids.contains(event_id) { - continue; - } - } - match participations.entry(*event_id) { - Entry::Vacant(entry) => { - entry.insert(HashMap::from([(*output_id, participation.clone())])); - } - Entry::Occupied(mut entry) => { - entry.get_mut().insert(*output_id, participation.clone()); - } - } - } - } + // // Add cached data + // for (output_id, output_status_response) in &spent_cached_outputs { + // for (event_id, participation) in &output_status_response.participations { + // // Skip events that aren't in `event_ids` if not None + // if let Some(event_ids) = event_ids.as_ref() { + // if !event_ids.contains(event_id) { + // continue; + // } + // } + // match participations.entry(*event_id) { + // Entry::Vacant(entry) => { + // entry.insert(HashMap::from([(*output_id, participation.clone())])); + // } + // Entry::Occupied(mut entry) => { + // entry.get_mut().insert(*output_id, participation.clone()); + // } + // } + // } + // } - for (event_id, mut output_ids) in events { - log::debug!( - "[get_participation_overview] requesting {} outputs for event {event_id}", - output_ids.len() - ); - let event_client = self.get_client_for_event(&event_id).await?; + // for (event_id, mut output_ids) in events { + // log::debug!( + // "[get_participation_overview] requesting {} outputs for event {event_id}", + // output_ids.len() + // ); + // let event_client = self.get_client_for_event(&event_id).await?; - output_ids.retain(|output_id| { - // Skip if participations already contains this output id with participation for this event - if let Some(p) = participations.get(&event_id) { - if p.contains_key(output_id) { - log::debug!( - "[get_participation_overview] skip requesting already known {output_id} for event {event_id}", - ); - return false; - } - } - true - }); + // output_ids.retain(|output_id| { + // // Skip if participations already contains this output id with participation for this event + // if let Some(p) = participations.get(&event_id) { + // if p.contains_key(output_id) { + // log::debug!( + // "[get_participation_overview] skip requesting already known {output_id} for event + // {event_id}", ); + // return false; + // } + // } + // true + // }); - let results = futures::future::try_join_all(output_ids.chunks(100).map(ToOwned::to_owned).map(|chunk| { - let event_client = event_client.clone(); - task::spawn(async move { - futures::future::join_all(chunk.iter().map(|output_id| async { - let output_id = *output_id; - (event_client.output_status(&output_id).await, output_id) - })) - .await - }) - })) - .await?; + // let results = futures::future::try_join_all(output_ids.chunks(100).map(ToOwned::to_owned).map(|chunk| { + // let event_client = event_client.clone(); + // task::spawn(async move { + // futures::future::join_all(chunk.iter().map(|output_id| async { + // let output_id = *output_id; + // (event_client.output_status(&output_id).await, output_id) + // })) + // .await + // }) + // })) + // .await?; - for (result, output_id) in results.into_iter().flatten() { - match result { - Ok(status) => { - // Cache data for spent outputs - if spent_outputs.contains(&output_id) { - match spent_cached_outputs.entry(output_id) { - Entry::Vacant(entry) => { - entry.insert(status.clone()); - } - Entry::Occupied(mut entry) => { - let output_status_response = entry.get_mut(); - for (event_id, participation) in &status.participations { - output_status_response - .participations - .insert(*event_id, participation.clone()); - } - } - } - } - for (event_id, participation) in status.participations { - // Skip events that aren't in `event_ids` if not None - if let Some(event_ids) = event_ids.as_ref() { - if !event_ids.contains(&event_id) { - continue; - } - } - match participations.entry(event_id) { - Entry::Vacant(entry) => { - entry.insert(HashMap::from([(output_id, participation)])); - } - Entry::Occupied(mut entry) => { - entry.get_mut().insert(output_id, participation); - } - } - } - } - Err(crate::client::Error::Node(crate::client::node_api::error::Error::NotFound(_))) => {} - Err(e) => return Err(crate::wallet::Error::Client(e.into())), - } - } - } + // for (result, output_id) in results.into_iter().flatten() { + // match result { + // Ok(status) => { + // // Cache data for spent outputs + // if spent_outputs.contains(&output_id) { + // match spent_cached_outputs.entry(output_id) { + // Entry::Vacant(entry) => { + // entry.insert(status.clone()); + // } + // Entry::Occupied(mut entry) => { + // let output_status_response = entry.get_mut(); + // for (event_id, participation) in &status.participations { + // output_status_response + // .participations + // .insert(*event_id, participation.clone()); + // } + // } + // } + // } + // for (event_id, participation) in status.participations { + // // Skip events that aren't in `event_ids` if not None + // if let Some(event_ids) = event_ids.as_ref() { + // if !event_ids.contains(&event_id) { + // continue; + // } + // } + // match participations.entry(event_id) { + // Entry::Vacant(entry) => { + // entry.insert(HashMap::from([(output_id, participation)])); + // } + // Entry::Occupied(mut entry) => { + // entry.get_mut().insert(output_id, participation); + // } + // } + // } + // } + // Err(crate::client::Error::Node(crate::client::node_api::error::Error::NotFound(_))) => {} + // Err(e) => return Err(crate::wallet::Error::Client(e.into())), + // } + // } + // } - log::debug!( - "[get_participation_overview] new spent_cached_outputs: {}", - spent_cached_outputs.len() - ); - // Only store updated data if new outputs got added - if spent_cached_outputs.len() > restored_spent_cached_outputs_len { - self.storage_manager - .read() - .await - .set_cached_participation_output_status(&spent_cached_outputs) - .await?; - } + // log::debug!( + // "[get_participation_overview] new spent_cached_outputs: {}", + // spent_cached_outputs.len() + // ); + // // Only store updated data if new outputs got added + // if spent_cached_outputs.len() > restored_spent_cached_outputs_len { + // self.storage_manager + // .read() + // .await + // .set_cached_participation_output_status(&spent_cached_outputs) + // .await?; + // } - Ok(ParticipationOverview { participations }) - } + // Ok(ParticipationOverview { participations }) + // } /// Returns the voting output ("PARTICIPATION" tag). /// @@ -227,54 +228,54 @@ where self.data().await.get_voting_output() } - /// Gets client for an event. - /// If event isn't found, the client from the account will be returned. - pub(crate) async fn get_client_for_event(&self, id: &ParticipationEventId) -> crate::wallet::Result { - log::debug!("[get_client_for_event]"); - let events = self.storage_manager.read().await.get_participation_events().await?; + // /// Gets client for an event. + // /// If event isn't found, the client from the account will be returned. + // pub(crate) async fn get_client_for_event(&self, id: &ParticipationEventId) -> crate::wallet::Result { + // log::debug!("[get_client_for_event]"); + // let events = self.storage_manager.read().await.get_participation_events().await?; - let event_with_nodes = match events.get(id) { - Some(event_with_nodes) => event_with_nodes, - None => return Ok(self.client().clone()), - }; + // let event_with_nodes = match events.get(id) { + // Some(event_with_nodes) => event_with_nodes, + // None => return Ok(self.client().clone()), + // }; - let mut client_builder = Client::builder().with_ignore_node_health(); - for node in &event_with_nodes.nodes { - client_builder = client_builder.with_node_auth(node.url.as_str(), node.auth.clone())?; - } + // let mut client_builder = Client::builder().with_ignore_node_health(); + // for node in &event_with_nodes.nodes { + // client_builder = client_builder.with_node_auth(node.url.as_str(), node.auth.clone())?; + // } - Ok(client_builder.finish().await?) - } + // Ok(client_builder.finish().await?) + // } - /// Checks if events in the participations ended and removes them. - pub(crate) async fn remove_ended_participation_events( - &self, - participations: &mut Participations, - ) -> crate::wallet::Result<()> { - log::debug!("[remove_ended_participation_events]"); - // TODO change to one of the new timestamps, which ones ? - let latest_milestone_index = 0; - // let latest_milestone_index = self.client().get_info().await?.node_info.status.latest_milestone.index; + // /// Checks if events in the participations ended and removes them. + // pub(crate) async fn remove_ended_participation_events( + // &self, + // participations: &mut Participations, + // ) -> crate::wallet::Result<()> { + // log::debug!("[remove_ended_participation_events]"); + // // TODO change to one of the new timestamps, which ones ? + // let latest_milestone_index = 0; + // // let latest_milestone_index = self.client().get_info().await?.node_info.status.latest_milestone.index; - let events = self.storage_manager.read().await.get_participation_events().await?; + // let events = self.storage_manager.read().await.get_participation_events().await?; - for participation in participations.participations.clone().iter() { - if let Some(event_with_nodes) = events.get(&participation.event_id) { - if event_with_nodes.data.milestone_index_end() < &latest_milestone_index { - participations.remove(&participation.event_id); - } - } else { - // If not found in local events, try to get the event status from the client. - if let Ok(event_status) = self.get_participation_event_status(&participation.event_id).await { - if event_status.status() == "ended" { - participations.remove(&participation.event_id); - } - } - } - } + // for participation in participations.participations.clone().iter() { + // if let Some(event_with_nodes) = events.get(&participation.event_id) { + // if event_with_nodes.data.milestone_index_end() < &latest_milestone_index { + // participations.remove(&participation.event_id); + // } + // } else { + // // If not found in local events, try to get the event status from the client. + // if let Ok(event_status) = self.get_participation_event_status(&participation.event_id).await { + // if event_status.status() == "ended" { + // participations.remove(&participation.event_id); + // } + // } + // } + // } - Ok(()) - } + // Ok(()) + // } } impl WalletData { diff --git a/sdk/src/wallet/operations/transaction/high_level/create_account.rs b/sdk/src/wallet/operations/transaction/high_level/create_account.rs index 9ae930a68f..fef642d842 100644 --- a/sdk/src/wallet/operations/transaction/high_level/create_account.rs +++ b/sdk/src/wallet/operations/transaction/high_level/create_account.rs @@ -83,24 +83,25 @@ where None => self.address().await.inner().clone(), }; - let mut account_output_builder = + let account_output_builder = AccountOutputBuilder::new_with_minimum_amount(storage_score_params, AccountId::null()) .with_foundry_counter(0) .add_unlock_condition(AddressUnlockCondition::new(address.clone())); - if let Some(CreateAccountParams { - immutable_metadata, - metadata, - .. - }) = params - { - if let Some(immutable_metadata) = immutable_metadata { - account_output_builder = - account_output_builder.add_immutable_feature(MetadataFeature::new(immutable_metadata)?); - } - if let Some(metadata) = metadata { - account_output_builder = account_output_builder.add_feature(MetadataFeature::new(metadata)?); - } - } + // TODO: enable again when MetadataFeature is cleared up + // if let Some(CreateAccountParams { + // immutable_metadata, + // metadata, + // .. + // }) = params + // { + // if let Some(immutable_metadata) = immutable_metadata { + // account_output_builder = + // account_output_builder.add_immutable_feature(MetadataFeature::new(immutable_metadata)?); + // } + // if let Some(metadata) = metadata { + // account_output_builder = account_output_builder.add_feature(MetadataFeature::new(metadata)?); + // } + // } let outputs = [account_output_builder.finish_output()?]; diff --git a/sdk/src/wallet/operations/transaction/high_level/minting/create_native_token.rs b/sdk/src/wallet/operations/transaction/high_level/minting/create_native_token.rs index e74dbc10f4..2e9f0776b6 100644 --- a/sdk/src/wallet/operations/transaction/high_level/minting/create_native_token.rs +++ b/sdk/src/wallet/operations/transaction/high_level/minting/create_native_token.rs @@ -169,9 +169,11 @@ where account_id, ))); - if let Some(foundry_metadata) = params.foundry_metadata { - foundry_builder = foundry_builder.add_immutable_feature(MetadataFeature::new(foundry_metadata)?) - } + // TODO: enable again when MetadataFeature is cleared up + // if let Some(foundry_metadata) = params.foundry_metadata { + // foundry_builder = + // foundry_builder.add_immutable_feature(MetadataFeature::new(foundry_metadata)?) + // } foundry_builder.finish_output()? }, // Native Tokens will be added automatically in the remainder output in try_select_inputs() diff --git a/sdk/src/wallet/operations/transaction/high_level/minting/mint_nfts.rs b/sdk/src/wallet/operations/transaction/high_level/minting/mint_nfts.rs index 613fd48d19..ae278f4884 100644 --- a/sdk/src/wallet/operations/transaction/high_level/minting/mint_nfts.rs +++ b/sdk/src/wallet/operations/transaction/high_level/minting/mint_nfts.rs @@ -191,9 +191,10 @@ where nft_builder = nft_builder.add_feature(SenderFeature::new(sender)); } - if let Some(metadata) = metadata { - nft_builder = nft_builder.add_feature(MetadataFeature::new(metadata)?); - } + // TODO: enable again when MetadataFeature is cleared up + // if let Some(metadata) = metadata { + // nft_builder = nft_builder.add_feature(MetadataFeature::new(metadata)?); + // } if let Some(tag) = tag { nft_builder = nft_builder.add_feature(TagFeature::new(tag)?); @@ -203,9 +204,10 @@ where nft_builder = nft_builder.add_immutable_feature(IssuerFeature::new(issuer)); } - if let Some(immutable_metadata) = immutable_metadata { - nft_builder = nft_builder.add_immutable_feature(MetadataFeature::new(immutable_metadata)?); - } + // TODO: enable again when MetadataFeature is cleared up + // if let Some(immutable_metadata) = immutable_metadata { + // nft_builder = nft_builder.add_immutable_feature(MetadataFeature::new(immutable_metadata)?); + // } outputs.push(nft_builder.finish_output()?); } diff --git a/sdk/src/wallet/operations/transaction/prepare_output.rs b/sdk/src/wallet/operations/transaction/prepare_output.rs index 70d832d510..02f255408e 100644 --- a/sdk/src/wallet/operations/transaction/prepare_output.rs +++ b/sdk/src/wallet/operations/transaction/prepare_output.rs @@ -63,11 +63,12 @@ where )?); } - if let Some(metadata) = features.metadata { - first_output_builder = first_output_builder.add_feature(MetadataFeature::new( - prefix_hex::decode::>(metadata).map_err(|_| Error::InvalidField("metadata"))?, - )?); - } + // TODO: enable again when MetadataFeature is cleared up + // if let Some(metadata) = features.metadata { + // first_output_builder = first_output_builder.add_feature(MetadataFeature::new( + // prefix_hex::decode::>(metadata).map_err(|_| Error::InvalidField("metadata"))?, + // )?); + // } if let Some(sender) = features.sender { first_output_builder = first_output_builder.add_feature(SenderFeature::new(sender)) diff --git a/sdk/src/wallet/storage/constants.rs b/sdk/src/wallet/storage/constants.rs index e50e1a3f15..3891fecf14 100644 --- a/sdk/src/wallet/storage/constants.rs +++ b/sdk/src/wallet/storage/constants.rs @@ -24,7 +24,7 @@ pub(crate) const WALLET_SYNC_OPTIONS: &str = "wallet-sync-options"; pub(crate) const SECRET_MANAGER_KEY: &str = "secret-manager"; -#[cfg(feature = "participation")] -pub(crate) const PARTICIPATION_EVENTS: &str = "participation-events"; -#[cfg(feature = "participation")] -pub(crate) const PARTICIPATION_CACHED_OUTPUTS: &str = "participation-cached-outputs"; +// #[cfg(feature = "participation")] +// pub(crate) const PARTICIPATION_EVENTS: &str = "participation-events"; +// #[cfg(feature = "participation")] +// pub(crate) const PARTICIPATION_CACHED_OUTPUTS: &str = "participation-cached-outputs"; diff --git a/sdk/src/wallet/storage/mod.rs b/sdk/src/wallet/storage/mod.rs index 63149817f2..d467f8bb2e 100644 --- a/sdk/src/wallet/storage/mod.rs +++ b/sdk/src/wallet/storage/mod.rs @@ -11,10 +11,10 @@ mod kind; mod manager; /// Storage options. mod options; -/// Storage functions related to participation. -#[cfg(feature = "participation")] -#[cfg_attr(docsrs, doc(cfg(feature = "participation")))] -mod participation; +// /// Storage functions related to participation. +// #[cfg(feature = "participation")] +// #[cfg_attr(docsrs, doc(cfg(feature = "participation")))] +// mod participation; use async_trait::async_trait; use crypto::ciphers::chacha; diff --git a/sdk/src/wallet/types/balance.rs b/sdk/src/wallet/types/balance.rs index 6b068788f2..3fb2249fe6 100644 --- a/sdk/src/wallet/types/balance.rs +++ b/sdk/src/wallet/types/balance.rs @@ -129,10 +129,11 @@ pub struct NativeTokensBalance { /// Balance that can currently be spent #[getset(get_copy = "pub")] pub(crate) available: U256, - /// Token foundry immutable metadata - #[getset(get = "pub")] - #[serde(with = "crate::utils::serde::option_string")] - pub(crate) metadata: Option, + // TODO: enable again when MetadataFeature is cleared up + // /// Token foundry immutable metadata + // #[getset(get = "pub")] + // #[serde(with = "crate::utils::serde::option_string")] + // pub(crate) metadata: Option, } impl Default for NativeTokensBalance { @@ -141,7 +142,8 @@ impl Default for NativeTokensBalance { token_id: TokenId::null(), total: U256::from(0u8), available: U256::from(0u8), - metadata: None, + // TODO: enable again when MetadataFeature is cleared up + // metadata: None, } } } @@ -150,9 +152,10 @@ impl std::ops::AddAssign for NativeTokensBalance { fn add_assign(&mut self, rhs: Self) { self.total += rhs.total; self.available += rhs.available; - if self.metadata.is_none() { - self.metadata = rhs.metadata; - } + // TODO: enable again when MetadataFeature is cleared up + // if self.metadata.is_none() { + // self.metadata = rhs.metadata; + // } } } diff --git a/sdk/tests/client/input_selection/nft_outputs.rs b/sdk/tests/client/input_selection/nft_outputs.rs index 33ddf7c960..50306791e1 100644 --- a/sdk/tests/client/input_selection/nft_outputs.rs +++ b/sdk/tests/client/input_selection/nft_outputs.rs @@ -1210,67 +1210,68 @@ fn transitioned_zero_nft_id_no_longer_is_zero() { }); } -#[test] -fn changed_immutable_metadata() { - let protocol_parameters = protocol_parameters(); - let nft_id_1 = NftId::from_str(NFT_ID_1).unwrap(); +// TODO: enable again when MetadataFeature is cleared up +// #[test] +// fn changed_immutable_metadata() { +// let protocol_parameters = protocol_parameters(); +// let nft_id_1 = NftId::from_str(NFT_ID_1).unwrap(); - #[cfg(feature = "irc_27")] - let metadata = iota_sdk::types::block::output::feature::Irc27Metadata::new( - "image/jpeg", - "https://mywebsite.com/my-nft-files-1.jpeg".parse().unwrap(), - "file 1", - ) - .with_issuer_name("Alice"); - #[cfg(not(feature = "irc_27"))] - let metadata = [1, 2, 3]; - - let nft_output = - NftOutputBuilder::new_with_minimum_amount(protocol_parameters.storage_score_parameters(), nft_id_1) - .with_immutable_features(MetadataFeature::try_from(metadata)) - .add_unlock_condition(AddressUnlockCondition::new( - Address::try_from_bech32(BECH32_ADDRESS_ED25519_0).unwrap(), - )) - .finish_output() - .unwrap(); - - let inputs = [InputSigningData { - output: nft_output.clone(), - output_metadata: rand_output_metadata(), - chain: None, - }]; - - #[cfg(feature = "irc_27")] - let metadata = iota_sdk::types::block::output::feature::Irc27Metadata::new( - "image/jpeg", - "https://mywebsite.com/my-nft-files-2.jpeg".parse().unwrap(), - "file 2", - ) - .with_issuer_name("Alice"); - #[cfg(not(feature = "irc_27"))] - let metadata = [4, 5, 6]; +// #[cfg(feature = "irc_27")] +// let metadata = iota_sdk::types::block::output::feature::Irc27Metadata::new( +// "image/jpeg", +// "https://mywebsite.com/my-nft-files-1.jpeg".parse().unwrap(), +// "file 1", +// ) +// .with_issuer_name("Alice"); +// #[cfg(not(feature = "irc_27"))] +// let metadata = [1, 2, 3]; + +// let nft_output = +// NftOutputBuilder::new_with_minimum_amount(protocol_parameters.storage_score_parameters(), nft_id_1) +// .with_immutable_features(MetadataFeature::try_from(metadata)) +// .add_unlock_condition(AddressUnlockCondition::new( +// Address::try_from_bech32(BECH32_ADDRESS_ED25519_0).unwrap(), +// )) +// .finish_output() +// .unwrap(); + +// let inputs = [InputSigningData { +// output: nft_output.clone(), +// output_metadata: rand_output_metadata(), +// chain: None, +// }]; + +// #[cfg(feature = "irc_27")] +// let metadata = iota_sdk::types::block::output::feature::Irc27Metadata::new( +// "image/jpeg", +// "https://mywebsite.com/my-nft-files-2.jpeg".parse().unwrap(), +// "file 2", +// ) +// .with_issuer_name("Alice"); +// #[cfg(not(feature = "irc_27"))] +// let metadata = [4, 5, 6]; - // New nft output with changed immutable metadata feature - let updated_nft_output = NftOutputBuilder::from(nft_output.as_nft()) - .with_minimum_amount(protocol_parameters.storage_score_parameters()) - .with_immutable_features(MetadataFeature::try_from(metadata)) - .finish_output() - .unwrap(); +// // New nft output with changed immutable metadata feature +// let updated_nft_output = NftOutputBuilder::from(nft_output.as_nft()) +// .with_minimum_amount(protocol_parameters.storage_score_parameters()) +// .with_immutable_features(MetadataFeature::try_from(metadata)) +// .finish_output() +// .unwrap(); - let outputs = [updated_nft_output]; +// let outputs = [updated_nft_output]; - let selected = InputSelection::new( - inputs, - outputs, - [Address::try_from_bech32(BECH32_ADDRESS_ED25519_0).unwrap()], - protocol_parameters, - ) - .select(); +// let selected = InputSelection::new( +// inputs, +// outputs, +// [Address::try_from_bech32(BECH32_ADDRESS_ED25519_0).unwrap()], +// protocol_parameters, +// ) +// .select(); - assert!(matches!( - selected, - Err(Error::UnfulfillableRequirement(Requirement::Nft( - nft_id, - ))) if nft_id == nft_id_1 - )); -} +// assert!(matches!( +// selected, +// Err(Error::UnfulfillableRequirement(Requirement::Nft( +// nft_id, +// ))) if nft_id == nft_id_1 +// )); +// } diff --git a/sdk/tests/wallet/balance.rs b/sdk/tests/wallet/balance.rs index 6cedf7c8a1..0907ec82da 100644 --- a/sdk/tests/wallet/balance.rs +++ b/sdk/tests/wallet/balance.rs @@ -259,46 +259,46 @@ async fn balance_transfer() -> Result<()> { Ok(()) } -#[ignore] -#[tokio::test] -#[cfg(feature = "participation")] -async fn balance_voting_power() -> Result<()> { - let storage_path = "test-storage/balance_voting_power"; - setup(storage_path)?; - - let wallet = make_wallet(storage_path, None, None).await?; - - request_funds(&wallet).await?; - - let faucet_amount = 100_000_000_000; - - let balance = wallet.balance().await?; - assert_eq!(balance.base_coin().total(), faucet_amount); - assert_eq!(balance.base_coin().available(), faucet_amount); - - let voting_power = 1_000_000; - // Only use a part as voting power - let tx = wallet.increase_voting_power(voting_power).await?; - wallet - .reissue_transaction_until_included(&tx.transaction_id, None, None) - .await?; - let balance = wallet.sync(None).await?; - assert_eq!(balance.base_coin().total(), faucet_amount); - assert_eq!(balance.base_coin().available(), faucet_amount - voting_power); - let wallet_voting_power = wallet.get_voting_power().await?; - assert_eq!(wallet_voting_power, voting_power); - - // Increase voting power to total amount - let tx = wallet.increase_voting_power(faucet_amount - voting_power).await?; - wallet - .reissue_transaction_until_included(&tx.transaction_id, None, None) - .await?; - let balance = wallet.sync(None).await?; - assert_eq!(balance.base_coin().total(), faucet_amount); - assert_eq!(balance.base_coin().available(), 0); - let wallet_voting_power = wallet.get_voting_power().await?; - assert_eq!(wallet_voting_power, faucet_amount); - - tear_down(storage_path)?; - Ok(()) -} +// #[ignore] +// #[tokio::test] +// #[cfg(feature = "participation")] +// async fn balance_voting_power() -> Result<()> { +// let storage_path = "test-storage/balance_voting_power"; +// setup(storage_path)?; + +// let wallet = make_wallet(storage_path, None, None).await?; + +// request_funds(&wallet).await?; + +// let faucet_amount = 100_000_000_000; + +// let balance = wallet.balance().await?; +// assert_eq!(balance.base_coin().total(), faucet_amount); +// assert_eq!(balance.base_coin().available(), faucet_amount); + +// let voting_power = 1_000_000; +// // Only use a part as voting power +// let tx = wallet.increase_voting_power(voting_power).await?; +// wallet +// .reissue_transaction_until_included(&tx.transaction_id, None, None) +// .await?; +// let balance = wallet.sync(None).await?; +// assert_eq!(balance.base_coin().total(), faucet_amount); +// assert_eq!(balance.base_coin().available(), faucet_amount - voting_power); +// let wallet_voting_power = wallet.get_voting_power().await?; +// assert_eq!(wallet_voting_power, voting_power); + +// // Increase voting power to total amount +// let tx = wallet.increase_voting_power(faucet_amount - voting_power).await?; +// wallet +// .reissue_transaction_until_included(&tx.transaction_id, None, None) +// .await?; +// let balance = wallet.sync(None).await?; +// assert_eq!(balance.base_coin().total(), faucet_amount); +// assert_eq!(balance.base_coin().available(), 0); +// let wallet_voting_power = wallet.get_voting_power().await?; +// assert_eq!(wallet_voting_power, faucet_amount); + +// tear_down(storage_path)?; +// Ok(()) +// } diff --git a/sdk/tests/wallet/native_tokens.rs b/sdk/tests/wallet/native_tokens.rs index a392e8fdd4..449d1a85b3 100644 --- a/sdk/tests/wallet/native_tokens.rs +++ b/sdk/tests/wallet/native_tokens.rs @@ -110,19 +110,20 @@ async fn native_token_foundry_metadata() -> Result<()> { })) .await?; assert_eq!(balance.native_tokens().len(), 1); - // Metadata should exist and be the same - assert_eq!( - balance - .native_tokens() - .iter() - .find(|t| t.token_id() == &create_tx.token_id) - .unwrap() - .metadata() - .as_ref() - .unwrap() - .data(), - &foundry_metadata - ); + // TODO: enable again when MetadataFeature is cleared up + // // Metadata should exist and be the same + // assert_eq!( + // balance + // .native_tokens() + // .iter() + // .find(|t| t.token_id() == &create_tx.token_id) + // .unwrap() + // .metadata() + // .as_ref() + // .unwrap() + // .data(), + // &foundry_metadata + // ); tear_down(storage_path) } diff --git a/sdk/tests/wallet/output_preparation.rs b/sdk/tests/wallet/output_preparation.rs index f6bc818ffc..0b7bd9b824 100644 --- a/sdk/tests/wallet/output_preparation.rs +++ b/sdk/tests/wallet/output_preparation.rs @@ -589,11 +589,12 @@ async fn prepare_nft_output_features_update() -> Result<()> { assert_eq!(nft.address(), wallet.address().await.inner()); assert!(nft.features().sender().is_none()); assert!(nft.features().tag().is_none()); - assert_eq!(nft.features().metadata().unwrap().data(), &[42]); - assert_eq!( - nft.immutable_features().metadata().unwrap().data(), - b"some immutable nft metadata" - ); + // TODO: enable again when MetadataFeature is cleared up + // assert_eq!(nft.features().metadata().unwrap().data(), &[42]); + // assert_eq!( + // nft.immutable_features().metadata().unwrap().data(), + // b"some immutable nft metadata" + // ); assert_eq!( nft.immutable_features().issuer().unwrap().address(), wallet.address().await.inner() @@ -865,10 +866,11 @@ async fn prepare_existing_nft_output_gift() -> Result<()> { assert_eq!(nft.amount(), 52300); assert_eq!(nft.address(), wallet.address().await.inner()); assert!(nft.features().is_empty()); - assert_eq!( - nft.immutable_features().metadata().unwrap().data(), - b"some immutable nft metadata" - ); + // TODO: enable again when MetadataFeature is cleared up + // assert_eq!( + // nft.immutable_features().metadata().unwrap().data(), + // b"some immutable nft metadata" + // ); assert_eq!( nft.immutable_features().issuer().unwrap().address(), wallet.address().await.inner()