Skip to content

Commit

Permalink
fix gas balance validation issue when balance < gas cost < SGT balance
Browse files Browse the repository at this point in the history
  • Loading branch information
Qi Zhou committed Oct 24, 2024
1 parent a248e78 commit 39f0ef9
Show file tree
Hide file tree
Showing 5 changed files with 33 additions and 14 deletions.
27 changes: 27 additions & 0 deletions core/state_transition.go
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,33 @@ func (st *StateTransition) GetSoulBalance(account common.Address) *uint256.Int {
return balance
}

func GetEffectiveGasBalance(state vm.StateDB, chainconfig *params.ChainConfig, account common.Address) *uint256.Int {
bal, sgtBal := GetGasBalances(state, chainconfig, account)
if bal.Cmp(sgtBal) < 0 {
return sgtBal
}

return bal
}

func GetGasBalances(state vm.StateDB, chainconfig *params.ChainConfig, account common.Address) (*uint256.Int, *uint256.Int) {
balance := state.GetBalance(account)
if chainconfig != nil && chainconfig.IsOptimism() && chainconfig.Optimism.UseSoulGasToken {
sgtBalanceSlot := TargetSGTBalanceSlot(account)
sgtBalanceValue := state.GetState(types.SoulGasTokenAddr, sgtBalanceSlot)
sgtBalance := new(uint256.Int).SetBytes(sgtBalanceValue[:])

return balance, sgtBalance
}

return balance, uint256.NewInt(0)
}

func GetGasBalancesInBig(state vm.StateDB, chainconfig *params.ChainConfig, account common.Address) (*big.Int, *big.Int) {
bal, sgtBal := GetGasBalances(state, chainconfig, account)
return bal.ToBig(), sgtBal.ToBig()
}

func (st *StateTransition) SubSoulBalance(account common.Address, amount *big.Int, reason tracing.BalanceChangeReason) (err error) {
current := st.GetSoulBalance(account).ToBig()
if current.Cmp(amount) < 0 {
Expand Down
2 changes: 1 addition & 1 deletion core/txpool/blobpool/blobpool.go
Original file line number Diff line number Diff line change
Expand Up @@ -668,7 +668,7 @@ func (p *BlobPool) recheck(addr common.Address, inclusions map[common.Hash]uint6
// Ensure that there's no over-draft, this is expected to happen when some
// transactions get included without publishing on the network
var (
balance = p.state.GetBalance(addr)
balance = core.GetEffectiveGasBalance(p.state, p.chain.Config(), addr)
spent = p.spent[addr]
)
if spent.Cmp(balance) > 0 {
Expand Down
4 changes: 2 additions & 2 deletions core/txpool/legacypool/legacypool.go
Original file line number Diff line number Diff line change
Expand Up @@ -1520,7 +1520,7 @@ func (pool *LegacyPool) promoteExecutables(accounts []common.Address) []*types.T
pool.all.Remove(hash)
}
log.Trace("Removed old queued transactions", "count", len(forwards))
balance := pool.currentState.GetBalance(addr)
balance := core.GetEffectiveGasBalance(pool.currentState, pool.chainconfig, addr)
balance = pool.reduceBalanceByL1Cost(list, balance)
// Drop all transactions that are too costly (low balance or out of gas)
drops, _ := list.Filter(balance, gasLimit)
Expand Down Expand Up @@ -1723,7 +1723,7 @@ func (pool *LegacyPool) demoteUnexecutables() {
pool.all.Remove(hash)
log.Trace("Removed old pending transaction", "hash", hash)
}
balance := pool.currentState.GetBalance(addr)
balance := core.GetEffectiveGasBalance(pool.currentState, pool.chainconfig, addr)
balance = pool.reduceBalanceByL1Cost(list, balance)
// Drop all transactions that are too costly (low balance or out of gas), and queue any invalids back for later
drops, invalids := list.Filter(balance, gasLimit)
Expand Down
12 changes: 2 additions & 10 deletions core/txpool/validation.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ import (
"github.com/ethereum/go-ethereum/crypto/kzg4844"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/params"
"github.com/holiman/uint256"
)

// L1 Info Gas Overhead is the amount of gas the the L1 info deposit consumes.
Expand Down Expand Up @@ -254,17 +253,10 @@ func ValidateTransactionWithState(tx *types.Transaction, signer types.Signer, op
}
// Ensure the transactor has enough funds to cover the transaction costs
var (
balance = opts.State.GetBalance(from).ToBig()
cost = tx.Cost()
balance, sgtBalance = core.GetGasBalancesInBig(opts.State, opts.Chainconfig, from)
cost = tx.Cost()
)

sgtBalance := new(big.Int)
if opts.Chainconfig != nil && opts.Chainconfig.IsOptimism() && opts.Chainconfig.Optimism.UseSoulGasToken {
sgtBalanceSlot := core.TargetSGTBalanceSlot(from)
sgtBalanceValue := opts.State.GetState(types.SoulGasTokenAddr, sgtBalanceSlot)
sgtBalance = new(uint256.Int).SetBytes(sgtBalanceValue[:]).ToBig()
}

if opts.L1CostFn != nil {
if l1Cost := opts.L1CostFn(tx.RollupCostData()); l1Cost != nil { // add rollup cost
cost = cost.Add(cost, l1Cost)
Expand Down
2 changes: 1 addition & 1 deletion eth/gasestimator/gasestimator.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ func Estimate(ctx context.Context, call *core.Message, opts *Options, gasCap uin
}
// Recap the highest gas limit with account's available balance.
if feeCap.BitLen() != 0 {
balance := opts.State.GetBalance(call.From).ToBig()
balance := core.GetEffectiveGasBalance(opts.State, opts.Config, call.From).ToBig()

available := balance
if call.Value != nil {
Expand Down

0 comments on commit 39f0ef9

Please sign in to comment.