From 70dcd3eabcc53c35e1d42bab18a41b926b5020bf Mon Sep 17 00:00:00 2001 From: pk910 Date: Thu, 14 Sep 2023 02:39:05 +0200 Subject: [PATCH] various small improvements & performance fixes --- indexer/client.go | 8 ++++++++ indexer/epoch_stats.go | 1 + indexer/votes.go | 4 ++++ services/beaconservice.go | 13 ++++++++++--- services/frontendcache.go | 2 ++ utils/debug.go | 32 ++++++++++++++++++++++++++++++++ 6 files changed, 57 insertions(+), 3 deletions(-) create mode 100644 utils/debug.go diff --git a/indexer/client.go b/indexer/client.go index 595b4ac6..3b25a147 100644 --- a/indexer/client.go +++ b/indexer/client.go @@ -415,6 +415,10 @@ func (client *IndexerClient) pollLatestBlocks() error { if err != nil { return err } + err = client.ensureEpochStats(utils.EpochOfSlot(currentBlock.Slot), currentBlock.Root) + if err != nil { + return err + } return nil } @@ -502,6 +506,10 @@ func (client *IndexerClient) processBlockEvent(evt *rpctypes.StandardV1StreamedB if err != nil { return err } + err = client.ensureEpochStats(utils.EpochOfSlot(currentBlock.Slot), currentBlock.Root) + if err != nil { + return err + } client.setHeadBlock(evt.Block, uint64(evt.Slot)) return nil } diff --git a/indexer/epoch_stats.go b/indexer/epoch_stats.go index 911e831f..7e2bf9b9 100644 --- a/indexer/epoch_stats.go +++ b/indexer/epoch_stats.go @@ -181,6 +181,7 @@ func (client *IndexerClient) ensureEpochStats(epoch uint64, head []byte) error { proposerRsp, err = client.rpcClient.GetProposerDuties(epoch) if err != nil { logger.WithField("client", client.clientName).Warnf("could not load proposer duties for epoch %v: %v", epoch, err) + return fmt.Errorf("could not find proposer duties for epoch %v: %v", epoch, err) } if proposerRsp == nil { return fmt.Errorf("could not find proposer duties for epoch %v", epoch) diff --git a/indexer/votes.go b/indexer/votes.go index 61e5cd23..98978c50 100644 --- a/indexer/votes.go +++ b/indexer/votes.go @@ -3,6 +3,7 @@ package indexer import ( "bytes" "fmt" + "time" "github.com/pk910/light-beaconchain-explorer/utils" ) @@ -23,6 +24,8 @@ type EpochVotes struct { } func aggregateEpochVotes(blockMap map[uint64]*CacheBlock, epoch uint64, epochStats *EpochStats, targetRoot []byte, currentOnly bool, awaitDutiesLoaded bool) *EpochVotes { + t1 := time.Now() + firstSlot := epoch * utils.Config.Chain.Config.SlotsPerEpoch lastSlot := firstSlot + utils.Config.Chain.Config.SlotsPerEpoch - 1 if !currentOnly { @@ -104,5 +107,6 @@ func aggregateEpochVotes(blockMap map[uint64]*CacheBlock, epoch uint64, epochSta } } + logger.Debugf("aggregated epoch %v votes in %v\n", epoch, time.Since(t1)) return &votes } diff --git a/services/beaconservice.go b/services/beaconservice.go index e6e9aa64..f008b1f6 100644 --- a/services/beaconservice.go +++ b/services/beaconservice.go @@ -314,12 +314,19 @@ func (bs *BeaconService) GetProposerAssignments(firstEpoch uint64, lastEpoch uin for epochIdx := int64(firstEpoch); epochIdx >= int64(idxMinEpoch) && epochIdx >= int64(lastEpoch); epochIdx-- { epoch = uint64(epochIdx) epochStats := bs.indexer.GetCachedEpochStats(epoch) + if epochStats != nil { synchronizedEpochs[epoch] = true - for slot, vidx := range epochStats.GetProposerAssignments() { - proposerAssignments[slot] = vidx + proposers := epochStats.TryGetProposerAssignments() + if proposers != nil { + for slot, vidx := range proposers { + proposerAssignments[slot] = vidx + } + } else { + epochStats = nil } - } else { + } + if epochStats == nil { for idx := uint64(0); idx < utils.Config.Chain.Config.SlotsPerEpoch; idx++ { proposerAssignments[(epoch*utils.Config.Chain.Config.SlotsPerEpoch)+idx] = math.MaxInt64 } diff --git a/services/frontendcache.go b/services/frontendcache.go index e3cb28a9..26461497 100644 --- a/services/frontendcache.go +++ b/services/frontendcache.go @@ -54,6 +54,8 @@ func (fc *FrontendCacheService) SetFrontendCache(pageKey string, value interface } func (fc *FrontendCacheService) ProcessCachedPage(pageKey string, caching bool, returnValue interface{}, buildFn func(pageCall *FrontendCacheProcessingPage) interface{}) interface{} { + //fmt.Printf("page call %v (goid: %v)\n", pageKey, utils.Goid()) + fc.processingMutex.Lock() processingPage := fc.processingDict[pageKey] if processingPage != nil { diff --git a/utils/debug.go b/utils/debug.go new file mode 100644 index 00000000..ddd63228 --- /dev/null +++ b/utils/debug.go @@ -0,0 +1,32 @@ +package utils + +import ( + "bytes" + "runtime" + "strconv" +) + +var ( + goroutinePrefix = []byte("goroutine ") +) + +// This is terrible, slow, and should never be used. +func Goid() int { + buf := make([]byte, 32) + n := runtime.Stack(buf, false) + buf = buf[:n] + // goroutine 1 [running]: ... + + buf, ok := bytes.CutPrefix(buf, goroutinePrefix) + if !ok { + return 0 + } + + i := bytes.IndexByte(buf, ' ') + if i < 0 { + return 0 + } + + res, _ := strconv.Atoi(string(buf[:i])) + return res +}