From 616f60ecdfa6ff2b72bf1b79695124d52bd73a38 Mon Sep 17 00:00:00 2001 From: Alexander Schmidt Date: Thu, 5 Oct 2023 10:59:22 +0200 Subject: [PATCH 01/10] rename trait and fn --- bindings/core/src/method_handler/client.rs | 5 +- bindings/core/src/method_handler/utils.rs | 4 +- .../input_selection/requirement/amount.rs | 4 +- sdk/src/types/block/output/account.rs | 6 +- sdk/src/types/block/output/basic.rs | 4 +- sdk/src/types/block/output/delegation.rs | 4 +- sdk/src/types/block/output/foundry.rs | 6 +- sdk/src/types/block/output/mod.rs | 8 +- sdk/src/types/block/output/nft.rs | 6 +- sdk/src/types/block/output/rent.rs | 182 ++++++++++-------- sdk/src/wallet/account/operations/balance.rs | 4 +- .../operations/transaction/prepare_output.rs | 8 +- sdk/tests/types/output/account.rs | 4 +- sdk/tests/types/output/basic.rs | 4 +- sdk/tests/types/output/foundry.rs | 6 +- sdk/tests/types/output/nft.rs | 4 +- sdk/tests/types/rent.rs | 2 +- sdk/tests/wallet/output_preparation.rs | 6 +- 18 files changed, 142 insertions(+), 125 deletions(-) diff --git a/bindings/core/src/method_handler/client.rs b/bindings/core/src/method_handler/client.rs index bfae35f84b..f5823aa006 100644 --- a/bindings/core/src/method_handler/client.rs +++ b/bindings/core/src/method_handler/client.rs @@ -9,7 +9,8 @@ use iota_sdk::{ api::core::response::OutputWithMetadataResponse, block::{ output::{ - dto::OutputDto, AccountOutput, BasicOutput, FoundryOutput, NftOutput, Output, OutputBuilderAmount, Rent, + dto::OutputDto, AccountOutput, BasicOutput, FoundryOutput, NftOutput, Output, OutputBuilderAmount, + StorageScore, }, payload::Payload, BlockWrapper, BlockWrapperDto, @@ -297,7 +298,7 @@ pub(crate) async fn call_client_method_internal(client: &Client, method: ClientM let output = Output::try_from_dto_with_params(output, client.get_token_supply().await?)?; let rent_structure = client.get_rent_structure().await?; - let minimum_storage_deposit = output.rent_cost(rent_structure); + let minimum_storage_deposit = output.storage_score(rent_structure); Response::MinimumRequiredStorageDeposit(minimum_storage_deposit.to_string()) } diff --git a/bindings/core/src/method_handler/utils.rs b/bindings/core/src/method_handler/utils.rs index 9b35265845..050f2389a3 100644 --- a/bindings/core/src/method_handler/utils.rs +++ b/bindings/core/src/method_handler/utils.rs @@ -8,7 +8,7 @@ use iota_sdk::{ block::{ address::{AccountAddress, Address, ToBech32Ext}, input::UtxoInput, - output::{AccountId, FoundryId, InputsCommitment, NftId, Output, OutputId, Rent, TokenId}, + output::{AccountId, FoundryId, InputsCommitment, NftId, Output, OutputId, StorageScore, TokenId}, payload::{transaction::TransactionEssence, TransactionPayload}, BlockWrapper, }, @@ -80,7 +80,7 @@ pub(crate) fn call_utils_method_internal(method: UtilsMethod) -> Result { let out = Output::try_from_dto(output)?; - Response::MinimumRequiredStorageDeposit(out.rent_cost(rent).to_string()) + Response::MinimumRequiredStorageDeposit(out.storage_score(rent).to_string()) } UtilsMethod::VerifyMnemonic { mnemonic } => { let mnemonic = Mnemonic::from(mnemonic); diff --git a/sdk/src/client/api/block_builder/input_selection/requirement/amount.rs b/sdk/src/client/api/block_builder/input_selection/requirement/amount.rs index 549bc43e62..75ee4d2aa6 100644 --- a/sdk/src/client/api/block_builder/input_selection/requirement/amount.rs +++ b/sdk/src/client/api/block_builder/input_selection/requirement/amount.rs @@ -11,7 +11,7 @@ use crate::{ input::INPUT_COUNT_MAX, output::{ unlock_condition::StorageDepositReturnUnlockCondition, AccountOutputBuilder, AccountTransition, - FoundryOutputBuilder, NftOutputBuilder, Output, OutputId, Rent, + FoundryOutputBuilder, NftOutputBuilder, Output, OutputId, StorageScore, }, slot::SlotIndex, }, @@ -240,7 +240,7 @@ impl InputSelection { for output in outputs { let diff = amount_selection.missing_amount(); let amount = output.amount(); - let rent = output.rent_cost(self.protocol_parameters.rent_structure()); + let rent = output.storage_score(self.protocol_parameters.rent_structure()); let new_amount = if amount >= diff + rent { amount - diff } else { rent }; diff --git a/sdk/src/types/block/output/account.rs b/sdk/src/types/block/output/account.rs index 5e1d832928..4face4d474 100644 --- a/sdk/src/types/block/output/account.rs +++ b/sdk/src/types/block/output/account.rs @@ -22,8 +22,8 @@ use crate::types::{ verify_allowed_unlock_conditions, UnlockCondition, UnlockConditionFlags, UnlockConditions, }, verify_output_amount_min, verify_output_amount_packable, verify_output_amount_supply, ChainId, NativeToken, - NativeTokens, Output, OutputBuilderAmount, OutputId, Rent, RentStructure, StateTransitionError, - StateTransitionVerifier, + NativeTokens, Output, OutputBuilderAmount, OutputId, RentStructure, StateTransitionError, + StateTransitionVerifier, StorageScore, }, protocol::ProtocolParameters, semantic::{TransactionFailureReason, ValidationContext}, @@ -319,7 +319,7 @@ impl AccountOutputBuilder { output.amount = match self.amount { OutputBuilderAmount::Amount(amount) => amount, OutputBuilderAmount::MinimumStorageDeposit(rent_structure) => { - Output::Account(output.clone()).rent_cost(rent_structure) + Output::Account(output.clone()).storage_score(rent_structure) } }; diff --git a/sdk/src/types/block/output/basic.rs b/sdk/src/types/block/output/basic.rs index 7fed97f268..76fbfade2d 100644 --- a/sdk/src/types/block/output/basic.rs +++ b/sdk/src/types/block/output/basic.rs @@ -14,7 +14,7 @@ use crate::types::{ verify_allowed_unlock_conditions, UnlockCondition, UnlockConditionFlags, UnlockConditions, }, verify_output_amount_min, verify_output_amount_packable, verify_output_amount_supply, NativeToken, - NativeTokens, Output, OutputBuilderAmount, OutputId, Rent, RentStructure, + NativeTokens, Output, OutputBuilderAmount, OutputId, RentStructure, StorageScore, }, protocol::ProtocolParameters, semantic::{TransactionFailureReason, ValidationContext}, @@ -172,7 +172,7 @@ impl BasicOutputBuilder { output.amount = match self.amount { OutputBuilderAmount::Amount(amount) => amount, OutputBuilderAmount::MinimumStorageDeposit(rent_structure) => { - Output::Basic(output.clone()).rent_cost(rent_structure) + Output::Basic(output.clone()).storage_score(rent_structure) } }; diff --git a/sdk/src/types/block/output/delegation.rs b/sdk/src/types/block/output/delegation.rs index 5c926cd55f..252fe9a2b4 100644 --- a/sdk/src/types/block/output/delegation.rs +++ b/sdk/src/types/block/output/delegation.rs @@ -19,7 +19,7 @@ use crate::types::{ verify_allowed_unlock_conditions, UnlockCondition, UnlockConditionFlags, UnlockConditions, }, verify_output_amount_min, verify_output_amount_packable, verify_output_amount_supply, Output, - OutputBuilderAmount, OutputId, Rent, RentStructure, StateTransitionError, StateTransitionVerifier, + OutputBuilderAmount, OutputId, RentStructure, StateTransitionError, StateTransitionVerifier, StorageScore, }, protocol::ProtocolParameters, semantic::{TransactionFailureReason, ValidationContext}, @@ -195,7 +195,7 @@ impl DelegationOutputBuilder { output.amount = match self.amount { OutputBuilderAmount::Amount(amount) => amount, OutputBuilderAmount::MinimumStorageDeposit(rent_structure) => { - Output::Delegation(output.clone()).rent_cost(rent_structure) + Output::Delegation(output.clone()).storage_score(rent_structure) } }; diff --git a/sdk/src/types/block/output/foundry.rs b/sdk/src/types/block/output/foundry.rs index f8b0854ee5..f7bb861cd9 100644 --- a/sdk/src/types/block/output/foundry.rs +++ b/sdk/src/types/block/output/foundry.rs @@ -22,8 +22,8 @@ use crate::types::{ verify_allowed_unlock_conditions, UnlockCondition, UnlockConditionFlags, UnlockConditions, }, verify_output_amount_min, verify_output_amount_packable, verify_output_amount_supply, ChainId, NativeToken, - NativeTokens, Output, OutputBuilderAmount, OutputId, Rent, RentStructure, StateTransitionError, - StateTransitionVerifier, TokenId, TokenScheme, + NativeTokens, Output, OutputBuilderAmount, OutputId, RentStructure, StateTransitionError, + StateTransitionVerifier, StorageScore, TokenId, TokenScheme, }, protocol::ProtocolParameters, semantic::{TransactionFailureReason, ValidationContext}, @@ -283,7 +283,7 @@ impl FoundryOutputBuilder { output.amount = match self.amount { OutputBuilderAmount::Amount(amount) => amount, OutputBuilderAmount::MinimumStorageDeposit(rent_structure) => { - Output::Foundry(output.clone()).rent_cost(rent_structure) + Output::Foundry(output.clone()).storage_score(rent_structure) } }; diff --git a/sdk/src/types/block/output/mod.rs b/sdk/src/types/block/output/mod.rs index c9829eb5a0..2b964ca9a2 100644 --- a/sdk/src/types/block/output/mod.rs +++ b/sdk/src/types/block/output/mod.rs @@ -53,7 +53,7 @@ pub use self::{ native_token::{NativeToken, NativeTokens, NativeTokensBuilder, TokenId}, nft::{NftId, NftOutput, NftOutputBuilder}, output_id::OutputId, - rent::{MinimumStorageDepositBasicOutput, Rent, RentStructure}, + rent::{MinimumStorageDepositBasicOutput, RentStructure, StorageScore}, state_transition::{StateTransitionError, StateTransitionVerifier}, token_scheme::{SimpleTokenScheme, TokenScheme}, unlock_condition::{UnlockCondition, UnlockConditions}, @@ -384,7 +384,7 @@ impl Output { /// If there is a [`StorageDepositReturnUnlockCondition`](unlock_condition::StorageDepositReturnUnlockCondition), /// its amount is also checked. pub fn verify_storage_deposit(&self, rent_structure: RentStructure, token_supply: u64) -> Result<(), Error> { - let required_output_amount = self.rent_cost(rent_structure); + let required_output_amount = self.storage_score(rent_structure); if self.amount() < required_output_amount { return Err(Error::InsufficientStorageDepositAmount { @@ -468,9 +468,9 @@ impl Packable for Output { } } -impl Rent for Output { +impl StorageScore for Output { fn weighted_bytes(&self, rent_structure: RentStructure) -> u64 { - self.packed_len() as u64 * rent_structure.byte_factor_data() as u64 + self.packed_len() as u64 * rent_structure.storage_score_factor_data() as u64 } } diff --git a/sdk/src/types/block/output/nft.rs b/sdk/src/types/block/output/nft.rs index 957e384e51..695411b096 100644 --- a/sdk/src/types/block/output/nft.rs +++ b/sdk/src/types/block/output/nft.rs @@ -19,8 +19,8 @@ use crate::types::{ verify_allowed_unlock_conditions, UnlockCondition, UnlockConditionFlags, UnlockConditions, }, verify_output_amount_min, verify_output_amount_packable, verify_output_amount_supply, ChainId, NativeToken, - NativeTokens, Output, OutputBuilderAmount, OutputId, Rent, RentStructure, StateTransitionError, - StateTransitionVerifier, + NativeTokens, Output, OutputBuilderAmount, OutputId, RentStructure, StateTransitionError, + StateTransitionVerifier, StorageScore, }, protocol::ProtocolParameters, semantic::{TransactionFailureReason, ValidationContext}, @@ -244,7 +244,7 @@ impl NftOutputBuilder { output.amount = match self.amount { OutputBuilderAmount::Amount(amount) => amount, OutputBuilderAmount::MinimumStorageDeposit(rent_structure) => { - Output::Nft(output.clone()).rent_cost(rent_structure) + Output::Nft(output.clone()).storage_score(rent_structure) } }; diff --git a/sdk/src/types/block/output/rent.rs b/sdk/src/types/block/output/rent.rs index a68346e76e..5c8f792a35 100644 --- a/sdk/src/types/block/output/rent.rs +++ b/sdk/src/types/block/output/rent.rs @@ -15,13 +15,18 @@ use crate::types::block::{ BlockId, Error, }; -const DEFAULT_BYTE_COST: u32 = 100; -const DEFAULT_BYTE_COST_FACTOR_KEY: u8 = 10; -const DEFAULT_BYTE_COST_FACTOR_DATA: u8 = 1; // TODO: fill in the real values -const DEFAULT_BYTE_COST_FACTOR_DELEGATION: u8 = 1; -const DEFAULT_BYTE_COST_FACTOR_STAKING_FEATURE: u8 = 1; -const DEFAULT_BYTE_COST_FACTOR_BLOCK_ISSUER_KEY: u8 = 1; +const DEFAULT_STORAGE_COST: u32 = 100; +const DEFAULT_STORAGE_SCORE_FACTOR_DATA: StorageScoreFactor = 1; +const DEFAULT_STORAGE_SCORE_OFFSET_OUTPUT: StorageScoreOffset = 1; +const DEFAULT_STORAGE_SCORE_OFFSET_ED25519_BLOCK_ISSUER_KEY: StorageScoreOffset = 1; +const DEFAULT_STORAGE_SCORE_STAKING_FEATURE: StorageScoreOffset = 1; +const DEFAULT_STORAGE_SCORE_OFFSET_DELEGATION: StorageScoreOffset = 1; + +// Defines the type of the storage score factor. +type StorageScoreFactor = u8; +// Defines the type of storage score. +type StorageScoreOffset = u64; /// Specifies the current parameters for the byte cost computation. #[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Packable)] @@ -31,29 +36,30 @@ const DEFAULT_BYTE_COST_FACTOR_BLOCK_ISSUER_KEY: u8 = 1; serde(rename_all = "camelCase") )] pub struct RentStructure { - /// Cost in tokens per virtual byte. - v_byte_cost: u32, - /// The weight factor used for data fields in the outputs. - v_byte_factor_data: u8, - /// The weight factor used for key fields in the outputs. - v_byte_factor_key: u8, - /// The weight factor used for block issuer key fields in the outputs. - v_byte_factor_block_issuer_key: u8, - /// The weight factor used for staking fields in the outputs. - v_byte_factor_staking_feature: u8, - /// The weight factor used for delegation fields in the outputs. - v_byte_factor_delegation: u8, + // TODO: what actual primitive type is their `BaseToken` type def? + /// Defines the number of IOTA tokens required per unit of storage score. + storage_cost: u32, + /// Defines the factor to be used for data only fields. + storage_score_factor_data: StorageScoreFactor, + /// Defines the offset to be used for key/lookup generating fields. + storage_score_offset_output: StorageScoreOffset, + /// Defines the offset to be used for block issuer feature public keys. + storage_score_offset_ed25519_block_issuer_key: StorageScoreOffset, + /// Defines the offset to be used for staking feature. + storage_score_offset_staking_feature: StorageScoreOffset, + /// Defines the offset to be used for delegation output. + storage_score_offset_delegation: StorageScoreOffset, } impl Default for RentStructure { fn default() -> Self { Self { - v_byte_cost: DEFAULT_BYTE_COST, - v_byte_factor_data: DEFAULT_BYTE_COST_FACTOR_DATA, - v_byte_factor_key: DEFAULT_BYTE_COST_FACTOR_KEY, - v_byte_factor_block_issuer_key: DEFAULT_BYTE_COST_FACTOR_BLOCK_ISSUER_KEY, - v_byte_factor_staking_feature: DEFAULT_BYTE_COST_FACTOR_STAKING_FEATURE, - v_byte_factor_delegation: DEFAULT_BYTE_COST_FACTOR_DELEGATION, + storage_cost: DEFAULT_STORAGE_COST, + storage_score_factor_data: DEFAULT_STORAGE_SCORE_FACTOR_DATA, + storage_score_offset_output: DEFAULT_STORAGE_SCORE_OFFSET_OUTPUT, + storage_score_offset_ed25519_block_issuer_key: DEFAULT_STORAGE_SCORE_OFFSET_ED25519_BLOCK_ISSUER_KEY, + storage_score_offset_staking_feature: DEFAULT_STORAGE_SCORE_STAKING_FEATURE, + storage_score_offset_delegation: DEFAULT_STORAGE_SCORE_OFFSET_DELEGATION, } } } @@ -61,115 +67,122 @@ impl Default for RentStructure { impl RentStructure { /// Creates a new [`RentStructure`]. pub fn new( - byte_cost: u32, - byte_factor_data: u8, - byte_factor_key: u8, - byte_factor_block_issuer_key: u8, - byte_factor_staking_feature: u8, - byte_factor_delegation: u8, + storage_cost: u32, + storage_score_factor_data: StorageScoreFactor, + storage_score_offset_output: StorageScoreOffset, + storage_score_offset_ed25519_block_issuer_key: StorageScoreOffset, + storage_score_offset_staking_feature: StorageScoreOffset, + storage_score_offset_delegation: StorageScoreOffset, ) -> Self { Self { - v_byte_cost: byte_cost, - v_byte_factor_data: byte_factor_data, - v_byte_factor_key: byte_factor_key, - v_byte_factor_block_issuer_key: byte_factor_block_issuer_key, - v_byte_factor_staking_feature: byte_factor_staking_feature, - v_byte_factor_delegation: byte_factor_delegation, + storage_cost, + storage_score_factor_data, + storage_score_offset_output: storage_score_offset_output, + storage_score_offset_ed25519_block_issuer_key: storage_score_offset_ed25519_block_issuer_key, + storage_score_offset_staking_feature: storage_score_offset_staking_feature, + storage_score_offset_delegation: storage_score_offset_delegation, } } - /// Sets the byte cost for the storage deposit. - pub fn with_byte_cost(mut self, byte_cost: u32) -> Self { - self.v_byte_cost = byte_cost; + /// Sets the storage cost for the storage deposit. + pub fn with_storage_cost(mut self, storage_cost: u32) -> Self { + self.storage_cost = storage_cost; self } - /// Sets the virtual byte weight for the data fields. - pub fn with_byte_factor_data(mut self, byte_factor_data: u8) -> Self { - self.v_byte_factor_data = byte_factor_data; + /// Sets the storage score factor for the data fields. + pub fn with_storage_score_factor_data(mut self, storage_score_factor_data: StorageScoreFactor) -> Self { + self.storage_score_factor_data = storage_score_factor_data; self } - /// Sets the virtual byte weight for the key fields. - pub fn with_byte_factor_key(mut self, byte_factor_key: u8) -> Self { - self.v_byte_factor_key = byte_factor_key; + /// Sets the TODO. + pub fn with_storage_score_offset_output(mut self, storage_score_offset_output: StorageScoreOffset) -> Self { + self.storage_score_offset_output = storage_score_offset_output; self } - /// Sets the virtual byte weight for the block issuer key fields. - pub fn with_byte_factor_block_issuer_key(mut self, byte_factor_block_issuer_key: u8) -> Self { - self.v_byte_factor_block_issuer_key = byte_factor_block_issuer_key; + /// Sets the TODO. + pub fn with_storage_score_offset_ed25519_block_issuer_key( + mut self, + storage_score_offset_ed25519_block_issuer_key: StorageScoreOffset, + ) -> Self { + self.storage_score_offset_ed25519_block_issuer_key = storage_score_offset_ed25519_block_issuer_key; self } - /// Sets the virtual byte weight for the staking fields. - pub fn with_byte_factor_staking_feature(mut self, byte_factor_staking_feature: u8) -> Self { - self.v_byte_factor_staking_feature = byte_factor_staking_feature; + /// Sets the TODO for the staking fields. + pub fn with_storage_score_offset_staking_feature( + mut self, + storage_score_offset_staking_feature: StorageScoreOffset, + ) -> Self { + self.storage_score_offset_staking_feature = storage_score_offset_staking_feature; self } - /// Sets the virtual byte weight for the delegation fields. - pub fn with_byte_factor_delegation(mut self, byte_factor_delegation: u8) -> Self { - self.v_byte_factor_delegation = byte_factor_delegation; + /// Sets the TODO for the delegation fields. + pub fn with_storage_score_offset_delegation(mut self, storage_score_offset_delegation: StorageScoreOffset) -> Self { + self.storage_score_offset_delegation = storage_score_offset_delegation; self } - /// Returns the byte cost of the [`RentStructure`]. - pub const fn byte_cost(&self) -> u32 { - self.v_byte_cost + /// Returns the TODO of the [`RentStructure`]. + pub const fn storage_cost(&self) -> u32 { + self.storage_cost } - /// Returns the byte factor data of the [`RentStructure`]. - pub const fn byte_factor_data(&self) -> u8 { - self.v_byte_factor_data + /// Returns the TODO of the [`RentStructure`]. + pub const fn storage_score_factor_data(&self) -> StorageScoreFactor { + self.storage_score_factor_data } - /// Returns the byte factor key of the [`RentStructure`]. - pub const fn byte_factor_key(&self) -> u8 { - self.v_byte_factor_key + /// Returns the TODO of the [`RentStructure`]. + pub const fn storage_score_offset_output(&self) -> StorageScoreOffset { + self.storage_score_offset_output } - /// Returns the block issuer key byte factor of the [`RentStructure`]. - pub const fn byte_factor_block_issuer_key(&self) -> u8 { - self.v_byte_factor_block_issuer_key + /// Returns the TODO the [`RentStructure`]. + pub const fn storage_score_offset_ed25519_block_issuer_key(&self) -> StorageScoreOffset { + self.storage_score_offset_ed25519_block_issuer_key } - /// Returns the staking byte factor of the [`RentStructure`]. - pub const fn byte_factor_staking_feature(&self) -> u8 { - self.v_byte_factor_staking_feature + /// Returns the TODO the [`RentStructure`]. + pub const fn storage_score_offset_staking_feature(&self) -> StorageScoreOffset { + self.storage_score_offset_staking_feature } - /// Returns the delegation byte factor of the [`RentStructure`]. - pub const fn byte_factor_delegation(&self) -> u8 { - self.v_byte_factor_delegation + /// Returns the TODO the [`RentStructure`]. + pub const fn storage_score_offset_delegation(&self) -> StorageScoreOffset { + self.storage_score_offset_delegation } } -/// A trait to facilitate the computation of the byte cost of block outputs, which is central to dust protection. -pub trait Rent { +/// A trait to facilitate the computation of the storage score of block outputs, which is central to dust protection. +pub trait StorageScore { /// Computes the byte offset given a [`RentStructure`]. fn byte_offset(&self, rent_structure: RentStructure) -> u32 { + // TODO: verify this // The ID of the output. - size_of::() as u32 * rent_structure.v_byte_factor_key as u32 + size_of::() as u32 * rent_structure.storage_score_offset_output as u32 // The ID of the block in which the transaction payload that created this output was included. - + size_of::() as u32 * rent_structure.v_byte_factor_data as u32 + + size_of::() as u32 * rent_structure.storage_score_factor_data as u32 // The index of the slot in which the transaction that created it was booked. - + size_of::() as u32 * rent_structure.v_byte_factor_data as u32 + + size_of::() as u32 * rent_structure.storage_score_factor_data as u32 // The index of the slot in which the transaction was created. - + size_of::() as u32 * rent_structure.v_byte_factor_data as u32 + + size_of::() as u32 * rent_structure.storage_score_factor_data as u32 } /// Different fields in a type lead to different storage requirements for the ledger state. fn weighted_bytes(&self, config: RentStructure) -> u64; - /// Computes the rent cost given a [`RentStructure`]. - fn rent_cost(&self, rent_structure: RentStructure) -> u64 { - rent_structure.v_byte_cost as u64 + /// Computes the storage score given a [`RentStructure`]. + fn storage_score(&self, rent_structure: RentStructure) -> u64 { + rent_structure.storage_cost as u64 * (self.weighted_bytes(rent_structure) + self.byte_offset(rent_structure) as u64) } } -impl Rent for [T; N] { +impl StorageScore for [T; N] { fn weighted_bytes(&self, config: RentStructure) -> u64 { self.iter().map(|elem| elem.weighted_bytes(config)).sum() } @@ -219,6 +232,9 @@ impl MinimumStorageDepositBasicOutput { } pub fn finish(self) -> Result { - Ok(self.builder.finish_output(self.token_supply)?.rent_cost(self.config)) + Ok(self + .builder + .finish_output(self.token_supply)? + .storage_score(self.config)) } } diff --git a/sdk/src/wallet/account/operations/balance.rs b/sdk/src/wallet/account/operations/balance.rs index 0a6d8fb026..85689610d3 100644 --- a/sdk/src/wallet/account/operations/balance.rs +++ b/sdk/src/wallet/account/operations/balance.rs @@ -7,7 +7,7 @@ use crate::{ client::secret::SecretManage, types::block::{ address::Bech32Address, - output::{unlock_condition::UnlockCondition, FoundryId, NativeTokensBuilder, Output, Rent}, + output::{unlock_condition::UnlockCondition, FoundryId, NativeTokensBuilder, Output, StorageScore}, ConvertTo, }, wallet::{ @@ -88,7 +88,7 @@ where } let output = &data.output; - let rent = output.rent_cost(rent_structure); + let rent = output.storage_score(rent_structure); // Add account and foundry outputs here because they can't have a // [`StorageDepositReturnUnlockCondition`] or time related unlock conditions diff --git a/sdk/src/wallet/account/operations/transaction/prepare_output.rs b/sdk/src/wallet/account/operations/transaction/prepare_output.rs index f682314eb9..26b4c075fc 100644 --- a/sdk/src/wallet/account/operations/transaction/prepare_output.rs +++ b/sdk/src/wallet/account/operations/transaction/prepare_output.rs @@ -13,8 +13,8 @@ use crate::{ AddressUnlockCondition, ExpirationUnlockCondition, StorageDepositReturnUnlockCondition, TimelockUnlockCondition, }, - BasicOutputBuilder, MinimumStorageDepositBasicOutput, NativeToken, NftId, NftOutputBuilder, Output, Rent, - RentStructure, UnlockCondition, + BasicOutputBuilder, MinimumStorageDepositBasicOutput, NativeToken, NftId, NftOutputBuilder, Output, + RentStructure, StorageScore, UnlockCondition, }, slot::SlotIndex, Error, @@ -114,7 +114,7 @@ where let min_storage_deposit_basic_output = MinimumStorageDepositBasicOutput::new(rent_structure, token_supply).finish()?; - let min_required_storage_deposit = first_output.rent_cost(rent_structure); + let min_required_storage_deposit = first_output.storage_score(rent_structure); if params.amount > min_required_storage_deposit { second_output_builder = second_output_builder.with_amount(params.amount); @@ -176,7 +176,7 @@ where // If we're sending an existing NFT, its minimum required storage deposit is not part of the available base_coin // balance, so we add it here if let Some(existing_nft_output_data) = existing_nft_output_data { - available_base_coin += existing_nft_output_data.output.rent_cost(rent_structure); + available_base_coin += existing_nft_output_data.output.storage_score(rent_structure); } if final_amount > available_base_coin { diff --git a/sdk/tests/types/output/account.rs b/sdk/tests/types/output/account.rs index d62f730398..a58f9cb0a1 100644 --- a/sdk/tests/types/output/account.rs +++ b/sdk/tests/types/output/account.rs @@ -4,7 +4,7 @@ use iota_sdk::types::{ block::{ address::AccountAddress, - output::{AccountOutput, Feature, FoundryId, NativeToken, Output, Rent, SimpleTokenScheme, TokenId}, + output::{AccountOutput, Feature, FoundryId, NativeToken, Output, SimpleTokenScheme, StorageScore, TokenId}, protocol::protocol_parameters, rand::output::{ feature::{rand_issuer_feature, rand_metadata_feature, rand_sender_feature}, @@ -83,7 +83,7 @@ fn builder() { assert_eq!( output.amount(), - Output::Account(output.clone()).rent_cost(protocol_parameters.rent_structure()) + Output::Account(output.clone()).storage_score(protocol_parameters.rent_structure()) ); assert_eq!(output.features().metadata(), Some(&metadata)); assert_eq!(output.features().sender(), Some(&sender_1)); diff --git a/sdk/tests/types/output/basic.rs b/sdk/tests/types/output/basic.rs index ae0dbea7a9..8b897e9b53 100644 --- a/sdk/tests/types/output/basic.rs +++ b/sdk/tests/types/output/basic.rs @@ -3,7 +3,7 @@ use iota_sdk::types::{ block::{ - output::{BasicOutput, Feature, FoundryId, NativeToken, Output, Rent, SimpleTokenScheme, TokenId}, + output::{BasicOutput, Feature, FoundryId, NativeToken, Output, SimpleTokenScheme, StorageScore, TokenId}, protocol::protocol_parameters, rand::{ address::rand_account_address, @@ -58,7 +58,7 @@ fn builder() { assert_eq!( output.amount(), - Output::Basic(output.clone()).rent_cost(protocol_parameters.rent_structure()) + Output::Basic(output.clone()).storage_score(protocol_parameters.rent_structure()) ); assert_eq!(output.features().metadata(), Some(&metadata)); assert_eq!(output.features().sender(), Some(&sender_1)); diff --git a/sdk/tests/types/output/foundry.rs b/sdk/tests/types/output/foundry.rs index 896351ef4a..a620b664b6 100644 --- a/sdk/tests/types/output/foundry.rs +++ b/sdk/tests/types/output/foundry.rs @@ -3,8 +3,8 @@ use iota_sdk::types::block::{ output::{ - unlock_condition::ImmutableAccountAddressUnlockCondition, FoundryId, FoundryOutput, NativeToken, Output, Rent, - SimpleTokenScheme, TokenId, + unlock_condition::ImmutableAccountAddressUnlockCondition, FoundryId, FoundryOutput, NativeToken, Output, + SimpleTokenScheme, StorageScore, TokenId, }, protocol::protocol_parameters, rand::{ @@ -58,7 +58,7 @@ fn builder() { assert_eq!( output.amount(), - Output::Foundry(output).rent_cost(protocol_parameters.rent_structure()) + Output::Foundry(output).storage_score(protocol_parameters.rent_structure()) ); } diff --git a/sdk/tests/types/output/nft.rs b/sdk/tests/types/output/nft.rs index 4617325d0d..4485176a36 100644 --- a/sdk/tests/types/output/nft.rs +++ b/sdk/tests/types/output/nft.rs @@ -2,7 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 use iota_sdk::types::block::{ - output::{FoundryId, NativeToken, NftId, NftOutput, Output, Rent, SimpleTokenScheme, TokenId}, + output::{FoundryId, NativeToken, NftId, NftOutput, Output, SimpleTokenScheme, StorageScore, TokenId}, protocol::protocol_parameters, rand::{ address::rand_account_address, @@ -59,7 +59,7 @@ fn builder() { assert_eq!( output.amount(), - Output::Nft(output).rent_cost(protocol_parameters.rent_structure()) + Output::Nft(output).storage_score(protocol_parameters.rent_structure()) ); } diff --git a/sdk/tests/types/rent.rs b/sdk/tests/types/rent.rs index 3d86541aa5..9f8bb6d9b2 100644 --- a/sdk/tests/types/rent.rs +++ b/sdk/tests/types/rent.rs @@ -10,7 +10,7 @@ // }; // fn output_in_range(output: Output, range: std::ops::RangeInclusive) { -// let cost = output.rent_cost(Default::default()); +// let cost = output.storage_score(Default::default()); // assert!(range.contains(&cost), "{output:#?} has a required byte cost of {cost}"); // } diff --git a/sdk/tests/wallet/output_preparation.rs b/sdk/tests/wallet/output_preparation.rs index 37e36ba2af..f032b59923 100644 --- a/sdk/tests/wallet/output_preparation.rs +++ b/sdk/tests/wallet/output_preparation.rs @@ -6,7 +6,7 @@ use std::str::FromStr; use iota_sdk::{ types::block::{ address::{Address, Bech32Address, ToBech32Ext}, - output::{MinimumStorageDepositBasicOutput, NativeToken, NftId, Output, Rent, TokenId}, + output::{MinimumStorageDepositBasicOutput, NativeToken, NftId, Output, StorageScore, TokenId}, slot::SlotIndex, }, wallet::{ @@ -409,7 +409,7 @@ async fn output_preparation() -> Result<()> { ) .await?; let rent_structure = wallet.client().get_rent_structure().await?; - let minimum_storage_deposit = output.rent_cost(rent_structure); + let minimum_storage_deposit = output.storage_score(rent_structure); assert_eq!(output.amount(), minimum_storage_deposit); assert_eq!(output.amount(), 187900); let sdr = output.unlock_conditions().unwrap().storage_deposit_return().unwrap(); @@ -850,7 +850,7 @@ async fn prepare_existing_nft_output_gift() -> Result<()> { .clone(); let rent_structure = wallet.client().get_rent_structure().await?; - let minimum_storage_deposit = Output::Nft(nft.clone()).rent_cost(rent_structure); + let minimum_storage_deposit = Output::Nft(nft.clone()).storage_score(rent_structure); assert_eq!(nft.amount(), minimum_storage_deposit); assert_eq!(nft.amount(), 52300); From d6f12e5aaabe65a4e0114b23b904004b7d4ed9e3 Mon Sep 17 00:00:00 2001 From: Alexander Schmidt Date: Fri, 6 Oct 2023 12:42:37 +0200 Subject: [PATCH 02/10] uplift and rename trait --- bindings/core/src/method/utils.rs | 5 +- bindings/core/src/method_handler/client.rs | 14 +- bindings/core/src/method_handler/utils.rs | 5 +- cli/src/command/account.rs | 4 +- .../client/output/build_account_output.rs | 4 +- .../client/output/build_nft_output.rs | 4 +- .../how_tos/account/state_transition.rs | 4 +- sdk/examples/how_tos/outputs/features.rs | 4 +- .../how_tos/outputs/unlock_conditions.rs | 10 +- .../input_selection/remainder.rs | 4 +- .../input_selection/requirement/amount.rs | 5 +- sdk/src/client/core.rs | 6 +- sdk/src/types/block/address/mod.rs | 33 +++- sdk/src/types/block/mod.rs | 2 + sdk/src/types/block/output/account.rs | 26 +-- sdk/src/types/block/output/basic.rs | 25 +-- sdk/src/types/block/output/delegation.rs | 23 +-- .../block/output/feature/block_issuer.rs | 31 +++- sdk/src/types/block/output/foundry.rs | 27 +-- sdk/src/types/block/output/mod.rs | 97 ++++++++--- sdk/src/types/block/output/nft.rs | 26 +-- .../payload/transaction/essence/regular.rs | 2 +- sdk/src/types/block/protocol.rs | 12 +- sdk/src/types/block/{output => }/rent.rs | 156 +++++++----------- sdk/src/wallet/account/mod.rs | 2 +- sdk/src/wallet/account/operations/balance.rs | 7 +- .../account/operations/output_claiming.rs | 8 +- .../transaction/high_level/create_account.rs | 4 +- .../high_level/minting/create_native_token.rs | 4 +- .../high_level/minting/mint_nfts.rs | 4 +- .../operations/transaction/high_level/send.rs | 6 +- .../high_level/send_native_tokens.rs | 4 +- .../account/operations/transaction/mod.rs | 5 +- .../operations/transaction/prepare_output.rs | 32 ++-- .../transaction/prepare_transaction.rs | 4 +- .../client/input_selection/account_outputs.rs | 8 +- .../client/input_selection/nft_outputs.rs | 17 +- sdk/tests/client/node_api/indexer.rs | 8 +- sdk/tests/types/block_id.rs | 4 +- sdk/tests/types/output/account.rs | 7 +- sdk/tests/types/output/basic.rs | 7 +- sdk/tests/types/output/foundry.rs | 7 +- sdk/tests/types/output/nft.rs | 7 +- sdk/tests/types/protocol.rs | 14 +- sdk/tests/types/rent.rs | 2 +- sdk/tests/wallet/claim_outputs.rs | 10 +- sdk/tests/wallet/output_preparation.rs | 32 ++-- 47 files changed, 406 insertions(+), 326 deletions(-) rename sdk/src/types/block/{output => }/rent.rs (55%) diff --git a/bindings/core/src/method/utils.rs b/bindings/core/src/method/utils.rs index 938b33b293..552aeef331 100644 --- a/bindings/core/src/method/utils.rs +++ b/bindings/core/src/method/utils.rs @@ -4,12 +4,13 @@ use derivative::Derivative; use iota_sdk::types::block::{ address::{Bech32Address, Hrp}, - output::{dto::OutputDto, AccountId, NftId, OutputId, RentStructure}, + output::{dto::OutputDto, AccountId, NftId, OutputId}, payload::transaction::{ dto::{TransactionEssenceDto, TransactionPayloadDto}, TransactionId, }, protocol::ProtocolParameters, + rent::RentParameters, signature::Ed25519Signature, slot::SlotCommitment, BlockWrapperDto, @@ -131,7 +132,7 @@ pub enum UtilsMethod { /// Computes the input commitment from the output objects that are used as inputs to fund the transaction. ComputeInputsCommitment { inputs: Vec }, /// Computes the required storage deposit of an output. - ComputeStorageDeposit { output: OutputDto, rent: RentStructure }, + ComputeStorageDeposit { output: OutputDto, rent: RentParameters }, /// Checks if the given mnemonic is valid. /// Expected response: [`Ok`](crate::Response::Ok) VerifyMnemonic { diff --git a/bindings/core/src/method_handler/client.rs b/bindings/core/src/method_handler/client.rs index f5823aa006..53a3da32a2 100644 --- a/bindings/core/src/method_handler/client.rs +++ b/bindings/core/src/method_handler/client.rs @@ -10,9 +10,9 @@ use iota_sdk::{ block::{ output::{ dto::OutputDto, AccountOutput, BasicOutput, FoundryOutput, NftOutput, Output, OutputBuilderAmount, - StorageScore, }, payload::Payload, + rent::StorageCost, BlockWrapper, BlockWrapperDto, }, TryFromDto, @@ -72,7 +72,7 @@ pub(crate) async fn call_client_method_internal(client: &Client, method: ClientM if let Some(amount) = amount { OutputBuilderAmount::Amount(amount) } else { - OutputBuilderAmount::MinimumStorageDeposit(client.get_rent_structure().await?) + OutputBuilderAmount::MinimumStorageDeposit(client.get_rent_parameters().await?) }, mana, native_tokens, @@ -99,7 +99,7 @@ pub(crate) async fn call_client_method_internal(client: &Client, method: ClientM if let Some(amount) = amount { OutputBuilderAmount::Amount(amount) } else { - OutputBuilderAmount::MinimumStorageDeposit(client.get_rent_structure().await?) + OutputBuilderAmount::MinimumStorageDeposit(client.get_rent_parameters().await?) }, mana, native_tokens, @@ -123,7 +123,7 @@ pub(crate) async fn call_client_method_internal(client: &Client, method: ClientM if let Some(amount) = amount { OutputBuilderAmount::Amount(amount) } else { - OutputBuilderAmount::MinimumStorageDeposit(client.get_rent_structure().await?) + OutputBuilderAmount::MinimumStorageDeposit(client.get_rent_parameters().await?) }, native_tokens, serial_number, @@ -149,7 +149,7 @@ pub(crate) async fn call_client_method_internal(client: &Client, method: ClientM if let Some(amount) = amount { OutputBuilderAmount::Amount(amount) } else { - OutputBuilderAmount::MinimumStorageDeposit(client.get_rent_structure().await?) + OutputBuilderAmount::MinimumStorageDeposit(client.get_rent_parameters().await?) }, mana, native_tokens, @@ -296,9 +296,9 @@ pub(crate) async fn call_client_method_internal(client: &Client, method: ClientM } ClientMethod::MinimumRequiredStorageDeposit { output } => { let output = Output::try_from_dto_with_params(output, client.get_token_supply().await?)?; - let rent_structure = client.get_rent_structure().await?; + let rent_params = client.get_rent_parameters().await?; - let minimum_storage_deposit = output.storage_score(rent_structure); + let minimum_storage_deposit = output.storage_cost(rent_params); Response::MinimumRequiredStorageDeposit(minimum_storage_deposit.to_string()) } diff --git a/bindings/core/src/method_handler/utils.rs b/bindings/core/src/method_handler/utils.rs index 050f2389a3..c4809711c5 100644 --- a/bindings/core/src/method_handler/utils.rs +++ b/bindings/core/src/method_handler/utils.rs @@ -8,8 +8,9 @@ use iota_sdk::{ block::{ address::{AccountAddress, Address, ToBech32Ext}, input::UtxoInput, - output::{AccountId, FoundryId, InputsCommitment, NftId, Output, OutputId, StorageScore, TokenId}, + output::{AccountId, FoundryId, InputsCommitment, NftId, Output, OutputId, TokenId}, payload::{transaction::TransactionEssence, TransactionPayload}, + rent::StorageCost, BlockWrapper, }, TryFromDto, @@ -80,7 +81,7 @@ pub(crate) fn call_utils_method_internal(method: UtilsMethod) -> Result { let out = Output::try_from_dto(output)?; - Response::MinimumRequiredStorageDeposit(out.storage_score(rent).to_string()) + Response::MinimumRequiredStorageDeposit(out.storage_cost(rent).to_string()) } UtilsMethod::VerifyMnemonic { mnemonic } => { let mnemonic = Mnemonic::from(mnemonic); diff --git a/cli/src/command/account.rs b/cli/src/command/account.rs index 5ea180908c..c2ca40a0ef 100644 --- a/cli/src/command/account.rs +++ b/cli/src/command/account.rs @@ -721,12 +721,12 @@ pub async fn send_native_token_command( let address = address.convert()?; let transaction = if gift_storage_deposit.unwrap_or(false) { // Send native tokens together with the required storage deposit - let rent_structure = account.client().get_rent_structure().await?; + let rent_params = account.client().get_rent_parameters().await?; let token_supply = account.client().get_token_supply().await?; account.client().bech32_hrp_matches(address.hrp()).await?; - let outputs = [BasicOutputBuilder::new_with_minimum_storage_deposit(rent_structure) + let outputs = [BasicOutputBuilder::new_with_minimum_storage_deposit(rent_params) .add_unlock_condition(AddressUnlockCondition::new(address)) .with_native_tokens([NativeToken::new( TokenId::from_str(&token_id)?, diff --git a/sdk/examples/client/output/build_account_output.rs b/sdk/examples/client/output/build_account_output.rs index a4c22583b5..c8c5fee712 100644 --- a/sdk/examples/client/output/build_account_output.rs +++ b/sdk/examples/client/output/build_account_output.rs @@ -35,7 +35,7 @@ async fn main() -> Result<()> { .await?; let token_supply = client.get_token_supply().await?; - let rent_structure = client.get_rent_structure().await?; + let rent_params = client.get_rent_parameters().await?; let address = std::env::args() .nth(1) @@ -43,7 +43,7 @@ async fn main() -> Result<()> { let address = Address::try_from_bech32(address)?; // Account id needs to be null the first time - let account_output = AccountOutputBuilder::new_with_minimum_storage_deposit(rent_structure, AccountId::null()) + let account_output = AccountOutputBuilder::new_with_minimum_storage_deposit(rent_params, AccountId::null()) .with_state_metadata(metadata) .add_feature(SenderFeature::new(address)) .add_feature(MetadataFeature::new(metadata)?) diff --git a/sdk/examples/client/output/build_nft_output.rs b/sdk/examples/client/output/build_nft_output.rs index e75aa942ba..5c9cf7bc0e 100644 --- a/sdk/examples/client/output/build_nft_output.rs +++ b/sdk/examples/client/output/build_nft_output.rs @@ -35,7 +35,7 @@ async fn main() -> Result<()> { .await?; let token_supply = client.get_token_supply().await?; - let rent_structure = client.get_rent_structure().await?; + let rent_params = client.get_rent_parameters().await?; let address = std::env::args() .nth(1) @@ -56,7 +56,7 @@ async fn main() -> Result<()> { .to_string(); // NftId needs to be null the first time - let nft_output = NftOutputBuilder::new_with_minimum_storage_deposit(rent_structure, NftId::null()) + let nft_output = NftOutputBuilder::new_with_minimum_storage_deposit(rent_params, NftId::null()) .add_unlock_condition(AddressUnlockCondition::new(address)) .add_feature(SenderFeature::new(address)) .add_feature(MetadataFeature::new(MUTABLE_METADATA)?) diff --git a/sdk/examples/how_tos/account/state_transition.rs b/sdk/examples/how_tos/account/state_transition.rs index f17919de50..2d945ddead 100644 --- a/sdk/examples/how_tos/account/state_transition.rs +++ b/sdk/examples/how_tos/account/state_transition.rs @@ -51,13 +51,13 @@ async fn main() -> Result<()> { ); let token_supply = account.client().get_token_supply().await?; - let rent_structure = account.client().get_rent_structure().await?; + let rent_params = account.client().get_rent_parameters().await?; let account_output = account_output_data.output.as_account(); let updated_account_output = AccountOutputBuilder::from(account_output) // Minimum required storage deposit will change if the new metadata has a different size, so we will update // the amount - .with_minimum_storage_deposit(rent_structure) + .with_minimum_storage_deposit(rent_params) .with_state_metadata(NEW_STATE_METADATA.as_bytes().to_vec()) .with_state_index(account_output.state_index() + 1) .finish_output(token_supply)?; diff --git a/sdk/examples/how_tos/outputs/features.rs b/sdk/examples/how_tos/outputs/features.rs index ca8367531e..71d45c5d60 100644 --- a/sdk/examples/how_tos/outputs/features.rs +++ b/sdk/examples/how_tos/outputs/features.rs @@ -32,11 +32,11 @@ async fn main() -> Result<()> { let client = Client::builder().with_node(&node_url)?.finish().await?; let token_supply = client.get_token_supply().await?; - let rent_structure = client.get_rent_structure().await?; + let rent_params = client.get_rent_parameters().await?; let address = Address::try_from_bech32("rms1qpllaj0pyveqfkwxmnngz2c488hfdtmfrj3wfkgxtk4gtyrax0jaxzt70zy")?; - let nft_output_builder = NftOutputBuilder::new_with_minimum_storage_deposit(rent_structure, NftId::null()) + let nft_output_builder = NftOutputBuilder::new_with_minimum_storage_deposit(rent_params, NftId::null()) .add_unlock_condition(AddressUnlockCondition::new(address)); let outputs = [ diff --git a/sdk/examples/how_tos/outputs/unlock_conditions.rs b/sdk/examples/how_tos/outputs/unlock_conditions.rs index 9d28bff850..7bd6723994 100644 --- a/sdk/examples/how_tos/outputs/unlock_conditions.rs +++ b/sdk/examples/how_tos/outputs/unlock_conditions.rs @@ -35,19 +35,17 @@ async fn main() -> Result<()> { let client = Client::builder().with_node(&node_url)?.finish().await?; let token_supply = client.get_token_supply().await?; - let rent_structure = client.get_rent_structure().await?; + let rent_params = client.get_rent_parameters().await?; let address = Address::try_from_bech32("rms1qpllaj0pyveqfkwxmnngz2c488hfdtmfrj3wfkgxtk4gtyrax0jaxzt70zy")?; let account_address = Address::try_from_bech32("rms1pr59qm43mjtvhcajfmupqf23x29llam88yecn6pyul80rx099krmv2fnnux")?; let token_scheme = TokenScheme::Simple(SimpleTokenScheme::new(50, 0, 100)?); - let basic_output_builder = BasicOutputBuilder::new_with_minimum_storage_deposit(rent_structure) + let basic_output_builder = BasicOutputBuilder::new_with_minimum_storage_deposit(rent_params) .add_unlock_condition(AddressUnlockCondition::new(address)); - let account_output_builder = - AccountOutputBuilder::new_with_minimum_storage_deposit(rent_structure, AccountId::null()); - let foundry_output_builder = - FoundryOutputBuilder::new_with_minimum_storage_deposit(rent_structure, 1, token_scheme); + let account_output_builder = AccountOutputBuilder::new_with_minimum_storage_deposit(rent_params, AccountId::null()); + let foundry_output_builder = FoundryOutputBuilder::new_with_minimum_storage_deposit(rent_params, 1, token_scheme); let outputs = [ //// most simple output diff --git a/sdk/src/client/api/block_builder/input_selection/remainder.rs b/sdk/src/client/api/block_builder/input_selection/remainder.rs index 5b2e39caa9..1eb84aca1b 100644 --- a/sdk/src/client/api/block_builder/input_selection/remainder.rs +++ b/sdk/src/client/api/block_builder/input_selection/remainder.rs @@ -65,7 +65,7 @@ impl InputSelection { let native_tokens_remainder = native_tokens_diff.is_some(); let mut remainder_builder = - BasicOutputBuilder::new_with_minimum_storage_deposit(self.protocol_parameters.rent_structure()) + BasicOutputBuilder::new_with_minimum_storage_deposit(self.protocol_parameters.rent_parameters()) .add_unlock_condition(AddressUnlockCondition::new(Address::from(Ed25519Address::from( [0; 32], )))); @@ -144,7 +144,7 @@ impl InputSelection { log::debug!("Created remainder output of {diff} for {remainder_address:?}"); remainder.verify_storage_deposit( - self.protocol_parameters.rent_structure(), + self.protocol_parameters.rent_parameters(), self.protocol_parameters.token_supply(), )?; diff --git a/sdk/src/client/api/block_builder/input_selection/requirement/amount.rs b/sdk/src/client/api/block_builder/input_selection/requirement/amount.rs index 75ee4d2aa6..a030f94101 100644 --- a/sdk/src/client/api/block_builder/input_selection/requirement/amount.rs +++ b/sdk/src/client/api/block_builder/input_selection/requirement/amount.rs @@ -11,8 +11,9 @@ use crate::{ input::INPUT_COUNT_MAX, output::{ unlock_condition::StorageDepositReturnUnlockCondition, AccountOutputBuilder, AccountTransition, - FoundryOutputBuilder, NftOutputBuilder, Output, OutputId, StorageScore, + FoundryOutputBuilder, NftOutputBuilder, Output, OutputId, }, + rent::StorageCost, slot::SlotIndex, }, }; @@ -240,7 +241,7 @@ impl InputSelection { for output in outputs { let diff = amount_selection.missing_amount(); let amount = output.amount(); - let rent = output.storage_score(self.protocol_parameters.rent_structure()); + let rent = output.storage_cost(self.protocol_parameters.rent_parameters()); let new_amount = if amount >= diff + rent { amount - diff } else { rent }; diff --git a/sdk/src/client/core.rs b/sdk/src/client/core.rs index e2ca71c2f4..f8efcb9ca1 100644 --- a/sdk/src/client/core.rs +++ b/sdk/src/client/core.rs @@ -24,7 +24,7 @@ use crate::{ node_manager::NodeManager, Error, }, - types::block::{address::Hrp, output::RentStructure, protocol::ProtocolParameters}, + types::block::{address::Hrp, protocol::ProtocolParameters, rent::RentParameters}, }; /// An IOTA node client. @@ -153,8 +153,8 @@ impl ClientInner { } /// Gets the rent structure of the node we're connecting to. - pub async fn get_rent_structure(&self) -> Result { - Ok(self.get_network_info().await?.protocol_parameters.rent_structure()) + pub async fn get_rent_parameters(&self) -> Result { + Ok(self.get_network_info().await?.protocol_parameters.rent_parameters()) } /// Gets the token supply of the node we're connecting to. diff --git a/sdk/src/types/block/address/mod.rs b/sdk/src/types/block/address/mod.rs index a870d399b7..0c63d3bc57 100644 --- a/sdk/src/types/block/address/mod.rs +++ b/sdk/src/types/block/address/mod.rs @@ -14,12 +14,16 @@ pub use self::{ ed25519::Ed25519Address, nft::NftAddress, }; -use crate::types::block::{ - output::{Output, OutputId}, - semantic::{TransactionFailureReason, ValidationContext}, - signature::Signature, - unlock::Unlock, - ConvertTo, Error, +use crate::{ + types::block::{ + output::{Output, OutputId}, + rent::{RentParameters, RentStructure, StorageCost}, + semantic::{TransactionFailureReason, ValidationContext}, + signature::Signature, + unlock::Unlock, + ConvertTo, Error, + }, + wallet::storage::Storage, }; /// A generic address supporting different address kinds. @@ -210,3 +214,20 @@ impl From<&Self> for Address { *value } } + +/// A trait to facilitate the rent cost computation for addresses, which is central to dust protection. +pub trait AddressStorageCost { + /// Computes the storage score of an address given a [`RentStructure`]. + fn storage_cost(&self, rent_structure: RentStructure) -> u64; +} + +impl AddressStorageCost for Address { + fn storage_cost(&self, rent_structure: RentStructure) -> u64 { + match self { + Self::Account(_) | Self::Ed25519(_) | Self::Nft(_) => 0, + // TODO: implicit account address and restricted address + // Address::ImplicitAccountCreation(_) => + // rent_stucture.storage_score_offset_implicit_account_creation_address + } + } +} diff --git a/sdk/src/types/block/mod.rs b/sdk/src/types/block/mod.rs index de471203d6..d2040863a4 100644 --- a/sdk/src/types/block/mod.rs +++ b/sdk/src/types/block/mod.rs @@ -31,6 +31,8 @@ pub mod protocol; /// A module that provides utilities for random generation of types. #[cfg(feature = "rand")] pub mod rand; +/// A module that provides types and rules for rent cost computation. +pub mod rent; /// A module that provides types and rules for semantic validation. pub mod semantic; /// A module that provides types and syntactic validations of signatures. diff --git a/sdk/src/types/block/output/account.rs b/sdk/src/types/block/output/account.rs index 4face4d474..108f64d7f9 100644 --- a/sdk/src/types/block/output/account.rs +++ b/sdk/src/types/block/output/account.rs @@ -22,10 +22,10 @@ use crate::types::{ verify_allowed_unlock_conditions, UnlockCondition, UnlockConditionFlags, UnlockConditions, }, verify_output_amount_min, verify_output_amount_packable, verify_output_amount_supply, ChainId, NativeToken, - NativeTokens, Output, OutputBuilderAmount, OutputId, RentStructure, StateTransitionError, - StateTransitionVerifier, StorageScore, + NativeTokens, Output, OutputBuilderAmount, OutputId, StateTransitionError, StateTransitionVerifier, }, protocol::ProtocolParameters, + rent::{RentParameters, StorageCost}, semantic::{TransactionFailureReason, ValidationContext}, unlock::Unlock, Error, @@ -112,8 +112,8 @@ impl AccountOutputBuilder { /// Creates an [`AccountOutputBuilder`] with a provided rent structure. /// The amount will be set to the minimum storage deposit. - pub fn new_with_minimum_storage_deposit(rent_structure: RentStructure, account_id: AccountId) -> Self { - Self::new(OutputBuilderAmount::MinimumStorageDeposit(rent_structure), account_id) + pub fn new_with_minimum_storage_deposit(rent_params: RentParameters, account_id: AccountId) -> Self { + Self::new(OutputBuilderAmount::MinimumStorageDeposit(rent_params), account_id) } fn new(amount: OutputBuilderAmount, account_id: AccountId) -> Self { @@ -140,8 +140,8 @@ impl AccountOutputBuilder { /// Sets the amount to the minimum storage deposit. #[inline(always)] - pub fn with_minimum_storage_deposit(mut self, rent_structure: RentStructure) -> Self { - self.amount = OutputBuilderAmount::MinimumStorageDeposit(rent_structure); + pub fn with_minimum_storage_deposit(mut self, rent_params: RentParameters) -> Self { + self.amount = OutputBuilderAmount::MinimumStorageDeposit(rent_params); self } @@ -318,8 +318,8 @@ impl AccountOutputBuilder { output.amount = match self.amount { OutputBuilderAmount::Amount(amount) => amount, - OutputBuilderAmount::MinimumStorageDeposit(rent_structure) => { - Output::Account(output.clone()).storage_score(rent_structure) + OutputBuilderAmount::MinimumStorageDeposit(rent_params) => { + Output::Account(output.clone()).storage_cost(rent_params) } }; @@ -413,10 +413,10 @@ impl AccountOutput { /// The amount will be set to the minimum storage deposit. #[inline(always)] pub fn build_with_minimum_storage_deposit( - rent_structure: RentStructure, + rent_params: RentParameters, account_id: AccountId, ) -> AccountOutputBuilder { - AccountOutputBuilder::new_with_minimum_storage_deposit(rent_structure, account_id) + AccountOutputBuilder::new_with_minimum_storage_deposit(rent_params, account_id) } /// @@ -856,8 +856,8 @@ pub(crate) mod dto { let params = params.into(); let mut builder = match amount { OutputBuilderAmount::Amount(amount) => AccountOutputBuilder::new_with_amount(amount, *account_id), - OutputBuilderAmount::MinimumStorageDeposit(rent_structure) => { - AccountOutputBuilder::new_with_minimum_storage_deposit(rent_structure, *account_id) + OutputBuilderAmount::MinimumStorageDeposit(rent_params) => { + AccountOutputBuilder::new_with_minimum_storage_deposit(rent_params, *account_id) } } .with_mana(mana); @@ -978,7 +978,7 @@ mod tests { test_split_dto(builder); let builder = - AccountOutput::build_with_minimum_storage_deposit(protocol_parameters.rent_structure(), account_id) + AccountOutput::build_with_minimum_storage_deposit(protocol_parameters.rent_parameters(), account_id) .add_native_token(NativeToken::new(TokenId::from(foundry_id), 1000).unwrap()) .add_unlock_condition(gov_address) .add_unlock_condition(state_address) diff --git a/sdk/src/types/block/output/basic.rs b/sdk/src/types/block/output/basic.rs index 76fbfade2d..c21f892655 100644 --- a/sdk/src/types/block/output/basic.rs +++ b/sdk/src/types/block/output/basic.rs @@ -14,9 +14,10 @@ use crate::types::{ verify_allowed_unlock_conditions, UnlockCondition, UnlockConditionFlags, UnlockConditions, }, verify_output_amount_min, verify_output_amount_packable, verify_output_amount_supply, NativeToken, - NativeTokens, Output, OutputBuilderAmount, OutputId, RentStructure, StorageScore, + NativeTokens, Output, OutputBuilderAmount, OutputId, }, protocol::ProtocolParameters, + rent::{RentParameters, StorageCost}, semantic::{TransactionFailureReason, ValidationContext}, unlock::Unlock, Error, @@ -45,8 +46,8 @@ impl BasicOutputBuilder { /// Creates an [`BasicOutputBuilder`] with a provided rent structure. /// The amount will be set to the minimum storage deposit. #[inline(always)] - pub fn new_with_minimum_storage_deposit(rent_structure: RentStructure) -> Self { - Self::new(OutputBuilderAmount::MinimumStorageDeposit(rent_structure)) + pub fn new_with_minimum_storage_deposit(rent_params: RentParameters) -> Self { + Self::new(OutputBuilderAmount::MinimumStorageDeposit(rent_params)) } fn new(amount: OutputBuilderAmount) -> Self { @@ -68,8 +69,8 @@ impl BasicOutputBuilder { /// Sets the amount to the minimum storage deposit. #[inline(always)] - pub fn with_minimum_storage_deposit(mut self, rent_structure: RentStructure) -> Self { - self.amount = OutputBuilderAmount::MinimumStorageDeposit(rent_structure); + pub fn with_minimum_storage_deposit(mut self, rent_params: RentParameters) -> Self { + self.amount = OutputBuilderAmount::MinimumStorageDeposit(rent_params); self } @@ -171,8 +172,8 @@ impl BasicOutputBuilder { output.amount = match self.amount { OutputBuilderAmount::Amount(amount) => amount, - OutputBuilderAmount::MinimumStorageDeposit(rent_structure) => { - Output::Basic(output.clone()).storage_score(rent_structure) + OutputBuilderAmount::MinimumStorageDeposit(rent_params) => { + Output::Basic(output.clone()).storage_cost(rent_params) } }; @@ -253,8 +254,8 @@ impl BasicOutput { /// Creates a new [`BasicOutputBuilder`] with a provided rent structure. /// The amount will be set to the minimum storage deposit. #[inline(always)] - pub fn build_with_minimum_storage_deposit(rent_structure: RentStructure) -> BasicOutputBuilder { - BasicOutputBuilder::new_with_minimum_storage_deposit(rent_structure) + pub fn build_with_minimum_storage_deposit(rent_params: RentParameters) -> BasicOutputBuilder { + BasicOutputBuilder::new_with_minimum_storage_deposit(rent_params) } /// @@ -428,8 +429,8 @@ pub(crate) mod dto { let params = params.into(); let mut builder = match amount { OutputBuilderAmount::Amount(amount) => BasicOutputBuilder::new_with_amount(amount), - OutputBuilderAmount::MinimumStorageDeposit(rent_structure) => { - BasicOutputBuilder::new_with_minimum_storage_deposit(rent_structure) + OutputBuilderAmount::MinimumStorageDeposit(rent_params) => { + BasicOutputBuilder::new_with_minimum_storage_deposit(rent_params) } } .with_mana(mana); @@ -517,7 +518,7 @@ mod tests { .with_features(rand_allowed_features(BasicOutput::ALLOWED_FEATURES)); test_split_dto(builder); - let builder = BasicOutput::build_with_minimum_storage_deposit(protocol_parameters.rent_structure()) + let builder = BasicOutput::build_with_minimum_storage_deposit(protocol_parameters.rent_parameters()) .add_native_token(NativeToken::new(TokenId::from(foundry_id), 1000).unwrap()) .add_unlock_condition(address) .with_features(rand_allowed_features(BasicOutput::ALLOWED_FEATURES)); diff --git a/sdk/src/types/block/output/delegation.rs b/sdk/src/types/block/output/delegation.rs index 252fe9a2b4..0e3c9970b1 100644 --- a/sdk/src/types/block/output/delegation.rs +++ b/sdk/src/types/block/output/delegation.rs @@ -19,9 +19,10 @@ use crate::types::{ verify_allowed_unlock_conditions, UnlockCondition, UnlockConditionFlags, UnlockConditions, }, verify_output_amount_min, verify_output_amount_packable, verify_output_amount_supply, Output, - OutputBuilderAmount, OutputId, RentStructure, StateTransitionError, StateTransitionVerifier, StorageScore, + OutputBuilderAmount, OutputId, StateTransitionError, StateTransitionVerifier, }, protocol::ProtocolParameters, + rent::{RentParameters, StorageCost}, semantic::{TransactionFailureReason, ValidationContext}, slot::EpochIndex, unlock::Unlock, @@ -79,13 +80,13 @@ impl DelegationOutputBuilder { /// Creates a [`DelegationOutputBuilder`] with a provided rent structure. /// The amount will be set to the minimum storage deposit. pub fn new_with_minimum_storage_deposit( - rent_structure: RentStructure, + rent_params: RentParameters, delegated_amount: u64, delegation_id: DelegationId, validator_address: AccountAddress, ) -> Self { Self::new( - OutputBuilderAmount::MinimumStorageDeposit(rent_structure), + OutputBuilderAmount::MinimumStorageDeposit(rent_params), delegated_amount, delegation_id, validator_address, @@ -116,8 +117,8 @@ impl DelegationOutputBuilder { } /// Sets the amount to the minimum storage deposit. - pub fn with_minimum_storage_deposit(mut self, rent_structure: RentStructure) -> Self { - self.amount = OutputBuilderAmount::MinimumStorageDeposit(rent_structure); + pub fn with_minimum_storage_deposit(mut self, rent_params: RentParameters) -> Self { + self.amount = OutputBuilderAmount::MinimumStorageDeposit(rent_params); self } @@ -194,8 +195,8 @@ impl DelegationOutputBuilder { output.amount = match self.amount { OutputBuilderAmount::Amount(amount) => amount, - OutputBuilderAmount::MinimumStorageDeposit(rent_structure) => { - Output::Delegation(output.clone()).storage_score(rent_structure) + OutputBuilderAmount::MinimumStorageDeposit(rent_params) => { + Output::Delegation(output.clone()).storage_cost(rent_params) } }; @@ -276,13 +277,13 @@ impl DelegationOutput { /// Creates a new [`DelegationOutputBuilder`] with a provided rent structure. /// The amount will be set to the minimum storage deposit. pub fn build_with_minimum_storage_deposit( - rent_structure: RentStructure, + rent_params: RentParameters, delegated_amount: u64, delegation_id: DelegationId, validator_address: AccountAddress, ) -> DelegationOutputBuilder { DelegationOutputBuilder::new_with_minimum_storage_deposit( - rent_structure, + rent_params, delegated_amount, delegation_id, validator_address, @@ -561,9 +562,9 @@ pub(crate) mod dto { *delegation_id, *validator_address, ), - OutputBuilderAmount::MinimumStorageDeposit(rent_structure) => { + OutputBuilderAmount::MinimumStorageDeposit(rent_params) => { DelegationOutputBuilder::new_with_minimum_storage_deposit( - rent_structure, + rent_params, delegated_amount, *delegation_id, *validator_address, diff --git a/sdk/src/types/block/output/feature/block_issuer.rs b/sdk/src/types/block/output/feature/block_issuer.rs index c7682bdf33..1a561e4bd5 100644 --- a/sdk/src/types/block/output/feature/block_issuer.rs +++ b/sdk/src/types/block/output/feature/block_issuer.rs @@ -16,7 +16,11 @@ use packable::{ Packable, }; -use crate::types::block::{slot::SlotIndex, Error}; +use crate::types::block::{ + rent::{RentParameters, StorageCost}, + slot::SlotIndex, + Error, +}; #[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Hash, From, packable::Packable)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize), serde(untagged))] @@ -57,6 +61,19 @@ impl BlockIssuerKey { } } +impl StorageCost for BlockIssuerKey { + fn offset_score(&self, rent_params: RentParameters) -> u64 { + // TODO: ?? + 0 + } + + fn score(&self, rent_params: RentParameters) -> u64 { + match self { + Self::Ed25519(key) => key.score(rent_params), + } + } +} + /// An Ed25519 block issuer key. #[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Deref, AsRef, From)] #[as_ref(forward)] @@ -99,6 +116,12 @@ impl Packable for Ed25519BlockIssuerKey { } } +impl StorageCost for Ed25519BlockIssuerKey { + fn score(&self, rent_params: RentParameters) -> u64 { + rent_params.storage_score_offset_ed25519_block_issuer_key() + } +} + pub(crate) type BlockIssuerKeyCount = BoundedU8<{ *BlockIssuerKeys::COUNT_RANGE.start() }, { *BlockIssuerKeys::COUNT_RANGE.end() }>; @@ -181,6 +204,12 @@ impl BlockIssuerKeys { } } +impl StorageCost for BlockIssuerKeys { + fn score(&self, rent_params: RentParameters) -> u64 { + (*self).iter().map(|key| key.score(rent_params)).sum() + } +} + /// This feature defines the block issuer keys with which a signature from the containing /// account's Block Issuance Credit can be verified in order to burn Mana. #[derive(Clone, Debug, Eq, PartialEq, Hash, packable::Packable)] diff --git a/sdk/src/types/block/output/foundry.rs b/sdk/src/types/block/output/foundry.rs index f7bb861cd9..6da68682cf 100644 --- a/sdk/src/types/block/output/foundry.rs +++ b/sdk/src/types/block/output/foundry.rs @@ -22,10 +22,11 @@ use crate::types::{ verify_allowed_unlock_conditions, UnlockCondition, UnlockConditionFlags, UnlockConditions, }, verify_output_amount_min, verify_output_amount_packable, verify_output_amount_supply, ChainId, NativeToken, - NativeTokens, Output, OutputBuilderAmount, OutputId, RentStructure, StateTransitionError, - StateTransitionVerifier, StorageScore, TokenId, TokenScheme, + NativeTokens, Output, OutputBuilderAmount, OutputId, StateTransitionError, StateTransitionVerifier, + TokenId, TokenScheme, }, protocol::ProtocolParameters, + rent::{RentParameters, StorageCost}, semantic::{TransactionFailureReason, ValidationContext}, unlock::Unlock, Error, @@ -103,12 +104,12 @@ impl FoundryOutputBuilder { /// Creates a [`FoundryOutputBuilder`] with a provided rent structure. /// The amount will be set to the minimum storage deposit. pub fn new_with_minimum_storage_deposit( - rent_structure: RentStructure, + rent_params: RentParameters, serial_number: u32, token_scheme: TokenScheme, ) -> Self { Self::new( - OutputBuilderAmount::MinimumStorageDeposit(rent_structure), + OutputBuilderAmount::MinimumStorageDeposit(rent_params), serial_number, token_scheme, ) @@ -135,8 +136,8 @@ impl FoundryOutputBuilder { /// Sets the amount to the minimum storage deposit. #[inline(always)] - pub fn with_minimum_storage_deposit(mut self, rent_structure: RentStructure) -> Self { - self.amount = OutputBuilderAmount::MinimumStorageDeposit(rent_structure); + pub fn with_minimum_storage_deposit(mut self, rent_params: RentParameters) -> Self { + self.amount = OutputBuilderAmount::MinimumStorageDeposit(rent_params); self } @@ -282,8 +283,8 @@ impl FoundryOutputBuilder { output.amount = match self.amount { OutputBuilderAmount::Amount(amount) => amount, - OutputBuilderAmount::MinimumStorageDeposit(rent_structure) => { - Output::Foundry(output.clone()).storage_score(rent_structure) + OutputBuilderAmount::MinimumStorageDeposit(rent_params) => { + Output::Foundry(output.clone()).storage_cost(rent_params) } }; @@ -365,11 +366,11 @@ impl FoundryOutput { /// The amount will be set to the minimum storage deposit. #[inline(always)] pub fn build_with_minimum_storage_deposit( - rent_structure: RentStructure, + rent_params: RentParameters, serial_number: u32, token_scheme: TokenScheme, ) -> FoundryOutputBuilder { - FoundryOutputBuilder::new_with_minimum_storage_deposit(rent_structure, serial_number, token_scheme) + FoundryOutputBuilder::new_with_minimum_storage_deposit(rent_params, serial_number, token_scheme) } /// @@ -758,8 +759,8 @@ pub(crate) mod dto { OutputBuilderAmount::Amount(amount) => { FoundryOutputBuilder::new_with_amount(amount, serial_number, token_scheme) } - OutputBuilderAmount::MinimumStorageDeposit(rent_structure) => { - FoundryOutputBuilder::new_with_minimum_storage_deposit(rent_structure, serial_number, token_scheme) + OutputBuilderAmount::MinimumStorageDeposit(rent_params) => { + FoundryOutputBuilder::new_with_minimum_storage_deposit(rent_params, serial_number, token_scheme) } }; @@ -846,7 +847,7 @@ mod tests { test_split_dto(builder); let builder = FoundryOutput::build_with_minimum_storage_deposit( - protocol_parameters.rent_structure(), + protocol_parameters.rent_parameters(), 123, rand_token_scheme(), ) diff --git a/sdk/src/types/block/output/mod.rs b/sdk/src/types/block/output/mod.rs index 2b964ca9a2..e4f142110e 100644 --- a/sdk/src/types/block/output/mod.rs +++ b/sdk/src/types/block/output/mod.rs @@ -7,7 +7,6 @@ mod inputs_commitment; mod metadata; mod native_token; mod output_id; -mod rent; mod state_transition; mod token_scheme; @@ -24,7 +23,7 @@ pub mod nft; /// pub mod unlock_condition; -use core::ops::RangeInclusive; +use core::{mem::size_of, ops::RangeInclusive}; use derive_more::From; use packable::{ @@ -39,7 +38,7 @@ pub(crate) use self::{ feature::{MetadataFeatureLength, TagFeatureLength}, native_token::NativeTokenCount, output_id::OutputIndex, - unlock_condition::AddressUnlockCondition, + unlock_condition::{AddressUnlockCondition, ExpirationUnlockCondition, StorageDepositReturnUnlockCondition}, }; pub use self::{ account::{AccountId, AccountOutput, AccountOutputBuilder, AccountTransition}, @@ -53,12 +52,16 @@ pub use self::{ native_token::{NativeToken, NativeTokens, NativeTokensBuilder, TokenId}, nft::{NftId, NftOutput, NftOutputBuilder}, output_id::OutputId, - rent::{MinimumStorageDepositBasicOutput, RentStructure, StorageScore}, state_transition::{StateTransitionError, StateTransitionVerifier}, token_scheme::{SimpleTokenScheme, TokenScheme}, unlock_condition::{UnlockCondition, UnlockConditions}, }; -use super::protocol::ProtocolParameters; +use super::{ + address::Ed25519Address, + protocol::ProtocolParameters, + rent::{RentParameters, StorageCost}, + BlockId, +}; use crate::types::block::{address::Address, semantic::ValidationContext, slot::SlotIndex, Error}; /// The maximum number of outputs of a transaction. @@ -73,7 +76,7 @@ pub const OUTPUT_INDEX_RANGE: RangeInclusive = 0..=OUTPUT_INDEX_MAX; // [0. #[derive(Copy, Clone)] pub enum OutputBuilderAmount { Amount(u64), - MinimumStorageDeposit(RentStructure), + MinimumStorageDeposit(RentParameters), } /// Contains the generic [`Output`] with associated [`OutputMetadata`]. @@ -380,11 +383,11 @@ impl Output { } /// Verifies if a valid storage deposit was made. Each [`Output`] has to have an amount that covers its associated - /// byte cost, given by [`RentStructure`]. + /// storage score, given by [`RentParameters`]. /// If there is a [`StorageDepositReturnUnlockCondition`](unlock_condition::StorageDepositReturnUnlockCondition), /// its amount is also checked. - pub fn verify_storage_deposit(&self, rent_structure: RentStructure, token_supply: u64) -> Result<(), Error> { - let required_output_amount = self.storage_score(rent_structure); + pub fn verify_storage_deposit(&self, rent_params: RentParameters, token_supply: u64) -> Result<(), Error> { + let required_output_amount = self.storage_cost(rent_params); if self.amount() < required_output_amount { return Err(Error::InsufficientStorageDepositAmount { @@ -406,8 +409,7 @@ impl Output { }); } - let minimum_deposit = - minimum_storage_deposit(return_condition.return_address(), rent_structure, token_supply); + let minimum_deposit = minimum_storage_deposit(return_condition.return_address(), rent_params, token_supply); // `Minimum Storage Deposit` ≤ `Return Amount` if return_condition.amount() < minimum_deposit { @@ -468,12 +470,6 @@ impl Packable for Output { } } -impl StorageScore for Output { - fn weighted_bytes(&self, rent_structure: RentStructure) -> u64 { - self.packed_len() as u64 * rent_structure.storage_score_factor_data() as u64 - } -} - pub(crate) fn verify_output_amount_min(amount: u64) -> Result<(), Error> { if amount < Output::AMOUNT_MIN { Err(Error::InvalidOutputAmount(amount)) @@ -507,16 +503,79 @@ pub(crate) fn verify_output_amount_packable( /// Computes the minimum amount that a storage deposit has to match to allow creating a return [`Output`] back to the /// sender [`Address`]. -fn minimum_storage_deposit(address: &Address, rent_structure: RentStructure, token_supply: u64) -> u64 { +fn minimum_storage_deposit(address: &Address, rent_parameters: RentParameters, token_supply: u64) -> u64 { // PANIC: This can never fail because the amount will always be within the valid range. Also, the actual value is // not important, we are only interested in the storage requirements of the type. - BasicOutputBuilder::new_with_minimum_storage_deposit(rent_structure) + BasicOutputBuilder::new_with_minimum_storage_deposit(rent_parameters) .add_unlock_condition(AddressUnlockCondition::new(*address)) .finish_with_params(token_supply) .unwrap() .amount() } +impl StorageCost for Output { + fn offset_score(&self, rent_params: RentParameters) -> u64 { + // included output id, block id, and slot booked data size + rent_params.storage_score_offset_output() + + (size_of::() as u64 + size_of::() as u64 + size_of::() as u64) + * rent_params.storage_score_factor_data() as u64 + } + + fn score(&self, rent_params: RentParameters) -> u64 { + self.packed_len() as u64 * rent_params.storage_score_factor_data() as u64 + } +} + +pub struct MinimumStorageDepositBasicOutput { + rent_params: RentParameters, + token_supply: u64, + builder: BasicOutputBuilder, +} + +impl MinimumStorageDepositBasicOutput { + pub fn new(rent_params: RentParameters, token_supply: u64) -> Self { + Self { + rent_params, + token_supply, + builder: BasicOutputBuilder::new_with_amount(Output::AMOUNT_MIN).add_unlock_condition( + AddressUnlockCondition::new(Address::from(Ed25519Address::from([0; Ed25519Address::LENGTH]))), + ), + } + } + + pub fn with_native_tokens(mut self, native_tokens: impl Into>) -> Self { + if let Some(native_tokens) = native_tokens.into() { + self.builder = self.builder.with_native_tokens(native_tokens); + } + self + } + + pub fn with_storage_deposit_return(mut self) -> Result { + self.builder = self + .builder + .add_unlock_condition(StorageDepositReturnUnlockCondition::new( + Address::from(Ed25519Address::from([0; Ed25519Address::LENGTH])), + Output::AMOUNT_MIN, + self.token_supply, + )?); + Ok(self) + } + + pub fn with_expiration(mut self) -> Result { + self.builder = self.builder.add_unlock_condition(ExpirationUnlockCondition::new( + Address::from(Ed25519Address::from([0; Ed25519Address::LENGTH])), + 1, + )?); + Ok(self) + } + + pub fn finish(self) -> Result { + Ok(self + .builder + .finish_output(self.token_supply)? + .storage_cost(self.rent_params)) + } +} #[cfg(feature = "serde")] pub mod dto { use alloc::format; diff --git a/sdk/src/types/block/output/nft.rs b/sdk/src/types/block/output/nft.rs index 695411b096..2bf755dbe0 100644 --- a/sdk/src/types/block/output/nft.rs +++ b/sdk/src/types/block/output/nft.rs @@ -19,8 +19,8 @@ use crate::types::{ verify_allowed_unlock_conditions, UnlockCondition, UnlockConditionFlags, UnlockConditions, }, verify_output_amount_min, verify_output_amount_packable, verify_output_amount_supply, ChainId, NativeToken, - NativeTokens, Output, OutputBuilderAmount, OutputId, RentStructure, StateTransitionError, - StateTransitionVerifier, StorageScore, + NativeTokens, Output, OutputBuilderAmount, OutputId, RentParameters, StateTransitionError, + StateTransitionVerifier, StorageCost, }, protocol::ProtocolParameters, semantic::{TransactionFailureReason, ValidationContext}, @@ -75,8 +75,8 @@ impl NftOutputBuilder { /// Creates an [`NftOutputBuilder`] with a provided rent structure. /// The amount will be set to the minimum storage deposit. - pub fn new_with_minimum_storage_deposit(rent_structure: RentStructure, nft_id: NftId) -> Self { - Self::new(OutputBuilderAmount::MinimumStorageDeposit(rent_structure), nft_id) + pub fn new_with_minimum_storage_deposit(rent_params: RentParameters, nft_id: NftId) -> Self { + Self::new(OutputBuilderAmount::MinimumStorageDeposit(rent_params), nft_id) } fn new(amount: OutputBuilderAmount, nft_id: NftId) -> Self { @@ -100,8 +100,8 @@ impl NftOutputBuilder { /// Sets the amount to the minimum storage deposit. #[inline(always)] - pub fn with_minimum_storage_deposit(mut self, rent_structure: RentStructure) -> Self { - self.amount = OutputBuilderAmount::MinimumStorageDeposit(rent_structure); + pub fn with_minimum_storage_deposit(mut self, rent_params: RentParameters) -> Self { + self.amount = OutputBuilderAmount::MinimumStorageDeposit(rent_params); self } @@ -243,8 +243,8 @@ impl NftOutputBuilder { output.amount = match self.amount { OutputBuilderAmount::Amount(amount) => amount, - OutputBuilderAmount::MinimumStorageDeposit(rent_structure) => { - Output::Nft(output.clone()).storage_score(rent_structure) + OutputBuilderAmount::MinimumStorageDeposit(rent_params) => { + Output::Nft(output.clone()).storage_cost(rent_params) } }; @@ -327,8 +327,8 @@ impl NftOutput { /// Creates a new [`NftOutputBuilder`] with a provided rent structure. /// The amount will be set to the minimum storage deposit. #[inline(always)] - pub fn build_with_minimum_storage_deposit(rent_structure: RentStructure, nft_id: NftId) -> NftOutputBuilder { - NftOutputBuilder::new_with_minimum_storage_deposit(rent_structure, nft_id) + pub fn build_with_minimum_storage_deposit(rent_params: RentParameters, nft_id: NftId) -> NftOutputBuilder { + NftOutputBuilder::new_with_minimum_storage_deposit(rent_params, nft_id) } /// @@ -617,8 +617,8 @@ pub(crate) mod dto { let params = params.into(); let mut builder = match amount { OutputBuilderAmount::Amount(amount) => NftOutputBuilder::new_with_amount(amount, *nft_id), - OutputBuilderAmount::MinimumStorageDeposit(rent_structure) => { - NftOutputBuilder::new_with_minimum_storage_deposit(rent_structure, *nft_id) + OutputBuilderAmount::MinimumStorageDeposit(rent_params) => { + NftOutputBuilder::new_with_minimum_storage_deposit(rent_params, *nft_id) } } .with_mana(mana); @@ -712,7 +712,7 @@ mod tests { test_split_dto(builder); let builder = - NftOutput::build_with_minimum_storage_deposit(protocol_parameters.rent_structure(), NftId::null()) + NftOutput::build_with_minimum_storage_deposit(protocol_parameters.rent_parameters(), NftId::null()) .add_native_token(NativeToken::new(TokenId::from(foundry_id), 1000).unwrap()) .add_unlock_condition(rand_address_unlock_condition()) .with_features(rand_allowed_features(NftOutput::ALLOWED_FEATURES)) diff --git a/sdk/src/types/block/payload/transaction/essence/regular.rs b/sdk/src/types/block/payload/transaction/essence/regular.rs index c21dfb0ddd..71e0d332cc 100644 --- a/sdk/src/types/block/payload/transaction/essence/regular.rs +++ b/sdk/src/types/block/payload/transaction/essence/regular.rs @@ -395,7 +395,7 @@ fn verify_outputs(outputs: &[Output], visitor: &ProtocolPara } } - output.verify_storage_deposit(visitor.rent_structure(), visitor.token_supply())?; + output.verify_storage_deposit(visitor.rent_parameters(), visitor.token_supply())?; } } diff --git a/sdk/src/types/block/protocol.rs b/sdk/src/types/block/protocol.rs index 7f07da3a8f..2fb9564ba5 100644 --- a/sdk/src/types/block/protocol.rs +++ b/sdk/src/types/block/protocol.rs @@ -13,7 +13,7 @@ use super::{ mana::{ManaStructure, RewardsParameters}, slot::SlotIndex, }; -use crate::types::block::{helper::network_name_to_id, output::RentStructure, ConvertTo, Error, PROTOCOL_VERSION}; +use crate::types::block::{helper::network_name_to_id, rent::RentParameters, ConvertTo, Error, PROTOCOL_VERSION}; /// Defines the parameters of the protocol at a particular version. #[derive(Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Packable, Getters, CopyGetters)] @@ -38,7 +38,7 @@ pub struct ProtocolParameters { /// The HRP prefix used for Bech32 addresses in the network. pub(crate) bech32_hrp: Hrp, /// The rent structure used by given node/network. - pub(crate) rent_structure: RentStructure, + pub(crate) rent_parameters: RentParameters, /// The work score structure used by the node/network. pub(crate) work_score_structure: WorkScoreStructure, /// TokenSupply defines the current token supply on the network. @@ -100,7 +100,7 @@ impl Default for ProtocolParameters { // Unwrap: Known to be valid network_name: String::from("iota-core-testnet").try_into().unwrap(), bech32_hrp: Hrp::from_str_unchecked("smr"), - rent_structure: Default::default(), + rent_parameters: Default::default(), work_score_structure: Default::default(), token_supply: 1_813_620_509_061_365, genesis_unix_timestamp: 1582328545, @@ -128,7 +128,7 @@ impl ProtocolParameters { version: u8, network_name: impl Into, bech32_hrp: impl ConvertTo, - rent_structure: RentStructure, + rent_parameters: RentParameters, token_supply: u64, genesis_unix_timestamp: u64, slot_duration_in_seconds: u8, @@ -138,7 +138,7 @@ impl ProtocolParameters { version, network_name: >::try_from(network_name.into()).map_err(Error::InvalidStringPrefix)?, bech32_hrp: bech32_hrp.convert()?, - rent_structure, + rent_parameters, token_supply, genesis_unix_timestamp, slot_duration_in_seconds, @@ -318,7 +318,7 @@ pub fn protocol_parameters() -> ProtocolParameters { 2, "testnet", "rms", - crate::types::block::output::RentStructure::new(500, 1, 10, 1, 1, 1), + crate::types::block::rent::RentParameters::new(500, 1, 10, 1, 1, 1), 1_813_620_509_061_365, 1582328545, 10, diff --git a/sdk/src/types/block/output/rent.rs b/sdk/src/types/block/rent.rs similarity index 55% rename from sdk/src/types/block/output/rent.rs rename to sdk/src/types/block/rent.rs index 5c8f792a35..1a48a92761 100644 --- a/sdk/src/types/block/output/rent.rs +++ b/sdk/src/types/block/rent.rs @@ -1,7 +1,7 @@ // Copyright 2022 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 -use core::mem::size_of; +use core::{mem::size_of, ops::Deref}; use packable::Packable; @@ -15,30 +15,44 @@ use crate::types::block::{ BlockId, Error, }; -// TODO: fill in the real values -const DEFAULT_STORAGE_COST: u32 = 100; +// TODO: fill in the real values and/or verify +const DEFAULT_STORAGE_COST: u64 = 500; const DEFAULT_STORAGE_SCORE_FACTOR_DATA: StorageScoreFactor = 1; -const DEFAULT_STORAGE_SCORE_OFFSET_OUTPUT: StorageScoreOffset = 1; -const DEFAULT_STORAGE_SCORE_OFFSET_ED25519_BLOCK_ISSUER_KEY: StorageScoreOffset = 1; -const DEFAULT_STORAGE_SCORE_STAKING_FEATURE: StorageScoreOffset = 1; -const DEFAULT_STORAGE_SCORE_OFFSET_DELEGATION: StorageScoreOffset = 1; +const DEFAULT_STORAGE_SCORE_OFFSET_OUTPUT: StorageScoreOffset = 10; +const DEFAULT_STORAGE_SCORE_OFFSET_ED25519_BLOCK_ISSUER_KEY: StorageScoreOffset = 50; +const DEFAULT_STORAGE_SCORE_OFFSET_STAKING_FEATURE: StorageScoreOffset = 100; +const DEFAULT_STORAGE_SCORE_OFFSET_DELEGATION: StorageScoreOffset = 100; -// Defines the type of the storage score factor. type StorageScoreFactor = u8; -// Defines the type of storage score. type StorageScoreOffset = u64; -/// Specifies the current parameters for the byte cost computation. +// Includes the rent parameters and the additional factors/offsets computed from these parameters. #[derive(Copy, +// Clone, Debug, Eq, PartialEq)] +pub struct RentStructure { + rent_parameters: RentParameters, + storage_score_offset_implicit_account_creation_address: u64, +} + +impl Deref for RentStructure { + type Target = RentParameters; + + fn deref(&self) -> &Self::Target { + &self.rent_parameters + } +} + +// Defines the parameters of storage score calculations on objects which take node resources. +// This structure defines the minimum base token deposit required on an object. This deposit does not +// generate Mana, which serves as a rent payment in Mana for storing the object. #[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Packable)] #[cfg_attr( feature = "serde", derive(serde::Serialize, serde::Deserialize), serde(rename_all = "camelCase") )] -pub struct RentStructure { - // TODO: what actual primitive type is their `BaseToken` type def? +pub struct RentParameters { /// Defines the number of IOTA tokens required per unit of storage score. - storage_cost: u32, + storage_cost: u64, /// Defines the factor to be used for data only fields. storage_score_factor_data: StorageScoreFactor, /// Defines the offset to be used for key/lookup generating fields. @@ -51,23 +65,23 @@ pub struct RentStructure { storage_score_offset_delegation: StorageScoreOffset, } -impl Default for RentStructure { +impl Default for RentParameters { fn default() -> Self { Self { storage_cost: DEFAULT_STORAGE_COST, storage_score_factor_data: DEFAULT_STORAGE_SCORE_FACTOR_DATA, storage_score_offset_output: DEFAULT_STORAGE_SCORE_OFFSET_OUTPUT, storage_score_offset_ed25519_block_issuer_key: DEFAULT_STORAGE_SCORE_OFFSET_ED25519_BLOCK_ISSUER_KEY, - storage_score_offset_staking_feature: DEFAULT_STORAGE_SCORE_STAKING_FEATURE, + storage_score_offset_staking_feature: DEFAULT_STORAGE_SCORE_OFFSET_STAKING_FEATURE, storage_score_offset_delegation: DEFAULT_STORAGE_SCORE_OFFSET_DELEGATION, } } } -impl RentStructure { - /// Creates a new [`RentStructure`]. +impl RentParameters { + /// Creates a new [`RentParameters`]. pub fn new( - storage_cost: u32, + storage_cost: u64, storage_score_factor_data: StorageScoreFactor, storage_score_offset_output: StorageScoreOffset, storage_score_offset_ed25519_block_issuer_key: StorageScoreOffset, @@ -85,7 +99,7 @@ impl RentStructure { } /// Sets the storage cost for the storage deposit. - pub fn with_storage_cost(mut self, storage_cost: u32) -> Self { + pub fn with_storage_cost(mut self, storage_cost: u64) -> Self { self.storage_cost = storage_cost; self } @@ -126,115 +140,59 @@ impl RentStructure { self } - /// Returns the TODO of the [`RentStructure`]. - pub const fn storage_cost(&self) -> u32 { + /// Returns the TODO of the [`RentParameters`]. + pub const fn storage_cost(&self) -> u64 { self.storage_cost } - /// Returns the TODO of the [`RentStructure`]. + /// Returns the TODO of the [`RentParameters`]. pub const fn storage_score_factor_data(&self) -> StorageScoreFactor { self.storage_score_factor_data } - /// Returns the TODO of the [`RentStructure`]. + /// Returns the TODO of the [`RentParameters`]. pub const fn storage_score_offset_output(&self) -> StorageScoreOffset { self.storage_score_offset_output } - /// Returns the TODO the [`RentStructure`]. + /// Returns the TODO the [`RentParameters`]. pub const fn storage_score_offset_ed25519_block_issuer_key(&self) -> StorageScoreOffset { self.storage_score_offset_ed25519_block_issuer_key } - /// Returns the TODO the [`RentStructure`]. + /// Returns the TODO the [`RentParameters`]. pub const fn storage_score_offset_staking_feature(&self) -> StorageScoreOffset { self.storage_score_offset_staking_feature } - /// Returns the TODO the [`RentStructure`]. + /// Returns the TODO the [`RentParameters`]. pub const fn storage_score_offset_delegation(&self) -> StorageScoreOffset { self.storage_score_offset_delegation } } -/// A trait to facilitate the computation of the storage score of block outputs, which is central to dust protection. -pub trait StorageScore { - /// Computes the byte offset given a [`RentStructure`]. - fn byte_offset(&self, rent_structure: RentStructure) -> u32 { - // TODO: verify this - // The ID of the output. - size_of::() as u32 * rent_structure.storage_score_offset_output as u32 - // The ID of the block in which the transaction payload that created this output was included. - + size_of::() as u32 * rent_structure.storage_score_factor_data as u32 - // The index of the slot in which the transaction that created it was booked. - + size_of::() as u32 * rent_structure.storage_score_factor_data as u32 - // The index of the slot in which the transaction was created. - + size_of::() as u32 * rent_structure.storage_score_factor_data as u32 - } - - /// Different fields in a type lead to different storage requirements for the ledger state. - fn weighted_bytes(&self, config: RentStructure) -> u64; - - /// Computes the storage score given a [`RentStructure`]. - fn storage_score(&self, rent_structure: RentStructure) -> u64 { - rent_structure.storage_cost as u64 - * (self.weighted_bytes(rent_structure) + self.byte_offset(rent_structure) as u64) +/// A trait to facilitate the rent cost computation for block outputs, which is central to dust protection. +pub trait StorageCost { + /// Computes the offset storage score given a [`RentParameters`]. Defaults to 0. + fn offset_score(&self, rent_params: RentParameters) -> u64 { + 0 } -} -impl StorageScore for [T; N] { - fn weighted_bytes(&self, config: RentStructure) -> u64 { - self.iter().map(|elem| elem.weighted_bytes(config)).sum() - } -} + /// Computes the storage score given a [`RentParameters`]. Different fields in a type lead to different storage + /// requirements for the ledger state. + fn score(&self, rent_params: RentParameters) -> u64; -pub struct MinimumStorageDepositBasicOutput { - config: RentStructure, - token_supply: u64, - builder: BasicOutputBuilder, -} - -impl MinimumStorageDepositBasicOutput { - pub fn new(config: RentStructure, token_supply: u64) -> Self { - Self { - config, - token_supply, - builder: BasicOutputBuilder::new_with_amount(Output::AMOUNT_MIN).add_unlock_condition( - AddressUnlockCondition::new(Address::from(Ed25519Address::from([0; Ed25519Address::LENGTH]))), - ), - } - } - - pub fn with_native_tokens(mut self, native_tokens: impl Into>) -> Self { - if let Some(native_tokens) = native_tokens.into() { - self.builder = self.builder.with_native_tokens(native_tokens); - } - self - } - - pub fn with_storage_deposit_return(mut self) -> Result { - self.builder = self - .builder - .add_unlock_condition(StorageDepositReturnUnlockCondition::new( - Address::from(Ed25519Address::from([0; Ed25519Address::LENGTH])), - Output::AMOUNT_MIN, - self.token_supply, - )?); - Ok(self) + /// Computes the storage cost given a [`RentParameters`]. + fn storage_cost(&self, rent_params: RentParameters) -> u64 { + rent_params.storage_cost as u64 * (self.offset_score(rent_params) + self.score(rent_params)) } +} - pub fn with_expiration(mut self) -> Result { - self.builder = self.builder.add_unlock_condition(ExpirationUnlockCondition::new( - Address::from(Ed25519Address::from([0; Ed25519Address::LENGTH])), - 1, - )?); - Ok(self) +impl StorageCost for [T; N] { + fn offset_score(&self, rent_params: RentParameters) -> u64 { + self.get(0).expect("zero sized array").score(rent_params) } - - pub fn finish(self) -> Result { - Ok(self - .builder - .finish_output(self.token_supply)? - .storage_score(self.config)) + fn score(&self, rent_params: RentParameters) -> u64 { + self.iter().map(|elem| elem.score(rent_params)).sum() } } diff --git a/sdk/src/wallet/account/mod.rs b/sdk/src/wallet/account/mod.rs index f8ab9a8e44..d07026b9df 100644 --- a/sdk/src/wallet/account/mod.rs +++ b/sdk/src/wallet/account/mod.rs @@ -613,7 +613,7 @@ fn serialize() { 2, "testnet", "rms", - crate::types::block::output::RentStructure::new(500, 1, 10, 1, 1, 1), + crate::types::block::rent::RentParameters::new(500, 1, 10, 1, 1, 1), 1_813_620_509_061_365, 1582328545, 10, diff --git a/sdk/src/wallet/account/operations/balance.rs b/sdk/src/wallet/account/operations/balance.rs index 85689610d3..5b622c01d1 100644 --- a/sdk/src/wallet/account/operations/balance.rs +++ b/sdk/src/wallet/account/operations/balance.rs @@ -7,7 +7,8 @@ use crate::{ client::secret::SecretManage, types::block::{ address::Bech32Address, - output::{unlock_condition::UnlockCondition, FoundryId, NativeTokensBuilder, Output, StorageScore}, + output::{unlock_condition::UnlockCondition, FoundryId, NativeTokensBuilder, Output}, + rent::StorageCost, ConvertTo, }, wallet::{ @@ -62,7 +63,7 @@ where account_details: &AccountDetails, ) -> Result { let network_id = self.client().get_network_id().await?; - let rent_structure = self.client().get_rent_structure().await?; + let rent_params = self.client().get_rent_parameters().await?; let mut balance = Balance::default(); let mut total_rent_amount = 0; let mut total_native_tokens = NativeTokensBuilder::default(); @@ -88,7 +89,7 @@ where } let output = &data.output; - let rent = output.storage_score(rent_structure); + let rent = output.storage_cost(rent_params); // Add account and foundry outputs here because they can't have a // [`StorageDepositReturnUnlockCondition`] or time related unlock conditions diff --git a/sdk/src/wallet/account/operations/output_claiming.rs b/sdk/src/wallet/account/operations/output_claiming.rs index 66192f018a..6ca1cc10b2 100644 --- a/sdk/src/wallet/account/operations/output_claiming.rs +++ b/sdk/src/wallet/account/operations/output_claiming.rs @@ -203,7 +203,7 @@ where log::debug!("[OUTPUT_CLAIMING] claim_outputs_internal"); let slot_index = self.client().get_slot_index().await?; - let rent_structure = self.client().get_rent_structure().await?; + let rent_params = self.client().get_rent_parameters().await?; let token_supply = self.client().get_token_supply().await?; let account_details = self.details().await; @@ -276,7 +276,7 @@ where .finish_output(token_supply)? } else { NftOutputBuilder::from(nft_output) - .with_minimum_storage_deposit(rent_structure) + .with_minimum_storage_deposit(rent_params) .with_nft_id(nft_output.nft_id_non_null(&output_data.output_id)) .with_unlock_conditions([AddressUnlockCondition::new(first_account_address.address.inner)]) // Set native tokens empty, we will collect them from all inputs later @@ -301,7 +301,7 @@ where required_amount_for_nfts } else { required_amount_for_nfts - + MinimumStorageDepositBasicOutput::new(rent_structure, token_supply) + + MinimumStorageDepositBasicOutput::new(rent_params, token_supply) .with_native_tokens(option_native_token) .finish()? }; @@ -321,7 +321,7 @@ where // Recalculate every time, because new inputs can also add more native tokens, which would increase // the required storage deposit required_amount = required_amount_for_nfts - + MinimumStorageDepositBasicOutput::new(rent_structure, token_supply) + + MinimumStorageDepositBasicOutput::new(rent_params, token_supply) .with_native_tokens(option_native_token) .finish()?; diff --git a/sdk/src/wallet/account/operations/transaction/high_level/create_account.rs b/sdk/src/wallet/account/operations/transaction/high_level/create_account.rs index 6a5a4b2310..31efd75e59 100644 --- a/sdk/src/wallet/account/operations/transaction/high_level/create_account.rs +++ b/sdk/src/wallet/account/operations/transaction/high_level/create_account.rs @@ -74,7 +74,7 @@ where options: impl Into> + Send, ) -> crate::wallet::Result { log::debug!("[TRANSACTION] prepare_create_account_output"); - let rent_structure = self.client().get_rent_structure().await?; + let rent_params = self.client().get_rent_parameters().await?; let token_supply = self.client().get_token_supply().await?; let controller_address = match params.as_ref().and_then(|options| options.address.as_ref()) { @@ -93,7 +93,7 @@ where }; let mut account_output_builder = - AccountOutputBuilder::new_with_minimum_storage_deposit(rent_structure, AccountId::null()) + AccountOutputBuilder::new_with_minimum_storage_deposit(rent_params, AccountId::null()) .with_state_index(0) .with_foundry_counter(0) .add_unlock_condition(StateControllerAddressUnlockCondition::new(controller_address)) diff --git a/sdk/src/wallet/account/operations/transaction/high_level/minting/create_native_token.rs b/sdk/src/wallet/account/operations/transaction/high_level/minting/create_native_token.rs index 8e7c71997e..373ac38201 100644 --- a/sdk/src/wallet/account/operations/transaction/high_level/minting/create_native_token.rs +++ b/sdk/src/wallet/account/operations/transaction/high_level/minting/create_native_token.rs @@ -131,7 +131,7 @@ where options: impl Into> + Send, ) -> crate::wallet::Result { log::debug!("[TRANSACTION] create_native_token"); - let rent_structure = self.client().get_rent_structure().await?; + let rent_params = self.client().get_rent_parameters().await?; let token_supply = self.client().get_token_supply().await?; let (account_id, account_output) = self @@ -158,7 +158,7 @@ where new_account_output_builder.finish_output(token_supply)?, { let mut foundry_builder = FoundryOutputBuilder::new_with_minimum_storage_deposit( - rent_structure, + rent_params, account_output.foundry_counter() + 1, TokenScheme::Simple(SimpleTokenScheme::new( params.circulating_supply, diff --git a/sdk/src/wallet/account/operations/transaction/high_level/minting/mint_nfts.rs b/sdk/src/wallet/account/operations/transaction/high_level/minting/mint_nfts.rs index 18996d33ee..f07f6e79a4 100644 --- a/sdk/src/wallet/account/operations/transaction/high_level/minting/mint_nfts.rs +++ b/sdk/src/wallet/account/operations/transaction/high_level/minting/mint_nfts.rs @@ -160,7 +160,7 @@ where I::IntoIter: Send, { log::debug!("[TRANSACTION] prepare_mint_nfts"); - let rent_structure = self.client().get_rent_structure().await?; + let rent_params = self.client().get_rent_parameters().await?; let token_supply = self.client().get_token_supply().await?; let account_addresses = self.addresses().await?; let mut outputs = Vec::new(); @@ -189,7 +189,7 @@ where }; // NftId needs to be set to 0 for the creation - let mut nft_builder = NftOutputBuilder::new_with_minimum_storage_deposit(rent_structure, NftId::null()) + let mut nft_builder = NftOutputBuilder::new_with_minimum_storage_deposit(rent_params, NftId::null()) // Address which will own the nft .add_unlock_condition(AddressUnlockCondition::new(address)); diff --git a/sdk/src/wallet/account/operations/transaction/high_level/send.rs b/sdk/src/wallet/account/operations/transaction/high_level/send.rs index 943aa87b9f..83dee32dcd 100644 --- a/sdk/src/wallet/account/operations/transaction/high_level/send.rs +++ b/sdk/src/wallet/account/operations/transaction/high_level/send.rs @@ -139,7 +139,7 @@ where { log::debug!("[TRANSACTION] prepare_send"); let options = options.into(); - let rent_structure = self.client().get_rent_structure().await?; + let rent_params = self.client().get_rent_parameters().await?; let token_supply = self.client().get_token_supply().await?; let account_addresses = self.addresses().await?; @@ -170,7 +170,7 @@ where .unwrap_or(default_return_address.address); // Get the minimum required amount for an output assuming it does not need a storage deposit. - let output = BasicOutputBuilder::new_with_minimum_storage_deposit(rent_structure) + let output = BasicOutputBuilder::new_with_minimum_storage_deposit(rent_params) .add_unlock_condition(AddressUnlockCondition::new(address)) .finish_output(token_supply)?; @@ -187,7 +187,7 @@ where }); // Since it does need a storage deposit, calculate how much that should be - let storage_deposit_amount = MinimumStorageDepositBasicOutput::new(rent_structure, token_supply) + let storage_deposit_amount = MinimumStorageDepositBasicOutput::new(rent_params, token_supply) .with_storage_deposit_return()? .with_expiration()? .finish()?; diff --git a/sdk/src/wallet/account/operations/transaction/high_level/send_native_tokens.rs b/sdk/src/wallet/account/operations/transaction/high_level/send_native_tokens.rs index 758074730e..571344c1a7 100644 --- a/sdk/src/wallet/account/operations/transaction/high_level/send_native_tokens.rs +++ b/sdk/src/wallet/account/operations/transaction/high_level/send_native_tokens.rs @@ -129,7 +129,7 @@ where I::IntoIter: Send, { log::debug!("[TRANSACTION] prepare_send_native_tokens"); - let rent_structure = self.client().get_rent_structure().await?; + let rent_params = self.client().get_rent_parameters().await?; let token_supply = self.client().get_token_supply().await?; let account_addresses = self.addresses().await?; @@ -171,7 +171,7 @@ where // get minimum required amount for such an output, so we don't lock more than required // We have to check it for every output individually, because different address types and amount of // different native tokens require a different storage deposit - let storage_deposit_amount = MinimumStorageDepositBasicOutput::new(rent_structure, token_supply) + let storage_deposit_amount = MinimumStorageDepositBasicOutput::new(rent_params, token_supply) .with_native_tokens(native_tokens.clone()) .with_storage_deposit_return()? .with_expiration()? diff --git a/sdk/src/wallet/account/operations/transaction/mod.rs b/sdk/src/wallet/account/operations/transaction/mod.rs index c3003ef4f8..0e0545827c 100644 --- a/sdk/src/wallet/account/operations/transaction/mod.rs +++ b/sdk/src/wallet/account/operations/transaction/mod.rs @@ -72,7 +72,10 @@ where // Check if the outputs have enough amount to cover the storage deposit for output in &outputs { - output.verify_storage_deposit(protocol_parameters.rent_structure(), protocol_parameters.token_supply())?; + output.verify_storage_deposit( + protocol_parameters.rent_parameters(), + protocol_parameters.token_supply(), + )?; } self.finish_transaction(outputs, options).await diff --git a/sdk/src/wallet/account/operations/transaction/prepare_output.rs b/sdk/src/wallet/account/operations/transaction/prepare_output.rs index 26b4c075fc..bb6af46d4e 100644 --- a/sdk/src/wallet/account/operations/transaction/prepare_output.rs +++ b/sdk/src/wallet/account/operations/transaction/prepare_output.rs @@ -14,8 +14,9 @@ use crate::{ TimelockUnlockCondition, }, BasicOutputBuilder, MinimumStorageDepositBasicOutput, NativeToken, NftId, NftOutputBuilder, Output, - RentStructure, StorageScore, UnlockCondition, + UnlockCondition, }, + rent::{RentParameters, StorageCost}, slot::SlotIndex, Error, }, @@ -46,12 +47,12 @@ where self.client().bech32_hrp_matches(params.recipient_address.hrp()).await?; - let rent_structure = self.client().get_rent_structure().await?; + let rent_params = self.client().get_rent_parameters().await?; let nft_id = params.assets.as_ref().and_then(|a| a.nft_id); let (mut first_output_builder, existing_nft_output_data) = self - .create_initial_output_builder(params.recipient_address, nft_id, rent_structure) + .create_initial_output_builder(params.recipient_address, nft_id, rent_params) .await?; if let Some(assets) = ¶ms.assets { @@ -102,7 +103,7 @@ where // Build output with minimum required storage deposit so we can use the amount in the next step let first_output = first_output_builder - .with_minimum_storage_deposit(rent_structure) + .with_minimum_storage_deposit(rent_params) .finish_output(token_supply)?; let mut second_output_builder = if nft_id.is_some() { @@ -112,9 +113,9 @@ where }; let min_storage_deposit_basic_output = - MinimumStorageDepositBasicOutput::new(rent_structure, token_supply).finish()?; + MinimumStorageDepositBasicOutput::new(rent_params, token_supply).finish()?; - let min_required_storage_deposit = first_output.storage_score(rent_structure); + let min_required_storage_deposit = first_output.storage_cost(rent_params); if params.amount > min_required_storage_deposit { second_output_builder = second_output_builder.with_amount(params.amount); @@ -146,7 +147,7 @@ where // need to check the min required storage deposit again let min_storage_deposit_new_amount = second_output_builder .clone() - .with_minimum_storage_deposit(rent_structure) + .with_minimum_storage_deposit(rent_params) .finish_output(token_supply)? .amount(); @@ -176,7 +177,7 @@ where // If we're sending an existing NFT, its minimum required storage deposit is not part of the available base_coin // balance, so we add it here if let Some(existing_nft_output_data) = existing_nft_output_data { - available_base_coin += existing_nft_output_data.output.storage_score(rent_structure); + available_base_coin += existing_nft_output_data.output.storage_cost(rent_params); } if final_amount > available_base_coin { @@ -236,16 +237,13 @@ where &self, recipient_address: Bech32Address, nft_id: Option, - rent_structure: RentStructure, + rent_params: RentParameters, ) -> crate::wallet::Result<(OutputBuilder, Option)> { let (mut first_output_builder, existing_nft_output_data) = if let Some(nft_id) = &nft_id { if nft_id.is_null() { // Mint a new NFT output ( - OutputBuilder::Nft(NftOutputBuilder::new_with_minimum_storage_deposit( - rent_structure, - *nft_id, - )), + OutputBuilder::Nft(NftOutputBuilder::new_with_minimum_storage_deposit(rent_params, *nft_id)), None, ) } else { @@ -266,7 +264,7 @@ where } } else { ( - OutputBuilder::Basic(BasicOutputBuilder::new_with_minimum_storage_deposit(rent_structure)), + OutputBuilder::Basic(BasicOutputBuilder::new_with_minimum_storage_deposit(rent_params)), None, ) }; @@ -429,13 +427,13 @@ impl OutputBuilder { } self } - fn with_minimum_storage_deposit(mut self, rent_structure: RentStructure) -> Self { + fn with_minimum_storage_deposit(mut self, rent_params: RentParameters) -> Self { match self { Self::Basic(b) => { - self = Self::Basic(b.with_minimum_storage_deposit(rent_structure)); + self = Self::Basic(b.with_minimum_storage_deposit(rent_params)); } Self::Nft(b) => { - self = Self::Nft(b.with_minimum_storage_deposit(rent_structure)); + self = Self::Nft(b.with_minimum_storage_deposit(rent_params)); } } self diff --git a/sdk/src/wallet/account/operations/transaction/prepare_transaction.rs b/sdk/src/wallet/account/operations/transaction/prepare_transaction.rs index 659fbb028d..d493791b05 100644 --- a/sdk/src/wallet/account/operations/transaction/prepare_transaction.rs +++ b/sdk/src/wallet/account/operations/transaction/prepare_transaction.rs @@ -34,12 +34,12 @@ where let options = options.into(); let outputs = outputs.into(); let prepare_transaction_start_time = Instant::now(); - let rent_structure = self.client().get_rent_structure().await?; + let rent_params = self.client().get_rent_parameters().await?; let token_supply = self.client().get_token_supply().await?; // Check if the outputs have enough amount to cover the storage deposit for output in &outputs { - output.verify_storage_deposit(rent_structure, token_supply)?; + output.verify_storage_deposit(rent_params, token_supply)?; } let is_burn_present = options.as_ref().map(|options| options.burn.is_some()).unwrap_or(false); diff --git a/sdk/tests/client/input_selection/account_outputs.rs b/sdk/tests/client/input_selection/account_outputs.rs index 9e1ce84ec2..d9fcb96d05 100644 --- a/sdk/tests/client/input_selection/account_outputs.rs +++ b/sdk/tests/client/input_selection/account_outputs.rs @@ -2313,7 +2313,7 @@ fn new_state_metadata() { let account_id_1 = AccountId::from_str(ACCOUNT_ID_1).unwrap(); let account_output = - AccountOutputBuilder::new_with_minimum_storage_deposit(protocol_parameters.rent_structure(), account_id_1) + AccountOutputBuilder::new_with_minimum_storage_deposit(protocol_parameters.rent_parameters(), account_id_1) .with_state_metadata([1, 2, 3]) .add_unlock_condition(StateControllerAddressUnlockCondition::new( Address::try_from_bech32(BECH32_ADDRESS_ED25519_0).unwrap(), @@ -2332,7 +2332,7 @@ fn new_state_metadata() { // New account output, with updated state index let updated_account_output = AccountOutputBuilder::from(account_output.as_account()) - .with_minimum_storage_deposit(protocol_parameters.rent_structure()) + .with_minimum_storage_deposit(protocol_parameters.rent_parameters()) .with_state_metadata([3, 4, 5]) .with_state_index(account_output.as_account().state_index() + 1) .finish_output(protocol_parameters.token_supply()) @@ -2359,7 +2359,7 @@ fn new_state_metadata_but_same_state_index() { let account_id_1 = AccountId::from_str(ACCOUNT_ID_1).unwrap(); let account_output = - AccountOutputBuilder::new_with_minimum_storage_deposit(protocol_parameters.rent_structure(), account_id_1) + AccountOutputBuilder::new_with_minimum_storage_deposit(protocol_parameters.rent_parameters(), account_id_1) .with_state_metadata([1, 2, 3]) .add_unlock_condition(StateControllerAddressUnlockCondition::new( Address::try_from_bech32(BECH32_ADDRESS_ED25519_0).unwrap(), @@ -2378,7 +2378,7 @@ fn new_state_metadata_but_same_state_index() { // New account output, without updated state index let updated_account_output = AccountOutputBuilder::from(account_output.as_account()) - .with_minimum_storage_deposit(protocol_parameters.rent_structure()) + .with_minimum_storage_deposit(protocol_parameters.rent_parameters()) .with_state_metadata([3, 4, 5]) .finish_output(protocol_parameters.token_supply()) .unwrap(); diff --git a/sdk/tests/client/input_selection/nft_outputs.rs b/sdk/tests/client/input_selection/nft_outputs.rs index 7033ed3f14..fa5a9b6cae 100644 --- a/sdk/tests/client/input_selection/nft_outputs.rs +++ b/sdk/tests/client/input_selection/nft_outputs.rs @@ -1197,13 +1197,14 @@ fn changed_immutable_metadata() { #[cfg(not(feature = "irc_27"))] let metadata = [1, 2, 3]; - let nft_output = NftOutputBuilder::new_with_minimum_storage_deposit(protocol_parameters.rent_structure(), 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(protocol_parameters.token_supply()) - .unwrap(); + let nft_output = + NftOutputBuilder::new_with_minimum_storage_deposit(protocol_parameters.rent_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(protocol_parameters.token_supply()) + .unwrap(); let inputs = [InputSigningData { output: nft_output.clone(), @@ -1223,7 +1224,7 @@ fn changed_immutable_metadata() { // New nft output with changed immutable metadata feature let updated_nft_output = NftOutputBuilder::from(nft_output.as_nft()) - .with_minimum_storage_deposit(protocol_parameters.rent_structure()) + .with_minimum_storage_deposit(protocol_parameters.rent_parameters()) .with_immutable_features(MetadataFeature::try_from(metadata)) .finish_output(protocol_parameters.token_supply()) .unwrap(); diff --git a/sdk/tests/client/node_api/indexer.rs b/sdk/tests/client/node_api/indexer.rs index c1c221e625..4914476f73 100644 --- a/sdk/tests/client/node_api/indexer.rs +++ b/sdk/tests/client/node_api/indexer.rs @@ -32,7 +32,7 @@ // .await?[0]; // let alias_output = -// AliasOutputBuilder::new_with_minimum_storage_deposit(*protocol_parameters.rent_structure(), AliasId::null()) +// AliasOutputBuilder::new_with_minimum_storage_deposit(*protocol_parameters.rent_parameters(), AliasId::null()) // .with_state_metadata([1, 2, 3]) // .add_unlock_condition(StateControllerAddressUnlockCondition::new(address)) // .add_unlock_condition(GovernorAddressUnlockCondition::new(address)) @@ -64,7 +64,7 @@ // .await?[0]; // let nft_output = -// NftOutputBuilder::new_with_minimum_storage_deposit(*protocol_parameters.rent_structure(), NftId::null()) +// NftOutputBuilder::new_with_minimum_storage_deposit(*protocol_parameters.rent_parameters(), NftId::null()) // .with_unlock_conditions([UnlockCondition::Address(AddressUnlockCondition::new(address))]) // .finish_output(protocol_parameters.token_supply())?; @@ -94,7 +94,7 @@ // .await?[0]; // let alias_output_0 = -// AliasOutputBuilder::new_with_minimum_storage_deposit(*protocol_parameters.rent_structure(), AliasId::null()) +// AliasOutputBuilder::new_with_minimum_storage_deposit(*protocol_parameters.rent_parameters(), AliasId::null()) // .with_state_metadata([1, 2, 3]) // .add_unlock_condition(StateControllerAddressUnlockCondition::new(address)) // .add_unlock_condition(GovernorAddressUnlockCondition::new(address)) @@ -122,7 +122,7 @@ // ); // let foundry_output = FoundryOutputBuilder::new_with_minimum_storage_deposit( -// *protocol_parameters.rent_structure(), +// *protocol_parameters.rent_parameters(), // alias_output_0.as_alias().foundry_counter() + 1, // TokenScheme::Simple(SimpleTokenScheme::new(100, 0, 500)?), // ) diff --git a/sdk/tests/types/block_id.rs b/sdk/tests/types/block_id.rs index 5e21824713..9ab5e30dca 100644 --- a/sdk/tests/types/block_id.rs +++ b/sdk/tests/types/block_id.rs @@ -5,7 +5,7 @@ use core::str::FromStr; use iota_sdk::types::{ block::{ - output::RentStructure, protocol::ProtocolParameters, rand::bytes::rand_bytes_array, BlockHash, BlockId, + protocol::ProtocolParameters, rand::bytes::rand_bytes_array, rent::RentParameters, BlockHash, BlockId, BlockWrapper, BlockWrapperDto, }, TryFromDto, @@ -68,7 +68,7 @@ fn memory_layout() { } fn protocol_parameters() -> ProtocolParameters { - ProtocolParameters::new(3, "test", "rms", RentStructure::default(), 0, 1695275822, 10, 0).unwrap() + ProtocolParameters::new(3, "test", "rms", RentParameters::default(), 0, 1695275822, 10, 0).unwrap() } #[test] diff --git a/sdk/tests/types/output/account.rs b/sdk/tests/types/output/account.rs index a58f9cb0a1..da57929d40 100644 --- a/sdk/tests/types/output/account.rs +++ b/sdk/tests/types/output/account.rs @@ -4,7 +4,7 @@ use iota_sdk::types::{ block::{ address::AccountAddress, - output::{AccountOutput, Feature, FoundryId, NativeToken, Output, SimpleTokenScheme, StorageScore, TokenId}, + output::{AccountOutput, Feature, FoundryId, NativeToken, Output, SimpleTokenScheme, TokenId}, protocol::protocol_parameters, rand::output::{ feature::{rand_issuer_feature, rand_metadata_feature, rand_sender_feature}, @@ -14,6 +14,7 @@ use iota_sdk::types::{ rand_state_controller_address_unlock_condition_different_from, }, }, + rent::StorageCost, }, ValidationParams, }; @@ -71,7 +72,7 @@ fn builder() { let metadata = rand_metadata_feature(); let output = builder - .with_minimum_storage_deposit(protocol_parameters.rent_structure()) + .with_minimum_storage_deposit(protocol_parameters.rent_parameters()) .add_unlock_condition(rand_state_controller_address_unlock_condition_different_from( &account_id, )) @@ -83,7 +84,7 @@ fn builder() { assert_eq!( output.amount(), - Output::Account(output.clone()).storage_score(protocol_parameters.rent_structure()) + Output::Account(output.clone()).storage_cost(protocol_parameters.rent_parameters()) ); assert_eq!(output.features().metadata(), Some(&metadata)); assert_eq!(output.features().sender(), Some(&sender_1)); diff --git a/sdk/tests/types/output/basic.rs b/sdk/tests/types/output/basic.rs index 8b897e9b53..7511b44410 100644 --- a/sdk/tests/types/output/basic.rs +++ b/sdk/tests/types/output/basic.rs @@ -3,7 +3,7 @@ use iota_sdk::types::{ block::{ - output::{BasicOutput, Feature, FoundryId, NativeToken, Output, SimpleTokenScheme, StorageScore, TokenId}, + output::{BasicOutput, Feature, FoundryId, NativeToken, Output, SimpleTokenScheme, TokenId}, protocol::protocol_parameters, rand::{ address::rand_account_address, @@ -13,6 +13,7 @@ use iota_sdk::types::{ unlock_condition::rand_address_unlock_condition, }, }, + rent::StorageCost, }, ValidationParams, }; @@ -50,7 +51,7 @@ fn builder() { let metadata = rand_metadata_feature(); let output = builder - .with_minimum_storage_deposit(protocol_parameters.rent_structure()) + .with_minimum_storage_deposit(protocol_parameters.rent_parameters()) .add_unlock_condition(rand_address_unlock_condition()) .with_features([Feature::from(metadata.clone()), sender_1.into()]) .finish_with_params(ValidationParams::default().with_protocol_parameters(protocol_parameters.clone())) @@ -58,7 +59,7 @@ fn builder() { assert_eq!( output.amount(), - Output::Basic(output.clone()).storage_score(protocol_parameters.rent_structure()) + Output::Basic(output.clone()).storage_cost(protocol_parameters.rent_parameters()) ); assert_eq!(output.features().metadata(), Some(&metadata)); assert_eq!(output.features().sender(), Some(&sender_1)); diff --git a/sdk/tests/types/output/foundry.rs b/sdk/tests/types/output/foundry.rs index a620b664b6..e5e5bba55b 100644 --- a/sdk/tests/types/output/foundry.rs +++ b/sdk/tests/types/output/foundry.rs @@ -4,13 +4,14 @@ use iota_sdk::types::block::{ output::{ unlock_condition::ImmutableAccountAddressUnlockCondition, FoundryId, FoundryOutput, NativeToken, Output, - SimpleTokenScheme, StorageScore, TokenId, + SimpleTokenScheme, TokenId, }, protocol::protocol_parameters, rand::{ address::rand_account_address, output::{feature::rand_metadata_feature, rand_foundry_output, rand_token_scheme}, }, + rent::StorageCost, }; use packable::PackableExt; @@ -51,14 +52,14 @@ fn builder() { assert!(output.immutable_features().is_empty()); let output = builder - .with_minimum_storage_deposit(protocol_parameters.rent_structure()) + .with_minimum_storage_deposit(protocol_parameters.rent_parameters()) .add_unlock_condition(ImmutableAccountAddressUnlockCondition::new(rand_account_address())) .finish_with_params(&protocol_parameters) .unwrap(); assert_eq!( output.amount(), - Output::Foundry(output).storage_score(protocol_parameters.rent_structure()) + Output::Foundry(output).storage_cost(protocol_parameters.rent_parameters()) ); } diff --git a/sdk/tests/types/output/nft.rs b/sdk/tests/types/output/nft.rs index 4485176a36..8c742cc4ae 100644 --- a/sdk/tests/types/output/nft.rs +++ b/sdk/tests/types/output/nft.rs @@ -2,7 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 use iota_sdk::types::block::{ - output::{FoundryId, NativeToken, NftId, NftOutput, Output, SimpleTokenScheme, StorageScore, TokenId}, + output::{FoundryId, NativeToken, NftId, NftOutput, Output, SimpleTokenScheme, TokenId}, protocol::protocol_parameters, rand::{ address::rand_account_address, @@ -12,6 +12,7 @@ use iota_sdk::types::block::{ unlock_condition::rand_address_unlock_condition, }, }, + rent::StorageCost, }; use packable::PackableExt; @@ -52,14 +53,14 @@ fn builder() { assert!(output.immutable_features().is_empty()); let output = builder - .with_minimum_storage_deposit(protocol_parameters.rent_structure()) + .with_minimum_storage_deposit(protocol_parameters.rent_parameters()) .add_unlock_condition(rand_address_unlock_condition()) .finish_with_params(protocol_parameters.token_supply()) .unwrap(); assert_eq!( output.amount(), - Output::Nft(output).storage_score(protocol_parameters.rent_structure()) + Output::Nft(output).storage_cost(protocol_parameters.rent_parameters()) ); } diff --git a/sdk/tests/types/protocol.rs b/sdk/tests/types/protocol.rs index 5ec2528475..d612358ecf 100644 --- a/sdk/tests/types/protocol.rs +++ b/sdk/tests/types/protocol.rs @@ -14,13 +14,13 @@ // "version":3, // "networkName":"TestJungle", // "bech32Hrp":"tgl", -// "rentStructure":{ -// "vByteCost":0, -// "vByteFactorData":0, -// "vByteFactorKey":0, -// "vByteFactorBlockIssuerKey":0, -// "vByteFactorStakingFeature":0, -// "vByteFactorDelegation":0 +// "rentParameters":{ +// "storageCost":0, +// "storageScoreFactorData":0, +// "storageScoreOffsetOutput":0, +// "storageScoreOffsetEd25519BlockIssuerKey":0, +// "storageScoreOffsetStakingFeature":0, +// "storageScoreOffsetDelegation":0 // }, // "workScoreStructure":{ // "dataByte":0, diff --git a/sdk/tests/types/rent.rs b/sdk/tests/types/rent.rs index 9f8bb6d9b2..9bffe8047d 100644 --- a/sdk/tests/types/rent.rs +++ b/sdk/tests/types/rent.rs @@ -11,7 +11,7 @@ // fn output_in_range(output: Output, range: std::ops::RangeInclusive) { // let cost = output.storage_score(Default::default()); -// assert!(range.contains(&cost), "{output:#?} has a required byte cost of {cost}"); +// assert!(range.contains(&cost), "{output:#?} has a required storage cost of {cost}"); // } // #[test] diff --git a/sdk/tests/wallet/claim_outputs.rs b/sdk/tests/wallet/claim_outputs.rs index 706811796e..f72f74dd60 100644 --- a/sdk/tests/wallet/claim_outputs.rs +++ b/sdk/tests/wallet/claim_outputs.rs @@ -127,11 +127,11 @@ async fn claim_2_basic_outputs_no_outputs_in_claim_account() -> Result<()> { let account_1 = wallet.create_account().finish().await?; let token_supply = account_0.client().get_token_supply().await?; - let rent_structure = account_0.client().get_rent_structure().await?; + let rent_params = account_0.client().get_rent_parameters().await?; // TODO more fitting value let expiration_slot = account_0.client().get_slot_index().await? + 86400; - let output = BasicOutputBuilder::new_with_minimum_storage_deposit(rent_structure) + let output = BasicOutputBuilder::new_with_minimum_storage_deposit(rent_params) .add_unlock_condition(AddressUnlockCondition::new( *account_1.addresses().await?[0].address().as_ref(), )) @@ -322,13 +322,13 @@ async fn claim_2_native_tokens_no_outputs_in_claim_account() -> Result<()> { .await?; account_0.sync(None).await?; - let rent_structure = account_0.client().get_rent_structure().await?; + let rent_params = account_0.client().get_rent_parameters().await?; let token_supply = account_0.client().get_token_supply().await?; let tx = account_0 .send_outputs( [ - BasicOutputBuilder::new_with_minimum_storage_deposit(rent_structure) + BasicOutputBuilder::new_with_minimum_storage_deposit(rent_params) .add_unlock_condition(AddressUnlockCondition::new( *account_1.addresses().await?[0].address().as_ref(), )) @@ -338,7 +338,7 @@ async fn claim_2_native_tokens_no_outputs_in_claim_account() -> Result<()> { )?) .add_native_token(NativeToken::new(create_tx_0.token_id, native_token_amount)?) .finish_output(token_supply)?, - BasicOutputBuilder::new_with_minimum_storage_deposit(rent_structure) + BasicOutputBuilder::new_with_minimum_storage_deposit(rent_params) .add_unlock_condition(AddressUnlockCondition::new( *account_1.addresses().await?[0].address().as_ref(), )) diff --git a/sdk/tests/wallet/output_preparation.rs b/sdk/tests/wallet/output_preparation.rs index f032b59923..dfe2bc4afa 100644 --- a/sdk/tests/wallet/output_preparation.rs +++ b/sdk/tests/wallet/output_preparation.rs @@ -6,7 +6,8 @@ use std::str::FromStr; use iota_sdk::{ types::block::{ address::{Address, Bech32Address, ToBech32Ext}, - output::{MinimumStorageDepositBasicOutput, NativeToken, NftId, Output, StorageScore, TokenId}, + output::{MinimumStorageDepositBasicOutput, NativeToken, NftId, Output, TokenId}, + rent::StorageCost, slot::SlotIndex, }, wallet::{ @@ -408,8 +409,8 @@ async fn output_preparation() -> Result<()> { None, ) .await?; - let rent_structure = wallet.client().get_rent_structure().await?; - let minimum_storage_deposit = output.storage_score(rent_structure); + let rent_params = wallet.client().get_rent_parameters().await?; + let minimum_storage_deposit = output.storage_cost(rent_params); assert_eq!(output.amount(), minimum_storage_deposit); assert_eq!(output.amount(), 187900); let sdr = output.unlock_conditions().unwrap().storage_deposit_return().unwrap(); @@ -432,7 +433,7 @@ async fn output_preparation_sdr() -> Result<()> { let wallet = make_wallet(storage_path, None, None).await?; let account = &create_accounts_with_funds(&wallet, 1).await?[0]; - let rent_structure = account.client().get_rent_structure().await?; + let rent_params = account.client().get_rent_parameters().await?; let token_supply = account.client().get_token_supply().await?; let recipient_address_bech32 = String::from("rms1qpszqzadsym6wpppd6z037dvlejmjuke7s24hm95s9fg9vpua7vluaw60xu"); @@ -454,7 +455,7 @@ async fn output_preparation_sdr() -> Result<()> { ) .await?; // Check if the output has enough amount to cover the storage deposit - output.verify_storage_deposit(rent_structure, token_supply)?; + output.verify_storage_deposit(rent_params, token_supply)?; assert_eq!(output.amount(), 50601); // address and sdr unlock condition assert_eq!(output.unlock_conditions().unwrap().len(), 2); @@ -475,7 +476,7 @@ async fn output_preparation_sdr() -> Result<()> { ) .await?; // Check if the output has enough amount to cover the storage deposit - output.verify_storage_deposit(rent_structure, token_supply)?; + output.verify_storage_deposit(rent_params, token_supply)?; assert_eq!(output.amount(), 85199); // address and sdr unlock condition assert_eq!(output.unlock_conditions().unwrap().len(), 2); @@ -500,7 +501,7 @@ async fn output_preparation_sdr() -> Result<()> { ) .await?; // Check if the output has enough amount to cover the storage deposit - output.verify_storage_deposit(rent_structure, token_supply)?; + output.verify_storage_deposit(rent_params, token_supply)?; assert_eq!(output.amount(), 85199); // address and sdr unlock condition assert_eq!(output.unlock_conditions().unwrap().len(), 2); @@ -525,7 +526,7 @@ async fn output_preparation_sdr() -> Result<()> { ) .await?; // Check if the output has enough amount to cover the storage deposit - output.verify_storage_deposit(rent_structure, token_supply)?; + output.verify_storage_deposit(rent_params, token_supply)?; // The additional 1 amount will be added, because the storage deposit should be gifted and not returned assert_eq!(output.amount(), 42600); // storage deposit gifted, only address unlock condition @@ -613,12 +614,11 @@ async fn prepare_output_remainder_dust() -> Result<()> { let addresses = &accounts[1].addresses().await?; let address = addresses[0].address(); - let rent_structure = account.client().get_rent_structure().await?; + let rent_params = account.client().get_rent_parameters().await?; let token_supply = account.client().get_token_supply().await?; let balance = account.sync(None).await?; - let minimum_required_storage_deposit = - MinimumStorageDepositBasicOutput::new(rent_structure, token_supply).finish()?; + let minimum_required_storage_deposit = MinimumStorageDepositBasicOutput::new(rent_params, token_supply).finish()?; // Send away most balance so we can test with leaving dust let output = account @@ -659,7 +659,7 @@ async fn prepare_output_remainder_dust() -> Result<()> { .await?; // Check if the output has enough amount to cover the storage deposit - output.verify_storage_deposit(rent_structure, token_supply)?; + output.verify_storage_deposit(rent_params, token_supply)?; // The left over 21299 is too small to keep, so we donate it assert_eq!(output.amount(), balance.base_coin().available()); // storage deposit gifted, only address unlock condition @@ -703,7 +703,7 @@ async fn prepare_output_remainder_dust() -> Result<()> { .await?; // Check if the output has enough amount to cover the storage deposit - output.verify_storage_deposit(rent_structure, token_supply)?; + output.verify_storage_deposit(rent_params, token_supply)?; // We use excess if leftover is too small, so amount == all available balance assert_eq!(output.amount(), 63900); // storage deposit gifted, only address unlock condition @@ -727,7 +727,7 @@ async fn prepare_output_remainder_dust() -> Result<()> { .await?; // Check if the output has enough amount to cover the storage deposit - output.verify_storage_deposit(rent_structure, token_supply)?; + output.verify_storage_deposit(rent_params, token_supply)?; // We use excess if leftover is too small, so amount == all available balance assert_eq!(output.amount(), 63900); // storage deposit returned, address and SDR unlock condition @@ -849,8 +849,8 @@ async fn prepare_existing_nft_output_gift() -> Result<()> { .as_nft() .clone(); - let rent_structure = wallet.client().get_rent_structure().await?; - let minimum_storage_deposit = Output::Nft(nft.clone()).storage_score(rent_structure); + let rent_params = wallet.client().get_rent_parameters().await?; + let minimum_storage_deposit = Output::Nft(nft.clone()).storage_cost(rent_params); assert_eq!(nft.amount(), minimum_storage_deposit); assert_eq!(nft.amount(), 52300); From c79c02444c0769f0e80b3e4afbe0e9f4424e3300 Mon Sep 17 00:00:00 2001 From: Alexander Schmidt Date: Fri, 6 Oct 2023 15:30:55 +0200 Subject: [PATCH 03/10] impl StorageScore for outputs --- bindings/core/src/method_handler/client.rs | 4 +-- bindings/core/src/method_handler/utils.rs | 4 +-- .../input_selection/requirement/amount.rs | 4 +-- sdk/src/types/block/address/mod.rs | 2 +- sdk/src/types/block/output/account.rs | 19 ++++++++++-- sdk/src/types/block/output/basic.rs | 17 +++++++++-- sdk/src/types/block/output/delegation.rs | 17 +++++++++-- .../block/output/feature/block_issuer.rs | 13 +++----- sdk/src/types/block/output/feature/issuer.rs | 12 +++++++- sdk/src/types/block/output/feature/mod.rs | 8 ++++- sdk/src/types/block/output/foundry.rs | 20 +++++++++++-- sdk/src/types/block/output/mod.rs | 30 ++++++++++++------- sdk/src/types/block/output/native_token.rs | 8 ++++- sdk/src/types/block/output/nft.rs | 19 ++++++++++-- .../types/block/output/token_scheme/mod.rs | 10 ++++++- .../types/block/output/token_scheme/simple.rs | 8 ++++- .../block/output/unlock_condition/mod.rs | 8 ++++- sdk/src/types/block/rent.rs | 16 +++------- sdk/src/wallet/account/operations/balance.rs | 4 +-- .../operations/transaction/prepare_output.rs | 6 ++-- sdk/tests/types/output/account.rs | 4 +-- sdk/tests/types/output/basic.rs | 4 +-- sdk/tests/types/output/foundry.rs | 4 +-- sdk/tests/types/output/nft.rs | 4 +-- sdk/tests/wallet/output_preparation.rs | 6 ++-- 25 files changed, 175 insertions(+), 76 deletions(-) diff --git a/bindings/core/src/method_handler/client.rs b/bindings/core/src/method_handler/client.rs index 53a3da32a2..e49965ea7b 100644 --- a/bindings/core/src/method_handler/client.rs +++ b/bindings/core/src/method_handler/client.rs @@ -12,7 +12,7 @@ use iota_sdk::{ dto::OutputDto, AccountOutput, BasicOutput, FoundryOutput, NftOutput, Output, OutputBuilderAmount, }, payload::Payload, - rent::StorageCost, + rent::StorageScore, BlockWrapper, BlockWrapperDto, }, TryFromDto, @@ -298,7 +298,7 @@ pub(crate) async fn call_client_method_internal(client: &Client, method: ClientM let output = Output::try_from_dto_with_params(output, client.get_token_supply().await?)?; let rent_params = client.get_rent_parameters().await?; - let minimum_storage_deposit = output.storage_cost(rent_params); + let minimum_storage_deposit = output.rent_cost(rent_params); Response::MinimumRequiredStorageDeposit(minimum_storage_deposit.to_string()) } diff --git a/bindings/core/src/method_handler/utils.rs b/bindings/core/src/method_handler/utils.rs index c4809711c5..5668e7399f 100644 --- a/bindings/core/src/method_handler/utils.rs +++ b/bindings/core/src/method_handler/utils.rs @@ -10,7 +10,7 @@ use iota_sdk::{ input::UtxoInput, output::{AccountId, FoundryId, InputsCommitment, NftId, Output, OutputId, TokenId}, payload::{transaction::TransactionEssence, TransactionPayload}, - rent::StorageCost, + rent::StorageScore, BlockWrapper, }, TryFromDto, @@ -81,7 +81,7 @@ pub(crate) fn call_utils_method_internal(method: UtilsMethod) -> Result { let out = Output::try_from_dto(output)?; - Response::MinimumRequiredStorageDeposit(out.storage_cost(rent).to_string()) + Response::MinimumRequiredStorageDeposit(out.rent_cost(rent).to_string()) } UtilsMethod::VerifyMnemonic { mnemonic } => { let mnemonic = Mnemonic::from(mnemonic); diff --git a/sdk/src/client/api/block_builder/input_selection/requirement/amount.rs b/sdk/src/client/api/block_builder/input_selection/requirement/amount.rs index a030f94101..da937b21c6 100644 --- a/sdk/src/client/api/block_builder/input_selection/requirement/amount.rs +++ b/sdk/src/client/api/block_builder/input_selection/requirement/amount.rs @@ -13,7 +13,7 @@ use crate::{ unlock_condition::StorageDepositReturnUnlockCondition, AccountOutputBuilder, AccountTransition, FoundryOutputBuilder, NftOutputBuilder, Output, OutputId, }, - rent::StorageCost, + rent::StorageScore, slot::SlotIndex, }, }; @@ -241,7 +241,7 @@ impl InputSelection { for output in outputs { let diff = amount_selection.missing_amount(); let amount = output.amount(); - let rent = output.storage_cost(self.protocol_parameters.rent_parameters()); + let rent = output.rent_cost(self.protocol_parameters.rent_parameters()); let new_amount = if amount >= diff + rent { amount - diff } else { rent }; diff --git a/sdk/src/types/block/address/mod.rs b/sdk/src/types/block/address/mod.rs index 0c63d3bc57..ba72388413 100644 --- a/sdk/src/types/block/address/mod.rs +++ b/sdk/src/types/block/address/mod.rs @@ -17,7 +17,7 @@ pub use self::{ use crate::{ types::block::{ output::{Output, OutputId}, - rent::{RentParameters, RentStructure, StorageCost}, + rent::{RentParameters, RentStructure, StorageScore}, semantic::{TransactionFailureReason, ValidationContext}, signature::Signature, unlock::Unlock, diff --git a/sdk/src/types/block/output/account.rs b/sdk/src/types/block/output/account.rs index 108f64d7f9..9bff1abb0d 100644 --- a/sdk/src/types/block/output/account.rs +++ b/sdk/src/types/block/output/account.rs @@ -10,7 +10,7 @@ use packable::{ packer::Packer, prefix::BoxedSlicePrefix, unpacker::Unpacker, - Packable, + Packable, PackableExt, }; use crate::types::{ @@ -25,7 +25,7 @@ use crate::types::{ NativeTokens, Output, OutputBuilderAmount, OutputId, StateTransitionError, StateTransitionVerifier, }, protocol::ProtocolParameters, - rent::{RentParameters, StorageCost}, + rent::{RentParameters, StorageScore}, semantic::{TransactionFailureReason, ValidationContext}, unlock::Unlock, Error, @@ -33,6 +33,8 @@ use crate::types::{ ValidationParams, }; +use super::storage_score_offset_output; + impl_id!(pub AccountId, 32, "Unique identifier of an account, which is the BLAKE2b-256 hash of the Output ID that created it."); #[cfg(feature = "serde")] @@ -319,7 +321,7 @@ impl AccountOutputBuilder { output.amount = match self.amount { OutputBuilderAmount::Amount(amount) => amount, OutputBuilderAmount::MinimumStorageDeposit(rent_params) => { - Output::Account(output.clone()).storage_cost(rent_params) + Output::Account(output.clone()).rent_cost(rent_params) } }; @@ -726,6 +728,17 @@ impl Packable for AccountOutput { } } +impl StorageScore for AccountOutput { + fn score(&self, rent_params: RentParameters) -> u64 { + storage_score_offset_output(rent_params) + + self.packed_len() as u64 * rent_params.storage_score_factor_data() as u64 + + self.native_tokens().score(rent_params) + + self.unlock_conditions().score(rent_params) + + self.features().score(rent_params) + + self.immutable_features().score(rent_params) + } +} + #[inline] fn verify_index_counter(account_id: &AccountId, state_index: u32, foundry_counter: u32) -> Result<(), Error> { if account_id.is_null() && (state_index != 0 || foundry_counter != 0) { diff --git a/sdk/src/types/block/output/basic.rs b/sdk/src/types/block/output/basic.rs index c21f892655..ef8abec914 100644 --- a/sdk/src/types/block/output/basic.rs +++ b/sdk/src/types/block/output/basic.rs @@ -3,8 +3,9 @@ use alloc::collections::BTreeSet; -use packable::Packable; +use packable::{Packable, PackableExt}; +use super::storage_score_offset_output; use crate::types::{ block::{ address::Address, @@ -17,7 +18,7 @@ use crate::types::{ NativeTokens, Output, OutputBuilderAmount, OutputId, }, protocol::ProtocolParameters, - rent::{RentParameters, StorageCost}, + rent::{RentParameters, StorageScore}, semantic::{TransactionFailureReason, ValidationContext}, unlock::Unlock, Error, @@ -173,7 +174,7 @@ impl BasicOutputBuilder { output.amount = match self.amount { OutputBuilderAmount::Amount(amount) => amount, OutputBuilderAmount::MinimumStorageDeposit(rent_params) => { - Output::Basic(output.clone()).storage_cost(rent_params) + Output::Basic(output.clone()).rent_cost(rent_params) } }; @@ -324,6 +325,16 @@ impl BasicOutput { } } +impl StorageScore for BasicOutput { + fn score(&self, rent_params: RentParameters) -> u64 { + storage_score_offset_output(rent_params) + + self.packed_len() as u64 * rent_params.storage_score_factor_data() as u64 + + self.native_tokens().score(rent_params) + + self.unlock_conditions().score(rent_params) + + self.features().score(rent_params) + } +} + fn verify_unlock_conditions(unlock_conditions: &UnlockConditions) -> Result<(), Error> { if VERIFY { if unlock_conditions.address().is_none() { diff --git a/sdk/src/types/block/output/delegation.rs b/sdk/src/types/block/output/delegation.rs index 0e3c9970b1..17fb61d5cf 100644 --- a/sdk/src/types/block/output/delegation.rs +++ b/sdk/src/types/block/output/delegation.rs @@ -7,7 +7,7 @@ use packable::{ error::{UnpackError, UnpackErrorExt}, packer::Packer, unpacker::Unpacker, - Packable, + Packable, PackableExt, }; use crate::types::{ @@ -22,7 +22,7 @@ use crate::types::{ OutputBuilderAmount, OutputId, StateTransitionError, StateTransitionVerifier, }, protocol::ProtocolParameters, - rent::{RentParameters, StorageCost}, + rent::{RentParameters, StorageScore}, semantic::{TransactionFailureReason, ValidationContext}, slot::EpochIndex, unlock::Unlock, @@ -31,6 +31,8 @@ use crate::types::{ ValidationParams, }; +use super::storage_score_offset_output; + impl_id!(pub DelegationId, 32, "Unique identifier of the Delegation Output, which is the BLAKE2b-256 hash of the Output ID that created it."); #[cfg(feature = "serde")] @@ -196,7 +198,7 @@ impl DelegationOutputBuilder { output.amount = match self.amount { OutputBuilderAmount::Amount(amount) => amount, OutputBuilderAmount::MinimumStorageDeposit(rent_params) => { - Output::Delegation(output.clone()).storage_cost(rent_params) + Output::Delegation(output.clone()).rent_cost(rent_params) } }; @@ -456,6 +458,15 @@ impl Packable for DelegationOutput { } } +impl StorageScore for DelegationOutput { + fn score(&self, rent_params: RentParameters) -> u64 { + storage_score_offset_output(rent_params) + + rent_params.storage_score_offset_delegation() + + self.packed_len() as u64 * rent_params.storage_score_factor_data() as u64 + + self.unlock_conditions().score(rent_params) + } +} + fn verify_unlock_conditions(unlock_conditions: &UnlockConditions) -> Result<(), Error> { if VERIFY { if unlock_conditions.address().is_none() { diff --git a/sdk/src/types/block/output/feature/block_issuer.rs b/sdk/src/types/block/output/feature/block_issuer.rs index 1a561e4bd5..941b161a9a 100644 --- a/sdk/src/types/block/output/feature/block_issuer.rs +++ b/sdk/src/types/block/output/feature/block_issuer.rs @@ -17,7 +17,7 @@ use packable::{ }; use crate::types::block::{ - rent::{RentParameters, StorageCost}, + rent::{RentParameters, StorageScore}, slot::SlotIndex, Error, }; @@ -61,12 +61,7 @@ impl BlockIssuerKey { } } -impl StorageCost for BlockIssuerKey { - fn offset_score(&self, rent_params: RentParameters) -> u64 { - // TODO: ?? - 0 - } - +impl StorageScore for BlockIssuerKey { fn score(&self, rent_params: RentParameters) -> u64 { match self { Self::Ed25519(key) => key.score(rent_params), @@ -116,7 +111,7 @@ impl Packable for Ed25519BlockIssuerKey { } } -impl StorageCost for Ed25519BlockIssuerKey { +impl StorageScore for Ed25519BlockIssuerKey { fn score(&self, rent_params: RentParameters) -> u64 { rent_params.storage_score_offset_ed25519_block_issuer_key() } @@ -204,7 +199,7 @@ impl BlockIssuerKeys { } } -impl StorageCost for BlockIssuerKeys { +impl StorageScore for BlockIssuerKeys { fn score(&self, rent_params: RentParameters) -> u64 { (*self).iter().map(|key| key.score(rent_params)).sum() } diff --git a/sdk/src/types/block/output/feature/issuer.rs b/sdk/src/types/block/output/feature/issuer.rs index 7e7b2b1d78..a966736e5e 100644 --- a/sdk/src/types/block/output/feature/issuer.rs +++ b/sdk/src/types/block/output/feature/issuer.rs @@ -3,7 +3,10 @@ use derive_more::From; -use crate::types::block::address::Address; +use crate::types::block::{ + address::Address, + rent::{RentParameters, StorageScore}, +}; /// Identifies the validated issuer of the UTXO state machine. #[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, From, packable::Packable)] @@ -26,6 +29,13 @@ impl IssuerFeature { } } +impl StorageScore for IssuerFeature { + fn score(&self, rent_params: RentParameters) -> u64 { + // self.0.score(rent_params) + todo!() + } +} + #[cfg(feature = "serde")] pub(crate) mod dto { use serde::{Deserialize, Serialize}; diff --git a/sdk/src/types/block/output/feature/mod.rs b/sdk/src/types/block/output/feature/mod.rs index 33904fe62e..16acf0340b 100644 --- a/sdk/src/types/block/output/feature/mod.rs +++ b/sdk/src/types/block/output/feature/mod.rs @@ -28,7 +28,7 @@ pub use self::{ staking::StakingFeature, tag::TagFeature, }; -use crate::types::block::{create_bitflags, Error}; +use crate::types::block::{create_bitflags, Error, rent::StorageScore}; /// #[derive(Clone, Eq, PartialEq, Hash, From, Packable)] @@ -313,6 +313,12 @@ impl Features { } } +impl StorageScore for Features { + fn score(&self, rent_params: crate::types::block::rent::RentParameters) -> u64 { + todo!() + } +} + #[inline] fn verify_unique_sorted(features: &[Feature], _: &()) -> Result<(), Error> { if VERIFY && !is_unique_sorted(features.iter().map(Feature::kind)) { diff --git a/sdk/src/types/block/output/foundry.rs b/sdk/src/types/block/output/foundry.rs index 6da68682cf..e83aa3c15e 100644 --- a/sdk/src/types/block/output/foundry.rs +++ b/sdk/src/types/block/output/foundry.rs @@ -8,7 +8,7 @@ use packable::{ error::{UnpackError, UnpackErrorExt}, packer::{Packer, SlicePacker}, unpacker::Unpacker, - Packable, + Packable, PackableExt, }; use primitive_types::U256; @@ -26,7 +26,7 @@ use crate::types::{ TokenId, TokenScheme, }, protocol::ProtocolParameters, - rent::{RentParameters, StorageCost}, + rent::{RentParameters, StorageScore}, semantic::{TransactionFailureReason, ValidationContext}, unlock::Unlock, Error, @@ -34,6 +34,8 @@ use crate::types::{ ValidationParams, }; +use super::storage_score_offset_output; + impl_id!(pub FoundryId, 38, "Defines the unique identifier of a foundry."); #[cfg(feature = "serde")] @@ -284,7 +286,7 @@ impl FoundryOutputBuilder { output.amount = match self.amount { OutputBuilderAmount::Amount(amount) => amount, OutputBuilderAmount::MinimumStorageDeposit(rent_params) => { - Output::Foundry(output.clone()).storage_cost(rent_params) + Output::Foundry(output.clone()).rent_cost(rent_params) } }; @@ -658,6 +660,18 @@ impl Packable for FoundryOutput { } } +impl StorageScore for FoundryOutput { + fn score(&self, rent_params: RentParameters) -> u64 { + storage_score_offset_output(rent_params) + + self.packed_len() as u64 * rent_params.storage_score_factor_data() as u64 + + self.native_tokens().score(rent_params) + + self.token_scheme().score(rent_params) + + self.unlock_conditions().score(rent_params) + + self.features().score(rent_params) + + self.immutable_features().score(rent_params) + } +} + fn verify_unlock_conditions(unlock_conditions: &UnlockConditions) -> Result<(), Error> { if unlock_conditions.immutable_account_address().is_none() { Err(Error::MissingAddressUnlockCondition) diff --git a/sdk/src/types/block/output/mod.rs b/sdk/src/types/block/output/mod.rs index e4f142110e..b9d982f4c1 100644 --- a/sdk/src/types/block/output/mod.rs +++ b/sdk/src/types/block/output/mod.rs @@ -59,7 +59,7 @@ pub use self::{ use super::{ address::Ed25519Address, protocol::ProtocolParameters, - rent::{RentParameters, StorageCost}, + rent::{RentParameters, StorageScore}, BlockId, }; use crate::types::block::{address::Address, semantic::ValidationContext, slot::SlotIndex, Error}; @@ -387,7 +387,7 @@ impl Output { /// If there is a [`StorageDepositReturnUnlockCondition`](unlock_condition::StorageDepositReturnUnlockCondition), /// its amount is also checked. pub fn verify_storage_deposit(&self, rent_params: RentParameters, token_supply: u64) -> Result<(), Error> { - let required_output_amount = self.storage_cost(rent_params); + let required_output_amount = self.rent_cost(rent_params); if self.amount() < required_output_amount { return Err(Error::InsufficientStorageDepositAmount { @@ -513,16 +513,24 @@ fn minimum_storage_deposit(address: &Address, rent_parameters: RentParameters, t .amount() } -impl StorageCost for Output { - fn offset_score(&self, rent_params: RentParameters) -> u64 { - // included output id, block id, and slot booked data size - rent_params.storage_score_offset_output() - + (size_of::() as u64 + size_of::() as u64 + size_of::() as u64) - * rent_params.storage_score_factor_data() as u64 - } +fn storage_score_offset_output(rent_params: RentParameters) -> u64 { + // included output id, block id, and slot booked data size + rent_params.storage_score_offset_output() + + rent_params.storage_score_factor_data() as u64 + * (size_of::() as u64 + size_of::() as u64 + size_of::() as u64) +} +impl StorageScore for Output { fn score(&self, rent_params: RentParameters) -> u64 { - self.packed_len() as u64 * rent_params.storage_score_factor_data() as u64 + // +1 score for the output kind + rent_params.storage_score_factor_data() as u64 * size_of::() as u64 + + match self { + Self::Basic(basic) => basic.score(rent_params), + Self::Account(account) => account.score(rent_params), + Self::Foundry(foundry) => foundry.score(rent_params), + Self::Nft(nft) => nft.score(rent_params), + Self::Delegation(delegation) => delegation.score(rent_params), + } } } @@ -573,7 +581,7 @@ impl MinimumStorageDepositBasicOutput { Ok(self .builder .finish_output(self.token_supply)? - .storage_cost(self.rent_params)) + .rent_cost(self.rent_params)) } } #[cfg(feature = "serde")] diff --git a/sdk/src/types/block/output/native_token.rs b/sdk/src/types/block/output/native_token.rs index d3806f7523..5fbd795139 100644 --- a/sdk/src/types/block/output/native_token.rs +++ b/sdk/src/types/block/output/native_token.rs @@ -12,7 +12,7 @@ use iterator_sorted::is_unique_sorted; use packable::{bounded::BoundedU8, prefix::BoxedSlicePrefix, Packable}; use primitive_types::U256; -use crate::types::block::{output::foundry::FoundryId, Error}; +use crate::types::block::{output::foundry::FoundryId, Error, rent::StorageScore}; impl_id!(pub TokenId, 38, "Unique identifiers of native tokens. The TokenId of native tokens minted by a specific foundry is the same as the FoundryId."); @@ -247,6 +247,12 @@ impl NativeTokens { } } +impl StorageScore for NativeTokens { + fn score(&self, rent_params: crate::types::block::rent::RentParameters) -> u64 { + todo!() + } +} + #[inline] fn verify_unique_sorted(native_tokens: &[NativeToken], _: &()) -> Result<(), Error> { if VERIFY && !is_unique_sorted(native_tokens.iter().map(NativeToken::token_id)) { diff --git a/sdk/src/types/block/output/nft.rs b/sdk/src/types/block/output/nft.rs index 2bf755dbe0..9ac1154e48 100644 --- a/sdk/src/types/block/output/nft.rs +++ b/sdk/src/types/block/output/nft.rs @@ -7,7 +7,7 @@ use packable::{ error::{UnpackError, UnpackErrorExt}, packer::Packer, unpacker::Unpacker, - Packable, + Packable, PackableExt, }; use crate::types::{ @@ -20,7 +20,7 @@ use crate::types::{ }, verify_output_amount_min, verify_output_amount_packable, verify_output_amount_supply, ChainId, NativeToken, NativeTokens, Output, OutputBuilderAmount, OutputId, RentParameters, StateTransitionError, - StateTransitionVerifier, StorageCost, + StateTransitionVerifier, StorageScore, }, protocol::ProtocolParameters, semantic::{TransactionFailureReason, ValidationContext}, @@ -30,6 +30,8 @@ use crate::types::{ ValidationParams, }; +use super::storage_score_offset_output; + impl_id!(pub NftId, 32, "Unique identifier of an NFT, which is the BLAKE2b-256 hash of the Output ID that created it."); #[cfg(feature = "serde")] @@ -244,7 +246,7 @@ impl NftOutputBuilder { output.amount = match self.amount { OutputBuilderAmount::Amount(amount) => amount, OutputBuilderAmount::MinimumStorageDeposit(rent_params) => { - Output::Nft(output.clone()).storage_cost(rent_params) + Output::Nft(output.clone()).rent_cost(rent_params) } }; @@ -520,6 +522,17 @@ impl Packable for NftOutput { } } +impl StorageScore for NftOutput { + fn score(&self, rent_params: RentParameters) -> u64 { + storage_score_offset_output(rent_params) + + self.packed_len() as u64 * rent_params.storage_score_factor_data() as u64 + + self.native_tokens().score(rent_params) + + self.unlock_conditions().score(rent_params) + + self.features().score(rent_params) + + self.immutable_features().score(rent_params) + } +} + fn verify_unlock_conditions(unlock_conditions: &UnlockConditions, nft_id: &NftId) -> Result<(), Error> { if let Some(unlock_condition) = unlock_conditions.address() { if let Address::Nft(nft_address) = unlock_condition.address() { diff --git a/sdk/src/types/block/output/token_scheme/mod.rs b/sdk/src/types/block/output/token_scheme/mod.rs index 3ae41b98d4..42b428dbc0 100644 --- a/sdk/src/types/block/output/token_scheme/mod.rs +++ b/sdk/src/types/block/output/token_scheme/mod.rs @@ -4,7 +4,7 @@ mod simple; pub use self::simple::SimpleTokenScheme; -use crate::types::block::Error; +use crate::types::block::{Error, rent::{StorageScore, RentParameters}}; /// #[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Hash, derive_more::From, packable::Packable)] @@ -45,3 +45,11 @@ impl TokenScheme { scheme } } + +impl StorageScore for TokenScheme { + fn score(&self, rent_params: RentParameters) -> u64 { + match self { + Self::Simple(simple) => simple.score(rent_params) + } + } +} diff --git a/sdk/src/types/block/output/token_scheme/simple.rs b/sdk/src/types/block/output/token_scheme/simple.rs index c8e4fa8599..34131f2127 100644 --- a/sdk/src/types/block/output/token_scheme/simple.rs +++ b/sdk/src/types/block/output/token_scheme/simple.rs @@ -9,7 +9,7 @@ use packable::{ }; use primitive_types::U256; -use crate::types::block::Error; +use crate::types::block::{Error, rent::{StorageScore, RentParameters}}; /// #[derive(Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)] @@ -103,6 +103,12 @@ impl Packable for SimpleTokenScheme { } } +impl StorageScore for SimpleTokenScheme { + fn score(&self, rent_params: RentParameters) -> u64 { + 0 + } +} + #[inline] fn verify_supply(minted_tokens: &U256, melted_tokens: &U256, maximum_supply: &U256) -> Result<(), Error> { if maximum_supply.is_zero() || melted_tokens > minted_tokens || minted_tokens - melted_tokens > *maximum_supply { diff --git a/sdk/src/types/block/output/unlock_condition/mod.rs b/sdk/src/types/block/output/unlock_condition/mod.rs index de473e337f..3e89809900 100644 --- a/sdk/src/types/block/output/unlock_condition/mod.rs +++ b/sdk/src/types/block/output/unlock_condition/mod.rs @@ -30,7 +30,7 @@ pub use self::{ state_controller_address::StateControllerAddressUnlockCondition, storage_deposit_return::StorageDepositReturnUnlockCondition, timelock::TimelockUnlockCondition, }; -use crate::types::block::{address::Address, create_bitflags, protocol::ProtocolParameters, slot::SlotIndex, Error}; +use crate::types::block::{address::Address, create_bitflags, protocol::ProtocolParameters, slot::SlotIndex, Error, rent::StorageScore}; /// #[derive(Clone, Eq, PartialEq, Hash, From)] @@ -444,6 +444,12 @@ impl UnlockConditions { } } +impl StorageScore for UnlockConditions { + fn score(&self, rent_params: crate::types::block::rent::RentParameters) -> u64 { + todo!() + } +} + #[inline] fn verify_unique_sorted(unlock_conditions: &[UnlockCondition]) -> Result<(), Error> { if VERIFY && !is_unique_sorted(unlock_conditions.iter().map(UnlockCondition::kind)) { diff --git a/sdk/src/types/block/rent.rs b/sdk/src/types/block/rent.rs index 1a48a92761..4608ad809f 100644 --- a/sdk/src/types/block/rent.rs +++ b/sdk/src/types/block/rent.rs @@ -172,26 +172,18 @@ impl RentParameters { } /// A trait to facilitate the rent cost computation for block outputs, which is central to dust protection. -pub trait StorageCost { - /// Computes the offset storage score given a [`RentParameters`]. Defaults to 0. - fn offset_score(&self, rent_params: RentParameters) -> u64 { - 0 - } - +pub trait StorageScore { /// Computes the storage score given a [`RentParameters`]. Different fields in a type lead to different storage /// requirements for the ledger state. fn score(&self, rent_params: RentParameters) -> u64; /// Computes the storage cost given a [`RentParameters`]. - fn storage_cost(&self, rent_params: RentParameters) -> u64 { - rent_params.storage_cost as u64 * (self.offset_score(rent_params) + self.score(rent_params)) + fn rent_cost(&self, rent_params: RentParameters) -> u64 { + rent_params.storage_cost as u64 * self.score(rent_params) } } -impl StorageCost for [T; N] { - fn offset_score(&self, rent_params: RentParameters) -> u64 { - self.get(0).expect("zero sized array").score(rent_params) - } +impl StorageScore for [T; N] { fn score(&self, rent_params: RentParameters) -> u64 { self.iter().map(|elem| elem.score(rent_params)).sum() } diff --git a/sdk/src/wallet/account/operations/balance.rs b/sdk/src/wallet/account/operations/balance.rs index 5b622c01d1..77f6fb02b7 100644 --- a/sdk/src/wallet/account/operations/balance.rs +++ b/sdk/src/wallet/account/operations/balance.rs @@ -8,7 +8,7 @@ use crate::{ types::block::{ address::Bech32Address, output::{unlock_condition::UnlockCondition, FoundryId, NativeTokensBuilder, Output}, - rent::StorageCost, + rent::StorageScore, ConvertTo, }, wallet::{ @@ -89,7 +89,7 @@ where } let output = &data.output; - let rent = output.storage_cost(rent_params); + let rent = output.rent_cost(rent_params); // Add account and foundry outputs here because they can't have a // [`StorageDepositReturnUnlockCondition`] or time related unlock conditions diff --git a/sdk/src/wallet/account/operations/transaction/prepare_output.rs b/sdk/src/wallet/account/operations/transaction/prepare_output.rs index bb6af46d4e..5d25537914 100644 --- a/sdk/src/wallet/account/operations/transaction/prepare_output.rs +++ b/sdk/src/wallet/account/operations/transaction/prepare_output.rs @@ -16,7 +16,7 @@ use crate::{ BasicOutputBuilder, MinimumStorageDepositBasicOutput, NativeToken, NftId, NftOutputBuilder, Output, UnlockCondition, }, - rent::{RentParameters, StorageCost}, + rent::{RentParameters, StorageScore}, slot::SlotIndex, Error, }, @@ -115,7 +115,7 @@ where let min_storage_deposit_basic_output = MinimumStorageDepositBasicOutput::new(rent_params, token_supply).finish()?; - let min_required_storage_deposit = first_output.storage_cost(rent_params); + let min_required_storage_deposit = first_output.rent_cost(rent_params); if params.amount > min_required_storage_deposit { second_output_builder = second_output_builder.with_amount(params.amount); @@ -177,7 +177,7 @@ where // If we're sending an existing NFT, its minimum required storage deposit is not part of the available base_coin // balance, so we add it here if let Some(existing_nft_output_data) = existing_nft_output_data { - available_base_coin += existing_nft_output_data.output.storage_cost(rent_params); + available_base_coin += existing_nft_output_data.output.rent_cost(rent_params); } if final_amount > available_base_coin { diff --git a/sdk/tests/types/output/account.rs b/sdk/tests/types/output/account.rs index da57929d40..277b04f3e1 100644 --- a/sdk/tests/types/output/account.rs +++ b/sdk/tests/types/output/account.rs @@ -14,7 +14,7 @@ use iota_sdk::types::{ rand_state_controller_address_unlock_condition_different_from, }, }, - rent::StorageCost, + rent::StorageScore, }, ValidationParams, }; @@ -84,7 +84,7 @@ fn builder() { assert_eq!( output.amount(), - Output::Account(output.clone()).storage_cost(protocol_parameters.rent_parameters()) + Output::Account(output.clone()).rent_cost(protocol_parameters.rent_parameters()) ); assert_eq!(output.features().metadata(), Some(&metadata)); assert_eq!(output.features().sender(), Some(&sender_1)); diff --git a/sdk/tests/types/output/basic.rs b/sdk/tests/types/output/basic.rs index 7511b44410..5f219c3851 100644 --- a/sdk/tests/types/output/basic.rs +++ b/sdk/tests/types/output/basic.rs @@ -13,7 +13,7 @@ use iota_sdk::types::{ unlock_condition::rand_address_unlock_condition, }, }, - rent::StorageCost, + rent::StorageScore, }, ValidationParams, }; @@ -59,7 +59,7 @@ fn builder() { assert_eq!( output.amount(), - Output::Basic(output.clone()).storage_cost(protocol_parameters.rent_parameters()) + Output::Basic(output.clone()).rent_cost(protocol_parameters.rent_parameters()) ); assert_eq!(output.features().metadata(), Some(&metadata)); assert_eq!(output.features().sender(), Some(&sender_1)); diff --git a/sdk/tests/types/output/foundry.rs b/sdk/tests/types/output/foundry.rs index e5e5bba55b..80703ecf6c 100644 --- a/sdk/tests/types/output/foundry.rs +++ b/sdk/tests/types/output/foundry.rs @@ -11,7 +11,7 @@ use iota_sdk::types::block::{ address::rand_account_address, output::{feature::rand_metadata_feature, rand_foundry_output, rand_token_scheme}, }, - rent::StorageCost, + rent::StorageScore, }; use packable::PackableExt; @@ -59,7 +59,7 @@ fn builder() { assert_eq!( output.amount(), - Output::Foundry(output).storage_cost(protocol_parameters.rent_parameters()) + Output::Foundry(output).rent_cost(protocol_parameters.rent_parameters()) ); } diff --git a/sdk/tests/types/output/nft.rs b/sdk/tests/types/output/nft.rs index 8c742cc4ae..da0c1867d0 100644 --- a/sdk/tests/types/output/nft.rs +++ b/sdk/tests/types/output/nft.rs @@ -12,7 +12,7 @@ use iota_sdk::types::block::{ unlock_condition::rand_address_unlock_condition, }, }, - rent::StorageCost, + rent::StorageScore, }; use packable::PackableExt; @@ -60,7 +60,7 @@ fn builder() { assert_eq!( output.amount(), - Output::Nft(output).storage_cost(protocol_parameters.rent_parameters()) + Output::Nft(output).rent_cost(protocol_parameters.rent_parameters()) ); } diff --git a/sdk/tests/wallet/output_preparation.rs b/sdk/tests/wallet/output_preparation.rs index dfe2bc4afa..ceb92acd42 100644 --- a/sdk/tests/wallet/output_preparation.rs +++ b/sdk/tests/wallet/output_preparation.rs @@ -7,7 +7,7 @@ use iota_sdk::{ types::block::{ address::{Address, Bech32Address, ToBech32Ext}, output::{MinimumStorageDepositBasicOutput, NativeToken, NftId, Output, TokenId}, - rent::StorageCost, + rent::StorageScore, slot::SlotIndex, }, wallet::{ @@ -410,7 +410,7 @@ async fn output_preparation() -> Result<()> { ) .await?; let rent_params = wallet.client().get_rent_parameters().await?; - let minimum_storage_deposit = output.storage_cost(rent_params); + let minimum_storage_deposit = output.rent_cost(rent_params); assert_eq!(output.amount(), minimum_storage_deposit); assert_eq!(output.amount(), 187900); let sdr = output.unlock_conditions().unwrap().storage_deposit_return().unwrap(); @@ -850,7 +850,7 @@ async fn prepare_existing_nft_output_gift() -> Result<()> { .clone(); let rent_params = wallet.client().get_rent_parameters().await?; - let minimum_storage_deposit = Output::Nft(nft.clone()).storage_cost(rent_params); + let minimum_storage_deposit = Output::Nft(nft.clone()).rent_cost(rent_params); assert_eq!(nft.amount(), minimum_storage_deposit); assert_eq!(nft.amount(), 52300); From 824b5e095a7b6512605616af7bc3710f1f8aae9a Mon Sep 17 00:00:00 2001 From: Alexander Schmidt Date: Fri, 6 Oct 2023 18:03:49 +0200 Subject: [PATCH 04/10] almost done --- bindings/core/src/method_handler/client.rs | 15 +++-- bindings/core/src/method_handler/utils.rs | 2 +- cli/src/command/account.rs | 4 +- .../client/output/build_account_output.rs | 4 +- .../client/output/build_nft_output.rs | 4 +- .../how_tos/account/state_transition.rs | 4 +- sdk/examples/how_tos/outputs/features.rs | 4 +- .../how_tos/outputs/unlock_conditions.rs | 8 +-- .../input_selection/remainder.rs | 5 +- .../input_selection/requirement/amount.rs | 4 +- sdk/src/types/block/address/account.rs | 12 +++- sdk/src/types/block/address/ed25519.rs | 16 ++++- sdk/src/types/block/address/mod.rs | 18 ++---- sdk/src/types/block/address/nft.rs | 12 +++- sdk/src/types/block/output/account.rs | 60 ++++++++++++------- sdk/src/types/block/output/basic.rs | 48 ++++++++------- sdk/src/types/block/output/delegation.rs | 35 ++++++----- .../block/output/feature/block_issuer.rs | 20 ++++--- sdk/src/types/block/output/feature/issuer.rs | 7 +-- sdk/src/types/block/output/feature/mod.rs | 23 ++++++- sdk/src/types/block/output/foundry.rs | 43 +++++++------ sdk/src/types/block/output/mod.rs | 42 ++++++------- sdk/src/types/block/output/native_token.rs | 16 ++++- sdk/src/types/block/output/nft.rs | 44 +++++++------- .../types/block/output/token_scheme/mod.rs | 9 ++- .../types/block/output/token_scheme/simple.rs | 7 ++- .../block/output/unlock_condition/mod.rs | 33 ++++++---- .../payload/transaction/essence/regular.rs | 3 +- sdk/src/types/block/rent.rs | 52 ++++++++++++---- sdk/src/wallet/account/operations/balance.rs | 6 +- .../account/operations/output_claiming.rs | 9 +-- .../transaction/high_level/create_account.rs | 4 +- .../high_level/minting/create_native_token.rs | 5 +- .../high_level/minting/mint_nfts.rs | 5 +- .../operations/transaction/high_level/send.rs | 7 ++- .../high_level/send_native_tokens.rs | 5 +- .../account/operations/transaction/mod.rs | 2 +- .../operations/transaction/prepare_output.rs | 28 ++++----- .../transaction/prepare_transaction.rs | 4 +- .../client/input_selection/account_outputs.rs | 52 ++++++++-------- .../client/input_selection/nft_outputs.rs | 4 +- sdk/tests/types/output/account.rs | 4 +- sdk/tests/types/output/basic.rs | 4 +- sdk/tests/types/output/foundry.rs | 4 +- sdk/tests/types/output/nft.rs | 4 +- sdk/tests/wallet/claim_outputs.rs | 10 ++-- sdk/tests/wallet/output_preparation.rs | 28 ++++----- 47 files changed, 441 insertions(+), 298 deletions(-) diff --git a/bindings/core/src/method_handler/client.rs b/bindings/core/src/method_handler/client.rs index e49965ea7b..89be3ec625 100644 --- a/bindings/core/src/method_handler/client.rs +++ b/bindings/core/src/method_handler/client.rs @@ -12,7 +12,7 @@ use iota_sdk::{ dto::OutputDto, AccountOutput, BasicOutput, FoundryOutput, NftOutput, Output, OutputBuilderAmount, }, payload::Payload, - rent::StorageScore, + rent::{RentStructure, StorageScore}, BlockWrapper, BlockWrapperDto, }, TryFromDto, @@ -72,7 +72,7 @@ pub(crate) async fn call_client_method_internal(client: &Client, method: ClientM if let Some(amount) = amount { OutputBuilderAmount::Amount(amount) } else { - OutputBuilderAmount::MinimumStorageDeposit(client.get_rent_parameters().await?) + OutputBuilderAmount::MinimumStorageDeposit(client.get_rent_parameters().await?.into()) }, mana, native_tokens, @@ -99,7 +99,7 @@ pub(crate) async fn call_client_method_internal(client: &Client, method: ClientM if let Some(amount) = amount { OutputBuilderAmount::Amount(amount) } else { - OutputBuilderAmount::MinimumStorageDeposit(client.get_rent_parameters().await?) + OutputBuilderAmount::MinimumStorageDeposit(client.get_rent_parameters().await?.into()) }, mana, native_tokens, @@ -123,7 +123,7 @@ pub(crate) async fn call_client_method_internal(client: &Client, method: ClientM if let Some(amount) = amount { OutputBuilderAmount::Amount(amount) } else { - OutputBuilderAmount::MinimumStorageDeposit(client.get_rent_parameters().await?) + OutputBuilderAmount::MinimumStorageDeposit(client.get_rent_parameters().await?.into()) }, native_tokens, serial_number, @@ -149,7 +149,7 @@ pub(crate) async fn call_client_method_internal(client: &Client, method: ClientM if let Some(amount) = amount { OutputBuilderAmount::Amount(amount) } else { - OutputBuilderAmount::MinimumStorageDeposit(client.get_rent_parameters().await?) + OutputBuilderAmount::MinimumStorageDeposit(client.get_rent_parameters().await?.into()) }, mana, native_tokens, @@ -296,9 +296,8 @@ pub(crate) async fn call_client_method_internal(client: &Client, method: ClientM } ClientMethod::MinimumRequiredStorageDeposit { output } => { let output = Output::try_from_dto_with_params(output, client.get_token_supply().await?)?; - let rent_params = client.get_rent_parameters().await?; - - let minimum_storage_deposit = output.rent_cost(rent_params); + let rent_struct = client.get_rent_parameters().await?.into(); + let minimum_storage_deposit = output.rent_cost(rent_struct); Response::MinimumRequiredStorageDeposit(minimum_storage_deposit.to_string()) } diff --git a/bindings/core/src/method_handler/utils.rs b/bindings/core/src/method_handler/utils.rs index 5668e7399f..0ee053e16b 100644 --- a/bindings/core/src/method_handler/utils.rs +++ b/bindings/core/src/method_handler/utils.rs @@ -81,7 +81,7 @@ pub(crate) fn call_utils_method_internal(method: UtilsMethod) -> Result { let out = Output::try_from_dto(output)?; - Response::MinimumRequiredStorageDeposit(out.rent_cost(rent).to_string()) + Response::MinimumRequiredStorageDeposit(out.rent_cost(rent.into()).to_string()) } UtilsMethod::VerifyMnemonic { mnemonic } => { let mnemonic = Mnemonic::from(mnemonic); diff --git a/cli/src/command/account.rs b/cli/src/command/account.rs index c2ca40a0ef..06f70dee86 100644 --- a/cli/src/command/account.rs +++ b/cli/src/command/account.rs @@ -721,12 +721,12 @@ pub async fn send_native_token_command( let address = address.convert()?; let transaction = if gift_storage_deposit.unwrap_or(false) { // Send native tokens together with the required storage deposit - let rent_params = account.client().get_rent_parameters().await?; + let rent_struct = account.client().get_rent_parameters().await?.into(); let token_supply = account.client().get_token_supply().await?; account.client().bech32_hrp_matches(address.hrp()).await?; - let outputs = [BasicOutputBuilder::new_with_minimum_storage_deposit(rent_params) + let outputs = [BasicOutputBuilder::new_with_minimum_storage_deposit(rent_struct) .add_unlock_condition(AddressUnlockCondition::new(address)) .with_native_tokens([NativeToken::new( TokenId::from_str(&token_id)?, diff --git a/sdk/examples/client/output/build_account_output.rs b/sdk/examples/client/output/build_account_output.rs index c8c5fee712..986f65e519 100644 --- a/sdk/examples/client/output/build_account_output.rs +++ b/sdk/examples/client/output/build_account_output.rs @@ -35,7 +35,7 @@ async fn main() -> Result<()> { .await?; let token_supply = client.get_token_supply().await?; - let rent_params = client.get_rent_parameters().await?; + let rent_struct = client.get_rent_parameters().await?.into(); let address = std::env::args() .nth(1) @@ -43,7 +43,7 @@ async fn main() -> Result<()> { let address = Address::try_from_bech32(address)?; // Account id needs to be null the first time - let account_output = AccountOutputBuilder::new_with_minimum_storage_deposit(rent_params, AccountId::null()) + let account_output = AccountOutputBuilder::new_with_minimum_storage_deposit(rent_struct, AccountId::null()) .with_state_metadata(metadata) .add_feature(SenderFeature::new(address)) .add_feature(MetadataFeature::new(metadata)?) diff --git a/sdk/examples/client/output/build_nft_output.rs b/sdk/examples/client/output/build_nft_output.rs index 5c9cf7bc0e..b2a86f1c3b 100644 --- a/sdk/examples/client/output/build_nft_output.rs +++ b/sdk/examples/client/output/build_nft_output.rs @@ -35,7 +35,7 @@ async fn main() -> Result<()> { .await?; let token_supply = client.get_token_supply().await?; - let rent_params = client.get_rent_parameters().await?; + let rent_struct = client.get_rent_parameters().await?.into(); let address = std::env::args() .nth(1) @@ -56,7 +56,7 @@ async fn main() -> Result<()> { .to_string(); // NftId needs to be null the first time - let nft_output = NftOutputBuilder::new_with_minimum_storage_deposit(rent_params, NftId::null()) + let nft_output = NftOutputBuilder::new_with_minimum_storage_deposit(rent_struct, NftId::null()) .add_unlock_condition(AddressUnlockCondition::new(address)) .add_feature(SenderFeature::new(address)) .add_feature(MetadataFeature::new(MUTABLE_METADATA)?) diff --git a/sdk/examples/how_tos/account/state_transition.rs b/sdk/examples/how_tos/account/state_transition.rs index 2d945ddead..bbc201f5fc 100644 --- a/sdk/examples/how_tos/account/state_transition.rs +++ b/sdk/examples/how_tos/account/state_transition.rs @@ -51,13 +51,13 @@ async fn main() -> Result<()> { ); let token_supply = account.client().get_token_supply().await?; - let rent_params = account.client().get_rent_parameters().await?; + let rent_struct = account.client().get_rent_parameters().await?.into(); let account_output = account_output_data.output.as_account(); let updated_account_output = AccountOutputBuilder::from(account_output) // Minimum required storage deposit will change if the new metadata has a different size, so we will update // the amount - .with_minimum_storage_deposit(rent_params) + .with_minimum_storage_deposit(rent_struct) .with_state_metadata(NEW_STATE_METADATA.as_bytes().to_vec()) .with_state_index(account_output.state_index() + 1) .finish_output(token_supply)?; diff --git a/sdk/examples/how_tos/outputs/features.rs b/sdk/examples/how_tos/outputs/features.rs index 71d45c5d60..f80599dca0 100644 --- a/sdk/examples/how_tos/outputs/features.rs +++ b/sdk/examples/how_tos/outputs/features.rs @@ -32,11 +32,11 @@ async fn main() -> Result<()> { let client = Client::builder().with_node(&node_url)?.finish().await?; let token_supply = client.get_token_supply().await?; - let rent_params = client.get_rent_parameters().await?; + let rent_struct = client.get_rent_parameters().await?.into(); let address = Address::try_from_bech32("rms1qpllaj0pyveqfkwxmnngz2c488hfdtmfrj3wfkgxtk4gtyrax0jaxzt70zy")?; - let nft_output_builder = NftOutputBuilder::new_with_minimum_storage_deposit(rent_params, NftId::null()) + let nft_output_builder = NftOutputBuilder::new_with_minimum_storage_deposit(rent_struct, NftId::null()) .add_unlock_condition(AddressUnlockCondition::new(address)); let outputs = [ diff --git a/sdk/examples/how_tos/outputs/unlock_conditions.rs b/sdk/examples/how_tos/outputs/unlock_conditions.rs index 7bd6723994..e5ee0cf8a3 100644 --- a/sdk/examples/how_tos/outputs/unlock_conditions.rs +++ b/sdk/examples/how_tos/outputs/unlock_conditions.rs @@ -35,17 +35,17 @@ async fn main() -> Result<()> { let client = Client::builder().with_node(&node_url)?.finish().await?; let token_supply = client.get_token_supply().await?; - let rent_params = client.get_rent_parameters().await?; + let rent_struct = client.get_rent_parameters().await?.into(); let address = Address::try_from_bech32("rms1qpllaj0pyveqfkwxmnngz2c488hfdtmfrj3wfkgxtk4gtyrax0jaxzt70zy")?; let account_address = Address::try_from_bech32("rms1pr59qm43mjtvhcajfmupqf23x29llam88yecn6pyul80rx099krmv2fnnux")?; let token_scheme = TokenScheme::Simple(SimpleTokenScheme::new(50, 0, 100)?); - let basic_output_builder = BasicOutputBuilder::new_with_minimum_storage_deposit(rent_params) + let basic_output_builder = BasicOutputBuilder::new_with_minimum_storage_deposit(rent_struct) .add_unlock_condition(AddressUnlockCondition::new(address)); - let account_output_builder = AccountOutputBuilder::new_with_minimum_storage_deposit(rent_params, AccountId::null()); - let foundry_output_builder = FoundryOutputBuilder::new_with_minimum_storage_deposit(rent_params, 1, token_scheme); + let account_output_builder = AccountOutputBuilder::new_with_minimum_storage_deposit(rent_struct, AccountId::null()); + let foundry_output_builder = FoundryOutputBuilder::new_with_minimum_storage_deposit(rent_struct, 1, token_scheme); let outputs = [ //// most simple output diff --git a/sdk/src/client/api/block_builder/input_selection/remainder.rs b/sdk/src/client/api/block_builder/input_selection/remainder.rs index 1eb84aca1b..194c881192 100644 --- a/sdk/src/client/api/block_builder/input_selection/remainder.rs +++ b/sdk/src/client/api/block_builder/input_selection/remainder.rs @@ -16,6 +16,7 @@ use crate::{ types::block::{ address::{Address, Ed25519Address}, output::{unlock_condition::AddressUnlockCondition, BasicOutputBuilder, NativeTokensBuilder, Output}, + rent::RentStructure, }, }; @@ -65,7 +66,7 @@ impl InputSelection { let native_tokens_remainder = native_tokens_diff.is_some(); let mut remainder_builder = - BasicOutputBuilder::new_with_minimum_storage_deposit(self.protocol_parameters.rent_parameters()) + BasicOutputBuilder::new_with_minimum_storage_deposit(self.protocol_parameters.rent_parameters().into()) .add_unlock_condition(AddressUnlockCondition::new(Address::from(Ed25519Address::from( [0; 32], )))); @@ -144,7 +145,7 @@ impl InputSelection { log::debug!("Created remainder output of {diff} for {remainder_address:?}"); remainder.verify_storage_deposit( - self.protocol_parameters.rent_parameters(), + self.protocol_parameters.rent_parameters().into(), self.protocol_parameters.token_supply(), )?; diff --git a/sdk/src/client/api/block_builder/input_selection/requirement/amount.rs b/sdk/src/client/api/block_builder/input_selection/requirement/amount.rs index da937b21c6..881c759936 100644 --- a/sdk/src/client/api/block_builder/input_selection/requirement/amount.rs +++ b/sdk/src/client/api/block_builder/input_selection/requirement/amount.rs @@ -13,7 +13,7 @@ use crate::{ unlock_condition::StorageDepositReturnUnlockCondition, AccountOutputBuilder, AccountTransition, FoundryOutputBuilder, NftOutputBuilder, Output, OutputId, }, - rent::StorageScore, + rent::{RentStructure, StorageScore}, slot::SlotIndex, }, }; @@ -241,7 +241,7 @@ impl InputSelection { for output in outputs { let diff = amount_selection.missing_amount(); let amount = output.amount(); - let rent = output.rent_cost(self.protocol_parameters.rent_parameters()); + let rent = output.rent_cost(self.protocol_parameters.rent_parameters().into()); let new_amount = if amount >= diff + rent { amount - diff } else { rent }; diff --git a/sdk/src/types/block/address/account.rs b/sdk/src/types/block/address/account.rs index 2406576371..e8b5c35b0d 100644 --- a/sdk/src/types/block/address/account.rs +++ b/sdk/src/types/block/address/account.rs @@ -5,7 +5,11 @@ use core::str::FromStr; use derive_more::{AsRef, Deref, From}; -use crate::types::block::{output::AccountId, Error}; +use crate::types::block::{ + output::AccountId, + rent::{RentStructure, StorageScore}, + Error, +}; /// An account address. #[derive(Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash, From, AsRef, Deref, packable::Packable)] @@ -57,6 +61,12 @@ impl core::fmt::Debug for AccountAddress { } } +impl StorageScore for AccountAddress { + fn score(&self, _rent_struct: RentStructure) -> u64 { + 0 + } +} + #[cfg(feature = "serde")] mod dto { use serde::{Deserialize, Serialize}; diff --git a/sdk/src/types/block/address/ed25519.rs b/sdk/src/types/block/address/ed25519.rs index 2adc90ed19..b63e070515 100644 --- a/sdk/src/types/block/address/ed25519.rs +++ b/sdk/src/types/block/address/ed25519.rs @@ -6,7 +6,10 @@ use core::str::FromStr; use crypto::signatures::ed25519::PublicKey; use derive_more::{AsRef, Deref, From}; -use crate::types::block::Error; +use crate::types::block::{ + rent::{RentStructure, StorageScore}, + Error, +}; /// An Ed25519 address. #[derive(Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash, From, AsRef, Deref, packable::Packable)] @@ -24,6 +27,11 @@ impl Ed25519Address { pub fn new(address: [u8; Self::LENGTH]) -> Self { Self::from(address) } + + /// Creates a dummy [`Ed25519Address`] used to calculate a storage score for implicit account addresses. + pub(crate) fn dummy() -> Self { + Self([0; Self::LENGTH]) + } } impl FromStr for Ed25519Address { @@ -46,6 +54,12 @@ impl core::fmt::Debug for Ed25519Address { } } +impl StorageScore for Ed25519Address { + fn score(&self, _rent_struct: RentStructure) -> u64 { + 0 + } +} + #[cfg(feature = "serde")] pub(crate) mod dto { use serde::{Deserialize, Serialize}; diff --git a/sdk/src/types/block/address/mod.rs b/sdk/src/types/block/address/mod.rs index ba72388413..d82e23b60e 100644 --- a/sdk/src/types/block/address/mod.rs +++ b/sdk/src/types/block/address/mod.rs @@ -215,19 +215,13 @@ impl From<&Self> for Address { } } -/// A trait to facilitate the rent cost computation for addresses, which is central to dust protection. -pub trait AddressStorageCost { - /// Computes the storage score of an address given a [`RentStructure`]. - fn storage_cost(&self, rent_structure: RentStructure) -> u64; -} - -impl AddressStorageCost for Address { - fn storage_cost(&self, rent_structure: RentStructure) -> u64 { +impl StorageScore for Address { + fn score(&self, rent_struct: RentStructure) -> u64 { match self { - Self::Account(_) | Self::Ed25519(_) | Self::Nft(_) => 0, - // TODO: implicit account address and restricted address - // Address::ImplicitAccountCreation(_) => - // rent_stucture.storage_score_offset_implicit_account_creation_address + Self::Account(account) => account.score(rent_struct), + Self::Ed25519(ed25519) => ed25519.score(rent_struct), + Self::Nft(nft) => nft.score(rent_struct), + // TODO: other address types once merged } } } diff --git a/sdk/src/types/block/address/nft.rs b/sdk/src/types/block/address/nft.rs index 93ca2ac0a8..10f622be7e 100644 --- a/sdk/src/types/block/address/nft.rs +++ b/sdk/src/types/block/address/nft.rs @@ -5,7 +5,11 @@ use core::str::FromStr; use derive_more::{AsRef, Deref, From}; -use crate::types::block::{output::NftId, Error}; +use crate::types::block::{ + output::NftId, + rent::{RentStructure, StorageScore}, + Error, +}; /// An NFT address. #[derive(Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash, From, AsRef, Deref, packable::Packable)] @@ -57,6 +61,12 @@ impl core::fmt::Debug for NftAddress { } } +impl StorageScore for NftAddress { + fn score(&self, _rent_struct: RentStructure) -> u64 { + 0 + } +} + #[cfg(feature = "serde")] pub(crate) mod dto { use serde::{Deserialize, Serialize}; diff --git a/sdk/src/types/block/output/account.rs b/sdk/src/types/block/output/account.rs index 9bff1abb0d..af3578f733 100644 --- a/sdk/src/types/block/output/account.rs +++ b/sdk/src/types/block/output/account.rs @@ -13,9 +13,14 @@ use packable::{ Packable, PackableExt, }; +use super::{ + feature::{BlockIssuerFeature, BlockIssuerKey, BlockIssuerKeys, Ed25519BlockIssuerKey}, + storage_score_offset_output, + unlock_condition::{GovernorAddressUnlockCondition, StateControllerAddressUnlockCondition}, +}; use crate::types::{ block::{ - address::{AccountAddress, Address}, + address::{AccountAddress, Address, Ed25519Address}, output::{ feature::{verify_allowed_features, Feature, FeatureFlags, Features}, unlock_condition::{ @@ -25,7 +30,7 @@ use crate::types::{ NativeTokens, Output, OutputBuilderAmount, OutputId, StateTransitionError, StateTransitionVerifier, }, protocol::ProtocolParameters, - rent::{RentParameters, StorageScore}, + rent::{RentParameters, RentStructure, StorageScore}, semantic::{TransactionFailureReason, ValidationContext}, unlock::Unlock, Error, @@ -33,8 +38,6 @@ use crate::types::{ ValidationParams, }; -use super::storage_score_offset_output; - impl_id!(pub AccountId, 32, "Unique identifier of an account, which is the BLAKE2b-256 hash of the Output ID that created it."); #[cfg(feature = "serde")] @@ -114,8 +117,8 @@ impl AccountOutputBuilder { /// Creates an [`AccountOutputBuilder`] with a provided rent structure. /// The amount will be set to the minimum storage deposit. - pub fn new_with_minimum_storage_deposit(rent_params: RentParameters, account_id: AccountId) -> Self { - Self::new(OutputBuilderAmount::MinimumStorageDeposit(rent_params), account_id) + pub fn new_with_minimum_storage_deposit(rent_struct: RentStructure, account_id: AccountId) -> Self { + Self::new(OutputBuilderAmount::MinimumStorageDeposit(rent_struct), account_id) } fn new(amount: OutputBuilderAmount, account_id: AccountId) -> Self { @@ -142,8 +145,8 @@ impl AccountOutputBuilder { /// Sets the amount to the minimum storage deposit. #[inline(always)] - pub fn with_minimum_storage_deposit(mut self, rent_params: RentParameters) -> Self { - self.amount = OutputBuilderAmount::MinimumStorageDeposit(rent_params); + pub fn with_minimum_storage_deposit(mut self, rent_struct: RentStructure) -> Self { + self.amount = OutputBuilderAmount::MinimumStorageDeposit(rent_struct); self } @@ -320,8 +323,8 @@ impl AccountOutputBuilder { output.amount = match self.amount { OutputBuilderAmount::Amount(amount) => amount, - OutputBuilderAmount::MinimumStorageDeposit(rent_params) => { - Output::Account(output.clone()).rent_cost(rent_params) + OutputBuilderAmount::MinimumStorageDeposit(rent_struct) => { + Output::Account(output.clone()).rent_cost(rent_struct) } }; @@ -415,10 +418,10 @@ impl AccountOutput { /// The amount will be set to the minimum storage deposit. #[inline(always)] pub fn build_with_minimum_storage_deposit( - rent_params: RentParameters, + rent_struct: RentStructure, account_id: AccountId, ) -> AccountOutputBuilder { - AccountOutputBuilder::new_with_minimum_storage_deposit(rent_params, account_id) + AccountOutputBuilder::new_with_minimum_storage_deposit(rent_struct, account_id) } /// @@ -618,6 +621,19 @@ impl AccountOutput { Ok(()) } + + /// Creates a dummy [`AccountOutput`] used to calculate a storage score for implicit account addresses. + pub(crate) fn dummy() -> Self { + // Unwrap: cannot fail for provided dummy data. + AccountOutputBuilder::new_with_amount(0, AccountId::null()) + .add_unlock_condition(GovernorAddressUnlockCondition::new(Ed25519Address::dummy())) + .add_unlock_condition(StateControllerAddressUnlockCondition::new(Ed25519Address::dummy())) + .add_feature( + BlockIssuerFeature::new(0, vec![BlockIssuerKey::Ed25519(Ed25519BlockIssuerKey::dummy())]).unwrap(), + ) + .finish() + .unwrap() + } } impl StateTransitionVerifier for AccountOutput { @@ -729,13 +745,13 @@ impl Packable for AccountOutput { } impl StorageScore for AccountOutput { - fn score(&self, rent_params: RentParameters) -> u64 { - storage_score_offset_output(rent_params) - + self.packed_len() as u64 * rent_params.storage_score_factor_data() as u64 - + self.native_tokens().score(rent_params) - + self.unlock_conditions().score(rent_params) - + self.features().score(rent_params) - + self.immutable_features().score(rent_params) + fn score(&self, rent_struct: RentStructure) -> u64 { + storage_score_offset_output(rent_struct) + + self.packed_len() as u64 * rent_struct.storage_score_factor_data() as u64 + + self.native_tokens().score(rent_struct) + + self.unlock_conditions().score(rent_struct) + + self.features().score(rent_struct) + + self.immutable_features().score(rent_struct) } } @@ -869,8 +885,8 @@ pub(crate) mod dto { let params = params.into(); let mut builder = match amount { OutputBuilderAmount::Amount(amount) => AccountOutputBuilder::new_with_amount(amount, *account_id), - OutputBuilderAmount::MinimumStorageDeposit(rent_params) => { - AccountOutputBuilder::new_with_minimum_storage_deposit(rent_params, *account_id) + OutputBuilderAmount::MinimumStorageDeposit(rent_struct) => { + AccountOutputBuilder::new_with_minimum_storage_deposit(rent_struct, *account_id) } } .with_mana(mana); @@ -991,7 +1007,7 @@ mod tests { test_split_dto(builder); let builder = - AccountOutput::build_with_minimum_storage_deposit(protocol_parameters.rent_parameters(), account_id) + AccountOutput::build_with_minimum_storage_deposit(protocol_parameters.rent_parameters().into(), account_id) .add_native_token(NativeToken::new(TokenId::from(foundry_id), 1000).unwrap()) .add_unlock_condition(gov_address) .add_unlock_condition(state_address) diff --git a/sdk/src/types/block/output/basic.rs b/sdk/src/types/block/output/basic.rs index ef8abec914..ff8de7c29a 100644 --- a/sdk/src/types/block/output/basic.rs +++ b/sdk/src/types/block/output/basic.rs @@ -5,10 +5,10 @@ use alloc::collections::BTreeSet; use packable::{Packable, PackableExt}; -use super::storage_score_offset_output; +use super::{storage_score_offset_output, AddressUnlockCondition}; use crate::types::{ block::{ - address::Address, + address::{Address, Ed25519Address}, output::{ feature::{verify_allowed_features, Feature, FeatureFlags, Features}, unlock_condition::{ @@ -18,7 +18,7 @@ use crate::types::{ NativeTokens, Output, OutputBuilderAmount, OutputId, }, protocol::ProtocolParameters, - rent::{RentParameters, StorageScore}, + rent::{RentParameters, RentStructure, StorageScore}, semantic::{TransactionFailureReason, ValidationContext}, unlock::Unlock, Error, @@ -47,8 +47,8 @@ impl BasicOutputBuilder { /// Creates an [`BasicOutputBuilder`] with a provided rent structure. /// The amount will be set to the minimum storage deposit. #[inline(always)] - pub fn new_with_minimum_storage_deposit(rent_params: RentParameters) -> Self { - Self::new(OutputBuilderAmount::MinimumStorageDeposit(rent_params)) + pub fn new_with_minimum_storage_deposit(rent_struct: RentStructure) -> Self { + Self::new(OutputBuilderAmount::MinimumStorageDeposit(rent_struct)) } fn new(amount: OutputBuilderAmount) -> Self { @@ -70,8 +70,8 @@ impl BasicOutputBuilder { /// Sets the amount to the minimum storage deposit. #[inline(always)] - pub fn with_minimum_storage_deposit(mut self, rent_params: RentParameters) -> Self { - self.amount = OutputBuilderAmount::MinimumStorageDeposit(rent_params); + pub fn with_minimum_storage_deposit(mut self, rent_struct: RentStructure) -> Self { + self.amount = OutputBuilderAmount::MinimumStorageDeposit(rent_struct); self } @@ -173,8 +173,8 @@ impl BasicOutputBuilder { output.amount = match self.amount { OutputBuilderAmount::Amount(amount) => amount, - OutputBuilderAmount::MinimumStorageDeposit(rent_params) => { - Output::Basic(output.clone()).rent_cost(rent_params) + OutputBuilderAmount::MinimumStorageDeposit(rent_struct) => { + Output::Basic(output.clone()).rent_cost(rent_struct) } }; @@ -255,8 +255,8 @@ impl BasicOutput { /// Creates a new [`BasicOutputBuilder`] with a provided rent structure. /// The amount will be set to the minimum storage deposit. #[inline(always)] - pub fn build_with_minimum_storage_deposit(rent_params: RentParameters) -> BasicOutputBuilder { - BasicOutputBuilder::new_with_minimum_storage_deposit(rent_params) + pub fn build_with_minimum_storage_deposit(rent_struct: RentStructure) -> BasicOutputBuilder { + BasicOutputBuilder::new_with_minimum_storage_deposit(rent_struct) } /// @@ -323,15 +323,23 @@ impl BasicOutput { None } + + /// Creates a dummy [`BasicOutput`] used to calculate a storage score for implicit account addresses. + pub(crate) fn dummy() -> Self { + BasicOutputBuilder::new_with_amount(0) + .add_unlock_condition(AddressUnlockCondition::new(Ed25519Address::dummy())) + .finish() + .unwrap() + } } impl StorageScore for BasicOutput { - fn score(&self, rent_params: RentParameters) -> u64 { - storage_score_offset_output(rent_params) - + self.packed_len() as u64 * rent_params.storage_score_factor_data() as u64 - + self.native_tokens().score(rent_params) - + self.unlock_conditions().score(rent_params) - + self.features().score(rent_params) + fn score(&self, rent_struct: RentStructure) -> u64 { + storage_score_offset_output(rent_struct) + + self.packed_len() as u64 * rent_struct.storage_score_factor_data() as u64 + + self.native_tokens().score(rent_struct) + + self.unlock_conditions().score(rent_struct) + + self.features().score(rent_struct) } } @@ -440,8 +448,8 @@ pub(crate) mod dto { let params = params.into(); let mut builder = match amount { OutputBuilderAmount::Amount(amount) => BasicOutputBuilder::new_with_amount(amount), - OutputBuilderAmount::MinimumStorageDeposit(rent_params) => { - BasicOutputBuilder::new_with_minimum_storage_deposit(rent_params) + OutputBuilderAmount::MinimumStorageDeposit(rent_struct) => { + BasicOutputBuilder::new_with_minimum_storage_deposit(rent_struct) } } .with_mana(mana); @@ -529,7 +537,7 @@ mod tests { .with_features(rand_allowed_features(BasicOutput::ALLOWED_FEATURES)); test_split_dto(builder); - let builder = BasicOutput::build_with_minimum_storage_deposit(protocol_parameters.rent_parameters()) + let builder = BasicOutput::build_with_minimum_storage_deposit(protocol_parameters.rent_parameters().into()) .add_native_token(NativeToken::new(TokenId::from(foundry_id), 1000).unwrap()) .add_unlock_condition(address) .with_features(rand_allowed_features(BasicOutput::ALLOWED_FEATURES)); diff --git a/sdk/src/types/block/output/delegation.rs b/sdk/src/types/block/output/delegation.rs index 17fb61d5cf..ae2d4f00c6 100644 --- a/sdk/src/types/block/output/delegation.rs +++ b/sdk/src/types/block/output/delegation.rs @@ -10,6 +10,7 @@ use packable::{ Packable, PackableExt, }; +use super::storage_score_offset_output; use crate::types::{ block::{ address::{AccountAddress, Address}, @@ -22,7 +23,7 @@ use crate::types::{ OutputBuilderAmount, OutputId, StateTransitionError, StateTransitionVerifier, }, protocol::ProtocolParameters, - rent::{RentParameters, StorageScore}, + rent::{RentParameters, RentStructure, StorageScore}, semantic::{TransactionFailureReason, ValidationContext}, slot::EpochIndex, unlock::Unlock, @@ -31,8 +32,6 @@ use crate::types::{ ValidationParams, }; -use super::storage_score_offset_output; - impl_id!(pub DelegationId, 32, "Unique identifier of the Delegation Output, which is the BLAKE2b-256 hash of the Output ID that created it."); #[cfg(feature = "serde")] @@ -82,13 +81,13 @@ impl DelegationOutputBuilder { /// Creates a [`DelegationOutputBuilder`] with a provided rent structure. /// The amount will be set to the minimum storage deposit. pub fn new_with_minimum_storage_deposit( - rent_params: RentParameters, + rent_struct: RentStructure, delegated_amount: u64, delegation_id: DelegationId, validator_address: AccountAddress, ) -> Self { Self::new( - OutputBuilderAmount::MinimumStorageDeposit(rent_params), + OutputBuilderAmount::MinimumStorageDeposit(rent_struct), delegated_amount, delegation_id, validator_address, @@ -119,8 +118,8 @@ impl DelegationOutputBuilder { } /// Sets the amount to the minimum storage deposit. - pub fn with_minimum_storage_deposit(mut self, rent_params: RentParameters) -> Self { - self.amount = OutputBuilderAmount::MinimumStorageDeposit(rent_params); + pub fn with_minimum_storage_deposit(mut self, rent_struct: RentStructure) -> Self { + self.amount = OutputBuilderAmount::MinimumStorageDeposit(rent_struct); self } @@ -197,8 +196,8 @@ impl DelegationOutputBuilder { output.amount = match self.amount { OutputBuilderAmount::Amount(amount) => amount, - OutputBuilderAmount::MinimumStorageDeposit(rent_params) => { - Output::Delegation(output.clone()).rent_cost(rent_params) + OutputBuilderAmount::MinimumStorageDeposit(rent_struct) => { + Output::Delegation(output.clone()).rent_cost(rent_struct) } }; @@ -279,13 +278,13 @@ impl DelegationOutput { /// Creates a new [`DelegationOutputBuilder`] with a provided rent structure. /// The amount will be set to the minimum storage deposit. pub fn build_with_minimum_storage_deposit( - rent_params: RentParameters, + rent_struct: RentStructure, delegated_amount: u64, delegation_id: DelegationId, validator_address: AccountAddress, ) -> DelegationOutputBuilder { DelegationOutputBuilder::new_with_minimum_storage_deposit( - rent_params, + rent_struct, delegated_amount, delegation_id, validator_address, @@ -459,11 +458,11 @@ impl Packable for DelegationOutput { } impl StorageScore for DelegationOutput { - fn score(&self, rent_params: RentParameters) -> u64 { - storage_score_offset_output(rent_params) - + rent_params.storage_score_offset_delegation() - + self.packed_len() as u64 * rent_params.storage_score_factor_data() as u64 - + self.unlock_conditions().score(rent_params) + fn score(&self, rent_struct: RentStructure) -> u64 { + storage_score_offset_output(rent_struct) + + rent_struct.storage_score_offset_delegation() + + self.packed_len() as u64 * rent_struct.storage_score_factor_data() as u64 + + self.unlock_conditions().score(rent_struct) } } @@ -573,9 +572,9 @@ pub(crate) mod dto { *delegation_id, *validator_address, ), - OutputBuilderAmount::MinimumStorageDeposit(rent_params) => { + OutputBuilderAmount::MinimumStorageDeposit(rent_struct) => { DelegationOutputBuilder::new_with_minimum_storage_deposit( - rent_params, + rent_struct, delegated_amount, *delegation_id, *validator_address, diff --git a/sdk/src/types/block/output/feature/block_issuer.rs b/sdk/src/types/block/output/feature/block_issuer.rs index 941b161a9a..3bb6e8dc0b 100644 --- a/sdk/src/types/block/output/feature/block_issuer.rs +++ b/sdk/src/types/block/output/feature/block_issuer.rs @@ -17,7 +17,7 @@ use packable::{ }; use crate::types::block::{ - rent::{RentParameters, StorageScore}, + rent::{RentParameters, RentStructure, StorageScore}, slot::SlotIndex, Error, }; @@ -62,9 +62,9 @@ impl BlockIssuerKey { } impl StorageScore for BlockIssuerKey { - fn score(&self, rent_params: RentParameters) -> u64 { + fn score(&self, rent_struct: RentStructure) -> u64 { match self { - Self::Ed25519(key) => key.score(rent_params), + Self::Ed25519(key) => key.score(rent_struct), } } } @@ -85,6 +85,12 @@ impl Ed25519BlockIssuerKey { pub fn try_from_bytes(bytes: [u8; Self::PUBLIC_KEY_LENGTH]) -> Result { Ok(Self(ed25519::PublicKey::try_from_bytes(bytes)?)) } + + /// Creates a dummy [`Ed25519BlockIssuerKey`] used to calculate a storage score for implicit account addresses. + pub(crate) fn dummy() -> Self { + // Unwrap: we provide a valid byte array + Self(ed25519::PublicKey::try_from_bytes([0; Self::PUBLIC_KEY_LENGTH]).unwrap()) + } } impl core::fmt::Debug for Ed25519BlockIssuerKey { @@ -112,8 +118,8 @@ impl Packable for Ed25519BlockIssuerKey { } impl StorageScore for Ed25519BlockIssuerKey { - fn score(&self, rent_params: RentParameters) -> u64 { - rent_params.storage_score_offset_ed25519_block_issuer_key() + fn score(&self, rent_struct: RentStructure) -> u64 { + rent_struct.storage_score_offset_ed25519_block_issuer_key() } } @@ -200,8 +206,8 @@ impl BlockIssuerKeys { } impl StorageScore for BlockIssuerKeys { - fn score(&self, rent_params: RentParameters) -> u64 { - (*self).iter().map(|key| key.score(rent_params)).sum() + fn score(&self, rent_struct: RentStructure) -> u64 { + (*self).iter().map(|key| key.score(rent_struct)).sum() } } diff --git a/sdk/src/types/block/output/feature/issuer.rs b/sdk/src/types/block/output/feature/issuer.rs index a966736e5e..be5448177a 100644 --- a/sdk/src/types/block/output/feature/issuer.rs +++ b/sdk/src/types/block/output/feature/issuer.rs @@ -5,7 +5,7 @@ use derive_more::From; use crate::types::block::{ address::Address, - rent::{RentParameters, StorageScore}, + rent::{RentParameters, RentStructure, StorageScore}, }; /// Identifies the validated issuer of the UTXO state machine. @@ -30,9 +30,8 @@ impl IssuerFeature { } impl StorageScore for IssuerFeature { - fn score(&self, rent_params: RentParameters) -> u64 { - // self.0.score(rent_params) - todo!() + fn score(&self, rent_struct: RentStructure) -> u64 { + self.0.score(rent_struct) } } diff --git a/sdk/src/types/block/output/feature/mod.rs b/sdk/src/types/block/output/feature/mod.rs index 16acf0340b..2130daecfa 100644 --- a/sdk/src/types/block/output/feature/mod.rs +++ b/sdk/src/types/block/output/feature/mod.rs @@ -28,7 +28,11 @@ pub use self::{ staking::StakingFeature, tag::TagFeature, }; -use crate::types::block::{create_bitflags, Error, rent::StorageScore}; +use crate::types::block::{ + create_bitflags, + rent::{RentStructure, StorageScore}, + Error, +}; /// #[derive(Clone, Eq, PartialEq, Hash, From, Packable)] @@ -197,6 +201,19 @@ impl Feature { } } +impl StorageScore for Feature { + fn score(&self, rent_struct: RentStructure) -> u64 { + match self { + Self::Sender(sender) => todo!(), + Self::Issuer(issuer) => todo!(), + Self::Metadata(metadata) => todo!(), + Self::Tag(tag) => todo!(), + Self::BlockIssuer(block_issuer) => todo!(), + Self::Staking(staking) => todo!(), + } + } +} + create_bitflags!( /// A bitflags-based representation of the set of active [`Feature`]s. pub FeatureFlags, @@ -314,8 +331,8 @@ impl Features { } impl StorageScore for Features { - fn score(&self, rent_params: crate::types::block::rent::RentParameters) -> u64 { - todo!() + fn score(&self, rent_struct: RentStructure) -> u64 { + self.0.iter().map(|f| f.score(rent_struct)).sum() } } diff --git a/sdk/src/types/block/output/foundry.rs b/sdk/src/types/block/output/foundry.rs index e83aa3c15e..d13d641c86 100644 --- a/sdk/src/types/block/output/foundry.rs +++ b/sdk/src/types/block/output/foundry.rs @@ -12,6 +12,7 @@ use packable::{ }; use primitive_types::U256; +use super::storage_score_offset_output; use crate::types::{ block::{ address::{AccountAddress, Address}, @@ -26,7 +27,7 @@ use crate::types::{ TokenId, TokenScheme, }, protocol::ProtocolParameters, - rent::{RentParameters, StorageScore}, + rent::{RentParameters, RentStructure, StorageScore}, semantic::{TransactionFailureReason, ValidationContext}, unlock::Unlock, Error, @@ -34,8 +35,6 @@ use crate::types::{ ValidationParams, }; -use super::storage_score_offset_output; - impl_id!(pub FoundryId, 38, "Defines the unique identifier of a foundry."); #[cfg(feature = "serde")] @@ -106,12 +105,12 @@ impl FoundryOutputBuilder { /// Creates a [`FoundryOutputBuilder`] with a provided rent structure. /// The amount will be set to the minimum storage deposit. pub fn new_with_minimum_storage_deposit( - rent_params: RentParameters, + rent_struct: RentStructure, serial_number: u32, token_scheme: TokenScheme, ) -> Self { Self::new( - OutputBuilderAmount::MinimumStorageDeposit(rent_params), + OutputBuilderAmount::MinimumStorageDeposit(rent_struct), serial_number, token_scheme, ) @@ -138,8 +137,8 @@ impl FoundryOutputBuilder { /// Sets the amount to the minimum storage deposit. #[inline(always)] - pub fn with_minimum_storage_deposit(mut self, rent_params: RentParameters) -> Self { - self.amount = OutputBuilderAmount::MinimumStorageDeposit(rent_params); + pub fn with_minimum_storage_deposit(mut self, rent_struct: RentStructure) -> Self { + self.amount = OutputBuilderAmount::MinimumStorageDeposit(rent_struct); self } @@ -285,8 +284,8 @@ impl FoundryOutputBuilder { output.amount = match self.amount { OutputBuilderAmount::Amount(amount) => amount, - OutputBuilderAmount::MinimumStorageDeposit(rent_params) => { - Output::Foundry(output.clone()).rent_cost(rent_params) + OutputBuilderAmount::MinimumStorageDeposit(rent_struct) => { + Output::Foundry(output.clone()).rent_cost(rent_struct) } }; @@ -368,11 +367,11 @@ impl FoundryOutput { /// The amount will be set to the minimum storage deposit. #[inline(always)] pub fn build_with_minimum_storage_deposit( - rent_params: RentParameters, + rent_struct: RentStructure, serial_number: u32, token_scheme: TokenScheme, ) -> FoundryOutputBuilder { - FoundryOutputBuilder::new_with_minimum_storage_deposit(rent_params, serial_number, token_scheme) + FoundryOutputBuilder::new_with_minimum_storage_deposit(rent_struct, serial_number, token_scheme) } /// @@ -661,14 +660,14 @@ impl Packable for FoundryOutput { } impl StorageScore for FoundryOutput { - fn score(&self, rent_params: RentParameters) -> u64 { - storage_score_offset_output(rent_params) - + self.packed_len() as u64 * rent_params.storage_score_factor_data() as u64 - + self.native_tokens().score(rent_params) - + self.token_scheme().score(rent_params) - + self.unlock_conditions().score(rent_params) - + self.features().score(rent_params) - + self.immutable_features().score(rent_params) + fn score(&self, rent_struct: RentStructure) -> u64 { + storage_score_offset_output(rent_struct) + + self.packed_len() as u64 * rent_struct.storage_score_factor_data() as u64 + + self.native_tokens().score(rent_struct) + + self.token_scheme().score(rent_struct) + + self.unlock_conditions().score(rent_struct) + + self.features().score(rent_struct) + + self.immutable_features().score(rent_struct) } } @@ -773,8 +772,8 @@ pub(crate) mod dto { OutputBuilderAmount::Amount(amount) => { FoundryOutputBuilder::new_with_amount(amount, serial_number, token_scheme) } - OutputBuilderAmount::MinimumStorageDeposit(rent_params) => { - FoundryOutputBuilder::new_with_minimum_storage_deposit(rent_params, serial_number, token_scheme) + OutputBuilderAmount::MinimumStorageDeposit(rent_struct) => { + FoundryOutputBuilder::new_with_minimum_storage_deposit(rent_struct, serial_number, token_scheme) } }; @@ -861,7 +860,7 @@ mod tests { test_split_dto(builder); let builder = FoundryOutput::build_with_minimum_storage_deposit( - protocol_parameters.rent_parameters(), + protocol_parameters.rent_parameters().into(), 123, rand_token_scheme(), ) diff --git a/sdk/src/types/block/output/mod.rs b/sdk/src/types/block/output/mod.rs index b9d982f4c1..3a5e3d1ab2 100644 --- a/sdk/src/types/block/output/mod.rs +++ b/sdk/src/types/block/output/mod.rs @@ -59,7 +59,7 @@ pub use self::{ use super::{ address::Ed25519Address, protocol::ProtocolParameters, - rent::{RentParameters, StorageScore}, + rent::{RentStructure, StorageScore}, BlockId, }; use crate::types::block::{address::Address, semantic::ValidationContext, slot::SlotIndex, Error}; @@ -76,7 +76,7 @@ pub const OUTPUT_INDEX_RANGE: RangeInclusive = 0..=OUTPUT_INDEX_MAX; // [0. #[derive(Copy, Clone)] pub enum OutputBuilderAmount { Amount(u64), - MinimumStorageDeposit(RentParameters), + MinimumStorageDeposit(RentStructure), } /// Contains the generic [`Output`] with associated [`OutputMetadata`]. @@ -386,8 +386,8 @@ impl Output { /// storage score, given by [`RentParameters`]. /// If there is a [`StorageDepositReturnUnlockCondition`](unlock_condition::StorageDepositReturnUnlockCondition), /// its amount is also checked. - pub fn verify_storage_deposit(&self, rent_params: RentParameters, token_supply: u64) -> Result<(), Error> { - let required_output_amount = self.rent_cost(rent_params); + pub fn verify_storage_deposit(&self, rent_struct: RentStructure, token_supply: u64) -> Result<(), Error> { + let required_output_amount = self.rent_cost(rent_struct); if self.amount() < required_output_amount { return Err(Error::InsufficientStorageDepositAmount { @@ -409,7 +409,7 @@ impl Output { }); } - let minimum_deposit = minimum_storage_deposit(return_condition.return_address(), rent_params, token_supply); + let minimum_deposit = minimum_storage_deposit(return_condition.return_address(), rent_struct, token_supply); // `Minimum Storage Deposit` ≤ `Return Amount` if return_condition.amount() < minimum_deposit { @@ -503,47 +503,47 @@ pub(crate) fn verify_output_amount_packable( /// Computes the minimum amount that a storage deposit has to match to allow creating a return [`Output`] back to the /// sender [`Address`]. -fn minimum_storage_deposit(address: &Address, rent_parameters: RentParameters, token_supply: u64) -> u64 { +fn minimum_storage_deposit(address: &Address, rent_struct: RentStructure, token_supply: u64) -> u64 { // PANIC: This can never fail because the amount will always be within the valid range. Also, the actual value is // not important, we are only interested in the storage requirements of the type. - BasicOutputBuilder::new_with_minimum_storage_deposit(rent_parameters) + BasicOutputBuilder::new_with_minimum_storage_deposit(rent_struct) .add_unlock_condition(AddressUnlockCondition::new(*address)) .finish_with_params(token_supply) .unwrap() .amount() } -fn storage_score_offset_output(rent_params: RentParameters) -> u64 { +fn storage_score_offset_output(rent_struct: RentStructure) -> u64 { // included output id, block id, and slot booked data size - rent_params.storage_score_offset_output() - + rent_params.storage_score_factor_data() as u64 + rent_struct.storage_score_offset_output() + + rent_struct.storage_score_factor_data() as u64 * (size_of::() as u64 + size_of::() as u64 + size_of::() as u64) } impl StorageScore for Output { - fn score(&self, rent_params: RentParameters) -> u64 { + fn score(&self, rent_struct: RentStructure) -> u64 { // +1 score for the output kind - rent_params.storage_score_factor_data() as u64 * size_of::() as u64 + rent_struct.storage_score_factor_data() as u64 * size_of::() as u64 + match self { - Self::Basic(basic) => basic.score(rent_params), - Self::Account(account) => account.score(rent_params), - Self::Foundry(foundry) => foundry.score(rent_params), - Self::Nft(nft) => nft.score(rent_params), - Self::Delegation(delegation) => delegation.score(rent_params), + Self::Basic(basic) => basic.score(rent_struct), + Self::Account(account) => account.score(rent_struct), + Self::Foundry(foundry) => foundry.score(rent_struct), + Self::Nft(nft) => nft.score(rent_struct), + Self::Delegation(delegation) => delegation.score(rent_struct), } } } pub struct MinimumStorageDepositBasicOutput { - rent_params: RentParameters, + rent_struct: RentStructure, token_supply: u64, builder: BasicOutputBuilder, } impl MinimumStorageDepositBasicOutput { - pub fn new(rent_params: RentParameters, token_supply: u64) -> Self { + pub fn new(rent_struct: RentStructure, token_supply: u64) -> Self { Self { - rent_params, + rent_struct, token_supply, builder: BasicOutputBuilder::new_with_amount(Output::AMOUNT_MIN).add_unlock_condition( AddressUnlockCondition::new(Address::from(Ed25519Address::from([0; Ed25519Address::LENGTH]))), @@ -581,7 +581,7 @@ impl MinimumStorageDepositBasicOutput { Ok(self .builder .finish_output(self.token_supply)? - .rent_cost(self.rent_params)) + .rent_cost(self.rent_struct)) } } #[cfg(feature = "serde")] diff --git a/sdk/src/types/block/output/native_token.rs b/sdk/src/types/block/output/native_token.rs index 5fbd795139..06bd001e86 100644 --- a/sdk/src/types/block/output/native_token.rs +++ b/sdk/src/types/block/output/native_token.rs @@ -12,7 +12,11 @@ use iterator_sorted::is_unique_sorted; use packable::{bounded::BoundedU8, prefix::BoxedSlicePrefix, Packable}; use primitive_types::U256; -use crate::types::block::{output::foundry::FoundryId, Error, rent::StorageScore}; +use crate::types::block::{ + output::foundry::FoundryId, + rent::{RentStructure, StorageScore}, + Error, +}; impl_id!(pub TokenId, 38, "Unique identifiers of native tokens. The TokenId of native tokens minted by a specific foundry is the same as the FoundryId."); @@ -73,6 +77,12 @@ impl Ord for NativeToken { } } +impl StorageScore for NativeToken { + fn score(&self, rent_struct: RentStructure) -> u64 { + todo!("native token score") + } +} + #[inline] fn verify_amount(amount: &U256, _: &()) -> Result<(), Error> { if VERIFY && amount.is_zero() { @@ -248,8 +258,8 @@ impl NativeTokens { } impl StorageScore for NativeTokens { - fn score(&self, rent_params: crate::types::block::rent::RentParameters) -> u64 { - todo!() + fn score(&self, rent_struct: RentStructure) -> u64 { + self.0.iter().map(|nt| nt.score(rent_struct)).sum() } } diff --git a/sdk/src/types/block/output/nft.rs b/sdk/src/types/block/output/nft.rs index 9ac1154e48..1acd52c40b 100644 --- a/sdk/src/types/block/output/nft.rs +++ b/sdk/src/types/block/output/nft.rs @@ -10,6 +10,7 @@ use packable::{ Packable, PackableExt, }; +use super::storage_score_offset_output; use crate::types::{ block::{ address::{Address, NftAddress}, @@ -19,10 +20,11 @@ use crate::types::{ verify_allowed_unlock_conditions, UnlockCondition, UnlockConditionFlags, UnlockConditions, }, verify_output_amount_min, verify_output_amount_packable, verify_output_amount_supply, ChainId, NativeToken, - NativeTokens, Output, OutputBuilderAmount, OutputId, RentParameters, StateTransitionError, - StateTransitionVerifier, StorageScore, + NativeTokens, Output, OutputBuilderAmount, OutputId, StateTransitionError, StateTransitionVerifier, + StorageScore, }, protocol::ProtocolParameters, + rent::RentStructure, semantic::{TransactionFailureReason, ValidationContext}, unlock::Unlock, Error, @@ -30,8 +32,6 @@ use crate::types::{ ValidationParams, }; -use super::storage_score_offset_output; - impl_id!(pub NftId, 32, "Unique identifier of an NFT, which is the BLAKE2b-256 hash of the Output ID that created it."); #[cfg(feature = "serde")] @@ -77,8 +77,8 @@ impl NftOutputBuilder { /// Creates an [`NftOutputBuilder`] with a provided rent structure. /// The amount will be set to the minimum storage deposit. - pub fn new_with_minimum_storage_deposit(rent_params: RentParameters, nft_id: NftId) -> Self { - Self::new(OutputBuilderAmount::MinimumStorageDeposit(rent_params), nft_id) + pub fn new_with_minimum_storage_deposit(rent_struct: RentStructure, nft_id: NftId) -> Self { + Self::new(OutputBuilderAmount::MinimumStorageDeposit(rent_struct), nft_id) } fn new(amount: OutputBuilderAmount, nft_id: NftId) -> Self { @@ -102,8 +102,8 @@ impl NftOutputBuilder { /// Sets the amount to the minimum storage deposit. #[inline(always)] - pub fn with_minimum_storage_deposit(mut self, rent_params: RentParameters) -> Self { - self.amount = OutputBuilderAmount::MinimumStorageDeposit(rent_params); + pub fn with_minimum_storage_deposit(mut self, rent_struct: RentStructure) -> Self { + self.amount = OutputBuilderAmount::MinimumStorageDeposit(rent_struct); self } @@ -245,8 +245,8 @@ impl NftOutputBuilder { output.amount = match self.amount { OutputBuilderAmount::Amount(amount) => amount, - OutputBuilderAmount::MinimumStorageDeposit(rent_params) => { - Output::Nft(output.clone()).rent_cost(rent_params) + OutputBuilderAmount::MinimumStorageDeposit(rent_struct) => { + Output::Nft(output.clone()).rent_cost(rent_struct) } }; @@ -329,8 +329,8 @@ impl NftOutput { /// Creates a new [`NftOutputBuilder`] with a provided rent structure. /// The amount will be set to the minimum storage deposit. #[inline(always)] - pub fn build_with_minimum_storage_deposit(rent_params: RentParameters, nft_id: NftId) -> NftOutputBuilder { - NftOutputBuilder::new_with_minimum_storage_deposit(rent_params, nft_id) + pub fn build_with_minimum_storage_deposit(rent_struct: RentStructure, nft_id: NftId) -> NftOutputBuilder { + NftOutputBuilder::new_with_minimum_storage_deposit(rent_struct, nft_id) } /// @@ -523,13 +523,13 @@ impl Packable for NftOutput { } impl StorageScore for NftOutput { - fn score(&self, rent_params: RentParameters) -> u64 { - storage_score_offset_output(rent_params) - + self.packed_len() as u64 * rent_params.storage_score_factor_data() as u64 - + self.native_tokens().score(rent_params) - + self.unlock_conditions().score(rent_params) - + self.features().score(rent_params) - + self.immutable_features().score(rent_params) + fn score(&self, rent_struct: RentStructure) -> u64 { + storage_score_offset_output(rent_struct) + + self.packed_len() as u64 * rent_struct.storage_score_factor_data() as u64 + + self.native_tokens().score(rent_struct) + + self.unlock_conditions().score(rent_struct) + + self.features().score(rent_struct) + + self.immutable_features().score(rent_struct) } } @@ -630,8 +630,8 @@ pub(crate) mod dto { let params = params.into(); let mut builder = match amount { OutputBuilderAmount::Amount(amount) => NftOutputBuilder::new_with_amount(amount, *nft_id), - OutputBuilderAmount::MinimumStorageDeposit(rent_params) => { - NftOutputBuilder::new_with_minimum_storage_deposit(rent_params, *nft_id) + OutputBuilderAmount::MinimumStorageDeposit(rent_struct) => { + NftOutputBuilder::new_with_minimum_storage_deposit(rent_struct, *nft_id) } } .with_mana(mana); @@ -725,7 +725,7 @@ mod tests { test_split_dto(builder); let builder = - NftOutput::build_with_minimum_storage_deposit(protocol_parameters.rent_parameters(), NftId::null()) + NftOutput::build_with_minimum_storage_deposit(protocol_parameters.rent_parameters().into(), NftId::null()) .add_native_token(NativeToken::new(TokenId::from(foundry_id), 1000).unwrap()) .add_unlock_condition(rand_address_unlock_condition()) .with_features(rand_allowed_features(NftOutput::ALLOWED_FEATURES)) diff --git a/sdk/src/types/block/output/token_scheme/mod.rs b/sdk/src/types/block/output/token_scheme/mod.rs index 42b428dbc0..4e63076c89 100644 --- a/sdk/src/types/block/output/token_scheme/mod.rs +++ b/sdk/src/types/block/output/token_scheme/mod.rs @@ -4,7 +4,10 @@ mod simple; pub use self::simple::SimpleTokenScheme; -use crate::types::block::{Error, rent::{StorageScore, RentParameters}}; +use crate::types::block::{ + rent::{RentParameters, RentStructure, StorageScore}, + Error, +}; /// #[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Hash, derive_more::From, packable::Packable)] @@ -47,9 +50,9 @@ impl TokenScheme { } impl StorageScore for TokenScheme { - fn score(&self, rent_params: RentParameters) -> u64 { + fn score(&self, rent_struct: RentStructure) -> u64 { match self { - Self::Simple(simple) => simple.score(rent_params) + Self::Simple(simple) => simple.score(rent_struct), } } } diff --git a/sdk/src/types/block/output/token_scheme/simple.rs b/sdk/src/types/block/output/token_scheme/simple.rs index 34131f2127..e1250b93bb 100644 --- a/sdk/src/types/block/output/token_scheme/simple.rs +++ b/sdk/src/types/block/output/token_scheme/simple.rs @@ -9,7 +9,10 @@ use packable::{ }; use primitive_types::U256; -use crate::types::block::{Error, rent::{StorageScore, RentParameters}}; +use crate::types::block::{ + rent::{RentParameters, RentStructure, StorageScore}, + Error, +}; /// #[derive(Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)] @@ -104,7 +107,7 @@ impl Packable for SimpleTokenScheme { } impl StorageScore for SimpleTokenScheme { - fn score(&self, rent_params: RentParameters) -> u64 { + fn score(&self, rent_struct: RentStructure) -> u64 { 0 } } diff --git a/sdk/src/types/block/output/unlock_condition/mod.rs b/sdk/src/types/block/output/unlock_condition/mod.rs index 3e89809900..f6cc8d19a8 100644 --- a/sdk/src/types/block/output/unlock_condition/mod.rs +++ b/sdk/src/types/block/output/unlock_condition/mod.rs @@ -30,7 +30,14 @@ pub use self::{ state_controller_address::StateControllerAddressUnlockCondition, storage_deposit_return::StorageDepositReturnUnlockCondition, timelock::TimelockUnlockCondition, }; -use crate::types::block::{address::Address, create_bitflags, protocol::ProtocolParameters, slot::SlotIndex, Error, rent::StorageScore}; +use crate::types::block::{ + address::Address, + create_bitflags, + protocol::ProtocolParameters, + rent::{RentStructure, StorageScore}, + slot::SlotIndex, + Error, +}; /// #[derive(Clone, Eq, PartialEq, Hash, From)] @@ -65,17 +72,23 @@ impl Ord for UnlockCondition { impl core::fmt::Debug for UnlockCondition { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { match self { - Self::Address(unlock_condition) => unlock_condition.fmt(f), - Self::StorageDepositReturn(unlock_condition) => unlock_condition.fmt(f), - Self::Timelock(unlock_condition) => unlock_condition.fmt(f), - Self::Expiration(unlock_condition) => unlock_condition.fmt(f), - Self::StateControllerAddress(unlock_condition) => unlock_condition.fmt(f), - Self::GovernorAddress(unlock_condition) => unlock_condition.fmt(f), - Self::ImmutableAccountAddress(unlock_condition) => unlock_condition.fmt(f), + Self::Address(address) => address.fmt(f), + Self::StorageDepositReturn(storage_deposit_return) => storage_deposit_return.fmt(f), + Self::Timelock(timelock) => timelock.fmt(f), + Self::Expiration(expiration) => expiration.fmt(f), + Self::StateControllerAddress(state_controller_address) => state_controller_address.fmt(f), + Self::GovernorAddress(governor_address) => governor_address.fmt(f), + Self::ImmutableAccountAddress(immutable_account_address) => immutable_account_address.fmt(f), } } } +impl StorageScore for UnlockCondition { + fn score(&self, rent_struct: RentStructure) -> u64 { + todo!("unlock condition score") + } +} + impl UnlockCondition { /// Return the output kind of an `Output`. pub fn kind(&self) -> u8 { @@ -445,8 +458,8 @@ impl UnlockConditions { } impl StorageScore for UnlockConditions { - fn score(&self, rent_params: crate::types::block::rent::RentParameters) -> u64 { - todo!() + fn score(&self, rent_struct: RentStructure) -> u64 { + self.0.iter().map(|uc| uc.score(rent_struct)).sum() } } diff --git a/sdk/src/types/block/payload/transaction/essence/regular.rs b/sdk/src/types/block/payload/transaction/essence/regular.rs index 71e0d332cc..3cb42a19b3 100644 --- a/sdk/src/types/block/payload/transaction/essence/regular.rs +++ b/sdk/src/types/block/payload/transaction/essence/regular.rs @@ -14,6 +14,7 @@ use crate::types::{ output::{InputsCommitment, NativeTokens, Output, OUTPUT_COUNT_RANGE}, payload::{OptionalPayload, Payload}, protocol::ProtocolParameters, + rent::RentStructure, slot::SlotIndex, Error, }, @@ -395,7 +396,7 @@ fn verify_outputs(outputs: &[Output], visitor: &ProtocolPara } } - output.verify_storage_deposit(visitor.rent_parameters(), visitor.token_supply())?; + output.verify_storage_deposit(visitor.rent_parameters().into(), visitor.token_supply())?; } } diff --git a/sdk/src/types/block/rent.rs b/sdk/src/types/block/rent.rs index 4608ad809f..f89c8e8c27 100644 --- a/sdk/src/types/block/rent.rs +++ b/sdk/src/types/block/rent.rs @@ -5,6 +5,7 @@ use core::{mem::size_of, ops::Deref}; use packable::Packable; +use super::output::{AccountOutput, BasicOutput}; use crate::types::block::{ address::{Address, Ed25519Address}, output::{ @@ -26,13 +27,38 @@ const DEFAULT_STORAGE_SCORE_OFFSET_DELEGATION: StorageScoreOffset = 100; type StorageScoreFactor = u8; type StorageScoreOffset = u64; -// Includes the rent parameters and the additional factors/offsets computed from these parameters. #[derive(Copy, -// Clone, Debug, Eq, PartialEq)] +// Includes the rent parameters and the additional factors/offsets computed from these parameters. +#[derive(Copy, Clone, Debug, Eq, PartialEq)] pub struct RentStructure { rent_parameters: RentParameters, storage_score_offset_implicit_account_creation_address: u64, } +impl RentStructure { + /// Creates a new [`RentStructure`]. Computes the score offset for implicit account creation addresses. + pub fn new(rent_parameters: RentParameters) -> Self { + let mut rent_structure = Self { + rent_parameters, + storage_score_offset_implicit_account_creation_address: 0, + }; + + // set the storage score offset for implicit account creation addresses as + // the difference between the storage score of the dummy account and the storage + // score of the dummy basic output minus the storage score of the dummy address. + let dummy_basic_output_score = BasicOutput::dummy().score(rent_structure); + let dummy_address_score = Ed25519Address::dummy().score(rent_structure); + let basic_score_without_address = dummy_basic_output_score + .checked_sub(dummy_address_score) + .expect("underflow"); + let dummy_account_output_score = AccountOutput::dummy().score(rent_structure); + + rent_structure.storage_score_offset_implicit_account_creation_address = dummy_account_output_score + .checked_sub(basic_score_without_address) + .expect("underflow"); + rent_structure + } +} + impl Deref for RentStructure { type Target = RentParameters; @@ -41,6 +67,12 @@ impl Deref for RentStructure { } } +impl From for RentStructure { + fn from(rent_parameters: RentParameters) -> Self { + Self::new(rent_parameters) + } +} + // Defines the parameters of storage score calculations on objects which take node resources. // This structure defines the minimum base token deposit required on an object. This deposit does not // generate Mana, which serves as a rent payment in Mana for storing the object. @@ -171,20 +203,20 @@ impl RentParameters { } } -/// A trait to facilitate the rent cost computation for block outputs, which is central to dust protection. +/// A trait to facilitate the rent cost computation for implementing types, which is central to dust protection. pub trait StorageScore { - /// Computes the storage score given a [`RentParameters`]. Different fields in a type lead to different storage + /// Computes the storage score given a [`RentStructure`]. Different fields in a type lead to different storage /// requirements for the ledger state. - fn score(&self, rent_params: RentParameters) -> u64; + fn score(&self, rent_struct: RentStructure) -> u64; - /// Computes the storage cost given a [`RentParameters`]. - fn rent_cost(&self, rent_params: RentParameters) -> u64 { - rent_params.storage_cost as u64 * self.score(rent_params) + /// Computes the rent cost given a [`RentStructure`]. + fn rent_cost(&self, rent_struct: RentStructure) -> u64 { + rent_struct.storage_cost as u64 * self.score(rent_struct) } } impl StorageScore for [T; N] { - fn score(&self, rent_params: RentParameters) -> u64 { - self.iter().map(|elem| elem.score(rent_params)).sum() + fn score(&self, rent_struct: RentStructure) -> u64 { + self.iter().map(|elem| elem.score(rent_struct)).sum() } } diff --git a/sdk/src/wallet/account/operations/balance.rs b/sdk/src/wallet/account/operations/balance.rs index 77f6fb02b7..65eb8be704 100644 --- a/sdk/src/wallet/account/operations/balance.rs +++ b/sdk/src/wallet/account/operations/balance.rs @@ -8,7 +8,7 @@ use crate::{ types::block::{ address::Bech32Address, output::{unlock_condition::UnlockCondition, FoundryId, NativeTokensBuilder, Output}, - rent::StorageScore, + rent::{RentStructure, StorageScore}, ConvertTo, }, wallet::{ @@ -63,7 +63,7 @@ where account_details: &AccountDetails, ) -> Result { let network_id = self.client().get_network_id().await?; - let rent_params = self.client().get_rent_parameters().await?; + let rent_struct = self.client().get_rent_parameters().await?.into(); let mut balance = Balance::default(); let mut total_rent_amount = 0; let mut total_native_tokens = NativeTokensBuilder::default(); @@ -89,7 +89,7 @@ where } let output = &data.output; - let rent = output.rent_cost(rent_params); + let rent = output.rent_cost(rent_struct); // Add account and foundry outputs here because they can't have a // [`StorageDepositReturnUnlockCondition`] or time related unlock conditions diff --git a/sdk/src/wallet/account/operations/output_claiming.rs b/sdk/src/wallet/account/operations/output_claiming.rs index 6ca1cc10b2..56c4e6e55c 100644 --- a/sdk/src/wallet/account/operations/output_claiming.rs +++ b/sdk/src/wallet/account/operations/output_claiming.rs @@ -14,6 +14,7 @@ use crate::{ BasicOutputBuilder, MinimumStorageDepositBasicOutput, NativeTokens, NativeTokensBuilder, NftOutputBuilder, Output, OutputId, }, + rent::RentStructure, slot::SlotIndex, }, wallet::account::{ @@ -203,7 +204,7 @@ where log::debug!("[OUTPUT_CLAIMING] claim_outputs_internal"); let slot_index = self.client().get_slot_index().await?; - let rent_params = self.client().get_rent_parameters().await?; + let rent_struct = self.client().get_rent_parameters().await?.into(); let token_supply = self.client().get_token_supply().await?; let account_details = self.details().await; @@ -276,7 +277,7 @@ where .finish_output(token_supply)? } else { NftOutputBuilder::from(nft_output) - .with_minimum_storage_deposit(rent_params) + .with_minimum_storage_deposit(rent_struct) .with_nft_id(nft_output.nft_id_non_null(&output_data.output_id)) .with_unlock_conditions([AddressUnlockCondition::new(first_account_address.address.inner)]) // Set native tokens empty, we will collect them from all inputs later @@ -301,7 +302,7 @@ where required_amount_for_nfts } else { required_amount_for_nfts - + MinimumStorageDepositBasicOutput::new(rent_params, token_supply) + + MinimumStorageDepositBasicOutput::new(rent_struct, token_supply) .with_native_tokens(option_native_token) .finish()? }; @@ -321,7 +322,7 @@ where // Recalculate every time, because new inputs can also add more native tokens, which would increase // the required storage deposit required_amount = required_amount_for_nfts - + MinimumStorageDepositBasicOutput::new(rent_params, token_supply) + + MinimumStorageDepositBasicOutput::new(rent_struct, token_supply) .with_native_tokens(option_native_token) .finish()?; diff --git a/sdk/src/wallet/account/operations/transaction/high_level/create_account.rs b/sdk/src/wallet/account/operations/transaction/high_level/create_account.rs index 31efd75e59..ad0f7d05eb 100644 --- a/sdk/src/wallet/account/operations/transaction/high_level/create_account.rs +++ b/sdk/src/wallet/account/operations/transaction/high_level/create_account.rs @@ -74,7 +74,7 @@ where options: impl Into> + Send, ) -> crate::wallet::Result { log::debug!("[TRANSACTION] prepare_create_account_output"); - let rent_params = self.client().get_rent_parameters().await?; + let rent_struct = self.client().get_rent_parameters().await?.into(); let token_supply = self.client().get_token_supply().await?; let controller_address = match params.as_ref().and_then(|options| options.address.as_ref()) { @@ -93,7 +93,7 @@ where }; let mut account_output_builder = - AccountOutputBuilder::new_with_minimum_storage_deposit(rent_params, AccountId::null()) + AccountOutputBuilder::new_with_minimum_storage_deposit(rent_struct, AccountId::null()) .with_state_index(0) .with_foundry_counter(0) .add_unlock_condition(StateControllerAddressUnlockCondition::new(controller_address)) diff --git a/sdk/src/wallet/account/operations/transaction/high_level/minting/create_native_token.rs b/sdk/src/wallet/account/operations/transaction/high_level/minting/create_native_token.rs index 373ac38201..ce3f7e2ace 100644 --- a/sdk/src/wallet/account/operations/transaction/high_level/minting/create_native_token.rs +++ b/sdk/src/wallet/account/operations/transaction/high_level/minting/create_native_token.rs @@ -15,6 +15,7 @@ use crate::{ feature::MetadataFeature, unlock_condition::ImmutableAccountAddressUnlockCondition, AccountId, AccountOutputBuilder, FoundryId, FoundryOutputBuilder, Output, SimpleTokenScheme, TokenId, TokenScheme, }, + rent::RentStructure, }, wallet::account::{ types::{Transaction, TransactionDto}, @@ -131,7 +132,7 @@ where options: impl Into> + Send, ) -> crate::wallet::Result { log::debug!("[TRANSACTION] create_native_token"); - let rent_params = self.client().get_rent_parameters().await?; + let rent_struct = self.client().get_rent_parameters().await?.into(); let token_supply = self.client().get_token_supply().await?; let (account_id, account_output) = self @@ -158,7 +159,7 @@ where new_account_output_builder.finish_output(token_supply)?, { let mut foundry_builder = FoundryOutputBuilder::new_with_minimum_storage_deposit( - rent_params, + rent_struct, account_output.foundry_counter() + 1, TokenScheme::Simple(SimpleTokenScheme::new( params.circulating_supply, diff --git a/sdk/src/wallet/account/operations/transaction/high_level/minting/mint_nfts.rs b/sdk/src/wallet/account/operations/transaction/high_level/minting/mint_nfts.rs index f07f6e79a4..c574ed781f 100644 --- a/sdk/src/wallet/account/operations/transaction/high_level/minting/mint_nfts.rs +++ b/sdk/src/wallet/account/operations/transaction/high_level/minting/mint_nfts.rs @@ -13,6 +13,7 @@ use crate::{ unlock_condition::AddressUnlockCondition, NftId, NftOutputBuilder, }, + rent::RentStructure, ConvertTo, }, wallet::{ @@ -160,7 +161,7 @@ where I::IntoIter: Send, { log::debug!("[TRANSACTION] prepare_mint_nfts"); - let rent_params = self.client().get_rent_parameters().await?; + let rent_struct = self.client().get_rent_parameters().await?.into(); let token_supply = self.client().get_token_supply().await?; let account_addresses = self.addresses().await?; let mut outputs = Vec::new(); @@ -189,7 +190,7 @@ where }; // NftId needs to be set to 0 for the creation - let mut nft_builder = NftOutputBuilder::new_with_minimum_storage_deposit(rent_params, NftId::null()) + let mut nft_builder = NftOutputBuilder::new_with_minimum_storage_deposit(rent_struct, NftId::null()) // Address which will own the nft .add_unlock_condition(AddressUnlockCondition::new(address)); diff --git a/sdk/src/wallet/account/operations/transaction/high_level/send.rs b/sdk/src/wallet/account/operations/transaction/high_level/send.rs index 83dee32dcd..2b1dad9068 100644 --- a/sdk/src/wallet/account/operations/transaction/high_level/send.rs +++ b/sdk/src/wallet/account/operations/transaction/high_level/send.rs @@ -14,6 +14,7 @@ use crate::{ }, BasicOutputBuilder, MinimumStorageDepositBasicOutput, }, + rent::RentStructure, slot::SlotIndex, ConvertTo, }, @@ -139,7 +140,7 @@ where { log::debug!("[TRANSACTION] prepare_send"); let options = options.into(); - let rent_params = self.client().get_rent_parameters().await?; + let rent_struct = self.client().get_rent_parameters().await?.into(); let token_supply = self.client().get_token_supply().await?; let account_addresses = self.addresses().await?; @@ -170,7 +171,7 @@ where .unwrap_or(default_return_address.address); // Get the minimum required amount for an output assuming it does not need a storage deposit. - let output = BasicOutputBuilder::new_with_minimum_storage_deposit(rent_params) + let output = BasicOutputBuilder::new_with_minimum_storage_deposit(rent_struct) .add_unlock_condition(AddressUnlockCondition::new(address)) .finish_output(token_supply)?; @@ -187,7 +188,7 @@ where }); // Since it does need a storage deposit, calculate how much that should be - let storage_deposit_amount = MinimumStorageDepositBasicOutput::new(rent_params, token_supply) + let storage_deposit_amount = MinimumStorageDepositBasicOutput::new(rent_struct, token_supply) .with_storage_deposit_return()? .with_expiration()? .finish()?; diff --git a/sdk/src/wallet/account/operations/transaction/high_level/send_native_tokens.rs b/sdk/src/wallet/account/operations/transaction/high_level/send_native_tokens.rs index 571344c1a7..7654b8693d 100644 --- a/sdk/src/wallet/account/operations/transaction/high_level/send_native_tokens.rs +++ b/sdk/src/wallet/account/operations/transaction/high_level/send_native_tokens.rs @@ -15,6 +15,7 @@ use crate::{ }, BasicOutputBuilder, MinimumStorageDepositBasicOutput, NativeToken, NativeTokens, TokenId, }, + rent::RentStructure, slot::SlotIndex, ConvertTo, }, @@ -129,7 +130,7 @@ where I::IntoIter: Send, { log::debug!("[TRANSACTION] prepare_send_native_tokens"); - let rent_params = self.client().get_rent_parameters().await?; + let rent_struct = self.client().get_rent_parameters().await?.into(); let token_supply = self.client().get_token_supply().await?; let account_addresses = self.addresses().await?; @@ -171,7 +172,7 @@ where // get minimum required amount for such an output, so we don't lock more than required // We have to check it for every output individually, because different address types and amount of // different native tokens require a different storage deposit - let storage_deposit_amount = MinimumStorageDepositBasicOutput::new(rent_params, token_supply) + let storage_deposit_amount = MinimumStorageDepositBasicOutput::new(rent_struct, token_supply) .with_native_tokens(native_tokens.clone()) .with_storage_deposit_return()? .with_expiration()? diff --git a/sdk/src/wallet/account/operations/transaction/mod.rs b/sdk/src/wallet/account/operations/transaction/mod.rs index 0e0545827c..d21ead4c00 100644 --- a/sdk/src/wallet/account/operations/transaction/mod.rs +++ b/sdk/src/wallet/account/operations/transaction/mod.rs @@ -73,7 +73,7 @@ where // Check if the outputs have enough amount to cover the storage deposit for output in &outputs { output.verify_storage_deposit( - protocol_parameters.rent_parameters(), + protocol_parameters.rent_parameters().into(), protocol_parameters.token_supply(), )?; } diff --git a/sdk/src/wallet/account/operations/transaction/prepare_output.rs b/sdk/src/wallet/account/operations/transaction/prepare_output.rs index 5d25537914..e258a14bce 100644 --- a/sdk/src/wallet/account/operations/transaction/prepare_output.rs +++ b/sdk/src/wallet/account/operations/transaction/prepare_output.rs @@ -16,7 +16,7 @@ use crate::{ BasicOutputBuilder, MinimumStorageDepositBasicOutput, NativeToken, NftId, NftOutputBuilder, Output, UnlockCondition, }, - rent::{RentParameters, StorageScore}, + rent::{RentParameters, RentStructure, StorageScore}, slot::SlotIndex, Error, }, @@ -47,12 +47,12 @@ where self.client().bech32_hrp_matches(params.recipient_address.hrp()).await?; - let rent_params = self.client().get_rent_parameters().await?; + let rent_struct = self.client().get_rent_parameters().await?.into(); let nft_id = params.assets.as_ref().and_then(|a| a.nft_id); let (mut first_output_builder, existing_nft_output_data) = self - .create_initial_output_builder(params.recipient_address, nft_id, rent_params) + .create_initial_output_builder(params.recipient_address, nft_id, rent_struct) .await?; if let Some(assets) = ¶ms.assets { @@ -103,7 +103,7 @@ where // Build output with minimum required storage deposit so we can use the amount in the next step let first_output = first_output_builder - .with_minimum_storage_deposit(rent_params) + .with_minimum_storage_deposit(rent_struct) .finish_output(token_supply)?; let mut second_output_builder = if nft_id.is_some() { @@ -113,9 +113,9 @@ where }; let min_storage_deposit_basic_output = - MinimumStorageDepositBasicOutput::new(rent_params, token_supply).finish()?; + MinimumStorageDepositBasicOutput::new(rent_struct, token_supply).finish()?; - let min_required_storage_deposit = first_output.rent_cost(rent_params); + let min_required_storage_deposit = first_output.rent_cost(rent_struct); if params.amount > min_required_storage_deposit { second_output_builder = second_output_builder.with_amount(params.amount); @@ -147,7 +147,7 @@ where // need to check the min required storage deposit again let min_storage_deposit_new_amount = second_output_builder .clone() - .with_minimum_storage_deposit(rent_params) + .with_minimum_storage_deposit(rent_struct) .finish_output(token_supply)? .amount(); @@ -177,7 +177,7 @@ where // If we're sending an existing NFT, its minimum required storage deposit is not part of the available base_coin // balance, so we add it here if let Some(existing_nft_output_data) = existing_nft_output_data { - available_base_coin += existing_nft_output_data.output.rent_cost(rent_params); + available_base_coin += existing_nft_output_data.output.rent_cost(rent_struct); } if final_amount > available_base_coin { @@ -237,13 +237,13 @@ where &self, recipient_address: Bech32Address, nft_id: Option, - rent_params: RentParameters, + rent_struct: RentStructure, ) -> crate::wallet::Result<(OutputBuilder, Option)> { let (mut first_output_builder, existing_nft_output_data) = if let Some(nft_id) = &nft_id { if nft_id.is_null() { // Mint a new NFT output ( - OutputBuilder::Nft(NftOutputBuilder::new_with_minimum_storage_deposit(rent_params, *nft_id)), + OutputBuilder::Nft(NftOutputBuilder::new_with_minimum_storage_deposit(rent_struct, *nft_id)), None, ) } else { @@ -264,7 +264,7 @@ where } } else { ( - OutputBuilder::Basic(BasicOutputBuilder::new_with_minimum_storage_deposit(rent_params)), + OutputBuilder::Basic(BasicOutputBuilder::new_with_minimum_storage_deposit(rent_struct)), None, ) }; @@ -427,13 +427,13 @@ impl OutputBuilder { } self } - fn with_minimum_storage_deposit(mut self, rent_params: RentParameters) -> Self { + fn with_minimum_storage_deposit(mut self, rent_struct: RentStructure) -> Self { match self { Self::Basic(b) => { - self = Self::Basic(b.with_minimum_storage_deposit(rent_params)); + self = Self::Basic(b.with_minimum_storage_deposit(rent_struct)); } Self::Nft(b) => { - self = Self::Nft(b.with_minimum_storage_deposit(rent_params)); + self = Self::Nft(b.with_minimum_storage_deposit(rent_struct)); } } self diff --git a/sdk/src/wallet/account/operations/transaction/prepare_transaction.rs b/sdk/src/wallet/account/operations/transaction/prepare_transaction.rs index d493791b05..9bbbc66398 100644 --- a/sdk/src/wallet/account/operations/transaction/prepare_transaction.rs +++ b/sdk/src/wallet/account/operations/transaction/prepare_transaction.rs @@ -34,12 +34,12 @@ where let options = options.into(); let outputs = outputs.into(); let prepare_transaction_start_time = Instant::now(); - let rent_params = self.client().get_rent_parameters().await?; + let rent_struct = self.client().get_rent_parameters().await?.into(); let token_supply = self.client().get_token_supply().await?; // Check if the outputs have enough amount to cover the storage deposit for output in &outputs { - output.verify_storage_deposit(rent_params, token_supply)?; + output.verify_storage_deposit(rent_struct, token_supply)?; } let is_burn_present = options.as_ref().map(|options| options.burn.is_some()).unwrap_or(false); diff --git a/sdk/tests/client/input_selection/account_outputs.rs b/sdk/tests/client/input_selection/account_outputs.rs index d9fcb96d05..e03739b902 100644 --- a/sdk/tests/client/input_selection/account_outputs.rs +++ b/sdk/tests/client/input_selection/account_outputs.rs @@ -2312,17 +2312,19 @@ fn new_state_metadata() { let protocol_parameters = protocol_parameters(); let account_id_1 = AccountId::from_str(ACCOUNT_ID_1).unwrap(); - let account_output = - AccountOutputBuilder::new_with_minimum_storage_deposit(protocol_parameters.rent_parameters(), account_id_1) - .with_state_metadata([1, 2, 3]) - .add_unlock_condition(StateControllerAddressUnlockCondition::new( - Address::try_from_bech32(BECH32_ADDRESS_ED25519_0).unwrap(), - )) - .add_unlock_condition(GovernorAddressUnlockCondition::new( - Address::try_from_bech32(BECH32_ADDRESS_ED25519_0).unwrap(), - )) - .finish_output(protocol_parameters.token_supply()) - .unwrap(); + let account_output = AccountOutputBuilder::new_with_minimum_storage_deposit( + protocol_parameters.rent_parameters().into(), + account_id_1, + ) + .with_state_metadata([1, 2, 3]) + .add_unlock_condition(StateControllerAddressUnlockCondition::new( + Address::try_from_bech32(BECH32_ADDRESS_ED25519_0).unwrap(), + )) + .add_unlock_condition(GovernorAddressUnlockCondition::new( + Address::try_from_bech32(BECH32_ADDRESS_ED25519_0).unwrap(), + )) + .finish_output(protocol_parameters.token_supply()) + .unwrap(); let inputs = [InputSigningData { output: account_output.clone(), @@ -2332,7 +2334,7 @@ fn new_state_metadata() { // New account output, with updated state index let updated_account_output = AccountOutputBuilder::from(account_output.as_account()) - .with_minimum_storage_deposit(protocol_parameters.rent_parameters()) + .with_minimum_storage_deposit(protocol_parameters.rent_parameters().into()) .with_state_metadata([3, 4, 5]) .with_state_index(account_output.as_account().state_index() + 1) .finish_output(protocol_parameters.token_supply()) @@ -2358,17 +2360,19 @@ fn new_state_metadata_but_same_state_index() { let protocol_parameters = protocol_parameters(); let account_id_1 = AccountId::from_str(ACCOUNT_ID_1).unwrap(); - let account_output = - AccountOutputBuilder::new_with_minimum_storage_deposit(protocol_parameters.rent_parameters(), account_id_1) - .with_state_metadata([1, 2, 3]) - .add_unlock_condition(StateControllerAddressUnlockCondition::new( - Address::try_from_bech32(BECH32_ADDRESS_ED25519_0).unwrap(), - )) - .add_unlock_condition(GovernorAddressUnlockCondition::new( - Address::try_from_bech32(BECH32_ADDRESS_ED25519_0).unwrap(), - )) - .finish_output(protocol_parameters.token_supply()) - .unwrap(); + let account_output = AccountOutputBuilder::new_with_minimum_storage_deposit( + protocol_parameters.rent_parameters().into(), + account_id_1, + ) + .with_state_metadata([1, 2, 3]) + .add_unlock_condition(StateControllerAddressUnlockCondition::new( + Address::try_from_bech32(BECH32_ADDRESS_ED25519_0).unwrap(), + )) + .add_unlock_condition(GovernorAddressUnlockCondition::new( + Address::try_from_bech32(BECH32_ADDRESS_ED25519_0).unwrap(), + )) + .finish_output(protocol_parameters.token_supply()) + .unwrap(); let inputs = [InputSigningData { output: account_output.clone(), @@ -2378,7 +2382,7 @@ fn new_state_metadata_but_same_state_index() { // New account output, without updated state index let updated_account_output = AccountOutputBuilder::from(account_output.as_account()) - .with_minimum_storage_deposit(protocol_parameters.rent_parameters()) + .with_minimum_storage_deposit(protocol_parameters.rent_parameters().into()) .with_state_metadata([3, 4, 5]) .finish_output(protocol_parameters.token_supply()) .unwrap(); diff --git a/sdk/tests/client/input_selection/nft_outputs.rs b/sdk/tests/client/input_selection/nft_outputs.rs index fa5a9b6cae..7c608f356d 100644 --- a/sdk/tests/client/input_selection/nft_outputs.rs +++ b/sdk/tests/client/input_selection/nft_outputs.rs @@ -1198,7 +1198,7 @@ fn changed_immutable_metadata() { let metadata = [1, 2, 3]; let nft_output = - NftOutputBuilder::new_with_minimum_storage_deposit(protocol_parameters.rent_parameters(), nft_id_1) + NftOutputBuilder::new_with_minimum_storage_deposit(protocol_parameters.rent_parameters().into(), nft_id_1) .with_immutable_features(MetadataFeature::try_from(metadata)) .add_unlock_condition(AddressUnlockCondition::new( Address::try_from_bech32(BECH32_ADDRESS_ED25519_0).unwrap(), @@ -1224,7 +1224,7 @@ fn changed_immutable_metadata() { // New nft output with changed immutable metadata feature let updated_nft_output = NftOutputBuilder::from(nft_output.as_nft()) - .with_minimum_storage_deposit(protocol_parameters.rent_parameters()) + .with_minimum_storage_deposit(protocol_parameters.rent_parameters().into()) .with_immutable_features(MetadataFeature::try_from(metadata)) .finish_output(protocol_parameters.token_supply()) .unwrap(); diff --git a/sdk/tests/types/output/account.rs b/sdk/tests/types/output/account.rs index 277b04f3e1..76a677b5ab 100644 --- a/sdk/tests/types/output/account.rs +++ b/sdk/tests/types/output/account.rs @@ -72,7 +72,7 @@ fn builder() { let metadata = rand_metadata_feature(); let output = builder - .with_minimum_storage_deposit(protocol_parameters.rent_parameters()) + .with_minimum_storage_deposit(protocol_parameters.rent_parameters().into()) .add_unlock_condition(rand_state_controller_address_unlock_condition_different_from( &account_id, )) @@ -84,7 +84,7 @@ fn builder() { assert_eq!( output.amount(), - Output::Account(output.clone()).rent_cost(protocol_parameters.rent_parameters()) + Output::Account(output.clone()).rent_cost(protocol_parameters.rent_parameters().into()) ); assert_eq!(output.features().metadata(), Some(&metadata)); assert_eq!(output.features().sender(), Some(&sender_1)); diff --git a/sdk/tests/types/output/basic.rs b/sdk/tests/types/output/basic.rs index 5f219c3851..f8989304ba 100644 --- a/sdk/tests/types/output/basic.rs +++ b/sdk/tests/types/output/basic.rs @@ -51,7 +51,7 @@ fn builder() { let metadata = rand_metadata_feature(); let output = builder - .with_minimum_storage_deposit(protocol_parameters.rent_parameters()) + .with_minimum_storage_deposit(protocol_parameters.rent_parameters().into()) .add_unlock_condition(rand_address_unlock_condition()) .with_features([Feature::from(metadata.clone()), sender_1.into()]) .finish_with_params(ValidationParams::default().with_protocol_parameters(protocol_parameters.clone())) @@ -59,7 +59,7 @@ fn builder() { assert_eq!( output.amount(), - Output::Basic(output.clone()).rent_cost(protocol_parameters.rent_parameters()) + Output::Basic(output.clone()).rent_cost(protocol_parameters.rent_parameters().into()) ); assert_eq!(output.features().metadata(), Some(&metadata)); assert_eq!(output.features().sender(), Some(&sender_1)); diff --git a/sdk/tests/types/output/foundry.rs b/sdk/tests/types/output/foundry.rs index 80703ecf6c..db44ee9bd7 100644 --- a/sdk/tests/types/output/foundry.rs +++ b/sdk/tests/types/output/foundry.rs @@ -52,14 +52,14 @@ fn builder() { assert!(output.immutable_features().is_empty()); let output = builder - .with_minimum_storage_deposit(protocol_parameters.rent_parameters()) + .with_minimum_storage_deposit(protocol_parameters.rent_parameters().into()) .add_unlock_condition(ImmutableAccountAddressUnlockCondition::new(rand_account_address())) .finish_with_params(&protocol_parameters) .unwrap(); assert_eq!( output.amount(), - Output::Foundry(output).rent_cost(protocol_parameters.rent_parameters()) + Output::Foundry(output).rent_cost(protocol_parameters.rent_parameters().into()) ); } diff --git a/sdk/tests/types/output/nft.rs b/sdk/tests/types/output/nft.rs index da0c1867d0..f6eafaf5c8 100644 --- a/sdk/tests/types/output/nft.rs +++ b/sdk/tests/types/output/nft.rs @@ -53,14 +53,14 @@ fn builder() { assert!(output.immutable_features().is_empty()); let output = builder - .with_minimum_storage_deposit(protocol_parameters.rent_parameters()) + .with_minimum_storage_deposit(protocol_parameters.rent_parameters().into()) .add_unlock_condition(rand_address_unlock_condition()) .finish_with_params(protocol_parameters.token_supply()) .unwrap(); assert_eq!( output.amount(), - Output::Nft(output).rent_cost(protocol_parameters.rent_parameters()) + Output::Nft(output).rent_cost(protocol_parameters.rent_parameters().into()) ); } diff --git a/sdk/tests/wallet/claim_outputs.rs b/sdk/tests/wallet/claim_outputs.rs index f72f74dd60..cb599df340 100644 --- a/sdk/tests/wallet/claim_outputs.rs +++ b/sdk/tests/wallet/claim_outputs.rs @@ -127,11 +127,11 @@ async fn claim_2_basic_outputs_no_outputs_in_claim_account() -> Result<()> { let account_1 = wallet.create_account().finish().await?; let token_supply = account_0.client().get_token_supply().await?; - let rent_params = account_0.client().get_rent_parameters().await?; + let rent_struct = account_0.client().get_rent_parameters().await?.into(); // TODO more fitting value let expiration_slot = account_0.client().get_slot_index().await? + 86400; - let output = BasicOutputBuilder::new_with_minimum_storage_deposit(rent_params) + let output = BasicOutputBuilder::new_with_minimum_storage_deposit(rent_struct) .add_unlock_condition(AddressUnlockCondition::new( *account_1.addresses().await?[0].address().as_ref(), )) @@ -322,13 +322,13 @@ async fn claim_2_native_tokens_no_outputs_in_claim_account() -> Result<()> { .await?; account_0.sync(None).await?; - let rent_params = account_0.client().get_rent_parameters().await?; + let rent_strcut = account_0.client().get_rent_parameters().await?.into(); let token_supply = account_0.client().get_token_supply().await?; let tx = account_0 .send_outputs( [ - BasicOutputBuilder::new_with_minimum_storage_deposit(rent_params) + BasicOutputBuilder::new_with_minimum_storage_deposit(rent_strcut) .add_unlock_condition(AddressUnlockCondition::new( *account_1.addresses().await?[0].address().as_ref(), )) @@ -338,7 +338,7 @@ async fn claim_2_native_tokens_no_outputs_in_claim_account() -> Result<()> { )?) .add_native_token(NativeToken::new(create_tx_0.token_id, native_token_amount)?) .finish_output(token_supply)?, - BasicOutputBuilder::new_with_minimum_storage_deposit(rent_params) + BasicOutputBuilder::new_with_minimum_storage_deposit(rent_strcut) .add_unlock_condition(AddressUnlockCondition::new( *account_1.addresses().await?[0].address().as_ref(), )) diff --git a/sdk/tests/wallet/output_preparation.rs b/sdk/tests/wallet/output_preparation.rs index ceb92acd42..58560f6556 100644 --- a/sdk/tests/wallet/output_preparation.rs +++ b/sdk/tests/wallet/output_preparation.rs @@ -409,8 +409,8 @@ async fn output_preparation() -> Result<()> { None, ) .await?; - let rent_params = wallet.client().get_rent_parameters().await?; - let minimum_storage_deposit = output.rent_cost(rent_params); + let rent_struct = wallet.client().get_rent_parameters().await?.into(); + let minimum_storage_deposit = output.rent_cost(rent_struct); assert_eq!(output.amount(), minimum_storage_deposit); assert_eq!(output.amount(), 187900); let sdr = output.unlock_conditions().unwrap().storage_deposit_return().unwrap(); @@ -433,7 +433,7 @@ async fn output_preparation_sdr() -> Result<()> { let wallet = make_wallet(storage_path, None, None).await?; let account = &create_accounts_with_funds(&wallet, 1).await?[0]; - let rent_params = account.client().get_rent_parameters().await?; + let rent_struct = account.client().get_rent_parameters().await?.into(); let token_supply = account.client().get_token_supply().await?; let recipient_address_bech32 = String::from("rms1qpszqzadsym6wpppd6z037dvlejmjuke7s24hm95s9fg9vpua7vluaw60xu"); @@ -455,7 +455,7 @@ async fn output_preparation_sdr() -> Result<()> { ) .await?; // Check if the output has enough amount to cover the storage deposit - output.verify_storage_deposit(rent_params, token_supply)?; + output.verify_storage_deposit(rent_struct, token_supply)?; assert_eq!(output.amount(), 50601); // address and sdr unlock condition assert_eq!(output.unlock_conditions().unwrap().len(), 2); @@ -476,7 +476,7 @@ async fn output_preparation_sdr() -> Result<()> { ) .await?; // Check if the output has enough amount to cover the storage deposit - output.verify_storage_deposit(rent_params, token_supply)?; + output.verify_storage_deposit(rent_struct, token_supply)?; assert_eq!(output.amount(), 85199); // address and sdr unlock condition assert_eq!(output.unlock_conditions().unwrap().len(), 2); @@ -501,7 +501,7 @@ async fn output_preparation_sdr() -> Result<()> { ) .await?; // Check if the output has enough amount to cover the storage deposit - output.verify_storage_deposit(rent_params, token_supply)?; + output.verify_storage_deposit(rent_struct, token_supply)?; assert_eq!(output.amount(), 85199); // address and sdr unlock condition assert_eq!(output.unlock_conditions().unwrap().len(), 2); @@ -526,7 +526,7 @@ async fn output_preparation_sdr() -> Result<()> { ) .await?; // Check if the output has enough amount to cover the storage deposit - output.verify_storage_deposit(rent_params, token_supply)?; + output.verify_storage_deposit(rent_struct, token_supply)?; // The additional 1 amount will be added, because the storage deposit should be gifted and not returned assert_eq!(output.amount(), 42600); // storage deposit gifted, only address unlock condition @@ -614,11 +614,11 @@ async fn prepare_output_remainder_dust() -> Result<()> { let addresses = &accounts[1].addresses().await?; let address = addresses[0].address(); - let rent_params = account.client().get_rent_parameters().await?; + let rent_struct = account.client().get_rent_parameters().await?.into(); let token_supply = account.client().get_token_supply().await?; let balance = account.sync(None).await?; - let minimum_required_storage_deposit = MinimumStorageDepositBasicOutput::new(rent_params, token_supply).finish()?; + let minimum_required_storage_deposit = MinimumStorageDepositBasicOutput::new(rent_struct, token_supply).finish()?; // Send away most balance so we can test with leaving dust let output = account @@ -659,7 +659,7 @@ async fn prepare_output_remainder_dust() -> Result<()> { .await?; // Check if the output has enough amount to cover the storage deposit - output.verify_storage_deposit(rent_params, token_supply)?; + output.verify_storage_deposit(rent_struct, token_supply)?; // The left over 21299 is too small to keep, so we donate it assert_eq!(output.amount(), balance.base_coin().available()); // storage deposit gifted, only address unlock condition @@ -703,7 +703,7 @@ async fn prepare_output_remainder_dust() -> Result<()> { .await?; // Check if the output has enough amount to cover the storage deposit - output.verify_storage_deposit(rent_params, token_supply)?; + output.verify_storage_deposit(rent_struct, token_supply)?; // We use excess if leftover is too small, so amount == all available balance assert_eq!(output.amount(), 63900); // storage deposit gifted, only address unlock condition @@ -727,7 +727,7 @@ async fn prepare_output_remainder_dust() -> Result<()> { .await?; // Check if the output has enough amount to cover the storage deposit - output.verify_storage_deposit(rent_params, token_supply)?; + output.verify_storage_deposit(rent_struct, token_supply)?; // We use excess if leftover is too small, so amount == all available balance assert_eq!(output.amount(), 63900); // storage deposit returned, address and SDR unlock condition @@ -849,8 +849,8 @@ async fn prepare_existing_nft_output_gift() -> Result<()> { .as_nft() .clone(); - let rent_params = wallet.client().get_rent_parameters().await?; - let minimum_storage_deposit = Output::Nft(nft.clone()).rent_cost(rent_params); + let rent_struct = wallet.client().get_rent_parameters().await?.into(); + let minimum_storage_deposit = Output::Nft(nft.clone()).rent_cost(rent_struct); assert_eq!(nft.amount(), minimum_storage_deposit); assert_eq!(nft.amount(), 52300); From 6b0fcf6c3d23fc1598918f411b381a686e461e20 Mon Sep 17 00:00:00 2001 From: Alexander Schmidt Date: Fri, 6 Oct 2023 18:14:28 +0200 Subject: [PATCH 05/10] rename trait fn --- sdk/src/types/block/address/account.rs | 2 +- sdk/src/types/block/address/ed25519.rs | 2 +- sdk/src/types/block/address/mod.rs | 8 ++++---- sdk/src/types/block/address/nft.rs | 2 +- sdk/src/types/block/output/account.rs | 10 +++++----- sdk/src/types/block/output/basic.rs | 8 ++++---- sdk/src/types/block/output/delegation.rs | 4 ++-- sdk/src/types/block/output/feature/block_issuer.rs | 10 +++++----- sdk/src/types/block/output/feature/issuer.rs | 4 ++-- sdk/src/types/block/output/feature/mod.rs | 6 +++--- sdk/src/types/block/output/foundry.rs | 12 ++++++------ sdk/src/types/block/output/mod.rs | 12 ++++++------ sdk/src/types/block/output/native_token.rs | 6 +++--- sdk/src/types/block/output/nft.rs | 10 +++++----- sdk/src/types/block/output/token_scheme/mod.rs | 4 ++-- sdk/src/types/block/output/token_scheme/simple.rs | 2 +- sdk/src/types/block/output/unlock_condition/mod.rs | 6 +++--- sdk/src/types/block/rent.rs | 14 +++++++------- 18 files changed, 61 insertions(+), 61 deletions(-) diff --git a/sdk/src/types/block/address/account.rs b/sdk/src/types/block/address/account.rs index e8b5c35b0d..8ce13ce512 100644 --- a/sdk/src/types/block/address/account.rs +++ b/sdk/src/types/block/address/account.rs @@ -62,7 +62,7 @@ impl core::fmt::Debug for AccountAddress { } impl StorageScore for AccountAddress { - fn score(&self, _rent_struct: RentStructure) -> u64 { + fn storage_score(&self, _rent_struct: RentStructure) -> u64 { 0 } } diff --git a/sdk/src/types/block/address/ed25519.rs b/sdk/src/types/block/address/ed25519.rs index b63e070515..aa09608318 100644 --- a/sdk/src/types/block/address/ed25519.rs +++ b/sdk/src/types/block/address/ed25519.rs @@ -55,7 +55,7 @@ impl core::fmt::Debug for Ed25519Address { } impl StorageScore for Ed25519Address { - fn score(&self, _rent_struct: RentStructure) -> u64 { + fn storage_score(&self, _rent_struct: RentStructure) -> u64 { 0 } } diff --git a/sdk/src/types/block/address/mod.rs b/sdk/src/types/block/address/mod.rs index d82e23b60e..87d778c797 100644 --- a/sdk/src/types/block/address/mod.rs +++ b/sdk/src/types/block/address/mod.rs @@ -216,11 +216,11 @@ impl From<&Self> for Address { } impl StorageScore for Address { - fn score(&self, rent_struct: RentStructure) -> u64 { + fn storage_score(&self, rent_struct: RentStructure) -> u64 { match self { - Self::Account(account) => account.score(rent_struct), - Self::Ed25519(ed25519) => ed25519.score(rent_struct), - Self::Nft(nft) => nft.score(rent_struct), + Self::Account(account) => account.storage_score(rent_struct), + Self::Ed25519(ed25519) => ed25519.storage_score(rent_struct), + Self::Nft(nft) => nft.storage_score(rent_struct), // TODO: other address types once merged } } diff --git a/sdk/src/types/block/address/nft.rs b/sdk/src/types/block/address/nft.rs index 10f622be7e..ab34a526e9 100644 --- a/sdk/src/types/block/address/nft.rs +++ b/sdk/src/types/block/address/nft.rs @@ -62,7 +62,7 @@ impl core::fmt::Debug for NftAddress { } impl StorageScore for NftAddress { - fn score(&self, _rent_struct: RentStructure) -> u64 { + fn storage_score(&self, _rent_struct: RentStructure) -> u64 { 0 } } diff --git a/sdk/src/types/block/output/account.rs b/sdk/src/types/block/output/account.rs index af3578f733..ff0dd9d436 100644 --- a/sdk/src/types/block/output/account.rs +++ b/sdk/src/types/block/output/account.rs @@ -745,13 +745,13 @@ impl Packable for AccountOutput { } impl StorageScore for AccountOutput { - fn score(&self, rent_struct: RentStructure) -> u64 { + fn storage_score(&self, rent_struct: RentStructure) -> u64 { storage_score_offset_output(rent_struct) + self.packed_len() as u64 * rent_struct.storage_score_factor_data() as u64 - + self.native_tokens().score(rent_struct) - + self.unlock_conditions().score(rent_struct) - + self.features().score(rent_struct) - + self.immutable_features().score(rent_struct) + + self.native_tokens().storage_score(rent_struct) + + self.unlock_conditions().storage_score(rent_struct) + + self.features().storage_score(rent_struct) + + self.immutable_features().storage_score(rent_struct) } } diff --git a/sdk/src/types/block/output/basic.rs b/sdk/src/types/block/output/basic.rs index ff8de7c29a..bf71b9bd44 100644 --- a/sdk/src/types/block/output/basic.rs +++ b/sdk/src/types/block/output/basic.rs @@ -334,12 +334,12 @@ impl BasicOutput { } impl StorageScore for BasicOutput { - fn score(&self, rent_struct: RentStructure) -> u64 { + fn storage_score(&self, rent_struct: RentStructure) -> u64 { storage_score_offset_output(rent_struct) + self.packed_len() as u64 * rent_struct.storage_score_factor_data() as u64 - + self.native_tokens().score(rent_struct) - + self.unlock_conditions().score(rent_struct) - + self.features().score(rent_struct) + + self.native_tokens().storage_score(rent_struct) + + self.unlock_conditions().storage_score(rent_struct) + + self.features().storage_score(rent_struct) } } diff --git a/sdk/src/types/block/output/delegation.rs b/sdk/src/types/block/output/delegation.rs index ae2d4f00c6..e928189178 100644 --- a/sdk/src/types/block/output/delegation.rs +++ b/sdk/src/types/block/output/delegation.rs @@ -458,11 +458,11 @@ impl Packable for DelegationOutput { } impl StorageScore for DelegationOutput { - fn score(&self, rent_struct: RentStructure) -> u64 { + fn storage_score(&self, rent_struct: RentStructure) -> u64 { storage_score_offset_output(rent_struct) + rent_struct.storage_score_offset_delegation() + self.packed_len() as u64 * rent_struct.storage_score_factor_data() as u64 - + self.unlock_conditions().score(rent_struct) + + self.unlock_conditions().storage_score(rent_struct) } } diff --git a/sdk/src/types/block/output/feature/block_issuer.rs b/sdk/src/types/block/output/feature/block_issuer.rs index 3bb6e8dc0b..92c793cae3 100644 --- a/sdk/src/types/block/output/feature/block_issuer.rs +++ b/sdk/src/types/block/output/feature/block_issuer.rs @@ -62,9 +62,9 @@ impl BlockIssuerKey { } impl StorageScore for BlockIssuerKey { - fn score(&self, rent_struct: RentStructure) -> u64 { + fn storage_score(&self, rent_struct: RentStructure) -> u64 { match self { - Self::Ed25519(key) => key.score(rent_struct), + Self::Ed25519(key) => key.storage_score(rent_struct), } } } @@ -118,7 +118,7 @@ impl Packable for Ed25519BlockIssuerKey { } impl StorageScore for Ed25519BlockIssuerKey { - fn score(&self, rent_struct: RentStructure) -> u64 { + fn storage_score(&self, rent_struct: RentStructure) -> u64 { rent_struct.storage_score_offset_ed25519_block_issuer_key() } } @@ -206,8 +206,8 @@ impl BlockIssuerKeys { } impl StorageScore for BlockIssuerKeys { - fn score(&self, rent_struct: RentStructure) -> u64 { - (*self).iter().map(|key| key.score(rent_struct)).sum() + fn storage_score(&self, rent_struct: RentStructure) -> u64 { + (*self).iter().map(|key| key.storage_score(rent_struct)).sum() } } diff --git a/sdk/src/types/block/output/feature/issuer.rs b/sdk/src/types/block/output/feature/issuer.rs index be5448177a..fc61921a45 100644 --- a/sdk/src/types/block/output/feature/issuer.rs +++ b/sdk/src/types/block/output/feature/issuer.rs @@ -30,8 +30,8 @@ impl IssuerFeature { } impl StorageScore for IssuerFeature { - fn score(&self, rent_struct: RentStructure) -> u64 { - self.0.score(rent_struct) + fn storage_score(&self, rent_struct: RentStructure) -> u64 { + self.0.storage_score(rent_struct) } } diff --git a/sdk/src/types/block/output/feature/mod.rs b/sdk/src/types/block/output/feature/mod.rs index 2130daecfa..dcbe47e70a 100644 --- a/sdk/src/types/block/output/feature/mod.rs +++ b/sdk/src/types/block/output/feature/mod.rs @@ -202,7 +202,7 @@ impl Feature { } impl StorageScore for Feature { - fn score(&self, rent_struct: RentStructure) -> u64 { + fn storage_score(&self, rent_struct: RentStructure) -> u64 { match self { Self::Sender(sender) => todo!(), Self::Issuer(issuer) => todo!(), @@ -331,8 +331,8 @@ impl Features { } impl StorageScore for Features { - fn score(&self, rent_struct: RentStructure) -> u64 { - self.0.iter().map(|f| f.score(rent_struct)).sum() + fn storage_score(&self, rent_struct: RentStructure) -> u64 { + self.0.iter().map(|f| f.storage_score(rent_struct)).sum() } } diff --git a/sdk/src/types/block/output/foundry.rs b/sdk/src/types/block/output/foundry.rs index d13d641c86..12611dadc7 100644 --- a/sdk/src/types/block/output/foundry.rs +++ b/sdk/src/types/block/output/foundry.rs @@ -660,14 +660,14 @@ impl Packable for FoundryOutput { } impl StorageScore for FoundryOutput { - fn score(&self, rent_struct: RentStructure) -> u64 { + fn storage_score(&self, rent_struct: RentStructure) -> u64 { storage_score_offset_output(rent_struct) + self.packed_len() as u64 * rent_struct.storage_score_factor_data() as u64 - + self.native_tokens().score(rent_struct) - + self.token_scheme().score(rent_struct) - + self.unlock_conditions().score(rent_struct) - + self.features().score(rent_struct) - + self.immutable_features().score(rent_struct) + + self.native_tokens().storage_score(rent_struct) + + self.token_scheme().storage_score(rent_struct) + + self.unlock_conditions().storage_score(rent_struct) + + self.features().storage_score(rent_struct) + + self.immutable_features().storage_score(rent_struct) } } diff --git a/sdk/src/types/block/output/mod.rs b/sdk/src/types/block/output/mod.rs index 3a5e3d1ab2..55dfd455f2 100644 --- a/sdk/src/types/block/output/mod.rs +++ b/sdk/src/types/block/output/mod.rs @@ -521,15 +521,15 @@ fn storage_score_offset_output(rent_struct: RentStructure) -> u64 { } impl StorageScore for Output { - fn score(&self, rent_struct: RentStructure) -> u64 { + fn storage_score(&self, rent_struct: RentStructure) -> u64 { // +1 score for the output kind rent_struct.storage_score_factor_data() as u64 * size_of::() as u64 + match self { - Self::Basic(basic) => basic.score(rent_struct), - Self::Account(account) => account.score(rent_struct), - Self::Foundry(foundry) => foundry.score(rent_struct), - Self::Nft(nft) => nft.score(rent_struct), - Self::Delegation(delegation) => delegation.score(rent_struct), + Self::Basic(basic) => basic.storage_score(rent_struct), + Self::Account(account) => account.storage_score(rent_struct), + Self::Foundry(foundry) => foundry.storage_score(rent_struct), + Self::Nft(nft) => nft.storage_score(rent_struct), + Self::Delegation(delegation) => delegation.storage_score(rent_struct), } } } diff --git a/sdk/src/types/block/output/native_token.rs b/sdk/src/types/block/output/native_token.rs index 06bd001e86..10d2e750e9 100644 --- a/sdk/src/types/block/output/native_token.rs +++ b/sdk/src/types/block/output/native_token.rs @@ -78,7 +78,7 @@ impl Ord for NativeToken { } impl StorageScore for NativeToken { - fn score(&self, rent_struct: RentStructure) -> u64 { + fn storage_score(&self, rent_struct: RentStructure) -> u64 { todo!("native token score") } } @@ -258,8 +258,8 @@ impl NativeTokens { } impl StorageScore for NativeTokens { - fn score(&self, rent_struct: RentStructure) -> u64 { - self.0.iter().map(|nt| nt.score(rent_struct)).sum() + fn storage_score(&self, rent_struct: RentStructure) -> u64 { + self.0.iter().map(|nt| nt.storage_score(rent_struct)).sum() } } diff --git a/sdk/src/types/block/output/nft.rs b/sdk/src/types/block/output/nft.rs index 1acd52c40b..330700b98c 100644 --- a/sdk/src/types/block/output/nft.rs +++ b/sdk/src/types/block/output/nft.rs @@ -523,13 +523,13 @@ impl Packable for NftOutput { } impl StorageScore for NftOutput { - fn score(&self, rent_struct: RentStructure) -> u64 { + fn storage_score(&self, rent_struct: RentStructure) -> u64 { storage_score_offset_output(rent_struct) + self.packed_len() as u64 * rent_struct.storage_score_factor_data() as u64 - + self.native_tokens().score(rent_struct) - + self.unlock_conditions().score(rent_struct) - + self.features().score(rent_struct) - + self.immutable_features().score(rent_struct) + + self.native_tokens().storage_score(rent_struct) + + self.unlock_conditions().storage_score(rent_struct) + + self.features().storage_score(rent_struct) + + self.immutable_features().storage_score(rent_struct) } } diff --git a/sdk/src/types/block/output/token_scheme/mod.rs b/sdk/src/types/block/output/token_scheme/mod.rs index 4e63076c89..cd0aae9965 100644 --- a/sdk/src/types/block/output/token_scheme/mod.rs +++ b/sdk/src/types/block/output/token_scheme/mod.rs @@ -50,9 +50,9 @@ impl TokenScheme { } impl StorageScore for TokenScheme { - fn score(&self, rent_struct: RentStructure) -> u64 { + fn storage_score(&self, rent_struct: RentStructure) -> u64 { match self { - Self::Simple(simple) => simple.score(rent_struct), + Self::Simple(simple) => simple.storage_score(rent_struct), } } } diff --git a/sdk/src/types/block/output/token_scheme/simple.rs b/sdk/src/types/block/output/token_scheme/simple.rs index e1250b93bb..9b62347ca8 100644 --- a/sdk/src/types/block/output/token_scheme/simple.rs +++ b/sdk/src/types/block/output/token_scheme/simple.rs @@ -107,7 +107,7 @@ impl Packable for SimpleTokenScheme { } impl StorageScore for SimpleTokenScheme { - fn score(&self, rent_struct: RentStructure) -> u64 { + fn storage_score(&self, rent_struct: RentStructure) -> u64 { 0 } } diff --git a/sdk/src/types/block/output/unlock_condition/mod.rs b/sdk/src/types/block/output/unlock_condition/mod.rs index f6cc8d19a8..ee01e76101 100644 --- a/sdk/src/types/block/output/unlock_condition/mod.rs +++ b/sdk/src/types/block/output/unlock_condition/mod.rs @@ -84,7 +84,7 @@ impl core::fmt::Debug for UnlockCondition { } impl StorageScore for UnlockCondition { - fn score(&self, rent_struct: RentStructure) -> u64 { + fn storage_score(&self, rent_struct: RentStructure) -> u64 { todo!("unlock condition score") } } @@ -458,8 +458,8 @@ impl UnlockConditions { } impl StorageScore for UnlockConditions { - fn score(&self, rent_struct: RentStructure) -> u64 { - self.0.iter().map(|uc| uc.score(rent_struct)).sum() + fn storage_score(&self, rent_struct: RentStructure) -> u64 { + self.0.iter().map(|uc| uc.storage_score(rent_struct)).sum() } } diff --git a/sdk/src/types/block/rent.rs b/sdk/src/types/block/rent.rs index f89c8e8c27..920f7b0db2 100644 --- a/sdk/src/types/block/rent.rs +++ b/sdk/src/types/block/rent.rs @@ -45,12 +45,12 @@ impl RentStructure { // set the storage score offset for implicit account creation addresses as // the difference between the storage score of the dummy account and the storage // score of the dummy basic output minus the storage score of the dummy address. - let dummy_basic_output_score = BasicOutput::dummy().score(rent_structure); - let dummy_address_score = Ed25519Address::dummy().score(rent_structure); + let dummy_basic_output_score = BasicOutput::dummy().storage_score(rent_structure); + let dummy_address_score = Ed25519Address::dummy().storage_score(rent_structure); let basic_score_without_address = dummy_basic_output_score .checked_sub(dummy_address_score) .expect("underflow"); - let dummy_account_output_score = AccountOutput::dummy().score(rent_structure); + let dummy_account_output_score = AccountOutput::dummy().storage_score(rent_structure); rent_structure.storage_score_offset_implicit_account_creation_address = dummy_account_output_score .checked_sub(basic_score_without_address) @@ -207,16 +207,16 @@ impl RentParameters { pub trait StorageScore { /// Computes the storage score given a [`RentStructure`]. Different fields in a type lead to different storage /// requirements for the ledger state. - fn score(&self, rent_struct: RentStructure) -> u64; + fn storage_score(&self, rent_struct: RentStructure) -> u64; /// Computes the rent cost given a [`RentStructure`]. fn rent_cost(&self, rent_struct: RentStructure) -> u64 { - rent_struct.storage_cost as u64 * self.score(rent_struct) + rent_struct.storage_cost as u64 * self.storage_score(rent_struct) } } impl StorageScore for [T; N] { - fn score(&self, rent_struct: RentStructure) -> u64 { - self.iter().map(|elem| elem.score(rent_struct)).sum() + fn storage_score(&self, rent_struct: RentStructure) -> u64 { + self.iter().map(|elem| elem.storage_score(rent_struct)).sum() } } From 6d1c4e1fac5be73cfbc51938b037d9ba0b31f6f0 Mon Sep 17 00:00:00 2001 From: Alexander Schmidt Date: Fri, 6 Oct 2023 18:43:12 +0200 Subject: [PATCH 06/10] complete feature storage scores --- sdk/src/types/block/output/feature/block_issuer.rs | 6 ++++++ sdk/src/types/block/output/feature/metadata.rs | 8 +++++++- sdk/src/types/block/output/feature/mod.rs | 12 ++++++------ sdk/src/types/block/output/feature/sender.rs | 10 +++++++++- sdk/src/types/block/output/feature/staking.rs | 10 +++++++++- sdk/src/types/block/output/feature/tag.rs | 10 +++++++++- 6 files changed, 46 insertions(+), 10 deletions(-) diff --git a/sdk/src/types/block/output/feature/block_issuer.rs b/sdk/src/types/block/output/feature/block_issuer.rs index 92c793cae3..4dba88498a 100644 --- a/sdk/src/types/block/output/feature/block_issuer.rs +++ b/sdk/src/types/block/output/feature/block_issuer.rs @@ -251,6 +251,12 @@ impl BlockIssuerFeature { } } +impl StorageScore for BlockIssuerFeature { + fn storage_score(&self, rent_struct: RentStructure) -> u64 { + self.block_issuer_keys.storage_score(rent_struct) + } +} + #[cfg(feature = "serde")] mod dto { use alloc::{string::String, vec::Vec}; diff --git a/sdk/src/types/block/output/feature/metadata.rs b/sdk/src/types/block/output/feature/metadata.rs index c8410c8edc..0f3601c941 100644 --- a/sdk/src/types/block/output/feature/metadata.rs +++ b/sdk/src/types/block/output/feature/metadata.rs @@ -6,7 +6,7 @@ use core::{ops::RangeInclusive, str::FromStr}; use packable::{bounded::BoundedU16, prefix::BoxedSlicePrefix}; -use crate::types::block::Error; +use crate::types::block::{Error, rent::{StorageScore, RentStructure}}; pub(crate) type MetadataFeatureLength = BoundedU16<{ *MetadataFeature::LENGTH_RANGE.start() }, { *MetadataFeature::LENGTH_RANGE.end() }>; @@ -97,6 +97,12 @@ impl core::fmt::Debug for MetadataFeature { } } +impl StorageScore for MetadataFeature { + fn storage_score(&self, rent_struct: RentStructure) -> u64 { + 0 + } +} + #[cfg(feature = "irc_27")] pub(crate) mod irc_27 { use alloc::{ diff --git a/sdk/src/types/block/output/feature/mod.rs b/sdk/src/types/block/output/feature/mod.rs index dcbe47e70a..996ddfedcd 100644 --- a/sdk/src/types/block/output/feature/mod.rs +++ b/sdk/src/types/block/output/feature/mod.rs @@ -204,12 +204,12 @@ impl Feature { impl StorageScore for Feature { fn storage_score(&self, rent_struct: RentStructure) -> u64 { match self { - Self::Sender(sender) => todo!(), - Self::Issuer(issuer) => todo!(), - Self::Metadata(metadata) => todo!(), - Self::Tag(tag) => todo!(), - Self::BlockIssuer(block_issuer) => todo!(), - Self::Staking(staking) => todo!(), + Self::Sender(sender) => sender.storage_score(rent_struct), + Self::Issuer(issuer) => issuer.storage_score(rent_struct), + Self::Metadata(metadata) => metadata.storage_score(rent_struct), + Self::Tag(tag) => tag.storage_score(rent_struct), + Self::BlockIssuer(block_issuer) => block_issuer.storage_score(rent_struct), + Self::Staking(staking) => staking.storage_score(rent_struct) } } } diff --git a/sdk/src/types/block/output/feature/sender.rs b/sdk/src/types/block/output/feature/sender.rs index 1faee6314a..81ca870753 100644 --- a/sdk/src/types/block/output/feature/sender.rs +++ b/sdk/src/types/block/output/feature/sender.rs @@ -3,7 +3,7 @@ use derive_more::From; -use crate::types::block::address::Address; +use crate::types::block::{address::Address, rent::{RentStructure, StorageScore}}; /// Identifies the validated sender of an output. #[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, From, packable::Packable)] @@ -26,6 +26,14 @@ impl SenderFeature { } } +impl StorageScore for SenderFeature { + fn storage_score(&self, rent_struct: RentStructure) -> u64 { + // TODO: In iota.go you can specify a closure f(rent_struct) -> u64 for this feature + // which immediately returns, hence overrides the default storage score. + self.0.storage_score(rent_struct) + } +} + #[cfg(feature = "serde")] pub(crate) mod dto { use serde::{Deserialize, Serialize}; diff --git a/sdk/src/types/block/output/feature/staking.rs b/sdk/src/types/block/output/feature/staking.rs index c7087d5fac..f4770503cd 100644 --- a/sdk/src/types/block/output/feature/staking.rs +++ b/sdk/src/types/block/output/feature/staking.rs @@ -1,7 +1,7 @@ // Copyright 2023 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 -use crate::types::block::slot::EpochIndex; +use crate::types::block::{slot::EpochIndex, rent::{RentStructure, StorageScore}}; /// Stakes coins to become eligible for committee selection, validate the network and receive Mana rewards. #[derive(Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, packable::Packable)] @@ -56,6 +56,14 @@ impl StakingFeature { } } +impl StorageScore for StakingFeature { + fn storage_score(&self, rent_struct: RentStructure) -> u64 { + // TODO: In iota.go you can specify a closure f(rent_struct) -> u64 for this feature + // which immediately returns, hence overrides the default storage score. + rent_struct.storage_score_offset_staking_feature() + } +} + #[cfg(feature = "serde")] pub(crate) mod dto { use serde::{Deserialize, Serialize}; diff --git a/sdk/src/types/block/output/feature/tag.rs b/sdk/src/types/block/output/feature/tag.rs index aa9ae7130f..e96c890019 100644 --- a/sdk/src/types/block/output/feature/tag.rs +++ b/sdk/src/types/block/output/feature/tag.rs @@ -6,7 +6,7 @@ use core::ops::RangeInclusive; use packable::{bounded::BoundedU8, prefix::BoxedSlicePrefix}; -use crate::types::block::Error; +use crate::types::block::{Error, rent::{StorageScore, RentStructure}}; pub(crate) type TagFeatureLength = BoundedU8<{ *TagFeature::LENGTH_RANGE.start() }, { *TagFeature::LENGTH_RANGE.end() }>; @@ -66,6 +66,14 @@ impl core::fmt::Debug for TagFeature { } } +impl StorageScore for TagFeature { + fn storage_score(&self, _rent_struct: RentStructure) -> u64 { + // TODO: In iota.go you can specify a closure f(rent_struct) -> u64 for this feature + // which immediately returns, hence overrides the default storage score. + 0 + } +} + #[cfg(feature = "serde")] pub(crate) mod dto { use alloc::borrow::Cow; From 1d063ab9d207004a776ed215336cb53eedb3ad49 Mon Sep 17 00:00:00 2001 From: Alexander Schmidt Date: Fri, 6 Oct 2023 18:57:38 +0200 Subject: [PATCH 07/10] complete unlock conditions storage scores --- sdk/src/types/block/output/feature/metadata.rs | 5 ++++- sdk/src/types/block/output/feature/mod.rs | 2 +- sdk/src/types/block/output/feature/sender.rs | 7 +++++-- sdk/src/types/block/output/feature/staking.rs | 7 +++++-- sdk/src/types/block/output/feature/tag.rs | 7 +++++-- sdk/src/types/block/output/native_token.rs | 2 +- .../types/block/output/unlock_condition/address.rs | 11 ++++++++++- .../block/output/unlock_condition/expiration.rs | 13 ++++++++++++- .../output/unlock_condition/governor_address.rs | 11 ++++++++++- .../unlock_condition/immutable_account_address.rs | 11 ++++++++++- sdk/src/types/block/output/unlock_condition/mod.rs | 14 +++++++++++++- .../unlock_condition/state_controller_address.rs | 12 +++++++++++- .../unlock_condition/storage_deposit_return.rs | 14 +++++++++++++- .../block/output/unlock_condition/timelock.rs | 12 +++++++++++- 14 files changed, 111 insertions(+), 17 deletions(-) diff --git a/sdk/src/types/block/output/feature/metadata.rs b/sdk/src/types/block/output/feature/metadata.rs index 0f3601c941..e4b96b2512 100644 --- a/sdk/src/types/block/output/feature/metadata.rs +++ b/sdk/src/types/block/output/feature/metadata.rs @@ -6,7 +6,10 @@ use core::{ops::RangeInclusive, str::FromStr}; use packable::{bounded::BoundedU16, prefix::BoxedSlicePrefix}; -use crate::types::block::{Error, rent::{StorageScore, RentStructure}}; +use crate::types::block::{ + rent::{RentStructure, StorageScore}, + Error, +}; pub(crate) type MetadataFeatureLength = BoundedU16<{ *MetadataFeature::LENGTH_RANGE.start() }, { *MetadataFeature::LENGTH_RANGE.end() }>; diff --git a/sdk/src/types/block/output/feature/mod.rs b/sdk/src/types/block/output/feature/mod.rs index 996ddfedcd..160ea1bb4b 100644 --- a/sdk/src/types/block/output/feature/mod.rs +++ b/sdk/src/types/block/output/feature/mod.rs @@ -209,7 +209,7 @@ impl StorageScore for Feature { Self::Metadata(metadata) => metadata.storage_score(rent_struct), Self::Tag(tag) => tag.storage_score(rent_struct), Self::BlockIssuer(block_issuer) => block_issuer.storage_score(rent_struct), - Self::Staking(staking) => staking.storage_score(rent_struct) + Self::Staking(staking) => staking.storage_score(rent_struct), } } } diff --git a/sdk/src/types/block/output/feature/sender.rs b/sdk/src/types/block/output/feature/sender.rs index 81ca870753..032b4b63d9 100644 --- a/sdk/src/types/block/output/feature/sender.rs +++ b/sdk/src/types/block/output/feature/sender.rs @@ -3,7 +3,10 @@ use derive_more::From; -use crate::types::block::{address::Address, rent::{RentStructure, StorageScore}}; +use crate::types::block::{ + address::Address, + rent::{RentStructure, StorageScore}, +}; /// Identifies the validated sender of an output. #[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, From, packable::Packable)] @@ -28,7 +31,7 @@ impl SenderFeature { impl StorageScore for SenderFeature { fn storage_score(&self, rent_struct: RentStructure) -> u64 { - // TODO: In iota.go you can specify a closure f(rent_struct) -> u64 for this feature + // TODO: In iota.go you can specify a closure f(rent_struct) -> u64 for this feature // which immediately returns, hence overrides the default storage score. self.0.storage_score(rent_struct) } diff --git a/sdk/src/types/block/output/feature/staking.rs b/sdk/src/types/block/output/feature/staking.rs index f4770503cd..8e8eafb54d 100644 --- a/sdk/src/types/block/output/feature/staking.rs +++ b/sdk/src/types/block/output/feature/staking.rs @@ -1,7 +1,10 @@ // Copyright 2023 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 -use crate::types::block::{slot::EpochIndex, rent::{RentStructure, StorageScore}}; +use crate::types::block::{ + rent::{RentStructure, StorageScore}, + slot::EpochIndex, +}; /// Stakes coins to become eligible for committee selection, validate the network and receive Mana rewards. #[derive(Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, packable::Packable)] @@ -58,7 +61,7 @@ impl StakingFeature { impl StorageScore for StakingFeature { fn storage_score(&self, rent_struct: RentStructure) -> u64 { - // TODO: In iota.go you can specify a closure f(rent_struct) -> u64 for this feature + // TODO: In iota.go you can specify a closure f(rent_struct) -> u64 for this feature // which immediately returns, hence overrides the default storage score. rent_struct.storage_score_offset_staking_feature() } diff --git a/sdk/src/types/block/output/feature/tag.rs b/sdk/src/types/block/output/feature/tag.rs index e96c890019..803e7c6b3b 100644 --- a/sdk/src/types/block/output/feature/tag.rs +++ b/sdk/src/types/block/output/feature/tag.rs @@ -6,7 +6,10 @@ use core::ops::RangeInclusive; use packable::{bounded::BoundedU8, prefix::BoxedSlicePrefix}; -use crate::types::block::{Error, rent::{StorageScore, RentStructure}}; +use crate::types::block::{ + rent::{RentStructure, StorageScore}, + Error, +}; pub(crate) type TagFeatureLength = BoundedU8<{ *TagFeature::LENGTH_RANGE.start() }, { *TagFeature::LENGTH_RANGE.end() }>; @@ -68,7 +71,7 @@ impl core::fmt::Debug for TagFeature { impl StorageScore for TagFeature { fn storage_score(&self, _rent_struct: RentStructure) -> u64 { - // TODO: In iota.go you can specify a closure f(rent_struct) -> u64 for this feature + // TODO: In iota.go you can specify a closure f(rent_struct) -> u64 for this feature // which immediately returns, hence overrides the default storage score. 0 } diff --git a/sdk/src/types/block/output/native_token.rs b/sdk/src/types/block/output/native_token.rs index 10d2e750e9..def9d88506 100644 --- a/sdk/src/types/block/output/native_token.rs +++ b/sdk/src/types/block/output/native_token.rs @@ -79,7 +79,7 @@ impl Ord for NativeToken { impl StorageScore for NativeToken { fn storage_score(&self, rent_struct: RentStructure) -> u64 { - todo!("native token score") + 0 } } diff --git a/sdk/src/types/block/output/unlock_condition/address.rs b/sdk/src/types/block/output/unlock_condition/address.rs index f1ad3005aa..07835019ea 100644 --- a/sdk/src/types/block/output/unlock_condition/address.rs +++ b/sdk/src/types/block/output/unlock_condition/address.rs @@ -3,7 +3,10 @@ use derive_more::From; -use crate::types::block::address::Address; +use crate::types::block::{ + address::Address, + rent::{RentStructure, StorageScore}, +}; /// Defines the Address that owns this output, that is, it can unlock it with the proper Unlock in a transaction. #[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, From, packable::Packable)] @@ -26,6 +29,12 @@ impl AddressUnlockCondition { } } +impl StorageScore for AddressUnlockCondition { + fn storage_score(&self, rent_struct: RentStructure) -> u64 { + self.0.storage_score(rent_struct) + } +} + #[cfg(feature = "serde")] pub(crate) mod dto { use serde::{Deserialize, Serialize}; diff --git a/sdk/src/types/block/output/unlock_condition/expiration.rs b/sdk/src/types/block/output/unlock_condition/expiration.rs index 185de6eb6a..059ea4ffe3 100644 --- a/sdk/src/types/block/output/unlock_condition/expiration.rs +++ b/sdk/src/types/block/output/unlock_condition/expiration.rs @@ -3,7 +3,12 @@ use derive_more::From; -use crate::types::block::{address::Address, slot::SlotIndex, Error}; +use crate::types::block::{ + address::Address, + rent::{RentStructure, StorageScore}, + slot::SlotIndex, + Error, +}; /// Defines an expiration slot index. Before the slot index is reached, only the Address defined in the Address /// Unlock Condition is allowed to unlock the output. Afterward, only the Return Address can unlock it. @@ -55,6 +60,12 @@ impl ExpirationUnlockCondition { } } +impl StorageScore for ExpirationUnlockCondition { + fn storage_score(&self, rent_struct: RentStructure) -> u64 { + self.return_address.storage_score(rent_struct) + } +} + #[inline] fn verify_slot_index(slot_index: &SlotIndex, _: &()) -> Result<(), Error> { if VERIFY && *slot_index == 0 { diff --git a/sdk/src/types/block/output/unlock_condition/governor_address.rs b/sdk/src/types/block/output/unlock_condition/governor_address.rs index 6ebb6cda8c..4e1b2c59f6 100644 --- a/sdk/src/types/block/output/unlock_condition/governor_address.rs +++ b/sdk/src/types/block/output/unlock_condition/governor_address.rs @@ -3,7 +3,10 @@ use derive_more::From; -use crate::types::block::address::Address; +use crate::types::block::{ + address::Address, + rent::{RentStructure, StorageScore}, +}; /// Defines the Governor Address that owns this output, that is, it can unlock it with the proper Unlock in a /// transaction that governance transitions the account output. @@ -28,6 +31,12 @@ impl GovernorAddressUnlockCondition { } } +impl StorageScore for GovernorAddressUnlockCondition { + fn storage_score(&self, rent_struct: RentStructure) -> u64 { + self.0.storage_score(rent_struct) + } +} + #[cfg(feature = "serde")] pub(crate) mod dto { use serde::{Deserialize, Serialize}; diff --git a/sdk/src/types/block/output/unlock_condition/immutable_account_address.rs b/sdk/src/types/block/output/unlock_condition/immutable_account_address.rs index 5277aec2df..79fbdc5bcb 100644 --- a/sdk/src/types/block/output/unlock_condition/immutable_account_address.rs +++ b/sdk/src/types/block/output/unlock_condition/immutable_account_address.rs @@ -3,7 +3,10 @@ use derive_more::From; -use crate::types::block::address::AccountAddress; +use crate::types::block::{ + address::AccountAddress, + rent::{RentStructure, StorageScore}, +}; /// Defines the permanent [`AccountAddress`] that owns this output. #[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, From, packable::Packable)] @@ -26,6 +29,12 @@ impl ImmutableAccountAddressUnlockCondition { } } +impl StorageScore for ImmutableAccountAddressUnlockCondition { + fn storage_score(&self, rent_struct: RentStructure) -> u64 { + self.0.storage_score(rent_struct) + } +} + #[cfg(feature = "serde")] mod dto { use serde::{Deserialize, Serialize}; diff --git a/sdk/src/types/block/output/unlock_condition/mod.rs b/sdk/src/types/block/output/unlock_condition/mod.rs index ee01e76101..642a8471f2 100644 --- a/sdk/src/types/block/output/unlock_condition/mod.rs +++ b/sdk/src/types/block/output/unlock_condition/mod.rs @@ -85,7 +85,19 @@ impl core::fmt::Debug for UnlockCondition { impl StorageScore for UnlockCondition { fn storage_score(&self, rent_struct: RentStructure) -> u64 { - todo!("unlock condition score") + match self { + Self::Address(address) => address.storage_score(rent_struct), + Self::StorageDepositReturn(storage_deposit_return) => storage_deposit_return.storage_score(rent_struct), + Self::Timelock(timelock) => timelock.storage_score(rent_struct), + Self::Expiration(expiration) => expiration.storage_score(rent_struct), + Self::StateControllerAddress(state_controller_address) => { + state_controller_address.storage_score(rent_struct) + } + Self::GovernorAddress(governor_address) => governor_address.storage_score(rent_struct), + Self::ImmutableAccountAddress(immutable_account_address) => { + immutable_account_address.storage_score(rent_struct) + } + } } } diff --git a/sdk/src/types/block/output/unlock_condition/state_controller_address.rs b/sdk/src/types/block/output/unlock_condition/state_controller_address.rs index 88281e0ac1..b961c34194 100644 --- a/sdk/src/types/block/output/unlock_condition/state_controller_address.rs +++ b/sdk/src/types/block/output/unlock_condition/state_controller_address.rs @@ -3,7 +3,11 @@ use derive_more::From; -use crate::types::block::address::Address; +use super::ImmutableAccountAddressUnlockCondition; +use crate::types::block::{ + address::Address, + rent::{RentStructure, StorageScore}, +}; /// Defines the State Controller Address that owns this output, that is, it can unlock it with the proper Unlock in a /// transaction that state transitions the account output. @@ -28,6 +32,12 @@ impl StateControllerAddressUnlockCondition { } } +impl StorageScore for StateControllerAddressUnlockCondition { + fn storage_score(&self, rent_struct: RentStructure) -> u64 { + self.0.storage_score(rent_struct) + } +} + #[cfg(feature = "serde")] pub(crate) mod dto { use serde::{Deserialize, Serialize}; diff --git a/sdk/src/types/block/output/unlock_condition/storage_deposit_return.rs b/sdk/src/types/block/output/unlock_condition/storage_deposit_return.rs index bec25f3eca..3ec738592a 100644 --- a/sdk/src/types/block/output/unlock_condition/storage_deposit_return.rs +++ b/sdk/src/types/block/output/unlock_condition/storage_deposit_return.rs @@ -1,7 +1,13 @@ // Copyright 2021 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 -use crate::types::block::{address::Address, output::verify_output_amount, protocol::ProtocolParameters, Error}; +use crate::types::block::{ + address::Address, + output::verify_output_amount, + protocol::ProtocolParameters, + rent::{RentStructure, StorageScore}, + Error, +}; /// Defines the amount of IOTAs used as storage deposit that have to be returned to the return [`Address`]. #[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, packable::Packable)] @@ -43,6 +49,12 @@ impl StorageDepositReturnUnlockCondition { } } +impl StorageScore for StorageDepositReturnUnlockCondition { + fn storage_score(&self, rent_struct: RentStructure) -> u64 { + self.return_address.storage_score(rent_struct) + } +} + fn verify_amount(amount: u64, token_supply: u64) -> Result<(), Error> { if VERIFY { verify_output_amount(amount, token_supply).map_err(|_| Error::InvalidStorageDepositAmount(amount))?; diff --git a/sdk/src/types/block/output/unlock_condition/timelock.rs b/sdk/src/types/block/output/unlock_condition/timelock.rs index 9a93d65ddc..c6b21ff88c 100644 --- a/sdk/src/types/block/output/unlock_condition/timelock.rs +++ b/sdk/src/types/block/output/unlock_condition/timelock.rs @@ -3,7 +3,11 @@ use derive_more::From; -use crate::types::block::{slot::SlotIndex, Error}; +use crate::types::block::{ + rent::{RentStructure, StorageScore}, + slot::SlotIndex, + Error, +}; /// Defines a slot index until which the output can not be unlocked. #[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, From, packable::Packable)] @@ -31,6 +35,12 @@ impl TimelockUnlockCondition { } } +impl StorageScore for TimelockUnlockCondition { + fn storage_score(&self, _rent_struct: RentStructure) -> u64 { + 0 + } +} + #[inline] fn verify_slot_index(slot_index: &SlotIndex, _: &()) -> Result<(), Error> { if VERIFY && *slot_index == 0 { From 6b5fadca8776e59945e27d1c89a7a84f5fa68bb8 Mon Sep 17 00:00:00 2001 From: Alexander Schmidt Date: Tue, 10 Oct 2023 16:18:18 +0200 Subject: [PATCH 08/10] rename and move rent.rs --- bindings/core/src/method/utils.rs | 3 +-- bindings/core/src/method_handler/client.rs | 2 +- bindings/core/src/method_handler/utils.rs | 2 +- .../input_selection/remainder.rs | 2 +- .../input_selection/requirement/amount.rs | 2 +- sdk/src/client/core.rs | 5 +++- sdk/src/types/block/address/account.rs | 2 +- sdk/src/types/block/address/ed25519.rs | 2 +- sdk/src/types/block/address/mod.rs | 2 +- sdk/src/types/block/address/nft.rs | 2 +- sdk/src/types/block/mod.rs | 2 -- sdk/src/types/block/output/account.rs | 3 +-- sdk/src/types/block/output/basic.rs | 3 +-- sdk/src/types/block/output/delegation.rs | 3 +-- .../block/output/feature/block_issuer.rs | 2 +- sdk/src/types/block/output/feature/issuer.rs | 2 +- .../types/block/output/feature/metadata.rs | 2 +- sdk/src/types/block/output/feature/mod.rs | 2 +- sdk/src/types/block/output/feature/sender.rs | 2 +- sdk/src/types/block/output/feature/staking.rs | 2 +- sdk/src/types/block/output/feature/tag.rs | 2 +- sdk/src/types/block/output/foundry.rs | 3 +-- sdk/src/types/block/output/mod.rs | 3 +-- sdk/src/types/block/output/native_token.rs | 2 +- sdk/src/types/block/output/nft.rs | 3 +-- .../types/block/output/token_scheme/mod.rs | 2 +- .../types/block/output/token_scheme/simple.rs | 2 +- .../block/output/unlock_condition/address.rs | 2 +- .../output/unlock_condition/expiration.rs | 2 +- .../unlock_condition/governor_address.rs | 2 +- .../immutable_account_address.rs | 2 +- .../block/output/unlock_condition/mod.rs | 3 +-- .../state_controller_address.rs | 2 +- .../storage_deposit_return.rs | 3 +-- .../block/output/unlock_condition/timelock.rs | 2 +- .../payload/transaction/essence/regular.rs | 3 +-- .../block/{protocol.rs => protocol/mod.rs} | 7 +++-- .../{rent.rs => protocol/storage_score.rs} | 27 +++++++++---------- sdk/src/wallet/account/mod.rs | 2 +- sdk/src/wallet/account/operations/balance.rs | 2 +- .../account/operations/output_claiming.rs | 2 +- .../high_level/minting/create_native_token.rs | 2 +- .../high_level/minting/mint_nfts.rs | 2 +- .../operations/transaction/high_level/send.rs | 2 +- .../high_level/send_native_tokens.rs | 2 +- .../operations/transaction/prepare_output.rs | 2 +- sdk/tests/types/block_id.rs | 5 ++-- sdk/tests/types/output/account.rs | 3 +-- sdk/tests/types/output/basic.rs | 3 +-- sdk/tests/types/output/foundry.rs | 3 +-- sdk/tests/types/output/nft.rs | 3 +-- sdk/tests/wallet/claim_outputs.rs | 6 ++--- sdk/tests/wallet/output_preparation.rs | 2 +- 53 files changed, 75 insertions(+), 85 deletions(-) rename sdk/src/types/block/{protocol.rs => protocol/mod.rs} (98%) rename sdk/src/types/block/{rent.rs => protocol/storage_score.rs} (90%) diff --git a/bindings/core/src/method/utils.rs b/bindings/core/src/method/utils.rs index 552aeef331..0d0edc58ec 100644 --- a/bindings/core/src/method/utils.rs +++ b/bindings/core/src/method/utils.rs @@ -9,8 +9,7 @@ use iota_sdk::types::block::{ dto::{TransactionEssenceDto, TransactionPayloadDto}, TransactionId, }, - protocol::ProtocolParameters, - rent::RentParameters, + protocol::{ProtocolParameters, RentParameters}, signature::Ed25519Signature, slot::SlotCommitment, BlockWrapperDto, diff --git a/bindings/core/src/method_handler/client.rs b/bindings/core/src/method_handler/client.rs index a488b80957..50cf94af9f 100644 --- a/bindings/core/src/method_handler/client.rs +++ b/bindings/core/src/method_handler/client.rs @@ -12,7 +12,7 @@ use iota_sdk::{ dto::OutputDto, AccountOutput, BasicOutput, FoundryOutput, NftOutput, Output, OutputBuilderAmount, }, payload::Payload, - rent::{RentStructure, StorageScore}, + protocol::{RentStructure, StorageScore}, BlockWrapper, BlockWrapperDto, }, TryFromDto, diff --git a/bindings/core/src/method_handler/utils.rs b/bindings/core/src/method_handler/utils.rs index 0ee053e16b..2b016213a8 100644 --- a/bindings/core/src/method_handler/utils.rs +++ b/bindings/core/src/method_handler/utils.rs @@ -10,7 +10,7 @@ use iota_sdk::{ input::UtxoInput, output::{AccountId, FoundryId, InputsCommitment, NftId, Output, OutputId, TokenId}, payload::{transaction::TransactionEssence, TransactionPayload}, - rent::StorageScore, + protocol::StorageScore, BlockWrapper, }, TryFromDto, diff --git a/sdk/src/client/api/block_builder/input_selection/remainder.rs b/sdk/src/client/api/block_builder/input_selection/remainder.rs index 194c881192..741af56d19 100644 --- a/sdk/src/client/api/block_builder/input_selection/remainder.rs +++ b/sdk/src/client/api/block_builder/input_selection/remainder.rs @@ -16,7 +16,7 @@ use crate::{ types::block::{ address::{Address, Ed25519Address}, output::{unlock_condition::AddressUnlockCondition, BasicOutputBuilder, NativeTokensBuilder, Output}, - rent::RentStructure, + protocol::RentStructure, }, }; diff --git a/sdk/src/client/api/block_builder/input_selection/requirement/amount.rs b/sdk/src/client/api/block_builder/input_selection/requirement/amount.rs index 881c759936..3ff7b260c5 100644 --- a/sdk/src/client/api/block_builder/input_selection/requirement/amount.rs +++ b/sdk/src/client/api/block_builder/input_selection/requirement/amount.rs @@ -13,7 +13,7 @@ use crate::{ unlock_condition::StorageDepositReturnUnlockCondition, AccountOutputBuilder, AccountTransition, FoundryOutputBuilder, NftOutputBuilder, Output, OutputId, }, - rent::{RentStructure, StorageScore}, + protocol::{RentStructure, StorageScore}, slot::SlotIndex, }, }; diff --git a/sdk/src/client/core.rs b/sdk/src/client/core.rs index f8efcb9ca1..65f9f4796c 100644 --- a/sdk/src/client/core.rs +++ b/sdk/src/client/core.rs @@ -24,7 +24,10 @@ use crate::{ node_manager::NodeManager, Error, }, - types::block::{address::Hrp, protocol::ProtocolParameters, rent::RentParameters}, + types::block::{ + address::Hrp, + protocol::{ProtocolParameters, RentParameters}, + }, }; /// An IOTA node client. diff --git a/sdk/src/types/block/address/account.rs b/sdk/src/types/block/address/account.rs index 8ce13ce512..afb184a905 100644 --- a/sdk/src/types/block/address/account.rs +++ b/sdk/src/types/block/address/account.rs @@ -7,7 +7,7 @@ use derive_more::{AsRef, Deref, From}; use crate::types::block::{ output::AccountId, - rent::{RentStructure, StorageScore}, + protocol::{RentStructure, StorageScore}, Error, }; diff --git a/sdk/src/types/block/address/ed25519.rs b/sdk/src/types/block/address/ed25519.rs index aa09608318..3442f6cf14 100644 --- a/sdk/src/types/block/address/ed25519.rs +++ b/sdk/src/types/block/address/ed25519.rs @@ -7,7 +7,7 @@ use crypto::signatures::ed25519::PublicKey; use derive_more::{AsRef, Deref, From}; use crate::types::block::{ - rent::{RentStructure, StorageScore}, + protocol::{RentStructure, StorageScore}, Error, }; diff --git a/sdk/src/types/block/address/mod.rs b/sdk/src/types/block/address/mod.rs index 87d778c797..732fb126c2 100644 --- a/sdk/src/types/block/address/mod.rs +++ b/sdk/src/types/block/address/mod.rs @@ -17,7 +17,7 @@ pub use self::{ use crate::{ types::block::{ output::{Output, OutputId}, - rent::{RentParameters, RentStructure, StorageScore}, + protocol::{RentParameters, RentStructure, StorageScore}, semantic::{TransactionFailureReason, ValidationContext}, signature::Signature, unlock::Unlock, diff --git a/sdk/src/types/block/address/nft.rs b/sdk/src/types/block/address/nft.rs index ab34a526e9..16b419c849 100644 --- a/sdk/src/types/block/address/nft.rs +++ b/sdk/src/types/block/address/nft.rs @@ -7,7 +7,7 @@ use derive_more::{AsRef, Deref, From}; use crate::types::block::{ output::NftId, - rent::{RentStructure, StorageScore}, + protocol::{RentStructure, StorageScore}, Error, }; diff --git a/sdk/src/types/block/mod.rs b/sdk/src/types/block/mod.rs index d2040863a4..de471203d6 100644 --- a/sdk/src/types/block/mod.rs +++ b/sdk/src/types/block/mod.rs @@ -31,8 +31,6 @@ pub mod protocol; /// A module that provides utilities for random generation of types. #[cfg(feature = "rand")] pub mod rand; -/// A module that provides types and rules for rent cost computation. -pub mod rent; /// A module that provides types and rules for semantic validation. pub mod semantic; /// A module that provides types and syntactic validations of signatures. diff --git a/sdk/src/types/block/output/account.rs b/sdk/src/types/block/output/account.rs index 388f979546..7a00953d5d 100644 --- a/sdk/src/types/block/output/account.rs +++ b/sdk/src/types/block/output/account.rs @@ -29,8 +29,7 @@ use crate::types::{ verify_output_amount_min, verify_output_amount_packable, verify_output_amount_supply, ChainId, NativeToken, NativeTokens, Output, OutputBuilderAmount, OutputId, StateTransitionError, StateTransitionVerifier, }, - protocol::ProtocolParameters, - rent::{RentParameters, RentStructure, StorageScore}, + protocol::{ProtocolParameters, RentParameters, RentStructure, StorageScore}, semantic::{TransactionFailureReason, ValidationContext}, unlock::Unlock, Error, diff --git a/sdk/src/types/block/output/basic.rs b/sdk/src/types/block/output/basic.rs index 0f33770607..53e68c9ae5 100644 --- a/sdk/src/types/block/output/basic.rs +++ b/sdk/src/types/block/output/basic.rs @@ -17,8 +17,7 @@ use crate::types::{ verify_output_amount_min, verify_output_amount_packable, verify_output_amount_supply, NativeToken, NativeTokens, Output, OutputBuilderAmount, OutputId, }, - protocol::ProtocolParameters, - rent::{RentParameters, RentStructure, StorageScore}, + protocol::{ProtocolParameters, RentParameters, RentStructure, StorageScore}, semantic::{TransactionFailureReason, ValidationContext}, unlock::Unlock, Error, diff --git a/sdk/src/types/block/output/delegation.rs b/sdk/src/types/block/output/delegation.rs index a736b22c20..93af69a3ec 100644 --- a/sdk/src/types/block/output/delegation.rs +++ b/sdk/src/types/block/output/delegation.rs @@ -22,8 +22,7 @@ use crate::types::{ verify_output_amount_min, verify_output_amount_packable, verify_output_amount_supply, Output, OutputBuilderAmount, OutputId, StateTransitionError, StateTransitionVerifier, }, - protocol::ProtocolParameters, - rent::{RentParameters, RentStructure, StorageScore}, + protocol::{ProtocolParameters, RentParameters, RentStructure, StorageScore}, semantic::{TransactionFailureReason, ValidationContext}, slot::EpochIndex, unlock::Unlock, diff --git a/sdk/src/types/block/output/feature/block_issuer.rs b/sdk/src/types/block/output/feature/block_issuer.rs index 4dba88498a..259d31e07e 100644 --- a/sdk/src/types/block/output/feature/block_issuer.rs +++ b/sdk/src/types/block/output/feature/block_issuer.rs @@ -17,7 +17,7 @@ use packable::{ }; use crate::types::block::{ - rent::{RentParameters, RentStructure, StorageScore}, + protocol::{RentParameters, RentStructure, StorageScore}, slot::SlotIndex, Error, }; diff --git a/sdk/src/types/block/output/feature/issuer.rs b/sdk/src/types/block/output/feature/issuer.rs index fc61921a45..bd801d52d4 100644 --- a/sdk/src/types/block/output/feature/issuer.rs +++ b/sdk/src/types/block/output/feature/issuer.rs @@ -5,7 +5,7 @@ use derive_more::From; use crate::types::block::{ address::Address, - rent::{RentParameters, RentStructure, StorageScore}, + protocol::{RentParameters, RentStructure, StorageScore}, }; /// Identifies the validated issuer of the UTXO state machine. diff --git a/sdk/src/types/block/output/feature/metadata.rs b/sdk/src/types/block/output/feature/metadata.rs index e4b96b2512..18bb3556d6 100644 --- a/sdk/src/types/block/output/feature/metadata.rs +++ b/sdk/src/types/block/output/feature/metadata.rs @@ -7,7 +7,7 @@ use core::{ops::RangeInclusive, str::FromStr}; use packable::{bounded::BoundedU16, prefix::BoxedSlicePrefix}; use crate::types::block::{ - rent::{RentStructure, StorageScore}, + protocol::{RentStructure, StorageScore}, Error, }; diff --git a/sdk/src/types/block/output/feature/mod.rs b/sdk/src/types/block/output/feature/mod.rs index 160ea1bb4b..b65675194f 100644 --- a/sdk/src/types/block/output/feature/mod.rs +++ b/sdk/src/types/block/output/feature/mod.rs @@ -30,7 +30,7 @@ pub use self::{ }; use crate::types::block::{ create_bitflags, - rent::{RentStructure, StorageScore}, + protocol::{RentStructure, StorageScore}, Error, }; diff --git a/sdk/src/types/block/output/feature/sender.rs b/sdk/src/types/block/output/feature/sender.rs index 032b4b63d9..8004b2e8ff 100644 --- a/sdk/src/types/block/output/feature/sender.rs +++ b/sdk/src/types/block/output/feature/sender.rs @@ -5,7 +5,7 @@ use derive_more::From; use crate::types::block::{ address::Address, - rent::{RentStructure, StorageScore}, + protocol::{RentStructure, StorageScore}, }; /// Identifies the validated sender of an output. diff --git a/sdk/src/types/block/output/feature/staking.rs b/sdk/src/types/block/output/feature/staking.rs index 8e8eafb54d..8f78e61a50 100644 --- a/sdk/src/types/block/output/feature/staking.rs +++ b/sdk/src/types/block/output/feature/staking.rs @@ -2,7 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 use crate::types::block::{ - rent::{RentStructure, StorageScore}, + protocol::{RentStructure, StorageScore}, slot::EpochIndex, }; diff --git a/sdk/src/types/block/output/feature/tag.rs b/sdk/src/types/block/output/feature/tag.rs index 803e7c6b3b..9f73a4f6fc 100644 --- a/sdk/src/types/block/output/feature/tag.rs +++ b/sdk/src/types/block/output/feature/tag.rs @@ -7,7 +7,7 @@ use core::ops::RangeInclusive; use packable::{bounded::BoundedU8, prefix::BoxedSlicePrefix}; use crate::types::block::{ - rent::{RentStructure, StorageScore}, + protocol::{RentStructure, StorageScore}, Error, }; diff --git a/sdk/src/types/block/output/foundry.rs b/sdk/src/types/block/output/foundry.rs index 7736101d17..655a183be9 100644 --- a/sdk/src/types/block/output/foundry.rs +++ b/sdk/src/types/block/output/foundry.rs @@ -26,8 +26,7 @@ use crate::types::{ NativeTokens, Output, OutputBuilderAmount, OutputId, StateTransitionError, StateTransitionVerifier, TokenId, TokenScheme, }, - protocol::ProtocolParameters, - rent::{RentParameters, RentStructure, StorageScore}, + protocol::{ProtocolParameters, RentParameters, RentStructure, StorageScore}, semantic::{TransactionFailureReason, ValidationContext}, unlock::Unlock, Error, diff --git a/sdk/src/types/block/output/mod.rs b/sdk/src/types/block/output/mod.rs index 55dfd455f2..01ad20135a 100644 --- a/sdk/src/types/block/output/mod.rs +++ b/sdk/src/types/block/output/mod.rs @@ -58,8 +58,7 @@ pub use self::{ }; use super::{ address::Ed25519Address, - protocol::ProtocolParameters, - rent::{RentStructure, StorageScore}, + protocol::{ProtocolParameters, RentStructure, StorageScore}, BlockId, }; use crate::types::block::{address::Address, semantic::ValidationContext, slot::SlotIndex, Error}; diff --git a/sdk/src/types/block/output/native_token.rs b/sdk/src/types/block/output/native_token.rs index def9d88506..2fe07bf9bd 100644 --- a/sdk/src/types/block/output/native_token.rs +++ b/sdk/src/types/block/output/native_token.rs @@ -14,7 +14,7 @@ use primitive_types::U256; use crate::types::block::{ output::foundry::FoundryId, - rent::{RentStructure, StorageScore}, + protocol::{RentStructure, StorageScore}, Error, }; diff --git a/sdk/src/types/block/output/nft.rs b/sdk/src/types/block/output/nft.rs index 3f9ca0ddd8..ce1874f9ba 100644 --- a/sdk/src/types/block/output/nft.rs +++ b/sdk/src/types/block/output/nft.rs @@ -23,8 +23,7 @@ use crate::types::{ NativeTokens, Output, OutputBuilderAmount, OutputId, StateTransitionError, StateTransitionVerifier, StorageScore, }, - protocol::ProtocolParameters, - rent::RentStructure, + protocol::{ProtocolParameters, RentStructure}, semantic::{TransactionFailureReason, ValidationContext}, unlock::Unlock, Error, diff --git a/sdk/src/types/block/output/token_scheme/mod.rs b/sdk/src/types/block/output/token_scheme/mod.rs index cd0aae9965..4bdd317bc0 100644 --- a/sdk/src/types/block/output/token_scheme/mod.rs +++ b/sdk/src/types/block/output/token_scheme/mod.rs @@ -5,7 +5,7 @@ mod simple; pub use self::simple::SimpleTokenScheme; use crate::types::block::{ - rent::{RentParameters, RentStructure, StorageScore}, + protocol::{RentParameters, RentStructure, StorageScore}, Error, }; diff --git a/sdk/src/types/block/output/token_scheme/simple.rs b/sdk/src/types/block/output/token_scheme/simple.rs index 9b62347ca8..1f0c833d82 100644 --- a/sdk/src/types/block/output/token_scheme/simple.rs +++ b/sdk/src/types/block/output/token_scheme/simple.rs @@ -10,7 +10,7 @@ use packable::{ use primitive_types::U256; use crate::types::block::{ - rent::{RentParameters, RentStructure, StorageScore}, + protocol::{RentParameters, RentStructure, StorageScore}, Error, }; diff --git a/sdk/src/types/block/output/unlock_condition/address.rs b/sdk/src/types/block/output/unlock_condition/address.rs index 07835019ea..8569745ef0 100644 --- a/sdk/src/types/block/output/unlock_condition/address.rs +++ b/sdk/src/types/block/output/unlock_condition/address.rs @@ -5,7 +5,7 @@ use derive_more::From; use crate::types::block::{ address::Address, - rent::{RentStructure, StorageScore}, + protocol::{RentStructure, StorageScore}, }; /// Defines the Address that owns this output, that is, it can unlock it with the proper Unlock in a transaction. diff --git a/sdk/src/types/block/output/unlock_condition/expiration.rs b/sdk/src/types/block/output/unlock_condition/expiration.rs index 059ea4ffe3..f4f458bfeb 100644 --- a/sdk/src/types/block/output/unlock_condition/expiration.rs +++ b/sdk/src/types/block/output/unlock_condition/expiration.rs @@ -5,7 +5,7 @@ use derive_more::From; use crate::types::block::{ address::Address, - rent::{RentStructure, StorageScore}, + protocol::{RentStructure, StorageScore}, slot::SlotIndex, Error, }; diff --git a/sdk/src/types/block/output/unlock_condition/governor_address.rs b/sdk/src/types/block/output/unlock_condition/governor_address.rs index 4e1b2c59f6..5ba110b854 100644 --- a/sdk/src/types/block/output/unlock_condition/governor_address.rs +++ b/sdk/src/types/block/output/unlock_condition/governor_address.rs @@ -5,7 +5,7 @@ use derive_more::From; use crate::types::block::{ address::Address, - rent::{RentStructure, StorageScore}, + protocol::{RentStructure, StorageScore}, }; /// Defines the Governor Address that owns this output, that is, it can unlock it with the proper Unlock in a diff --git a/sdk/src/types/block/output/unlock_condition/immutable_account_address.rs b/sdk/src/types/block/output/unlock_condition/immutable_account_address.rs index 79fbdc5bcb..ad8d67c9bd 100644 --- a/sdk/src/types/block/output/unlock_condition/immutable_account_address.rs +++ b/sdk/src/types/block/output/unlock_condition/immutable_account_address.rs @@ -5,7 +5,7 @@ use derive_more::From; use crate::types::block::{ address::AccountAddress, - rent::{RentStructure, StorageScore}, + protocol::{RentStructure, StorageScore}, }; /// Defines the permanent [`AccountAddress`] that owns this output. diff --git a/sdk/src/types/block/output/unlock_condition/mod.rs b/sdk/src/types/block/output/unlock_condition/mod.rs index 642a8471f2..315f0354d5 100644 --- a/sdk/src/types/block/output/unlock_condition/mod.rs +++ b/sdk/src/types/block/output/unlock_condition/mod.rs @@ -33,8 +33,7 @@ pub use self::{ use crate::types::block::{ address::Address, create_bitflags, - protocol::ProtocolParameters, - rent::{RentStructure, StorageScore}, + protocol::{ProtocolParameters, RentStructure, StorageScore}, slot::SlotIndex, Error, }; diff --git a/sdk/src/types/block/output/unlock_condition/state_controller_address.rs b/sdk/src/types/block/output/unlock_condition/state_controller_address.rs index b961c34194..978940ca82 100644 --- a/sdk/src/types/block/output/unlock_condition/state_controller_address.rs +++ b/sdk/src/types/block/output/unlock_condition/state_controller_address.rs @@ -6,7 +6,7 @@ use derive_more::From; use super::ImmutableAccountAddressUnlockCondition; use crate::types::block::{ address::Address, - rent::{RentStructure, StorageScore}, + protocol::{RentStructure, StorageScore}, }; /// Defines the State Controller Address that owns this output, that is, it can unlock it with the proper Unlock in a diff --git a/sdk/src/types/block/output/unlock_condition/storage_deposit_return.rs b/sdk/src/types/block/output/unlock_condition/storage_deposit_return.rs index 3ec738592a..075e87fedd 100644 --- a/sdk/src/types/block/output/unlock_condition/storage_deposit_return.rs +++ b/sdk/src/types/block/output/unlock_condition/storage_deposit_return.rs @@ -4,8 +4,7 @@ use crate::types::block::{ address::Address, output::verify_output_amount, - protocol::ProtocolParameters, - rent::{RentStructure, StorageScore}, + protocol::{ProtocolParameters, RentStructure, StorageScore}, Error, }; diff --git a/sdk/src/types/block/output/unlock_condition/timelock.rs b/sdk/src/types/block/output/unlock_condition/timelock.rs index c6b21ff88c..54ad6eb5ec 100644 --- a/sdk/src/types/block/output/unlock_condition/timelock.rs +++ b/sdk/src/types/block/output/unlock_condition/timelock.rs @@ -4,7 +4,7 @@ use derive_more::From; use crate::types::block::{ - rent::{RentStructure, StorageScore}, + protocol::{RentStructure, StorageScore}, slot::SlotIndex, Error, }; diff --git a/sdk/src/types/block/payload/transaction/essence/regular.rs b/sdk/src/types/block/payload/transaction/essence/regular.rs index 3cb42a19b3..b71d2ae9c2 100644 --- a/sdk/src/types/block/payload/transaction/essence/regular.rs +++ b/sdk/src/types/block/payload/transaction/essence/regular.rs @@ -13,8 +13,7 @@ use crate::types::{ mana::{verify_mana_allotments_sum, ManaAllotment, ManaAllotments}, output::{InputsCommitment, NativeTokens, Output, OUTPUT_COUNT_RANGE}, payload::{OptionalPayload, Payload}, - protocol::ProtocolParameters, - rent::RentStructure, + protocol::{ProtocolParameters, RentStructure}, slot::SlotIndex, Error, }, diff --git a/sdk/src/types/block/protocol.rs b/sdk/src/types/block/protocol/mod.rs similarity index 98% rename from sdk/src/types/block/protocol.rs rename to sdk/src/types/block/protocol/mod.rs index 2fb9564ba5..8b5e6aa2b9 100644 --- a/sdk/src/types/block/protocol.rs +++ b/sdk/src/types/block/protocol/mod.rs @@ -1,19 +1,22 @@ // Copyright 2022 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 +mod storage_score; + use alloc::string::String; use core::borrow::Borrow; use crypto::hashes::{blake2b::Blake2b256, Digest}; use getset::{CopyGetters, Getters}; use packable::{prefix::StringPrefix, Packable, PackableExt}; +pub use storage_score::*; use super::{ address::Hrp, mana::{ManaStructure, RewardsParameters}, slot::SlotIndex, }; -use crate::types::block::{helper::network_name_to_id, rent::RentParameters, ConvertTo, Error, PROTOCOL_VERSION}; +use crate::types::block::{helper::network_name_to_id, ConvertTo, Error, PROTOCOL_VERSION}; /// Defines the parameters of the protocol at a particular version. #[derive(Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Packable, Getters, CopyGetters)] @@ -318,7 +321,7 @@ pub fn protocol_parameters() -> ProtocolParameters { 2, "testnet", "rms", - crate::types::block::rent::RentParameters::new(500, 1, 10, 1, 1, 1), + crate::types::block::protocol::RentParameters::new(500, 1, 10, 1, 1, 1), 1_813_620_509_061_365, 1582328545, 10, diff --git a/sdk/src/types/block/rent.rs b/sdk/src/types/block/protocol/storage_score.rs similarity index 90% rename from sdk/src/types/block/rent.rs rename to sdk/src/types/block/protocol/storage_score.rs index 920f7b0db2..1514026295 100644 --- a/sdk/src/types/block/rent.rs +++ b/sdk/src/types/block/protocol/storage_score.rs @@ -5,12 +5,11 @@ use core::{mem::size_of, ops::Deref}; use packable::Packable; -use super::output::{AccountOutput, BasicOutput}; use crate::types::block::{ address::{Address, Ed25519Address}, output::{ unlock_condition::{AddressUnlockCondition, ExpirationUnlockCondition, StorageDepositReturnUnlockCondition}, - BasicOutputBuilder, NativeTokens, Output, OutputId, + AccountOutput, BasicOutput, BasicOutputBuilder, NativeTokens, Output, OutputId, }, slot::SlotIndex, BlockId, Error, @@ -130,25 +129,25 @@ impl RentParameters { } } - /// Sets the storage cost for the storage deposit. + /// Sets the storage cost per unit of storage score. pub fn with_storage_cost(mut self, storage_cost: u64) -> Self { self.storage_cost = storage_cost; self } - /// Sets the storage score factor for the data fields. + /// Sets the storage score factor for data fields. pub fn with_storage_score_factor_data(mut self, storage_score_factor_data: StorageScoreFactor) -> Self { self.storage_score_factor_data = storage_score_factor_data; self } - /// Sets the TODO. + /// Sets the storage score offset per output. pub fn with_storage_score_offset_output(mut self, storage_score_offset_output: StorageScoreOffset) -> Self { self.storage_score_offset_output = storage_score_offset_output; self } - /// Sets the TODO. + /// Sets the storage score offset for Ed25519 block issuer key fields. pub fn with_storage_score_offset_ed25519_block_issuer_key( mut self, storage_score_offset_ed25519_block_issuer_key: StorageScoreOffset, @@ -157,7 +156,7 @@ impl RentParameters { self } - /// Sets the TODO for the staking fields. + /// Sets the storage score offset for staking fields. pub fn with_storage_score_offset_staking_feature( mut self, storage_score_offset_staking_feature: StorageScoreOffset, @@ -166,38 +165,38 @@ impl RentParameters { self } - /// Sets the TODO for the delegation fields. + /// Sets the storage score offset for delegation fields. pub fn with_storage_score_offset_delegation(mut self, storage_score_offset_delegation: StorageScoreOffset) -> Self { self.storage_score_offset_delegation = storage_score_offset_delegation; self } - /// Returns the TODO of the [`RentParameters`]. + /// Returns the storage cost per unit of storage score. pub const fn storage_cost(&self) -> u64 { self.storage_cost } - /// Returns the TODO of the [`RentParameters`]. + /// Returns the storage score factor for data fields. pub const fn storage_score_factor_data(&self) -> StorageScoreFactor { self.storage_score_factor_data } - /// Returns the TODO of the [`RentParameters`]. + /// Returns the storage score offset per output. pub const fn storage_score_offset_output(&self) -> StorageScoreOffset { self.storage_score_offset_output } - /// Returns the TODO the [`RentParameters`]. + /// Returns the storage score offset for Ed25519 block issuer key fields. pub const fn storage_score_offset_ed25519_block_issuer_key(&self) -> StorageScoreOffset { self.storage_score_offset_ed25519_block_issuer_key } - /// Returns the TODO the [`RentParameters`]. + /// Returns the storage score offset for staking fields. pub const fn storage_score_offset_staking_feature(&self) -> StorageScoreOffset { self.storage_score_offset_staking_feature } - /// Returns the TODO the [`RentParameters`]. + /// Returns the storage score offset for delegation fields. pub const fn storage_score_offset_delegation(&self) -> StorageScoreOffset { self.storage_score_offset_delegation } diff --git a/sdk/src/wallet/account/mod.rs b/sdk/src/wallet/account/mod.rs index d07026b9df..bae37f0e59 100644 --- a/sdk/src/wallet/account/mod.rs +++ b/sdk/src/wallet/account/mod.rs @@ -613,7 +613,7 @@ fn serialize() { 2, "testnet", "rms", - crate::types::block::rent::RentParameters::new(500, 1, 10, 1, 1, 1), + crate::types::block::protocol::RentParameters::new(500, 1, 10, 1, 1, 1), 1_813_620_509_061_365, 1582328545, 10, diff --git a/sdk/src/wallet/account/operations/balance.rs b/sdk/src/wallet/account/operations/balance.rs index c2848b6efb..58540fde49 100644 --- a/sdk/src/wallet/account/operations/balance.rs +++ b/sdk/src/wallet/account/operations/balance.rs @@ -8,7 +8,7 @@ use crate::{ types::block::{ address::Bech32Address, output::{unlock_condition::UnlockCondition, FoundryId, NativeTokensBuilder, Output}, - rent::{RentStructure, StorageScore}, + protocol::{RentStructure, StorageScore}, ConvertTo, }, wallet::{ diff --git a/sdk/src/wallet/account/operations/output_claiming.rs b/sdk/src/wallet/account/operations/output_claiming.rs index eae1159640..a47f05770a 100644 --- a/sdk/src/wallet/account/operations/output_claiming.rs +++ b/sdk/src/wallet/account/operations/output_claiming.rs @@ -14,7 +14,7 @@ use crate::{ BasicOutputBuilder, MinimumStorageDepositBasicOutput, NativeTokens, NativeTokensBuilder, NftOutputBuilder, Output, OutputId, }, - rent::RentStructure, + protocol::RentStructure, slot::SlotIndex, }, wallet::account::{ diff --git a/sdk/src/wallet/account/operations/transaction/high_level/minting/create_native_token.rs b/sdk/src/wallet/account/operations/transaction/high_level/minting/create_native_token.rs index ebe5898a62..10c4acbf7b 100644 --- a/sdk/src/wallet/account/operations/transaction/high_level/minting/create_native_token.rs +++ b/sdk/src/wallet/account/operations/transaction/high_level/minting/create_native_token.rs @@ -15,7 +15,7 @@ use crate::{ feature::MetadataFeature, unlock_condition::ImmutableAccountAddressUnlockCondition, AccountId, AccountOutputBuilder, FoundryId, FoundryOutputBuilder, Output, SimpleTokenScheme, TokenId, TokenScheme, }, - rent::RentStructure, + protocol::RentStructure, }, wallet::account::{ types::{Transaction, TransactionDto}, diff --git a/sdk/src/wallet/account/operations/transaction/high_level/minting/mint_nfts.rs b/sdk/src/wallet/account/operations/transaction/high_level/minting/mint_nfts.rs index 328063d85c..fc72a18e67 100644 --- a/sdk/src/wallet/account/operations/transaction/high_level/minting/mint_nfts.rs +++ b/sdk/src/wallet/account/operations/transaction/high_level/minting/mint_nfts.rs @@ -13,7 +13,7 @@ use crate::{ unlock_condition::AddressUnlockCondition, NftId, NftOutputBuilder, }, - rent::RentStructure, + protocol::RentStructure, ConvertTo, }, wallet::{ diff --git a/sdk/src/wallet/account/operations/transaction/high_level/send.rs b/sdk/src/wallet/account/operations/transaction/high_level/send.rs index 110bbb092c..3c7f0c5d42 100644 --- a/sdk/src/wallet/account/operations/transaction/high_level/send.rs +++ b/sdk/src/wallet/account/operations/transaction/high_level/send.rs @@ -14,7 +14,7 @@ use crate::{ }, BasicOutputBuilder, MinimumStorageDepositBasicOutput, }, - rent::RentStructure, + protocol::RentStructure, slot::SlotIndex, ConvertTo, }, diff --git a/sdk/src/wallet/account/operations/transaction/high_level/send_native_tokens.rs b/sdk/src/wallet/account/operations/transaction/high_level/send_native_tokens.rs index f352fbc7e7..ab41371b43 100644 --- a/sdk/src/wallet/account/operations/transaction/high_level/send_native_tokens.rs +++ b/sdk/src/wallet/account/operations/transaction/high_level/send_native_tokens.rs @@ -15,7 +15,7 @@ use crate::{ }, BasicOutputBuilder, MinimumStorageDepositBasicOutput, NativeToken, NativeTokens, TokenId, }, - rent::RentStructure, + protocol::RentStructure, slot::SlotIndex, ConvertTo, }, diff --git a/sdk/src/wallet/account/operations/transaction/prepare_output.rs b/sdk/src/wallet/account/operations/transaction/prepare_output.rs index b3a200176e..51e31c2e58 100644 --- a/sdk/src/wallet/account/operations/transaction/prepare_output.rs +++ b/sdk/src/wallet/account/operations/transaction/prepare_output.rs @@ -16,7 +16,7 @@ use crate::{ BasicOutputBuilder, MinimumStorageDepositBasicOutput, NativeToken, NftId, NftOutputBuilder, Output, UnlockCondition, }, - rent::{RentParameters, RentStructure, StorageScore}, + protocol::{RentParameters, RentStructure, StorageScore}, slot::SlotIndex, Error, }, diff --git a/sdk/tests/types/block_id.rs b/sdk/tests/types/block_id.rs index ab62bd013f..b07613bc27 100644 --- a/sdk/tests/types/block_id.rs +++ b/sdk/tests/types/block_id.rs @@ -5,8 +5,9 @@ use core::str::FromStr; use iota_sdk::types::{ block::{ - protocol::ProtocolParameters, rand::bytes::rand_bytes_array, rent::RentParameters, BlockHash, BlockId, - BlockWrapper, BlockWrapperDto, + protocol::{ProtocolParameters, RentParameters}, + rand::bytes::rand_bytes_array, + BlockHash, BlockId, BlockWrapper, BlockWrapperDto, }, TryFromDto, }; diff --git a/sdk/tests/types/output/account.rs b/sdk/tests/types/output/account.rs index 76a677b5ab..a89091ff7a 100644 --- a/sdk/tests/types/output/account.rs +++ b/sdk/tests/types/output/account.rs @@ -5,7 +5,7 @@ use iota_sdk::types::{ block::{ address::AccountAddress, output::{AccountOutput, Feature, FoundryId, NativeToken, Output, SimpleTokenScheme, TokenId}, - protocol::protocol_parameters, + protocol::{protocol_parameters, StorageScore}, rand::output::{ feature::{rand_issuer_feature, rand_metadata_feature, rand_sender_feature}, rand_account_id, rand_account_output, @@ -14,7 +14,6 @@ use iota_sdk::types::{ rand_state_controller_address_unlock_condition_different_from, }, }, - rent::StorageScore, }, ValidationParams, }; diff --git a/sdk/tests/types/output/basic.rs b/sdk/tests/types/output/basic.rs index f8989304ba..8e04f5df35 100644 --- a/sdk/tests/types/output/basic.rs +++ b/sdk/tests/types/output/basic.rs @@ -4,7 +4,7 @@ use iota_sdk::types::{ block::{ output::{BasicOutput, Feature, FoundryId, NativeToken, Output, SimpleTokenScheme, TokenId}, - protocol::protocol_parameters, + protocol::{protocol_parameters, StorageScore}, rand::{ address::rand_account_address, output::{ @@ -13,7 +13,6 @@ use iota_sdk::types::{ unlock_condition::rand_address_unlock_condition, }, }, - rent::StorageScore, }, ValidationParams, }; diff --git a/sdk/tests/types/output/foundry.rs b/sdk/tests/types/output/foundry.rs index db44ee9bd7..289f3904ba 100644 --- a/sdk/tests/types/output/foundry.rs +++ b/sdk/tests/types/output/foundry.rs @@ -6,12 +6,11 @@ use iota_sdk::types::block::{ unlock_condition::ImmutableAccountAddressUnlockCondition, FoundryId, FoundryOutput, NativeToken, Output, SimpleTokenScheme, TokenId, }, - protocol::protocol_parameters, + protocol::{protocol_parameters, StorageScore}, rand::{ address::rand_account_address, output::{feature::rand_metadata_feature, rand_foundry_output, rand_token_scheme}, }, - rent::StorageScore, }; use packable::PackableExt; diff --git a/sdk/tests/types/output/nft.rs b/sdk/tests/types/output/nft.rs index f6eafaf5c8..0ce5f0a617 100644 --- a/sdk/tests/types/output/nft.rs +++ b/sdk/tests/types/output/nft.rs @@ -3,7 +3,7 @@ use iota_sdk::types::block::{ output::{FoundryId, NativeToken, NftId, NftOutput, Output, SimpleTokenScheme, TokenId}, - protocol::protocol_parameters, + protocol::{protocol_parameters, StorageScore}, rand::{ address::rand_account_address, output::{ @@ -12,7 +12,6 @@ use iota_sdk::types::block::{ unlock_condition::rand_address_unlock_condition, }, }, - rent::StorageScore, }; use packable::PackableExt; diff --git a/sdk/tests/wallet/claim_outputs.rs b/sdk/tests/wallet/claim_outputs.rs index cb599df340..e1d2481dba 100644 --- a/sdk/tests/wallet/claim_outputs.rs +++ b/sdk/tests/wallet/claim_outputs.rs @@ -322,13 +322,13 @@ async fn claim_2_native_tokens_no_outputs_in_claim_account() -> Result<()> { .await?; account_0.sync(None).await?; - let rent_strcut = account_0.client().get_rent_parameters().await?.into(); + let rent_struct = account_0.client().get_rent_parameters().await?.into(); let token_supply = account_0.client().get_token_supply().await?; let tx = account_0 .send_outputs( [ - BasicOutputBuilder::new_with_minimum_storage_deposit(rent_strcut) + BasicOutputBuilder::new_with_minimum_storage_deposit(rent_struct) .add_unlock_condition(AddressUnlockCondition::new( *account_1.addresses().await?[0].address().as_ref(), )) @@ -338,7 +338,7 @@ async fn claim_2_native_tokens_no_outputs_in_claim_account() -> Result<()> { )?) .add_native_token(NativeToken::new(create_tx_0.token_id, native_token_amount)?) .finish_output(token_supply)?, - BasicOutputBuilder::new_with_minimum_storage_deposit(rent_strcut) + BasicOutputBuilder::new_with_minimum_storage_deposit(rent_struct) .add_unlock_condition(AddressUnlockCondition::new( *account_1.addresses().await?[0].address().as_ref(), )) diff --git a/sdk/tests/wallet/output_preparation.rs b/sdk/tests/wallet/output_preparation.rs index 58560f6556..c4f5f596aa 100644 --- a/sdk/tests/wallet/output_preparation.rs +++ b/sdk/tests/wallet/output_preparation.rs @@ -7,7 +7,7 @@ use iota_sdk::{ types::block::{ address::{Address, Bech32Address, ToBech32Ext}, output::{MinimumStorageDepositBasicOutput, NativeToken, NftId, Output, TokenId}, - rent::StorageScore, + protocol::StorageScore, slot::SlotIndex, }, wallet::{ From e60d56d151156268ee8f5952e2063a028166b2ea Mon Sep 17 00:00:00 2001 From: Alexander Schmidt Date: Tue, 10 Oct 2023 16:37:38 +0200 Subject: [PATCH 09/10] remove dummy fns --- sdk/src/types/block/address/ed25519.rs | 8 ++-- sdk/src/types/block/output/account.rs | 13 ------ sdk/src/types/block/output/basic.rs | 8 ---- .../block/output/feature/block_issuer.rs | 2 +- sdk/src/types/block/protocol/storage_score.rs | 46 ++++++++++++++----- 5 files changed, 40 insertions(+), 37 deletions(-) diff --git a/sdk/src/types/block/address/ed25519.rs b/sdk/src/types/block/address/ed25519.rs index 3442f6cf14..78bfac5ad9 100644 --- a/sdk/src/types/block/address/ed25519.rs +++ b/sdk/src/types/block/address/ed25519.rs @@ -28,8 +28,9 @@ impl Ed25519Address { Self::from(address) } - /// Creates a dummy [`Ed25519Address`] used to calculate a storage score for implicit account addresses. - pub(crate) fn dummy() -> Self { + /// Creates an empty [`Ed25519Address`]. + /// This is used internally to calculate a storage score for implicit account addresses. + pub(crate) fn null() -> Self { Self([0; Self::LENGTH]) } } @@ -55,7 +56,8 @@ impl core::fmt::Debug for Ed25519Address { } impl StorageScore for Ed25519Address { - fn storage_score(&self, _rent_struct: RentStructure) -> u64 { + fn storage_score(&self, rent_struct: RentStructure) -> u64 { + // TODO: wait for TIP for this to change?! 0 } } diff --git a/sdk/src/types/block/output/account.rs b/sdk/src/types/block/output/account.rs index 7a00953d5d..459ff412ea 100644 --- a/sdk/src/types/block/output/account.rs +++ b/sdk/src/types/block/output/account.rs @@ -620,19 +620,6 @@ impl AccountOutput { Ok(()) } - - /// Creates a dummy [`AccountOutput`] used to calculate a storage score for implicit account addresses. - pub(crate) fn dummy() -> Self { - // Unwrap: cannot fail for provided dummy data. - AccountOutputBuilder::new_with_amount(0, AccountId::null()) - .add_unlock_condition(GovernorAddressUnlockCondition::new(Ed25519Address::dummy())) - .add_unlock_condition(StateControllerAddressUnlockCondition::new(Ed25519Address::dummy())) - .add_feature( - BlockIssuerFeature::new(0, vec![BlockIssuerKey::Ed25519(Ed25519BlockIssuerKey::dummy())]).unwrap(), - ) - .finish() - .unwrap() - } } impl StateTransitionVerifier for AccountOutput { diff --git a/sdk/src/types/block/output/basic.rs b/sdk/src/types/block/output/basic.rs index 53e68c9ae5..10f1d0756b 100644 --- a/sdk/src/types/block/output/basic.rs +++ b/sdk/src/types/block/output/basic.rs @@ -322,14 +322,6 @@ impl BasicOutput { None } - - /// Creates a dummy [`BasicOutput`] used to calculate a storage score for implicit account addresses. - pub(crate) fn dummy() -> Self { - BasicOutputBuilder::new_with_amount(0) - .add_unlock_condition(AddressUnlockCondition::new(Ed25519Address::dummy())) - .finish() - .unwrap() - } } impl StorageScore for BasicOutput { diff --git a/sdk/src/types/block/output/feature/block_issuer.rs b/sdk/src/types/block/output/feature/block_issuer.rs index 259d31e07e..fb16826a00 100644 --- a/sdk/src/types/block/output/feature/block_issuer.rs +++ b/sdk/src/types/block/output/feature/block_issuer.rs @@ -87,7 +87,7 @@ impl Ed25519BlockIssuerKey { } /// Creates a dummy [`Ed25519BlockIssuerKey`] used to calculate a storage score for implicit account addresses. - pub(crate) fn dummy() -> Self { + pub(crate) fn null() -> Self { // Unwrap: we provide a valid byte array Self(ed25519::PublicKey::try_from_bytes([0; Self::PUBLIC_KEY_LENGTH]).unwrap()) } diff --git a/sdk/src/types/block/protocol/storage_score.rs b/sdk/src/types/block/protocol/storage_score.rs index 1514026295..f075ab4fe1 100644 --- a/sdk/src/types/block/protocol/storage_score.rs +++ b/sdk/src/types/block/protocol/storage_score.rs @@ -8,8 +8,13 @@ use packable::Packable; use crate::types::block::{ address::{Address, Ed25519Address}, output::{ - unlock_condition::{AddressUnlockCondition, ExpirationUnlockCondition, StorageDepositReturnUnlockCondition}, - AccountOutput, BasicOutput, BasicOutputBuilder, NativeTokens, Output, OutputId, + feature::{BlockIssuerFeature, BlockIssuerKey, Ed25519BlockIssuerKey}, + unlock_condition::{ + AddressUnlockCondition, ExpirationUnlockCondition, GovernorAddressUnlockCondition, + StateControllerAddressUnlockCondition, StorageDepositReturnUnlockCondition, + }, + AccountId, AccountOutput, AccountOutputBuilder, BasicOutput, BasicOutputBuilder, NativeTokens, Output, + OutputId, }, slot::SlotIndex, BlockId, Error, @@ -36,25 +41,42 @@ pub struct RentStructure { impl RentStructure { /// Creates a new [`RentStructure`]. Computes the score offset for implicit account creation addresses. pub fn new(rent_parameters: RentParameters) -> Self { - let mut rent_structure = Self { + let mut rent_struct = Self { rent_parameters, storage_score_offset_implicit_account_creation_address: 0, }; - // set the storage score offset for implicit account creation addresses as + // TODO: check TIP for changes! + // Set the storage score offset for implicit account creation addresses as // the difference between the storage score of the dummy account and the storage // score of the dummy basic output minus the storage score of the dummy address. - let dummy_basic_output_score = BasicOutput::dummy().storage_score(rent_structure); - let dummy_address_score = Ed25519Address::dummy().storage_score(rent_structure); - let basic_score_without_address = dummy_basic_output_score - .checked_sub(dummy_address_score) - .expect("underflow"); - let dummy_account_output_score = AccountOutput::dummy().storage_score(rent_structure); - rent_structure.storage_score_offset_implicit_account_creation_address = dummy_account_output_score + // Unwrap: cannot fail for provided dummy data. + let basic_output_score = BasicOutputBuilder::new_with_amount(0) + .add_unlock_condition(AddressUnlockCondition::new(Ed25519Address::null())) + .finish() + .unwrap() + .storage_score(rent_struct); + let ed25519_address_score = Ed25519Address::null().storage_score(rent_struct); + // Unwrap: should never underflow. + let basic_score_without_address = basic_output_score + .checked_sub(ed25519_address_score) + .expect("underflow"); + // Unwrap: cannot fail for provided dummy data. + let account_output_score = AccountOutputBuilder::new_with_amount(0, AccountId::null()) + .add_unlock_condition(GovernorAddressUnlockCondition::new(Ed25519Address::null())) + .add_unlock_condition(StateControllerAddressUnlockCondition::new(Ed25519Address::null())) + .add_feature( + BlockIssuerFeature::new(0, vec![BlockIssuerKey::Ed25519(Ed25519BlockIssuerKey::null())]).unwrap(), + ) + .finish() + .unwrap() + .storage_score(rent_struct); + // Unwrap: should never underflow. + rent_struct.storage_score_offset_implicit_account_creation_address = account_output_score .checked_sub(basic_score_without_address) .expect("underflow"); - rent_structure + rent_struct } } From 8aa49fca0fb0e5fd333cab3f785caaa6016881e9 Mon Sep 17 00:00:00 2001 From: Alexander Schmidt Date: Tue, 10 Oct 2023 17:06:20 +0200 Subject: [PATCH 10/10] rename back to rent_structure :sadcat: --- bindings/core/src/method_handler/client.rs | 4 +- cli/src/command/account.rs | 4 +- .../client/output/build_account_output.rs | 4 +- .../client/output/build_nft_output.rs | 4 +- .../how_tos/account/state_transition.rs | 4 +- sdk/examples/how_tos/outputs/features.rs | 4 +- .../how_tos/outputs/unlock_conditions.rs | 10 +++-- sdk/src/types/block/address/ed25519.rs | 2 +- sdk/src/types/block/address/mod.rs | 8 ++-- sdk/src/types/block/output/account.rs | 34 ++++++++-------- sdk/src/types/block/output/basic.rs | 32 +++++++-------- sdk/src/types/block/output/delegation.rs | 30 +++++++------- .../block/output/feature/block_issuer.rs | 16 ++++---- sdk/src/types/block/output/feature/issuer.rs | 4 +- .../types/block/output/feature/metadata.rs | 2 +- sdk/src/types/block/output/feature/mod.rs | 18 ++++----- sdk/src/types/block/output/feature/sender.rs | 6 +-- sdk/src/types/block/output/feature/staking.rs | 6 +-- sdk/src/types/block/output/feature/tag.rs | 2 +- sdk/src/types/block/output/foundry.rs | 36 ++++++++--------- sdk/src/types/block/output/mod.rs | 39 ++++++++++--------- sdk/src/types/block/output/native_token.rs | 6 +-- sdk/src/types/block/output/nft.rs | 34 ++++++++-------- .../types/block/output/token_scheme/mod.rs | 4 +- .../types/block/output/token_scheme/simple.rs | 2 +- .../block/output/unlock_condition/address.rs | 4 +- .../output/unlock_condition/expiration.rs | 4 +- .../unlock_condition/governor_address.rs | 4 +- .../immutable_account_address.rs | 4 +- .../block/output/unlock_condition/mod.rs | 20 +++++----- .../state_controller_address.rs | 4 +- .../storage_deposit_return.rs | 4 +- sdk/src/types/block/protocol/storage_score.rs | 22 +++++------ sdk/src/wallet/account/operations/balance.rs | 4 +- .../account/operations/output_claiming.rs | 8 ++-- .../transaction/high_level/create_account.rs | 4 +- .../high_level/minting/create_native_token.rs | 4 +- .../high_level/minting/mint_nfts.rs | 4 +- .../operations/transaction/high_level/send.rs | 6 +-- .../high_level/send_native_tokens.rs | 4 +- .../operations/transaction/prepare_output.rs | 29 +++++++------- .../transaction/prepare_transaction.rs | 4 +- sdk/tests/wallet/claim_outputs.rs | 10 ++--- sdk/tests/wallet/output_preparation.rs | 29 +++++++------- 44 files changed, 247 insertions(+), 240 deletions(-) diff --git a/bindings/core/src/method_handler/client.rs b/bindings/core/src/method_handler/client.rs index 50cf94af9f..5b6e2558e2 100644 --- a/bindings/core/src/method_handler/client.rs +++ b/bindings/core/src/method_handler/client.rs @@ -297,8 +297,8 @@ pub(crate) async fn call_client_method_internal(client: &Client, method: ClientM } ClientMethod::MinimumRequiredStorageDeposit { output } => { let output = Output::try_from_dto_with_params(output, client.get_token_supply().await?)?; - let rent_struct = client.get_rent_parameters().await?.into(); - let minimum_storage_deposit = output.rent_cost(rent_struct); + let rent_structure = client.get_rent_parameters().await?.into(); + let minimum_storage_deposit = output.rent_cost(rent_structure); Response::MinimumRequiredStorageDeposit(minimum_storage_deposit.to_string()) } diff --git a/cli/src/command/account.rs b/cli/src/command/account.rs index 06f70dee86..7c15f7c366 100644 --- a/cli/src/command/account.rs +++ b/cli/src/command/account.rs @@ -721,12 +721,12 @@ pub async fn send_native_token_command( let address = address.convert()?; let transaction = if gift_storage_deposit.unwrap_or(false) { // Send native tokens together with the required storage deposit - let rent_struct = account.client().get_rent_parameters().await?.into(); + let rent_structure = account.client().get_rent_parameters().await?.into(); let token_supply = account.client().get_token_supply().await?; account.client().bech32_hrp_matches(address.hrp()).await?; - let outputs = [BasicOutputBuilder::new_with_minimum_storage_deposit(rent_struct) + let outputs = [BasicOutputBuilder::new_with_minimum_storage_deposit(rent_structure) .add_unlock_condition(AddressUnlockCondition::new(address)) .with_native_tokens([NativeToken::new( TokenId::from_str(&token_id)?, diff --git a/sdk/examples/client/output/build_account_output.rs b/sdk/examples/client/output/build_account_output.rs index 986f65e519..bee13b861c 100644 --- a/sdk/examples/client/output/build_account_output.rs +++ b/sdk/examples/client/output/build_account_output.rs @@ -35,7 +35,7 @@ async fn main() -> Result<()> { .await?; let token_supply = client.get_token_supply().await?; - let rent_struct = client.get_rent_parameters().await?.into(); + let rent_structure = client.get_rent_parameters().await?.into(); let address = std::env::args() .nth(1) @@ -43,7 +43,7 @@ async fn main() -> Result<()> { let address = Address::try_from_bech32(address)?; // Account id needs to be null the first time - let account_output = AccountOutputBuilder::new_with_minimum_storage_deposit(rent_struct, AccountId::null()) + let account_output = AccountOutputBuilder::new_with_minimum_storage_deposit(rent_structure, AccountId::null()) .with_state_metadata(metadata) .add_feature(SenderFeature::new(address)) .add_feature(MetadataFeature::new(metadata)?) diff --git a/sdk/examples/client/output/build_nft_output.rs b/sdk/examples/client/output/build_nft_output.rs index b2a86f1c3b..7bd0baef77 100644 --- a/sdk/examples/client/output/build_nft_output.rs +++ b/sdk/examples/client/output/build_nft_output.rs @@ -35,7 +35,7 @@ async fn main() -> Result<()> { .await?; let token_supply = client.get_token_supply().await?; - let rent_struct = client.get_rent_parameters().await?.into(); + let rent_structure = client.get_rent_parameters().await?.into(); let address = std::env::args() .nth(1) @@ -56,7 +56,7 @@ async fn main() -> Result<()> { .to_string(); // NftId needs to be null the first time - let nft_output = NftOutputBuilder::new_with_minimum_storage_deposit(rent_struct, NftId::null()) + let nft_output = NftOutputBuilder::new_with_minimum_storage_deposit(rent_structure, NftId::null()) .add_unlock_condition(AddressUnlockCondition::new(address)) .add_feature(SenderFeature::new(address)) .add_feature(MetadataFeature::new(MUTABLE_METADATA)?) diff --git a/sdk/examples/how_tos/account/state_transition.rs b/sdk/examples/how_tos/account/state_transition.rs index bbc201f5fc..402d9ed146 100644 --- a/sdk/examples/how_tos/account/state_transition.rs +++ b/sdk/examples/how_tos/account/state_transition.rs @@ -51,13 +51,13 @@ async fn main() -> Result<()> { ); let token_supply = account.client().get_token_supply().await?; - let rent_struct = account.client().get_rent_parameters().await?.into(); + let rent_structure = account.client().get_rent_parameters().await?.into(); let account_output = account_output_data.output.as_account(); let updated_account_output = AccountOutputBuilder::from(account_output) // Minimum required storage deposit will change if the new metadata has a different size, so we will update // the amount - .with_minimum_storage_deposit(rent_struct) + .with_minimum_storage_deposit(rent_structure) .with_state_metadata(NEW_STATE_METADATA.as_bytes().to_vec()) .with_state_index(account_output.state_index() + 1) .finish_output(token_supply)?; diff --git a/sdk/examples/how_tos/outputs/features.rs b/sdk/examples/how_tos/outputs/features.rs index f80599dca0..d5ae68900f 100644 --- a/sdk/examples/how_tos/outputs/features.rs +++ b/sdk/examples/how_tos/outputs/features.rs @@ -32,11 +32,11 @@ async fn main() -> Result<()> { let client = Client::builder().with_node(&node_url)?.finish().await?; let token_supply = client.get_token_supply().await?; - let rent_struct = client.get_rent_parameters().await?.into(); + let rent_structure = client.get_rent_parameters().await?.into(); let address = Address::try_from_bech32("rms1qpllaj0pyveqfkwxmnngz2c488hfdtmfrj3wfkgxtk4gtyrax0jaxzt70zy")?; - let nft_output_builder = NftOutputBuilder::new_with_minimum_storage_deposit(rent_struct, NftId::null()) + let nft_output_builder = NftOutputBuilder::new_with_minimum_storage_deposit(rent_structure, NftId::null()) .add_unlock_condition(AddressUnlockCondition::new(address)); let outputs = [ diff --git a/sdk/examples/how_tos/outputs/unlock_conditions.rs b/sdk/examples/how_tos/outputs/unlock_conditions.rs index e5ee0cf8a3..a3de8d0f44 100644 --- a/sdk/examples/how_tos/outputs/unlock_conditions.rs +++ b/sdk/examples/how_tos/outputs/unlock_conditions.rs @@ -35,17 +35,19 @@ async fn main() -> Result<()> { let client = Client::builder().with_node(&node_url)?.finish().await?; let token_supply = client.get_token_supply().await?; - let rent_struct = client.get_rent_parameters().await?.into(); + let rent_structure = client.get_rent_parameters().await?.into(); let address = Address::try_from_bech32("rms1qpllaj0pyveqfkwxmnngz2c488hfdtmfrj3wfkgxtk4gtyrax0jaxzt70zy")?; let account_address = Address::try_from_bech32("rms1pr59qm43mjtvhcajfmupqf23x29llam88yecn6pyul80rx099krmv2fnnux")?; let token_scheme = TokenScheme::Simple(SimpleTokenScheme::new(50, 0, 100)?); - let basic_output_builder = BasicOutputBuilder::new_with_minimum_storage_deposit(rent_struct) + let basic_output_builder = BasicOutputBuilder::new_with_minimum_storage_deposit(rent_structure) .add_unlock_condition(AddressUnlockCondition::new(address)); - let account_output_builder = AccountOutputBuilder::new_with_minimum_storage_deposit(rent_struct, AccountId::null()); - let foundry_output_builder = FoundryOutputBuilder::new_with_minimum_storage_deposit(rent_struct, 1, token_scheme); + let account_output_builder = + AccountOutputBuilder::new_with_minimum_storage_deposit(rent_structure, AccountId::null()); + let foundry_output_builder = + FoundryOutputBuilder::new_with_minimum_storage_deposit(rent_structure, 1, token_scheme); let outputs = [ //// most simple output diff --git a/sdk/src/types/block/address/ed25519.rs b/sdk/src/types/block/address/ed25519.rs index 78bfac5ad9..cfbd2495b4 100644 --- a/sdk/src/types/block/address/ed25519.rs +++ b/sdk/src/types/block/address/ed25519.rs @@ -56,7 +56,7 @@ impl core::fmt::Debug for Ed25519Address { } impl StorageScore for Ed25519Address { - fn storage_score(&self, rent_struct: RentStructure) -> u64 { + fn storage_score(&self, rent_structure: RentStructure) -> u64 { // TODO: wait for TIP for this to change?! 0 } diff --git a/sdk/src/types/block/address/mod.rs b/sdk/src/types/block/address/mod.rs index 732fb126c2..fad40d3c57 100644 --- a/sdk/src/types/block/address/mod.rs +++ b/sdk/src/types/block/address/mod.rs @@ -216,11 +216,11 @@ impl From<&Self> for Address { } impl StorageScore for Address { - fn storage_score(&self, rent_struct: RentStructure) -> u64 { + fn storage_score(&self, rent_structure: RentStructure) -> u64 { match self { - Self::Account(account) => account.storage_score(rent_struct), - Self::Ed25519(ed25519) => ed25519.storage_score(rent_struct), - Self::Nft(nft) => nft.storage_score(rent_struct), + Self::Account(account) => account.storage_score(rent_structure), + Self::Ed25519(ed25519) => ed25519.storage_score(rent_structure), + Self::Nft(nft) => nft.storage_score(rent_structure), // TODO: other address types once merged } } diff --git a/sdk/src/types/block/output/account.rs b/sdk/src/types/block/output/account.rs index 459ff412ea..ec1d8ef02c 100644 --- a/sdk/src/types/block/output/account.rs +++ b/sdk/src/types/block/output/account.rs @@ -116,8 +116,8 @@ impl AccountOutputBuilder { /// Creates an [`AccountOutputBuilder`] with a provided rent structure. /// The amount will be set to the minimum storage deposit. - pub fn new_with_minimum_storage_deposit(rent_struct: RentStructure, account_id: AccountId) -> Self { - Self::new(OutputBuilderAmount::MinimumStorageDeposit(rent_struct), account_id) + pub fn new_with_minimum_storage_deposit(rent_structure: RentStructure, account_id: AccountId) -> Self { + Self::new(OutputBuilderAmount::MinimumStorageDeposit(rent_structure), account_id) } fn new(amount: OutputBuilderAmount, account_id: AccountId) -> Self { @@ -144,8 +144,8 @@ impl AccountOutputBuilder { /// Sets the amount to the minimum storage deposit. #[inline(always)] - pub fn with_minimum_storage_deposit(mut self, rent_struct: RentStructure) -> Self { - self.amount = OutputBuilderAmount::MinimumStorageDeposit(rent_struct); + pub fn with_minimum_storage_deposit(mut self, rent_structure: RentStructure) -> Self { + self.amount = OutputBuilderAmount::MinimumStorageDeposit(rent_structure); self } @@ -322,8 +322,8 @@ impl AccountOutputBuilder { output.amount = match self.amount { OutputBuilderAmount::Amount(amount) => amount, - OutputBuilderAmount::MinimumStorageDeposit(rent_struct) => { - Output::Account(output.clone()).rent_cost(rent_struct) + OutputBuilderAmount::MinimumStorageDeposit(rent_structure) => { + Output::Account(output.clone()).rent_cost(rent_structure) } }; @@ -417,10 +417,10 @@ impl AccountOutput { /// The amount will be set to the minimum storage deposit. #[inline(always)] pub fn build_with_minimum_storage_deposit( - rent_struct: RentStructure, + rent_structure: RentStructure, account_id: AccountId, ) -> AccountOutputBuilder { - AccountOutputBuilder::new_with_minimum_storage_deposit(rent_struct, account_id) + AccountOutputBuilder::new_with_minimum_storage_deposit(rent_structure, account_id) } /// @@ -731,13 +731,13 @@ impl Packable for AccountOutput { } impl StorageScore for AccountOutput { - fn storage_score(&self, rent_struct: RentStructure) -> u64 { - storage_score_offset_output(rent_struct) - + self.packed_len() as u64 * rent_struct.storage_score_factor_data() as u64 - + self.native_tokens().storage_score(rent_struct) - + self.unlock_conditions().storage_score(rent_struct) - + self.features().storage_score(rent_struct) - + self.immutable_features().storage_score(rent_struct) + fn storage_score(&self, rent_structure: RentStructure) -> u64 { + storage_score_offset_output(rent_structure) + + self.packed_len() as u64 * rent_structure.storage_score_factor_data() as u64 + + self.native_tokens().storage_score(rent_structure) + + self.unlock_conditions().storage_score(rent_structure) + + self.features().storage_score(rent_structure) + + self.immutable_features().storage_score(rent_structure) } } @@ -871,8 +871,8 @@ pub(crate) mod dto { let params = params.into(); let mut builder = match amount { OutputBuilderAmount::Amount(amount) => AccountOutputBuilder::new_with_amount(amount, *account_id), - OutputBuilderAmount::MinimumStorageDeposit(rent_struct) => { - AccountOutputBuilder::new_with_minimum_storage_deposit(rent_struct, *account_id) + OutputBuilderAmount::MinimumStorageDeposit(rent_structure) => { + AccountOutputBuilder::new_with_minimum_storage_deposit(rent_structure, *account_id) } } .with_mana(mana); diff --git a/sdk/src/types/block/output/basic.rs b/sdk/src/types/block/output/basic.rs index 10f1d0756b..de6d93a0a9 100644 --- a/sdk/src/types/block/output/basic.rs +++ b/sdk/src/types/block/output/basic.rs @@ -46,8 +46,8 @@ impl BasicOutputBuilder { /// Creates an [`BasicOutputBuilder`] with a provided rent structure. /// The amount will be set to the minimum storage deposit. #[inline(always)] - pub fn new_with_minimum_storage_deposit(rent_struct: RentStructure) -> Self { - Self::new(OutputBuilderAmount::MinimumStorageDeposit(rent_struct)) + pub fn new_with_minimum_storage_deposit(rent_structure: RentStructure) -> Self { + Self::new(OutputBuilderAmount::MinimumStorageDeposit(rent_structure)) } fn new(amount: OutputBuilderAmount) -> Self { @@ -69,8 +69,8 @@ impl BasicOutputBuilder { /// Sets the amount to the minimum storage deposit. #[inline(always)] - pub fn with_minimum_storage_deposit(mut self, rent_struct: RentStructure) -> Self { - self.amount = OutputBuilderAmount::MinimumStorageDeposit(rent_struct); + pub fn with_minimum_storage_deposit(mut self, rent_structure: RentStructure) -> Self { + self.amount = OutputBuilderAmount::MinimumStorageDeposit(rent_structure); self } @@ -172,8 +172,8 @@ impl BasicOutputBuilder { output.amount = match self.amount { OutputBuilderAmount::Amount(amount) => amount, - OutputBuilderAmount::MinimumStorageDeposit(rent_struct) => { - Output::Basic(output.clone()).rent_cost(rent_struct) + OutputBuilderAmount::MinimumStorageDeposit(rent_structure) => { + Output::Basic(output.clone()).rent_cost(rent_structure) } }; @@ -254,8 +254,8 @@ impl BasicOutput { /// Creates a new [`BasicOutputBuilder`] with a provided rent structure. /// The amount will be set to the minimum storage deposit. #[inline(always)] - pub fn build_with_minimum_storage_deposit(rent_struct: RentStructure) -> BasicOutputBuilder { - BasicOutputBuilder::new_with_minimum_storage_deposit(rent_struct) + pub fn build_with_minimum_storage_deposit(rent_structure: RentStructure) -> BasicOutputBuilder { + BasicOutputBuilder::new_with_minimum_storage_deposit(rent_structure) } /// @@ -325,12 +325,12 @@ impl BasicOutput { } impl StorageScore for BasicOutput { - fn storage_score(&self, rent_struct: RentStructure) -> u64 { - storage_score_offset_output(rent_struct) - + self.packed_len() as u64 * rent_struct.storage_score_factor_data() as u64 - + self.native_tokens().storage_score(rent_struct) - + self.unlock_conditions().storage_score(rent_struct) - + self.features().storage_score(rent_struct) + fn storage_score(&self, rent_structure: RentStructure) -> u64 { + storage_score_offset_output(rent_structure) + + self.packed_len() as u64 * rent_structure.storage_score_factor_data() as u64 + + self.native_tokens().storage_score(rent_structure) + + self.unlock_conditions().storage_score(rent_structure) + + self.features().storage_score(rent_structure) } } @@ -439,8 +439,8 @@ pub(crate) mod dto { let params = params.into(); let mut builder = match amount { OutputBuilderAmount::Amount(amount) => BasicOutputBuilder::new_with_amount(amount), - OutputBuilderAmount::MinimumStorageDeposit(rent_struct) => { - BasicOutputBuilder::new_with_minimum_storage_deposit(rent_struct) + OutputBuilderAmount::MinimumStorageDeposit(rent_structure) => { + BasicOutputBuilder::new_with_minimum_storage_deposit(rent_structure) } } .with_mana(mana); diff --git a/sdk/src/types/block/output/delegation.rs b/sdk/src/types/block/output/delegation.rs index 93af69a3ec..cb64bdf5e4 100644 --- a/sdk/src/types/block/output/delegation.rs +++ b/sdk/src/types/block/output/delegation.rs @@ -80,13 +80,13 @@ impl DelegationOutputBuilder { /// Creates a [`DelegationOutputBuilder`] with a provided rent structure. /// The amount will be set to the minimum storage deposit. pub fn new_with_minimum_storage_deposit( - rent_struct: RentStructure, + rent_structure: RentStructure, delegated_amount: u64, delegation_id: DelegationId, validator_address: AccountAddress, ) -> Self { Self::new( - OutputBuilderAmount::MinimumStorageDeposit(rent_struct), + OutputBuilderAmount::MinimumStorageDeposit(rent_structure), delegated_amount, delegation_id, validator_address, @@ -117,8 +117,8 @@ impl DelegationOutputBuilder { } /// Sets the amount to the minimum storage deposit. - pub fn with_minimum_storage_deposit(mut self, rent_struct: RentStructure) -> Self { - self.amount = OutputBuilderAmount::MinimumStorageDeposit(rent_struct); + pub fn with_minimum_storage_deposit(mut self, rent_structure: RentStructure) -> Self { + self.amount = OutputBuilderAmount::MinimumStorageDeposit(rent_structure); self } @@ -195,8 +195,8 @@ impl DelegationOutputBuilder { output.amount = match self.amount { OutputBuilderAmount::Amount(amount) => amount, - OutputBuilderAmount::MinimumStorageDeposit(rent_struct) => { - Output::Delegation(output.clone()).rent_cost(rent_struct) + OutputBuilderAmount::MinimumStorageDeposit(rent_structure) => { + Output::Delegation(output.clone()).rent_cost(rent_structure) } }; @@ -277,13 +277,13 @@ impl DelegationOutput { /// Creates a new [`DelegationOutputBuilder`] with a provided rent structure. /// The amount will be set to the minimum storage deposit. pub fn build_with_minimum_storage_deposit( - rent_struct: RentStructure, + rent_structure: RentStructure, delegated_amount: u64, delegation_id: DelegationId, validator_address: AccountAddress, ) -> DelegationOutputBuilder { DelegationOutputBuilder::new_with_minimum_storage_deposit( - rent_struct, + rent_structure, delegated_amount, delegation_id, validator_address, @@ -457,11 +457,11 @@ impl Packable for DelegationOutput { } impl StorageScore for DelegationOutput { - fn storage_score(&self, rent_struct: RentStructure) -> u64 { - storage_score_offset_output(rent_struct) - + rent_struct.storage_score_offset_delegation() - + self.packed_len() as u64 * rent_struct.storage_score_factor_data() as u64 - + self.unlock_conditions().storage_score(rent_struct) + fn storage_score(&self, rent_structure: RentStructure) -> u64 { + storage_score_offset_output(rent_structure) + + rent_structure.storage_score_offset_delegation() + + self.packed_len() as u64 * rent_structure.storage_score_factor_data() as u64 + + self.unlock_conditions().storage_score(rent_structure) } } @@ -571,9 +571,9 @@ pub(crate) mod dto { *delegation_id, *validator_address, ), - OutputBuilderAmount::MinimumStorageDeposit(rent_struct) => { + OutputBuilderAmount::MinimumStorageDeposit(rent_structure) => { DelegationOutputBuilder::new_with_minimum_storage_deposit( - rent_struct, + rent_structure, delegated_amount, *delegation_id, *validator_address, diff --git a/sdk/src/types/block/output/feature/block_issuer.rs b/sdk/src/types/block/output/feature/block_issuer.rs index fb16826a00..9f9c36d6e3 100644 --- a/sdk/src/types/block/output/feature/block_issuer.rs +++ b/sdk/src/types/block/output/feature/block_issuer.rs @@ -62,9 +62,9 @@ impl BlockIssuerKey { } impl StorageScore for BlockIssuerKey { - fn storage_score(&self, rent_struct: RentStructure) -> u64 { + fn storage_score(&self, rent_structure: RentStructure) -> u64 { match self { - Self::Ed25519(key) => key.storage_score(rent_struct), + Self::Ed25519(key) => key.storage_score(rent_structure), } } } @@ -118,8 +118,8 @@ impl Packable for Ed25519BlockIssuerKey { } impl StorageScore for Ed25519BlockIssuerKey { - fn storage_score(&self, rent_struct: RentStructure) -> u64 { - rent_struct.storage_score_offset_ed25519_block_issuer_key() + fn storage_score(&self, rent_structure: RentStructure) -> u64 { + rent_structure.storage_score_offset_ed25519_block_issuer_key() } } @@ -206,8 +206,8 @@ impl BlockIssuerKeys { } impl StorageScore for BlockIssuerKeys { - fn storage_score(&self, rent_struct: RentStructure) -> u64 { - (*self).iter().map(|key| key.storage_score(rent_struct)).sum() + fn storage_score(&self, rent_structure: RentStructure) -> u64 { + (*self).iter().map(|key| key.storage_score(rent_structure)).sum() } } @@ -252,8 +252,8 @@ impl BlockIssuerFeature { } impl StorageScore for BlockIssuerFeature { - fn storage_score(&self, rent_struct: RentStructure) -> u64 { - self.block_issuer_keys.storage_score(rent_struct) + fn storage_score(&self, rent_structure: RentStructure) -> u64 { + self.block_issuer_keys.storage_score(rent_structure) } } diff --git a/sdk/src/types/block/output/feature/issuer.rs b/sdk/src/types/block/output/feature/issuer.rs index bd801d52d4..d6d35733ad 100644 --- a/sdk/src/types/block/output/feature/issuer.rs +++ b/sdk/src/types/block/output/feature/issuer.rs @@ -30,8 +30,8 @@ impl IssuerFeature { } impl StorageScore for IssuerFeature { - fn storage_score(&self, rent_struct: RentStructure) -> u64 { - self.0.storage_score(rent_struct) + fn storage_score(&self, rent_structure: RentStructure) -> u64 { + self.0.storage_score(rent_structure) } } diff --git a/sdk/src/types/block/output/feature/metadata.rs b/sdk/src/types/block/output/feature/metadata.rs index 18bb3556d6..30f645fcc9 100644 --- a/sdk/src/types/block/output/feature/metadata.rs +++ b/sdk/src/types/block/output/feature/metadata.rs @@ -101,7 +101,7 @@ impl core::fmt::Debug for MetadataFeature { } impl StorageScore for MetadataFeature { - fn storage_score(&self, rent_struct: RentStructure) -> u64 { + fn storage_score(&self, rent_structure: RentStructure) -> u64 { 0 } } diff --git a/sdk/src/types/block/output/feature/mod.rs b/sdk/src/types/block/output/feature/mod.rs index b65675194f..78842ca59a 100644 --- a/sdk/src/types/block/output/feature/mod.rs +++ b/sdk/src/types/block/output/feature/mod.rs @@ -202,14 +202,14 @@ impl Feature { } impl StorageScore for Feature { - fn storage_score(&self, rent_struct: RentStructure) -> u64 { + fn storage_score(&self, rent_structure: RentStructure) -> u64 { match self { - Self::Sender(sender) => sender.storage_score(rent_struct), - Self::Issuer(issuer) => issuer.storage_score(rent_struct), - Self::Metadata(metadata) => metadata.storage_score(rent_struct), - Self::Tag(tag) => tag.storage_score(rent_struct), - Self::BlockIssuer(block_issuer) => block_issuer.storage_score(rent_struct), - Self::Staking(staking) => staking.storage_score(rent_struct), + Self::Sender(sender) => sender.storage_score(rent_structure), + Self::Issuer(issuer) => issuer.storage_score(rent_structure), + Self::Metadata(metadata) => metadata.storage_score(rent_structure), + Self::Tag(tag) => tag.storage_score(rent_structure), + Self::BlockIssuer(block_issuer) => block_issuer.storage_score(rent_structure), + Self::Staking(staking) => staking.storage_score(rent_structure), } } } @@ -331,8 +331,8 @@ impl Features { } impl StorageScore for Features { - fn storage_score(&self, rent_struct: RentStructure) -> u64 { - self.0.iter().map(|f| f.storage_score(rent_struct)).sum() + fn storage_score(&self, rent_structure: RentStructure) -> u64 { + self.0.iter().map(|f| f.storage_score(rent_structure)).sum() } } diff --git a/sdk/src/types/block/output/feature/sender.rs b/sdk/src/types/block/output/feature/sender.rs index 8004b2e8ff..e831683804 100644 --- a/sdk/src/types/block/output/feature/sender.rs +++ b/sdk/src/types/block/output/feature/sender.rs @@ -30,10 +30,10 @@ impl SenderFeature { } impl StorageScore for SenderFeature { - fn storage_score(&self, rent_struct: RentStructure) -> u64 { - // TODO: In iota.go you can specify a closure f(rent_struct) -> u64 for this feature + fn storage_score(&self, rent_structure: RentStructure) -> u64 { + // TODO: In iota.go you can specify a closure f(rent_structure) -> u64 for this feature // which immediately returns, hence overrides the default storage score. - self.0.storage_score(rent_struct) + self.0.storage_score(rent_structure) } } diff --git a/sdk/src/types/block/output/feature/staking.rs b/sdk/src/types/block/output/feature/staking.rs index 8f78e61a50..7727cd8314 100644 --- a/sdk/src/types/block/output/feature/staking.rs +++ b/sdk/src/types/block/output/feature/staking.rs @@ -60,10 +60,10 @@ impl StakingFeature { } impl StorageScore for StakingFeature { - fn storage_score(&self, rent_struct: RentStructure) -> u64 { - // TODO: In iota.go you can specify a closure f(rent_struct) -> u64 for this feature + fn storage_score(&self, rent_structure: RentStructure) -> u64 { + // TODO: In iota.go you can specify a closure f(rent_structure) -> u64 for this feature // which immediately returns, hence overrides the default storage score. - rent_struct.storage_score_offset_staking_feature() + rent_structure.storage_score_offset_staking_feature() } } diff --git a/sdk/src/types/block/output/feature/tag.rs b/sdk/src/types/block/output/feature/tag.rs index 9f73a4f6fc..41ff9abe55 100644 --- a/sdk/src/types/block/output/feature/tag.rs +++ b/sdk/src/types/block/output/feature/tag.rs @@ -71,7 +71,7 @@ impl core::fmt::Debug for TagFeature { impl StorageScore for TagFeature { fn storage_score(&self, _rent_struct: RentStructure) -> u64 { - // TODO: In iota.go you can specify a closure f(rent_struct) -> u64 for this feature + // TODO: In iota.go you can specify a closure f(rent_structure) -> u64 for this feature // which immediately returns, hence overrides the default storage score. 0 } diff --git a/sdk/src/types/block/output/foundry.rs b/sdk/src/types/block/output/foundry.rs index 655a183be9..4a7168c375 100644 --- a/sdk/src/types/block/output/foundry.rs +++ b/sdk/src/types/block/output/foundry.rs @@ -104,12 +104,12 @@ impl FoundryOutputBuilder { /// Creates a [`FoundryOutputBuilder`] with a provided rent structure. /// The amount will be set to the minimum storage deposit. pub fn new_with_minimum_storage_deposit( - rent_struct: RentStructure, + rent_structure: RentStructure, serial_number: u32, token_scheme: TokenScheme, ) -> Self { Self::new( - OutputBuilderAmount::MinimumStorageDeposit(rent_struct), + OutputBuilderAmount::MinimumStorageDeposit(rent_structure), serial_number, token_scheme, ) @@ -136,8 +136,8 @@ impl FoundryOutputBuilder { /// Sets the amount to the minimum storage deposit. #[inline(always)] - pub fn with_minimum_storage_deposit(mut self, rent_struct: RentStructure) -> Self { - self.amount = OutputBuilderAmount::MinimumStorageDeposit(rent_struct); + pub fn with_minimum_storage_deposit(mut self, rent_structure: RentStructure) -> Self { + self.amount = OutputBuilderAmount::MinimumStorageDeposit(rent_structure); self } @@ -283,8 +283,8 @@ impl FoundryOutputBuilder { output.amount = match self.amount { OutputBuilderAmount::Amount(amount) => amount, - OutputBuilderAmount::MinimumStorageDeposit(rent_struct) => { - Output::Foundry(output.clone()).rent_cost(rent_struct) + OutputBuilderAmount::MinimumStorageDeposit(rent_structure) => { + Output::Foundry(output.clone()).rent_cost(rent_structure) } }; @@ -366,11 +366,11 @@ impl FoundryOutput { /// The amount will be set to the minimum storage deposit. #[inline(always)] pub fn build_with_minimum_storage_deposit( - rent_struct: RentStructure, + rent_structure: RentStructure, serial_number: u32, token_scheme: TokenScheme, ) -> FoundryOutputBuilder { - FoundryOutputBuilder::new_with_minimum_storage_deposit(rent_struct, serial_number, token_scheme) + FoundryOutputBuilder::new_with_minimum_storage_deposit(rent_structure, serial_number, token_scheme) } /// @@ -659,14 +659,14 @@ impl Packable for FoundryOutput { } impl StorageScore for FoundryOutput { - fn storage_score(&self, rent_struct: RentStructure) -> u64 { - storage_score_offset_output(rent_struct) - + self.packed_len() as u64 * rent_struct.storage_score_factor_data() as u64 - + self.native_tokens().storage_score(rent_struct) - + self.token_scheme().storage_score(rent_struct) - + self.unlock_conditions().storage_score(rent_struct) - + self.features().storage_score(rent_struct) - + self.immutable_features().storage_score(rent_struct) + fn storage_score(&self, rent_structure: RentStructure) -> u64 { + storage_score_offset_output(rent_structure) + + self.packed_len() as u64 * rent_structure.storage_score_factor_data() as u64 + + self.native_tokens().storage_score(rent_structure) + + self.token_scheme().storage_score(rent_structure) + + self.unlock_conditions().storage_score(rent_structure) + + self.features().storage_score(rent_structure) + + self.immutable_features().storage_score(rent_structure) } } @@ -771,8 +771,8 @@ pub(crate) mod dto { OutputBuilderAmount::Amount(amount) => { FoundryOutputBuilder::new_with_amount(amount, serial_number, token_scheme) } - OutputBuilderAmount::MinimumStorageDeposit(rent_struct) => { - FoundryOutputBuilder::new_with_minimum_storage_deposit(rent_struct, serial_number, token_scheme) + OutputBuilderAmount::MinimumStorageDeposit(rent_structure) => { + FoundryOutputBuilder::new_with_minimum_storage_deposit(rent_structure, serial_number, token_scheme) } }; diff --git a/sdk/src/types/block/output/mod.rs b/sdk/src/types/block/output/mod.rs index 01ad20135a..239ca49b32 100644 --- a/sdk/src/types/block/output/mod.rs +++ b/sdk/src/types/block/output/mod.rs @@ -385,8 +385,8 @@ impl Output { /// storage score, given by [`RentParameters`]. /// If there is a [`StorageDepositReturnUnlockCondition`](unlock_condition::StorageDepositReturnUnlockCondition), /// its amount is also checked. - pub fn verify_storage_deposit(&self, rent_struct: RentStructure, token_supply: u64) -> Result<(), Error> { - let required_output_amount = self.rent_cost(rent_struct); + pub fn verify_storage_deposit(&self, rent_structure: RentStructure, token_supply: u64) -> Result<(), Error> { + let required_output_amount = self.rent_cost(rent_structure); if self.amount() < required_output_amount { return Err(Error::InsufficientStorageDepositAmount { @@ -408,7 +408,8 @@ impl Output { }); } - let minimum_deposit = minimum_storage_deposit(return_condition.return_address(), rent_struct, token_supply); + let minimum_deposit = + minimum_storage_deposit(return_condition.return_address(), rent_structure, token_supply); // `Minimum Storage Deposit` ≤ `Return Amount` if return_condition.amount() < minimum_deposit { @@ -502,47 +503,47 @@ pub(crate) fn verify_output_amount_packable( /// Computes the minimum amount that a storage deposit has to match to allow creating a return [`Output`] back to the /// sender [`Address`]. -fn minimum_storage_deposit(address: &Address, rent_struct: RentStructure, token_supply: u64) -> u64 { +fn minimum_storage_deposit(address: &Address, rent_structure: RentStructure, token_supply: u64) -> u64 { // PANIC: This can never fail because the amount will always be within the valid range. Also, the actual value is // not important, we are only interested in the storage requirements of the type. - BasicOutputBuilder::new_with_minimum_storage_deposit(rent_struct) + BasicOutputBuilder::new_with_minimum_storage_deposit(rent_structure) .add_unlock_condition(AddressUnlockCondition::new(*address)) .finish_with_params(token_supply) .unwrap() .amount() } -fn storage_score_offset_output(rent_struct: RentStructure) -> u64 { +fn storage_score_offset_output(rent_structure: RentStructure) -> u64 { // included output id, block id, and slot booked data size - rent_struct.storage_score_offset_output() - + rent_struct.storage_score_factor_data() as u64 + rent_structure.storage_score_offset_output() + + rent_structure.storage_score_factor_data() as u64 * (size_of::() as u64 + size_of::() as u64 + size_of::() as u64) } impl StorageScore for Output { - fn storage_score(&self, rent_struct: RentStructure) -> u64 { + fn storage_score(&self, rent_structure: RentStructure) -> u64 { // +1 score for the output kind - rent_struct.storage_score_factor_data() as u64 * size_of::() as u64 + rent_structure.storage_score_factor_data() as u64 * size_of::() as u64 + match self { - Self::Basic(basic) => basic.storage_score(rent_struct), - Self::Account(account) => account.storage_score(rent_struct), - Self::Foundry(foundry) => foundry.storage_score(rent_struct), - Self::Nft(nft) => nft.storage_score(rent_struct), - Self::Delegation(delegation) => delegation.storage_score(rent_struct), + Self::Basic(basic) => basic.storage_score(rent_structure), + Self::Account(account) => account.storage_score(rent_structure), + Self::Foundry(foundry) => foundry.storage_score(rent_structure), + Self::Nft(nft) => nft.storage_score(rent_structure), + Self::Delegation(delegation) => delegation.storage_score(rent_structure), } } } pub struct MinimumStorageDepositBasicOutput { - rent_struct: RentStructure, + rent_structure: RentStructure, token_supply: u64, builder: BasicOutputBuilder, } impl MinimumStorageDepositBasicOutput { - pub fn new(rent_struct: RentStructure, token_supply: u64) -> Self { + pub fn new(rent_structure: RentStructure, token_supply: u64) -> Self { Self { - rent_struct, + rent_structure, token_supply, builder: BasicOutputBuilder::new_with_amount(Output::AMOUNT_MIN).add_unlock_condition( AddressUnlockCondition::new(Address::from(Ed25519Address::from([0; Ed25519Address::LENGTH]))), @@ -580,7 +581,7 @@ impl MinimumStorageDepositBasicOutput { Ok(self .builder .finish_output(self.token_supply)? - .rent_cost(self.rent_struct)) + .rent_cost(self.rent_structure)) } } #[cfg(feature = "serde")] diff --git a/sdk/src/types/block/output/native_token.rs b/sdk/src/types/block/output/native_token.rs index 2fe07bf9bd..aab5e42140 100644 --- a/sdk/src/types/block/output/native_token.rs +++ b/sdk/src/types/block/output/native_token.rs @@ -78,7 +78,7 @@ impl Ord for NativeToken { } impl StorageScore for NativeToken { - fn storage_score(&self, rent_struct: RentStructure) -> u64 { + fn storage_score(&self, rent_structure: RentStructure) -> u64 { 0 } } @@ -258,8 +258,8 @@ impl NativeTokens { } impl StorageScore for NativeTokens { - fn storage_score(&self, rent_struct: RentStructure) -> u64 { - self.0.iter().map(|nt| nt.storage_score(rent_struct)).sum() + fn storage_score(&self, rent_structure: RentStructure) -> u64 { + self.0.iter().map(|nt| nt.storage_score(rent_structure)).sum() } } diff --git a/sdk/src/types/block/output/nft.rs b/sdk/src/types/block/output/nft.rs index ce1874f9ba..b4d9400be6 100644 --- a/sdk/src/types/block/output/nft.rs +++ b/sdk/src/types/block/output/nft.rs @@ -76,8 +76,8 @@ impl NftOutputBuilder { /// Creates an [`NftOutputBuilder`] with a provided rent structure. /// The amount will be set to the minimum storage deposit. - pub fn new_with_minimum_storage_deposit(rent_struct: RentStructure, nft_id: NftId) -> Self { - Self::new(OutputBuilderAmount::MinimumStorageDeposit(rent_struct), nft_id) + pub fn new_with_minimum_storage_deposit(rent_structure: RentStructure, nft_id: NftId) -> Self { + Self::new(OutputBuilderAmount::MinimumStorageDeposit(rent_structure), nft_id) } fn new(amount: OutputBuilderAmount, nft_id: NftId) -> Self { @@ -101,8 +101,8 @@ impl NftOutputBuilder { /// Sets the amount to the minimum storage deposit. #[inline(always)] - pub fn with_minimum_storage_deposit(mut self, rent_struct: RentStructure) -> Self { - self.amount = OutputBuilderAmount::MinimumStorageDeposit(rent_struct); + pub fn with_minimum_storage_deposit(mut self, rent_structure: RentStructure) -> Self { + self.amount = OutputBuilderAmount::MinimumStorageDeposit(rent_structure); self } @@ -244,8 +244,8 @@ impl NftOutputBuilder { output.amount = match self.amount { OutputBuilderAmount::Amount(amount) => amount, - OutputBuilderAmount::MinimumStorageDeposit(rent_struct) => { - Output::Nft(output.clone()).rent_cost(rent_struct) + OutputBuilderAmount::MinimumStorageDeposit(rent_structure) => { + Output::Nft(output.clone()).rent_cost(rent_structure) } }; @@ -328,8 +328,8 @@ impl NftOutput { /// Creates a new [`NftOutputBuilder`] with a provided rent structure. /// The amount will be set to the minimum storage deposit. #[inline(always)] - pub fn build_with_minimum_storage_deposit(rent_struct: RentStructure, nft_id: NftId) -> NftOutputBuilder { - NftOutputBuilder::new_with_minimum_storage_deposit(rent_struct, nft_id) + pub fn build_with_minimum_storage_deposit(rent_structure: RentStructure, nft_id: NftId) -> NftOutputBuilder { + NftOutputBuilder::new_with_minimum_storage_deposit(rent_structure, nft_id) } /// @@ -522,13 +522,13 @@ impl Packable for NftOutput { } impl StorageScore for NftOutput { - fn storage_score(&self, rent_struct: RentStructure) -> u64 { - storage_score_offset_output(rent_struct) - + self.packed_len() as u64 * rent_struct.storage_score_factor_data() as u64 - + self.native_tokens().storage_score(rent_struct) - + self.unlock_conditions().storage_score(rent_struct) - + self.features().storage_score(rent_struct) - + self.immutable_features().storage_score(rent_struct) + fn storage_score(&self, rent_structure: RentStructure) -> u64 { + storage_score_offset_output(rent_structure) + + self.packed_len() as u64 * rent_structure.storage_score_factor_data() as u64 + + self.native_tokens().storage_score(rent_structure) + + self.unlock_conditions().storage_score(rent_structure) + + self.features().storage_score(rent_structure) + + self.immutable_features().storage_score(rent_structure) } } @@ -629,8 +629,8 @@ pub(crate) mod dto { let params = params.into(); let mut builder = match amount { OutputBuilderAmount::Amount(amount) => NftOutputBuilder::new_with_amount(amount, *nft_id), - OutputBuilderAmount::MinimumStorageDeposit(rent_struct) => { - NftOutputBuilder::new_with_minimum_storage_deposit(rent_struct, *nft_id) + OutputBuilderAmount::MinimumStorageDeposit(rent_structure) => { + NftOutputBuilder::new_with_minimum_storage_deposit(rent_structure, *nft_id) } } .with_mana(mana); diff --git a/sdk/src/types/block/output/token_scheme/mod.rs b/sdk/src/types/block/output/token_scheme/mod.rs index 4bdd317bc0..3a71068d9a 100644 --- a/sdk/src/types/block/output/token_scheme/mod.rs +++ b/sdk/src/types/block/output/token_scheme/mod.rs @@ -50,9 +50,9 @@ impl TokenScheme { } impl StorageScore for TokenScheme { - fn storage_score(&self, rent_struct: RentStructure) -> u64 { + fn storage_score(&self, rent_structure: RentStructure) -> u64 { match self { - Self::Simple(simple) => simple.storage_score(rent_struct), + Self::Simple(simple) => simple.storage_score(rent_structure), } } } diff --git a/sdk/src/types/block/output/token_scheme/simple.rs b/sdk/src/types/block/output/token_scheme/simple.rs index 1f0c833d82..791368b7d7 100644 --- a/sdk/src/types/block/output/token_scheme/simple.rs +++ b/sdk/src/types/block/output/token_scheme/simple.rs @@ -107,7 +107,7 @@ impl Packable for SimpleTokenScheme { } impl StorageScore for SimpleTokenScheme { - fn storage_score(&self, rent_struct: RentStructure) -> u64 { + fn storage_score(&self, rent_structure: RentStructure) -> u64 { 0 } } diff --git a/sdk/src/types/block/output/unlock_condition/address.rs b/sdk/src/types/block/output/unlock_condition/address.rs index 8569745ef0..e829d2f8c5 100644 --- a/sdk/src/types/block/output/unlock_condition/address.rs +++ b/sdk/src/types/block/output/unlock_condition/address.rs @@ -30,8 +30,8 @@ impl AddressUnlockCondition { } impl StorageScore for AddressUnlockCondition { - fn storage_score(&self, rent_struct: RentStructure) -> u64 { - self.0.storage_score(rent_struct) + fn storage_score(&self, rent_structure: RentStructure) -> u64 { + self.0.storage_score(rent_structure) } } diff --git a/sdk/src/types/block/output/unlock_condition/expiration.rs b/sdk/src/types/block/output/unlock_condition/expiration.rs index f4f458bfeb..8afb937671 100644 --- a/sdk/src/types/block/output/unlock_condition/expiration.rs +++ b/sdk/src/types/block/output/unlock_condition/expiration.rs @@ -61,8 +61,8 @@ impl ExpirationUnlockCondition { } impl StorageScore for ExpirationUnlockCondition { - fn storage_score(&self, rent_struct: RentStructure) -> u64 { - self.return_address.storage_score(rent_struct) + fn storage_score(&self, rent_structure: RentStructure) -> u64 { + self.return_address.storage_score(rent_structure) } } diff --git a/sdk/src/types/block/output/unlock_condition/governor_address.rs b/sdk/src/types/block/output/unlock_condition/governor_address.rs index 5ba110b854..94e151790a 100644 --- a/sdk/src/types/block/output/unlock_condition/governor_address.rs +++ b/sdk/src/types/block/output/unlock_condition/governor_address.rs @@ -32,8 +32,8 @@ impl GovernorAddressUnlockCondition { } impl StorageScore for GovernorAddressUnlockCondition { - fn storage_score(&self, rent_struct: RentStructure) -> u64 { - self.0.storage_score(rent_struct) + fn storage_score(&self, rent_structure: RentStructure) -> u64 { + self.0.storage_score(rent_structure) } } diff --git a/sdk/src/types/block/output/unlock_condition/immutable_account_address.rs b/sdk/src/types/block/output/unlock_condition/immutable_account_address.rs index ad8d67c9bd..5fe3879ed7 100644 --- a/sdk/src/types/block/output/unlock_condition/immutable_account_address.rs +++ b/sdk/src/types/block/output/unlock_condition/immutable_account_address.rs @@ -30,8 +30,8 @@ impl ImmutableAccountAddressUnlockCondition { } impl StorageScore for ImmutableAccountAddressUnlockCondition { - fn storage_score(&self, rent_struct: RentStructure) -> u64 { - self.0.storage_score(rent_struct) + fn storage_score(&self, rent_structure: RentStructure) -> u64 { + self.0.storage_score(rent_structure) } } diff --git a/sdk/src/types/block/output/unlock_condition/mod.rs b/sdk/src/types/block/output/unlock_condition/mod.rs index 315f0354d5..3736e0e679 100644 --- a/sdk/src/types/block/output/unlock_condition/mod.rs +++ b/sdk/src/types/block/output/unlock_condition/mod.rs @@ -83,18 +83,18 @@ impl core::fmt::Debug for UnlockCondition { } impl StorageScore for UnlockCondition { - fn storage_score(&self, rent_struct: RentStructure) -> u64 { + fn storage_score(&self, rent_structure: RentStructure) -> u64 { match self { - Self::Address(address) => address.storage_score(rent_struct), - Self::StorageDepositReturn(storage_deposit_return) => storage_deposit_return.storage_score(rent_struct), - Self::Timelock(timelock) => timelock.storage_score(rent_struct), - Self::Expiration(expiration) => expiration.storage_score(rent_struct), + Self::Address(address) => address.storage_score(rent_structure), + Self::StorageDepositReturn(storage_deposit_return) => storage_deposit_return.storage_score(rent_structure), + Self::Timelock(timelock) => timelock.storage_score(rent_structure), + Self::Expiration(expiration) => expiration.storage_score(rent_structure), Self::StateControllerAddress(state_controller_address) => { - state_controller_address.storage_score(rent_struct) + state_controller_address.storage_score(rent_structure) } - Self::GovernorAddress(governor_address) => governor_address.storage_score(rent_struct), + Self::GovernorAddress(governor_address) => governor_address.storage_score(rent_structure), Self::ImmutableAccountAddress(immutable_account_address) => { - immutable_account_address.storage_score(rent_struct) + immutable_account_address.storage_score(rent_structure) } } } @@ -469,8 +469,8 @@ impl UnlockConditions { } impl StorageScore for UnlockConditions { - fn storage_score(&self, rent_struct: RentStructure) -> u64 { - self.0.iter().map(|uc| uc.storage_score(rent_struct)).sum() + fn storage_score(&self, rent_structure: RentStructure) -> u64 { + self.0.iter().map(|uc| uc.storage_score(rent_structure)).sum() } } diff --git a/sdk/src/types/block/output/unlock_condition/state_controller_address.rs b/sdk/src/types/block/output/unlock_condition/state_controller_address.rs index 978940ca82..9216aaadb9 100644 --- a/sdk/src/types/block/output/unlock_condition/state_controller_address.rs +++ b/sdk/src/types/block/output/unlock_condition/state_controller_address.rs @@ -33,8 +33,8 @@ impl StateControllerAddressUnlockCondition { } impl StorageScore for StateControllerAddressUnlockCondition { - fn storage_score(&self, rent_struct: RentStructure) -> u64 { - self.0.storage_score(rent_struct) + fn storage_score(&self, rent_structure: RentStructure) -> u64 { + self.0.storage_score(rent_structure) } } diff --git a/sdk/src/types/block/output/unlock_condition/storage_deposit_return.rs b/sdk/src/types/block/output/unlock_condition/storage_deposit_return.rs index 075e87fedd..f2a7c3f81c 100644 --- a/sdk/src/types/block/output/unlock_condition/storage_deposit_return.rs +++ b/sdk/src/types/block/output/unlock_condition/storage_deposit_return.rs @@ -49,8 +49,8 @@ impl StorageDepositReturnUnlockCondition { } impl StorageScore for StorageDepositReturnUnlockCondition { - fn storage_score(&self, rent_struct: RentStructure) -> u64 { - self.return_address.storage_score(rent_struct) + fn storage_score(&self, rent_structure: RentStructure) -> u64 { + self.return_address.storage_score(rent_structure) } } diff --git a/sdk/src/types/block/protocol/storage_score.rs b/sdk/src/types/block/protocol/storage_score.rs index f075ab4fe1..9fcd0fa852 100644 --- a/sdk/src/types/block/protocol/storage_score.rs +++ b/sdk/src/types/block/protocol/storage_score.rs @@ -41,7 +41,7 @@ pub struct RentStructure { impl RentStructure { /// Creates a new [`RentStructure`]. Computes the score offset for implicit account creation addresses. pub fn new(rent_parameters: RentParameters) -> Self { - let mut rent_struct = Self { + let mut rent_structure = Self { rent_parameters, storage_score_offset_implicit_account_creation_address: 0, }; @@ -56,8 +56,8 @@ impl RentStructure { .add_unlock_condition(AddressUnlockCondition::new(Ed25519Address::null())) .finish() .unwrap() - .storage_score(rent_struct); - let ed25519_address_score = Ed25519Address::null().storage_score(rent_struct); + .storage_score(rent_structure); + let ed25519_address_score = Ed25519Address::null().storage_score(rent_structure); // Unwrap: should never underflow. let basic_score_without_address = basic_output_score .checked_sub(ed25519_address_score) @@ -71,12 +71,12 @@ impl RentStructure { ) .finish() .unwrap() - .storage_score(rent_struct); + .storage_score(rent_structure); // Unwrap: should never underflow. - rent_struct.storage_score_offset_implicit_account_creation_address = account_output_score + rent_structure.storage_score_offset_implicit_account_creation_address = account_output_score .checked_sub(basic_score_without_address) .expect("underflow"); - rent_struct + rent_structure } } @@ -228,16 +228,16 @@ impl RentParameters { pub trait StorageScore { /// Computes the storage score given a [`RentStructure`]. Different fields in a type lead to different storage /// requirements for the ledger state. - fn storage_score(&self, rent_struct: RentStructure) -> u64; + fn storage_score(&self, rent_structure: RentStructure) -> u64; /// Computes the rent cost given a [`RentStructure`]. - fn rent_cost(&self, rent_struct: RentStructure) -> u64 { - rent_struct.storage_cost as u64 * self.storage_score(rent_struct) + fn rent_cost(&self, rent_structure: RentStructure) -> u64 { + rent_structure.storage_cost as u64 * self.storage_score(rent_structure) } } impl StorageScore for [T; N] { - fn storage_score(&self, rent_struct: RentStructure) -> u64 { - self.iter().map(|elem| elem.storage_score(rent_struct)).sum() + fn storage_score(&self, rent_structure: RentStructure) -> u64 { + self.iter().map(|elem| elem.storage_score(rent_structure)).sum() } } diff --git a/sdk/src/wallet/account/operations/balance.rs b/sdk/src/wallet/account/operations/balance.rs index 58540fde49..30f46cfede 100644 --- a/sdk/src/wallet/account/operations/balance.rs +++ b/sdk/src/wallet/account/operations/balance.rs @@ -64,7 +64,7 @@ where account_details: &AccountDetails, ) -> Result { let network_id = self.client().get_network_id().await?; - let rent_struct = self.client().get_rent_parameters().await?.into(); + let rent_structure = self.client().get_rent_parameters().await?.into(); let mut balance = Balance::default(); let mut total_rent_amount = 0; let mut total_native_tokens = NativeTokensBuilder::default(); @@ -90,7 +90,7 @@ where } let output = &data.output; - let rent = output.rent_cost(rent_struct); + let rent = output.rent_cost(rent_structure); // Add account and foundry outputs here because they can't have a // [`StorageDepositReturnUnlockCondition`] or time related unlock conditions diff --git a/sdk/src/wallet/account/operations/output_claiming.rs b/sdk/src/wallet/account/operations/output_claiming.rs index a47f05770a..635b126372 100644 --- a/sdk/src/wallet/account/operations/output_claiming.rs +++ b/sdk/src/wallet/account/operations/output_claiming.rs @@ -205,7 +205,7 @@ where log::debug!("[OUTPUT_CLAIMING] claim_outputs_internal"); let slot_index = self.client().get_slot_index().await?; - let rent_struct = self.client().get_rent_parameters().await?.into(); + let rent_structure = self.client().get_rent_parameters().await?.into(); let token_supply = self.client().get_token_supply().await?; let account_details = self.details().await; @@ -278,7 +278,7 @@ where .finish_output(token_supply)? } else { NftOutputBuilder::from(nft_output) - .with_minimum_storage_deposit(rent_struct) + .with_minimum_storage_deposit(rent_structure) .with_nft_id(nft_output.nft_id_non_null(&output_data.output_id)) .with_unlock_conditions([AddressUnlockCondition::new(first_account_address.address.inner)]) // Set native tokens empty, we will collect them from all inputs later @@ -303,7 +303,7 @@ where required_amount_for_nfts } else { required_amount_for_nfts - + MinimumStorageDepositBasicOutput::new(rent_struct, token_supply) + + MinimumStorageDepositBasicOutput::new(rent_structure, token_supply) .with_native_tokens(option_native_token) .finish()? }; @@ -323,7 +323,7 @@ where // Recalculate every time, because new inputs can also add more native tokens, which would increase // the required storage deposit required_amount = required_amount_for_nfts - + MinimumStorageDepositBasicOutput::new(rent_struct, token_supply) + + MinimumStorageDepositBasicOutput::new(rent_structure, token_supply) .with_native_tokens(option_native_token) .finish()?; diff --git a/sdk/src/wallet/account/operations/transaction/high_level/create_account.rs b/sdk/src/wallet/account/operations/transaction/high_level/create_account.rs index ffec7b9b3a..43a950ce52 100644 --- a/sdk/src/wallet/account/operations/transaction/high_level/create_account.rs +++ b/sdk/src/wallet/account/operations/transaction/high_level/create_account.rs @@ -75,7 +75,7 @@ where options: impl Into> + Send, ) -> crate::wallet::Result { log::debug!("[TRANSACTION] prepare_create_account_output"); - let rent_struct = self.client().get_rent_parameters().await?.into(); + let rent_structure = self.client().get_rent_parameters().await?.into(); let token_supply = self.client().get_token_supply().await?; let controller_address = match params.as_ref().and_then(|options| options.address.as_ref()) { @@ -94,7 +94,7 @@ where }; let mut account_output_builder = - AccountOutputBuilder::new_with_minimum_storage_deposit(rent_struct, AccountId::null()) + AccountOutputBuilder::new_with_minimum_storage_deposit(rent_structure, AccountId::null()) .with_state_index(0) .with_foundry_counter(0) .add_unlock_condition(StateControllerAddressUnlockCondition::new(controller_address)) diff --git a/sdk/src/wallet/account/operations/transaction/high_level/minting/create_native_token.rs b/sdk/src/wallet/account/operations/transaction/high_level/minting/create_native_token.rs index 10c4acbf7b..dbf6040682 100644 --- a/sdk/src/wallet/account/operations/transaction/high_level/minting/create_native_token.rs +++ b/sdk/src/wallet/account/operations/transaction/high_level/minting/create_native_token.rs @@ -133,7 +133,7 @@ where options: impl Into> + Send, ) -> crate::wallet::Result { log::debug!("[TRANSACTION] create_native_token"); - let rent_struct = self.client().get_rent_parameters().await?.into(); + let rent_structure = self.client().get_rent_parameters().await?.into(); let token_supply = self.client().get_token_supply().await?; let (account_id, account_output) = self @@ -160,7 +160,7 @@ where new_account_output_builder.finish_output(token_supply)?, { let mut foundry_builder = FoundryOutputBuilder::new_with_minimum_storage_deposit( - rent_struct, + rent_structure, account_output.foundry_counter() + 1, TokenScheme::Simple(SimpleTokenScheme::new( params.circulating_supply, diff --git a/sdk/src/wallet/account/operations/transaction/high_level/minting/mint_nfts.rs b/sdk/src/wallet/account/operations/transaction/high_level/minting/mint_nfts.rs index fc72a18e67..ff7a7a737f 100644 --- a/sdk/src/wallet/account/operations/transaction/high_level/minting/mint_nfts.rs +++ b/sdk/src/wallet/account/operations/transaction/high_level/minting/mint_nfts.rs @@ -162,7 +162,7 @@ where I::IntoIter: Send, { log::debug!("[TRANSACTION] prepare_mint_nfts"); - let rent_struct = self.client().get_rent_parameters().await?.into(); + let rent_structure = self.client().get_rent_parameters().await?.into(); let token_supply = self.client().get_token_supply().await?; let account_addresses = self.addresses().await?; let mut outputs = Vec::new(); @@ -191,7 +191,7 @@ where }; // NftId needs to be set to 0 for the creation - let mut nft_builder = NftOutputBuilder::new_with_minimum_storage_deposit(rent_struct, NftId::null()) + let mut nft_builder = NftOutputBuilder::new_with_minimum_storage_deposit(rent_structure, NftId::null()) // Address which will own the nft .add_unlock_condition(AddressUnlockCondition::new(address)); diff --git a/sdk/src/wallet/account/operations/transaction/high_level/send.rs b/sdk/src/wallet/account/operations/transaction/high_level/send.rs index 3c7f0c5d42..2ec18a124f 100644 --- a/sdk/src/wallet/account/operations/transaction/high_level/send.rs +++ b/sdk/src/wallet/account/operations/transaction/high_level/send.rs @@ -141,7 +141,7 @@ where { log::debug!("[TRANSACTION] prepare_send"); let options = options.into(); - let rent_struct = self.client().get_rent_parameters().await?.into(); + let rent_structure = self.client().get_rent_parameters().await?.into(); let token_supply = self.client().get_token_supply().await?; let account_addresses = self.addresses().await?; @@ -172,7 +172,7 @@ where .unwrap_or(default_return_address.address); // Get the minimum required amount for an output assuming it does not need a storage deposit. - let output = BasicOutputBuilder::new_with_minimum_storage_deposit(rent_struct) + let output = BasicOutputBuilder::new_with_minimum_storage_deposit(rent_structure) .add_unlock_condition(AddressUnlockCondition::new(address)) .finish_output(token_supply)?; @@ -189,7 +189,7 @@ where }); // Since it does need a storage deposit, calculate how much that should be - let storage_deposit_amount = MinimumStorageDepositBasicOutput::new(rent_struct, token_supply) + let storage_deposit_amount = MinimumStorageDepositBasicOutput::new(rent_structure, token_supply) .with_storage_deposit_return()? .with_expiration()? .finish()?; diff --git a/sdk/src/wallet/account/operations/transaction/high_level/send_native_tokens.rs b/sdk/src/wallet/account/operations/transaction/high_level/send_native_tokens.rs index ab41371b43..018c65babe 100644 --- a/sdk/src/wallet/account/operations/transaction/high_level/send_native_tokens.rs +++ b/sdk/src/wallet/account/operations/transaction/high_level/send_native_tokens.rs @@ -131,7 +131,7 @@ where I::IntoIter: Send, { log::debug!("[TRANSACTION] prepare_send_native_tokens"); - let rent_struct = self.client().get_rent_parameters().await?.into(); + let rent_structure = self.client().get_rent_parameters().await?.into(); let token_supply = self.client().get_token_supply().await?; let account_addresses = self.addresses().await?; @@ -173,7 +173,7 @@ where // get minimum required amount for such an output, so we don't lock more than required // We have to check it for every output individually, because different address types and amount of // different native tokens require a different storage deposit - let storage_deposit_amount = MinimumStorageDepositBasicOutput::new(rent_struct, token_supply) + let storage_deposit_amount = MinimumStorageDepositBasicOutput::new(rent_structure, token_supply) .with_native_tokens(native_tokens.clone()) .with_storage_deposit_return()? .with_expiration()? diff --git a/sdk/src/wallet/account/operations/transaction/prepare_output.rs b/sdk/src/wallet/account/operations/transaction/prepare_output.rs index 51e31c2e58..6c0f80c0de 100644 --- a/sdk/src/wallet/account/operations/transaction/prepare_output.rs +++ b/sdk/src/wallet/account/operations/transaction/prepare_output.rs @@ -48,12 +48,12 @@ where self.client().bech32_hrp_matches(params.recipient_address.hrp()).await?; - let rent_struct = self.client().get_rent_parameters().await?.into(); + let rent_structure = self.client().get_rent_parameters().await?.into(); let nft_id = params.assets.as_ref().and_then(|a| a.nft_id); let (mut first_output_builder, existing_nft_output_data) = self - .create_initial_output_builder(params.recipient_address, nft_id, rent_struct) + .create_initial_output_builder(params.recipient_address, nft_id, rent_structure) .await?; if let Some(assets) = ¶ms.assets { @@ -104,7 +104,7 @@ where // Build output with minimum required storage deposit so we can use the amount in the next step let first_output = first_output_builder - .with_minimum_storage_deposit(rent_struct) + .with_minimum_storage_deposit(rent_structure) .finish_output(token_supply)?; let mut second_output_builder = if nft_id.is_some() { @@ -114,9 +114,9 @@ where }; let min_storage_deposit_basic_output = - MinimumStorageDepositBasicOutput::new(rent_struct, token_supply).finish()?; + MinimumStorageDepositBasicOutput::new(rent_structure, token_supply).finish()?; - let min_required_storage_deposit = first_output.rent_cost(rent_struct); + let min_required_storage_deposit = first_output.rent_cost(rent_structure); if params.amount > min_required_storage_deposit { second_output_builder = second_output_builder.with_amount(params.amount); @@ -148,7 +148,7 @@ where // need to check the min required storage deposit again let min_storage_deposit_new_amount = second_output_builder .clone() - .with_minimum_storage_deposit(rent_struct) + .with_minimum_storage_deposit(rent_structure) .finish_output(token_supply)? .amount(); @@ -178,7 +178,7 @@ where // If we're sending an existing NFT, its minimum required storage deposit is not part of the available base_coin // balance, so we add it here if let Some(existing_nft_output_data) = existing_nft_output_data { - available_base_coin += existing_nft_output_data.output.rent_cost(rent_struct); + available_base_coin += existing_nft_output_data.output.rent_cost(rent_structure); } if final_amount > available_base_coin { @@ -238,13 +238,16 @@ where &self, recipient_address: Bech32Address, nft_id: Option, - rent_struct: RentStructure, + rent_structure: RentStructure, ) -> crate::wallet::Result<(OutputBuilder, Option)> { let (mut first_output_builder, existing_nft_output_data) = if let Some(nft_id) = &nft_id { if nft_id.is_null() { // Mint a new NFT output ( - OutputBuilder::Nft(NftOutputBuilder::new_with_minimum_storage_deposit(rent_struct, *nft_id)), + OutputBuilder::Nft(NftOutputBuilder::new_with_minimum_storage_deposit( + rent_structure, + *nft_id, + )), None, ) } else { @@ -265,7 +268,7 @@ where } } else { ( - OutputBuilder::Basic(BasicOutputBuilder::new_with_minimum_storage_deposit(rent_struct)), + OutputBuilder::Basic(BasicOutputBuilder::new_with_minimum_storage_deposit(rent_structure)), None, ) }; @@ -428,13 +431,13 @@ impl OutputBuilder { } self } - fn with_minimum_storage_deposit(mut self, rent_struct: RentStructure) -> Self { + fn with_minimum_storage_deposit(mut self, rent_structure: RentStructure) -> Self { match self { Self::Basic(b) => { - self = Self::Basic(b.with_minimum_storage_deposit(rent_struct)); + self = Self::Basic(b.with_minimum_storage_deposit(rent_structure)); } Self::Nft(b) => { - self = Self::Nft(b.with_minimum_storage_deposit(rent_struct)); + self = Self::Nft(b.with_minimum_storage_deposit(rent_structure)); } } self diff --git a/sdk/src/wallet/account/operations/transaction/prepare_transaction.rs b/sdk/src/wallet/account/operations/transaction/prepare_transaction.rs index 7b06af3714..ca0b5c1f87 100644 --- a/sdk/src/wallet/account/operations/transaction/prepare_transaction.rs +++ b/sdk/src/wallet/account/operations/transaction/prepare_transaction.rs @@ -35,12 +35,12 @@ where let options = options.into(); let outputs = outputs.into(); let prepare_transaction_start_time = Instant::now(); - let rent_struct = self.client().get_rent_parameters().await?.into(); + let rent_structure = self.client().get_rent_parameters().await?.into(); let token_supply = self.client().get_token_supply().await?; // Check if the outputs have enough amount to cover the storage deposit for output in &outputs { - output.verify_storage_deposit(rent_struct, token_supply)?; + output.verify_storage_deposit(rent_structure, token_supply)?; } let is_burn_present = options.as_ref().map(|options| options.burn.is_some()).unwrap_or(false); diff --git a/sdk/tests/wallet/claim_outputs.rs b/sdk/tests/wallet/claim_outputs.rs index e1d2481dba..cea2cf2d5d 100644 --- a/sdk/tests/wallet/claim_outputs.rs +++ b/sdk/tests/wallet/claim_outputs.rs @@ -127,11 +127,11 @@ async fn claim_2_basic_outputs_no_outputs_in_claim_account() -> Result<()> { let account_1 = wallet.create_account().finish().await?; let token_supply = account_0.client().get_token_supply().await?; - let rent_struct = account_0.client().get_rent_parameters().await?.into(); + let rent_structure = account_0.client().get_rent_parameters().await?.into(); // TODO more fitting value let expiration_slot = account_0.client().get_slot_index().await? + 86400; - let output = BasicOutputBuilder::new_with_minimum_storage_deposit(rent_struct) + let output = BasicOutputBuilder::new_with_minimum_storage_deposit(rent_structure) .add_unlock_condition(AddressUnlockCondition::new( *account_1.addresses().await?[0].address().as_ref(), )) @@ -322,13 +322,13 @@ async fn claim_2_native_tokens_no_outputs_in_claim_account() -> Result<()> { .await?; account_0.sync(None).await?; - let rent_struct = account_0.client().get_rent_parameters().await?.into(); + let rent_structure = account_0.client().get_rent_parameters().await?.into(); let token_supply = account_0.client().get_token_supply().await?; let tx = account_0 .send_outputs( [ - BasicOutputBuilder::new_with_minimum_storage_deposit(rent_struct) + BasicOutputBuilder::new_with_minimum_storage_deposit(rent_structure) .add_unlock_condition(AddressUnlockCondition::new( *account_1.addresses().await?[0].address().as_ref(), )) @@ -338,7 +338,7 @@ async fn claim_2_native_tokens_no_outputs_in_claim_account() -> Result<()> { )?) .add_native_token(NativeToken::new(create_tx_0.token_id, native_token_amount)?) .finish_output(token_supply)?, - BasicOutputBuilder::new_with_minimum_storage_deposit(rent_struct) + BasicOutputBuilder::new_with_minimum_storage_deposit(rent_structure) .add_unlock_condition(AddressUnlockCondition::new( *account_1.addresses().await?[0].address().as_ref(), )) diff --git a/sdk/tests/wallet/output_preparation.rs b/sdk/tests/wallet/output_preparation.rs index c4f5f596aa..6cd136c314 100644 --- a/sdk/tests/wallet/output_preparation.rs +++ b/sdk/tests/wallet/output_preparation.rs @@ -409,8 +409,8 @@ async fn output_preparation() -> Result<()> { None, ) .await?; - let rent_struct = wallet.client().get_rent_parameters().await?.into(); - let minimum_storage_deposit = output.rent_cost(rent_struct); + let rent_structure = wallet.client().get_rent_parameters().await?.into(); + let minimum_storage_deposit = output.rent_cost(rent_structure); assert_eq!(output.amount(), minimum_storage_deposit); assert_eq!(output.amount(), 187900); let sdr = output.unlock_conditions().unwrap().storage_deposit_return().unwrap(); @@ -433,7 +433,7 @@ async fn output_preparation_sdr() -> Result<()> { let wallet = make_wallet(storage_path, None, None).await?; let account = &create_accounts_with_funds(&wallet, 1).await?[0]; - let rent_struct = account.client().get_rent_parameters().await?.into(); + let rent_structure = account.client().get_rent_parameters().await?.into(); let token_supply = account.client().get_token_supply().await?; let recipient_address_bech32 = String::from("rms1qpszqzadsym6wpppd6z037dvlejmjuke7s24hm95s9fg9vpua7vluaw60xu"); @@ -455,7 +455,7 @@ async fn output_preparation_sdr() -> Result<()> { ) .await?; // Check if the output has enough amount to cover the storage deposit - output.verify_storage_deposit(rent_struct, token_supply)?; + output.verify_storage_deposit(rent_structure, token_supply)?; assert_eq!(output.amount(), 50601); // address and sdr unlock condition assert_eq!(output.unlock_conditions().unwrap().len(), 2); @@ -476,7 +476,7 @@ async fn output_preparation_sdr() -> Result<()> { ) .await?; // Check if the output has enough amount to cover the storage deposit - output.verify_storage_deposit(rent_struct, token_supply)?; + output.verify_storage_deposit(rent_structure, token_supply)?; assert_eq!(output.amount(), 85199); // address and sdr unlock condition assert_eq!(output.unlock_conditions().unwrap().len(), 2); @@ -501,7 +501,7 @@ async fn output_preparation_sdr() -> Result<()> { ) .await?; // Check if the output has enough amount to cover the storage deposit - output.verify_storage_deposit(rent_struct, token_supply)?; + output.verify_storage_deposit(rent_structure, token_supply)?; assert_eq!(output.amount(), 85199); // address and sdr unlock condition assert_eq!(output.unlock_conditions().unwrap().len(), 2); @@ -526,7 +526,7 @@ async fn output_preparation_sdr() -> Result<()> { ) .await?; // Check if the output has enough amount to cover the storage deposit - output.verify_storage_deposit(rent_struct, token_supply)?; + output.verify_storage_deposit(rent_structure, token_supply)?; // The additional 1 amount will be added, because the storage deposit should be gifted and not returned assert_eq!(output.amount(), 42600); // storage deposit gifted, only address unlock condition @@ -614,11 +614,12 @@ async fn prepare_output_remainder_dust() -> Result<()> { let addresses = &accounts[1].addresses().await?; let address = addresses[0].address(); - let rent_struct = account.client().get_rent_parameters().await?.into(); + let rent_structure = account.client().get_rent_parameters().await?.into(); let token_supply = account.client().get_token_supply().await?; let balance = account.sync(None).await?; - let minimum_required_storage_deposit = MinimumStorageDepositBasicOutput::new(rent_struct, token_supply).finish()?; + let minimum_required_storage_deposit = + MinimumStorageDepositBasicOutput::new(rent_structure, token_supply).finish()?; // Send away most balance so we can test with leaving dust let output = account @@ -659,7 +660,7 @@ async fn prepare_output_remainder_dust() -> Result<()> { .await?; // Check if the output has enough amount to cover the storage deposit - output.verify_storage_deposit(rent_struct, token_supply)?; + output.verify_storage_deposit(rent_structure, token_supply)?; // The left over 21299 is too small to keep, so we donate it assert_eq!(output.amount(), balance.base_coin().available()); // storage deposit gifted, only address unlock condition @@ -703,7 +704,7 @@ async fn prepare_output_remainder_dust() -> Result<()> { .await?; // Check if the output has enough amount to cover the storage deposit - output.verify_storage_deposit(rent_struct, token_supply)?; + output.verify_storage_deposit(rent_structure, token_supply)?; // We use excess if leftover is too small, so amount == all available balance assert_eq!(output.amount(), 63900); // storage deposit gifted, only address unlock condition @@ -727,7 +728,7 @@ async fn prepare_output_remainder_dust() -> Result<()> { .await?; // Check if the output has enough amount to cover the storage deposit - output.verify_storage_deposit(rent_struct, token_supply)?; + output.verify_storage_deposit(rent_structure, token_supply)?; // We use excess if leftover is too small, so amount == all available balance assert_eq!(output.amount(), 63900); // storage deposit returned, address and SDR unlock condition @@ -849,8 +850,8 @@ async fn prepare_existing_nft_output_gift() -> Result<()> { .as_nft() .clone(); - let rent_struct = wallet.client().get_rent_parameters().await?.into(); - let minimum_storage_deposit = Output::Nft(nft.clone()).rent_cost(rent_struct); + let rent_structure = wallet.client().get_rent_parameters().await?.into(); + let minimum_storage_deposit = Output::Nft(nft.clone()).rent_cost(rent_structure); assert_eq!(nft.amount(), minimum_storage_deposit); assert_eq!(nft.amount(), 52300);