Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix gas balance validation issue when balance < gas cost < SGT balance #14

Merged
merged 3 commits into from
Oct 26, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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()
qizhou marked this conversation as resolved.
Show resolved Hide resolved

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