From 1b70b87b8a13a3aa65424f72a253d64ea570ccc0 Mon Sep 17 00:00:00 2001 From: Damilola Edwards Date: Wed, 19 Aug 2026 10:26:51 +0100 Subject: [PATCH] Fix PreviousFork never selecting a fork at epoch 0 The search seeded its running maximum at epoch 0 and only replaced it on a strict greater than, so a fork activating at epoch 0 could never win. Every real chain has its genesis fork at epoch 0, so PreviousFork returned "no previous fork" on any mainnet-shaped spec. Changed the comparison to greater than or equal, matching how CurrentFork already does this same search. --- pkg/beacon/state/fork_epoch.go | 2 +- pkg/beacon/state/fork_epoch_test.go | 43 +++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 1 deletion(-) diff --git a/pkg/beacon/state/fork_epoch.go b/pkg/beacon/state/fork_epoch.go index f54cce0..74655f6 100644 --- a/pkg/beacon/state/fork_epoch.go +++ b/pkg/beacon/state/fork_epoch.go @@ -112,7 +112,7 @@ func (f *ForkEpochs) PreviousFork(epoch phase0.Epoch) (*ForkEpoch, error) { } for _, fork := range f.Active(epoch) { - if fork.Active(epoch) && fork.Name != current.Name && fork.Epoch > largest.Epoch { + if fork.Active(epoch) && fork.Name != current.Name && fork.Epoch >= largest.Epoch { found = true largest = fork diff --git a/pkg/beacon/state/fork_epoch_test.go b/pkg/beacon/state/fork_epoch_test.go index 02b0153..1e022ff 100644 --- a/pkg/beacon/state/fork_epoch_test.go +++ b/pkg/beacon/state/fork_epoch_test.go @@ -232,6 +232,49 @@ func TestForkEpochsPreviousFork(t *testing.T) { Name: spec.DataVersionPhase0, }, }, + { + // Mainnet-shaped: genesis fork activates at epoch 0, which every + // real chain has. Regression test for a bug where a fork at + // epoch 0 could never be selected as the previous fork. + name: "returns genesis fork at epoch 0 as the previous fork", + forks: state.ForkEpochs{ + { + Epoch: 0, + Name: spec.DataVersionPhase0, + }, + { + Epoch: 74240, + Name: spec.DataVersionAltair, + }, + }, + epoch: 74241, + expected: &state.ForkEpoch{ + Epoch: 0, + Name: spec.DataVersionPhase0, + }, + }, + { + name: "returns the most recent previous fork across three activated forks", + forks: state.ForkEpochs{ + { + Epoch: 0, + Name: spec.DataVersionPhase0, + }, + { + Epoch: 100, + Name: spec.DataVersionAltair, + }, + { + Epoch: 200, + Name: spec.DataVersionBellatrix, + }, + }, + epoch: 250, + expected: &state.ForkEpoch{ + Epoch: 100, + Name: spec.DataVersionAltair, + }, + }, } for _, test := range tests {