txpool: limit max gas when mining is enabled; (#2435)
This commit is contained in:
parent
901ea2e0d2
commit
7bc5a3353d
@ -25,6 +25,8 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/params"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/accounts"
|
"github.com/ethereum/go-ethereum/accounts"
|
||||||
"github.com/ethereum/go-ethereum/accounts/keystore"
|
"github.com/ethereum/go-ethereum/accounts/keystore"
|
||||||
"github.com/ethereum/go-ethereum/cmd/utils"
|
"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
|
// Set the gas price to the limits from the CLI and start mining
|
||||||
gasprice := flags.GlobalBig(ctx, utils.MinerGasPriceFlag.Name)
|
gasprice := flags.GlobalBig(ctx, utils.MinerGasPriceFlag.Name)
|
||||||
ethBackend.TxPool().SetGasTip(gasprice)
|
ethBackend.TxPool().SetGasTip(gasprice)
|
||||||
|
gasCeil := ethBackend.Miner().GasCeil()
|
||||||
|
if gasCeil > params.SystemTxsGas {
|
||||||
|
ethBackend.TxPool().SetMaxGas(gasCeil - params.SystemTxsGas)
|
||||||
|
}
|
||||||
if err := ethBackend.StartMining(); err != nil {
|
if err := ethBackend.StartMining(); err != nil {
|
||||||
utils.Fatalf("Failed to start mining: %v", err)
|
utils.Fatalf("Failed to start mining: %v", err)
|
||||||
}
|
}
|
||||||
|
@ -27,6 +27,7 @@ import (
|
|||||||
"path/filepath"
|
"path/filepath"
|
||||||
"sort"
|
"sort"
|
||||||
"sync"
|
"sync"
|
||||||
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
@ -305,6 +306,7 @@ type BlobPool struct {
|
|||||||
head *types.Header // Current head of the chain
|
head *types.Header // Current head of the chain
|
||||||
state *state.StateDB // Current state at the head of the chain
|
state *state.StateDB // Current state at the head of the chain
|
||||||
gasTip *uint256.Int // Currently accepted minimum gas tip
|
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
|
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
|
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,
|
Accept: 1 << types.BlobTxType,
|
||||||
MaxSize: txMaxSize,
|
MaxSize: txMaxSize,
|
||||||
MinTip: p.gasTip.ToBig(),
|
MinTip: p.gasTip.ToBig(),
|
||||||
|
MaxGas: p.GetMaxGas(),
|
||||||
}
|
}
|
||||||
if err := txpool.ValidateTransaction(tx, p.head, p.signer, baseOpts); err != nil {
|
if err := txpool.ValidateTransaction(tx, p.head, p.signer, baseOpts); err != nil {
|
||||||
return err
|
return err
|
||||||
@ -1671,3 +1674,11 @@ func (p *BlobPool) Status(hash common.Hash) txpool.TxStatus {
|
|||||||
}
|
}
|
||||||
return txpool.TxStatusUnknown
|
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
|
scope event.SubscriptionScope
|
||||||
signer types.Signer
|
signer types.Signer
|
||||||
mu sync.RWMutex
|
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
|
currentHead atomic.Pointer[types.Header] // Current head of the blockchain
|
||||||
currentState *state.StateDB // Current state in the blockchain head
|
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,
|
1<<types.DynamicFeeTxType,
|
||||||
MaxSize: txMaxSize,
|
MaxSize: txMaxSize,
|
||||||
MinTip: pool.gasTip.Load().ToBig(),
|
MinTip: pool.gasTip.Load().ToBig(),
|
||||||
|
MaxGas: pool.GetMaxGas(),
|
||||||
}
|
}
|
||||||
if local {
|
if local {
|
||||||
opts.MinTip = new(big.Int)
|
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.
|
// addressByHeartbeat is an account address tagged with its last activity timestamp.
|
||||||
type addressByHeartbeat struct {
|
type addressByHeartbeat struct {
|
||||||
address common.Address
|
address common.Address
|
||||||
|
@ -166,4 +166,7 @@ type SubPool interface {
|
|||||||
// Status returns the known status (unknown/pending/queued) of a transaction
|
// Status returns the known status (unknown/pending/queued) of a transaction
|
||||||
// identified by their hashes.
|
// identified by their hashes.
|
||||||
Status(hash common.Hash) TxStatus
|
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
|
// Has returns an indicator whether the pool has a transaction cached with the
|
||||||
// given hash.
|
// given hash.
|
||||||
func (p *TxPool) Has(hash common.Hash) bool {
|
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
|
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
|
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
|
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
|
// 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() {
|
if head.GasLimit < tx.Gas() {
|
||||||
return ErrGasLimit
|
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)
|
// Sanity check for extremely large numbers (supported by RLP or RPC)
|
||||||
if tx.GasFeeCap().BitLen() > 256 {
|
if tx.GasFeeCap().BitLen() > 256 {
|
||||||
return core.ErrFeeCapVeryHigh
|
return core.ErrFeeCapVeryHigh
|
||||||
|
@ -20,6 +20,8 @@ import (
|
|||||||
"math/big"
|
"math/big"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/params"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
"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.
|
// SetGasLimit sets the gaslimit to target towards during mining.
|
||||||
func (api *MinerAPI) SetGasLimit(gasLimit hexutil.Uint64) bool {
|
func (api *MinerAPI) SetGasLimit(gasLimit hexutil.Uint64) bool {
|
||||||
api.e.Miner().SetGasCeil(uint64(gasLimit))
|
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
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -295,3 +295,7 @@ func (miner *Miner) SubscribePendingLogs(ch chan<- []*types.Log) event.Subscript
|
|||||||
func (miner *Miner) BuildPayload(args *BuildPayloadArgs) (*Payload, error) {
|
func (miner *Miner) BuildPayload(args *BuildPayloadArgs) (*Payload, error) {
|
||||||
return miner.worker.buildPayload(args)
|
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
|
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.
|
// setExtra sets the content used to initialize the block extra field.
|
||||||
func (w *worker) setExtra(extra []byte) {
|
func (w *worker) setExtra(extra []byte) {
|
||||||
w.mu.Lock()
|
w.mu.Lock()
|
||||||
|
Loading…
Reference in New Issue
Block a user