core, eth: minor fixes

This commit is contained in:
Gary Rong 2024-01-22 12:08:54 +08:00
parent 811ed9207e
commit aa21c1f2f4
3 changed files with 40 additions and 51 deletions

View file

@ -244,7 +244,6 @@ type BlockChain struct {
chainHeadFeed event.Feed chainHeadFeed event.Feed
logsFeed event.Feed logsFeed event.Feed
blockProcFeed event.Feed blockProcFeed event.Feed
txIndexFeed event.Feed
scope event.SubscriptionScope scope event.SubscriptionScope
genesisBlock *types.Block genesisBlock *types.Block
@ -267,10 +266,12 @@ type BlockChain struct {
futureBlocks *lru.Cache[common.Hash, *types.Block] futureBlocks *lru.Cache[common.Hash, *types.Block]
wg sync.WaitGroup wg sync.WaitGroup
quit chan struct{} // shutdown signal, closed in Stop. quit chan struct{} // shutdown signal, closed in Stop.
stopping atomic.Bool // false if chain is running, true when stopped stopping atomic.Bool // false if chain is running, true when stopped
procInterrupt atomic.Bool // interrupt signaler for block processing procInterrupt atomic.Bool // interrupt signaler for block processing
txIndexProgCh chan chan TxIndexProgress // chan for querying the progress of transaction indexing
txIndexRunning bool // flag if the background tx indexer is activated
txIndexProgCh chan chan TxIndexProgress // chan for querying the progress of transaction indexing
engine consensus.Engine engine consensus.Engine
validator Validator // Block and state validator interface validator Validator // Block and state validator interface
@ -487,6 +488,7 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, genesis *Genesis
// Start tx indexer/unindexer if required. // Start tx indexer/unindexer if required.
if txLookupLimit != nil { if txLookupLimit != nil {
bc.txLookupLimit = *txLookupLimit bc.txLookupLimit = *txLookupLimit
bc.txIndexRunning = true
bc.wg.Add(1) bc.wg.Add(1)
go bc.maintainTxIndex() go bc.maintainTxIndex()
@ -2462,7 +2464,7 @@ func (bc *BlockChain) reportTxIndexProgress(head uint64) TxIndexProgress {
indexed = head - *tail + 1 indexed = head - *tail + 1
} }
// The value of indexed might be larger than total if some blocks need // The value of indexed might be larger than total if some blocks need
// to unindexed, avoiding a negative remaining. // to be unindexed, avoiding a negative remaining.
if indexed < total { if indexed < total {
remaining = total - indexed remaining = total - indexed
} }
@ -2472,8 +2474,12 @@ func (bc *BlockChain) reportTxIndexProgress(head uint64) TxIndexProgress {
} }
} }
// TxIndexProgress retrieves the tx indexing progress. // TxIndexProgress retrieves the tx indexing progress, or an error if the
// background tx indexer is not activated or already stopped.
func (bc *BlockChain) TxIndexProgress() (TxIndexProgress, error) { func (bc *BlockChain) TxIndexProgress() (TxIndexProgress, error) {
if !bc.txIndexRunning {
return TxIndexProgress{}, errors.New("tx indexer is not activated")
}
ch := make(chan TxIndexProgress, 1) ch := make(chan TxIndexProgress, 1)
select { select {
case bc.txIndexProgCh <- ch: case bc.txIndexProgCh <- ch:
@ -2527,14 +2533,6 @@ func (bc *BlockChain) maintainTxIndex() {
lastHead = head.Block.NumberU64() lastHead = head.Block.NumberU64()
case <-done: case <-done:
done = nil done = nil
// WARNING, the event will be fired for each signal once the
// transaction indexing is finished. Subscribers need to manage
// the event stream by themselves. It's recommended to unsubscribe
// once the event is received.
if bc.reportTxIndexProgress(lastHead).Done() {
bc.txIndexFeed.Send(true)
}
case ch := <-bc.txIndexProgCh: case ch := <-bc.txIndexProgCh:
ch <- bc.reportTxIndexProgress(lastHead) ch <- bc.reportTxIndexProgress(lastHead)
case <-bc.quit: case <-bc.quit:

View file

@ -444,9 +444,3 @@ func (bc *BlockChain) SubscribeLogsEvent(ch chan<- []*types.Log) event.Subscript
func (bc *BlockChain) SubscribeBlockProcessingEvent(ch chan<- bool) event.Subscription { func (bc *BlockChain) SubscribeBlockProcessingEvent(ch chan<- bool) event.Subscription {
return bc.scope.Track(bc.blockProcFeed.Subscribe(ch)) return bc.scope.Track(bc.blockProcFeed.Subscribe(ch))
} }
// SubscribeTxIndexEvent registers a subscription of bool where true means
// transaction indexing has finished.
func (bc *BlockChain) SubscribeTxIndexEvent(ch chan<- bool) event.Subscription {
return bc.scope.Track(bc.txIndexFeed.Subscribe(ch))
}

View file

@ -19,6 +19,7 @@ package downloader
import ( import (
"context" "context"
"sync" "sync"
"time"
"github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum"
"github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core"
@ -57,25 +58,33 @@ func NewDownloaderAPI(d *Downloader, chain *core.BlockChain, m *event.TypeMux) *
// new sync subscriptions and broadcasts sync status updates to the installed sync // new sync subscriptions and broadcasts sync status updates to the installed sync
// subscriptions. // subscriptions.
// //
// The sync status pushed to subscriptions can a stream like: // The sync status pushed to subscriptions can be a stream like:
// >>> {Syncing: true, Progress: {...}} // >>> {Syncing: true, Progress: {...}}
// >>> {false} // >>> {false}
// //
// If the node is already synced up, then only a single event will be pushed {false}. // If the node is already synced up, then only a single event subscribers will
// receive is {false}.
func (api *DownloaderAPI) eventLoop() { func (api *DownloaderAPI) eventLoop() {
var ( var (
sub = api.mux.Subscribe(StartEvent{}) sub = api.mux.Subscribe(StartEvent{})
syncSubscriptions = make(map[chan interface{}]struct{}) syncSubscriptions = make(map[chan interface{}]struct{})
txIndexCh = make(chan bool, 1) checkInterval = time.Second * 30
done bool checkTimer = time.NewTimer(checkInterval)
)
txIndexSub := api.chain.SubscribeTxIndexEvent(txIndexCh) // status flags
defer func() { started bool
if txIndexSub == nil { done bool
return
getProgress = func() ethereum.SyncProgress {
prog := api.d.Progress()
if txProg, err := api.chain.TxIndexProgress(); err == nil {
prog.TxIndexFinishedBlocks = txProg.Indexed
prog.TxIndexRemainingBlocks = txProg.Remaining
}
return prog
} }
txIndexSub.Unsubscribe() )
}() defer checkTimer.Stop()
for { for {
select { select {
@ -93,11 +102,7 @@ func (api *DownloaderAPI) eventLoop() {
} }
switch event.Data.(type) { switch event.Data.(type) {
case StartEvent: case StartEvent:
prog := api.d.Progress() prog := getProgress()
if txProg, err := api.chain.TxIndexProgress(); err == nil {
prog.TxIndexFinishedBlocks = txProg.Indexed
prog.TxIndexRemainingBlocks = txProg.Remaining
}
notification := &SyncingResult{ notification := &SyncingResult{
Syncing: true, Syncing: true,
Status: prog, Status: prog,
@ -106,30 +111,22 @@ func (api *DownloaderAPI) eventLoop() {
for c := range syncSubscriptions { for c := range syncSubscriptions {
c <- notification c <- notification
} }
started = true
} }
case synced := <-txIndexCh: case <-checkTimer.C:
if !synced { if !started {
checkTimer.Reset(checkInterval)
continue continue
} }
prog := api.d.Progress() prog := getProgress()
if !prog.Done() { if !prog.Done() {
continue checkTimer.Reset(checkInterval)
}
txProg, err := api.chain.TxIndexProgress()
if err != nil || !txProg.Done() {
continue continue
} }
for c := range syncSubscriptions { for c := range syncSubscriptions {
c <- false c <- false
} }
done = true done = true
// Unsubscribe the tx indexing events as the whole
// state sync is already finished.
if txIndexSub != nil {
txIndexSub.Unsubscribe()
txIndexSub = nil
}
} }
} }
} }