Skip to content

Commit 658dedd

Browse files
authored
Merge pull request #542 from ethpandaops/pk910/fix-double-finalization
fix finalization issue when two epochs are finalized at the same time
2 parents f2db7c5 + 52f0505 commit 658dedd

File tree

2 files changed

+24
-7
lines changed

2 files changed

+24
-7
lines changed

indexer/beacon/finalization.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ func (indexer *Indexer) processFinalityEvent(finalityEvent *v1.Finality) error {
2929
oldLastFinalizedEpoch := indexer.lastFinalizedEpoch
3030

3131
for finalizeEpoch := indexer.lastFinalizedEpoch; finalizeEpoch < finalityEvent.Finalized.Epoch; finalizeEpoch++ {
32-
readyClients := indexer.GetReadyClientsByCheckpoint(finalityEvent.Finalized.Root, true)
32+
readyClients := indexer.GetReadyClientsByCheckpoint(finalityEvent.Finalized.Epoch, finalityEvent.Finalized.Root, true)
3333
retryCount := 5
3434

3535
for {

indexer/beacon/indexer_getter.go

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,17 +28,34 @@ func (indexer *Indexer) GetAllClients() []*Client {
2828
}
2929

3030
// GetReadyClientsByCheckpoint returns a slice of clients that are ready for processing based on the finalized root and preference for archive clients.
31-
func (indexer *Indexer) GetReadyClientsByCheckpoint(finalizedRoot phase0.Root, preferArchive bool) []*Client {
31+
func (indexer *Indexer) GetReadyClientsByCheckpoint(finalizedEpoch phase0.Epoch, finalizedRoot phase0.Root, preferArchive bool) []*Client {
3232
clients := make([]*Client, 0)
3333

34+
finalizedSlot := indexer.consensusPool.GetChainState().EpochToSlot(finalizedEpoch)
35+
3436
for _, client := range indexer.clients {
3537
if client.client.GetStatus() != consensus.ClientStatusOnline {
3638
continue
3739
}
3840

3941
_, root, _, _ := client.client.GetFinalityCheckpoint()
40-
if !bytes.Equal(root[:], finalizedRoot[:]) && !bytes.Equal(root[:], consensus.NullRoot[:]) {
41-
continue
42+
if !bytes.Equal(root[:], finalizedRoot[:]) {
43+
block := indexer.blockCache.getBlockByRoot(root)
44+
if block == nil {
45+
// block is not in the cache, probably a very old block before the finalizatio checkpoint
46+
continue
47+
}
48+
49+
if block.Slot < finalizedSlot {
50+
// block is before the finalized slot, so client is lagging behind
51+
continue
52+
}
53+
54+
isInChain, _ := indexer.blockCache.getCanonicalDistance(finalizedRoot, root, 0)
55+
if !isInChain {
56+
// block is not in the canonical chain, so client is on a different fork
57+
continue
58+
}
4259
}
4360

4461
clients = append(clients, client)
@@ -101,10 +118,10 @@ func (indexer *Indexer) GetReadyClientByBlockRoot(blockRoot phase0.Root, preferA
101118

102119
// GetReadyClients returns a slice of clients that are on the finalized chain and preference for archive clients.
103120
func (indexer *Indexer) GetReadyClients(preferArchive bool) []*Client {
104-
_, finalizedRoot := indexer.consensusPool.GetChainState().GetFinalizedCheckpoint()
105-
clients := indexer.GetReadyClientsByCheckpoint(finalizedRoot, preferArchive)
121+
finalizedEpoch, finalizedRoot := indexer.consensusPool.GetChainState().GetFinalizedCheckpoint()
122+
clients := indexer.GetReadyClientsByCheckpoint(finalizedEpoch, finalizedRoot, preferArchive)
106123
if len(clients) == 0 {
107-
clients = indexer.GetReadyClientsByCheckpoint(consensus.NullRoot, preferArchive)
124+
clients = indexer.GetReadyClientsByCheckpoint(finalizedEpoch, consensus.NullRoot, preferArchive)
108125
}
109126
return clients
110127
}

0 commit comments

Comments
 (0)