diff --git a/core/gaspool.go b/core/gaspool.go index 1e8b57fd11..690882c7b1 100644 --- a/core/gaspool.go +++ b/core/gaspool.go @@ -36,7 +36,6 @@ type GasPool struct { // NewGasPool initializes the gasPool with the given amount. func NewGasPool(amount uint64) *GasPool { - fmt.Printf("DEBUG_POOL NewGasPool: amount=%d\n", amount) return &GasPool{ remaining: amount, initial: amount, @@ -46,7 +45,6 @@ func NewGasPool(amount uint64) *GasPool { // SubGas deducts the given amount from the pool if enough gas is // available and returns an error otherwise. func (gp *GasPool) SubGas(amount uint64) error { - fmt.Printf("DEBUG_POOL SubGas: before_remaining=%d amount=%d initial=%d\n", gp.remaining, amount, gp.initial) if gp.remaining < amount { return ErrGasLimitReached } @@ -57,8 +55,6 @@ func (gp *GasPool) SubGas(amount uint64) error { // ReturnGas adds the refunded gas back to the pool and updates // the cumulative gas usage accordingly. func (gp *GasPool) ReturnGas(returned uint64, gasUsed uint64) error { - fmt.Printf("DEBUG_POOL ReturnGas: before_remaining=%d returned=%d gasUsed=%d initial=%d cumR=%d cumS=%d\n", - gp.remaining, returned, gasUsed, gp.initial, gp.cumulativeRegular, gp.cumulativeState) if gp.remaining > math.MaxUint64-returned { return fmt.Errorf("%w: remaining: %d, returned: %d", ErrGasLimitOverflow, gp.remaining, returned) } @@ -77,6 +73,21 @@ func (gp *GasPool) ReturnGas(returned uint64, gasUsed uint64) error { return nil } +// ReturnGasAmsterdam handles 2D gas accounting for Amsterdam (EIP-8037). +// It undoes the SubGas deduction fully and accumulates per-dimension block totals. +func (gp *GasPool) ReturnGasAmsterdam(returned, txRegular, txState, receiptGasUsed uint64) error { + if gp.remaining > math.MaxUint64-returned { + return fmt.Errorf("%w: remaining: %d, returned: %d", ErrGasLimitOverflow, gp.remaining, returned) + } + // Undo SubGas deduction fully (Amsterdam uses cumulative tracking) + gp.remaining += returned + // Accumulate 2D block dimensions + gp.cumulativeRegular += txRegular + gp.cumulativeState += txState + gp.cumulativeUsed += receiptGasUsed + return nil +} + // Gas returns the amount of gas remaining in the pool. func (gp *GasPool) Gas() uint64 { return gp.remaining @@ -92,8 +103,6 @@ func (gp *GasPool) CumulativeUsed() uint64 { // Used returns the amount of consumed gas. For Amsterdam blocks with // 2D gas accounting (EIP-8037), returns max(sum_regular, sum_state). func (gp *GasPool) Used() uint64 { - fmt.Printf("DEBUG_POOL Used: initial=%d remaining=%d cumR=%d cumS=%d cumUsed=%d\n", - gp.initial, gp.remaining, gp.cumulativeRegular, gp.cumulativeState, gp.cumulativeUsed) if gp.cumulativeRegular > 0 || gp.cumulativeState > 0 { return max(gp.cumulativeRegular, gp.cumulativeState) } diff --git a/core/state_transition.go b/core/state_transition.go index dd1ebffdc8..c85cb0468f 100644 --- a/core/state_transition.go +++ b/core/state_transition.go @@ -260,8 +260,6 @@ type stateTransition struct { initialGas vm.GasCosts state vm.StateDB evm *vm.EVM - - stateGasRefund uint64 // EIP-8037: state gas refund for auth on existing accounts } // newStateTransition initialises and returns a new state transition object. @@ -570,6 +568,12 @@ func (st *stateTransition) execute() (*ExecutionResult, error) { // gas allowance required to complete execution. peakGasUsed := st.gasUsed() + // EIP-8037: Capture pre-refund remaining for 2D gas accounting. + var preRefundRemaining uint64 + if rules.IsAmsterdam { + preRefundRemaining = st.gasRemaining.Sum() + } + // Compute refund counter, capped to a refund quotient. st.gasRemaining.RegularGas += st.calcRefund() if rules.IsPrague { @@ -587,11 +591,21 @@ func (st *stateTransition) execute() (*ExecutionResult, error) { } returned := st.returnGas() - fmt.Printf("DEBUG_GAS buyGas_deducted=%d returned=%d gasUsed=%d remR=%d remS=%d initR=%d initS=%d refund=%d stateGasRef=%d SGC=%d\n", - msg.GasLimit, returned, st.gasUsed(), st.gasRemaining.RegularGas, st.gasRemaining.StateGas, st.initialGas.RegularGas, st.initialGas.StateGas, st.state.GetRefund(), st.stateGasRefund, st.gasRemaining.StateGasCharged) - if err := st.gp.ReturnGas(returned, st.gasUsed()); err != nil { - return nil, err + if rules.IsAmsterdam { + // EIP-8037: 2D gas accounting for Amsterdam. + // tx_state = adjusted_intrinsic_state + exec_state_used (spec: set_delegation adjusts intrinsic) + // tx_regular = total_dimensional_used - tx_state + txState := gas.StateGas + st.gasRemaining.StateGasCharged + txRegular := (msg.GasLimit - preRefundRemaining) - txState + txRegular = max(txRegular, floorDataGas) + if err := st.gp.ReturnGasAmsterdam(returned, txRegular, txState, st.gasUsed()); err != nil { + return nil, err + } + } else { + if err := st.gp.ReturnGas(returned, st.gasUsed()); err != nil { + return nil, err + } } effectiveTip := msg.GasPrice if rules.IsLondon { @@ -670,7 +684,9 @@ func (st *stateTransition) applyAuthorization(rules params.Rules, auth *types.Se // charged in the intrinsic calculation. if st.state.Exist(authority) { if rules.IsAmsterdam { - st.stateGasRefund += params.AccountCreationSize * st.evm.Context.CostPerGasByte + refund := params.AccountCreationSize * st.evm.Context.CostPerGasByte + // EIP-8037: return the account creation state gas to the reservoir + st.gasRemaining.StateGas += refund } else { st.state.AddRefund(params.CallNewAccountGas - params.TxAuthTupleGas) }