mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-27 23:26:44 +00:00
feat(worker): try to limit the number of txns miner has to deal with (#745)
to reduce the effect of having a huge backlog on performance
This commit is contained in:
parent
abca104d18
commit
12871c7745
10 changed files with 59 additions and 5 deletions
|
|
@ -131,6 +131,7 @@ var (
|
|||
utils.MinerRecommitIntervalFlag,
|
||||
utils.MinerNoVerifyFlag,
|
||||
utils.MinerStoreSkippedTxTracesFlag,
|
||||
utils.MinerMaxAccountsNumFlag,
|
||||
utils.NATFlag,
|
||||
utils.NoDiscoverFlag,
|
||||
utils.DiscoveryV5Flag,
|
||||
|
|
|
|||
|
|
@ -194,6 +194,7 @@ var AppHelpFlagGroups = []flags.FlagGroup{
|
|||
utils.MinerRecommitIntervalFlag,
|
||||
utils.MinerNoVerifyFlag,
|
||||
utils.MinerStoreSkippedTxTracesFlag,
|
||||
utils.MinerMaxAccountsNumFlag,
|
||||
},
|
||||
},
|
||||
{
|
||||
|
|
|
|||
|
|
@ -500,6 +500,11 @@ var (
|
|||
Name: "miner.storeskippedtxtraces",
|
||||
Usage: "Store the wrapped traces when storing a skipped tx",
|
||||
}
|
||||
MinerMaxAccountsNumFlag = cli.IntFlag{
|
||||
Name: "miner.maxaccountsnum",
|
||||
Usage: "Maximum number of accounts that miner will fetch the pending transactions of when building a new block",
|
||||
Value: math.MaxInt,
|
||||
}
|
||||
// Account settings
|
||||
UnlockedAccountFlag = cli.StringFlag{
|
||||
Name: "unlock",
|
||||
|
|
@ -1519,6 +1524,9 @@ func setMiner(ctx *cli.Context, cfg *miner.Config) {
|
|||
if ctx.GlobalIsSet(MinerStoreSkippedTxTracesFlag.Name) {
|
||||
cfg.StoreSkippedTxTraces = ctx.GlobalBool(MinerStoreSkippedTxTracesFlag.Name)
|
||||
}
|
||||
if ctx.GlobalIsSet(MinerMaxAccountsNumFlag.Name) {
|
||||
cfg.MaxAccountsNum = ctx.GlobalInt(MinerMaxAccountsNumFlag.Name)
|
||||
}
|
||||
if ctx.GlobalIsSet(LegacyMinerGasTargetFlag.Name) {
|
||||
log.Warn("The generic --miner.gastarget flag is deprecated and will be removed in the future!")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -537,6 +537,16 @@ func (pool *TxPool) ContentFrom(addr common.Address) (types.Transactions, types.
|
|||
// transactions and only return those whose **effective** tip is large enough in
|
||||
// the next pending execution environment.
|
||||
func (pool *TxPool) Pending(enforceTips bool) map[common.Address]types.Transactions {
|
||||
return pool.pendingWithMax(enforceTips, math.MaxInt)
|
||||
}
|
||||
|
||||
// PendingWithMax works similar to Pending but allows setting an upper limit on how many
|
||||
// accounts to return
|
||||
func (pool *TxPool) PendingWithMax(enforceTips bool, maxAccountsNum int) map[common.Address]types.Transactions {
|
||||
return pool.pendingWithMax(enforceTips, maxAccountsNum)
|
||||
}
|
||||
|
||||
func (pool *TxPool) pendingWithMax(enforceTips bool, maxAccountsNum int) map[common.Address]types.Transactions {
|
||||
pool.mu.Lock()
|
||||
defer pool.mu.Unlock()
|
||||
|
||||
|
|
@ -555,6 +565,9 @@ func (pool *TxPool) Pending(enforceTips bool) map[common.Address]types.Transacti
|
|||
}
|
||||
if len(txs) > 0 {
|
||||
pending[addr] = txs
|
||||
if len(pending) >= maxAccountsNum {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
return pending
|
||||
|
|
|
|||
|
|
@ -28,6 +28,8 @@ import (
|
|||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/scroll-tech/go-ethereum/common"
|
||||
"github.com/scroll-tech/go-ethereum/core/rawdb"
|
||||
"github.com/scroll-tech/go-ethereum/core/state"
|
||||
|
|
@ -2575,3 +2577,27 @@ func BenchmarkPoolMultiAccountBatchInsert(b *testing.B) {
|
|||
pool.AddRemotesSync([]*types.Transaction{tx})
|
||||
}
|
||||
}
|
||||
|
||||
func TestPoolPending(t *testing.T) {
|
||||
// Generate a batch of transactions to enqueue into the pool
|
||||
pool, _ := setupTxPool()
|
||||
defer pool.Stop()
|
||||
numTxns := 100
|
||||
batches := make(types.Transactions, numTxns)
|
||||
for i := 0; i < numTxns; i++ {
|
||||
key, _ := crypto.GenerateKey()
|
||||
account := crypto.PubkeyToAddress(key.PublicKey)
|
||||
pool.currentState.AddBalance(account, big.NewInt(1000000))
|
||||
tx := transaction(uint64(0), 100000, key)
|
||||
batches[i] = tx
|
||||
}
|
||||
// Benchmark importing the transactions into the queue
|
||||
for _, tx := range batches {
|
||||
pool.AddRemotesSync([]*types.Transaction{tx})
|
||||
}
|
||||
|
||||
assert.Len(t, pool.Pending(false), numTxns)
|
||||
|
||||
maxAccounts := 10
|
||||
assert.Len(t, pool.PendingWithMax(false, maxAccounts), maxAccounts)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -58,6 +58,7 @@ type Config struct {
|
|||
Noverify bool // Disable remote mining solution verification(only useful in ethash).
|
||||
|
||||
StoreSkippedTxTraces bool // Whether store the wrapped traces when storing a skipped tx
|
||||
MaxAccountsNum int // Maximum number of accounts that miner will fetch the pending transactions of when building a new block
|
||||
}
|
||||
|
||||
// Miner creates blocks and searches for proof-of-work values.
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@
|
|||
package miner
|
||||
|
||||
import (
|
||||
"math"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
|
|
@ -244,7 +245,8 @@ func waitForMiningState(t *testing.T, m *Miner, mining bool) {
|
|||
func createMiner(t *testing.T) (*Miner, *event.TypeMux) {
|
||||
// Create Ethash config
|
||||
config := Config{
|
||||
Etherbase: common.HexToAddress("123456789"),
|
||||
Etherbase: common.HexToAddress("123456789"),
|
||||
MaxAccountsNum: math.MaxInt,
|
||||
}
|
||||
// Create chainConfig
|
||||
memdb := memorydb.New()
|
||||
|
|
|
|||
|
|
@ -1446,7 +1446,7 @@ func (w *worker) commitNewWork(interrupt *int32, noempty bool, timestamp int64)
|
|||
|
||||
tidyPendingStart := time.Now()
|
||||
// Fill the block with all available pending transactions.
|
||||
pending := w.eth.TxPool().Pending(false)
|
||||
pending := w.eth.TxPool().PendingWithMax(false, w.config.MaxAccountsNum)
|
||||
// Short circuit if there is no available pending transactions.
|
||||
// But if we disable empty precommit already, ignore it. Since
|
||||
// empty block is necessary to keep the liveness of the network.
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
package miner
|
||||
|
||||
import (
|
||||
"math"
|
||||
"math/big"
|
||||
"math/rand"
|
||||
"sync/atomic"
|
||||
|
|
@ -70,8 +71,9 @@ var (
|
|||
newTxs []*types.Transaction
|
||||
|
||||
testConfig = &Config{
|
||||
Recommit: time.Second,
|
||||
GasCeil: params.GenesisGasLimit,
|
||||
Recommit: time.Second,
|
||||
GasCeil: params.GenesisGasLimit,
|
||||
MaxAccountsNum: math.MaxInt,
|
||||
}
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ import (
|
|||
const (
|
||||
VersionMajor = 5 // Major version component of the current release
|
||||
VersionMinor = 3 // Minor version component of the current release
|
||||
VersionPatch = 14 // Patch version component of the current release
|
||||
VersionPatch = 15 // Patch version component of the current release
|
||||
VersionMeta = "mainnet" // Version metadata to append to the version string
|
||||
)
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue