Skip to content

core: implement EIP-8037, state creation gas cost increase#33601

Open
MariusVanDerWijden wants to merge 5 commits into
ethereum:masterfrom
MariusVanDerWijden:eip-8037
Open

core: implement EIP-8037, state creation gas cost increase#33601
MariusVanDerWijden wants to merge 5 commits into
ethereum:masterfrom
MariusVanDerWijden:eip-8037

Conversation

@MariusVanDerWijden
Copy link
Copy Markdown
Member

Implements https://eips.ethereum.org/EIPS/eip-8037
mainly done in order to judge the complexity of the EIP
and to act as a jumping off point, since the eip will likely
change.

Comment thread core/state_transition.go Outdated
Comment thread core/state_transition.go
Comment thread core/vm/instructions.go
Comment thread core/gaspool.go Outdated
Comment thread core/state_transition.go Outdated
Comment thread core/vm/operations_acl.go
return GasCosts{}, ErrGasUintOverflow
}
return totalCost, nil
return GasCosts{RegularGas: totalCost}, nil
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

We should return the stateGas explicitly in the return and add the pre-deducted value back?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I think there was a reason why I did it this way. The ordering when we charge state gas and when we charge regular gas matters

Comment thread core/vm/evm.go Outdated
// the necessary steps to create accounts and reverses the state in case of an
// execution error or failed value transfer.
func (evm *EVM) Call(caller common.Address, addr common.Address, input []byte, gas uint64, value *uint256.Int) (ret []byte, leftOverGas uint64, err error) {
func (evm *EVM) Call(caller common.Address, addr common.Address, input []byte, gas GasCosts, value *uint256.Int) (ret []byte, leftOverGas GasCosts, gasUsed GasUsed, err error) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Nitpick, It will be much more readable if:

(1) change gas to gasBudget
(2) change leftOverGas to gasBudget

and I am wondering if it's feasible/makesense to change to gasBudget as the pointer, so that the leftOverGas can be eliminated.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I tried it, but its not great. Neither for readability nor useability
I would prefer not to do it

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Is the gasBudget idea bad for readability or the pointer idea is bad, or both of them :)

Comment thread core/vm/evm.go Outdated
Comment thread core/vm/evm.go Outdated
Comment thread core/vm/instructions.go Outdated
Comment thread core/vm/gas_table.go Outdated
return GasCosts{}, err
}
evm.callGasTemp, err = callGas(evm.chainRules.IsEIP150, contract.Gas.RegularGas, intrinsic.RegularGas, stack.Back(0))
evm.callGasTemp, err = callGas(evm.chainRules.IsEIP150, contract.Gas.RegularGas, intrinsic, stack.Back(0))
Copy link
Copy Markdown
Member

@rjl493456442 rjl493456442 Apr 22, 2026

Choose a reason for hiding this comment

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

The semantics here is ambiguous. It should be

  • intrinsicFunc should return a vector of gas cost, including both regular and state gas cost
  • the remaining regular gas should be calculated after deducting the intrinsic cost
  • the 63/64 rule should be applied on the regular gas only
  • the regular gas budget for child frame should then be capped by the user-specified amount

Comment thread core/vm/gas_table.go
Comment thread core/vm/operations_acl.go Outdated
}

// Compute and charge state gas (new account creation) AFTER regular gas.
stateGas, err := stateGasFunc(evm, contract, stack, mem, memorySize)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I am not sure if the stateGasFunc is necessary. In the EIP-7702 check, the state access already happens evm.StateDB.GetCode(addr). The gas metering reordering becomes moot.

Comment thread core/state_transition.go Outdated
// When the calldata floor exceeds actual gas used, any
// remaining state gas must also be consumed.
targetRemaining := (st.initialBudget.RegularGas + st.initialBudget.StateGas) - floorDataGas
st.gasRemaining.StateGas = 0
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

It looks very weird to empties the state gas.

In theory, if there are some state gas left, we should deduct from the regular gas first for floor cost cap.

I guess in this case, we only care about the sum of leftover regular gas and state gas for ether refund (to sender).

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Needs to be checked against spec

Comment thread core/state_transition.go Outdated
fee.Mul(fee, effectiveTipU256)

// always read the coinbase account to include it in the BAL (TODO check this is actually part of the spec)
st.state.GetBalance(st.evm.Context.Coinbase)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

AddBalance will also touch the account regardless of the amount to be collected

Comment thread core/state_transition.go
Comment thread core/state_transition.go Outdated
if subGasAmount > cost.StateGas {
subGasAmount -= cost.StateGas
} else {
subGasAmount = 0
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

error?

Comment thread core/state_transition.go
Comment thread core/state_transition.go Outdated
Comment thread core/state_transition.go Outdated
Comment thread core/state_transition.go Outdated
// exceeded the intrinsic-charged state gas
txState := cost.StateGas
if execGasUsed.StateGas > 0 {
txState += uint64(execGasUsed.StateGas)
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Can we go lower than intrinsic gas here? We should theoretically do that. Check spec

Comment thread core/state_transition.go Outdated
Comment thread core/vm/evm.go Outdated
Comment thread core/vm/gas_table.go Outdated
Comment on lines +676 to +678
if !contract.IsSystemCall {
stateGas = params.StorageCreationSize * evm.Context.CostPerGasByte
}
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Spec change?

Comment thread core/vm/contract.go Outdated
Comment thread core/txpool/validation.go
Comment thread core/state/statedb.go Outdated
Comment thread core/state_transition.go Outdated
Comment thread core/vm/gas_table.go
if evm.chainRules.IsEIP150 {
gas = params.SelfdestructGasEIP150
var address = common.Address(stack.back(0).Bytes20())
if gas > contract.Gas.RegularGas {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

@MariusVanDerWijden why do we need to abort the gas calculation with a nil error here?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants