Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Eip1559 updates #2505

Merged
merged 5 commits into from
Mar 12, 2020
Merged
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
96 changes: 75 additions & 21 deletions EIPS/eip-1559.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
eip: 1559
title: Fee market change for ETH 1.0 chain
author: Vitalik Buterin (@vbuterin), Eric Conner (@econoar)
author: Vitalik Buterin (@vbuterin), Eric Conner (@econoar), Rick Dudley (@AFDudley), Matthew Slipper (@mslipper), Ian Norden (@i-norden)
discussions-to: https://ethereum-magicians.org/t/eip-1559-fee-market-change-for-eth-1-0-chain/2783
status: Draft
type: Standards Track
Expand All @@ -17,11 +17,13 @@ The current "first price auction" fee model in Ethereum is inefficient and needl

## Abstract
<!--A short (~200 word) description of the technical issue being addressed.-->
There is a BASEFEE value in protocol, which can move up or down by a maximum of 1/8 in each block; initially, miners adjust this value to target an average gas usage of 8 million, increasing BASEFEE if usage is higher and decreasing it if usage is lower. Transaction senders specify their fees by providing two values:
There is a base fee value in protocol, which can move up or down by a maximum of 1/8 in each block; initially, miners adjust this value to target an average gas usage of 10 million, increasing base fee if usage is higher and decreasing it if usage is lower. Transaction senders specify their fees by providing two values:

* A "premium" gasprice which gets added onto the BASEFEE gasprice, which can either be set to a fairly low value (eg. 1 gwei) to compensate miners for uncle rate risk or to a high value to compete during sudden bursts of activity. The BASEFEE gets burned, the premium is given to the miner.
* A gas premium which gets added onto the base fee to calculate the gas price. The gas premium can either be set to a fairly low value (eg. 1 gwei) to compensate miners for uncle rate risk or to a high value to compete during sudden bursts of activity. The base fee gets burned, the gas premium is given to the miner.

* A "cap" which represents the maximum total that the transaction sender would be willing to pay to get included.
* A fee cap which represents the maximum total (base fee + gas premium) that the transaction sender would be willing to pay to get their transaction included.

The current miner-voting based gas limit is changed to a hard-coded gas limit of 16 million. Instead of miners directly adjusting the gas limit in response to changes in network demand they adjust the base fee to apply economic pressure towards a target gas usage of 10 million.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This reads like miners still have control of the parameter. If I'm right in thinking they don't it would be clearer to say "the protocol adjusts the gas limit" or "the gas limit is adjusted".

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree, thanks for pointing this out! I've updated it to hopefully be more clear.


## Motivation
<!--The motivation is critical for EIPs that want to change the Ethereum protocol. It should clearly explain why the existing protocol specification is inadequate to address the problem that the EIP solves. EIP submissions without sufficient motivation may be rejected outright.-->
Expand All @@ -32,34 +34,61 @@ Ethereum currently prices transaction fees using a simple auction mechanism, whe
* **Inefficiencies of first price auctions**: see https://ethresear.ch/t/first-and-second-price-auctions-and-improved-transaction-fee-markets/2410 for a detailed writeup. In short, the current approach, where transaction senders publish a transaction with a fee, miners choose the highest-paying transactions, and everyone pays what they bid, is well-known in mechanism design literature to be highly inefficient, and so complex fee estimation algorithms are required, and even these algorithms often end up not working very well, leading to frequent fee overpayment. See also https://blog.bitgo.com/the-challenges-of-bitcoin-transaction-fee-estimation-e47a64a61c72 for a Bitcoin core developer's description of the challenges involved in fee estimation in the status quo.
* **Instability of blockchains with no block reward**: in the long run, blockchains where there is no issuance (including Bitcoin and Zcash) at present intend to switch to rewarding miners entirely through transaction fees. However, there are [known results](http://randomwalker.info/publications/mining_CCS.pdf) showing that this likely leads to a lot of instability, incentivizing mining "sister blocks" that steal transaction fees, opening up much stronger selfish mining attack vectors, and more. There is at present no good mitigation for this.

The proposal in this EIP is to start with a BASEFEE amount which is adjusted up and down by the protocol based on how congested the network is. To accommodate this system, the network capacity would be increased to 16 million gas, so that 50% utilization matches up with our current 8 million gas limit. Then, when the network is at >50% capacity, the BASEFEE increments up slightly and when capacity is at <50%, it decrements down slightly. Because these increments are constrained, the maximum difference in BASEFEE from block to block is predictable. This then allows wallets to auto-set the gas fees for users in a highly reliable fashion. It is expected that most users will not have to manually adjust gas fees, even in periods of high network activity. For most users, the BASEFEE will be automatically set by their wallet, along with the addition of a small fixed amount, called a ‘tip’, to compensate miners (e.g. 0.5 gwei).
The proposal in this EIP is to start with a base fee amount which is adjusted up and down by the protocol based on how congested the network is. To accommodate this system, the total network capacity would be increased to 16 million gas. When the network exceeds the target 10 million gas usage, the base fee increments up slightly and when capacity is below the target, it decrements down slightly. Because these increments are constrained, the maximum difference in base fee from block to block is predictable. This then allows wallets to auto-set the gas fees for users in a highly reliable fashion. It is expected that most users will not have to manually adjust gas fees, even in periods of high network activity. For most users post 1559 implementation the base fee will be estimated by their wallet and a small gas premium- which acts as a 'tip' to compensate miners (e.g. 0.5 gwei)- will be automatically set. Users can also manually set the transaction fee cap to bound their total costs.

An important aspect of this upgraded fee system is that miners only get to keep the tips. The base fee is always burned (i.e. it is destroyed by the protocol). Burning this is important because it prevents miners from manipulating the fee in order to extract more fees from users. It also ensures that only ETH can ever be used to pay for transactions on Ethereum, cementing the economic value of ETH within the Ethereum platform. Additionally, this burn counterbalances Ethereum inflation without greatly diminishing miner rewards.

An important aspect of this upgraded fee system is that miners only get to keep the tips. The BASEFEE is always burned (i.e. it is destroyed by the protocol). Burning this is important because it prevents miners from manipulating the fee in order to extract more fees from users. It also ensures that only ETH can ever be used to pay for transactions on Ethereum, cementing the economic value of ETH within the Ethereum platform.
The transition to this gas price system will occur in two phases, in the first phase both legacy and EIP1559 transactions will be accepted by the protocol. Over the course of this first phase the amount of gas available for processing legacy transactions will decrease while the amount of gas available for processing EIP1559 transactions will increase, moving gas from the legacy pool into the EIP1559 pool until the legacy pool is depleted and the EIP1559 pool contains the entire gas maximum. After all of the gas has transitioned to the EIP1559 pool, the second- finalized- phase is entered and legacy transactions will no longer be accepted on the network.


## Specification
<!--The technical specification should describe the syntax and semantics of any new feature. The specification should be detailed enough to allow competing, interoperable implementations for any of the current Ethereum platforms (go-ethereum, parity, cpp-ethereum, ethereumj, ethereumjs, and [others](https://github.com/ethereum/wiki/wiki/Clients)).-->
**Parameters**
* `FORK_BLKNUM`: TBD
* `INITIAL_FORK_BLKNUM`: TBD
* `BASEFEE_MAX_CHANGE_DENOMINATOR`: 8
* `SLACK_COEFFICIENT`: 3
* `TARGET_GASUSED`: 8,000,000
* `TARGET_GAS_USED`: 10,000,000
* `MAX_GAS_EIP1559`: 16,000,000
* `FINAL_FORK_BLKNUM`: `INITIAL_FORK_BLKNUM + (MAX_GAS_EIP1559 / (10 * SLACK_COEFFICIENT))`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Slack coefficient was removed, but is still used here.

Also, why a slack coefficient of only 1.6?

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

gogo I want to see ethereum at #1

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry I missed this comment when it was made.

I've removed any mention of the slack coefficient from the doc, as it had already been removed from the implementation.

The slack coefficient was never being used for anything other than as the scalar that described the ratio between max gas used and target gas used. It was 2 when target gas used was 8m and max gas used was 16m, but after switching to a target gas used of 10m it became 1.6.

* `EIP1559_GAS_INCREMENT_AMOUNT`: `(MAX_GAS_EIP1559 / 2) / (FINAL_FORK_BLKNUM - INITIAL_FORK_BLKNUM)`
* `INITIAL_BASEFEE` : 1,000,000,000 wei (1 gwei)


**Proposal**
For all blocks where `block.number >= FORK_BLKNUM`:

* Impose a hard in-protocol gas limit of `SLACK_COEFFICIENT * TARGET_GASUSED`, used instead of the gas limit calculated using the previously existing formulas
* Replace the `GASLIMIT` field in the block header with a BASEFEE field (the same field can be used)
* Let `PARENT_BASEFEE` be the parent block's `BASEFEE` (or 1 billion wei if `block.number == FORK_BLKNUM`). A valid `BASEFEE` is one such that `abs(BASEFEE - PARENT_BASEFEE) <= max(1, PARENT_BASEFEE // BASEFEE_MAX_CHANGE_DENOMINATOR)`
* Redefine the way the `tx.gasprice` field is used: define `tx.fee_premium = tx.gasprice // 2**128` and `tx.fee_cap = tx.gasprice % 2**128`
* During transaction execution, we calculate the cost to the `tx.origin` and the gain to the `block.coinbase` as follows:
* Let `gasprice = min(BASEFEE + tx.fee_premium, tx.fee_cap)`. The `tx.origin` initially pays `gasprice * tx.gas`, and gets refunded `gasprice * (tx.gas - gasused)`.
* The `block.coinbase` gains `(gasprice - BASEFEE) * gasused`. If `gasprice < BASEFEE` (due to the `fee_cap`), this means that the `block.coinbase` _loses_ funds from this operation; in this case, check that the post-balance is non-negative and throw an exception if it is negative.
As a default strategy, miners set `BASEFEE` as follows. Let `delta = block.gas_used - TARGET_GASUSED` (possibly negative). Set `BASEFEE = PARENT_BASEFEE + PARENT_BASEFEE * delta // TARGET_GASUSED // BASEFEE_MAX_CHANGE_DENOMINATOR`, clamping this result inside of the allowable bounds if needed (with the parameter setting above clamping will not be required).
For all blocks where `block.number >= INITIAL_FORK_BLKNUM`:

For the gas limit:

* `MAX_GAS_EIP1559` acts as the hard in-protocol gas limit, instead of the gas limit calculated using the previously existing formulas
* The `GASLIMIT` field in the block header is the gas limit for the EIP1559 gas pool, and over the transition period this value increases until it reaches `MAX_GAS_EIP1559` at `FINAL_FORK_BLKNUM`
* The gas limit for the legacy gas pool is `MAX_GAS_EIP1559 - GASLIMIT`, as `GASLIMIT` increases towards `MAX_GAS_EIP1559` gas is moved from the legacy pool into the EIP1559 pool until all of the gas is in the EIP1559 pool
* At `block.number == INITIAL_FORK_BLKNUM`, let `GASLIMIT = (MAX_GAS_EIP1559 / 2)` so that the gas maximum is split evenly between the legacy and EIP1559 gas pools
* As `block.number` increases towards `FINAL_FORK_BLKNUM`, at every block we shift `EIP1559_GAS_INCREMENT_AMOUNT` from the legacy pool into the EIP1559 gas pool
* At `block.number >= FINAL_FORK_BLKNUM` the entire `MAX_GAS_EIP1559` is assigned to the EIP1559 gas pool and the legacy pool is empty
* We enforce a per-transaction gas limit of 8,000,000.``
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

8,000,000 should be a parameter, no?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, thanks! It is a parameter in the implementation, but I didn't reflect that here. Will update. Although it looks like there is some more discussion about what the per-transaction gas limit should in the magicians thread: https://ethereum-magicians.org/t/eip-1559-go-ethereum-implementation/3918/15?u=i-norden


For the gas price:

* We add a new field to the block header, `BASEFEE`
* `BASEFEE` is maintained under consensus by the ethash engine
* At `block.number == INITIAL_FORK_BLKNUM` we set `BASEFEE = INITIAL_BASEFEE`
* As a default strategy, miners set `BASEFEE` as follows.
* Let `delta = block.gas_used - TARGET_GASUSED` (possibly negative).
* Set `BASEFEE = PARENT_BASEFEE + PARENT_BASEFEE * delta // TARGET_GASUSED // BASEFEE_MAX_CHANGE_DENOMINATOR`
* Clamp the resulting `BASEFEE` inside of the allowable bounds if needed, where a valid `BASEFEE` is one such that `abs(BASEFEE - PARENT_BASEFEE) <= max(1, PARENT_BASEFEE // BASEFEE_MAX_CHANGE_DENOMINATOR)`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are we letting miners adjust the basefee? I thought we are forcing the specific change in the protocol?

Copy link
Contributor Author

@i-norden i-norden Feb 4, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I haven't had the time to thoroughly model the BASEFEE function, but in my limited experimentation there were scenarios where the specific change enforced by the protocol would result in a BASEFEE that falls out of the bounds described above. In that case the result is clamped down to those bounds.

I will update all the references to "miners adjusting/setting BASEFEE" to reflect it being the protocol. I think this is a bit of semantic misunderstanding on my part, in my eyes the miners are still "setting" the BASEFEE in the blocks they mine, even if they have no control over what that set value is.

Copy link
Contributor

@vbuterin vbuterin Mar 24, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe to avoid simplicity reword this as:

  • Let gas_delta = block.gas_used - TARGET_GASUSED (possibly negative).
  • Let basefee_delta = PARENT_BASEFEE * gas_delta // TARGET_GASUSED // BASEFEE_MAX_CHANGE_DENOMINATOR
  • Let max_basefee_delta = max(1, PARENT_BASEFEE // BASEFEE_MAX_CHANGE_DENOMINATOR)
  • Set BASEFEE = PARENT_BASEFEE + max(-max_basefee_delta, min(max_basefee_delta, basefee_delta))

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, it's also important to specify cleanly what we mean by // in the negative case. Is -7 // 5 equal to -1 or -2? In python it's the latter, in some languages it's the former. Perhaps avoid negative numbers entirely?

  • Let max_basefee_delta = max(1, PARENT_BASEFEE // BASEFEE_MAX_CHANGE_DENOMINATOR)
  • If block.gas_used >= TARGET_GASUSED:
    • Let gas_delta = block.gas_used - TARGET_GASUSED
    • Let basefee_delta = PARENT_BASEFEE * gas_delta // TARGET_GASUSED // BASEFEE_MAX_CHANGE_DENOMINATOR
    • Set BASEFEE = PARENT_BASEFEE + min(max_basefee_delta, basefee_delta)
  • block.gas_used < TARGET_GASUSED:
    • Let gas_delta = TARGET_GASUSED - block.gas_used
    • Let basefee_delta = PARENT_BASEFEE * gas_delta // TARGET_GASUSED // BASEFEE_MAX_CHANGE_DENOMINATOR
    • Set BASEFEE = max(0, PARENT_BASEFEE - min(max_basefee_delta, basefee_delta))

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a great point, we are using big.Int division which is true Euclidean division where the remainder is bound above 0 so we round to negative infinity and would get -2. We can make that the specification, or avoid negative numbers entirely. What do you think is best?

* We add two new fields to transactions: `GAS_PREMIUM` and `FEECAP`
* During the transition phase, these fields can be left `nil` and a `tx.gas_price` can be set as usual to generate a backwards compatible legacy transaction
* To produce an EIP1559 transactions, `tx.gas_price` is set to `nil` while the new `GAS_PREMIUM` and `FEECAP` fields are set whereby:
* `GAS_PREMIUM` serves as a "tip" to the miner
* `FEECAP` serves as the absolute maximum that the transaction sender is willing to pay
* During transaction execution, for EIP1559 transactions we calculate the cost to the `tx.origin` and the gain to the `block.coinbase` as follows:
* Set `GASPRICE = min(BASEFEE + tx.GasPremium, tx.fee_cap)`
* Let `GASUSED` be the gas used during the transaction execution/state transition
* The `tx.origin` initially pays `GASPRICE * tx.gas`, and gets refunded `GASPRICE * (tx.gas - GASUSED)`
* The `block.coinbase` gains `(GASPRICE - BASEFEE) * GASUSED`.
* If `GASPRICE < BASEFEE` (due to the `FEECAP`), this means that the `block.coinbase` _loses_ funds from this operation; in this case, we check that the post-balance is non-negative and throw an exception if it is negative.

## Backwards Compatibility
Transactions published before this EIP or by wallets that do not support this EIP will be interpreted by the above formulas as having a `fee_premium` of zero and a `fee_cap` of the fee that they submit. Provided that at least some miners are temporarily willing to be altruistic and accept zero-fee-premium transactions for a short period of time after the fork, this should not greatly affect usability. There is an invariant that a `gasprice` constructed "the old way" still constitutes an upper bound on the amount that a user will pay.
We split the EIP1559 upgrade into two phases with a transition period during which both legacy and EIP1559 transaction can be accepted so that compatibility with wallets and other ETH-adjacent software is maintained while their maintainers have time to upgrade to using the new transaction type. During this transition period legacy transactions are accepted and processed identically to the current implementation, with the only difference being that the amount of gas (gas limit) dedicated to processing legacy transactions is calculated as above and incrementally decreases over this period.


## Test Cases
Expand All @@ -68,7 +97,32 @@ Transactions published before this EIP or by wallets that do not support this EI

## Implementation
<!--The implementations must be completed before any EIP is given status "Final", but it need not be completed before the EIP is accepted. While there is merit to the approach of reaching consensus on the specification and rationale before writing code, the principle of "rough consensus and running code" is still useful when it comes to resolving many discussions of API details.-->

Go-ethereum implementation by Vulcanize Inc: https://github.com/vulcanize/go-ethereum-EIP1559

## Security Considerations
<!--All EIPs must contain a section that discusses the security implications/considerations relevant to the proposed change. Include information that might be important for security discussions, surfaces risks and can be used throughout the life cycle of the proposal. E.g. include security-relevant design decisions, concerns, important discussions, implementation-specific guidance and pitfalls, an outline of threats and risks and how they are being addressed. EIP submissions missing the "Security Considerations" section will be rejected. An EIP cannot proceed to status "Final" without a Security Considerations discussion deemed sufficient by the reviewers.-->
The security considerations for this EIP are:
1. The consequences of raising the gas limit
* This concern was brought up [here](https://ethereum-magicians.org/t/eip-1559-fee-market-change-for-eth-1-0-chain/2783/45)
* This EIP currently proposes to raise the total gas limit from 8,000,000 to 16,000,000
2. The consequences of the new gas pricing on total transaction order
* This concern was brought up [here](https://ethereum-magicians.org/t/eip-1559-fee-market-change-for-eth-1-0-chain/2783/45)
* This issue is avoided by maintaining a single total ordering of transactions by price and nonce, where the derived EIP1559 gas price is used like the legacy gas price
3. The effects on miner incentives
* This concern was brought up [here](https://ethereum-magicians.org/t/eip-1559-fee-market-change-for-eth-1-0-chain/2783/15)
* This concern is addressed [here](https://ethereum-magicians.org/t/eip-1559-fee-market-change-for-eth-1-0-chain/2783/16)
4. Concerns of BASEFEE manipulation
* This concern was brought up [here](https://ethereum-magicians.org/t/eip-1559-fee-market-change-for-eth-1-0-chain/2783/50)
* To avoid this, the BASEFEE is included as part of the header structure and is maintained under consensus by the ethash engine
5. Implications of BASEFEE burning on proposals to cap the total ether supply (e.g. EIP-960).
* This concern was brought up [here](https://ethereum-magicians.org/t/eip-1559-fee-market-change-for-eth-1-0-chain/2783/13)

## Resources
* [Call notes](https://github.com/ethereum/pm/blob/master/All%20Core%20Devs%20Meetings/Meeting%2077.md)
* [Original Magicians thread](https://ethereum-magicians.org/t/eip-1559-fee-market-change-for-eth-1-0-chain/2783)
* [Ethresear.ch Post w/ Vitalik’s Paper](https://ethresear.ch/t/draft-position-paper-on-resource-pricing/2838)
* [Go-ethereum implementation](https://github.com/vulcanize/go-ethereum-EIP1559)
* [Implementation-specific Magicians thread](https://ethereum-magicians.org/t/eip-1559-go-etheruem-implementation/3918)

## Copyright
Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).