Skip to content

Commit 03bc8b7

Browse files
holimanWeiLoy
andauthored
core: more efficient nonce-update in txpool (#22231)
* Adjust pending nonce update operation Benchmark the speed of transaction insertion under multiple accounts core: fix rebase issues + docstring core: make benchmark test use sync:ed method * core: address review comments * core: add memreport to benchmark Co-authored-by: WeiLoy <[email protected]>
1 parent f49e90e commit 03bc8b7

File tree

3 files changed

+36
-5
lines changed

3 files changed

+36
-5
lines changed

core/tx_noncer.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,3 +77,11 @@ func (txn *txNoncer) setIfLower(addr common.Address, nonce uint64) {
7777
}
7878
txn.nonces[addr] = nonce
7979
}
80+
81+
// setAll sets the nonces for all accounts to the given map.
82+
func (txn *txNoncer) setAll(all map[common.Address]uint64) {
83+
txn.lock.Lock()
84+
defer txn.lock.Unlock()
85+
86+
txn.nonces = all
87+
}

core/tx_pool.go

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1182,16 +1182,18 @@ func (pool *TxPool) runReorg(done chan struct{}, reset *txpoolResetRequest, dirt
11821182
pendingBaseFee := misc.CalcBaseFee(pool.chainconfig, reset.newHead)
11831183
pool.priced.SetBaseFee(pendingBaseFee)
11841184
}
1185+
// Update all accounts to the latest known pending nonce
1186+
nonces := make(map[common.Address]uint64, len(pool.pending))
1187+
for addr, list := range pool.pending {
1188+
highestPending := list.LastElement()
1189+
nonces[addr] = highestPending.Nonce() + 1
1190+
}
1191+
pool.pendingNonces.setAll(nonces)
11851192
}
11861193
// Ensure pool.queue and pool.pending sizes stay within the configured limits.
11871194
pool.truncatePending()
11881195
pool.truncateQueue()
11891196

1190-
// Update all accounts to the latest known pending nonce
1191-
for addr, list := range pool.pending {
1192-
highestPending := list.LastElement()
1193-
pool.pendingNonces.set(addr, highestPending.Nonce()+1)
1194-
}
11951197
dropBetweenReorgHistogram.Update(int64(pool.changesSinceReorg))
11961198
pool.changesSinceReorg = 0 // Reset change counter
11971199
pool.mu.Unlock()

core/tx_pool_test.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2540,3 +2540,24 @@ func BenchmarkInsertRemoteWithAllLocals(b *testing.B) {
25402540
pool.Stop()
25412541
}
25422542
}
2543+
2544+
// Benchmarks the speed of batch transaction insertion in case of multiple accounts.
2545+
func BenchmarkPoolMultiAccountBatchInsert(b *testing.B) {
2546+
// Generate a batch of transactions to enqueue into the pool
2547+
pool, _ := setupTxPool()
2548+
defer pool.Stop()
2549+
b.ReportAllocs()
2550+
batches := make(types.Transactions, b.N)
2551+
for i := 0; i < b.N; i++ {
2552+
key, _ := crypto.GenerateKey()
2553+
account := crypto.PubkeyToAddress(key.PublicKey)
2554+
pool.currentState.AddBalance(account, big.NewInt(1000000))
2555+
tx := transaction(uint64(0), 100000, key)
2556+
batches[i] = tx
2557+
}
2558+
// Benchmark importing the transactions into the queue
2559+
b.ResetTimer()
2560+
for _, tx := range batches {
2561+
pool.AddRemotesSync([]*types.Transaction{tx})
2562+
}
2563+
}

0 commit comments

Comments
 (0)