p2p: wire stategen into service for last finalized state (#16034)

This PR removes the last production usage for: `LastArchivedRoot` by

- extend the P2P config to accept a `StateGen` dependency and wire it up
from the beacon node
- update gossip scoring to read the active validator count via stategen
using last finalized block root

note: i think the correct implementation should process last finalizes
state to current slot, but that's a bigger change i dont want to make in
this PR, i just want to remove usages for `LastArchivedRoot`
This commit is contained in:
terence
2025-11-21 11:13:00 -05:00
committed by GitHub
parent 3d7f7b588b
commit 5449fd0352
6 changed files with 40 additions and 22 deletions

View File

@@ -663,6 +663,7 @@ func (b *BeaconNode) registerP2P(cliCtx *cli.Context) error {
EnableUPnP: cliCtx.Bool(cmd.EnableUPnPFlag.Name),
StateNotifier: b,
DB: b.db,
StateGen: b.stateGen,
ClockWaiter: b.clockWaiter,
})
if err != nil {

View File

@@ -56,6 +56,7 @@ go_library(
"//beacon-chain/p2p/peers/scorers:go_default_library",
"//beacon-chain/p2p/types:go_default_library",
"//beacon-chain/startup:go_default_library",
"//beacon-chain/state/stategen:go_default_library",
"//cmd/beacon-chain/flags:go_default_library",
"//config/features:go_default_library",
"//config/fieldparams:go_default_library",
@@ -153,6 +154,7 @@ go_test(
"//beacon-chain/core/helpers:go_default_library",
"//beacon-chain/core/peerdas:go_default_library",
"//beacon-chain/core/signing:go_default_library",
"//beacon-chain/db/iface:go_default_library",
"//beacon-chain/db/testing:go_default_library",
"//beacon-chain/p2p/encoder:go_default_library",
"//beacon-chain/p2p/peers:go_default_library",
@@ -161,6 +163,7 @@ go_test(
"//beacon-chain/p2p/testing:go_default_library",
"//beacon-chain/p2p/types:go_default_library",
"//beacon-chain/startup:go_default_library",
"//beacon-chain/state/stategen/mock:go_default_library",
"//cmd/beacon-chain/flags:go_default_library",
"//config/fieldparams:go_default_library",
"//config/params:go_default_library",

View File

@@ -7,6 +7,7 @@ import (
statefeed "github.com/OffchainLabs/prysm/v7/beacon-chain/core/feed/state"
"github.com/OffchainLabs/prysm/v7/beacon-chain/db"
"github.com/OffchainLabs/prysm/v7/beacon-chain/startup"
"github.com/OffchainLabs/prysm/v7/beacon-chain/state/stategen"
"github.com/sirupsen/logrus"
)
@@ -49,6 +50,7 @@ type Config struct {
IPColocationWhitelist []*net.IPNet
StateNotifier statefeed.Notifier
DB db.ReadOnlyDatabaseWithSeqNum
StateGen stategen.StateManager
ClockWaiter startup.ClockWaiter
}

View File

@@ -156,29 +156,13 @@ func (s *Service) retrieveActiveValidators() (uint64, error) {
if s.activeValidatorCount != 0 {
return s.activeValidatorCount, nil
}
rt := s.cfg.DB.LastArchivedRoot(s.ctx)
if rt == params.BeaconConfig().ZeroHash {
genState, err := s.cfg.DB.GenesisState(s.ctx)
if err != nil {
return 0, err
}
if genState == nil || genState.IsNil() {
return 0, errors.New("no genesis state exists")
}
activeVals, err := helpers.ActiveValidatorCount(context.Background(), genState, coreTime.CurrentEpoch(genState))
if err != nil {
return 0, err
}
// Cache active validator count
s.activeValidatorCount = activeVals
return activeVals, nil
}
bState, err := s.cfg.DB.State(s.ctx, rt)
finalizedCheckpoint, err := s.cfg.DB.FinalizedCheckpoint(s.ctx)
if err != nil {
return 0, err
}
if bState == nil || bState.IsNil() {
return 0, errors.Errorf("no state with root %#x exists", rt)
bState, err := s.cfg.StateGen.StateByRoot(s.ctx, [32]byte(finalizedCheckpoint.Root))
if err != nil {
return 0, err
}
activeVals, err := helpers.ActiveValidatorCount(context.Background(), bState, coreTime.CurrentEpoch(bState))
if err != nil {

View File

@@ -1,10 +1,14 @@
package p2p
import (
"context"
"testing"
iface "github.com/OffchainLabs/prysm/v7/beacon-chain/db/iface"
dbutil "github.com/OffchainLabs/prysm/v7/beacon-chain/db/testing"
mockstategen "github.com/OffchainLabs/prysm/v7/beacon-chain/state/stategen/mock"
"github.com/OffchainLabs/prysm/v7/config/params"
"github.com/OffchainLabs/prysm/v7/encoding/bytesutil"
ethpb "github.com/OffchainLabs/prysm/v7/proto/prysm/v1alpha1"
"github.com/OffchainLabs/prysm/v7/testing/assert"
"github.com/OffchainLabs/prysm/v7/testing/require"
@@ -20,9 +24,11 @@ func TestCorrect_ActiveValidatorsCount(t *testing.T) {
params.OverrideBeaconConfig(cfg)
db := dbutil.SetupDB(t)
wrappedDB := &finalizedCheckpointDB{ReadOnlyDatabaseWithSeqNum: db}
stateGen := mockstategen.NewService()
s := &Service{
ctx: t.Context(),
cfg: &Config{DB: db},
cfg: &Config{DB: wrappedDB, StateGen: stateGen},
}
bState, err := util.NewBeaconState(func(state *ethpb.BeaconState) error {
validators := make([]*ethpb.Validator, params.BeaconConfig().MinGenesisActiveValidatorCount)
@@ -39,6 +45,10 @@ func TestCorrect_ActiveValidatorsCount(t *testing.T) {
})
require.NoError(t, err)
require.NoError(t, db.SaveGenesisData(s.ctx, bState))
checkpoint, err := db.FinalizedCheckpoint(s.ctx)
require.NoError(t, err)
wrappedDB.finalized = checkpoint
stateGen.AddStateForRoot(bState, bytesutil.ToBytes32(checkpoint.Root))
vals, err := s.retrieveActiveValidators()
assert.NoError(t, err, "genesis state not retrieved")
@@ -52,7 +62,10 @@ func TestCorrect_ActiveValidatorsCount(t *testing.T) {
}))
}
require.NoError(t, bState.SetSlot(10000))
require.NoError(t, db.SaveState(s.ctx, bState, [32]byte{'a'}))
rootA := [32]byte{'a'}
require.NoError(t, db.SaveState(s.ctx, bState, rootA))
wrappedDB.finalized = &ethpb.Checkpoint{Root: rootA[:]}
stateGen.AddStateForRoot(bState, rootA)
// Reset count
s.activeValidatorCount = 0
@@ -77,3 +90,15 @@ func TestLoggingParameters(_ *testing.T) {
logGossipParameters("testing", defaultLightClientOptimisticUpdateTopicParams())
logGossipParameters("testing", defaultLightClientFinalityUpdateTopicParams())
}
type finalizedCheckpointDB struct {
iface.ReadOnlyDatabaseWithSeqNum
finalized *ethpb.Checkpoint
}
func (f *finalizedCheckpointDB) FinalizedCheckpoint(ctx context.Context) (*ethpb.Checkpoint, error) {
if f.finalized != nil {
return f.finalized, nil
}
return f.ReadOnlyDatabaseWithSeqNum.FinalizedCheckpoint(ctx)
}

View File

@@ -0,0 +1,3 @@
### Ignored
- P2p: wire stategen into service for last finalized state and use it for active validator count