Skip to content

Latest commit

 

History

History
143 lines (93 loc) · 9.61 KB

aip-65.md

File metadata and controls

143 lines (93 loc) · 9.61 KB
aip title author discussions-to Status last-call-end-date (*optional) type created updated (*optional) requires (*optional)
65
Storage Fee for State Bytes refundable
msmouse
In Review
Gas
12/12/2023

AIP-65 - Storage Fee for State Bytes Refundable

Summary

Proposed is an evolution of the Storage Fee charging scheme where a category of storage fee (dubbed "bytes deposit") is charged and refunded according to the number of bytes a state item itself occupies in the current state, in addition to the existing "slot deposit" which reflects the storage impact imposed by a individual state item via the authenticated data structures.

Specifically, the legacy "free quota" mechanism which heavily punishes updating a large state item is removed.

The updated scheme aligns better with the reality of disk space consumption by the transactions hence serves as a better economic benchmark for the developers to optimize the cost of transactions.

Background - Why the "free bytes quota" existed

Generally speaking the Aptos nodes keep two categories of blockchain data on disk:

  1. The latest state: Items in the latest state and associated authentication data structures -- the network has to keep them around indefinitely until a transaction deleted the relevant state. Such storage should be priced high and is subject to refunding once deleted.
  2. The ledger history: the transaction itself and its outputs, including the "write set", which is the collection of the updated state items -- the entirety of the updated items.

Let's say, a large state item increases in size slightly:

  1. there's a small increase in the total size of the latest state.
  2. the entirety of the updated item will end up in the write set, which is part of the ledger hisotry, and lives on disk until the transaction version is old enough to be pruned.

Historically the storage fee charging scheme is designed to prevent both categories of storage consumption from filling the disk up for cheap. Specifically, to make sure the disk is not filled with the latest state items, storage fee for bytes was high; and to make sure disk is not filled with write sets generated by updating large items, the entirety of the updated state item is charged for the high rate; and finally, to make the cost of common use cases reasonable, there is a per item "free bytes qouta" of 1KB -- not only smaller items are cheaper to allocate, they are modified free of charge.

However, items larger than the free quota are very expensive to modify repeatedly.

The proposal

The old scheme penalizes frequently modified large state items heavily hence brought strong incentives for items smaller than the free quota, which imposes awkward trade-offs for developers to design storage granularities of their contracts and potentially make the state explosion problem worse by incentivizing more state items.

With the introduction of AIP-57, which adds a limit to per block transaction output size, the disk bandwidth for writing down the ledger history is effectively upper bounded. As a result, the total disk space to store a specific length of ledger history (measured by days) is upper bounded. To simplify the model, we propose this part of cost to be deemed constant and not applicable for storage fee charges. As a result, the fee charge uppon the size of state item reflects only the permanent storage impact and should be charged incrementally as the item grow in size and refunded as the slot it occupies gets cleaned up.

Goals

Remove the per slot free quota and be more friendly to reasonable large items.

Out of Scope

Notice that this AIP is about the Storage Fee which concerns disk space consumption. There's a related concern on the latency side of things which is covered by the Io Gas. Changes needed to be made on that front as well and that's covered by (AIP-59)[https://github.com/aptos-foundation/AIPs/blob/main/aips/aip-59.md]

Impact

Frequently updated larger state items are now cheaper. And when deleted, fees paid for the bytes are refundable. As a result, the developer can now straightforwardly decide on storage granularity according to the access (modification) pattern of things without worrying about modifying larger items being punished.

Pricing is reduced to 4000 octas per slot and 40 octas per byte and the 1KB free quota is removed. As a result:

  1. Allocating an item smaller than 250 bytes is cheaper than before.
  2. Allocating an item of the size between 250 to 4K bytes will be slightly more expensive than before, but more fair. The price increase peaks at 1KB at about 60%
  3. Merely touching a slot > 1KB no longer imposes penalty so such txns get significantly cheaper. As seen in MutateLargeTokenV2, UpgradeLarge, etc in the table below.

Before vs. After gas cost for common transaction types (assuming gas_unit_price=100 octas):

original 5k/slot 50/byte w/ 1KB free quota 4k/slot 40/byte
Transfer 6 6 100.0%
2ndTransfer 6 6 100.0%
CreateAccount 1004 992 98.8%
CreateTransfer 1006 994 98.8%
MintTokenV2 511 633 123.9%
MutateTokenV2 7 7 100.0%
MintLargeTokenV2 1620 1453 89.7%
MutateLargeTokenV2 1755 9 0.5%
CreateStakePool 2018 2347 116.3%
RotateConsensusKey 45 64 142.2%
JoinValidator100 4559 51 1.1%
AddStake 4561 13 0.3%
UnlockStake 9 38 422.2%
WithdrawStake 9 9 100.0%
LeaveValidatorSet100 4558 10 0.2%
CreateCollection 1006 962 95.6%
CreateTokenFirstTime 1509 1489 98.7%
MintTokenV1 8 8 100.0%
MutateTokenV1 509 483 94.9%
MutateTokenV12ndTime 8 8 100.0%
MutateTokenAdd10NewProperties 12 64 533.3%
MutateTokenMutate10ExistingProperties 12 12 100.0%
PublishSmall 1065 1122 105.4%
UpgradeSmall 71 70 98.6%
PublishLarge 13166 11055 84.0%
UpgradeLarge 10812 1443 13.3%

Alternative solutions

N/A

Specification

  1. The per slot "free bytes" quota is removed. Instead, all the bytes of a state item are priced uniformly for the permanent space occupation in the state DB.
  2. Treat storage fee for bytes as deposit, which is refundable.
  3. When a slot increases in size on modification, charge additionally into the deposit.
    1. legacy slots that didn't pay bytes deposits won't get charged for the bytes allocated for free.
    2. Considering pricing change, charge only to the point where the total deposit for bytes doesn't go beyond current_price_per_byte * num_current_bytes
  4. When slot decrease in size, don't refund, to simplify implementation and reasoning.
  5. If slot doesn't change in size on modification, no charging even if pricing changes.
  6. Refund only on deletion.

Reference Implementation

aptos-labs/aptos-core#11333

aptos-labs/aptos-core#11279

Testing (Optional)

Risks and Drawbacks

Due to pricing change, certain transactions got pricier. Specifically, those allocates (not modifying) slots that's larger than 250 bytes and smaller than 4K bytes. But it's more fair.

Timeline

Suggested implementation timeline

Release 1.10, early 2024

Suggested developer platform support timeline

Suggested deployment timeline

Release 1.10, early 2024

Security Considerations

Permanent storage price is lowered by 20%, which we think is worth the trade offs.