Skip to content

Commit

Permalink
core: Check gasBailout before deducting balance in trace_call (#11813
Browse files Browse the repository at this point in the history
…) (#11866)

**Existing behaviour:**
- Add up the possible value that user must pay beforehand to buy gas
- Deduct that amount from the sender's account in `intraBlockState`,
but:
- Don't deduct the gas value amount if the user doesn't have enough, and
`gasBailout` is set

**New behaviour:**
- Don't check if sender's balance is enough to pay gas value amount, nor
deduct it, if `gasBailout` is set

**More rationale**
This would mean the sender's account would show `"balance": "="` in
`trace_call` rpc method, that is, no change, if gas is the only thing
the user pays for. This is fine because the gas price can fluctuate in a
real transaction. This also removes the inconsistency of sometimes
having to bother deducting the amount if it is less than sender's
balance, thereby causing a
bug/inconsistency.(#11813)
  • Loading branch information
somnathb1 authored Sep 4, 2024
1 parent d94de51 commit 4085099
Showing 1 changed file with 22 additions and 29 deletions.
51 changes: 22 additions & 29 deletions core/state_transition.go
Original file line number Diff line number Diff line change
Expand Up @@ -192,49 +192,42 @@ func (st *StateTransition) buyGas(gasBailout bool) error {
}
}

balanceCheck := gasVal
if st.gasFeeCap != nil {
balanceCheck = st.sharedBuyGasBalance.SetUint64(st.msg.Gas())
balanceCheck, overflow = balanceCheck.MulOverflow(balanceCheck, st.gasFeeCap)
if overflow {
return fmt.Errorf("%w: address %v", ErrInsufficientFunds, st.msg.From().Hex())
}
balanceCheck, overflow = balanceCheck.AddOverflow(balanceCheck, st.value)
if overflow {
return fmt.Errorf("%w: address %v", ErrInsufficientFunds, st.msg.From().Hex())
}
if st.evm.ChainRules().IsCancun {
maxBlobFee, overflow := new(uint256.Int).MulOverflow(st.msg.MaxFeePerBlobGas(), new(uint256.Int).SetUint64(st.msg.BlobGas()))
if !gasBailout {
balanceCheck := gasVal
if st.gasFeeCap != nil {
balanceCheck = st.sharedBuyGasBalance.SetUint64(st.msg.Gas())
balanceCheck, overflow = balanceCheck.MulOverflow(balanceCheck, st.gasFeeCap)
if overflow {
return fmt.Errorf("%w: address %v", ErrInsufficientFunds, st.msg.From().Hex())
}
balanceCheck, overflow = balanceCheck.AddOverflow(balanceCheck, maxBlobFee)
balanceCheck, overflow = balanceCheck.AddOverflow(balanceCheck, st.value)
if overflow {
return fmt.Errorf("%w: address %v", ErrInsufficientFunds, st.msg.From().Hex())
}
if st.evm.ChainRules().IsCancun {
maxBlobFee, overflow := new(uint256.Int).MulOverflow(st.msg.MaxFeePerBlobGas(), new(uint256.Int).SetUint64(st.msg.BlobGas()))
if overflow {
return fmt.Errorf("%w: address %v", ErrInsufficientFunds, st.msg.From().Hex())
}
balanceCheck, overflow = balanceCheck.AddOverflow(balanceCheck, maxBlobFee)
if overflow {
return fmt.Errorf("%w: address %v", ErrInsufficientFunds, st.msg.From().Hex())
}
}
}
}
var subBalance = false
if have, want := st.state.GetBalance(st.msg.From()), balanceCheck; have.Cmp(want) < 0 {
if !gasBailout {
if have, want := st.state.GetBalance(st.msg.From()), balanceCheck; have.Cmp(want) < 0 {
return fmt.Errorf("%w: address %v have %v want %v", ErrInsufficientFunds, st.msg.From().Hex(), have, want)
}
} else {
subBalance = true
st.state.SubBalance(st.msg.From(), gasVal, tracing.BalanceDecreaseGasBuy)
st.state.SubBalance(st.msg.From(), blobGasVal, tracing.BalanceDecreaseGasBuy)
}

if err := st.gp.SubGas(st.msg.Gas()); err != nil {
if !gasBailout {
return err
}
return err
}
st.gasRemaining += st.msg.Gas()
st.initialGas = st.msg.Gas()
st.evm.BlobFee = blobGasVal

if subBalance {
st.state.SubBalance(st.msg.From(), gasVal, tracing.BalanceDecreaseGasBuy)
st.state.SubBalance(st.msg.From(), blobGasVal, tracing.BalanceDecreaseGasBuy)
}
return nil
}

Expand Down Expand Up @@ -456,7 +449,7 @@ func (st *StateTransition) TransitionDb(refunds bool, gasBailout bool) (*evmtype
} else {
ret, st.gasRemaining, vmerr = st.evm.Call(sender, st.to(), st.data, st.gasRemaining, st.value, bailout)
}
if refunds {
if refunds && !gasBailout {
if rules.IsLondon {
// After EIP-3529: refunds are capped to gasUsed / 5
st.refundGas(params.RefundQuotientEIP3529)
Expand Down

0 comments on commit 4085099

Please sign in to comment.