EIP-1559 Go-ethereum implementation

Did you decide to make the basefee adjustment formula “just a suggestion”? I thought we had talked about this and decided to make it hard-coded to prevent miners from being able to individually push the fee up or down by a significant amount by adjusting the formula? Or is there some overriding rationale for making it just a suggestion?

1 Like

Hey @edmundedgar and @vbuterin , thanks for the comments!

@edmundedgar TARGET_GASUSED is a constant that is used in the BASEFEE adjustment formula, it is the amount of gas we target to use and miners adjust the BASEFEE up or down depending on how the actual gas usage deviates from this value. Specifically, miners set a block’s BASEFEE as PARENT_BASEFEE + PARENT_BASEFEE * DELTA // TARGET_GASUSED // BASEFEE_MAX_CHANGE_DENOMINATOR, where DELTA = PARENT_GASUSED - TARGET_GASUSED.

The BASEFEE is maintained under consensus by the ethash engine. In the verifyHeader() method a header is invalidated if the BASEFEE increases or decreases relative to PARENT_BASEFEE more than the allowed amount (PARENT_BASEFEE // BASEFEE_MAX_CHANGE_DENOMINATOR).

@vbuterin per your comment the above is not quite right. I will update the consensus engine so that the exact value from the basefee adjustment formula is enforced, not just an upper and lower bound on the value. The need for this is apparent, currently a miner could change their basefee adjustment algo to submit arbitrary BASEFEEs that are valid so long as they are within the upper and lower limits e.g. they could raise the BASEFEE by as much as PARENT_BASEFEE // BASEFEE_MAX_CHANGE_DENOMINATOR even if PARENT_GASUSED is below TARGET_GASUSED. That’s an oversight on my part, but a simple fix to make. Thank you for pointing it out!

@i-norden Thanks, so to make sure this is clear, the proposal is that TARGET_GASUSED is hard-coded at 8 million and never changed, except by a future hard fork.

1 Like

@edmundedgar that is correct!

Any reason why 8m, and not the current max of 10m? Setting to the current max seems most sensible.

1 Like

Just a thought: It might be worth putting something about the change from miner voting to a hard-coded limit that’s only changed in hard forks in the abstract and the motivation section of the EIP; I think I understand the basic reasons why this is being done from the previous Magicians discussion, but it’s arguably a more significant change than the fee market reform that’s the subject of the EIP.

3 Likes

@vbuterin 8m is left over from when work began on this, before the gas limit increase to 10m. I simply missed that change. Will update to 10m now.

@edmundedgar that is a good point, I will update the EIP doc to be more explicit about this.

Thank you both!

Another change I would recommend is setting a hard per-transaction gas limit of 10m, arguably even set the per-transaction limit to 8m. Don’t want to set the precedent that yuge transactions are possible.

1 Like

@vbuterin added a per-transaction gas limit of 8m as recommended :slight_smile:

1 Like

Just curious, what are the next steps for moving forward with this EIP?

Will your team be presenting the updates to the spec on the Core Dev call tomorrow?

1 Like

Hi @tvanepp! Sorry for the delayed response.

We didn’t make it on the Core Dev call last Friday. The plan of action is to incorporate feedback from here and then move forward by opening a PR for the EIP doc and Go-ethereum implementation. I’ll go ahead and open those PRs at the end of the week if no more changes are recommended/requested here. A more code-focused review can occur on the Go-ethereum PR.

1 Like

Hi all!

The PRs for the EIP doc and for the implementation have been opened. I’ll continue to incorporate feedback received here. Thanks!

3 Likes

I think that we should use the same constant for both GASTLIMIT and this new ‘TXGASLIMIT’, mostly because some smart contracts may assume that they can use the whole block for gas if necessary, this is sometimes used to detect out of gas exceptions on-chain.

@Agusx1211 just to clarify, we should use the 16m MAX_GAS_EIP1559 as the TX_GASLIMIT? Or the 10m TARGET_GAS_USED?

IMO we should use the 16m (or 20m ?) MAX_GAS_EIP1559 as the TX_GASLIMIT

Thanks @Agusx1211! One potential issue with this is that during the transition period during which both legacy and EIP1559 transactions are accepted the MAX_GAS_EIP1559 is split between the two gas pools. For example, at the block that EIP1559 is activated 8m is in the legacy pool and 8m is in the 1559 pool. So a transaction to either pool with gas usage of MAX_GAS_EIP1559 would be rejected. This would be the case until the EIP finalization block is reached and the entire MAX_GAS_EIP1559 is available to the 1559 pool.

Perhaps the TX_GASLIMIT could be set to the portion of MAX_GAS_EIP1559 available for processing that type of transaction at a given blockheight. But that will still cause issue for smart contracts that assume they can use the whole block for gas.

We’ve raised the TARGET_GAS_USED to 10m since that is the current gas limit, but I am hesitant to raise MAX_GAS_EIP1559 to 20m. It was originally set to be 24m, but there were some concerns raised by Péter and in our Core Dev’s call about the ramifications of this (EIP-1559: Fee market change for ETH 1.0 chain).

Wouldn’t smart contracts read that the “whole block” is composed by the “portion of MAX_GAS_EIP1559 available for processing that type of transaction at a given blockheight”?

If opcode 0x45 (GASLIMIT) returns the portion of the block available for processing it should be safe to allow TXs to reach the same limit, in that way we aren’t breaking the two implicit rules of the current chain A) A TX could use the totality of GASLIMIT and B) GASLIMIT can never be below the TX gas

Maybe I am missing the point

1 Like

Opcode 0x45 returns the gas limit value from the block header, after EIP1559 activation this value is the gas limit for the EIP1559 gas pool and the gas limit for the legacy gas pool is equal to MAX_GAS_EIP1559 - this value.

Sorry for the confusion, the issue I brought up in my previous response still exists with where the per-tx gas limit is set right now (8m), e.g. just 1 block after EIP1559 activation the legacy gas pool will have less than 8m gas available for processing transactions.

1 Like

I’m thinking that it might be a good idea to introduce a check for monotonically increasing tx.gasprice in block validation along with this EIP.

While default miner software already orders the transactions of a block according to their gas price, there doesn’t seem to be any checks that miners running custom software adhere to this rule.

The assumption that higher gas price transactions will be executed before low gas price transactions is widespread in developing and interacting with contracts and is the default behaviour of client software. I don’t see any reason it why miners should be given the capability to order transactions as they see fit.

Transaction ordering is a highly sensitive matter, as demonstrated in Flash Boys 2.0 by Phil Daian et. al and I think we should limit miner privileges where we can. I think enforcing tx ordering by gas price would definitely increase the predictability of outcomes here.

1 Like

@MrChico thank you for bringing this up! My initial reaction is that this should be a separate EIP because while EIP1559 potentially exasperates this issue (I’ll get to that at the end) it’s not specific to EIP1559.

There are a few reasons why that assumption is already not safe to make even with standard miners/clients. I apologize and please correct me if I am wrong on any of these points or if I misunderstood you.

  1. Parity has a CLI flag --tx-queue-strategy that lets you customize how your miner prioritizes transactions (this might be for the miner pool only with standard sorting still done before committing, I’m not super familiar with Parity)

  2. Geth sorts and commits local and remote transactions separately, it commits all local transactions before moving to the remotes

  3. Within the local and remote batches the transactions are sorted by nonce and gas price, with nonce taking precedence. More specifically, in NewTransactionsByPriceAndNonce we iterate through a map of addresses to nonce-sorted transactions, taking only the lowest-nonce transaction for each address and adding it to a heap which is sorted by gas price. Transactions are read from the heap here and after they are committed they are replaced with the next lowest nonce transaction for that account and the heap is re-sorted.

E.g. let’s say we have 2 remote accounts A and B

A has three transactions with nonce n and gas price p: A(n:0, p:100), A(n:1, p:200), A(n:2, p:100)
B has three transactions: B(n:0, p:200), B(n:1, p:50), B(n:2, p:400)

And one local account C with a single tx: C(n:0, p:50)

The final ordering (as I understand it) will be: C(n:0, p:50), B(n:0, p:200), A(n:0, p:100), A(n:1, p:200), A(n:2, p:100), B(n:1, p:50), B(n:2, p:400)

As for how EIP1559 relates to this all…

This implementation currently retains the above ordering of transactions using either legacy or EIP1559 gas price. During the transition period during which both legacy and EIP1559 transactions are accepted, since EIP1559_GASPRICE = min(BASE_FEE + GAS_PREMIUM, FEE_CAP) and the BASE_FEE is always burned a miner will be rewarded more for a LEGACY_GASPRICE where LEGACY_GASPRICE < EIP1559_GASPRICE so long as LEGACY_GASPRICE > GAS_PREMIUM or LEGACY_GASPRICE > FEE_CAP - BASE_FEE if FEE_CAP < BASE_FEE + GAS_PREMIUM.

We can prescribe a new ordering based on LEGACY_GASPRICE and GAS_PREMIUM or FEE_CAP - BASE_FEE instead, that would remove the new incentive but then the standard itself would no longer be to order by gas price as it does now. The other way would be what you recommend and include tx ordering under consensus :slight_smile:

Curious what other people’s thoughts are. I can bring this up at the Core Dev’s call this Friday.