Skip to content

Commit

Permalink
txpool: limit max gas when mining is enabled; (#2435)
Browse files Browse the repository at this point in the history
  • Loading branch information
galaio committed May 9, 2024
1 parent 901ea2e commit 7bc5a33
Show file tree
Hide file tree
Showing 9 changed files with 58 additions and 0 deletions.
6 changes: 6 additions & 0 deletions cmd/geth/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ import (
"strings"
"time"

"github.com/ethereum/go-ethereum/params"

"github.com/ethereum/go-ethereum/accounts"
"github.com/ethereum/go-ethereum/accounts/keystore"
"github.com/ethereum/go-ethereum/cmd/utils"
Expand Down Expand Up @@ -456,6 +458,10 @@ func startNode(ctx *cli.Context, stack *node.Node, backend ethapi.Backend, isCon
// Set the gas price to the limits from the CLI and start mining
gasprice := flags.GlobalBig(ctx, utils.MinerGasPriceFlag.Name)
ethBackend.TxPool().SetGasTip(gasprice)
gasCeil := ethBackend.Miner().GasCeil()
if gasCeil > params.SystemTxsGas {
ethBackend.TxPool().SetMaxGas(gasCeil - params.SystemTxsGas)
}
if err := ethBackend.StartMining(); err != nil {
utils.Fatalf("Failed to start mining: %v", err)
}
Expand Down
11 changes: 11 additions & 0 deletions core/txpool/blobpool/blobpool.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import (
"path/filepath"
"sort"
"sync"
"sync/atomic"
"time"

"github.com/ethereum/go-ethereum/common"
Expand Down Expand Up @@ -305,6 +306,7 @@ type BlobPool struct {
head *types.Header // Current head of the chain
state *state.StateDB // Current state at the head of the chain
gasTip *uint256.Int // Currently accepted minimum gas tip
maxGas atomic.Uint64 // Currently accepted max gas, it will be modified by MinerAPI

lookup map[common.Hash]uint64 // Lookup table mapping hashes to tx billy entries
index map[common.Address][]*blobTxMeta // Blob transactions grouped by accounts, sorted by nonce
Expand Down Expand Up @@ -1098,6 +1100,7 @@ func (p *BlobPool) validateTx(tx *types.Transaction) error {
Accept: 1 << types.BlobTxType,
MaxSize: txMaxSize,
MinTip: p.gasTip.ToBig(),
MaxGas: p.GetMaxGas(),
}
if err := txpool.ValidateTransaction(tx, p.head, p.signer, baseOpts); err != nil {
return err
Expand Down Expand Up @@ -1671,3 +1674,11 @@ func (p *BlobPool) Status(hash common.Hash) txpool.TxStatus {
}
return txpool.TxStatusUnknown
}

func (p *BlobPool) SetMaxGas(maxGas uint64) {
p.maxGas.Store(maxGas)
}

func (p *BlobPool) GetMaxGas() uint64 {
return p.maxGas.Load()
}
10 changes: 10 additions & 0 deletions core/txpool/legacypool/legacypool.go
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,7 @@ type LegacyPool struct {
scope event.SubscriptionScope
signer types.Signer
mu sync.RWMutex
maxGas atomic.Uint64 // Currently accepted max gas, it will be modified by MinerAPI

currentHead atomic.Pointer[types.Header] // Current head of the blockchain
currentState *state.StateDB // Current state in the blockchain head
Expand Down Expand Up @@ -670,6 +671,7 @@ func (pool *LegacyPool) validateTxBasics(tx *types.Transaction, local bool) erro
1<<types.DynamicFeeTxType,
MaxSize: txMaxSize,
MinTip: pool.gasTip.Load().ToBig(),
MaxGas: pool.GetMaxGas(),
}
if local {
opts.MinTip = new(big.Int)
Expand Down Expand Up @@ -1769,6 +1771,14 @@ func (pool *LegacyPool) demoteUnexecutables() {
}
}

func (pool *LegacyPool) GetMaxGas() uint64 {
return pool.maxGas.Load()
}

func (pool *LegacyPool) SetMaxGas(maxGas uint64) {
pool.maxGas.Store(maxGas)
}

// addressByHeartbeat is an account address tagged with its last activity timestamp.
type addressByHeartbeat struct {
address common.Address
Expand Down
3 changes: 3 additions & 0 deletions core/txpool/subpool.go
Original file line number Diff line number Diff line change
Expand Up @@ -166,4 +166,7 @@ type SubPool interface {
// Status returns the known status (unknown/pending/queued) of a transaction
// identified by their hashes.
Status(hash common.Hash) TxStatus

// SetMaxGas limit max acceptable tx gas when mine is enabled
SetMaxGas(maxGas uint64)
}
6 changes: 6 additions & 0 deletions core/txpool/txpool.go
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,12 @@ func (p *TxPool) SetGasTip(tip *big.Int) {
}
}

func (p *TxPool) SetMaxGas(gas uint64) {
for _, subpool := range p.subpools {
subpool.SetMaxGas(gas)
}
}

// Has returns an indicator whether the pool has a transaction cached with the
// given hash.
func (p *TxPool) Has(hash common.Hash) bool {
Expand Down
7 changes: 7 additions & 0 deletions core/txpool/validation.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ type ValidationOptions struct {
Accept uint8 // Bitmap of transaction types that should be accepted for the calling pool
MaxSize uint64 // Maximum size of a transaction that the caller can meaningfully handle
MinTip *big.Int // Minimum gas tip needed to allow a transaction into the caller pool
MaxGas uint64 // Max acceptable transaction gas in the txpool
}

// ValidateTransaction is a helper method to check whether a transaction is valid
Expand Down Expand Up @@ -86,6 +87,12 @@ func ValidateTransaction(tx *types.Transaction, head *types.Header, signer types
if head.GasLimit < tx.Gas() {
return ErrGasLimit
}

// Ensure the transaction doesn't exceed the current miner max acceptable limit gas
if opts.MaxGas > 0 && opts.MaxGas < tx.Gas() {
return ErrGasLimit
}

// Sanity check for extremely large numbers (supported by RLP or RPC)
if tx.GasFeeCap().BitLen() > 256 {
return core.ErrFeeCapVeryHigh
Expand Down
5 changes: 5 additions & 0 deletions eth/api_miner.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ import (
"math/big"
"time"

"github.com/ethereum/go-ethereum/params"

"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
)
Expand Down Expand Up @@ -71,6 +73,9 @@ func (api *MinerAPI) SetGasPrice(gasPrice hexutil.Big) bool {
// SetGasLimit sets the gaslimit to target towards during mining.
func (api *MinerAPI) SetGasLimit(gasLimit hexutil.Uint64) bool {
api.e.Miner().SetGasCeil(uint64(gasLimit))
if api.e.Miner().Mining() && uint64(gasLimit) > params.SystemTxsGas {
api.e.TxPool().SetMaxGas(uint64(gasLimit) - params.SystemTxsGas)
}
return true
}

Expand Down
4 changes: 4 additions & 0 deletions miner/miner.go
Original file line number Diff line number Diff line change
Expand Up @@ -295,3 +295,7 @@ func (miner *Miner) SubscribePendingLogs(ch chan<- []*types.Log) event.Subscript
func (miner *Miner) BuildPayload(args *BuildPayloadArgs) (*Payload, error) {
return miner.worker.buildPayload(args)
}

func (miner *Miner) GasCeil() uint64 {
return miner.worker.getGasCeil()
}
6 changes: 6 additions & 0 deletions miner/worker.go
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,12 @@ func (w *worker) setGasCeil(ceil uint64) {
w.config.GasCeil = ceil
}

func (w *worker) getGasCeil() uint64 {
w.mu.Lock()
defer w.mu.Unlock()
return w.config.GasCeil
}

// setExtra sets the content used to initialize the block extra field.
func (w *worker) setExtra(extra []byte) {
w.mu.Lock()
Expand Down

0 comments on commit 7bc5a33

Please sign in to comment.