From c00c26747f5d1202d9b1a8baeaa5a4483a6f3c7c Mon Sep 17 00:00:00 2001 From: Andrew Date: Tue, 1 Aug 2023 12:46:07 +0100 Subject: [PATCH 1/5] rename deposit to base token amount --- builder/output_builder.go | 66 ++++++++++++++++----------------- builder/output_builder_test.go | 40 ++++++++++---------- mana_decay_provider.go | 14 +++---- mana_decay_provider_test.go | 22 +++++------ output.go | 38 +++++++++---------- output_account.go | 2 +- output_basic.go | 2 +- output_delegation.go | 2 +- output_foundry.go | 2 +- output_nft.go | 2 +- output_test.go | 6 +-- transaction_essence.go | 8 ++-- vm/stardust/vm_stardust.go | 2 +- vm/stardust/vm_stardust_test.go | 2 +- vm/vm.go | 16 ++++---- 15 files changed, 112 insertions(+), 112 deletions(-) diff --git a/builder/output_builder.go b/builder/output_builder.go index 7c0c3c3d9..76ebfbd00 100644 --- a/builder/output_builder.go +++ b/builder/output_builder.go @@ -9,10 +9,10 @@ import ( iotago "github.com/iotaledger/iota.go/v4" ) -// NewBasicOutputBuilder creates a new BasicOutputBuilder with the required target address and deposit amount. -func NewBasicOutputBuilder(targetAddr iotago.Address, deposit iotago.BaseToken) *BasicOutputBuilder { +// NewBasicOutputBuilder creates a new BasicOutputBuilder with the required target address and base token amount. +func NewBasicOutputBuilder(targetAddr iotago.Address, amount iotago.BaseToken) *BasicOutputBuilder { return &BasicOutputBuilder{output: &iotago.BasicOutput{ - Amount: deposit, + Amount: amount, NativeTokens: iotago.NativeTokens{}, Conditions: iotago.BasicOutputUnlockConditions{ &iotago.AddressUnlockCondition{Address: targetAddr}, @@ -32,9 +32,9 @@ type BasicOutputBuilder struct { output *iotago.BasicOutput } -// Deposit sets the deposit of the output. -func (builder *BasicOutputBuilder) Deposit(deposit iotago.BaseToken) *BasicOutputBuilder { - builder.output.Amount = deposit +// Amount sets the base token amount of the output. +func (builder *BasicOutputBuilder) Amount(amount iotago.BaseToken) *BasicOutputBuilder { + builder.output.Amount = amount return builder } @@ -121,10 +121,10 @@ func (builder *BasicOutputBuilder) Build() (*iotago.BasicOutput, error) { return builder.output, nil } -// NewAccountOutputBuilder creates a new AccountOutputBuilder with the required state controller/governor addresses and deposit amount. -func NewAccountOutputBuilder(stateCtrl iotago.Address, govAddr iotago.Address, deposit iotago.BaseToken) *AccountOutputBuilder { +// NewAccountOutputBuilder creates a new AccountOutputBuilder with the required state controller/governor addresses and base token amount. +func NewAccountOutputBuilder(stateCtrl iotago.Address, govAddr iotago.Address, amount iotago.BaseToken) *AccountOutputBuilder { return &AccountOutputBuilder{output: &iotago.AccountOutput{ - Amount: deposit, + Amount: amount, NativeTokens: iotago.NativeTokens{}, Conditions: iotago.AccountOutputUnlockConditions{ &iotago.StateControllerAddressUnlockCondition{Address: stateCtrl}, @@ -152,9 +152,9 @@ type AccountOutputBuilder struct { govCtrlReq bool } -// Deposit sets the deposit of the output. -func (builder *AccountOutputBuilder) Deposit(deposit iotago.BaseToken) *AccountOutputBuilder { - builder.output.Amount = deposit +// Amount sets the base token amount of the output. +func (builder *AccountOutputBuilder) Amount(amount iotago.BaseToken) *AccountOutputBuilder { + builder.output.Amount = amount builder.stateCtrlReq = true return builder @@ -324,9 +324,9 @@ func (builder *AccountOutputBuilder) StateTransition() *accountStateTransition { return &accountStateTransition{builder: builder} } -// Deposit sets the deposit of the output. -func (trans *accountStateTransition) Deposit(deposit iotago.BaseToken) *accountStateTransition { - return trans.builder.Deposit(deposit).StateTransition() +// Amount sets the base token amount of the output. +func (trans *accountStateTransition) Amount(amount iotago.BaseToken) *accountStateTransition { + return trans.builder.Amount(amount).StateTransition() } // StateMetadata sets the state metadata of the output. @@ -540,10 +540,10 @@ func (trans *stakingTransition) Builder() *AccountOutputBuilder { return trans.builder } -// NewFoundryOutputBuilder creates a new FoundryOutputBuilder with the account address, serial number, token scheme and deposit amount. -func NewFoundryOutputBuilder(accountAddr *iotago.AccountAddress, tokenScheme iotago.TokenScheme, deposit iotago.BaseToken) *FoundryOutputBuilder { +// NewFoundryOutputBuilder creates a new FoundryOutputBuilder with the account address, serial number, token scheme and base token amount. +func NewFoundryOutputBuilder(accountAddr *iotago.AccountAddress, tokenScheme iotago.TokenScheme, amount iotago.BaseToken) *FoundryOutputBuilder { return &FoundryOutputBuilder{output: &iotago.FoundryOutput{ - Amount: deposit, + Amount: amount, TokenScheme: tokenScheme, NativeTokens: iotago.NativeTokens{}, Conditions: iotago.FoundryOutputUnlockConditions{ @@ -569,9 +569,9 @@ type FoundryOutputBuilder struct { output *iotago.FoundryOutput } -// Deposit sets the deposit of the output. -func (builder *FoundryOutputBuilder) Deposit(deposit iotago.BaseToken) *FoundryOutputBuilder { - builder.output.Amount = deposit +// Amount sets the base token amount of the output. +func (builder *FoundryOutputBuilder) Amount(amount iotago.BaseToken) *FoundryOutputBuilder { + builder.output.Amount = amount return builder } @@ -632,10 +632,10 @@ func (builder *FoundryOutputBuilder) Build() (*iotago.FoundryOutput, error) { return builder.output, nil } -// NewNFTOutputBuilder creates a new NFTOutputBuilder with the address and deposit amount. -func NewNFTOutputBuilder(targetAddr iotago.Address, deposit iotago.BaseToken) *NFTOutputBuilder { +// NewNFTOutputBuilder creates a new NFTOutputBuilder with the address and base token amount. +func NewNFTOutputBuilder(targetAddr iotago.Address, amount iotago.BaseToken) *NFTOutputBuilder { return &NFTOutputBuilder{output: &iotago.NFTOutput{ - Amount: deposit, + Amount: amount, NativeTokens: iotago.NativeTokens{}, Conditions: iotago.NFTOutputUnlockConditions{ &iotago.AddressUnlockCondition{Address: targetAddr}, @@ -660,9 +660,9 @@ type NFTOutputBuilder struct { output *iotago.NFTOutput } -// Deposit sets the deposit of the output. -func (builder *NFTOutputBuilder) Deposit(deposit iotago.BaseToken) *NFTOutputBuilder { - builder.output.Amount = deposit +// Amount sets the base token amount of the output. +func (builder *NFTOutputBuilder) Amount(amount iotago.BaseToken) *NFTOutputBuilder { + builder.output.Amount = amount return builder } @@ -780,10 +780,10 @@ func (builder *NFTOutputBuilder) Build() (*iotago.NFTOutput, error) { return builder.output, nil } -// NewDelegationOutputBuilder creates a new DelegationOutputBuilder with the account address, serial number, token scheme and deposit amount. -func NewDelegationOutputBuilder(validatorID iotago.AccountID, addr iotago.Address, deposit iotago.BaseToken) *DelegationOutputBuilder { +// NewDelegationOutputBuilder creates a new DelegationOutputBuilder with the account address, serial number, token scheme and base token amount. +func NewDelegationOutputBuilder(validatorID iotago.AccountID, addr iotago.Address, amount iotago.BaseToken) *DelegationOutputBuilder { return &DelegationOutputBuilder{output: &iotago.DelegationOutput{ - Amount: deposit, + Amount: amount, DelegatedAmount: 0, DelegationID: iotago.DelegationID{}, ValidatorID: validatorID, @@ -808,9 +808,9 @@ type DelegationOutputBuilder struct { output *iotago.DelegationOutput } -// Deposit sets the deposit of the output. -func (builder *DelegationOutputBuilder) Deposit(deposit iotago.BaseToken) *DelegationOutputBuilder { - builder.output.Amount = deposit +// Amount sets the base token amount of the output. +func (builder *DelegationOutputBuilder) Amount(amount iotago.BaseToken) *DelegationOutputBuilder { + builder.output.Amount = amount return builder } diff --git a/builder/output_builder_test.go b/builder/output_builder_test.go index ba27d8937..251475e9b 100644 --- a/builder/output_builder_test.go +++ b/builder/output_builder_test.go @@ -16,7 +16,7 @@ import ( func TestBasicOutputBuilder(t *testing.T) { var ( targetAddr = tpkg.RandEd25519Address() - deposit iotago.BaseToken = 1337 + amount iotago.BaseToken = 1337 nt = tpkg.RandNativeToken() expirationTarget = tpkg.RandEd25519Address() metadata = []byte("123456") @@ -25,7 +25,7 @@ func TestBasicOutputBuilder(t *testing.T) { timelock := slotTimeProvider.SlotFromTime(time.Now().Add(5 * time.Minute)) expiration := slotTimeProvider.SlotFromTime(time.Now().Add(10 * time.Minute)) - basicOutput, err := builder.NewBasicOutputBuilder(targetAddr, deposit). + basicOutput, err := builder.NewBasicOutputBuilder(targetAddr, amount). NativeToken(nt). Timelock(timelock). Expiration(expirationTarget, expiration). @@ -51,7 +51,7 @@ func TestAccountOutputBuilder(t *testing.T) { var ( stateCtrl = tpkg.RandEd25519Address() gov = tpkg.RandEd25519Address() - deposit iotago.BaseToken = 1337 + amount iotago.BaseToken = 1337 nt = tpkg.RandNativeToken() metadata = []byte("123456") immMetadata = []byte("654321") @@ -64,11 +64,11 @@ func TestAccountOutputBuilder(t *testing.T) { newBlockIssuerKey2 = tpkg.Rand32ByteArray() ) - accountOutput, err := builder.NewAccountOutputBuilder(stateCtrl, gov, deposit). + accountOutput, err := builder.NewAccountOutputBuilder(stateCtrl, gov, amount). NativeToken(nt). Metadata(metadata). StateMetadata(metadata). - Staking(deposit, 1, 1000). + Staking(amount, 1, 1000). BlockIssuer(iotago.BlockIssuerKeys{blockIssuerKey1, blockIssuerKey2, blockIssuerKey3}, 100000). ImmutableMetadata(immMetadata). ImmutableSender(immSender). @@ -96,7 +96,7 @@ func TestAccountOutputBuilder(t *testing.T) { ExpirySlot: 100000, }, &iotago.StakingFeature{ - StakedAmount: deposit, + StakedAmount: amount, FixedCost: 1, StartEpoch: 1000, EndEpoch: math.MaxUint64, @@ -109,13 +109,13 @@ func TestAccountOutputBuilder(t *testing.T) { } require.Equal(t, expected, accountOutput) - const newDeposit iotago.BaseToken = 7331 + const newAmount iotago.BaseToken = 7331 //nolint:forcetypeassert // we can safely assume that this is an AccountOutput expectedCpy := expected.Clone().(*iotago.AccountOutput) - expectedCpy.Amount = newDeposit + expectedCpy.Amount = newAmount expectedCpy.StateIndex++ updatedOutput, err := builder.NewAccountOutputBuilderFromPrevious(accountOutput).StateTransition(). - Deposit(newDeposit).Builder().Build() + Amount(newAmount).Builder().Build() require.NoError(t, err) require.Equal(t, expectedCpy, updatedOutput) @@ -151,7 +151,7 @@ func TestAccountOutputBuilder(t *testing.T) { ExpirySlot: 1500, }, &iotago.StakingFeature{ - StakedAmount: deposit, + StakedAmount: amount, FixedCost: 1, StartEpoch: 1000, EndEpoch: 2000, @@ -169,14 +169,14 @@ func TestDelegationOutputBuilder(t *testing.T) { var ( address = tpkg.RandEd25519Address() updatedAddress = tpkg.RandEd25519Address() - deposit iotago.BaseToken = 1337 - updatedDeposit iotago.BaseToken = 127 + amount iotago.BaseToken = 1337 + updatedAmount iotago.BaseToken = 127 validatorID = tpkg.RandAccountID() delegationID = tpkg.RandDelegationID() ) - delegationOutput, err := builder.NewDelegationOutputBuilder(validatorID, address, deposit). - DelegatedAmount(deposit). + delegationOutput, err := builder.NewDelegationOutputBuilder(validatorID, address, amount). + DelegatedAmount(amount). StartEpoch(1000). Build() require.NoError(t, err) @@ -196,8 +196,8 @@ func TestDelegationOutputBuilder(t *testing.T) { updatedOutput, err := builder.NewDelegationOutputBuilderFromPrevious(delegationOutput). DelegationID(delegationID). - DelegatedAmount(updatedDeposit). - Deposit(updatedDeposit). + DelegatedAmount(updatedAmount). + Amount(updatedAmount). EndEpoch(1500). Address(updatedAddress). Build() @@ -220,7 +220,7 @@ func TestDelegationOutputBuilder(t *testing.T) { func TestFoundryOutputBuilder(t *testing.T) { var ( accountAddr = tpkg.RandAccountAddress() - deposit iotago.BaseToken = 1337 + amount iotago.BaseToken = 1337 tokenScheme = &iotago.SimpleTokenScheme{ MintedTokens: big.NewInt(0), MeltedTokens: big.NewInt(0), @@ -231,7 +231,7 @@ func TestFoundryOutputBuilder(t *testing.T) { immMetadata = []byte("654321") ) - foundryOutput, err := builder.NewFoundryOutputBuilder(accountAddr, tokenScheme, deposit). + foundryOutput, err := builder.NewFoundryOutputBuilder(accountAddr, tokenScheme, amount). NativeToken(nt). Metadata(metadata). ImmutableMetadata(immMetadata). @@ -257,13 +257,13 @@ func TestFoundryOutputBuilder(t *testing.T) { func TestNFTOutputBuilder(t *testing.T) { var ( targetAddr = tpkg.RandAccountAddress() - deposit iotago.BaseToken = 1337 + amount iotago.BaseToken = 1337 nt = tpkg.RandNativeToken() metadata = []byte("123456") immMetadata = []byte("654321") ) - nftOutput, err := builder.NewNFTOutputBuilder(targetAddr, deposit). + nftOutput, err := builder.NewNFTOutputBuilder(targetAddr, amount). NativeToken(nt). Metadata(metadata). ImmutableMetadata(immMetadata). diff --git a/mana_decay_provider.go b/mana_decay_provider.go index 161cdc74c..1c6c64ea7 100644 --- a/mana_decay_provider.go +++ b/mana_decay_provider.go @@ -154,7 +154,7 @@ func (p *ManaDecayProvider) StoredManaWithDecay(storedMana Mana, slotIndexCreate } // PotentialManaWithDecay calculates the generated potential mana and applies the decay to the result. -func (p *ManaDecayProvider) PotentialManaWithDecay(deposit BaseToken, slotIndexCreated SlotIndex, slotIndexTarget SlotIndex) (Mana, error) { +func (p *ManaDecayProvider) PotentialManaWithDecay(amount BaseToken, slotIndexCreated SlotIndex, slotIndexTarget SlotIndex) (Mana, error) { epochIndexCreated := p.timeProvider.EpochFromSlot(slotIndexCreated) epochIndexTarget := p.timeProvider.EpochFromSlot(slotIndexTarget) @@ -165,24 +165,24 @@ func (p *ManaDecayProvider) PotentialManaWithDecay(deposit BaseToken, slotIndexC epochIndexDiff := epochIndexTarget - epochIndexCreated switch epochIndexDiff { case 0: - return p.generateMana(deposit, slotIndexTarget-slotIndexCreated), nil + return p.generateMana(amount, slotIndexTarget-slotIndexCreated), nil case 1: - manaDecayed := p.decay(p.generateMana(deposit, p.timeProvider.SlotsBeforeNextEpoch(slotIndexCreated)), 1) - manaGenerated := p.generateMana(deposit, p.timeProvider.SlotsSinceEpochStart(slotIndexTarget)) + manaDecayed := p.decay(p.generateMana(amount, p.timeProvider.SlotsBeforeNextEpoch(slotIndexCreated)), 1) + manaGenerated := p.generateMana(amount, p.timeProvider.SlotsSinceEpochStart(slotIndexTarget)) return safemath.SafeAdd(manaDecayed, manaGenerated) default: - c := Mana(fixedPointMultiplication32(uint64(deposit), p.decayFactorEpochsSum, p.decayFactorEpochsSumExponent+p.generationRateExponent-p.slotsPerEpochExponent)) + c := Mana(fixedPointMultiplication32(uint64(amount), p.decayFactorEpochsSum, p.decayFactorEpochsSumExponent+p.generationRateExponent-p.slotsPerEpochExponent)) //nolint:golint,revive,nosnakecase,stylecheck // taken from the formula, lets keep it that way - potentialMana_n := p.decay(p.generateMana(deposit, p.timeProvider.SlotsBeforeNextEpoch(slotIndexCreated)), epochIndexDiff) + potentialMana_n := p.decay(p.generateMana(amount, p.timeProvider.SlotsBeforeNextEpoch(slotIndexCreated)), epochIndexDiff) //nolint:golint,revive,nosnakecase,stylecheck // taken from the formula, lets keep it that way potentialMana_n_1 := p.decay(c, epochIndexDiff-1) //nolint:golint,revive,nosnakecase,stylecheck // taken from the formula, lets keep it that way - potentialMana_0, err := safemath.SafeAdd(c, p.generateMana(deposit, p.timeProvider.SlotsSinceEpochStart(slotIndexTarget))) + potentialMana_0, err := safemath.SafeAdd(c, p.generateMana(amount, p.timeProvider.SlotsSinceEpochStart(slotIndexTarget))) if err != nil { return 0, err } diff --git a/mana_decay_provider_test.go b/mana_decay_provider_test.go index 8058933b0..6c5c9188f 100644 --- a/mana_decay_provider_test.go +++ b/mana_decay_provider_test.go @@ -181,7 +181,7 @@ func TestManaDecay_StoredMana(t *testing.T) { func TestManaDecay_PotentialMana(t *testing.T) { type test struct { name string - deposit iotago.BaseToken + amount iotago.BaseToken slotIndexCreated iotago.SlotIndex slotIndexTarget iotago.SlotIndex result iotago.Mana @@ -191,7 +191,7 @@ func TestManaDecay_PotentialMana(t *testing.T) { tests := []test{ { name: "check if mana decay works for 0 base token values", - deposit: 0, + amount: 0, slotIndexCreated: testTimeProvider.EpochStart(1), slotIndexTarget: testTimeProvider.EpochStart(400), result: 0, @@ -199,7 +199,7 @@ func TestManaDecay_PotentialMana(t *testing.T) { }, { name: "check if mana decay works for 0 slot index diffs", - deposit: math.MaxInt64, + amount: math.MaxInt64, slotIndexCreated: testTimeProvider.EpochStart(1), slotIndexTarget: testTimeProvider.EpochStart(1), result: 0, @@ -207,7 +207,7 @@ func TestManaDecay_PotentialMana(t *testing.T) { }, { name: "check for error if target index is lower than created index", - deposit: 0, + amount: 0, slotIndexCreated: testTimeProvider.EpochStart(2), slotIndexTarget: testTimeProvider.EpochStart(1), result: 0, @@ -215,7 +215,7 @@ func TestManaDecay_PotentialMana(t *testing.T) { }, { name: "check if mana decay works for exactly the amount of epoch indexes in the lookup table", - deposit: math.MaxInt64, + amount: math.MaxInt64, slotIndexCreated: testTimeProvider.EpochStart(1), slotIndexTarget: testTimeProvider.EpochStart(iotago.EpochIndex(len(testManaDecayFactors) + 1)), result: 183827294847826527, @@ -223,7 +223,7 @@ func TestManaDecay_PotentialMana(t *testing.T) { }, { name: "check if mana decay works for multiples of the available epoch indexes in the lookup table", - deposit: math.MaxInt64, + amount: math.MaxInt64, slotIndexCreated: testTimeProvider.EpochStart(1), slotIndexTarget: testTimeProvider.EpochStart(iotago.EpochIndex(3*len(testManaDecayFactors) + 1)), result: 410192222442040018, @@ -231,7 +231,7 @@ func TestManaDecay_PotentialMana(t *testing.T) { }, { name: "check if mana generation works for 0 epoch index diffs", - deposit: math.MaxInt64, + amount: math.MaxInt64, slotIndexCreated: testTimeProvider.EpochStart(1), slotIndexTarget: testTimeProvider.EpochEnd(1), result: 562881233944575, @@ -239,7 +239,7 @@ func TestManaDecay_PotentialMana(t *testing.T) { }, { name: "check if mana generation works for 1 epoch index diffs", - deposit: math.MaxInt64, + amount: math.MaxInt64, slotIndexCreated: testTimeProvider.EpochStart(1), slotIndexTarget: testTimeProvider.EpochEnd(2), result: 1125343946211326, @@ -247,7 +247,7 @@ func TestManaDecay_PotentialMana(t *testing.T) { }, { name: "check if mana generation works for >=2 epoch index diffs", - deposit: math.MaxInt64, + amount: math.MaxInt64, slotIndexCreated: testTimeProvider.EpochStart(1), slotIndexTarget: testTimeProvider.EpochEnd(3), result: 1687319975062367, @@ -255,7 +255,7 @@ func TestManaDecay_PotentialMana(t *testing.T) { }, { name: "even with the highest possible int64 number, the calculation should not overflow", - deposit: math.MaxInt64, + amount: math.MaxInt64, slotIndexCreated: testTimeProvider.EpochStart(1), slotIndexTarget: testTimeProvider.EpochStart(401), result: 190239292158065300, @@ -265,7 +265,7 @@ func TestManaDecay_PotentialMana(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - result, err := testManaDecayProvider.PotentialManaWithDecay(tt.deposit, tt.slotIndexCreated, tt.slotIndexTarget) + result, err := testManaDecayProvider.PotentialManaWithDecay(tt.amount, tt.slotIndexCreated, tt.slotIndexTarget) if tt.wantErr != nil { require.ErrorIs(t, err, tt.wantErr) diff --git a/output.go b/output.go index 0c7eb48ac..8751ca449 100644 --- a/output.go +++ b/output.go @@ -35,8 +35,8 @@ type Output interface { NonEphemeralObject ProcessableObject - // Deposit returns the amount this Output deposits. - Deposit() BaseToken + // BaseTokenAmount the amount of base tokens held by this Output. + BaseTokenAmount() BaseToken // StoredMana returns the stored mana held by this output. StoredMana() Mana @@ -294,8 +294,8 @@ func (outputIDs OutputIDs) OrderedSet(set OutputSet) Outputs[Output] { } var ( - // ErrDepositAmountMustBeGreaterThanZero returned if the deposit amount of an output is less or equal zero. - ErrDepositAmountMustBeGreaterThanZero = ierrors.New("deposit amount must be greater than zero") + // ErrAmountMustBeGreaterThanZero returned if the base token amount of an output is less or equal zero. + ErrAmountMustBeGreaterThanZero = ierrors.New("base token amount must be greater than zero") // ErrChainMissing gets returned when a chain is missing. ErrChainMissing = ierrors.New("chain missing") // ErrNonUniqueChainOutputs gets returned when multiple ChainOutputs(s) with the same ChainID exist within sets. @@ -718,29 +718,29 @@ func (oih OutputIDHex) AsUTXOInput() (*UTXOInput, error) { type OutputsSyntacticalValidationFunc func(index int, output Output) error // OutputsSyntacticalDepositAmount returns an OutputsSyntacticalValidationFunc which checks that: -// - every output deposits more than zero -// - every output deposits less than the total supply -// - the sum of deposits does not exceed the total supply -// - the deposit fulfills the minimum storage deposit as calculated from the virtual byte cost of the output +// - every output has base token amount more than zero +// - every output has base token amount less than the total supply +// - the sum of base token amounts does not exceed the total supply +// - the base token amount fulfills the minimum storage deposit as calculated from the virtual byte cost of the output // - if the output contains a StorageDepositReturnUnlockCondition, it must "return" bigger equal than the minimum storage deposit // required for the sender to send back the tokens. func OutputsSyntacticalDepositAmount(protoParams ProtocolParameters) OutputsSyntacticalValidationFunc { var sum BaseToken return func(index int, output Output) error { - deposit := output.Deposit() + amount := output.BaseTokenAmount() switch { - case deposit == 0: - return ierrors.Wrapf(ErrDepositAmountMustBeGreaterThanZero, "output %d", index) - case deposit > protoParams.TokenSupply(): - return ierrors.Wrapf(ErrOutputDepositsMoreThanTotalSupply, "output %d", index) - case sum+deposit > protoParams.TokenSupply(): + case amount == 0: + return ierrors.Wrapf(ErrAmountMustBeGreaterThanZero, "output %d", index) + case amount > protoParams.TokenSupply(): + return ierrors.Wrapf(ErrOutputAmountMoreThanTotalSupply, "output %d", index) + case sum+amount > protoParams.TokenSupply(): return ierrors.Wrapf(ErrOutputsSumExceedsTotalSupply, "output %d", index) } - // check whether deposit fulfills the storage deposit cost - if _, err := protoParams.RentStructure().CoversStateRent(output, deposit); err != nil { + // check whether base token amount fulfills the storage deposit cost + if _, err := protoParams.RentStructure().CoversStateRent(output, amount); err != nil { return ierrors.Wrapf(err, "output %d", index) } @@ -750,12 +750,12 @@ func OutputsSyntacticalDepositAmount(protoParams ProtocolParameters) OutputsSynt switch { case storageDep.Amount < minStorageDepositForReturnOutput: return ierrors.Wrapf(ErrStorageDepositLessThanMinReturnOutputStorageDeposit, "output %d, needed %d, have %d", index, minStorageDepositForReturnOutput, storageDep.Amount) - case storageDep.Amount > deposit: - return ierrors.Wrapf(ErrStorageDepositExceedsTargetOutputDeposit, "output %d, target output's deposit %d < storage deposit %d", index, deposit, storageDep.Amount) + case storageDep.Amount > amount: + return ierrors.Wrapf(ErrStorageDepositExceedsTargetOutputAmount, "output %d, target output's amount %d < storage deposit %d", index, amount, storageDep.Amount) } } - sum += deposit + sum += amount return nil } diff --git a/output_account.go b/output_account.go index 8deae4f36..1099142ec 100644 --- a/output_account.go +++ b/output_account.go @@ -279,7 +279,7 @@ func (a *AccountOutput) ImmutableFeatureSet() FeatureSet { return a.ImmutableFeatures.MustSet() } -func (a *AccountOutput) Deposit() BaseToken { +func (a *AccountOutput) BaseTokenAmount() BaseToken { return a.Amount } diff --git a/output_basic.go b/output_basic.go index 9ca024f50..8cbea0c89 100644 --- a/output_basic.go +++ b/output_basic.go @@ -94,7 +94,7 @@ func (e *BasicOutput) UnlockConditionSet() UnlockConditionSet { return e.Conditions.MustSet() } -func (e *BasicOutput) Deposit() BaseToken { +func (e *BasicOutput) BaseTokenAmount() BaseToken { return e.Amount } diff --git a/output_delegation.go b/output_delegation.go index 428e13163..fa852f660 100644 --- a/output_delegation.go +++ b/output_delegation.go @@ -174,7 +174,7 @@ func (d *DelegationOutput) UnlockConditionSet() UnlockConditionSet { return d.Conditions.MustSet() } -func (d *DelegationOutput) Deposit() BaseToken { +func (d *DelegationOutput) BaseTokenAmount() BaseToken { return d.Amount } diff --git a/output_foundry.go b/output_foundry.go index c5de4f4f0..1c327012c 100644 --- a/output_foundry.go +++ b/output_foundry.go @@ -231,7 +231,7 @@ func (f *FoundryOutput) ImmutableFeatureSet() FeatureSet { return f.ImmutableFeatures.MustSet() } -func (f *FoundryOutput) Deposit() BaseToken { +func (f *FoundryOutput) BaseTokenAmount() BaseToken { return f.Amount } diff --git a/output_nft.go b/output_nft.go index f1bef5d15..7f4a7f806 100644 --- a/output_nft.go +++ b/output_nft.go @@ -182,7 +182,7 @@ func (n *NFTOutput) ImmutableFeatureSet() FeatureSet { return n.ImmutableFeatures.MustSet() } -func (n *NFTOutput) Deposit() BaseToken { +func (n *NFTOutput) BaseTokenAmount() BaseToken { return n.Amount } diff --git a/output_test.go b/output_test.go index 3ef7ee48a..7ce446202 100644 --- a/output_test.go +++ b/output_test.go @@ -286,7 +286,7 @@ func TestOutputsSyntacticalDepositAmount(t *testing.T) { Mana: 500, }, }, - wantErr: iotago.ErrStorageDepositExceedsTargetOutputDeposit, + wantErr: iotago.ErrStorageDepositExceedsTargetOutputAmount, }, { name: "fail - state rent not covered", @@ -312,7 +312,7 @@ func TestOutputsSyntacticalDepositAmount(t *testing.T) { }, }, }, - wantErr: iotago.ErrDepositAmountMustBeGreaterThanZero, + wantErr: iotago.ErrAmountMustBeGreaterThanZero, }, { name: "fail - more than total supply on single output", @@ -325,7 +325,7 @@ func TestOutputsSyntacticalDepositAmount(t *testing.T) { }, }, }, - wantErr: iotago.ErrOutputDepositsMoreThanTotalSupply, + wantErr: iotago.ErrOutputAmountMoreThanTotalSupply, }, { name: "fail - sum more than total supply over multiple outputs", diff --git a/transaction_essence.go b/transaction_essence.go index 836fa448b..a9b4e349a 100644 --- a/transaction_essence.go +++ b/transaction_essence.go @@ -61,12 +61,12 @@ var ( ErrDelegationValidatorIDZeroed = ierrors.New("delegation output's validator ID is zeroed") // ErrOutputsSumExceedsTotalSupply gets returned if the sum of the output deposits exceeds the total supply of tokens. ErrOutputsSumExceedsTotalSupply = ierrors.New("accumulated output balance exceeds total supply") - // ErrOutputDepositsMoreThanTotalSupply gets returned if an output deposits more than the total supply. - ErrOutputDepositsMoreThanTotalSupply = ierrors.New("an output can not deposit more than the total supply") + // ErrOutputAmountMoreThanTotalSupply gets returned if an output base token amount is more than the total supply. + ErrOutputAmountMoreThanTotalSupply = ierrors.New("an output can not have base token amount more than the total supply") // ErrStorageDepositLessThanMinReturnOutputStorageDeposit gets returned when the storage deposit condition's amount is less than the min storage deposit for the return output. ErrStorageDepositLessThanMinReturnOutputStorageDeposit = ierrors.New("storage deposit return amount is less than the min storage deposit needed for the return output") - // ErrStorageDepositExceedsTargetOutputDeposit gets returned when the storage deposit condition's amount exceeds the target output's deposit. - ErrStorageDepositExceedsTargetOutputDeposit = ierrors.New("storage deposit return amount exceeds target output's deposit") + // ErrStorageDepositExceedsTargetOutputAmount gets returned when the storage deposit condition's amount exceeds the target output's base token amount. + ErrStorageDepositExceedsTargetOutputAmount = ierrors.New("storage deposit return amount exceeds target output's base token amount") // ErrMaxNativeTokensCountExceeded gets returned if outputs or transactions exceed the MaxNativeTokensCount. ErrMaxNativeTokensCountExceeded = ierrors.New("max native tokens count exceeded") ) diff --git a/vm/stardust/vm_stardust.go b/vm/stardust/vm_stardust.go index 70224103d..a874cc9c9 100644 --- a/vm/stardust/vm_stardust.go +++ b/vm/stardust/vm_stardust.go @@ -16,7 +16,7 @@ func NewVirtualMachine() vm.VirtualMachine { vm.ExecFuncTimelocks(), vm.ExecFuncInputUnlocks(), vm.ExecFuncSenderUnlocked(), - vm.ExecFuncBalancedDeposit(), + vm.ExecFuncBalancedBaseTokens(), vm.ExecFuncBalancedNativeTokens(), vm.ExecFuncChainTransitions(), vm.ExecFuncBalancedMana(), diff --git a/vm/stardust/vm_stardust_test.go b/vm/stardust/vm_stardust_test.go index 3ca052d1f..0eab6671e 100644 --- a/vm/stardust/vm_stardust_test.go +++ b/vm/stardust/vm_stardust_test.go @@ -2504,7 +2504,7 @@ func TestTxSemanticDeposit(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - err := stardustVM.Execute(tt.tx, tt.vmParams, tt.resolvedInputs, vm.ExecFuncInputUnlocks(), vm.ExecFuncBalancedDeposit()) + err := stardustVM.Execute(tt.tx, tt.vmParams, tt.resolvedInputs, vm.ExecFuncInputUnlocks(), vm.ExecFuncBalancedBaseTokens()) if tt.wantErr != nil { require.ErrorIs(t, err, tt.wantErr) return diff --git a/vm/vm.go b/vm/vm.go index 57a596806..f4ce7881e 100644 --- a/vm/vm.go +++ b/vm/vm.go @@ -139,7 +139,7 @@ func TotalManaIn(manaDecayProvider *iotago.ManaDecayProvider, txCreationTime iot } // potential Mana - manaPotential, err := manaDecayProvider.PotentialManaWithDecay(input.Output.Deposit(), input.CreationTime, txCreationTime) + manaPotential, err := manaDecayProvider.PotentialManaWithDecay(input.Output.BaseTokenAmount(), input.CreationTime, txCreationTime) if err != nil { return 0, ierrors.Wrapf(err, "input %s potential mana calculation failed", outputID) } @@ -547,17 +547,17 @@ func ExecFuncBalancedMana() ExecFunc { } } -// ExecFuncBalancedDeposit validates that the IOTA tokens are balanced from the input/output side. +// ExecFuncBalancedBaseTokens validates that the base tokens are balanced from the input/output side. // It additionally also incorporates the check whether return amounts via StorageDepositReturnUnlockCondition(s) for specified identities // are fulfilled from the output side. -func ExecFuncBalancedDeposit() ExecFunc { +func ExecFuncBalancedBaseTokens() ExecFunc { return func(vm VirtualMachine, vmParams *Params) error { - // note that due to syntactic validation of outputs, input and output deposit sums + // note that due to syntactic validation of outputs, input and output base token amount sums // are always within bounds of the total token supply var in, out iotago.BaseToken inputSumReturnAmountPerIdent := make(map[string]iotago.BaseToken) for inputID, input := range vmParams.WorkingSet.UTXOInputsWithCreationTime { - in += input.Output.Deposit() + in += input.Output.BaseTokenAmount() returnUnlockCond := input.Output.UnlockConditionSet().StorageDepositReturn() if returnUnlockCond == nil { @@ -577,12 +577,12 @@ func ExecFuncBalancedDeposit() ExecFunc { outputSimpleTransfersPerIdent := make(map[string]iotago.BaseToken) for _, output := range vmParams.WorkingSet.Tx.Essence.Outputs { - outDeposit := output.Deposit() - out += outDeposit + outAmount := output.BaseTokenAmount() + out += outAmount // accumulate simple transfers for StorageDepositReturnUnlockCondition checks if basicOutput, is := output.(*iotago.BasicOutput); is && basicOutput.IsSimpleTransfer() { - outputSimpleTransfersPerIdent[basicOutput.Ident().Key()] += outDeposit + outputSimpleTransfersPerIdent[basicOutput.Ident().Key()] += outAmount } } From 7ad1c0d005cf97ae91b01b0dce6701344f2a4d75 Mon Sep 17 00:00:00 2001 From: Andrew Date: Tue, 1 Aug 2023 13:34:55 +0100 Subject: [PATCH 2/5] don't generate Mana from storage deposit --- output.go | 2 +- output_test.go | 2 +- rent.go | 26 ++++++++++++++------------ vm/stardust/vm_stardust.go | 17 +++++++++++++---- vm/stardust/vm_stardust_test.go | 8 ++++++-- vm/vm.go | 9 ++++++--- 6 files changed, 41 insertions(+), 23 deletions(-) diff --git a/output.go b/output.go index 8751ca449..13411349a 100644 --- a/output.go +++ b/output.go @@ -740,7 +740,7 @@ func OutputsSyntacticalDepositAmount(protoParams ProtocolParameters) OutputsSynt } // check whether base token amount fulfills the storage deposit cost - if _, err := protoParams.RentStructure().CoversStateRent(output, amount); err != nil { + if _, err := protoParams.RentStructure().CoversMinDeposit(output, amount); err != nil { return ierrors.Wrapf(err, "output %d", index) } diff --git a/output_test.go b/output_test.go index 7ce446202..501d8af06 100644 --- a/output_test.go +++ b/output_test.go @@ -299,7 +299,7 @@ func TestOutputsSyntacticalDepositAmount(t *testing.T) { }, }, }, - wantErr: iotago.ErrVByteRentNotCovered, + wantErr: iotago.ErrVByteDepositNotCovered, }, { name: "fail - zero deposit", diff --git a/rent.go b/rent.go index 4dae399f1..1db560431 100644 --- a/rent.go +++ b/rent.go @@ -18,9 +18,9 @@ const ( ) var ( - // ErrVByteRentNotCovered gets returned when a NonEphemeralObject does not cover the state rent - // cost which are calculated from its virtual byte costs. - ErrVByteRentNotCovered = ierrors.New("virtual byte rent costs not covered") + // ErrVByteDepositNotCovered gets returned when a NonEphemeralObject does not cover the minimum deposit + // which is calculated from its virtual byte costs. + ErrVByteDepositNotCovered = ierrors.New("virtual byte minimum deposit not covered") // ErrTypeIsNotSupportedRentStructure gets returned when a serializable was found to not be a supported RentStructure. ErrTypeIsNotSupportedRentStructure = ierrors.New("serializable is not a supported rent structure") ) @@ -36,6 +36,8 @@ func (factor VByteCostFactor) With(other VByteCostFactor) VByteCostFactor { } // RentStructure defines the parameters of rent cost 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. type RentStructure struct { // Defines the rent of a single virtual byte denoted in IOTA tokens. VByteCost uint32 `serix:"0,mapKey=vByteCost"` @@ -45,20 +47,20 @@ type RentStructure struct { VBFactorKey VByteCostFactor `serix:"2,mapKey=vByteFactorKey"` } -// CoversStateRent tells whether given this NonEphemeralObject, the given rent fulfills the renting costs +// CoversMinDeposit tells whether given this NonEphemeralObject, the base token amount fulfills the deposit requirements // by examining the virtual bytes cost of the object. -// Returns the minimum rent computed and an error if it is not covered by rent. -func (r *RentStructure) CoversStateRent(object NonEphemeralObject, rent BaseToken) (BaseToken, error) { - minRent := r.MinRent(object) - if rent < minRent { - return 0, ierrors.Wrapf(ErrVByteRentNotCovered, "needed %d but only got %d", minRent, rent) +// Returns the minimum deposit computed and an error if it is not covered by the base token amount of the object. +func (r *RentStructure) CoversMinDeposit(object NonEphemeralObject, amount BaseToken) (BaseToken, error) { + minDeposit := r.MinDeposit(object) + if amount < minDeposit { + return 0, ierrors.Wrapf(ErrVByteDepositNotCovered, "needed %d but only got %d", minDeposit, amount) } - return minRent, nil + return minDeposit, nil } -// MinRent returns the minimum rent to cover a given object. -func (r *RentStructure) MinRent(object NonEphemeralObject) BaseToken { +// MinDeposit returns the minimum rent to cover a given object. +func (r *RentStructure) MinDeposit(object NonEphemeralObject) BaseToken { return BaseToken(r.VByteCost) * BaseToken(object.VBytes(r, nil)) } diff --git a/vm/stardust/vm_stardust.go b/vm/stardust/vm_stardust.go index a874cc9c9..5651378a3 100644 --- a/vm/stardust/vm_stardust.go +++ b/vm/stardust/vm_stardust.go @@ -288,8 +288,10 @@ func accountBlockIssuerSTVF(input *vm.ChainOutputWithCreationTime, next *iotago. // the Mana on the account on the input side must not be moved to any other outputs or accounts. manaDecayProvider := vmParams.API.ProtocolParameters().ManaDecayProvider() + rentStructure := vmParams.API.ProtocolParameters().RentStructure() manaIn, err := vm.TotalManaIn( manaDecayProvider, + rentStructure, vmParams.WorkingSet.Tx.Essence.CreationTime, vmParams.WorkingSet.UTXOInputsWithCreationTime, ) @@ -305,20 +307,27 @@ func accountBlockIssuerSTVF(input *vm.ChainOutputWithCreationTime, next *iotago. return err } - manaStoredAccount, err := manaDecayProvider.StoredManaWithDecay(current.Mana, input.CreationTime, vmParams.WorkingSet.Tx.Essence.CreationTime) // AccountInStored + // AccountInStored + manaStoredAccount, err := manaDecayProvider.StoredManaWithDecay(current.Mana, input.CreationTime, vmParams.WorkingSet.Tx.Essence.CreationTime) if err != nil { return ierrors.Wrapf(err, "account %s stored mana calculation failed", current.AccountID) } manaIn -= manaStoredAccount - manaPotentialAccount, err := manaDecayProvider.PotentialManaWithDecay(current.Amount, input.CreationTime, vmParams.WorkingSet.Tx.Essence.CreationTime) // AccountInPotential + // AccountInPotential + // the storage deposit does not generate potential mana, so we only use the excess base tokens to calculate the potential mana + // don't need to check for underflow because we already checked that the output amount is greater than the min deposit + excessBaseTokensAccount := current.Amount - rentStructure.MinDeposit(current) + manaPotentialAccount, err := manaDecayProvider.PotentialManaWithDecay(excessBaseTokensAccount, input.CreationTime, vmParams.WorkingSet.Tx.Essence.CreationTime) if err != nil { return ierrors.Wrapf(err, "account %s potential mana calculation failed", current.AccountID) } manaIn -= manaPotentialAccount - manaOut -= next.Mana // AccountOutStored - manaOut -= vmParams.WorkingSet.Tx.Essence.Allotments.Get(current.AccountID) // AccountOutAllotted + // AccountOutStored + manaOut -= next.Mana + // AccountOutAllotted + manaOut -= vmParams.WorkingSet.Tx.Essence.Allotments.Get(current.AccountID) // subtract AccountOutLocked - we only consider basic and NFT outputs because only these output types can include a timelock and address unlock condition. minManalockedSlotIndex := pastBoundedSlotIndex + vmParams.API.ProtocolParameters().MaxCommittableAge() diff --git a/vm/stardust/vm_stardust_test.go b/vm/stardust/vm_stardust_test.go index 0eab6671e..7ec6768f7 100644 --- a/vm/stardust/vm_stardust_test.go +++ b/vm/stardust/vm_stardust_test.go @@ -3918,7 +3918,9 @@ func TestTxSemanticMana(t *testing.T) { var slotIndexCreated iotago.SlotIndex = 10 slotIndexTarget := 10 + 100*testProtoParams.ParamEpochDurationInSlots() - potentialMana, err := testProtoParams.ManaDecayProvider().PotentialManaWithDecay(OneMi, slotIndexCreated, slotIndexTarget) + input := inputs[inputIDs[0]] + excessBaseTokens := input.Output.BaseTokenAmount() - testProtoParams.RentStructure().MinDeposit(input.Output) + potentialMana, err := testProtoParams.ManaDecayProvider().PotentialManaWithDecay(excessBaseTokens, slotIndexCreated, slotIndexTarget) require.NoError(t, err) storedMana, err := testProtoParams.ManaDecayProvider().StoredManaWithDecay(math.MaxUint64, slotIndexCreated, slotIndexTarget) @@ -3977,7 +3979,9 @@ func TestTxSemanticMana(t *testing.T) { var slotIndexCreated iotago.SlotIndex = 10 slotIndexTarget := 10 + 100*testProtoParams.ParamEpochDurationInSlots() - potentialMana, err := testProtoParams.ManaDecayProvider().PotentialManaWithDecay(OneMi, slotIndexCreated, slotIndexTarget) + input := inputs[inputIDs[0]] + excessBaseTokens := input.Output.BaseTokenAmount() - testProtoParams.RentStructure().MinDeposit(input.Output) + potentialMana, err := testProtoParams.ManaDecayProvider().PotentialManaWithDecay(excessBaseTokens, slotIndexCreated, slotIndexTarget) require.NoError(t, err) storedMana, err := testProtoParams.ManaDecayProvider().StoredManaWithDecay(math.MaxUint64, slotIndexCreated, slotIndexTarget) diff --git a/vm/vm.go b/vm/vm.go index f4ce7881e..4bb4951de 100644 --- a/vm/vm.go +++ b/vm/vm.go @@ -125,7 +125,7 @@ func NewVMParamsWorkingSet(api iotago.API, t *iotago.Transaction, inputs Resolve return workingSet, nil } -func TotalManaIn(manaDecayProvider *iotago.ManaDecayProvider, txCreationTime iotago.SlotIndex, inputSet InputSet) (iotago.Mana, error) { +func TotalManaIn(manaDecayProvider *iotago.ManaDecayProvider, rentStructure *iotago.RentStructure, txCreationTime iotago.SlotIndex, inputSet InputSet) (iotago.Mana, error) { var totalIn iotago.Mana for outputID, input := range inputSet { // stored Mana @@ -139,7 +139,10 @@ func TotalManaIn(manaDecayProvider *iotago.ManaDecayProvider, txCreationTime iot } // potential Mana - manaPotential, err := manaDecayProvider.PotentialManaWithDecay(input.Output.BaseTokenAmount(), input.CreationTime, txCreationTime) + // the storage deposit does not generate potential mana, so we only use the excess base tokens to calculate the potential mana + // don't need to check for underflow because we already checked that the output amount is greater than the min deposit + excessBaseTokens := input.Output.BaseTokenAmount() - rentStructure.MinDeposit(input.Output) + manaPotential, err := manaDecayProvider.PotentialManaWithDecay(excessBaseTokens, input.CreationTime, txCreationTime) if err != nil { return 0, ierrors.Wrapf(err, "input %s potential mana calculation failed", outputID) } @@ -524,7 +527,7 @@ func ExecFuncBalancedMana() ExecFunc { return ierrors.Wrapf(iotago.ErrInputCreationAfterTxCreation, "input %s has creation time %d, tx creation time %d", outputID, input.CreationTime, txCreationTime) } } - manaIn, err := TotalManaIn(vmParams.API.ManaDecayProvider(), txCreationTime, vmParams.WorkingSet.UTXOInputsWithCreationTime) + manaIn, err := TotalManaIn(vmParams.API.ManaDecayProvider(), vmParams.API.ProtocolParameters().RentStructure(), txCreationTime, vmParams.WorkingSet.UTXOInputsWithCreationTime) if err != nil { return ierrors.Join(iotago.ErrManaAmountInvalid, err) } From 6d8858976f9484863df13d39cd50b12912ee0ea2 Mon Sep 17 00:00:00 2001 From: Andrew Date: Wed, 2 Aug 2023 08:59:04 +0100 Subject: [PATCH 3/5] philipp review changes --- output.go | 6 +++--- transaction_essence.go | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/output.go b/output.go index 13411349a..976fe8b1f 100644 --- a/output.go +++ b/output.go @@ -35,7 +35,7 @@ type Output interface { NonEphemeralObject ProcessableObject - // BaseTokenAmount the amount of base tokens held by this Output. + // BaseTokenAmount returns the amount of base tokens held by this Output. BaseTokenAmount() BaseToken // StoredMana returns the stored mana held by this output. @@ -294,7 +294,7 @@ func (outputIDs OutputIDs) OrderedSet(set OutputSet) Outputs[Output] { } var ( - // ErrAmountMustBeGreaterThanZero returned if the base token amount of an output is less or equal zero. + // ErrAmountMustBeGreaterThanZero gets returned if the base token amount of an output is less or equal zero. ErrAmountMustBeGreaterThanZero = ierrors.New("base token amount must be greater than zero") // ErrChainMissing gets returned when a chain is missing. ErrChainMissing = ierrors.New("chain missing") @@ -751,7 +751,7 @@ func OutputsSyntacticalDepositAmount(protoParams ProtocolParameters) OutputsSynt case storageDep.Amount < minStorageDepositForReturnOutput: return ierrors.Wrapf(ErrStorageDepositLessThanMinReturnOutputStorageDeposit, "output %d, needed %d, have %d", index, minStorageDepositForReturnOutput, storageDep.Amount) case storageDep.Amount > amount: - return ierrors.Wrapf(ErrStorageDepositExceedsTargetOutputAmount, "output %d, target output's amount %d < storage deposit %d", index, amount, storageDep.Amount) + return ierrors.Wrapf(ErrStorageDepositExceedsTargetOutputAmount, "output %d, target output's base token amount %d < storage deposit %d", index, amount, storageDep.Amount) } } diff --git a/transaction_essence.go b/transaction_essence.go index a9b4e349a..a1a3e1fbd 100644 --- a/transaction_essence.go +++ b/transaction_essence.go @@ -62,7 +62,7 @@ var ( // ErrOutputsSumExceedsTotalSupply gets returned if the sum of the output deposits exceeds the total supply of tokens. ErrOutputsSumExceedsTotalSupply = ierrors.New("accumulated output balance exceeds total supply") // ErrOutputAmountMoreThanTotalSupply gets returned if an output base token amount is more than the total supply. - ErrOutputAmountMoreThanTotalSupply = ierrors.New("an output can not have base token amount more than the total supply") + ErrOutputAmountMoreThanTotalSupply = ierrors.New("an output's base token amount cannot exceed the total supply") // ErrStorageDepositLessThanMinReturnOutputStorageDeposit gets returned when the storage deposit condition's amount is less than the min storage deposit for the return output. ErrStorageDepositLessThanMinReturnOutputStorageDeposit = ierrors.New("storage deposit return amount is less than the min storage deposit needed for the return output") // ErrStorageDepositExceedsTargetOutputAmount gets returned when the storage deposit condition's amount exceeds the target output's base token amount. From bbf9a519fa93ebc9bab27f0afdf8cc9b19abae15 Mon Sep 17 00:00:00 2001 From: Andrew Date: Wed, 2 Aug 2023 11:51:22 +0100 Subject: [PATCH 4/5] check for inputs with less than min storage deposit --- vm/stardust/vm_stardust.go | 8 ++++++-- vm/vm.go | 4 +++- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/vm/stardust/vm_stardust.go b/vm/stardust/vm_stardust.go index 5651378a3..8815704c4 100644 --- a/vm/stardust/vm_stardust.go +++ b/vm/stardust/vm_stardust.go @@ -316,8 +316,12 @@ func accountBlockIssuerSTVF(input *vm.ChainOutputWithCreationTime, next *iotago. // AccountInPotential // the storage deposit does not generate potential mana, so we only use the excess base tokens to calculate the potential mana - // don't need to check for underflow because we already checked that the output amount is greater than the min deposit - excessBaseTokensAccount := current.Amount - rentStructure.MinDeposit(current) + var excessBaseTokensAccount iotago.BaseToken + if current.Amount <= rentStructure.MinDeposit(current) { + excessBaseTokensAccount = 0 + } else { + excessBaseTokensAccount = current.Amount - rentStructure.MinDeposit(current) + } manaPotentialAccount, err := manaDecayProvider.PotentialManaWithDecay(excessBaseTokensAccount, input.CreationTime, vmParams.WorkingSet.Tx.Essence.CreationTime) if err != nil { return ierrors.Wrapf(err, "account %s potential mana calculation failed", current.AccountID) diff --git a/vm/vm.go b/vm/vm.go index 4bb4951de..1cc294ee6 100644 --- a/vm/vm.go +++ b/vm/vm.go @@ -140,7 +140,9 @@ func TotalManaIn(manaDecayProvider *iotago.ManaDecayProvider, rentStructure *iot // potential Mana // the storage deposit does not generate potential mana, so we only use the excess base tokens to calculate the potential mana - // don't need to check for underflow because we already checked that the output amount is greater than the min deposit + if input.Output.BaseTokenAmount() <= rentStructure.MinDeposit(input.Output) { + continue + } excessBaseTokens := input.Output.BaseTokenAmount() - rentStructure.MinDeposit(input.Output) manaPotential, err := manaDecayProvider.PotentialManaWithDecay(excessBaseTokens, input.CreationTime, txCreationTime) if err != nil { From da1cd54b4e67468c9b998c79cc37f447671fda29 Mon Sep 17 00:00:00 2001 From: Andrew Date: Wed, 2 Aug 2023 14:48:54 +0100 Subject: [PATCH 5/5] mux review comments --- rent.go | 2 +- vm/stardust/vm_stardust.go | 5 +++-- vm/vm.go | 5 +++-- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/rent.go b/rent.go index 1db560431..8557f8b11 100644 --- a/rent.go +++ b/rent.go @@ -59,7 +59,7 @@ func (r *RentStructure) CoversMinDeposit(object NonEphemeralObject, amount BaseT return minDeposit, nil } -// MinDeposit returns the minimum rent to cover a given object. +// MinDeposit returns the minimum deposit to cover a given object. func (r *RentStructure) MinDeposit(object NonEphemeralObject) BaseToken { return BaseToken(r.VByteCost) * BaseToken(object.VBytes(r, nil)) } diff --git a/vm/stardust/vm_stardust.go b/vm/stardust/vm_stardust.go index 8815704c4..881bab735 100644 --- a/vm/stardust/vm_stardust.go +++ b/vm/stardust/vm_stardust.go @@ -317,10 +317,11 @@ func accountBlockIssuerSTVF(input *vm.ChainOutputWithCreationTime, next *iotago. // AccountInPotential // the storage deposit does not generate potential mana, so we only use the excess base tokens to calculate the potential mana var excessBaseTokensAccount iotago.BaseToken - if current.Amount <= rentStructure.MinDeposit(current) { + minDeposit := rentStructure.MinDeposit(current) + if current.Amount <= minDeposit { excessBaseTokensAccount = 0 } else { - excessBaseTokensAccount = current.Amount - rentStructure.MinDeposit(current) + excessBaseTokensAccount = current.Amount - minDeposit } manaPotentialAccount, err := manaDecayProvider.PotentialManaWithDecay(excessBaseTokensAccount, input.CreationTime, vmParams.WorkingSet.Tx.Essence.CreationTime) if err != nil { diff --git a/vm/vm.go b/vm/vm.go index 1cc294ee6..9937e178e 100644 --- a/vm/vm.go +++ b/vm/vm.go @@ -140,10 +140,11 @@ func TotalManaIn(manaDecayProvider *iotago.ManaDecayProvider, rentStructure *iot // potential Mana // the storage deposit does not generate potential mana, so we only use the excess base tokens to calculate the potential mana - if input.Output.BaseTokenAmount() <= rentStructure.MinDeposit(input.Output) { + minDeposit := rentStructure.MinDeposit(input.Output) + if input.Output.BaseTokenAmount() <= minDeposit { continue } - excessBaseTokens := input.Output.BaseTokenAmount() - rentStructure.MinDeposit(input.Output) + excessBaseTokens := input.Output.BaseTokenAmount() - minDeposit manaPotential, err := manaDecayProvider.PotentialManaWithDecay(excessBaseTokens, input.CreationTime, txCreationTime) if err != nil { return 0, ierrors.Wrapf(err, "input %s potential mana calculation failed", outputID)