mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-03-08 04:15:04 +00:00
core: fixed issues from devnet
This commit is contained in:
parent
d27b174680
commit
964a117ea7
3 changed files with 48 additions and 17 deletions
|
|
@ -781,7 +781,10 @@ func (st *stateTransition) blockGasUsed(intrinsicGas, execGasStart vm.GasCosts)
|
|||
totalExecUsed := (execGasStart.RegularGas + execGasStart.StateGas) -
|
||||
(st.gasRemaining.RegularGas + st.gasRemaining.StateGas)
|
||||
execStateUsed := st.gasRemaining.TotalStateGasCharged
|
||||
execRegularUsed := totalExecUsed - execStateUsed
|
||||
// Exclude state gas that was charged from regular gas but then reverted.
|
||||
// This gas was consumed from the regular pool but was for state operations
|
||||
// that didn't persist, so it shouldn't count in the regular dimension.
|
||||
execRegularUsed := totalExecUsed - execStateUsed - st.gasRemaining.RevertedStateGasSpill
|
||||
|
||||
txRegular := intrinsicGas.RegularGas + execRegularUsed
|
||||
txState := intrinsicGas.StateGas + execStateUsed - st.stateGasRefund
|
||||
|
|
|
|||
|
|
@ -316,7 +316,8 @@ func (evm *EVM) Call(caller common.Address, addr common.Address, input []byte, g
|
|||
// when we're in homestead this also counts for code storage gas errors.
|
||||
if err != nil {
|
||||
evm.StateDB.RevertToSnapshot(snapshot)
|
||||
if err != ErrExecutionReverted {
|
||||
isRevert := err == ErrExecutionReverted
|
||||
if !isRevert {
|
||||
if evm.Config.Tracer != nil && evm.Config.Tracer.OnGasChange != nil {
|
||||
evm.Config.Tracer.OnGasChange(gas.RegularGas, 0, tracing.GasChangeCallFailedExecution)
|
||||
}
|
||||
|
|
@ -325,8 +326,7 @@ func (evm *EVM) Call(caller common.Address, addr common.Address, input []byte, g
|
|||
// State changes are rolled back on any error, so state gas charges
|
||||
// from the reverted execution should not count toward block accounting.
|
||||
// Also restore the state gas reservoir since state creation was undone.
|
||||
gas.TotalStateGasCharged = savedTotalStateGas
|
||||
gas.StateGas = savedStateGas
|
||||
gas.RevertStateGas(savedTotalStateGas, savedStateGas, isRevert)
|
||||
// TODO: consider clearing up unused snapshots:
|
||||
//} else {
|
||||
// evm.StateDB.DiscardSnapshot(snapshot)
|
||||
|
|
@ -381,14 +381,14 @@ func (evm *EVM) CallCode(caller common.Address, addr common.Address, input []byt
|
|||
}
|
||||
if err != nil {
|
||||
evm.StateDB.RevertToSnapshot(snapshot)
|
||||
if err != ErrExecutionReverted {
|
||||
isRevert := err == ErrExecutionReverted
|
||||
if !isRevert {
|
||||
if evm.Config.Tracer != nil && evm.Config.Tracer.OnGasChange != nil {
|
||||
evm.Config.Tracer.OnGasChange(gas.RegularGas, 0, tracing.GasChangeCallFailedExecution)
|
||||
}
|
||||
gas.RegularGas = 0
|
||||
}
|
||||
gas.TotalStateGasCharged = savedTotalStateGas
|
||||
gas.StateGas = savedStateGas
|
||||
gas.RevertStateGas(savedTotalStateGas, savedStateGas, isRevert)
|
||||
}
|
||||
return ret, gas, err
|
||||
}
|
||||
|
|
@ -433,14 +433,14 @@ func (evm *EVM) DelegateCall(originCaller common.Address, caller common.Address,
|
|||
}
|
||||
if err != nil {
|
||||
evm.StateDB.RevertToSnapshot(snapshot)
|
||||
if err != ErrExecutionReverted {
|
||||
isRevert := err == ErrExecutionReverted
|
||||
if !isRevert {
|
||||
if evm.Config.Tracer != nil && evm.Config.Tracer.OnGasChange != nil {
|
||||
evm.Config.Tracer.OnGasChange(gas.RegularGas, 0, tracing.GasChangeCallFailedExecution)
|
||||
}
|
||||
gas.RegularGas = 0
|
||||
}
|
||||
gas.TotalStateGasCharged = savedTotalStateGas
|
||||
gas.StateGas = savedStateGas
|
||||
gas.RevertStateGas(savedTotalStateGas, savedStateGas, isRevert)
|
||||
}
|
||||
return ret, gas, err
|
||||
}
|
||||
|
|
@ -496,15 +496,14 @@ func (evm *EVM) StaticCall(caller common.Address, addr common.Address, input []b
|
|||
}
|
||||
if err != nil {
|
||||
evm.StateDB.RevertToSnapshot(snapshot)
|
||||
if err != ErrExecutionReverted {
|
||||
isRevert := err == ErrExecutionReverted
|
||||
if !isRevert {
|
||||
if evm.Config.Tracer != nil && evm.Config.Tracer.OnGasChange != nil {
|
||||
evm.Config.Tracer.OnGasChange(gas.RegularGas, 0, tracing.GasChangeCallFailedExecution)
|
||||
}
|
||||
|
||||
gas.RegularGas = 0
|
||||
}
|
||||
gas.TotalStateGasCharged = savedTotalStateGas
|
||||
gas.StateGas = savedStateGas
|
||||
gas.RevertStateGas(savedTotalStateGas, savedStateGas, isRevert)
|
||||
}
|
||||
return ret, gas, err
|
||||
}
|
||||
|
|
@ -615,14 +614,14 @@ func (evm *EVM) create(caller common.Address, code []byte, gas GasCosts, value *
|
|||
ret, err = evm.initNewContract(contract, address)
|
||||
if err != nil && (evm.chainRules.IsHomestead || err != ErrCodeStoreOutOfGas) {
|
||||
evm.StateDB.RevertToSnapshot(snapshot)
|
||||
if err != ErrExecutionReverted {
|
||||
isRevert := err == ErrExecutionReverted
|
||||
if !isRevert {
|
||||
contract.UseGas(contract.Gas, evm.Config.Tracer, tracing.GasChangeCallFailedExecution)
|
||||
}
|
||||
// State changes are rolled back, so state gas charges from the
|
||||
// reverted execution should not count toward block accounting.
|
||||
// Also restore the state gas reservoir since state creation was undone.
|
||||
contract.Gas.TotalStateGasCharged = savedTotalStateGas
|
||||
contract.Gas.StateGas = savedStateGas
|
||||
contract.Gas.RevertStateGas(savedTotalStateGas, savedStateGas, isRevert)
|
||||
}
|
||||
return ret, address, contract.Gas, err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,6 +11,13 @@ type GasCosts struct {
|
|||
// This is needed for EIP-8037 block gas accounting where the state gas
|
||||
// dimension counts ALL state creation charges, not just reservoir consumption.
|
||||
TotalStateGasCharged uint64
|
||||
|
||||
// RevertedStateGasSpill tracks state gas that was charged from regular gas
|
||||
// (spilled) during execution of a call that subsequently reverted. When a
|
||||
// call fails, its state changes are undone, but the regular gas was already
|
||||
// consumed. Block gas accounting must exclude this amount from the regular
|
||||
// gas dimension since it was for state operations that didn't persist.
|
||||
RevertedStateGasSpill uint64
|
||||
}
|
||||
|
||||
func (g GasCosts) Max() uint64 {
|
||||
|
|
@ -52,6 +59,28 @@ func (g *GasCosts) Add(b GasCosts) {
|
|||
g.RegularGas += b.RegularGas
|
||||
g.StateGas += b.StateGas
|
||||
g.TotalStateGasCharged += b.TotalStateGasCharged
|
||||
g.RevertedStateGasSpill += b.RevertedStateGasSpill
|
||||
}
|
||||
|
||||
// RevertStateGas handles state gas accounting when a call reverts (EIP-8037).
|
||||
// It computes how much state gas was charged from regular gas (spill) during the
|
||||
// call, and either returns it for REVERT errors or tracks it for non-REVERT errors.
|
||||
func (g *GasCosts) RevertStateGas(savedTotalStateGas, savedStateGas uint64, isRevert bool) {
|
||||
chargedDuringCall := g.TotalStateGasCharged - savedTotalStateGas
|
||||
fromReservoir := savedStateGas - g.StateGas
|
||||
spilledFromRegular := chargedDuringCall - fromReservoir
|
||||
|
||||
if isRevert {
|
||||
// REVERT: return the spilled state gas to regular gas since the caller
|
||||
// keeps unused gas and state operations were undone.
|
||||
g.RegularGas += spilledFromRegular
|
||||
} else {
|
||||
// Non-REVERT: regular gas is zeroed, but block accounting must exclude
|
||||
// the spill from the regular gas dimension.
|
||||
g.RevertedStateGasSpill += spilledFromRegular
|
||||
}
|
||||
g.TotalStateGasCharged = savedTotalStateGas
|
||||
g.StateGas = savedStateGas
|
||||
}
|
||||
|
||||
func (g GasCosts) String() string {
|
||||
|
|
|
|||
Loading…
Reference in a new issue