mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-06-08 07:58:40 +00:00
core: apply fixes for 8037
This commit is contained in:
parent
fa45d1a38f
commit
a91cb20ae9
4 changed files with 45 additions and 28 deletions
|
|
@ -609,14 +609,16 @@ func (st *stateTransition) execute() (*ExecutionResult, error) {
|
|||
|
||||
// On outer level tx failure, no state is written.
|
||||
if rules.IsAmsterdam && vmerr != nil {
|
||||
st.gasRemaining.StateGas += execGasUsed.StateGas
|
||||
if execGasUsed.StateGas > 0 {
|
||||
st.gasRemaining.StateGas += uint64(execGasUsed.StateGas)
|
||||
}
|
||||
execGasUsed.StateGas = 0
|
||||
}
|
||||
|
||||
// Refund costs for selfdestructed accounts and slots.
|
||||
if rules.IsAmsterdam && vmerr == nil {
|
||||
cpsb := st.evm.Context.CostPerGasByte
|
||||
stateGasUsed := execGasUsed.StateGas + cost.StateGas
|
||||
stateGasUsed := int64(cost.StateGas) + execGasUsed.StateGas
|
||||
var sdRefund uint64
|
||||
for _, addr := range st.state.SameTxSelfDestructs() {
|
||||
r := params.AccountCreationSize * cpsb
|
||||
|
|
@ -624,15 +626,22 @@ func (st *stateTransition) execute() (*ExecutionResult, error) {
|
|||
r += uint64(st.state.GetCodeSize(addr)) * cpsb
|
||||
sdRefund += r
|
||||
}
|
||||
if sdRefund > stateGasUsed {
|
||||
sdRefund = stateGasUsed
|
||||
if stateGasUsed < 0 {
|
||||
sdRefund = 0
|
||||
} else if sdRefund > uint64(stateGasUsed) {
|
||||
sdRefund = uint64(stateGasUsed)
|
||||
}
|
||||
if sdRefund > 0 {
|
||||
st.gasRemaining.StateGas += sdRefund
|
||||
if execGasUsed.StateGas >= sdRefund {
|
||||
execGasUsed.StateGas -= sdRefund
|
||||
if execGasUsed.StateGas >= int64(sdRefund) {
|
||||
execGasUsed.StateGas -= int64(sdRefund)
|
||||
} else {
|
||||
extra := sdRefund - execGasUsed.StateGas
|
||||
var extra uint64
|
||||
if execGasUsed.StateGas > 0 {
|
||||
extra = sdRefund - uint64(execGasUsed.StateGas)
|
||||
} else {
|
||||
extra = sdRefund
|
||||
}
|
||||
execGasUsed.StateGas = 0
|
||||
if cost.StateGas >= extra {
|
||||
cost.StateGas -= extra
|
||||
|
|
@ -673,7 +682,12 @@ func (st *stateTransition) execute() (*ExecutionResult, error) {
|
|||
// EIP-8037: 2D gas accounting for Amsterdam.
|
||||
// tx_regular = intrinsic_regular + exec_regular_gas_used
|
||||
// tx_state = intrinsic_state (adjusted) + exec_state_gas_used
|
||||
txState := cost.StateGas + execGasUsed.StateGas
|
||||
// execGasUsed.StateGas may be negative when an SSTORE 0→x→0 refund
|
||||
// exceeded the intrinsic-charged state gas
|
||||
txState := cost.StateGas
|
||||
if execGasUsed.StateGas > 0 {
|
||||
txState += uint64(execGasUsed.StateGas)
|
||||
}
|
||||
txRegular := cost.RegularGas + execGasUsed.RegularGas
|
||||
txRegular = max(txRegular, floorDataGas)
|
||||
if err := st.gp.ReturnGasAmsterdam(txRegular, txState, st.gasUsed()); err != nil {
|
||||
|
|
|
|||
|
|
@ -139,13 +139,21 @@ func (c *Contract) UseGas(cost GasCosts, logger *tracing.Hooks, reason tracing.G
|
|||
return true
|
||||
}
|
||||
|
||||
// RefundGas refunds gas to the contract. gasUsed carries the child frame's
|
||||
// accumulated gas usage metrics (EIP-8037), incorporated on both success and error.
|
||||
// RefundGas refunds gas to the contract.
|
||||
func (c *Contract) RefundGas(err error, initialRegularGasUsed uint64, gas GasBudget, gasUsed GasUsed, logger *tracing.Hooks, reason tracing.GasChangeReason) {
|
||||
// If the preceding call errored, return the state gas
|
||||
// to the parent call
|
||||
// If the preceding call errored, return the child's state-gas reservoir
|
||||
// and any net state-gas consumption to the parent. A negative
|
||||
// gasUsed.StateGas (an unabsorbed SSTORE 0→x→0 refund) is an inflation
|
||||
// to undo: the matching state mutation was reverted with the child, so
|
||||
// the refund must not leak back to the parent.
|
||||
if err != nil {
|
||||
gas.StateGas += gasUsed.StateGas
|
||||
if gasUsed.StateGas >= 0 {
|
||||
gas.StateGas += uint64(gasUsed.StateGas)
|
||||
} else if undo := uint64(-gasUsed.StateGas); gas.StateGas >= undo {
|
||||
gas.StateGas -= undo
|
||||
} else {
|
||||
gas.StateGas = 0
|
||||
}
|
||||
gasUsed.StateGas = 0
|
||||
}
|
||||
if gas.RegularGas == 0 && gas.StateGas == 0 && gasUsed.StateGas == 0 && gasUsed.RegularGas == 0 {
|
||||
|
|
@ -164,11 +172,7 @@ func (c *Contract) RefundGas(err error, initialRegularGasUsed uint64, gas GasBud
|
|||
func (c *Contract) RefundCreateStateGas(refund uint64) {
|
||||
if refund > 0 {
|
||||
c.Gas.StateGas += refund
|
||||
if c.GasUsed.StateGas >= refund {
|
||||
c.GasUsed.StateGas -= refund
|
||||
} else {
|
||||
c.GasUsed.StateGas = 0
|
||||
}
|
||||
c.GasUsed.StateGas -= int64(refund)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -702,11 +702,7 @@ func gasSStore8037(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memo
|
|||
// refund counter, which is capped at gas_used/5.
|
||||
stateRefund := params.StorageCreationSize * evm.Context.CostPerGasByte
|
||||
contract.Gas.StateGas += stateRefund
|
||||
if contract.GasUsed.StateGas >= stateRefund {
|
||||
contract.GasUsed.StateGas -= stateRefund
|
||||
} else {
|
||||
contract.GasUsed.StateGas = 0
|
||||
}
|
||||
contract.GasUsed.StateGas -= int64(stateRefund)
|
||||
// Regular portion of the refund still goes through the refund counter.
|
||||
evm.StateDB.AddRefund(params.SstoreResetGasEIP2200 - params.ColdSloadCostEIP2929 - params.WarmStorageReadCostEIP2929)
|
||||
} else { // reset to original existing slot (2.2.2.2)
|
||||
|
|
|
|||
|
|
@ -18,11 +18,16 @@ package vm
|
|||
|
||||
import "fmt"
|
||||
|
||||
type GasUsed = GasCosts
|
||||
// GasUsed is the per-frame accumulator for gas consumption.
|
||||
// StateGas is signed because of 0 -> X -> 0 SSTORE refunds.
|
||||
type GasUsed struct {
|
||||
RegularGas uint64
|
||||
StateGas int64
|
||||
}
|
||||
|
||||
func (g *GasUsed) Add(costs GasCosts) {
|
||||
g.RegularGas += costs.RegularGas
|
||||
g.StateGas += costs.StateGas
|
||||
g.StateGas += int64(costs.StateGas)
|
||||
}
|
||||
|
||||
// GasCosts denotes a vector of gas costs in the
|
||||
|
|
@ -66,11 +71,9 @@ func (g GasBudget) Used(initial GasBudget) uint64 {
|
|||
return (initial.RegularGas + initial.StateGas) - (g.RegularGas + g.StateGas)
|
||||
}
|
||||
|
||||
// Exhaust sets all remaining gas to zero, preserving the initial amount
|
||||
// for usage tracking.
|
||||
// Exhaust burns the remaining regular gas on exceptional halt.
|
||||
func (g *GasBudget) Exhaust() {
|
||||
g.RegularGas = 0
|
||||
g.StateGas = 0
|
||||
}
|
||||
|
||||
func (g *GasBudget) Copy() GasBudget {
|
||||
|
|
|
|||
Loading…
Reference in a new issue