txpool: limit max gas when mining is enabled; (#2435)
This commit is contained in:
parent
901ea2e0d2
commit
7bc5a3353d
@ -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"
|
||||
@ -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)
|
||||
}
|
||||
|
@ -27,6 +27,7 @@ import (
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
@ -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
|
||||
@ -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
|
||||
@ -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()
|
||||
}
|
||||
|
@ -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
|
||||
@ -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)
|
||||
@ -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
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
@ -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
|
||||
|
@ -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"
|
||||
)
|
||||
@ -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
|
||||
}
|
||||
|
||||
|
@ -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()
|
||||
}
|
||||
|
@ -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()
|
||||
|
Loading…
Reference in New Issue
Block a user