Closed setunapo closed 10 months ago
there are 2 updated version in forum:
this repo has more information about StateExpiry, both Consensus & Non-Consensus version: https://github.com/bnb-chain/BSC-State-Expiry
about how to revive https://github.com/bnb-chain/BEPs/pull/215
BEP(v0.5): Hybrid Mode State Expiry
1.Summary
This BEP proposes a practical solution to address the problem of increasing world state storage on the BNB Smart Chain, by removing expired storage state.
2.Motivation
Storage presents a significant challenge for many blockchains, as new blocks are continually generated, and transactions within these blocks could invoke smart contracts that also add more states to the blockchain. A large storage size can cause several side effects on the chain, such as higher hardware requirements, increased network resources required for downloading and performing p2p sync, and performance degradation due to MPT write amplification.
Due to the high volume of traffic, the storage size on BSC grows very rapidly. As of the end of 2022, a pruned BSC full node snapshot file is approximately 1.6TB in size, compared to approximately 1TB just one year ago. The 1.6TB storage consists mainly of two parts:
3.Specification
3.1.Design Guide
a.The Two Principles
b.Better To Have
Simple protocol
Less impact to UX
Affordable price: storage access fee, state revive fee…
3.2.The Components
There will be some new components introduced and some existing components will be updated.
a.New Components
b.Existing Components
3.3.General Workflow
a.From User’s Perspective
Users will not need to be aware of StateExpiry, generally before users send out the transaction, they would query a RPC node about the estimated gas needed. The RPC nodes will estimate the gas needed based on execution fee and the fee to revive all the expired states. If the estimated gas needed is acceptable, the user will send out the transaction as usual.
When the transaction is propagated to the tx pool of validator, the validator would know whether the transaction needs to access any expired state or not, if yes, the validator would be required to collect the witness and rewarded accordingly. It is ok if the validator does not get the witness, then the validator will not be allowed to include this transaction.
b.From Node’s Perspective
In Epoch 0
Nothing will be changed, nodes just operate as usual.
In Epoch 1
State will not expire when entering Epoch 1, so the whole state will be there in Epoch 1, no rent will be charged either. But the meta information will be updated on block finalization to record the latest status.
In Epoch 2+
Since Epoch 2, state expiry will start to work. The state of the contract will be expired if none of the following requirements are met:
3.4.The Meta
a.Definition
// if no rent, no meta content needed, can be empty
b.How to persistent the meta bytes
There will be a meta hash in account structure, which will be the key to access encoded meta information.
c.How To Update The MetaInfo
It will be updated on block finalization, not by transaction level. When a block is finalized, then the access record will be determined, we will know the keys that are accessed, created or deleted. These information will be updated to the meta structure
d.How To Calculate The MetaHash
Metahash is just simply the keccak256 hash of the meta bytecode
3.5.Epoch Information In Trie Node
It would be very simple, only extend the current branch node, which will include an epoch map, which is used to mark its children’s accessed epoch value. Hash calculation will include this epoch map element, so once the epoch map is updated, the corresponding intermediate nodes will be updated as well.
3.6.About GetState/SetState
If GetState tries to access an expired state, then the transaction will be reverted.
For SetState, it must do GetState first, if GetState fails due to accessing expired state, then the transaction will be reverted.
And since delete operation can be treated the same as set, it also needs to perform GetState first.
3.7.Gas Metering
Depends on the witness size used in this contract, the cost can calculated simply by: WitnessSize * WitnessPrice
If several transactions have overlapped KVs to revive, the first transaction would probably pay more, as when the later transaction to access these KVs, they are already revived.
It is somehow reasonable, as the first transaction will be executed first, so it will pay slightly more.
3.8.Support Snapshot
Snapshot will still be corresponding to the MPT structure.
Once the MPT is shrinked due to more sub-paths being expired, which will make the MPT end up with some boundary nodes. Boundary nodes are trie nodes that are either leaf nodes or intermediate nodes with at least one of its children expired.
The snapshot shrink can be conducted by off-line prune according to the MPT.
a.By Off-Line Prune
After off line prune of the MPT trie, the boundary will be generated. Then just go through the MPT tree, prune the snapshot according to the intermediate boundary node.
b.Handle State Revive
TBD
c.Handle New Key Insert
TBD
3.8.The Rent Model
a.Rent Policy
If the percentage of not expired KV accessed in the last epoch is greater than a threshold(30%? governable), then these alive KVs will not be expired.
update: no liveness check, since no big scan
User could save a certain range of Epoch, user may prefer to only save the KV of a few recent epochs
b.How To Fill The RentBalance
There will be a system contract to handle it, users just need to call it with the target address & balance provided, the system contract will help add the rent balance to the target address.
The balance can not be reclaimed.
But if the user sends the balance to an un-existed address, can it be refunded?
c.How To Determine The RentPrice
TBD
d.How To Charge Rent Fee
On first access of metainfo in a new Epoch, i.e. CurrentEpoch is not in EpochRecord, there will be a rent price for each epoch
3.9.Precompile Contracts: BSCStateExpiry
This contract will has some variable to set for governance
3.10.New Account Structure
3.12.New Block Structure (TBD)
type Block struct { header Header uncles []Header transactions Transactions witness []Witness // for StateExpiry }