Wei Han Ng
    • Create new note
    • Create a note from template
      • Sharing URL Link copied
      • /edit
      • View mode
        • Edit mode
        • View mode
        • Book mode
        • Slide mode
        Edit mode View mode Book mode Slide mode
      • Customize slides
      • Note Permission
      • Read
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Write
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Engagement control Commenting, Suggest edit, Emoji Reply
    • Invite by email
      Invitee

      This note has no invitees

    • Publish Note

      Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

      Your note will be visible on your profile and discoverable by anyone.
      Your note is now live.
      This note is visible on your profile and discoverable online.
      Everyone on the web can find and read all notes of this public team.
      See published notes
      Unpublish note
      Please check the box to agree to the Community Guidelines.
      View profile
    • Commenting
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
      • Everyone
    • Suggest edit
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
    • Emoji Reply
    • Enable
    • Versions and GitHub Sync
    • Note settings
    • Note Insights New
    • Engagement control
    • Transfer ownership
    • Delete this note
    • Save as template
    • Insert from template
    • Import from
      • Dropbox
      • Google Drive
      • Gist
      • Clipboard
    • Export to
      • Dropbox
      • Google Drive
      • Gist
    • Download
      • Markdown
      • HTML
      • Raw HTML
Menu Note settings Note Insights Versions and GitHub Sync Sharing URL Create Help
Create Create new note Create a note from template
Menu
Options
Engagement control Transfer ownership Delete this note
Import from
Dropbox Google Drive Gist Clipboard
Export to
Dropbox Google Drive Gist
Download
Markdown HTML Raw HTML
Back
Sharing URL Link copied
/edit
View mode
  • Edit mode
  • View mode
  • Book mode
  • Slide mode
Edit mode View mode Book mode Slide mode
Customize slides
Note Permission
Read
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Write
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Engagement control Commenting, Suggest edit, Emoji Reply
  • Invite by email
    Invitee

    This note has no invitees

  • Publish Note

    Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

    Your note will be visible on your profile and discoverable by anyone.
    Your note is now live.
    This note is visible on your profile and discoverable online.
    Everyone on the web can find and read all notes of this public team.
    See published notes
    Unpublish note
    Please check the box to agree to the Community Guidelines.
    View profile
    Engagement control
    Commenting
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    • Everyone
    Suggest edit
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    Emoji Reply
    Enable
    Import from Dropbox Google Drive Gist Clipboard
       Owned this note    Owned this note      
    Published Linked with GitHub
    1
    • Any changes
      Be notified of any changes
    • Mention me
      Be notified of mention me
    • Unsubscribe
    ## ❌ State Bloat: The Killer of all Blockchains On Ethereum, **State** consists of the following: - Account balances - Account nonces - Contract code - Contract storage At any given time, nodes need to know the current state to process new blocks and transactions. As more users join the network, more states are created (more accounts and contracts). As the state grows, the storage requirement for a node increases because they need to store the full state. When a blockchain's state grows significantly, it hinders the network's performance, making it difficult for many people to run nodes, leading to centralization. This issue is known as the **State Bloat** problem. ## 📖 Theory ### ReGenesis > 💣 Nuke everything and let's start over!!! *Refer to [Regenesis Explained.](https://medium.com/@mandrigin/regenesis-explained-97540f457807)* ![](https://hackmd.io/_uploads/rJaGXkT92.png) The general idea of ReGenesis is for blockchain nodes to delete the entire blockchain state and start anew, while retaining only the pre-ReGenesis state's root hash. This process occurs at fixed intervals, such as every 1,000,000 blocks, to limit state growth and address the state bloat problem. But what if a user wants to access the old state and perform actions with it? Users can send a transaction containing the operation (e.g., sending Ether) and the witness (i.e., useful state and proof). The state included in each transaction is merged back with the primary blockchain state. This means that with every ReGenesis, redundant state is guaranteed to be removed from the blockchain state. However, a caveat remains: the pre-ReGenesis state still needs to be stored somewhere, such as IPFS, Portal Network, a self-hosted database, or any accessible location. Additionally, Merkle proofs can be too large and impact network bandwidth, which could potentially be addressed with Verkle Trees. ### Blockchain Rent > 💸 Pay rent or say bye bye to your data. *Refer to [EIP 103 (Serenity).](https://github.com/ethereum/EIPs/issues/35)* The concept of blockchain rent is simple – rather than paying a one-time cost to store data permanently on a blockchain, users must now pay rent to keep the data on the blockchain. However, implementing this on existing chains like Ethereum is not straightforward, as it adds complexity to the existing economic model. Blockchain rent also introduces uncertainties into accounts, which creates new attack vectors. ### Statelessness > 🧊 Ain't nobody got time to store states! *Refer to [A Theory of Ethereum State Size Management.](https://hackmd.io/@vbuterin/state_size_management)* The general idea is that block verification no longer requires the full state. Instead, blocks can be executed standalone, allowing nodes to verify using only the information contained in the blocks. To achieve this, blocks need to come with witnesses that prove the correctness of the new state root after executing the block. Vitalik's article outlines two forms of statelessness: - **Weak statelessness**: only block producers require the full state so that they can generate witnesses for block creation, but other nodes can be stateless by using blocks to perform verification - **Strong statelessness**: full state is not necessary for all nodes. Users need to provide witnesses whenever sending a transaction. Block producers would aggregate the witnesses and still store portions of the state tree to generate witnesses for accounts that they care about. While weak statelessness doesn't solve the state bloat problem, it eases the burden of storing the full state for non-block producers, enabling regular people to run nodes with lower hardware requirements and increasing decentralization. Strong statelessness shifts the responsibility of "knowing the state" to users, which may impact user experience. Additionally, strong statelessness may have a higher impact on network bandwidth, as transactions need to contain more information, such as accounts and storage keys they access. ### State Expiry > 👋 Not using your data anymore? Then go away. *Refer to [A Theory of Ethereum State Size Management.](https://hackmd.io/@vbuterin/state_size_management)* If a state is no longer accessed for a long time, then why should we store them? State expiry is a solution to label if a state is inactive or active and temporarily removes the inactive state from the blockchain. Inactive state can be revived by providing some witnesses and be active again. From Vitalik's article, there are a few ways to determine the inactivity of a state (I rewrote it in my own words): - **Automatic rent on account balance**: each account has a default "rent-free" period. After that, the account balance automatically gets deducted. The account is deemed inactive and expired when its balance reaches zero. - **Subscription model**: each state object has a time period to stay in the blockchain and can be extended by paying a fee. - **Refresh by touching**: each state object has a time period to stay in the blockchain and it is automatically extended by reading or writing to the object. - **ReGenesis**: all states expire automatically at a fixed interval The key challenge with state expiry schemes is **resurrection conflict**. Supposed that Alice had an account 5 years ago with a balance of 10 ETH. It is expired due to inactivity. Alice now creates a new account at the same address and has a balance of 5 ETH. Finally, a resurrection of the original account is executed. How do we handle this scenario? From Vitalik's article, there are a few possible solutions (again, rewriting in my own words): - **Account merge**: accounts that expired and accounts that got created at the same address are merged. Merging logic for contract level may be customized, only the latest state or only the old state. Account balance may be merged together as well. - **Eliminate same-address re-creation**: CREATE2 opcode now adds the current year so that address generated in different years cannot be the same. - **Add a "stub" at expired location**: if reading or writing to a state passes through a "stub", transaction will be reverted. For a transaction to succeed, it needs to recover the expired location first. - **Account creations with non-prior-expiry proofs**: all account creations must come with some witnesses to prove that it does not expire previously. All of the solutions have its own tradeoffs. Merging account introduces complexity and things become super messy. Preventing users from re-creating addresses and requiring account creations to come with non-prior-expiry proofs affect user experience. In this case, adding a stub seems like the best solution among all, but it has the tree rot problem (see [this](https://hackmd.io/@vbuterin/state_size_management#Tree-rot)). To summarize, state expiry is an "elegant" way of eliminating inactive state while providing the capability of resurrecting inactive state to active state again. ## 🛠️ Ideas & Implementations ### Ethereum's State Expiry > 🌲 Many Verkle Trees + Address extension + Refresh by touching *Refer to [State Expiry EIP](https://notes.ethereum.org/@vbuterin/state_expiry_eip)* ![](https://hackmd.io/_uploads/HJbOiWCqh.png) *Diagram by Vitalik* Instead of having only a single state tree, this proposal suggests creating a new tree at fixed epochs, such as every year, so that the blockchain generates a new state tree annually. State modifications can only be done on the current and previous state trees. If a state does not exist in these trees, it is considered expired. Users must provide witnesses to resurrect expired states for use. The revived state then becomes part of the current state tree and can be modified as usual. Concerns about this EIP include data redundancy, as the two most recent state trees could be identical, doubling node storage costs. Another concern is I/O cost, as each epoch has its own isolated tree, which may increase the number of reads/writes to disk, affecting client performance. ### BSC's State Expiry (MPT) > 💐 One MPT + Stub + Refresh by touching *Refer to [BSC State Expiry.](https://github.com/bnb-chain/BSC-State-Expiry)* ![](https://hackmd.io/_uploads/HyvaGL1j3.png) This proposal is inspired by Ethereum's State Expiry but uses only one Merkle Patricia Tree (MPT) and introduces a separate structure called ShadowTree. ShadowTree stores metadata corresponding to the MPT, and each node in the ShadowTree called ShadowNode records the epoch information that corresponds to an MPT node, determining if an MPT node has expired or not. It uses the "refresh by touching" method, which means that once a node is accessed, its epoch will be updated to the current epoch in the blockchain. When a node or a subtree is expired, it will be replaced with a "stub" node, which is just a hash node (root hash of expired subtree). To perform state revive, users can send a transaction that includes the necessary witnesses to revive the desired state. There's already a demo for this, and you can try it out yourselves [here](https://github.com/node-real/state-expiry-poc/). At first glance, we know that this definitely wouldn't on a mainnet. Why? Because it's using MPT proofs, and MPT proofs are way too large. ### BSC's State Expiry (Verkle Tree) > 🍃 Only expire values from the leaf nodes *Refer to [BSC State Expiry (VKT)](https://forum.bnbchain.org/t/bep-idea-state-expiry-on-bnb-chain/646/6?u=0xbundler)* ![](https://hackmd.io/_uploads/ryx7U81i3.png) In this variation of BSC's State Expiry, the proposal again resembles the previous one but utilizes a Verkle Tree instead of a Merkle Patricia Tree. Instead of expiring entire subtrees with "stub" nodes, only the values in the leaf nodes are expired. Each value in the leaf node is associated with its own metadata, including an epoch value that determines whether it has expired or not. To revive an expired value, a Verkle proof needs to be provided, but in this case, the proof only needs to demonstrate that the value is included in the commitment. This implementation is more straightforward, but the effect of expiring values may not be as significant as it appears, as intermediate nodes still exist in the tree and could also be redundant. ### Solana's State Rent > 💰 No pay no gain *Refer to [Solana Docs.](https://docs.solana.com/developing/intro/rent)* In Solana, the state is stored using accounts. An account includes metadata for the lifetime of the file, and it is expressed by a number of fractional native tokens called lamports. The fee for every Solana Account to store data on the blockchain is called rent. Since Solana clusters must actively maintain this data, there is a time and space-based fee required to keep an account and its data alive on the blockchain. Accounts pay "rent" to hold their data in validators' memory. Each validator occasionally collects rent from all accounts. If an account is unavailable to pay rent (i.e. zero lamports), it is purged and removed from the network in a process known as garbage collection. However, an account can become rent exempted if the account maintains a high enough lamport balance. A rent-exempted account does not have to pay rent and can still remain on the blockchain. To summarize, by ensuring that accounts pay certain amount of fees to be stored on Solana, it reduces the amount of redundant data and ensure that accounts on the blockchain are the active ones. ### Mina's Recursive Proof > 🤯 Constant 22kB blockchain size *Refer to [What is Mina Protocol? - SK Kai.](https://skkai.substack.com/p/what-is-mina-protocol)* ![](https://hackmd.io/_uploads/rkKP5Iyjh.png) Mina's design differs significantly from EVM chains, but its approach to maintaining a small blockchain size is intriguing. Mina utilizes a recursive SNARK system, where one SNARK can verify other snarks. This process creates multiple proofs that can be aggregated into a single block proof, submitted to the mainnet. However, there are concerns regarding the time it takes to generate the proof, which can impact user experience. While the size of the blockchain may be small, processing the proofs requires a well-equipped machine. ### Soroban's State Expiration > 👯‍♂️ Rent + Secondary DB *Refer to [How Soroban is Solving State Bloat.](https://www.stellar.org/developers-blog/not-all-data-is-equal-how-soroban-is-solving-state-bloat-with-state-expiration)* ![](https://hackmd.io/_uploads/HyXP38Ji2.png) Soroban introduces two types of contracts: Persistent and Temporary. All states are stored in a specialized database model called BucketListDB. Temporary contracts are permanently deleted from the blockchain when expired, while persistent contracts are stored in Expired State Storage (ESS), another database. Users can use operations to recover desired contracts from ESS back to BucketListDB. Persistent contracts expire based on rent, and the rent rate depends on the contract's storage size and duration on the blockchain. While the proposal aims to improve node performance by removing unused data from BucketListDB, there are questions about its effectiveness in solving the state bloat problem, as the amount of expired data may grow as the blockchain expands, requiring additional hardware to maintain ESS. ## Thoughts After examining all the proposed solutions, there doesn't appear to be a one-size-fits-all solution. Each approach has its tradeoffs, and the choice ultimately depends on what tradeoffs are deemed acceptable. I'm also exploring some combination of the solutions. Here are some of them: **Rent + Refresh by touching** Every contract accounts will have an epoch. Contract accounts can forever stay on the blockchain. However, if a contract account has never been called or accessed, its balance will be deducted until its balance is 0, and the contract will be forever removed from the blockchain. The deduction amount is based on the contract's storage size. The deducted fee will also be reimbursed to validators. Another variance of this idea is that, instead of determining whether to deduct contract balance based on whether the contract is being accessed or not in an epoch, we can determine whether to deduct the contract balance based on the amount of data being accessed in an epoch. Let's say we set a rule such that if less than 20% of contract storage is being accessed in an epoch, then its contract balance will be deducted. For example, if a contract storage size is 100MB, in epoch 1, only 10MB is being accessed (<20%), then its contract balance is deducted. The rationale behind this idea is to make it fair for all network participants. Validators should be compensated if they are storing your data permanently on a blockchain. But at the same time, if your contracts has high user activity, then validators wouldn't mind storing data for free. **Cold DB + Hot DB** Inspired by Soroban, why not have separate storage for "hot" data and "cold" data? Hot data refers to the state being accessed frequently, while cold data means that the state has not been accessed for a long time. Accessing cold data would incur a higher gas cost. **Ethereum's State Expiry without ASE** Address Space Extension (ASE) itself is a highly debatable topic within the community. Combining both State Expiry and ASE could potentially hinder the progress of State Expiry for an extended period. Is there a way we can implement State Expiry without relying on ASE? Also, it'll be quite interesting if we can know how much states are active/inactive in the past 1 or 2 years. Might be working on a quick tooling for this.

    Import from clipboard

    Paste your markdown or webpage here...

    Advanced permission required

    Your current role can only read. Ask the system administrator to acquire write and comment permission.

    This team is disabled

    Sorry, this team is disabled. You can't edit this note.

    This note is locked

    Sorry, only owner can edit this note.

    Reach the limit

    Sorry, you've reached the max length this note can be.
    Please reduce the content or divide it to more notes, thank you!

    Import from Gist

    Import from Snippet

    or

    Export to Snippet

    Are you sure?

    Do you really want to delete this note?
    All users will lose their connection.

    Create a note from template

    Create a note from template

    Oops...
    This template has been removed or transferred.
    Upgrade
    All
    • All
    • Team
    No template.

    Create a template

    Upgrade

    Delete template

    Do you really want to delete this template?
    Turn this template into a regular note and keep its content, versions, and comments.

    This page need refresh

    You have an incompatible client version.
    Refresh to update.
    New version available!
    See releases notes here
    Refresh to enjoy new features.
    Your user state has changed.
    Refresh to load new user state.

    Sign in

    Forgot password

    or

    By clicking below, you agree to our terms of service.

    Sign in via Facebook Sign in via Twitter Sign in via GitHub Sign in via Dropbox Sign in with Wallet
    Wallet ( )
    Connect another wallet

    New to HackMD? Sign up

    Help

    • English
    • 中文
    • Français
    • Deutsch
    • 日本語
    • Español
    • Català
    • Ελληνικά
    • Português
    • italiano
    • Türkçe
    • Русский
    • Nederlands
    • hrvatski jezik
    • język polski
    • Українська
    • हिन्दी
    • svenska
    • Esperanto
    • dansk

    Documents

    Help & Tutorial

    How to use Book mode

    Slide Example

    API Docs

    Edit in VSCode

    Install browser extension

    Contacts

    Feedback

    Discord

    Send us email

    Resources

    Releases

    Pricing

    Blog

    Policy

    Terms

    Privacy

    Cheatsheet

    Syntax Example Reference
    # Header Header 基本排版
    - Unordered List
    • Unordered List
    1. Ordered List
    1. Ordered List
    - [ ] Todo List
    • Todo List
    > Blockquote
    Blockquote
    **Bold font** Bold font
    *Italics font* Italics font
    ~~Strikethrough~~ Strikethrough
    19^th^ 19th
    H~2~O H2O
    ++Inserted text++ Inserted text
    ==Marked text== Marked text
    [link text](https:// "title") Link
    ![image alt](https:// "title") Image
    `Code` Code 在筆記中貼入程式碼
    ```javascript
    var i = 0;
    ```
    var i = 0;
    :smile: :smile: Emoji list
    {%youtube youtube_id %} Externals
    $L^aT_eX$ LaTeX
    :::info
    This is a alert area.
    :::

    This is a alert area.

    Versions and GitHub Sync
    Get Full History Access

    • Edit version name
    • Delete

    revision author avatar     named on  

    More Less

    Note content is identical to the latest version.
    Compare
      Choose a version
      No search result
      Version not found
    Sign in to link this note to GitHub
    Learn more
    This note is not linked with GitHub
     

    Feedback

    Submission failed, please try again

    Thanks for your support.

    On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?

    Please give us some advice and help us improve HackMD.

     

    Thanks for your feedback

    Remove version name

    Do you want to remove this version name and description?

    Transfer ownership

    Transfer to
      Warning: is a public team. If you transfer note to this team, everyone on the web can find and read this note.

        Link with GitHub

        Please authorize HackMD on GitHub
        • Please sign in to GitHub and install the HackMD app on your GitHub repo.
        • HackMD links with GitHub through a GitHub App. You can choose which repo to install our App.
        Learn more  Sign in to GitHub

        Push the note to GitHub Push to GitHub Pull a file from GitHub

          Authorize again
         

        Choose which file to push to

        Select repo
        Refresh Authorize more repos
        Select branch
        Select file
        Select branch
        Choose version(s) to push
        • Save a new version and push
        • Choose from existing versions
        Include title and tags
        Available push count

        Pull from GitHub

         
        File from GitHub
        File from HackMD

        GitHub Link Settings

        File linked

        Linked by
        File path
        Last synced branch
        Available push count

        Danger Zone

        Unlink
        You will no longer receive notification when GitHub file changes after unlink.

        Syncing

        Push failed

        Push successfully