Skip to content

Commit 80ff0b4

Browse files
authored
core/txpool: use atomic int added in go1.19 (#26913)
Makes use of atomic.Uint64 instead of atomic by pointer
1 parent 81b0aa0 commit 80ff0b4

File tree

4 files changed

+39
-37
lines changed

4 files changed

+39
-37
lines changed

core/txpool/list.go

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -508,10 +508,7 @@ func (h *priceHeap) Pop() interface{} {
508508
// the floating heap is better. When baseFee is decreasing they behave similarly.
509509
type pricedList struct {
510510
// Number of stale price points to (re-heap trigger).
511-
// This field is accessed atomically, and must be the first field
512-
// to ensure it has correct alignment for atomic.AddInt64.
513-
// See https://golang.org/pkg/sync/atomic/#pkg-note-BUG.
514-
stales int64
511+
stales atomic.Int64
515512

516513
all *lookup // Pointer to the map of all transactions
517514
urgent, floating priceHeap // Heaps of prices of all the stored **remote** transactions
@@ -545,7 +542,7 @@ func (l *pricedList) Put(tx *types.Transaction, local bool) {
545542
// the heap if a large enough ratio of transactions go stale.
546543
func (l *pricedList) Removed(count int) {
547544
// Bump the stale counter, but exit if still too low (< 25%)
548-
stales := atomic.AddInt64(&l.stales, int64(count))
545+
stales := l.stales.Add(int64(count))
549546
if int(stales) <= (len(l.urgent.list)+len(l.floating.list))/4 {
550547
return
551548
}
@@ -570,7 +567,7 @@ func (l *pricedList) underpricedFor(h *priceHeap, tx *types.Transaction) bool {
570567
for len(h.list) > 0 {
571568
head := h.list[0]
572569
if l.all.GetRemote(head.Hash()) == nil { // Removed or migrated
573-
atomic.AddInt64(&l.stales, -1)
570+
l.stales.Add(-1)
574571
heap.Pop(h)
575572
continue
576573
}
@@ -597,7 +594,7 @@ func (l *pricedList) Discard(slots int, force bool) (types.Transactions, bool) {
597594
// Discard stale transactions if found during cleanup
598595
tx := heap.Pop(&l.urgent).(*types.Transaction)
599596
if l.all.GetRemote(tx.Hash()) == nil { // Removed or migrated
600-
atomic.AddInt64(&l.stales, -1)
597+
l.stales.Add(-1)
601598
continue
602599
}
603600
// Non stale transaction found, move to floating heap
@@ -610,7 +607,7 @@ func (l *pricedList) Discard(slots int, force bool) (types.Transactions, bool) {
610607
// Discard stale transactions if found during cleanup
611608
tx := heap.Pop(&l.floating).(*types.Transaction)
612609
if l.all.GetRemote(tx.Hash()) == nil { // Removed or migrated
613-
atomic.AddInt64(&l.stales, -1)
610+
l.stales.Add(-1)
614611
continue
615612
}
616613
// Non stale transaction found, discard it
@@ -633,7 +630,7 @@ func (l *pricedList) Reheap() {
633630
l.reheapMu.Lock()
634631
defer l.reheapMu.Unlock()
635632
start := time.Now()
636-
atomic.StoreInt64(&l.stales, 0)
633+
l.stales.Store(0)
637634
l.urgent.list = make([]*types.Transaction, 0, l.all.RemoteCount())
638635
l.all.Range(func(hash common.Hash, tx *types.Transaction, local bool) bool {
639636
l.urgent.list = append(l.urgent.list, tx)

core/txpool/txpool.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ import (
2323
"math/big"
2424
"sort"
2525
"sync"
26-
"sync/atomic"
2726
"time"
2827

2928
"github.com/ethereum/go-ethereum/common"
@@ -383,7 +382,7 @@ func (pool *TxPool) loop() {
383382
pool.mu.RLock()
384383
pending, queued := pool.stats()
385384
pool.mu.RUnlock()
386-
stales := int(atomic.LoadInt64(&pool.priced.stales))
385+
stales := int(pool.priced.stales.Load())
387386

388387
if pending != prevPending || queued != prevQueued || stales != prevStales {
389388
log.Debug("Transaction pool status report", "executable", pending, "queued", queued, "stales", stales)

core/txpool/txpool2_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ func TestTransactionFutureAttack(t *testing.T) {
7979

8080
// Create the pool to test the limit enforcement with
8181
statedb, _ := state.New(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil)
82-
blockchain := &testBlockChain{1000000, statedb, new(event.Feed)}
82+
blockchain := newTestBlockChain(1000000, statedb, new(event.Feed))
8383
config := testTxPoolConfig
8484
config.GlobalQueue = 100
8585
config.GlobalSlots = 100
@@ -115,7 +115,7 @@ func TestTransactionFuture1559(t *testing.T) {
115115
t.Parallel()
116116
// Create the pool to test the pricing enforcement with
117117
statedb, _ := state.New(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil)
118-
blockchain := &testBlockChain{1000000, statedb, new(event.Feed)}
118+
blockchain := newTestBlockChain(1000000, statedb, new(event.Feed))
119119
pool := NewTxPool(testTxPoolConfig, eip1559Config, blockchain)
120120
defer pool.Stop()
121121

@@ -147,7 +147,7 @@ func TestTransactionZAttack(t *testing.T) {
147147
t.Parallel()
148148
// Create the pool to test the pricing enforcement with
149149
statedb, _ := state.New(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil)
150-
blockchain := &testBlockChain{1000000, statedb, new(event.Feed)}
150+
blockchain := newTestBlockChain(1000000, statedb, new(event.Feed))
151151
pool := NewTxPool(testTxPoolConfig, eip1559Config, blockchain)
152152
defer pool.Stop()
153153
// Create a number of test accounts, fund them and make transactions

core/txpool/txpool_test.go

Lines changed: 29 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -59,15 +59,21 @@ func init() {
5959
}
6060

6161
type testBlockChain struct {
62-
gasLimit uint64 // must be first field for 64 bit alignment (atomic access)
62+
gasLimit atomic.Uint64
6363
statedb *state.StateDB
6464
chainHeadFeed *event.Feed
6565
}
6666

67+
func newTestBlockChain(gasLimit uint64, statedb *state.StateDB, chainHeadFeed *event.Feed) *testBlockChain {
68+
bc := testBlockChain{statedb: statedb, chainHeadFeed: new(event.Feed)}
69+
bc.gasLimit.Store(gasLimit)
70+
return &bc
71+
}
72+
6773
func (bc *testBlockChain) CurrentBlock() *types.Header {
6874
return &types.Header{
6975
Number: new(big.Int),
70-
GasLimit: atomic.LoadUint64(&bc.gasLimit),
76+
GasLimit: bc.gasLimit.Load(),
7177
}
7278
}
7379

@@ -121,7 +127,7 @@ func setupPool() (*TxPool, *ecdsa.PrivateKey) {
121127

122128
func setupPoolWithConfig(config *params.ChainConfig) (*TxPool, *ecdsa.PrivateKey) {
123129
statedb, _ := state.New(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil)
124-
blockchain := &testBlockChain{10000000, statedb, new(event.Feed)}
130+
blockchain := newTestBlockChain(10000000, statedb, new(event.Feed))
125131

126132
key, _ := crypto.GenerateKey()
127133
pool := NewTxPool(testTxPoolConfig, config, blockchain)
@@ -236,7 +242,7 @@ func TestStateChangeDuringReset(t *testing.T) {
236242

237243
// setup pool with 2 transaction in it
238244
statedb.SetBalance(address, new(big.Int).SetUint64(params.Ether))
239-
blockchain := &testChain{&testBlockChain{1000000000, statedb, new(event.Feed)}, address, &trigger}
245+
blockchain := &testChain{newTestBlockChain(1000000000, statedb, new(event.Feed)), address, &trigger}
240246

241247
tx0 := transaction(0, 100000, key)
242248
tx1 := transaction(1, 100000, key)
@@ -430,7 +436,7 @@ func TestChainFork(t *testing.T) {
430436
statedb, _ := state.New(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil)
431437
statedb.AddBalance(addr, big.NewInt(100000000000000))
432438

433-
pool.chain = &testBlockChain{1000000, statedb, new(event.Feed)}
439+
pool.chain = newTestBlockChain(1000000, statedb, new(event.Feed))
434440
<-pool.requestReset(nil, nil)
435441
}
436442
resetState()
@@ -459,7 +465,7 @@ func TestDoubleNonce(t *testing.T) {
459465
statedb, _ := state.New(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil)
460466
statedb.AddBalance(addr, big.NewInt(100000000000000))
461467

462-
pool.chain = &testBlockChain{1000000, statedb, new(event.Feed)}
468+
pool.chain = newTestBlockChain(1000000, statedb, new(event.Feed))
463469
<-pool.requestReset(nil, nil)
464470
}
465471
resetState()
@@ -629,7 +635,7 @@ func TestDropping(t *testing.T) {
629635
t.Errorf("total transaction mismatch: have %d, want %d", pool.all.Count(), 4)
630636
}
631637
// Reduce the block gas limit, check that invalidated transactions are dropped
632-
atomic.StoreUint64(&pool.chain.(*testBlockChain).gasLimit, 100)
638+
pool.chain.(*testBlockChain).gasLimit.Store(100)
633639
<-pool.requestReset(nil, nil)
634640

635641
if _, ok := pool.pending[account].txs.items[tx0.Nonce()]; !ok {
@@ -657,7 +663,7 @@ func TestPostponing(t *testing.T) {
657663

658664
// Create the pool to test the postponing with
659665
statedb, _ := state.New(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil)
660-
blockchain := &testBlockChain{1000000, statedb, new(event.Feed)}
666+
blockchain := newTestBlockChain(1000000, statedb, new(event.Feed))
661667

662668
pool := NewTxPool(testTxPoolConfig, params.TestChainConfig, blockchain)
663669
defer pool.Stop()
@@ -869,7 +875,7 @@ func testQueueGlobalLimiting(t *testing.T, nolocals bool) {
869875

870876
// Create the pool to test the limit enforcement with
871877
statedb, _ := state.New(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil)
872-
blockchain := &testBlockChain{1000000, statedb, new(event.Feed)}
878+
blockchain := newTestBlockChain(1000000, statedb, new(event.Feed))
873879

874880
config := testTxPoolConfig
875881
config.NoLocals = nolocals
@@ -961,7 +967,7 @@ func testQueueTimeLimiting(t *testing.T, nolocals bool) {
961967

962968
// Create the pool to test the non-expiration enforcement
963969
statedb, _ := state.New(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil)
964-
blockchain := &testBlockChain{1000000, statedb, new(event.Feed)}
970+
blockchain := newTestBlockChain(1000000, statedb, new(event.Feed))
965971

966972
config := testTxPoolConfig
967973
config.Lifetime = time.Second
@@ -1146,7 +1152,7 @@ func TestPendingGlobalLimiting(t *testing.T) {
11461152

11471153
// Create the pool to test the limit enforcement with
11481154
statedb, _ := state.New(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil)
1149-
blockchain := &testBlockChain{1000000, statedb, new(event.Feed)}
1155+
blockchain := newTestBlockChain(1000000, statedb, new(event.Feed))
11501156

11511157
config := testTxPoolConfig
11521158
config.GlobalSlots = config.AccountSlots * 10
@@ -1248,7 +1254,7 @@ func TestCapClearsFromAll(t *testing.T) {
12481254

12491255
// Create the pool to test the limit enforcement with
12501256
statedb, _ := state.New(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil)
1251-
blockchain := &testBlockChain{1000000, statedb, new(event.Feed)}
1257+
blockchain := newTestBlockChain(1000000, statedb, new(event.Feed))
12521258

12531259
config := testTxPoolConfig
12541260
config.AccountSlots = 2
@@ -1282,7 +1288,7 @@ func TestPendingMinimumAllowance(t *testing.T) {
12821288

12831289
// Create the pool to test the limit enforcement with
12841290
statedb, _ := state.New(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil)
1285-
blockchain := &testBlockChain{1000000, statedb, new(event.Feed)}
1291+
blockchain := newTestBlockChain(1000000, statedb, new(event.Feed))
12861292

12871293
config := testTxPoolConfig
12881294
config.GlobalSlots = 1
@@ -1330,7 +1336,7 @@ func TestRepricing(t *testing.T) {
13301336

13311337
// Create the pool to test the pricing enforcement with
13321338
statedb, _ := state.New(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil)
1333-
blockchain := &testBlockChain{1000000, statedb, new(event.Feed)}
1339+
blockchain := newTestBlockChain(1000000, statedb, new(event.Feed))
13341340

13351341
pool := NewTxPool(testTxPoolConfig, params.TestChainConfig, blockchain)
13361342
defer pool.Stop()
@@ -1578,7 +1584,7 @@ func TestRepricingKeepsLocals(t *testing.T) {
15781584

15791585
// Create the pool to test the pricing enforcement with
15801586
statedb, _ := state.New(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil)
1581-
blockchain := &testBlockChain{1000000, statedb, new(event.Feed)}
1587+
blockchain := newTestBlockChain(1000000, statedb, new(event.Feed))
15821588

15831589
pool := NewTxPool(testTxPoolConfig, eip1559Config, blockchain)
15841590
defer pool.Stop()
@@ -1651,7 +1657,7 @@ func TestUnderpricing(t *testing.T) {
16511657

16521658
// Create the pool to test the pricing enforcement with
16531659
statedb, _ := state.New(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil)
1654-
blockchain := &testBlockChain{1000000, statedb, new(event.Feed)}
1660+
blockchain := newTestBlockChain(1000000, statedb, new(event.Feed))
16551661

16561662
config := testTxPoolConfig
16571663
config.GlobalSlots = 2
@@ -1765,7 +1771,7 @@ func TestStableUnderpricing(t *testing.T) {
17651771

17661772
// Create the pool to test the pricing enforcement with
17671773
statedb, _ := state.New(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil)
1768-
blockchain := &testBlockChain{1000000, statedb, new(event.Feed)}
1774+
blockchain := newTestBlockChain(1000000, statedb, new(event.Feed))
17691775

17701776
config := testTxPoolConfig
17711777
config.GlobalSlots = 128
@@ -1997,7 +2003,7 @@ func TestDeduplication(t *testing.T) {
19972003

19982004
// Create the pool to test the pricing enforcement with
19992005
statedb, _ := state.New(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil)
2000-
blockchain := &testBlockChain{1000000, statedb, new(event.Feed)}
2006+
blockchain := newTestBlockChain(1000000, statedb, new(event.Feed))
20012007

20022008
pool := NewTxPool(testTxPoolConfig, params.TestChainConfig, blockchain)
20032009
defer pool.Stop()
@@ -2063,7 +2069,7 @@ func TestReplacement(t *testing.T) {
20632069

20642070
// Create the pool to test the pricing enforcement with
20652071
statedb, _ := state.New(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil)
2066-
blockchain := &testBlockChain{1000000, statedb, new(event.Feed)}
2072+
blockchain := newTestBlockChain(1000000, statedb, new(event.Feed))
20672073

20682074
pool := NewTxPool(testTxPoolConfig, params.TestChainConfig, blockchain)
20692075
defer pool.Stop()
@@ -2268,7 +2274,7 @@ func testJournaling(t *testing.T, nolocals bool) {
22682274

22692275
// Create the original pool to inject transaction into the journal
22702276
statedb, _ := state.New(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil)
2271-
blockchain := &testBlockChain{1000000, statedb, new(event.Feed)}
2277+
blockchain := newTestBlockChain(1000000, statedb, new(event.Feed))
22722278

22732279
config := testTxPoolConfig
22742280
config.NoLocals = nolocals
@@ -2310,7 +2316,7 @@ func testJournaling(t *testing.T, nolocals bool) {
23102316
// Terminate the old pool, bump the local nonce, create a new pool and ensure relevant transaction survive
23112317
pool.Stop()
23122318
statedb.SetNonce(crypto.PubkeyToAddress(local.PublicKey), 1)
2313-
blockchain = &testBlockChain{1000000, statedb, new(event.Feed)}
2319+
blockchain = newTestBlockChain(1000000, statedb, new(event.Feed))
23142320

23152321
pool = NewTxPool(config, params.TestChainConfig, blockchain)
23162322

@@ -2337,7 +2343,7 @@ func testJournaling(t *testing.T, nolocals bool) {
23372343
pool.Stop()
23382344

23392345
statedb.SetNonce(crypto.PubkeyToAddress(local.PublicKey), 1)
2340-
blockchain = &testBlockChain{1000000, statedb, new(event.Feed)}
2346+
blockchain = newTestBlockChain(1000000, statedb, new(event.Feed))
23412347
pool = NewTxPool(config, params.TestChainConfig, blockchain)
23422348

23432349
pending, queued = pool.Stats()
@@ -2366,7 +2372,7 @@ func TestStatusCheck(t *testing.T) {
23662372

23672373
// Create the pool to test the status retrievals with
23682374
statedb, _ := state.New(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil)
2369-
blockchain := &testBlockChain{1000000, statedb, new(event.Feed)}
2375+
blockchain := newTestBlockChain(1000000, statedb, new(event.Feed))
23702376

23712377
pool := NewTxPool(testTxPoolConfig, params.TestChainConfig, blockchain)
23722378
defer pool.Stop()

0 commit comments

Comments
 (0)