From 5c67d3942eb0eddf82716252fa3f2d81c454244c Mon Sep 17 00:00:00 2001 From: WeiLoy Date: Wed, 3 Jun 2020 18:21:24 +0800 Subject: [PATCH 1/3] 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/tx_noncer.go | 8 ++++++++ core/tx_pool.go | 12 +++++++----- core/tx_pool_test.go | 21 +++++++++++++++++++++ 3 files changed, 36 insertions(+), 5 deletions(-) diff --git a/core/tx_noncer.go b/core/tx_noncer.go index aa87c643aee2..d4e2f93245d8 100644 --- a/core/tx_noncer.go +++ b/core/tx_noncer.go @@ -77,3 +77,11 @@ func (txn *txNoncer) setIfLower(addr common.Address, nonce uint64) { } txn.nonces[addr] = nonce } + +// resetAll sets the nonces for all accounts to the given map. +func (txn *txNoncer) resetAll(all map[common.Address]uint64) { + txn.lock.Lock() + defer txn.lock.Unlock() + + txn.nonces = all +} diff --git a/core/tx_pool.go b/core/tx_pool.go index 4f627fcb9eba..13d038942000 100644 --- a/core/tx_pool.go +++ b/core/tx_pool.go @@ -1182,16 +1182,18 @@ func (pool *TxPool) runReorg(done chan struct{}, reset *txpoolResetRequest, dirt pendingBaseFee := misc.CalcBaseFee(pool.chainconfig, reset.newHead) pool.priced.SetBaseFee(pendingBaseFee) } + // Update all accounts to the latest known pending nonce + nonces := make(map[common.Address]uint64) + for addr, list := range pool.pending { + highestPending := list.LastElement() + nonces[addr] = highestPending.Nonce() + 1 + } + pool.pendingNonces.resetAll(nonces) } // Ensure pool.queue and pool.pending sizes stay within the configured limits. pool.truncatePending() pool.truncateQueue() - // Update all accounts to the latest known pending nonce - for addr, list := range pool.pending { - highestPending := list.LastElement() - pool.pendingNonces.set(addr, highestPending.Nonce()+1) - } dropBetweenReorgHistogram.Update(int64(pool.changesSinceReorg)) pool.changesSinceReorg = 0 // Reset change counter pool.mu.Unlock() diff --git a/core/tx_pool_test.go b/core/tx_pool_test.go index 1406c8df0264..879b69711615 100644 --- a/core/tx_pool_test.go +++ b/core/tx_pool_test.go @@ -2540,3 +2540,24 @@ func BenchmarkInsertRemoteWithAllLocals(b *testing.B) { pool.Stop() } } + +// Benchmarks the speed of batch transaction insertion in case of multiple accounts. +func BenchmarkPoolMultiAccountBatchInsert(b *testing.B) { + // Generate a batch of transactions to enqueue into the pool + pool, _ := setupTxPool() + defer pool.Stop() + + batches := make(types.Transactions, b.N) + for i := 0; i < b.N; 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 + b.ResetTimer() + for _, tx := range batches { + pool.AddRemotesSync([]*types.Transaction{tx}) + } +} From 0eb0005a447bcef27fe26efa82faf2a8ed6d5a0c Mon Sep 17 00:00:00 2001 From: Martin Holst Swende Date: Tue, 2 Nov 2021 11:06:40 +0100 Subject: [PATCH 2/3] core: address review comments --- core/tx_noncer.go | 4 ++-- core/tx_pool.go | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/core/tx_noncer.go b/core/tx_noncer.go index d4e2f93245d8..d6d220077507 100644 --- a/core/tx_noncer.go +++ b/core/tx_noncer.go @@ -78,8 +78,8 @@ func (txn *txNoncer) setIfLower(addr common.Address, nonce uint64) { txn.nonces[addr] = nonce } -// resetAll sets the nonces for all accounts to the given map. -func (txn *txNoncer) resetAll(all map[common.Address]uint64) { +// setAll sets the nonces for all accounts to the given map. +func (txn *txNoncer) setAll(all map[common.Address]uint64) { txn.lock.Lock() defer txn.lock.Unlock() diff --git a/core/tx_pool.go b/core/tx_pool.go index 13d038942000..3329d736a37f 100644 --- a/core/tx_pool.go +++ b/core/tx_pool.go @@ -1183,12 +1183,12 @@ func (pool *TxPool) runReorg(done chan struct{}, reset *txpoolResetRequest, dirt pool.priced.SetBaseFee(pendingBaseFee) } // Update all accounts to the latest known pending nonce - nonces := make(map[common.Address]uint64) + nonces := make(map[common.Address]uint64, len(pool.pending)) for addr, list := range pool.pending { highestPending := list.LastElement() nonces[addr] = highestPending.Nonce() + 1 } - pool.pendingNonces.resetAll(nonces) + pool.pendingNonces.setAll(nonces) } // Ensure pool.queue and pool.pending sizes stay within the configured limits. pool.truncatePending() From c5722dde8eb92039a1f6edf2ed9e2abb087e883c Mon Sep 17 00:00:00 2001 From: Martin Holst Swende Date: Tue, 2 Nov 2021 11:17:44 +0100 Subject: [PATCH 3/3] core: add memreport to benchmark --- core/tx_pool_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/tx_pool_test.go b/core/tx_pool_test.go index 879b69711615..a7af275835ac 100644 --- a/core/tx_pool_test.go +++ b/core/tx_pool_test.go @@ -2546,7 +2546,7 @@ func BenchmarkPoolMultiAccountBatchInsert(b *testing.B) { // Generate a batch of transactions to enqueue into the pool pool, _ := setupTxPool() defer pool.Stop() - + b.ReportAllocs() batches := make(types.Transactions, b.N) for i := 0; i < b.N; i++ { key, _ := crypto.GenerateKey()