mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-06-06 23:18:37 +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.Validation = vtime - (statedb.AccountHashes + statedb.AccountUpdates + statedb.StorageUpdates) // The time spent on block validation
|
||||||
stats.CrossValidation = xvtime // The time spent on stateless cross 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.
|
// Write the block to the chain and get the status.
|
||||||
var status WriteStatus
|
var status WriteStatus
|
||||||
if config.WriteState {
|
if config.WriteState {
|
||||||
|
|
|
||||||
|
|
@ -781,21 +781,28 @@ func (st *stateTransition) execute() (*ExecutionResult, error) {
|
||||||
st.gasRemaining.RefundRegular(st.calcRefund())
|
st.gasRemaining.RefundRegular(st.calcRefund())
|
||||||
|
|
||||||
if rules.IsPrague {
|
if rules.IsPrague {
|
||||||
// We can always guarantee that the initial regular gas allowance
|
// EIP-7623 floor: tx_gas_used_after_refund = max(used, calldata_floor).
|
||||||
// is sufficient to cover the floor cost.
|
// Drain the leftover gas budget — regular first, then state — to bring
|
||||||
//
|
// gasUsed up to the floor. State must be drained too because a failed
|
||||||
// Pre-Amsterdam, there is a single dimension and gas limit is greater
|
// contract-creation top-level refund (line ~770) can move otherwise-spent
|
||||||
// than the floor cost.
|
// gas back into the state reservoir, leaving RegularGas too small to
|
||||||
//
|
// satisfy the floor on its own.
|
||||||
// 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.
|
|
||||||
if used := st.gasUsed(); used < floorDataGas {
|
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() {
|
if st.evm.Config.Tracer.HasGasHook() {
|
||||||
st.evm.Config.Tracer.EmitGasChange(prior.AsTracing(), st.gasRemaining.AsTracing(), tracing.GasChangeTxDataFloor)
|
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 {
|
if err != nil {
|
||||||
return err
|
return 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.
|
||||||
if st.state.Exist(authority) {
|
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)
|
st.state.AddRefund(params.CallNewAccountGas - params.TxAuthTupleGas)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
prevDelegation, isDelegated := types.ParseDelegation(st.state.GetCode(authority))
|
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.
|
// Update nonce and account code.
|
||||||
st.state.SetNonce(authority, auth.Nonce+1, tracing.NonceChangeAuthorization)
|
st.state.SetNonce(authority, auth.Nonce+1, tracing.NonceChangeAuthorization)
|
||||||
|
|
||||||
|
// Delegation to zero address means clear.
|
||||||
if auth.Address == (common.Address{}) {
|
if auth.Address == (common.Address{}) {
|
||||||
// Delegation to zero address means clear.
|
|
||||||
if isDelegated {
|
if isDelegated {
|
||||||
st.state.SetCode(authority, nil, tracing.CodeChangeAuthorizationClear)
|
st.state.SetCode(authority, nil, tracing.CodeChangeAuthorizationClear)
|
||||||
}
|
}
|
||||||
return nil
|
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 {
|
if !isDelegated || auth.Address != prevDelegation {
|
||||||
st.state.SetCode(authority, types.AddressToDelegation(auth.Address), tracing.CodeChangeAuthorization)
|
st.state.SetCode(authority, types.AddressToDelegation(auth.Address), tracing.CodeChangeAuthorization)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -958,7 +973,7 @@ func (st *stateTransition) calcRefund() uint64 {
|
||||||
// returnGas returns ETH for remaining gas, exchanged at the original rate.
|
// returnGas returns ETH for remaining gas, exchanged at the original rate.
|
||||||
func (st *stateTransition) returnGas() uint64 {
|
func (st *stateTransition) returnGas() uint64 {
|
||||||
gas := st.gasRemaining.RegularGas + st.gasRemaining.StateGas
|
gas := st.gasRemaining.RegularGas + st.gasRemaining.StateGas
|
||||||
remaining := uint256.NewInt(st.gasRemaining.RegularGas)
|
remaining := uint256.NewInt(gas)
|
||||||
remaining.Mul(remaining, st.msg.GasPrice)
|
remaining.Mul(remaining, st.msg.GasPrice)
|
||||||
st.state.AddBalance(st.msg.From, remaining, tracing.BalanceIncreaseGasReturn)
|
st.state.AddBalance(st.msg.From, remaining, tracing.BalanceIncreaseGasReturn)
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue