mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-03 19:51:15 +00:00
core. last 3 fixes (claude) will pull them out later
This commit is contained in:
parent
64d77794a7
commit
8f16e534f8
3 changed files with 37 additions and 6 deletions
|
|
@ -737,7 +737,7 @@ func (st *stateTransition) execute() (*ExecutionResult, error) {
|
|||
// If the contract creation failed, or the destination was pre-existing,
|
||||
// refund the account-creation state gas pre-charged in IntrinsicGas.
|
||||
if rules.IsAmsterdam && !creation {
|
||||
st.gasRemaining.RefundState(params.AccountCreationSize * st.evm.Context.CostPerStateByte)
|
||||
st.gasRemaining.RefundStateToReservoir(params.AccountCreationSize * st.evm.Context.CostPerStateByte)
|
||||
}
|
||||
} else {
|
||||
// Increment the nonce for the next transaction.
|
||||
|
|
@ -753,6 +753,13 @@ func (st *stateTransition) execute() (*ExecutionResult, error) {
|
|||
// performing the resolution and warming.
|
||||
if addr, ok := types.ParseDelegation(st.state.GetCode(*msg.To)); ok {
|
||||
st.state.AddAddressToAccessList(addr)
|
||||
// The spec resolves the delegated code in process_message_call,
|
||||
// before the top-frame recipient charges: the delegated account is
|
||||
// read (and recorded in the block access list) even if the cold
|
||||
// access charge below runs out of gas.
|
||||
if rules.IsAmsterdam {
|
||||
st.state.GetCode(addr)
|
||||
}
|
||||
}
|
||||
// EIP-2780: charge the transaction's top-level recipient costs. If the
|
||||
// budget cannot cover the charge, the top frame halts out of gas.
|
||||
|
|
@ -966,7 +973,7 @@ func (st *stateTransition) applyAuthorization(rules params.Rules, auth *types.Se
|
|||
authority, err := st.validateAuthorization(auth)
|
||||
if err != nil {
|
||||
if rules.IsAmsterdam {
|
||||
st.gasRemaining.RefundState((params.AccountCreationSize + params.AuthorizationCreationSize) * st.evm.Context.CostPerStateByte)
|
||||
st.gasRemaining.RefundStateToReservoir((params.AccountCreationSize + params.AuthorizationCreationSize) * st.evm.Context.CostPerStateByte)
|
||||
st.state.AddRefund(params.AccountWriteAmsterdam)
|
||||
}
|
||||
return err
|
||||
|
|
@ -979,7 +986,7 @@ func (st *stateTransition) applyAuthorization(rules params.Rules, auth *types.Se
|
|||
}
|
||||
} else {
|
||||
if st.state.Exist(authority) {
|
||||
st.gasRemaining.RefundState(params.AccountCreationSize * st.evm.Context.CostPerStateByte)
|
||||
st.gasRemaining.RefundStateToReservoir(params.AccountCreationSize * st.evm.Context.CostPerStateByte)
|
||||
st.state.AddRefund(params.AccountWriteAmsterdam)
|
||||
}
|
||||
authBase := params.AuthorizationCreationSize * st.evm.Context.CostPerStateByte
|
||||
|
|
@ -991,17 +998,17 @@ func (st *stateTransition) applyAuthorization(rules params.Rules, auth *types.Se
|
|||
}
|
||||
if auth.Address == (common.Address{}) {
|
||||
// Clearing writes no indicator, refill this auth's state charge.
|
||||
st.gasRemaining.RefundState(authBase)
|
||||
st.gasRemaining.RefundStateToReservoir(authBase)
|
||||
|
||||
// The indicator was created by an earlier auth within the same
|
||||
// transaction, refill the state charge as it's no longer justified.
|
||||
if curDelegated && !preDelegated {
|
||||
st.gasRemaining.RefundState(authBase)
|
||||
st.gasRemaining.RefundStateToReservoir(authBase)
|
||||
}
|
||||
} else if curDelegated || preDelegated {
|
||||
// The 23-byte slot is already occupied, overwriting it writes no
|
||||
// new bytes, refill the state charge.
|
||||
st.gasRemaining.RefundState(authBase)
|
||||
st.gasRemaining.RefundStateToReservoir(authBase)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -196,6 +196,22 @@ func (g *GasBudget) RefundState(s uint64) {
|
|||
g.UsedStateGas -= int64(s)
|
||||
}
|
||||
|
||||
// RefundStateToReservoir credits a state-gas refund directly to the
|
||||
// reservoir, without repaying spilled regular gas first.
|
||||
//
|
||||
// Per the spec's set_delegation, authorization refunds (and the post-create
|
||||
// new-account refund) are added to message.state_gas_reservoir directly, in
|
||||
// contrast to the LIFO inline refunds handled by RefundState. The usage
|
||||
// counter is decremented by the full amount, matching the spec's
|
||||
// tx_state_gas = intrinsic_state + state_gas_used - state_refund and
|
||||
// preserving the per-frame invariant:
|
||||
//
|
||||
// StateGas + UsedStateGas == initialStateGas + Spilled
|
||||
func (g *GasBudget) RefundStateToReservoir(s uint64) {
|
||||
g.StateGas += s
|
||||
g.UsedStateGas -= int64(s)
|
||||
}
|
||||
|
||||
// Forward drains `regular` regular gas and the entire state reservoir from
|
||||
// the parent's running budget and returns the initial GasBudget for a child
|
||||
// frame. The parent's UsedRegularGas is bumped by the forwarded amount so
|
||||
|
|
|
|||
|
|
@ -415,6 +415,14 @@ func makeCallVariantGasCallEIP7702(intrinsicFunc intrinsicGasFunc, coldCost uint
|
|||
if !contract.chargeRegular(eip7702Cost, evm.Config.Tracer, tracing.GasChangeCallStorageColdAccess) {
|
||||
return GasCosts{}, ErrOutOfGas
|
||||
}
|
||||
// The spec checks the delegation cost together with the memory
|
||||
// expansion and transfer costs before reading the delegated account.
|
||||
// Since intrinsicCost is only checked (not charged) above, re-check it
|
||||
// against the remaining gas so the delegated address is not recorded
|
||||
// in the block access list when the combined costs are unaffordable.
|
||||
if contract.Gas.RegularGas < intrinsicCost {
|
||||
return GasCosts{}, ErrOutOfGas
|
||||
}
|
||||
// The delegated address has passed its gas check; record it in the
|
||||
// block access list now, before the call's sender-balance and
|
||||
// call-stack-depth checks.
|
||||
|
|
|
|||
Loading…
Reference in a new issue