Through this blog post, the purpose is to formally disclose the serious threat to the Ethereum platform, which was an obvious current danger before the Berlin hard fork.
Let’s start with some background on Ethereum and the country.
The Ethereum state consists of the patricia-merkle trie (prefix tree). This article will not be too detailed, just say that as the state grows, the branches on this tree will become denser. Each account added is another leaf. Between the root of the tree and the leaf itself, there are many “intermediate” nodes.
In order to find a given account or “leaf” in this huge tree, it is necessary to resolve some position of about 6-9 hashes from the root to the intermediate nodes to finally resolve the last hash, which leads to The data we are looking for.
In short: every time a Trie lookup is performed to find an account, 8-9 resolution operations are performed. Each parsing operation is a database lookup, and each database lookup can be any number of actual disk operations. The number of disk operations is difficult to estimate, but because the trie key is a cryptographic hash (collision resistant), the key is “random”, which is the worst case for any database.
As Ethereum grows, it is necessary to increase the price of gasoline to enter the tribe’s business.This is at
Tangerine Whistle In the block
2,463,000 In October 2016, which included EIP 150. After the so-called “Shanghai Attack”, EIP 150 actively increased the cost of gasoline and made a series of modifications to prevent DoS attacks.
Another such raise is in
Istanbul Upgrade, in block
9,069,000 In December 2019. In this upgrade, EIP 1884 Was activated.
EIP-1884 made the following changes:
700Gasoline (and cheap
In March 2019, Martin Swende is doing some measuring EVM opcode performance. Subsequent investigations led to the creation of EIP-1884.In the months before EIP-1884 went live, the paper Broken table Released (September 2019).
Two Ethereum security researchers-Hubert Ritzdorf and Matthias Egli-collaborated with an author behind the paper. Daniel Perez, and “weaponized” the vulnerabilities that they submitted to the Ethereum bug bounty. This is October 4, 2019.
We recommend you to read submit Overall, this is a well-written report.
On the channel dedicated to cross-client security, the developers from Geth, Parity and Aleth were informed about the submission that day.
The essence of the vulnerability is to trigger random trie queries. A very simple variant is:
jumpdest ; jump label, start of loop gas ; get a 'random' value on the stack extcodesize ; trigger trie lookup pop ; ignore the extcodesize result push1 0x00 ; jump label dest jump ; jump back to start
In their report, the researchers executed this payload against the nodes synchronized to the mainnet
eth_call, These are the numbers at the time of execution
EXTCODEHASH(Under 400 gas)
EXTCODESIZE(Under 700 gas)
- Parity check:
- Parity check:
Obviously, the changes in EIP 1884 did have an impact in reducing the impact of the attack, but it was far from enough.
This was before the Osaka Devcon. During Devcon, the mainnet client developers shared knowledge of this issue. We also met with Hubert and Mathias and Greg Markou (the ETC staff from Chainsafe). ETC developers also received the report.
As 2019 draws to a close, we know that the problems we are experiencing are larger than we had previously expected, and malicious transactions may result in block times in the range of minutes. To make matters worse, the developer community is dissatisfied with EIP-1884, because EIP-1884 violates certain contract procedures, and users and miners are very eager to increase the use of lump gas.
In addition, only two months later, in December 2019, Ethereum Ethereum Announce They left the scene, and OpenEthereum took over the maintenance of the code base.
A new customer coordination channel was created, in which Geth, Nethermind, OpenEthereum and Besu developers continue to coordinate.
We realize that we must take two approaches to solve these problems. One way is to use the Ethereum protocol and solve this problem at the protocol layer in some way. It’s best not to break the contract, it’s best not to punish “good” behavior, but still try to prevent attacks.
The second method is through software engineering, by changing the data model and structure in the client.
The first iteration of how to deal with these types of attacks is Here. In February 2020, it was officially released, EIP 2583. The idea behind it is to simply add a penalty every time a Trie lookup results in a miss.
However, Peter found a solution to this problem-the “shield relay” attack-which can effectively limit the upper limit of this penalty (approximately £800).
With the problem penalty It is the first need to search to determine that punishment must be imposed. However, if the remaining gasoline is not sufficient for the fine, it means that the unpaid expenses have been executed. Even if it does cause an exception to be thrown, these state readings can be wrapped into nested calls. Allow outside callers to continue repeat attacks without paying (full) fines.
Therefore, EIP was abandoned, and we are looking for a better alternative.
- Alexey Akhunov explored oil – A secondary source of “gas”, but is essentially different from “gas”
gas, Because it is invisible to the execution layer and may cause the transaction to be restored globally.
- Martin made a similar suggestion, Karma, In May 2020.
When repeating these plans, Vitalik Buterin suggested only increasing gas costs and maintaining a visit list. In August 2020, Martin and Vitalik begin to iterate what is about to become EIP-2929 And its companion eip, EIP-2930.
EIP-2929 effectively solves many previous problems.
- Contrary to EIP-1884 (unconditional increase in costs), it only increases costs for content that has not yet been accessed.This leads to just Less than a few percent growth Net cost.
- In addition, it, like EIP-2930, will not break any contract process,
- Moreover, it can be adjusted further by increasing gasoline costs (without interrupting operations).
On April 15, 2021, both of them
Peter’s attempt to solve this problem is Dynamic state snapshot, Released in October 2019.
Snapshot is an auxiliary data structure used to store the state of Ethereum in a flat format. During the real-time operation of the Geth node, the state of Ethereum can be constructed completely online. The advantage of a snapshot is that it acts as an acceleration structure for state access:
- Instead of doing
O(log N)Disk read (
xLevelDB overhead) access to an account/storage slot, snapshots can be provided directly,
- Snapshot supports account and storage iteration in the following locations
O(1)The complexity of each entry makes the cost of retrieving sequential status data by remote nodes much lower than before.
- The existence of snapshots also enables more exotic use cases, such as offline trimming state Trie or migrating to other data formats.
The disadvantage of snapshots is that the original account and stored data are actually duplicates.For the mainnet, this means additional
25GB SSD space used.
The idea of dynamic snapshots has started in mid-2019, and the main purpose is to become
snap Synchronize. At the time, the geth team was working on many “big projects”.
- Offline trim
- Dynamic snapshot + snapshot synchronization
- LES state distribution through sharding state
However, it was decided to give full priority to snapshots and to postpone other projects for the time being.These laid the foundation for future development
snap/1 Synchronize algorithm. Merged in March 2020.
With the release of the “motion snapshot” feature, we have some breathing room. If the Ethereum network is attacked, it will be painful, yes, but it is at least possible to inform users about enabling snapshots. The entire snapshot generation will take a lot of time, and snapshots cannot be synchronized yet, but the network can at least continue to run.
From March to April 2021,
snap/1 The protocol has been introduced in geth, so new algorithms based on snapshots can be used for synchronization. Although it is still not the default synchronization mode, this is an important step in making snapshots not only useful for attack protection, but also a major improvement for users.
In terms of agreement,
Berlin The upgrade will take place in April 2021.
The following are some benchmark tests developed in our AWS monitoring environment:
- Before Berlin, there were no snapshots,
- Before Berlin, there are snapshots,
- After Berlin, there are no snapshots,
- After Berlin, with a snapshot,
(Thick) digital representation
Berlin By reducing attack efficiency
5x, While snapshots reduce
10x, The total is
50x Reduce the impact.
We estimate that currently, on the mainnet (15 million gas), it is possible to create blocks that take a lot of time.
2.5-3s Execute on
geth node No Snapshot. As the state grows, this number will continue to deteriorate (for non-snapshot nodes).
If refunds are used to increase the effective natural gas usage in a block, it may be further aggravated by the (max) multiple
2x .with EIP 1559, The block gas limit will have higher flexibility and allow further
As for the feasibility of implementing this attack; the cost of the attacker to purchase the entire block is about a few ether (
Why disclose now
This threat has been an “open secret” for a long time. In fact, it was publicly disclosed by mistake at least once and was mentioned many times in ACD calls without clear details.
Since the Berlin upgrade is now over, and by default, geth nodes are using snapshots, we estimate that the threat is very low and transparency is better. Now it is time to fully disclose the work behind the scenes.
It is important to give the community an opportunity to understand the reasons behind changes that have a negative impact on the user experience, such as increased gasoline costs and restrictions on refunds.
This post was written by Martin Holst Swende and Peter Szilagyi on April 23, 2021. It was shared with other Ethereum-based projects on 2021-04-26, and publicly disclosed on 2021-05-18.