@@ -192,17 +192,6 @@ type txLookup struct {
192
192
transaction * types.Transaction
193
193
}
194
194
195
- // TxIndexProgress is the struct describing the progress for transaction indexing.
196
- type TxIndexProgress struct {
197
- Indexed uint64 // number of blocks whose transactions are indexed
198
- Remaining uint64 // number of blocks whose transactions are not indexed yet
199
- }
200
-
201
- // Done returns an indicator if the transaction indexing is finished.
202
- func (prog TxIndexProgress ) Done () bool {
203
- return prog .Remaining == 0
204
- }
205
-
206
195
// BlockChain represents the canonical chain given a database with a genesis
207
196
// block. The Blockchain manages chain imports, reverts, chain reorganisations.
208
197
//
@@ -229,13 +218,7 @@ type BlockChain struct {
229
218
flushInterval atomic.Int64 // Time interval (processing time) after which to flush a state
230
219
triedb * trie.Database // The database handler for maintaining trie nodes.
231
220
stateCache state.Database // State database to reuse between imports (contains state cache)
232
-
233
- // txLookupLimit is the maximum number of blocks from head whose tx indices
234
- // are reserved:
235
- // * 0: means no limit and regenerate any missing indexes
236
- // * N: means N block limit [HEAD-N+1, HEAD] and delete extra indexes
237
- // * nil: disable tx reindexer/deleter, but still index new blocks
238
- txLookupLimit uint64
221
+ txIndexer * txIndexer // Transaction indexer, might be nil if not enabled
239
222
240
223
hc * HeaderChain
241
224
rmLogsFeed event.Feed
@@ -270,9 +253,6 @@ type BlockChain struct {
270
253
stopping atomic.Bool // false if chain is running, true when stopped
271
254
procInterrupt atomic.Bool // interrupt signaler for block processing
272
255
273
- txIndexRunning bool // flag if the background tx indexer is activated
274
- txIndexProgCh chan chan TxIndexProgress // chan for querying the progress of transaction indexing
275
-
276
256
engine consensus.Engine
277
257
validator Validator // Block and state validator interface
278
258
prefetcher Prefetcher
@@ -320,7 +300,6 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, genesis *Genesis
320
300
blockCache : lru.NewCache [common.Hash , * types.Block ](blockCacheLimit ),
321
301
txLookupCache : lru.NewCache [common.Hash , txLookup ](txLookupCacheLimit ),
322
302
futureBlocks : lru.NewCache [common.Hash , * types.Block ](maxFutureBlocks ),
323
- txIndexProgCh : make (chan chan TxIndexProgress ),
324
303
engine : engine ,
325
304
vmConfig : vmConfig ,
326
305
}
@@ -485,13 +464,9 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, genesis *Genesis
485
464
}
486
465
rawdb .WriteChainConfig (db , genesisHash , chainConfig )
487
466
}
488
- // Start tx indexer/unindexer if required .
467
+ // Start tx indexer if it's enabled .
489
468
if txLookupLimit != nil {
490
- bc .txLookupLimit = * txLookupLimit
491
- bc .txIndexRunning = true
492
-
493
- bc .wg .Add (1 )
494
- go bc .maintainTxIndex ()
469
+ bc .txIndexer = newTxIndexer (* txLookupLimit , bc )
495
470
}
496
471
return bc , nil
497
472
}
@@ -981,7 +956,10 @@ func (bc *BlockChain) stopWithoutSaving() {
981
956
if ! bc .stopping .CompareAndSwap (false , true ) {
982
957
return
983
958
}
984
-
959
+ // Signal shutdown tx indexer.
960
+ if bc .txIndexer != nil {
961
+ bc .txIndexer .close ()
962
+ }
985
963
// Unsubscribe all subscriptions registered from blockchain.
986
964
bc .scope .Close ()
987
965
@@ -2403,148 +2381,6 @@ func (bc *BlockChain) skipBlock(err error, it *insertIterator) bool {
2403
2381
return false
2404
2382
}
2405
2383
2406
- // indexBlocks reindexes or unindexes transactions depending on user configuration
2407
- func (bc * BlockChain ) indexBlocks (tail * uint64 , head uint64 , done chan struct {}) {
2408
- defer func () { close (done ) }()
2409
-
2410
- // If head is 0, it means the chain is just initialized and no blocks are
2411
- // inserted, so don't need to index anything.
2412
- if head == 0 {
2413
- return
2414
- }
2415
- // The tail flag is not existent, it means the node is just initialized
2416
- // and all blocks in the chain (part of them may from ancient store) are
2417
- // not indexed yet, index the chain according to the configuration then.
2418
- if tail == nil {
2419
- from := uint64 (0 )
2420
- if bc .txLookupLimit != 0 && head >= bc .txLookupLimit {
2421
- from = head - bc .txLookupLimit + 1
2422
- }
2423
- rawdb .IndexTransactions (bc .db , from , head + 1 , bc .quit , true )
2424
- return
2425
- }
2426
- // The tail flag is existent (which means indexes in [tail, head] should be
2427
- // present), while the whole chain are requested for indexing.
2428
- if bc .txLookupLimit == 0 || head < bc .txLookupLimit {
2429
- if * tail > 0 {
2430
- // It can happen when chain is rewound to a historical point which
2431
- // is even lower than the indexes tail, recap the indexing target
2432
- // to new head to avoid reading non-existent block bodies.
2433
- end := * tail
2434
- if end > head + 1 {
2435
- end = head + 1
2436
- }
2437
- rawdb .IndexTransactions (bc .db , 0 , end , bc .quit , true )
2438
- }
2439
- return
2440
- }
2441
- // The tail flag is existent, adjust the index range according to configuration
2442
- // and latest head.
2443
- if head - bc .txLookupLimit + 1 < * tail {
2444
- // Reindex a part of missing indices and rewind index tail to HEAD-limit
2445
- rawdb .IndexTransactions (bc .db , head - bc .txLookupLimit + 1 , * tail , bc .quit , true )
2446
- } else {
2447
- // Unindex a part of stale indices and forward index tail to HEAD-limit
2448
- rawdb .UnindexTransactions (bc .db , * tail , head - bc .txLookupLimit + 1 , bc .quit , false )
2449
- }
2450
- }
2451
-
2452
- // reportTxIndexProgress returns the tx indexing progress.
2453
- func (bc * BlockChain ) reportTxIndexProgress (head uint64 ) TxIndexProgress {
2454
- var (
2455
- remaining uint64
2456
- tail = rawdb .ReadTxIndexTail (bc .db )
2457
- )
2458
- total := bc .txLookupLimit
2459
- if bc .txLookupLimit == 0 {
2460
- total = head + 1 // genesis included
2461
- }
2462
- var indexed uint64
2463
- if tail != nil {
2464
- indexed = head - * tail + 1
2465
- }
2466
- // The value of indexed might be larger than total if some blocks need
2467
- // to be unindexed, avoiding a negative remaining.
2468
- if indexed < total {
2469
- remaining = total - indexed
2470
- }
2471
- return TxIndexProgress {
2472
- Indexed : indexed ,
2473
- Remaining : remaining ,
2474
- }
2475
- }
2476
-
2477
- // TxIndexProgress retrieves the tx indexing progress, or an error if the
2478
- // background tx indexer is not activated or already stopped.
2479
- func (bc * BlockChain ) TxIndexProgress () (TxIndexProgress , error ) {
2480
- if ! bc .txIndexRunning {
2481
- return TxIndexProgress {}, errors .New ("tx indexer is not activated" )
2482
- }
2483
- ch := make (chan TxIndexProgress , 1 )
2484
- select {
2485
- case bc .txIndexProgCh <- ch :
2486
- return <- ch , nil
2487
- case <- bc .quit :
2488
- return TxIndexProgress {}, errors .New ("blockchain is closed" )
2489
- }
2490
- }
2491
-
2492
- // maintainTxIndex is responsible for the construction and deletion of the
2493
- // transaction index.
2494
- //
2495
- // User can use flag `txlookuplimit` to specify a "recentness" block, below
2496
- // which ancient tx indices get deleted. If `txlookuplimit` is 0, it means
2497
- // all tx indices will be reserved.
2498
- //
2499
- // The user can adjust the txlookuplimit value for each launch after sync,
2500
- // Geth will automatically construct the missing indices or delete the extra
2501
- // indices.
2502
- func (bc * BlockChain ) maintainTxIndex () {
2503
- defer bc .wg .Done ()
2504
-
2505
- // Listening to chain events and manipulate the transaction indexes.
2506
- var (
2507
- done chan struct {} // Non-nil if background unindexing or reindexing routine is active.
2508
- lastHead uint64 // The latest announced chain head (whose tx indexes are assumed created)
2509
- headCh = make (chan ChainHeadEvent , 1 ) // Buffered to avoid locking up the event feed
2510
- )
2511
- sub := bc .SubscribeChainHeadEvent (headCh )
2512
- if sub == nil {
2513
- return
2514
- }
2515
- defer sub .Unsubscribe ()
2516
- log .Info ("Initialized transaction indexer" , "limit" , bc .TxLookupLimit ())
2517
-
2518
- // Launch the initial processing if chain is not empty (head != genesis).
2519
- // This step is useful in these scenarios that chain has no progress and
2520
- // indexer is never triggered.
2521
- if head := rawdb .ReadHeadBlock (bc .db ); head != nil && head .Number ().Uint64 () != 0 {
2522
- done = make (chan struct {})
2523
- lastHead = head .Number ().Uint64 ()
2524
- go bc .indexBlocks (rawdb .ReadTxIndexTail (bc .db ), head .NumberU64 (), done )
2525
- }
2526
- for {
2527
- select {
2528
- case head := <- headCh :
2529
- if done == nil {
2530
- done = make (chan struct {})
2531
- go bc .indexBlocks (rawdb .ReadTxIndexTail (bc .db ), head .Block .NumberU64 (), done )
2532
- }
2533
- lastHead = head .Block .NumberU64 ()
2534
- case <- done :
2535
- done = nil
2536
- case ch := <- bc .txIndexProgCh :
2537
- ch <- bc .reportTxIndexProgress (lastHead )
2538
- case <- bc .quit :
2539
- if done != nil {
2540
- log .Info ("Waiting background transaction indexer to exit" )
2541
- <- done
2542
- }
2543
- return
2544
- }
2545
- }
2546
- }
2547
-
2548
2384
// reportBlock logs a bad block error.
2549
2385
func (bc * BlockChain ) reportBlock (block * types.Block , receipts types.Receipts , err error ) {
2550
2386
rawdb .WriteBadBlock (bc .db , block )
0 commit comments