Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor rent cost traits #1065

Merged
merged 116 commits into from
Nov 15, 2023
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
Show all changes
116 commits
Select commit Hold shift + click to select a range
e4ee434
Refactor rent cost traits
Aug 22, 2023
565f31e
Merge branch '2.0' into feat/rent-cost
Aug 23, 2023
6c3d6ae
Merge branch '2.0' into feat/rent-cost
Aug 23, 2023
c79412b
Merge branch '2.0' into feat/rent-cost
Aug 28, 2023
46b3974
remove pub'd field
Aug 28, 2023
871648b
Merge branch '2.0' into feat/rent-cost
Aug 28, 2023
2db3948
Fix sufficient storage deposit calculation
Aug 29, 2023
d5c013e
Merge branch '2.0' into feat/rent-cost
Aug 29, 2023
4a7f0c8
Merge branch '2.0' into feat/rent-cost
Aug 29, 2023
94d35db
Reduce sufficient SDR amount
Aug 30, 2023
27a52dd
Update comment
Aug 30, 2023
76e9f06
Hopefully last fix and better comments
Aug 30, 2023
db526dd
Add delegation and staking byte costs, clippy
Aug 30, 2023
60bf8d5
Merge branch '2.0' into feat/rent-cost
Aug 30, 2023
eec081f
block issuer key byte factor
Aug 31, 2023
db546f4
Merge branch '2.0' into feat/rent-cost
Sep 1, 2023
d92493e
clippy and fix claiming calc
Sep 1, 2023
4ccc610
Merge branch '2.0' into feat/rent-cost
Sep 1, 2023
66c93b6
Merge branch '2.0' into feat/rent-cost
Sep 5, 2023
d6301f1
Revert check
Sep 5, 2023
0745f90
cleanup, renames, and add test
Sep 5, 2023
591afd2
Remove static rent
Sep 5, 2023
5661fa0
more cleanup
Sep 5, 2023
069546b
Merge branch '2.0' into feat/rent-cost
Sep 6, 2023
f223610
Merge branch '2.0' into feat/rent-cost
Sep 6, 2023
d53e25f
Merge branch '2.0' into feat/rent-cost
Sep 7, 2023
d9485e1
Merge branch '2.0' into feat/rent-cost
Sep 7, 2023
3601754
Merge branch '2.0' into feat/rent-cost
Sep 8, 2023
b979d89
Merge branch '2.0' into feat/rent-cost
Sep 8, 2023
7efde19
Merge branch '2.0' into feat/rent-cost
Sep 11, 2023
16b3b82
Merge branch '2.0' into feat/rent-cost
Sep 11, 2023
fec3c1a
Merge branch '2.0' into feat/rent-cost
Sep 11, 2023
0861097
Merge branch '2.0' into feat/rent-cost
Sep 12, 2023
d606ab0
Merge branch 'feat/rent-cost' of https://github.com/iotaledger/iota-s…
Sep 12, 2023
ec59289
Merge branch '2.0' into feat/rent-cost
Sep 12, 2023
77db3fd
Merge branch '2.0' into feat/rent-cost
Sep 13, 2023
ab69ab7
Merge branch '2.0' into feat/rent-cost
Sep 14, 2023
db18131
Merge branch '2.0' into feat/rent-cost
Sep 14, 2023
f19bb38
Merge branch '2.0' into feat/rent-cost
Sep 15, 2023
359ffb0
Merge branch '2.0' into feat/rent-cost
Sep 15, 2023
63dc2e4
Merge branch '2.0' into feat/rent-cost
Sep 18, 2023
d06bb81
Merge branch '2.0' into feat/rent-cost
Sep 19, 2023
d9ab179
fix merge
Sep 19, 2023
178668d
Merge branch '2.0' into feat/rent-cost
Sep 19, 2023
8a0fea9
Merge branch '2.0' into feat/rent-cost
Sep 20, 2023
4e2e889
Merge branch '2.0' into feat/rent-cost
Sep 27, 2023
7274c3f
Merge branch '2.0' into feat/rent-cost
Sep 27, 2023
e1327c2
Merge branch '2.0' into feat/rent-cost
Sep 29, 2023
6d52f2d
Merge branch '2.0' into feat/rent-cost
Oct 2, 2023
95001b7
Merge branch '2.0' into feat/rent-cost
Oct 3, 2023
7f28105
Merge branch '2.0' into feat/rent-cost
Oct 4, 2023
da2d84d
Merge branch '2.0' into feat/rent-cost
Oct 5, 2023
c3f64c0
Merge branch '2.0' into feat/rent-cost
Oct 6, 2023
f9dcf8d
Merge branch '2.0' into feat/rent-cost
Oct 10, 2023
e96509b
Merge branch '2.0' into feat/rent-cost
Oct 10, 2023
193ff40
Merge branch '2.0' into feat/rent-cost
Oct 10, 2023
28a6ec0
Merge branch '2.0' into feat/rent-cost
Oct 11, 2023
ed8b288
Merge branch '2.0' into feat/rent-cost
Oct 11, 2023
22ca84b
Merge branch '2.0' into feat/rent-cost
Oct 13, 2023
0dad0b7
revert claiming calculations
Oct 13, 2023
ae25885
Merge branch '2.0' into feat/rent-cost
Oct 13, 2023
e95f9a3
Merge branch '2.0' into feat/rent-cost
Oct 16, 2023
088b2a0
Merge branch '2.0' into feat/rent-cost
Oct 17, 2023
03c41fc
refactor rent parameters
Oct 17, 2023
b3f7864
Rename min_deposit fn to better reflect usage
Oct 18, 2023
7ef858f
Merge branch '2.0' into feat/rent-cost
Oct 18, 2023
691e20f
rename rent
Oct 18, 2023
e5533fb
no_std
Oct 18, 2023
42d19ae
PR suggestions
Oct 18, 2023
95d0e76
Merge branch '2.0' into feat/rent-cost
Oct 18, 2023
95051d3
weird comment
Oct 18, 2023
6d6fbdc
Merge branch '2.0' into feat/rent-cost
Oct 18, 2023
8ff7195
Merge branch '2.0' into feat/rent-cost
Oct 19, 2023
9ab095a
refactor with overhead
Oct 19, 2023
4f6cd1c
review
Oct 19, 2023
3159d57
Merge branch '2.0' into feat/rent-cost
Oct 19, 2023
379766e
fix builder storage cost
Oct 19, 2023
0f9a154
Merge branch '2.0' into feat/rent-cost
Oct 20, 2023
2dcb64b
Merge branch '2.0' into feat/rent-cost
Oct 23, 2023
56ebdb7
comment out tests
Oct 23, 2023
dcec104
Merge branch '2.0' into feat/rent-cost
Oct 24, 2023
aa09046
Merge branch '2.0' into feat/rent-cost
Oct 25, 2023
badc436
Merge branch '2.0' into feat/rent-cost
Oct 25, 2023
841e4aa
Merge branch '2.0' into feat/rent-cost
Oct 31, 2023
9d01cb5
Merge branch '2.0' into feat/rent-cost
Nov 6, 2023
0bd4d6b
Merge branch '2.0' into feat/rent-cost
thibault-martinez Nov 7, 2023
bb5f807
Merge branch '2.0' into feat/rent-cost
thibault-martinez Nov 7, 2023
e78a090
impl StorageScore for MultiAddress {}
thibault-martinez Nov 7, 2023
c50a2b9
Merge branch '2.0' into feat/rent-cost
thibault-martinez Nov 7, 2023
4f49f87
Add missing serde(with = "crate::utils::serde::string"))
thibault-martinez Nov 7, 2023
a8e126b
Merge imports
thibault-martinez Nov 8, 2023
341aa9c
Rename nits
thibault-martinez Nov 8, 2023
f47a4b6
Merge some more imports
thibault-martinez Nov 8, 2023
14d6191
More renames
thibault-martinez Nov 8, 2023
a5c637f
Add TODO
thibault-martinez Nov 8, 2023
eaf85d9
rename output builder amount variant
Nov 8, 2023
f5e946f
Remove excess
Nov 8, 2023
dff70c8
Merge branch '2.0' into feat/rent-cost
thibault-martinez Nov 8, 2023
5e214c3
Some renames lost in the merge
thibault-martinez Nov 8, 2023
45e8e64
nit
thibault-martinez Nov 8, 2023
d46307a
suggestions
Nov 8, 2023
1388b73
Merge branch 'feat/rent-cost' of https://github.com/iotaledger/iota-s…
Nov 8, 2023
81e49d7
cleanup imports
Nov 8, 2023
c844407
fix implicit storage score
Nov 8, 2023
cabaaf9
update terminology and separate trait
Nov 13, 2023
1f8d25a
Merge branch '2.0' into feat/rent-cost
Nov 13, 2023
9ea3f81
nit
Nov 13, 2023
4e8b054
suggestions
Nov 13, 2023
248945c
I did change that
Nov 13, 2023
b29a709
blame the sickness
Nov 13, 2023
c9f95e6
cleanup
Nov 13, 2023
1cac8a6
Merge branch '2.0' into feat/rent-cost
Nov 13, 2023
a6da4ce
Nits
thibault-martinez Nov 14, 2023
7e5a5de
Return is a BasicOutputBuilder
thibault-martinez Nov 14, 2023
893ffe4
fmt
thibault-martinez Nov 14, 2023
5454a3a
Merge branch '2.0' into feat/rent-cost
Nov 14, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion bindings/core/src/method_handler/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
RentCost,
},
payload::Payload,
Block, BlockDto,
Expand Down
2 changes: 1 addition & 1 deletion bindings/core/src/method_handler/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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, RentCost, TokenId},
payload::{transaction::TransactionEssence, TransactionPayload},
Block,
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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, RentCost,
},
},
};
Expand Down
5 changes: 5 additions & 0 deletions sdk/src/types/block/address/ed25519.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@ impl Ed25519Address {
pub fn new(address: [u8; Self::LENGTH]) -> Self {
Self::from(address)
}

#[allow(dead_code)]
thibault-martinez marked this conversation as resolved.
Show resolved Hide resolved
pub(crate) fn null() -> Self {
Self::new([0; Self::LENGTH])
}
}

impl FromStr for Ed25519Address {
Expand Down
98 changes: 81 additions & 17 deletions sdk/src/types/block/output/account.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,10 @@ use packable::{
Packable,
};

use super::verify_output_amount_packable;
use super::{
rent::{RentBuilder, RentCost},
verify_output_amount_packable,
};
use crate::types::{
block::{
address::{AccountAddress, Address},
Expand Down Expand Up @@ -256,6 +259,10 @@ impl AccountOutputBuilder {

///
pub fn finish(self) -> Result<AccountOutput, Error> {
let amount = match self.amount {
OutputBuilderAmount::Amount(amount) => amount,
OutputBuilderAmount::MinimumStorageDeposit(rent_structure) => self.rent_cost(rent_structure),
};
let state_index = self.state_index.unwrap_or(0);
let foundry_counter = self.foundry_counter.unwrap_or(0);

Expand All @@ -279,8 +286,8 @@ impl AccountOutputBuilder {

verify_allowed_features(&immutable_features, AccountOutput::ALLOWED_IMMUTABLE_FEATURES)?;

let mut output = AccountOutput {
amount: 1,
Ok(AccountOutput {
amount,
mana: self.mana,
native_tokens: NativeTokens::from_set(self.native_tokens)?,
account_id: self.account_id,
Expand All @@ -290,16 +297,7 @@ impl AccountOutputBuilder {
unlock_conditions,
features,
immutable_features,
};

output.amount = match self.amount {
OutputBuilderAmount::Amount(amount) => amount,
OutputBuilderAmount::MinimumStorageDeposit(rent_structure) => {
Output::Account(output.clone()).rent_cost(rent_structure)
}
};

Ok(output)
})
}

///
Expand Down Expand Up @@ -339,6 +337,43 @@ impl From<&AccountOutput> for AccountOutputBuilder {
}
}

impl Rent for AccountOutputBuilder {
fn build_weighted_bytes(&self, builder: &mut RentBuilder) {
builder
// Kind
.data_field::<u8>()
// Amount
.data_field::<u64>()
// Mana
.data_field::<u64>()
// Native Tokens
.data_field::<u8>()
.weighted_field(&self.native_tokens)
// State Index
.data_field::<u32>()
// State Metadata
.data_field::<u16>()
.bytes(self.state_metadata.len() as _)
// Foundry Counter
.data_field::<u32>()
// Unlock Conditions
.data_field::<u8>()
.weighted_field(&self.unlock_conditions)
// Features
.data_field::<u8>()
.weighted_field(&self.features)
// Immutable Features
.data_field::<u8>()
.weighted_field(&self.features);
}
}

impl RentCost for AccountOutputBuilder {
fn build_byte_offset(builder: &mut RentBuilder) {
Output::build_byte_offset(builder)
}
}

pub(crate) type StateMetadataLength = BoundedU16<0, { AccountOutput::STATE_METADATA_LENGTH_MAX }>;

/// Describes an account in the ledger that can be controlled by the state and governance controllers.
Expand Down Expand Up @@ -625,6 +660,38 @@ impl StateTransitionVerifier for AccountOutput {
}
}

impl Rent for AccountOutput {
fn build_weighted_bytes(&self, builder: &mut RentBuilder) {
builder
// Kind
.data_field::<u8>()
// Amount
.data_field::<u64>()
// Mana
.data_field::<u64>()
// Native Tokens
.packable_field(&self.native_tokens)
// State Index
.data_field::<u32>()
// State Metadata
.packable_field(&self.state_metadata)
// Foundry Counter
.data_field::<u32>()
// Unlock Conditions
.packable_field(&self.unlock_conditions)
// Features
.packable_field(&self.features)
// Immutable Features
.packable_field(&self.immutable_features);
}
}

impl RentCost for AccountOutput {
fn build_byte_offset(builder: &mut RentBuilder) {
Output::build_byte_offset(builder)
}
}

impl Packable for AccountOutput {
type UnpackError = Error;
type UnpackVisitor = ProtocolParameters;
Expand Down Expand Up @@ -964,10 +1031,7 @@ mod tests {
.finish_with_params(ValidationParams::default().with_protocol_parameters(protocol_parameters.clone()))
.unwrap();

assert_eq!(
output.amount(),
Output::Account(output.clone()).rent_cost(protocol_parameters.rent_structure())
);
assert_eq!(output.amount(), output.rent_cost(protocol_parameters.rent_structure()));
assert_eq!(output.features().metadata(), Some(&metadata));
assert_eq!(output.features().sender(), Some(&sender_1));
assert_eq!(output.immutable_features().metadata(), Some(&metadata));
Expand Down
133 changes: 116 additions & 17 deletions sdk/src/types/block/output/basic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,11 @@ use alloc::{collections::BTreeSet, vec::Vec};

use packable::Packable;

use super::verify_output_amount_packable;
use super::{
rent::{RentBuilder, RentCost},
unlock_condition::StorageDepositReturnUnlockCondition,
verify_output_amount_packable, AddressUnlockCondition,
};
use crate::types::{
block::{
address::Address,
Expand Down Expand Up @@ -152,8 +156,64 @@ impl BasicOutputBuilder {
self
}

/// Adds a storage deposit return unlock condition if one is needed to cover the current amount
/// (i.e. `amount < rent_cost`). This will increase the total amount to equal the `rent_cost` with
/// the additional unlock condition that will return the remainder to the provided `return_address`.
pub fn with_sufficient_storage_deposit(
mut self,
return_address: impl Into<Address>,
rent_structure: RentStructure,
token_supply: u64,
) -> Result<Self, Error> {
Ok(match self.amount {
OutputBuilderAmount::Amount(amount) => {
let return_address = return_address.into();
// Get the current rent requirement
let rent_cost = self.rent_cost(rent_structure);
// Check whether we already have enough funds to cover it
if amount < rent_cost {
// Get the projected rent cost of the return output
let return_rent_cost = Self::new_with_amount(0)
.add_unlock_condition(AddressUnlockCondition::new(return_address))
.rent_cost(rent_structure);
// Add a temporary storage deposit unlock condition so the new rent requirement can be calculated
self = self.add_unlock_condition(StorageDepositReturnUnlockCondition::new(
return_address,
0,
token_supply,
)?);
// Get the rent cost of the output with the added storage deposit return unlock condition
let rent_cost_with_sdruc = self.rent_cost(rent_structure);
// If the return rent cost and amount are less than the required min
let (amount, sdruc_amount) = if rent_cost_with_sdruc >= return_rent_cost + amount {
// Then sending rent_cost_with_sdruc covers both minimum requirements
(rent_cost_with_sdruc, rent_cost_with_sdruc - amount)
} else {
// Otherwise we must use the total of the return minimum and the original amount
// which is unfortunately more than the rent_cost_with_sdruc
Thoralf-M marked this conversation as resolved.
Show resolved Hide resolved
(return_rent_cost + amount, return_rent_cost)
};
// Add the required storage deposit unlock condition and the additional rent amount
self.with_amount(amount)
.replace_unlock_condition(StorageDepositReturnUnlockCondition::new(
return_address,
sdruc_amount,
token_supply,
)?)
} else {
self
}
}
OutputBuilderAmount::MinimumStorageDeposit(_) => self,
})
}

///
pub fn finish(self) -> Result<BasicOutput, Error> {
let amount = match self.amount {
OutputBuilderAmount::Amount(amount) => amount,
OutputBuilderAmount::MinimumStorageDeposit(rent_structure) => self.rent_cost(rent_structure),
};
let unlock_conditions = UnlockConditions::from_set(self.unlock_conditions)?;

verify_unlock_conditions::<true>(&unlock_conditions)?;
Expand All @@ -162,22 +222,13 @@ impl BasicOutputBuilder {

verify_features::<true>(&features)?;

let mut output = BasicOutput {
amount: 1u64,
Ok(BasicOutput {
amount,
mana: self.mana,
native_tokens: NativeTokens::from_set(self.native_tokens)?,
unlock_conditions,
features,
};

output.amount = match self.amount {
OutputBuilderAmount::Amount(amount) => amount,
OutputBuilderAmount::MinimumStorageDeposit(rent_structure) => {
Output::Basic(output.clone()).rent_cost(rent_structure)
}
};

Ok(output)
})
}

///
Expand All @@ -197,6 +248,33 @@ impl BasicOutputBuilder {
}
}

impl Rent for BasicOutputBuilder {
thibault-martinez marked this conversation as resolved.
Show resolved Hide resolved
fn build_weighted_bytes(&self, builder: &mut RentBuilder) {
builder
// Kind
.data_field::<u8>()
// Amount
.data_field::<u64>()
// Mana
.data_field::<u64>()
// Native Tokens
.data_field::<u8>()
.weighted_field(&self.native_tokens)
// Unlock Conditions
.data_field::<u8>()
.weighted_field(&self.unlock_conditions)
// Features
.data_field::<u8>()
.weighted_field(&self.features);
}
}

impl RentCost for BasicOutputBuilder {
fn build_byte_offset(builder: &mut RentBuilder) {
Output::build_byte_offset(builder)
}
}

impl From<&BasicOutput> for BasicOutputBuilder {
fn from(output: &BasicOutput) -> Self {
Self {
Expand Down Expand Up @@ -319,6 +397,30 @@ impl BasicOutput {
}
}

impl Rent for BasicOutput {
fn build_weighted_bytes(&self, builder: &mut RentBuilder) {
builder
// Kind
.data_field::<u8>()
// Amount
.data_field::<u64>()
// Mana
.data_field::<u64>()
// Native Tokens
.packable_field(&self.native_tokens)
// Unlock Conditions
.packable_field(&self.unlock_conditions)
// Features
.packable_field(&self.features);
}
}

impl RentCost for BasicOutput {
fn build_byte_offset(builder: &mut RentBuilder) {
Output::build_byte_offset(builder)
}
}

fn verify_unlock_conditions<const VERIFY: bool>(unlock_conditions: &UnlockConditions) -> Result<(), Error> {
if VERIFY {
if unlock_conditions.address().is_none() {
Expand Down Expand Up @@ -506,10 +608,7 @@ mod tests {
.finish_with_params(ValidationParams::default().with_protocol_parameters(protocol_parameters.clone()))
.unwrap();

assert_eq!(
output.amount(),
Output::Basic(output.clone()).rent_cost(protocol_parameters.rent_structure())
);
assert_eq!(output.amount(), output.rent_cost(protocol_parameters.rent_structure()));
assert_eq!(output.features().metadata(), Some(&metadata));
assert_eq!(output.features().sender(), Some(&sender_1));
}
Expand Down
Loading