Vitalik New Title: What is Longest Gas Pricing?

Author: Vitalik Buterin

Compiler: Karen, Foreisght News

In Ethereum, resources were limited until recently and priced through a single resource called “Gas.” Gas is a unit of measurement that measures the “computational effort” required to process a particular transaction or block. Gas brings together longest types of “computations”, the most important of which include:

  1. Raw computation (e.g., ADD, MULTIPLY);

  2. Read, write and write to Ethereum storage (such as SSTORE, SLOAD, ETH transfer);

  3. Data bandwidth;

  4. The cost of generating ZK-SNARK proofs for blocks.

For example, this transaction I sent consumed a total of 47,085 Gas. These include: (i) a base cost of 21,000 Gas, (ii) 1,556 Gas for the calldata bytes included as part of the transaction, (iii) 16,500 Gas for read and write storage, (iv) 2,149 Gas for generating logs, and the rest for EVM execution. The Money Laundering that users must pay is proportional to the gas consumed by the transaction. A Block can contain up to 30 million gas long, and the gas price is continuously adjusted through the EIP-1559 targeting mechanism to ensure that each Block contains an average of 15 million gas.

This approach has one major advantage: because everything is combined into a single virtual resource, the marketplace design is very simple. It’s easy to optimize transactions to minimize costs, it’s relatively easy to optimize blocks to charge the highest possible fees (excluding MEV), and there are no weird incentives to encourage some transactions to bundle with other transactions to save fees.

However, there are inefficiencies with this approach: it treats different resources as if they were convertible to each other, when the actual underlying constraints are not the same. To understand this, you can first look at the following chart:

Vitalik新作:什么是多维Gas定价?

The gas limit imposes a constraint:

Vitalik新作:什么是多维Gas定价?

The actual underlying security constraints are often closer to:

Vitalik新作:什么是多维Gas定价?

This difference causes gas limits to either unjustifiably exclude actually safe blocks, accept actually insecure blocks, or both.

If there are n resources with different security limits, then one-dimensional gas may make the throughput up to long drop n times. As a result, there has long been interest in the concept of longing gas, and with EIP-4844, we have now actually implemented longing gas on Ethereum. This article explores the advantages of this approach, as well as the prospects for further enhancements.

Blob: Longest gas in Dencun

At the beginning of this year, the average block size was 150 kB. A large part of this is rollup data: Layer 2 protocol store data on-chain. This data is very expensive: although the Transaction Cost on Rollup is only 5-10 times that of the corresponding transaction on Ethereum L1, even such a cost is too high for a long use case.

So why not drop the gas cost for calldata (currently 16 gas for non-zero bytes and 4 gas for zero bytes) to make rollups cheaper? We’ve done this before, and we can do it again now. But the answer here is that the maximum size of a block is 30,000,000/16=1,875,000 non-zero bytes, and the network can barely or barely handle a block of this size. Dropping the cost by another 4x increases the maximum to 7.5 MB, which poses a significant risk to security.

This problem is eventually solved by introducing a separate, rollup-friendly data shorter (called blob) in each block.

There are different prices and limits for these two resources: after the Dencun Hard Fork, a Ethereum Block maximum long can contain (i) 30 million gas and (ii) 6 blobs, each of which can contain about 125 kB of calldata. Both resources have separate prices and are adjusted through a separate pricing mechanism similar to EIP-1559, with the goal of using an average of 15 million gas and 3 blobs per block.

As a result, the cost of the Rollup was dropped by a factor of 100, the volume on the Rollup increased by more than 3 times, and the theoretical maximum Block size increased only slightly: from about 1.9 MB to about 2.6 MB.

Vitalik新作:什么是多维Gas定价?

Note: Rollup Money Laundering, provided by Growthepie.xyz. The Dencun fork occurred on March 13, 2024, introducing longest pricing blobs.

Longest gas and stateless clients

In the near future, a similar problem will arise with stored proofs for stateless clients. A stateless client is a new type of client that will be able to validate the chain without having to store a large amount or any data locally. Stateless clients do this by accepting proofs of specific parts of Ethereum’s state that transactions in that block need to access.

The diagram above shows a stateless client receiving a Block and proof of the current value of a particular part of the state (e.g., account balance, code, storage) touched by the execution of that Block, which enables the Node to validate a Block without any storage.

A storage read costs 2100-2600 gas, depending on the read type, and storage writes are more expensive. On average, a block performs about 1,000 storage reads and writes (including ETH balance checks, SSTORE and SLOAD calls, contract code reads, and other operations). However, the theoretical maximum is 30,000,000/2,100=14,285 reads. The bandwidth load of a stateless client is proportional to that number.

The current plan is to support stateless clients by transforming Ethereum’s State tree design from Merkle Patricia trees to Verkle trees. However, Verkle trees are not quantum-resistant and are not optimal for newer STARK proof systems. As a result, longest people are interested in supporting stateless clients with binary Merkle trees and STARKs, either skipping Verkle altogether or upgrading a few years after Verkle’s transition once STARK becomes more mature.

STARK proofs based on binary hash tree branches have long many advantages, but their key weakness is the long time it takes to generate proofs: Verkle trees can prove more than 100,000 values per second, while hash-based STARKs typically only prove a few k hash per second, and each value needs to contain a long hash “branch”.

Considering the numbers predicted today from hyper-optimized proof systems like Binius and Plonky3, as well as proprietary hashes like Vision-Mark-32, it seems like we’ll be in a practical range for some time where proving 1000 values per second is feasible, but proving 14,285 values is not. The average block would be fine, but the potentially worst-case Block (published by an attacker) would disrupt the network.

Our default approach to handling such cases is to reprice: increase the cost of storing reads to reduce the maximum per block to a more secure level. However, we’ve done this long times, and if we do it again, it would make too long app too expensive. A better approach is longing gas: limit and charge storage access separately, keeping average usage at 1,000 storage visits per block, but setting an upper limit per block, such as 2000.

The ubiquity of longest gas

Another resource worth considering is state size rising: operations that increase the state size of Ethereum, which then need to be saved by a full node. The state size rises is unique in that the rationale for limiting it comes solely from long-term sustained use, not peaks.

Therefore, it may be valuable to add a separate gas dimension for operations that increase the size of the state (e.g., zero-to-nonzero SSTORE, contract creation), but the goal is different: we can set a floating price to long wick candle on a specific average usage, but not set a per-Block limit at all.

This demonstrates a powerful property of long-dimensional gas: it allows us to long wick candle each resource separately and ask (i) what is the ideal average usage long less? (ii) What is the maximum safe usage per Block long small? Instead of setting the gas price based on the maximum value of each block and letting the average usage follow, we have 2n degrees of freedom to set 2n parameters, adjusting each parameter according to network security considerations.

More complex cases, such as when the security considerations of two resources are partially summed, can be handled by making a Operation Code or resource consume a certain amount of long type of gas (e.g., a zero-to-nonzero SSTORE might consume 5,000 stateless client attestation gas and 20,000 storage expansion gas).

Max per transaction (the one that consumes more data or calculations)

Let x1 be the gas cost of the data and x2 be the calculated gas cost, so in a one-dimensional gas system we can write the gas cost of a transaction:

Vitalik新作:什么是多维Gas定价?

In this scenario, we define the gas cost of the transaction as:

Vitalik新作:什么是多维Gas定价?

That is, a transaction is not charged based on data plus calculations, but on which of the two resources it consumes longest. This can be easily extended to cover more long dimensions (e.g. max(…,x3∗storage_access)).

It should be easy to see how this can increase throughput while maintaining security. Theoretically, the maximum amount of data in a block is still GasLIMIT/x1, which is exactly the same as in the one-dimensional gas scheme. Similarly, the theoretical maximum amount of computation is GasLIMIT/x2, which is exactly the same as in a one-dimensional gas scheme. However, the gas cost of any transaction that consumes data and calculations drops.

This is presumably the scheme adopted in the proposed EIP-7623 to reduce the maximum block size while further increasing the blob count. The precise mechanism in EIP-7623 is a little more complicated: it keeps the current calldata price at 16 gas per byte, but adds a floor price of 48 gas per byte; The greater of the transaction payment (16 * bytes + ution_Gas) and (48 * bytes). As a result, EIP-7623 reduces the theoretical maximum transaction call data in a block from about 1.9 MB to about 0.6 MB, while keeping the cost unchanged for longest applications. The benefit of this approach is that it changes very little compared to the current one-dimensional gas scheme, making it very easy to implement.

However, there are two drawbacks to this approach:

  1. Even if all other transactions in the block use only a small amount of that resource, transactions that occupy a large amount of one resource will still charge a large fee unnecessarily;

  2. It incentivizes data-intensive and compute-intensive transactions to merge into a single bundle to save costs.

In my opinion, a rule like EIP-7623, whether for trading calldata or other resources, can be of great enough benefit that even with these drawbacks, it is worth it.

However, if we are willing to put in (significantly higher) development efforts, a more desirable approach will emerge.

Longest EIP-1559: A more difficult but desirable strategy

Let’s start by reviewing how regular EIP-1559 works. We’ll focus on the version introduced by the long wick candle blob in EIP-4844 because it’s mathematically more elegant.

We keep track of one parameter, excess_blobs. During each block, we set:

excess_blobs <-- max(excess_blobs + len(block.blobs) - TARGET, 0)

where TARGET = 3. That is, if the number of blobs in a Block is long than the target, the excess_blobs increases, and if the number of blobs in a Block is less than the target, the excess_blobs decreases. Then we set blob_basefee = exp(excess_blobs / 25.47), where exp is an approximation of the exponential function exp(x)=2.71828^x.

Vitalik新作:什么是多维Gas定价?

That is, whenever the excess_blobs increases by about 25, the blob base charge increases by about 2.7x. If the blob becomes too expensive, the average usage drops and the excess_blobs starts to decrease, automatically drop the price again. The price of blobs is constantly adjusted to ensure that, on average, the Block is half full, that is, each Block contains an average of 3 blobs.

If there is a short-term spike in usage, there is a limit: each Block can only contain 6 blobs at a maximum long, in which case transactions can compete with each other by increasing the priority fee. However, under normal circumstances, each blob only pays blob_basefee plus a small additional priority fee as an incentive to be included.

This gas pricing has been around in Ethereum for longest: back in 2020, EIP-1559 introduced a very similar mechanism. With EIP-4844, we set two separate floating prices for Gas and Blobs.

Vitalik新作:什么是多维Gas定价?

Note: The base gas charge for one hour on May 8, 2024, in gwei. Source: ultrasound.money

In principle, we could add more long independent floating fees for storage reads and other types of operations, but I’ll elaborate on one issue in the next section.

For users, the experience is very similar to today: instead of paying one basefee, you pay two basic fees, but your wallet can abstract it out of your hands, showing you only the expected and maximum fees you can expect to pay.

Block builders, longest of the time, the best strategy is the same as it is today: include anything that works. Longest Blocks Are Not Full - Gas or Blobs. A challenging situation is that when there is enough gas or enough blobs to exceed the block limit, builders need to potentially solve the longest knapsack problem to maximize their profits. However, even if there is a fairly good approximation Algorithm, in this case, the gain from optimizing profits by formulating proprietary Algorithm is long smaller than the gain from doing the same with MEV.

The main challenge for developers is the need to redesign the functionality of the EVM and its associated infrastructure, which were currently designed based on a single price and a single limit, and now need to be retrofitted to accommodate longest prices and longest limitations.

One problem that application developers face is that optimization becomes slightly more difficult: in some cases, you can no longer explicitly say that A is more efficient than B, because if A uses a more long calldata and B uses a more long execution, then when calldata is cheaper, it is more expensive when calldata is expensive.

One problem that app developers face is that optimization becomes slightly more difficult: in some cases, you can’t definitively say that A is more efficient than B, because if A uses a more long calldata and B uses a more long execution, then A may be cheaper when calldata is cheap, and A may be more expensive when calldata is expensive.

However, developers can still get pretty good results by optimizing based on long-term historical average prices.

Longest pricing, EVM, and sub-calls

There’s a problem that doesn’t appear in blobs, nor does it appear in EIP-7623 or even the full longest pricing implementation of long wick candles for calldata, but if we try to price state access or any other resource separately, then this problem arises: the gas limit in sub-calls.

Gas limits in EVM exist in two places. First, each transaction sets a gas limit, which limits the total amount of gas that can be used in that transaction. Second, when one contract calls another, that call can set its own gas limit. This allows contracts to call other contracts they don’t trust, and still guarantees that they still have residual gas to perform other calculations after the call.

Vitalik新作:什么是多维Gas定价?

Note: Traces of account abstraction transactions where one account calls another account and only a limited amount of gas is provided to the callee to ensure that the external call continues to run even if the callee consumes all the gas allocated to it.

The challenge is that getting longest gas between different types of execution seems to require subcalls to provide longest limits for each type of gas, which would require very deep changes to the EVM and would not be compatible with existing applications.

This is one of the reasons why longest gas proposals typically stay in two dimensions: data and execution. Data, whether transactional calldata or blobs, is only distributed outside of the EVM, so nothing needs to change inside the EVM for calldata or blobs to be priced separately.

We can come up with an “EIP-7623-style solution” to solve this problem. This is a simple implementation: during execution, the storage operation is charged 4 times the fee; To simplify the analysis, let’s assume 10,000 gases per storage operation. At the end of the transaction, the min(7500 * storage_operations, ution_Gas) is refunded. As a result, after deducting the refund, the user is required to pay the following fees:

ution_Gas + 10000 * storage_operations - min(7500 * storage_operations, ution_Gas)

This equals:

max(ution_Gas + 2500 * storage_operations, 10000 * storage_operations)

This mirrors the structure of EIP-7623. Another approach is to track storage_operations and ution_Gas in real time and charge 2500 or 10000 less depending on the max(ution_Gas + 2500 * storage_operations, 10000 * storage_operations) at pump long the time. The Operation Code is called. This avoids the need for transactions to over-allocate gas, which is mostly recouped through refunds.

We don’t have fine-grained licensing for subcalls: subcalls can consume all of the transaction’s allowances for cheap storage operations.

But we do get something good enough that the contract that makes the sub-call can set a limit and ensure that once the sub-call is executed, the main call still has enough gas for the required post-processing.

The simplest “complete longest pricing solution” I can think of is this: we treat the sub-call gas limit as proportional. That is, suppose there are k different execution types, and each transaction is set with a longest limit L1… 𝐿𝑘 。 Suppose that at the current execution point, the remaining gas is g1… Gk. Suppose you call the CALL Operation Code and use the sub-call Gas to limit S. Let s1=S, then s2=s1/g1∗g2, s3=s1/g1∗g3, and so on.

That is, we treat the first type of gas (which is actually VM execution) as a special “account unit” and then allocate other types of gas so that the subcall gets the same percentage of available gas in each type of gas. This approach is a bit ugly and maximizes backward compatibility.

If we want to make the scheme more “neutral” between different types of gas without sacrificing backward compatibility, we can simply represent the gas limit parameter of the child call as part of the remaining gas in the current context (e.g., [1…63]/64).

In either case, however, it’s worth emphasizing that once you start introducing longest execution gas, the inherent complexity (ugliness) increases, which seems hard to avoid.

So our task is to make a complex trade-off: do we accept some level of ugliness increase at the EVM level to safely unlock significant L1 scalability gains, and if so, which specific proposal will be most effective for protocol economics and application developers? Chances are, neither of the two options I’ve mentioned above is the best, but there’s still shorts to come up with more elegant and better solutions.

Special thanks to Ansgar Dietrichs, Barnabe Monnot, and Davide Crapis for their feedback and review.

View Original
This page may contain third-party content, which is provided for information purposes only (not representations/warranties) and should not be considered as an endorsement of its views by Gate, nor as financial or professional advice. See Disclaimer for details.
  • Reward
  • 1
  • Repost
  • Share
Comment
0/400
No comments
  • Pin
Trade Crypto Anywhere Anytime
qrCode
Scan to download Gate App
Community
  • 简体中文
  • English
  • Tiếng Việt
  • 繁體中文
  • Español
  • Русский
  • Français (Afrique)
  • Português (Portugal)
  • Bahasa Indonesia
  • 日本語
  • بالعربية
  • Українська
  • Português (Brasil)