From 8ff89d76c70353c459a90df61bc24df80425978f Mon Sep 17 00:00:00 2001 From: Kaloyan Tanev Date: Thu, 29 Jan 2026 14:13:47 +0200 Subject: [PATCH 1/3] Fix erroring on unknown key in proposer duty --- core/validatorapi/validatorapi.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/core/validatorapi/validatorapi.go b/core/validatorapi/validatorapi.go index e171d8ad7..82ee011ca 100644 --- a/core/validatorapi/validatorapi.go +++ b/core/validatorapi/validatorapi.go @@ -1131,7 +1131,8 @@ func (c Component) ProposerDuties(ctx context.Context, opts *eth2api.ProposerDut pubshare, ok := c.getPubShareFunc(duty.PubKey) if !ok { - return nil, errors.New("pubshare not found") + // Ignore unknown validators since ProposerDuties returns ALL proposers for the epoch if validatorIndices is empty. + continue } duty.PubKey = pubshare From 2f4e247f74eaaca5c7c81a5d073ffa334b46c54b Mon Sep 17 00:00:00 2001 From: Kaloyan Tanev Date: Thu, 29 Jan 2026 14:14:21 +0200 Subject: [PATCH 2/3] Add debug logs on reorgs --- app/eth2wrap/cache.go | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/app/eth2wrap/cache.go b/app/eth2wrap/cache.go index 79721078f..4e4364e8f 100644 --- a/app/eth2wrap/cache.go +++ b/app/eth2wrap/cache.go @@ -15,6 +15,8 @@ import ( "github.com/obolnetwork/charon/app/errors" "github.com/obolnetwork/charon/app/featureset" + "github.com/obolnetwork/charon/app/log" + "github.com/obolnetwork/charon/app/z" ) // dutiesCacheTrimThreshold is the number of epochs after which duties are trimmed from the cache. @@ -281,7 +283,7 @@ func (c *DutiesCache) UpdateCacheIndices(_ context.Context, indices []eth2p0.Val // InvalidateCache handles chain reorg, invalidating cached duties. // The epoch parameter indicates at which epoch the reorg led us to. // Meaning, we should invalidate all duties prior to that epoch. -func (c *DutiesCache) InvalidateCache(_ context.Context, epoch eth2p0.Epoch) { +func (c *DutiesCache) InvalidateCache(ctx context.Context, epoch eth2p0.Epoch) { c.mu.Lock() defer c.mu.Unlock() @@ -308,7 +310,10 @@ func (c *DutiesCache) InvalidateCache(_ context.Context, epoch eth2p0.Epoch) { } if invalidated { + log.Debug(ctx, "Reorg occurred through epoch transition, invalidating duties cache", z.U64("reorged_back_to_epoch", uint64(epoch))) invalidatedCacheDueReorgCount.WithLabelValues("validators").Inc() + } else { + log.Debug(ctx, "Reorg occurred, but it was not through epoch transition, duties cache is not invalidated", z.U64("reorged_epoch", uint64(epoch))) } } From 3db315b5ec728a343c112de8f24650d37a9fe09d Mon Sep 17 00:00:00 2001 From: Kaloyan Tanev Date: Thu, 29 Jan 2026 14:14:29 +0200 Subject: [PATCH 3/3] Fix metric labels --- app/eth2wrap/cache.go | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/app/eth2wrap/cache.go b/app/eth2wrap/cache.go index 4e4364e8f..1c42b724d 100644 --- a/app/eth2wrap/cache.go +++ b/app/eth2wrap/cache.go @@ -331,11 +331,11 @@ func (c *DutiesCache) ProposerDutiesCache(ctx context.Context, epoch eth2p0.Epoc duties, ok := c.cachedProposerDuties(epoch, vidxs) if ok { - usedCacheCount.WithLabelValues("validators").Inc() + usedCacheCount.WithLabelValues("proposer_duties").Inc() return duties, nil } - missedCacheCount.WithLabelValues("validators").Inc() + missedCacheCount.WithLabelValues("proposer_duties").Inc() c.mu.Lock() defer c.mu.Unlock() @@ -380,11 +380,11 @@ func (c *DutiesCache) AttesterDutiesCache(ctx context.Context, epoch eth2p0.Epoc duties, ok := c.cachedAttesterDuties(epoch, vidxs) if ok { - usedCacheCount.WithLabelValues("validators").Inc() + usedCacheCount.WithLabelValues("attester_duties").Inc() return duties, nil } - missedCacheCount.WithLabelValues("validators").Inc() + missedCacheCount.WithLabelValues("attester_duties").Inc() c.mu.Lock() defer c.mu.Unlock() @@ -417,11 +417,11 @@ func (c *DutiesCache) SyncCommDutiesCache(ctx context.Context, epoch eth2p0.Epoc duties, ok := c.cachedSyncDuties(epoch, vidxs) if ok { - usedCacheCount.WithLabelValues("validators").Inc() + usedCacheCount.WithLabelValues("sync_committee_duties").Inc() return duties, nil } - missedCacheCount.WithLabelValues("validators").Inc() + missedCacheCount.WithLabelValues("sync_committee_duties").Inc() c.mu.Lock() defer c.mu.Unlock()