@@ -98,8 +98,8 @@ type TransactionPool struct {
98
98
// exceed the txPoolMaxSize. This flag is reset to false OnNewBlock
99
99
stateproofOverflowed bool
100
100
101
- testEvalCtx * testEvalContext
102
- testEvalCtxMu deadlock.RWMutex
101
+ testBlockEvaluator * eval. TestBlockEvaluator
102
+ testBlockEvaluatorMu deadlock.RWMutex
103
103
104
104
// shutdown is set to true when the pool is being shut down. It is checked in exported methods
105
105
// to prevent pool operations like remember and recomputing the block evaluator
@@ -109,7 +109,6 @@ type TransactionPool struct {
109
109
110
110
// BlockEvaluator defines the block evaluator interface exposed by the ledger package.
111
111
type BlockEvaluator interface {
112
- TestTransactionGroup (txgroup []transactions.SignedTxn ) error
113
112
Round () basics.Round
114
113
PaySetSize () int
115
114
TransactionGroup (txads []transactions.SignedTxnWithAD ) error
@@ -118,30 +117,33 @@ type BlockEvaluator interface {
118
117
ResetTxnBytes ()
119
118
}
120
119
121
- // testEvalContext implements the eval.TestEvalContext interface.
120
+ // testEvalContext implements the eval.TestEvalContext interface. It allows for concurrent
121
+ // calls to TestTransactionGroup for candidate transactions calling transactionPool.Test.
122
122
type testEvalContext struct {
123
123
ledger * ledger.Ledger
124
124
block bookkeeping.Block
125
125
proto config.ConsensusParams
126
126
specials transactions.SpecialAddresses
127
127
}
128
128
129
- func newTestEvalCtx (ledger * ledger.Ledger , block bookkeeping.Block ) * testEvalContext {
130
- return & testEvalContext {
131
- ledger : ledger ,
132
- block : block ,
133
- proto : config .Consensus [block .CurrentProtocol ],
134
- specials : transactions.SpecialAddresses {
135
- FeeSink : block .FeeSink ,
136
- RewardsPool : block .RewardsPool ,
137
- },
138
- }
129
+ func newTestBlockEvaluator (ledger * ledger.Ledger , block bookkeeping.Block ) * eval.TestBlockEvaluator {
130
+ return & eval.TestBlockEvaluator {
131
+ TestEvalContext : & testEvalContext {
132
+ ledger : ledger ,
133
+ block : block ,
134
+ proto : config .Consensus [block .CurrentProtocol ],
135
+ specials : transactions.SpecialAddresses {
136
+ FeeSink : block .FeeSink ,
137
+ RewardsPool : block .RewardsPool ,
138
+ },
139
+ }}
139
140
}
140
141
141
142
func (c * testEvalContext ) Proto () config.ConsensusParams { return c .proto }
142
143
func (c * testEvalContext ) Specials () transactions.SpecialAddresses { return c .specials }
143
144
func (c * testEvalContext ) TxnContext () transactions.TxnContext { return c .block }
144
145
func (c * testEvalContext ) CheckDup (firstValid , lastValid basics.Round , txid transactions.Txid , txl ledgercore.Txlease ) error {
146
+ // will call txTail.checkDup, which uses an RLock for concurrent access.
145
147
return c .ledger .CheckDup (c .proto , c .block .BlockHeader .Round , firstValid , lastValid , txid , txl )
146
148
}
147
149
@@ -421,19 +423,20 @@ func (pool *TransactionPool) checkSufficientFee(txgroup []transactions.SignedTxn
421
423
422
424
// Test performs basic duplicate detection and well-formedness checks
423
425
// on a transaction group without storing the group.
426
+ // It may be called concurrently.
424
427
func (pool * TransactionPool ) Test (txgroup []transactions.SignedTxn ) error {
425
428
if err := pool .checkPendingQueueSize (txgroup ); err != nil {
426
429
return err
427
430
}
428
431
429
- pool .testEvalCtxMu .RLock ()
430
- defer pool .testEvalCtxMu .RUnlock ()
432
+ pool .testBlockEvaluatorMu .RLock ()
433
+ defer pool .testBlockEvaluatorMu .RUnlock ()
431
434
432
- if pool .testEvalCtx == nil {
435
+ if pool .testBlockEvaluator == nil {
433
436
return fmt .Errorf ("Test: testEvalCtx is nil" )
434
437
}
435
438
436
- return eval . TestTransactionGroup (pool . testEvalCtx , txgroup )
439
+ return pool . testBlockEvaluator . TestTransactionGroup (txgroup )
437
440
}
438
441
439
442
type poolIngestParams struct {
@@ -780,9 +783,9 @@ func (pool *TransactionPool) recomputeBlockEvaluator(committedTxIDs map[transact
780
783
return
781
784
}
782
785
783
- pool .testEvalCtxMu .Lock ()
784
- pool .testEvalCtx = newTestEvalCtx (pool .ledger , next )
785
- pool .testEvalCtxMu .Unlock ()
786
+ pool .testBlockEvaluatorMu .Lock ()
787
+ pool .testBlockEvaluator = newTestBlockEvaluator (pool .ledger , next )
788
+ pool .testBlockEvaluatorMu .Unlock ()
786
789
787
790
var asmStats telemetryspec.AssembleBlockMetrics
788
791
asmStats .StartCount = len (txgroups )
0 commit comments