mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-05-24 08:49:29 +00:00
core: absorb marius's fix from the baldev-7 branch
This commit is contained in:
parent
5963fc8408
commit
39fb6df951
2 changed files with 42 additions and 21 deletions
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue