core: absorb marius's fix from the baldev-7 branch

This commit is contained in:
Gary Rong 2026-05-20 15:18:03 +08:00
parent 5963fc8408
commit 39fb6df951
2 changed files with 42 additions and 21 deletions

View file

@ -2301,6 +2301,12 @@ func (bc *BlockChain) ProcessBlock(ctx context.Context, parentRoot common.Hash,
stats.Validation = vtime - (statedb.AccountHashes + statedb.AccountUpdates + statedb.StorageUpdates) // The time spent on block validation
stats.CrossValidation = xvtime // The time spent on stateless cross validation
// Attach the computed block access list so it gets persisted alongside the
// block. The validator has already verified the hash matches the header.
if res.Bal != nil && block.AccessList() == nil {
block = block.WithAccessListUnsafe(res.Bal.ToEncodingObj())
}
// Write the block to the chain and get the status.
var status WriteStatus
if config.WriteState {

View file

@ -781,21 +781,28 @@ func (st *stateTransition) execute() (*ExecutionResult, error) {
st.gasRemaining.RefundRegular(st.calcRefund())
if rules.IsPrague {
// We can always guarantee that the initial regular gas allowance
// is sufficient to cover the floor cost.
//
// Pre-Amsterdam, there is a single dimension and gas limit is greater
// than the floor cost.
//
// Since Amsterdam:
// - If GasLimit <= 16M, the state reservoir is initialized to 0,
// and regular_gas_budget >= floor_cost always holds.
// - If GasLimit > 16M, the state reservoir is non-zero, while
// regular_gas_budget == 16M, which is still guaranteed to be
// greater than the floor cost. The extra cost should be deducted
// from the regular even the state reservoir is non-zero.
// EIP-7623 floor: tx_gas_used_after_refund = max(used, calldata_floor).
// Drain the leftover gas budget — regular first, then state — to bring
// gasUsed up to the floor. State must be drained too because a failed
// contract-creation top-level refund (line ~770) can move otherwise-spent
// gas back into the state reservoir, leaving RegularGas too small to
// satisfy the floor on its own.
if used := st.gasUsed(); used < floorDataGas {
prior, _ := st.gasRemaining.ChargeRegular(floorDataGas - used)
prior := st.gasRemaining
need := floorDataGas - used
if take := min(need, st.gasRemaining.RegularGas); take > 0 {
st.gasRemaining.RegularGas -= take
st.gasRemaining.UsedRegularGas += take
need -= take
}
if take := min(need, st.gasRemaining.StateGas); take > 0 {
st.gasRemaining.StateGas -= take
st.gasRemaining.UsedStateGas += int64(take)
need -= take
}
if need > 0 {
return nil, fmt.Errorf("insufficient gas for floor cost, remaining: %d", need)
}
if st.evm.Config.Tracer.HasGasHook() {
st.evm.Config.Tracer.EmitGasChange(prior.AsTracing(), st.gasRemaining.AsTracing(), tracing.GasChangeTxDataFloor)
}
@ -901,7 +908,6 @@ func (st *stateTransition) applyAuthorization(rules params.Rules, auth *types.Se
if err != nil {
return err
}
// If the account already exists in state, refund the new account cost
// charged in the intrinsic calculation.
if st.state.Exist(authority) {
@ -912,24 +918,33 @@ func (st *stateTransition) applyAuthorization(rules params.Rules, auth *types.Se
st.state.AddRefund(params.CallNewAccountGas - params.TxAuthTupleGas)
}
}
prevDelegation, isDelegated := types.ParseDelegation(st.state.GetCode(authority))
if rules.IsAmsterdam {
// EIP-8037: also refund the auth-base state gas when no new delegation
// indicator bytes are written. Two cases:
// - the authority already has a delegation (overwrite in place); or
// - the auth is no-op (auth.Address == 0).
// In both cases the 23 delegation bytes are reused, so the auth-base
// portion of the intrinsic state gas is refilled.
if isDelegated || auth.Address == (common.Address{}) {
st.gasRemaining.RefundState(params.AuthorizationCreationSize * st.evm.Context.CostPerStateByte)
}
}
// Update nonce and account code.
st.state.SetNonce(authority, auth.Nonce+1, tracing.NonceChangeAuthorization)
// Delegation to zero address means clear.
if auth.Address == (common.Address{}) {
// Delegation to zero address means clear.
if isDelegated {
st.state.SetCode(authority, nil, tracing.CodeChangeAuthorizationClear)
}
return nil
}
// install delegation to auth.Address if the delegation changed
// Install delegation to auth.Address if the delegation changed
if !isDelegated || auth.Address != prevDelegation {
st.state.SetCode(authority, types.AddressToDelegation(auth.Address), tracing.CodeChangeAuthorization)
}
return nil
}
@ -958,7 +973,7 @@ func (st *stateTransition) calcRefund() uint64 {
// returnGas returns ETH for remaining gas, exchanged at the original rate.
func (st *stateTransition) returnGas() uint64 {
gas := st.gasRemaining.RegularGas + st.gasRemaining.StateGas
remaining := uint256.NewInt(st.gasRemaining.RegularGas)
remaining := uint256.NewInt(gas)
remaining.Mul(remaining, st.msg.GasPrice)
st.state.AddBalance(st.msg.From, remaining, tracing.BalanceIncreaseGasReturn)