core/vm: fix authorization gas calculation

This commit is contained in:
Marius van der Wijden 2026-03-10 12:43:54 +01:00
parent 03a86abfaa
commit 8d6622b86d

View file

@ -534,8 +534,9 @@ func (st *stateTransition) execute() (*ExecutionResult, error) {
st.state.Prepare(rules, msg.From, st.evm.Context.Coinbase, msg.To, vm.ActivePrecompiles(rules), msg.AccessList) st.state.Prepare(rules, msg.From, st.evm.Context.Coinbase, msg.To, vm.ActivePrecompiles(rules), msg.AccessList)
var ( var (
ret []byte ret []byte
vmerr error // vm errors do not effect consensus and are therefore not assigned to err vmerr error // vm errors do not effect consensus and are therefore not assigned to err
authRefund uint64
) )
if contractCreation { if contractCreation {
ret, _, st.gasRemaining, vmerr = st.evm.Create(msg.From, msg.Data, st.gasRemaining, value) ret, _, st.gasRemaining, vmerr = st.evm.Create(msg.From, msg.Data, st.gasRemaining, value)
@ -547,7 +548,8 @@ func (st *stateTransition) execute() (*ExecutionResult, error) {
if msg.SetCodeAuthorizations != nil { if msg.SetCodeAuthorizations != nil {
for _, auth := range msg.SetCodeAuthorizations { for _, auth := range msg.SetCodeAuthorizations {
// Note errors are ignored, we simply skip invalid authorizations here. // Note errors are ignored, we simply skip invalid authorizations here.
st.applyAuthorization(rules, &auth) refund, _ := st.applyAuthorization(rules, &auth)
authRefund += refund
} }
} }
@ -596,7 +598,7 @@ func (st *stateTransition) execute() (*ExecutionResult, error) {
// EIP-8037: 2D gas accounting for Amsterdam. // EIP-8037: 2D gas accounting for Amsterdam.
// tx_state = adjusted_intrinsic_state + exec_state_used (spec: set_delegation adjusts intrinsic) // tx_state = adjusted_intrinsic_state + exec_state_used (spec: set_delegation adjusts intrinsic)
// tx_regular = total_dimensional_used - tx_state // tx_regular = total_dimensional_used - tx_state
txState := gas.StateGas + st.gasRemaining.StateGasCharged txState := (gas.StateGas - authRefund) + st.gasRemaining.StateGasCharged
txRegular := (msg.GasLimit - preRefundRemaining) - txState txRegular := (msg.GasLimit - preRefundRemaining) - txState
txRegular = max(txRegular, floorDataGas) txRegular = max(txRegular, floorDataGas)
if err := st.gp.ReturnGasAmsterdam(returned, txRegular, txState, st.gasUsed()); err != nil { if err := st.gp.ReturnGasAmsterdam(returned, txRegular, txState, st.gasUsed()); err != nil {
@ -674,18 +676,19 @@ func (st *stateTransition) validateAuthorization(auth *types.SetCodeAuthorizatio
} }
// applyAuthorization applies an EIP-7702 code delegation to the state. // applyAuthorization applies an EIP-7702 code delegation to the state.
func (st *stateTransition) applyAuthorization(rules params.Rules, auth *types.SetCodeAuthorization) error { func (st *stateTransition) applyAuthorization(rules params.Rules, auth *types.SetCodeAuthorization) (uint64, error) {
authority, err := st.validateAuthorization(auth) authority, err := st.validateAuthorization(auth)
if err != nil { if err != nil {
return err return 0, err
} }
// If the account already exists in state, refund the new account cost // If the account already exists in state, refund the new account cost
// charged in the intrinsic calculation. // charged in the intrinsic calculation.
var refund uint64
if st.state.Exist(authority) { if st.state.Exist(authority) {
if rules.IsAmsterdam { if rules.IsAmsterdam {
refund := params.AccountCreationSize * st.evm.Context.CostPerGasByte // EIP-8037: refund account creation state gas to the reservoir
// EIP-8037: return the account creation state gas to the reservoir refund = params.AccountCreationSize * st.evm.Context.CostPerGasByte
st.gasRemaining.StateGas += refund st.gasRemaining.StateGas += refund
} else { } else {
st.state.AddRefund(params.CallNewAccountGas - params.TxAuthTupleGas) st.state.AddRefund(params.CallNewAccountGas - params.TxAuthTupleGas)
@ -701,7 +704,7 @@ func (st *stateTransition) applyAuthorization(rules params.Rules, auth *types.Se
if isDelegated { if isDelegated {
st.state.SetCode(authority, nil, tracing.CodeChangeAuthorizationClear) st.state.SetCode(authority, nil, tracing.CodeChangeAuthorizationClear)
} }
return nil return refund, nil
} }
// install delegation to auth.Address if the delegation changed // install delegation to auth.Address if the delegation changed
@ -709,7 +712,7 @@ func (st *stateTransition) applyAuthorization(rules params.Rules, auth *types.Se
st.state.SetCode(authority, types.AddressToDelegation(auth.Address), tracing.CodeChangeAuthorization) st.state.SetCode(authority, types.AddressToDelegation(auth.Address), tracing.CodeChangeAuthorization)
} }
return nil return refund, nil
} }
// calcRefund computes refund counter, capped to a refund quotient. // calcRefund computes refund counter, capped to a refund quotient.