mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-05-20 14:59:26 +00:00
core/vm: more fixes from ai
This commit is contained in:
parent
da4700411e
commit
22738576fc
3 changed files with 25 additions and 5 deletions
|
|
@ -603,12 +603,22 @@ func (st *stateTransition) execute() (*ExecutionResult, error) {
|
||||||
var receiptGasUsed uint64
|
var receiptGasUsed uint64
|
||||||
if rules.IsAmsterdam {
|
if rules.IsAmsterdam {
|
||||||
receiptGasUsed = msg.GasLimit - st.gasRemaining.RegularGas - st.gasRemaining.StateGas - st.stateGasRefund
|
receiptGasUsed = msg.GasLimit - st.gasRemaining.RegularGas - st.gasRemaining.StateGas - st.stateGasRefund
|
||||||
|
// On successful execution, refund regular gas that was consumed for
|
||||||
|
// state operations in child calls that subsequently reverted. This gas
|
||||||
|
// paid for state growth that didn't persist, so the user shouldn't pay.
|
||||||
|
// On failed execution (exceptional halt), all gas is consumed — no refund.
|
||||||
|
if vmerr == nil {
|
||||||
|
receiptGasUsed -= st.gasRemaining.RevertedStateGasSpill
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return gas to the user
|
// Return gas to the user
|
||||||
if rules.IsAmsterdam {
|
if rules.IsAmsterdam {
|
||||||
// In Amsterdam, return regular gas + unspent state gas reservoir + state gas refund.
|
// In Amsterdam, return regular gas + unspent state gas reservoir + state gas refund.
|
||||||
gasReturn := st.gasRemaining.RegularGas + st.gasRemaining.StateGas + st.stateGasRefund
|
gasReturn := st.gasRemaining.RegularGas + st.gasRemaining.StateGas + st.stateGasRefund
|
||||||
|
if vmerr == nil {
|
||||||
|
gasReturn += st.gasRemaining.RevertedStateGasSpill
|
||||||
|
}
|
||||||
remaining := uint256.NewInt(gasReturn)
|
remaining := uint256.NewInt(gasReturn)
|
||||||
remaining.Mul(remaining, uint256.MustFromBig(st.msg.GasPrice))
|
remaining.Mul(remaining, uint256.MustFromBig(st.msg.GasPrice))
|
||||||
st.state.AddBalance(st.msg.From, remaining, tracing.BalanceIncreaseGasReturn)
|
st.state.AddBalance(st.msg.From, remaining, tracing.BalanceIncreaseGasReturn)
|
||||||
|
|
@ -785,7 +795,7 @@ func (st *stateTransition) blockGasUsed(intrinsicGas, execGasStart vm.GasCosts)
|
||||||
// This gas was consumed from the regular pool but was for state operations
|
// This gas was consumed from the regular pool but was for state operations
|
||||||
// that didn't persist, so it shouldn't count in either dimension for block
|
// that didn't persist, so it shouldn't count in either dimension for block
|
||||||
// accounting (invisible to the block). This matches nethermind's approach.
|
// accounting (invisible to the block). This matches nethermind's approach.
|
||||||
execRegularUsed := totalExecUsed - execStateUsed - st.gasRemaining.RevertedStateGasSpill
|
execRegularUsed := totalExecUsed - execStateUsed - st.gasRemaining.RevertedStateGasSpill - st.gasRemaining.CollisionConsumedGas
|
||||||
|
|
||||||
txRegular := intrinsicGas.RegularGas + execRegularUsed
|
txRegular := intrinsicGas.RegularGas + execRegularUsed
|
||||||
txState := intrinsicGas.StateGas + execStateUsed - st.stateGasRefund
|
txState := intrinsicGas.StateGas + execStateUsed - st.stateGasRefund
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,14 @@ type GasCosts struct {
|
||||||
// call fails, its state changes are undone, but the regular gas was already
|
// call fails, its state changes are undone, but the regular gas was already
|
||||||
// consumed. Block gas accounting must exclude this amount from the regular
|
// consumed. Block gas accounting must exclude this amount from the regular
|
||||||
// gas dimension since it was for state operations that didn't persist.
|
// gas dimension since it was for state operations that didn't persist.
|
||||||
|
// This gas is refunded to the user (invisible to both block and receipt).
|
||||||
RevertedStateGasSpill uint64
|
RevertedStateGasSpill uint64
|
||||||
|
|
||||||
|
// CollisionConsumedGas tracks regular gas consumed on CREATE/CREATE2 address
|
||||||
|
// collision. On collision, the child's regular gas is consumed (user pays)
|
||||||
|
// but must be excluded from block regular gas accounting to preserve 2D
|
||||||
|
// block gas semantics. Unlike RevertedStateGasSpill, this is NOT refunded.
|
||||||
|
CollisionConsumedGas uint64
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g GasCosts) Max() uint64 {
|
func (g GasCosts) Max() uint64 {
|
||||||
|
|
@ -64,6 +71,7 @@ func (g *GasCosts) Add(b GasCosts) {
|
||||||
g.StateGas += b.StateGas
|
g.StateGas += b.StateGas
|
||||||
g.TotalStateGasCharged += b.TotalStateGasCharged
|
g.TotalStateGasCharged += b.TotalStateGasCharged
|
||||||
g.RevertedStateGasSpill += b.RevertedStateGasSpill
|
g.RevertedStateGasSpill += b.RevertedStateGasSpill
|
||||||
|
g.CollisionConsumedGas += b.CollisionConsumedGas
|
||||||
}
|
}
|
||||||
|
|
||||||
// RevertStateGas handles state gas accounting when a call reverts (EIP-8037).
|
// RevertStateGas handles state gas accounting when a call reverts (EIP-8037).
|
||||||
|
|
|
||||||
|
|
@ -704,9 +704,10 @@ func opCreate(pc *uint64, evm *EVM, scope *ScopeContext) ([]byte, error) {
|
||||||
returnGas.StateGas = stateGas
|
returnGas.StateGas = stateGas
|
||||||
}
|
}
|
||||||
// On address collision, child's regular gas is consumed (not returned).
|
// On address collision, child's regular gas is consumed (not returned).
|
||||||
// Track as RevertedStateGasSpill so block 2D accounting is unaffected.
|
// Track as CollisionConsumedGas so block 2D accounting is unaffected
|
||||||
|
// while the user still pays for the consumed gas (not refunded).
|
||||||
if evm.chainRules.IsAmsterdam && errors.Is(suberr, ErrContractAddressCollision) {
|
if evm.chainRules.IsAmsterdam && errors.Is(suberr, ErrContractAddressCollision) {
|
||||||
returnGas.RevertedStateGasSpill += returnGas.RegularGas
|
returnGas.CollisionConsumedGas += returnGas.RegularGas
|
||||||
returnGas.RegularGas = 0
|
returnGas.RegularGas = 0
|
||||||
}
|
}
|
||||||
scope.Contract.RefundGas(returnGas, evm.Config.Tracer, tracing.GasChangeCallLeftOverRefunded)
|
scope.Contract.RefundGas(returnGas, evm.Config.Tracer, tracing.GasChangeCallLeftOverRefunded)
|
||||||
|
|
@ -770,9 +771,10 @@ func opCreate2(pc *uint64, evm *EVM, scope *ScopeContext) ([]byte, error) {
|
||||||
returnGas.StateGas = stateGas
|
returnGas.StateGas = stateGas
|
||||||
}
|
}
|
||||||
// On address collision, child's regular gas is consumed (not returned).
|
// On address collision, child's regular gas is consumed (not returned).
|
||||||
// Track as RevertedStateGasSpill so block 2D accounting is unaffected.
|
// Track as CollisionConsumedGas so block 2D accounting is unaffected
|
||||||
|
// while the user still pays for the consumed gas (not refunded).
|
||||||
if evm.chainRules.IsAmsterdam && errors.Is(suberr, ErrContractAddressCollision) {
|
if evm.chainRules.IsAmsterdam && errors.Is(suberr, ErrContractAddressCollision) {
|
||||||
returnGas.RevertedStateGasSpill += returnGas.RegularGas
|
returnGas.CollisionConsumedGas += returnGas.RegularGas
|
||||||
returnGas.RegularGas = 0
|
returnGas.RegularGas = 0
|
||||||
}
|
}
|
||||||
scope.Contract.RefundGas(returnGas, evm.Config.Tracer, tracing.GasChangeCallLeftOverRefunded)
|
scope.Contract.RefundGas(returnGas, evm.Config.Tracer, tracing.GasChangeCallLeftOverRefunded)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue