Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Analysis and optimization of Ethereum storage explosion problem
#1
The booming development of decentralized applications such as DeFi and GameFi has greatly increased the demand for high-performance blockchain with low transaction costs. However, a key challenge in building high-performance blockchains is the storage explosion. The graph below, taken from Etherscan, illustrates the size of blockchain data for a full Ethereum node (archive).


As can be seen from the figure, the scale of chain data of nodes increases steadily and now reaches ~9TB. Since one goal of a decentralized blockchain is to allow commonly-configured computers to run nodes, imposing a 9TB storage requirement on commonly-configured computers would be difficult to achieve.

block

state

Transaction receipt

State is the main component of 8.7 terabytes. So sometimes we call a storage explosion a "state explosion." But why is it so big?

What is the Ethereum state?

The Ethereum state is a Merkle Patrica tree (MPT) in which

The leaf node is the address (0x...) => Account mapping, where the account stores the balance and nonce associated with the address

The internal nodes maintain the tree structure so that hashes of the entire tree can be computed quickly



Since the archive node will retain all the historical state of all the blocks, this means that any update in the MPT will create O(log(N)) internal nodes and will not delete the old internal nodes.



By storing MPT periodically, the storage size of state is significantly reduced. According to Etherscan, the current Geth full node blockchain data size is about 1 terabyte.



The storage size of a Geth node can be further reduced to 447GB (as of 2021/12/06) without storing the historical MPT (and sometimes even the historical block body). By subtracting 300GB of block data, we infer that the state size is about 150GB.

Binance Intelligent Chain (BSC). As of December 8, 2021, BSC has:
About 984 GB of on-chain data, of which blocks account for about 550 GB and states for about 400 GB.

2,06623 million transactions, 100 TPS

If we further use the number of transactions to predict the data size, we can get:

If THE TPS is 100, that is ~3,153 M TPY

One year later, total TX ~5,219M, block ~ 1.375 TB, state ~ 1.085TB

After 3 years, total TX ~11,525M, block ~3.025TB, state ~ 2.387TB

If the TPS is 150 (the observed peak TPS), that is ~4,730 M TPY

One year later, total TX ~6,796M, block ~1.809 TB, state ~1.427 TB

After 3 years, total TX ~16,256M, block ~4.327 TB, state ~3.414TB

To sum up, for BSC, if the current speed is maintained even higher, it will soon reach the same storage size as ethereum archive nodes, which is almost impossible for normal computers to run.

Storage explosion problem with extremely high TPS blockchain

If we were to make a bolder assumption about a blockchain with extremely high TPS, such as QuarkChain is able to do, what would that number become? If we consider a blockchain with 1000 TPS and analyze its block and state size, it would be:

Assuming that the tx size is about 100 bytes, the amount of storage required for the block per year is 1000 (TPS) x 100 (number of bytes per Tx) x 365 * 24 * 3600 = 2.86 TB

Let's say MPT has 10 billion accounts (more than the world's population!). , we expect the state size to be 150GB (Ethereum state size) /0.18B (Ethereum unique address) * 10B = 8.3TB

Putting these numbers together, it's easy to come to the conclusion that this is a requirement that most commonly configured computers will not be able to withstand!

To optimize the

To optimize storage costs, we had to relax the restrictions to be EVM-compatible rather than Ethereum compatible. That is, we had to build/run another EVM-enabled chain instead of a highly optimized Ethereum client.

~ 10B * 50 100GB (code) = 600 GB, about 1/10 of the MPT version!

While there are huge benefits to using normal KV, one major problem is that we can't calculate the state of each block post hashing in such short block intervals, which means we will lose the following benefits of Ethereum:

Fast sync: Download the state of any block and quickly sync the network by replaying the rest of the block

Fork detection (or Byzantine detection) : Whether a newly created block from a peer results in a different state from that of a locally executed block.

To enable fast synchronization, we have a periodic snapshot block (snapshot interval = epoch = for example, 14 weeks). A snapshot block contains additional information about the pre-state hash, which is the post-state hash of the previous snapshot block (the hash of the state after the transaction was executed) :

Non-snapshot blocks do not maintain state hashes, but instead have incremental hashes that contain the hashes of the original database operations (delete, update) of all transaction transactions for that block. This makes forking detection possible!

We use a pre-trade state hash instead of a post-trade state hash for blocks in Ethereum. The reason is that the node cannot immediately compute the hash of the post-transaction state, but by using the hash of the pre-transaction state, the node can compute the hash of the entire EPOCH interval. For example, if the state hash computation processes state data at 10M per second, it would take 600 GB / 10M ~ 16.67 hours (vs. EPOCH = 14 weeks) to compute the entire state of 600 GB



The process of calculating the hash before the state is as follows:

1. When a snapshot block is received and finalized, its KV state is snapshot and a background thread is created to iterate over all KV entries (addresses => accounts) and compute the hash.



2. When the next snapshot block is created, the calculated pre-state hash value is stored in that block. Again, the node will create another snapshot of KV and compute its hash in the background.



3. When the next snapshot block is created, in addition to storing the pre-state hash, the node can now release the KV snapshot of the snapshot block, which means that all deleted/updated data from the snapshot block will be automatically garbage collected (for example, compressed in levelDB).



The result means that nodes only need a maximum of two KV snapshots (most likely one with delta and one KV snapshot) to store state.

A snapshot of the pre-transaction state of the latest snapshot block, that is, the post-transaction state of the (latest -1) snapshot block

(latest - 1) The full block after the snapshot block

We can do a simple mathematical calculation of the storage cost: assuming the epoch lasts 2 weeks, the block replay size is

2 * 14 (days) * 24 (hours) * 3600 (seconds) * 100 * 1000 (TPS) = 224 GB!

Also, the numbers here don't grow over time!



Not only blocks, but state stores consume a lot of space

When TPS > 1000, storage usage is prohibitively high

We propose to optimize blocks and states:

The block size was reduced from 2.86 TB to 224 GB per year

State size (~10B accounts) reduced from 8.3 TB to 600 GB

A 2TB general-configuration computer should be able to run nodes for a long time

Disadvantages: Light node cannot validate one data in state (must be full node)

Thank you

Thank you to Dap-Learning for hosting this event.
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)