mirror of
https://github.com/OffchainLabs/prysm.git
synced 2026-01-09 15:37:56 -05:00
Chain info: Return err if checkpoint is nil (#10729)
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
This commit is contained in:
@@ -4,6 +4,8 @@ import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/blockchain/store"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/forkchoice"
|
||||
doublylinkedtree "github.com/prysmaticlabs/prysm/beacon-chain/forkchoice/doubly-linked-tree"
|
||||
@@ -79,9 +81,9 @@ type CanonicalFetcher interface {
|
||||
// FinalizationFetcher defines a common interface for methods in blockchain service which
|
||||
// directly retrieve finalization and justification related data.
|
||||
type FinalizationFetcher interface {
|
||||
FinalizedCheckpt() *ethpb.Checkpoint
|
||||
CurrentJustifiedCheckpt() *ethpb.Checkpoint
|
||||
PreviousJustifiedCheckpt() *ethpb.Checkpoint
|
||||
FinalizedCheckpt() (*ethpb.Checkpoint, error)
|
||||
CurrentJustifiedCheckpt() (*ethpb.Checkpoint, error)
|
||||
PreviousJustifiedCheckpt() (*ethpb.Checkpoint, error)
|
||||
VerifyFinalizedBlkDescendant(ctx context.Context, blockRoot [32]byte) error
|
||||
}
|
||||
|
||||
@@ -92,44 +94,47 @@ type OptimisticModeFetcher interface {
|
||||
}
|
||||
|
||||
// FinalizedCheckpt returns the latest finalized checkpoint from chain store.
|
||||
func (s *Service) FinalizedCheckpt() *ethpb.Checkpoint {
|
||||
cp := s.store.FinalizedCheckpt()
|
||||
if cp == nil {
|
||||
return ðpb.Checkpoint{Root: params.BeaconConfig().ZeroHash[:]}
|
||||
func (s *Service) FinalizedCheckpt() (*ethpb.Checkpoint, error) {
|
||||
cp, err := s.store.FinalizedCheckpt()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return ethpb.CopyCheckpoint(cp)
|
||||
return ethpb.CopyCheckpoint(cp), nil
|
||||
}
|
||||
|
||||
// CurrentJustifiedCheckpt returns the current justified checkpoint from chain store.
|
||||
func (s *Service) CurrentJustifiedCheckpt() *ethpb.Checkpoint {
|
||||
cp := s.store.JustifiedCheckpt()
|
||||
if cp == nil {
|
||||
return ðpb.Checkpoint{Root: params.BeaconConfig().ZeroHash[:]}
|
||||
func (s *Service) CurrentJustifiedCheckpt() (*ethpb.Checkpoint, error) {
|
||||
cp, err := s.store.JustifiedCheckpt()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return ethpb.CopyCheckpoint(cp)
|
||||
return ethpb.CopyCheckpoint(cp), nil
|
||||
}
|
||||
|
||||
// PreviousJustifiedCheckpt returns the previous justified checkpoint from chain store.
|
||||
func (s *Service) PreviousJustifiedCheckpt() *ethpb.Checkpoint {
|
||||
cp := s.store.PrevJustifiedCheckpt()
|
||||
if cp == nil {
|
||||
return ðpb.Checkpoint{Root: params.BeaconConfig().ZeroHash[:]}
|
||||
func (s *Service) PreviousJustifiedCheckpt() (*ethpb.Checkpoint, error) {
|
||||
cp, err := s.store.PrevJustifiedCheckpt()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return ethpb.CopyCheckpoint(cp)
|
||||
return ethpb.CopyCheckpoint(cp), nil
|
||||
}
|
||||
|
||||
// BestJustifiedCheckpt returns the best justified checkpoint from store.
|
||||
func (s *Service) BestJustifiedCheckpt() *ethpb.Checkpoint {
|
||||
cp := s.store.BestJustifiedCheckpt()
|
||||
// If there is no best justified checkpoint, return the checkpoint with root as zeros to be used for genesis cases.
|
||||
if cp == nil {
|
||||
return ðpb.Checkpoint{Root: params.BeaconConfig().ZeroHash[:]}
|
||||
func (s *Service) BestJustifiedCheckpt() (*ethpb.Checkpoint, error) {
|
||||
cp, err := s.store.BestJustifiedCheckpt()
|
||||
if err != nil {
|
||||
// If there is no best justified checkpoint, return the checkpoint with root as zeros to be used for genesis cases.
|
||||
if errors.Is(err, store.ErrNilCheckpoint) {
|
||||
return ðpb.Checkpoint{Root: params.BeaconConfig().ZeroHash[:]}, nil
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return ethpb.CopyCheckpoint(cp)
|
||||
return ethpb.CopyCheckpoint(cp), nil
|
||||
}
|
||||
|
||||
// HeadSlot returns the slot of the head of the chain.
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/blockchain/store"
|
||||
testDB "github.com/prysmaticlabs/prysm/beacon-chain/db/testing"
|
||||
doublylinkedtree "github.com/prysmaticlabs/prysm/beacon-chain/forkchoice/doubly-linked-tree"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/forkchoice/protoarray"
|
||||
@@ -26,12 +27,6 @@ var _ ChainInfoFetcher = (*Service)(nil)
|
||||
var _ TimeFetcher = (*Service)(nil)
|
||||
var _ ForkFetcher = (*Service)(nil)
|
||||
|
||||
func TestFinalizedCheckpt_Nil(t *testing.T) {
|
||||
beaconDB := testDB.SetupDB(t)
|
||||
c := setupBeaconChain(t, beaconDB)
|
||||
assert.DeepEqual(t, params.BeaconConfig().ZeroHash[:], c.FinalizedCheckpt().Root, "Incorrect pre chain start value")
|
||||
}
|
||||
|
||||
func TestHeadRoot_Nil(t *testing.T) {
|
||||
beaconDB := testDB.SetupDB(t)
|
||||
c := setupBeaconChain(t, beaconDB)
|
||||
@@ -53,7 +48,9 @@ func TestFinalizedCheckpt_CanRetrieve(t *testing.T) {
|
||||
c := setupBeaconChain(t, beaconDB)
|
||||
c.store.SetFinalizedCheckptAndPayloadHash(cp, [32]byte{'a'})
|
||||
|
||||
assert.Equal(t, cp.Epoch, c.FinalizedCheckpt().Epoch, "Unexpected finalized epoch")
|
||||
cp, err := c.FinalizedCheckpt()
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, cp.Epoch, cp.Epoch, "Unexpected finalized epoch")
|
||||
}
|
||||
|
||||
func TestFinalizedCheckpt_GenesisRootOk(t *testing.T) {
|
||||
@@ -64,17 +61,22 @@ func TestFinalizedCheckpt_GenesisRootOk(t *testing.T) {
|
||||
c := setupBeaconChain(t, beaconDB)
|
||||
c.store.SetFinalizedCheckptAndPayloadHash(cp, [32]byte{'a'})
|
||||
c.originBlockRoot = genesisRoot
|
||||
assert.DeepEqual(t, c.originBlockRoot[:], c.FinalizedCheckpt().Root)
|
||||
cp, err := c.FinalizedCheckpt()
|
||||
require.NoError(t, err)
|
||||
assert.DeepEqual(t, c.originBlockRoot[:], cp.Root)
|
||||
}
|
||||
|
||||
func TestCurrentJustifiedCheckpt_CanRetrieve(t *testing.T) {
|
||||
beaconDB := testDB.SetupDB(t)
|
||||
|
||||
c := setupBeaconChain(t, beaconDB)
|
||||
assert.Equal(t, params.BeaconConfig().ZeroHash, bytesutil.ToBytes32(c.CurrentJustifiedCheckpt().Root), "Unexpected justified epoch")
|
||||
_, err := c.CurrentJustifiedCheckpt()
|
||||
require.ErrorIs(t, err, store.ErrNilCheckpoint)
|
||||
cp := ðpb.Checkpoint{Epoch: 6, Root: bytesutil.PadTo([]byte("foo"), 32)}
|
||||
c.store.SetJustifiedCheckptAndPayloadHash(cp, [32]byte{})
|
||||
assert.Equal(t, cp.Epoch, c.CurrentJustifiedCheckpt().Epoch, "Unexpected justified epoch")
|
||||
jp, err := c.CurrentJustifiedCheckpt()
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, cp.Epoch, jp.Epoch, "Unexpected justified epoch")
|
||||
}
|
||||
|
||||
func TestJustifiedCheckpt_GenesisRootOk(t *testing.T) {
|
||||
@@ -85,7 +87,9 @@ func TestJustifiedCheckpt_GenesisRootOk(t *testing.T) {
|
||||
cp := ðpb.Checkpoint{Root: genesisRoot[:]}
|
||||
c.store.SetJustifiedCheckptAndPayloadHash(cp, [32]byte{})
|
||||
c.originBlockRoot = genesisRoot
|
||||
assert.DeepEqual(t, c.originBlockRoot[:], c.CurrentJustifiedCheckpt().Root)
|
||||
cp, err := c.CurrentJustifiedCheckpt()
|
||||
require.NoError(t, err)
|
||||
assert.DeepEqual(t, c.originBlockRoot[:], cp.Root)
|
||||
}
|
||||
|
||||
func TestPreviousJustifiedCheckpt_CanRetrieve(t *testing.T) {
|
||||
@@ -93,9 +97,12 @@ func TestPreviousJustifiedCheckpt_CanRetrieve(t *testing.T) {
|
||||
|
||||
cp := ðpb.Checkpoint{Epoch: 7, Root: bytesutil.PadTo([]byte("foo"), 32)}
|
||||
c := setupBeaconChain(t, beaconDB)
|
||||
assert.Equal(t, params.BeaconConfig().ZeroHash, bytesutil.ToBytes32(c.CurrentJustifiedCheckpt().Root), "Unexpected justified epoch")
|
||||
_, err := c.PreviousJustifiedCheckpt()
|
||||
require.ErrorIs(t, err, store.ErrNilCheckpoint)
|
||||
c.store.SetPrevJustifiedCheckpt(cp)
|
||||
assert.Equal(t, cp.Epoch, c.PreviousJustifiedCheckpt().Epoch, "Unexpected previous justified epoch")
|
||||
pcp, err := c.PreviousJustifiedCheckpt()
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, cp.Epoch, pcp.Epoch, "Unexpected previous justified epoch")
|
||||
}
|
||||
|
||||
func TestPrevJustifiedCheckpt_GenesisRootOk(t *testing.T) {
|
||||
@@ -106,7 +113,9 @@ func TestPrevJustifiedCheckpt_GenesisRootOk(t *testing.T) {
|
||||
c := setupBeaconChain(t, beaconDB)
|
||||
c.store.SetPrevJustifiedCheckpt(cp)
|
||||
c.originBlockRoot = genesisRoot
|
||||
assert.DeepEqual(t, c.originBlockRoot[:], c.PreviousJustifiedCheckpt().Root)
|
||||
pcp, err := c.PreviousJustifiedCheckpt()
|
||||
require.NoError(t, err)
|
||||
assert.DeepEqual(t, c.originBlockRoot[:], pcp.Root)
|
||||
}
|
||||
|
||||
func TestHeadSlot_CanRetrieve(t *testing.T) {
|
||||
|
||||
@@ -3,10 +3,6 @@ package blockchain
|
||||
import "github.com/pkg/errors"
|
||||
|
||||
var (
|
||||
// errNilJustifiedInStore is returned when a nil justified checkpt is returned from store.
|
||||
errNilJustifiedInStore = errors.New("nil justified checkpoint returned from store")
|
||||
// errNilBestJustifiedInStore is returned when a nil justified checkpt is returned from store.
|
||||
errNilBestJustifiedInStore = errors.New("nil best justified checkpoint returned from store")
|
||||
// errNilFinalizedInStore is returned when a nil finalized checkpt is returned from store.
|
||||
errNilFinalizedInStore = errors.New("nil finalized checkpoint returned from store")
|
||||
// errInvalidNilSummary is returned when a nil summary is returned from the DB.
|
||||
|
||||
@@ -27,9 +27,9 @@ import (
|
||||
// UpdateAndSaveHeadWithBalances updates the beacon state head after getting justified balanced from cache.
|
||||
// This function is only used in spec-tests, it does save the head after updating it.
|
||||
func (s *Service) UpdateAndSaveHeadWithBalances(ctx context.Context) error {
|
||||
cp := s.store.JustifiedCheckpt()
|
||||
if cp == nil {
|
||||
return errors.New("no justified checkpoint")
|
||||
cp, err := s.store.JustifiedCheckpt()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
balances, err := s.justifiedBalances.get(ctx, bytesutil.ToBytes32(cp.Root))
|
||||
if err != nil {
|
||||
@@ -66,13 +66,13 @@ func (s *Service) updateHead(ctx context.Context, balances []uint64) ([32]byte,
|
||||
defer span.End()
|
||||
|
||||
// Get head from the fork choice service.
|
||||
f := s.store.FinalizedCheckpt()
|
||||
if f == nil {
|
||||
return [32]byte{}, errNilFinalizedInStore
|
||||
f, err := s.store.FinalizedCheckpt()
|
||||
if err != nil {
|
||||
return [32]byte{}, errors.Wrap(err, "could not get finalized checkpoint")
|
||||
}
|
||||
j := s.store.JustifiedCheckpt()
|
||||
if j == nil {
|
||||
return [32]byte{}, errNilJustifiedInStore
|
||||
j, err := s.store.JustifiedCheckpt()
|
||||
if err != nil {
|
||||
return [32]byte{}, errors.Wrap(err, "could not get justified checkpoint")
|
||||
}
|
||||
// To get head before the first justified epoch, the fork choice will start with origin root
|
||||
// instead of zero hashes.
|
||||
|
||||
@@ -42,17 +42,17 @@ func (s *Service) NewSlot(ctx context.Context, slot types.Slot) error {
|
||||
}
|
||||
|
||||
// Update store.justified_checkpoint if a better checkpoint on the store.finalized_checkpoint chain
|
||||
bj := s.store.BestJustifiedCheckpt()
|
||||
if bj == nil {
|
||||
return errNilBestJustifiedInStore
|
||||
bj, err := s.store.BestJustifiedCheckpt()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "could not get best justified checkpoint")
|
||||
}
|
||||
j := s.store.JustifiedCheckpt()
|
||||
if j == nil {
|
||||
return errNilJustifiedInStore
|
||||
j, err := s.store.JustifiedCheckpt()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "could not get justified checkpoint")
|
||||
}
|
||||
f := s.store.FinalizedCheckpt()
|
||||
if f == nil {
|
||||
return errNilFinalizedInStore
|
||||
f, err := s.store.FinalizedCheckpt()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "could not get finalized checkpoint")
|
||||
}
|
||||
if bj.Epoch > j.Epoch {
|
||||
finalizedSlot, err := slots.EpochStart(f.Epoch)
|
||||
|
||||
@@ -103,9 +103,17 @@ func TestService_newSlot(t *testing.T) {
|
||||
|
||||
require.NoError(t, service.NewSlot(ctx, test.args.slot))
|
||||
if test.args.shouldEqual {
|
||||
require.DeepSSZEqual(t, service.store.BestJustifiedCheckpt(), service.store.JustifiedCheckpt())
|
||||
bcp, err := service.store.BestJustifiedCheckpt()
|
||||
require.NoError(t, err)
|
||||
cp, err := service.store.JustifiedCheckpt()
|
||||
require.NoError(t, err)
|
||||
require.DeepSSZEqual(t, bcp, cp)
|
||||
} else {
|
||||
require.DeepNotSSZEqual(t, service.store.BestJustifiedCheckpt(), service.store.JustifiedCheckpt())
|
||||
bcp, err := service.store.BestJustifiedCheckpt()
|
||||
require.NoError(t, err)
|
||||
cp, err := service.store.JustifiedCheckpt()
|
||||
require.NoError(t, err)
|
||||
require.DeepNotSSZEqual(t, bcp, cp)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -176,9 +176,9 @@ func (s *Service) onBlock(ctx context.Context, signed interfaces.SignedBeaconBlo
|
||||
}
|
||||
|
||||
// Update justified check point.
|
||||
justified := s.store.JustifiedCheckpt()
|
||||
if justified == nil {
|
||||
return errNilJustifiedInStore
|
||||
justified, err := s.store.JustifiedCheckpt()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "could not get justified checkpoint")
|
||||
}
|
||||
currJustifiedEpoch := justified.Epoch
|
||||
if postState.CurrentJustifiedCheckpoint().Epoch > currJustifiedEpoch {
|
||||
@@ -187,7 +187,10 @@ func (s *Service) onBlock(ctx context.Context, signed interfaces.SignedBeaconBlo
|
||||
}
|
||||
}
|
||||
|
||||
finalized := s.store.FinalizedCheckpt()
|
||||
finalized, err := s.store.FinalizedCheckpt()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "could not get finalized checkpoint")
|
||||
}
|
||||
if finalized == nil {
|
||||
return errNilFinalizedInStore
|
||||
}
|
||||
@@ -473,9 +476,9 @@ func (s *Service) handleBlockAfterBatchVerify(ctx context.Context, signed interf
|
||||
s.clearInitSyncBlocks()
|
||||
}
|
||||
|
||||
justified := s.store.JustifiedCheckpt()
|
||||
if justified == nil {
|
||||
return errNilJustifiedInStore
|
||||
justified, err := s.store.JustifiedCheckpt()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "could not get justified checkpoint")
|
||||
}
|
||||
if jCheckpoint.Epoch > justified.Epoch {
|
||||
if err := s.updateJustifiedInitSync(ctx, jCheckpoint); err != nil {
|
||||
@@ -483,7 +486,10 @@ func (s *Service) handleBlockAfterBatchVerify(ctx context.Context, signed interf
|
||||
}
|
||||
}
|
||||
|
||||
finalized := s.store.FinalizedCheckpt()
|
||||
finalized, err := s.store.FinalizedCheckpt()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "could not get finalized checkpoint")
|
||||
}
|
||||
if finalized == nil {
|
||||
return errNilFinalizedInStore
|
||||
}
|
||||
|
||||
@@ -92,9 +92,9 @@ func (s *Service) verifyBlkPreState(ctx context.Context, b interfaces.BeaconBloc
|
||||
func (s *Service) VerifyFinalizedBlkDescendant(ctx context.Context, root [32]byte) error {
|
||||
ctx, span := trace.StartSpan(ctx, "blockChain.VerifyFinalizedBlkDescendant")
|
||||
defer span.End()
|
||||
finalized := s.store.FinalizedCheckpt()
|
||||
if finalized == nil {
|
||||
return errNilFinalizedInStore
|
||||
finalized, err := s.store.FinalizedCheckpt()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "could not get finalized checkpoint")
|
||||
}
|
||||
fRoot := s.ensureRootNotZeros(bytesutil.ToBytes32(finalized.Root))
|
||||
finalizedBlkSigned, err := s.getBlock(ctx, fRoot)
|
||||
@@ -123,9 +123,9 @@ func (s *Service) VerifyFinalizedBlkDescendant(ctx context.Context, root [32]byt
|
||||
// verifyBlkFinalizedSlot validates input block is not less than or equal
|
||||
// to current finalized slot.
|
||||
func (s *Service) verifyBlkFinalizedSlot(b interfaces.BeaconBlock) error {
|
||||
finalized := s.store.FinalizedCheckpt()
|
||||
if finalized == nil {
|
||||
return errNilFinalizedInStore
|
||||
finalized, err := s.store.FinalizedCheckpt()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "could not get finalized checkpoint")
|
||||
}
|
||||
finalizedSlot, err := slots.EpochStart(finalized.Epoch)
|
||||
if err != nil {
|
||||
@@ -166,7 +166,10 @@ func (s *Service) shouldUpdateCurrentJustified(ctx context.Context, newJustified
|
||||
if slots.SinceEpochStarts(s.CurrentSlot()) < params.BeaconConfig().SafeSlotsToUpdateJustified {
|
||||
return true, nil
|
||||
}
|
||||
justified := s.store.JustifiedCheckpt()
|
||||
justified, err := s.store.JustifiedCheckpt()
|
||||
if err != nil {
|
||||
return false, errors.Wrap(err, "could not get justified checkpoint")
|
||||
}
|
||||
jSlot, err := slots.EpochStart(justified.Epoch)
|
||||
if err != nil {
|
||||
return false, err
|
||||
@@ -188,9 +191,9 @@ func (s *Service) updateJustified(ctx context.Context, state state.ReadOnlyBeaco
|
||||
defer span.End()
|
||||
|
||||
cpt := state.CurrentJustifiedCheckpoint()
|
||||
bestJustified := s.store.BestJustifiedCheckpt()
|
||||
if bestJustified == nil {
|
||||
return errNilBestJustifiedInStore
|
||||
bestJustified, err := s.store.BestJustifiedCheckpt()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "could not get best justified checkpoint")
|
||||
}
|
||||
if cpt.Epoch > bestJustified.Epoch {
|
||||
s.store.SetBestJustifiedCheckpt(cpt)
|
||||
@@ -201,9 +204,9 @@ func (s *Service) updateJustified(ctx context.Context, state state.ReadOnlyBeaco
|
||||
}
|
||||
|
||||
if canUpdate {
|
||||
justified := s.store.JustifiedCheckpt()
|
||||
if justified == nil {
|
||||
return errNilJustifiedInStore
|
||||
justified, err := s.store.JustifiedCheckpt()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "could not get justified checkpoint")
|
||||
}
|
||||
s.store.SetPrevJustifiedCheckpt(justified)
|
||||
h, err := s.getPayloadHash(ctx, cpt.Root)
|
||||
@@ -220,9 +223,9 @@ func (s *Service) updateJustified(ctx context.Context, state state.ReadOnlyBeaco
|
||||
// caches justified checkpoint balances for fork choice and save justified checkpoint in DB.
|
||||
// This method does not have defense against fork choice bouncing attack, which is why it's only recommend to be used during initial syncing.
|
||||
func (s *Service) updateJustifiedInitSync(ctx context.Context, cp *ethpb.Checkpoint) error {
|
||||
justified := s.store.JustifiedCheckpt()
|
||||
if justified == nil {
|
||||
return errNilJustifiedInStore
|
||||
justified, err := s.store.JustifiedCheckpt()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "could not get justified checkpoint")
|
||||
}
|
||||
s.store.SetPrevJustifiedCheckpt(justified)
|
||||
|
||||
@@ -345,9 +348,9 @@ func (s *Service) fillInForkChoiceMissingBlocks(ctx context.Context, blk interfa
|
||||
parentRoot := bytesutil.ToBytes32(blk.ParentRoot())
|
||||
slot := blk.Slot()
|
||||
// Fork choice only matters from last finalized slot.
|
||||
finalized := s.store.FinalizedCheckpt()
|
||||
if finalized == nil {
|
||||
return errNilFinalizedInStore
|
||||
finalized, err := s.store.FinalizedCheckpt()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fSlot, err := slots.EpochStart(finalized.Epoch)
|
||||
if err != nil {
|
||||
|
||||
@@ -709,13 +709,17 @@ func TestUpdateJustified_CouldUpdateBest(t *testing.T) {
|
||||
require.NoError(t, s.SetCurrentJustifiedCheckpoint(ðpb.Checkpoint{Epoch: 1, Root: r[:]}))
|
||||
require.NoError(t, service.updateJustified(context.Background(), s))
|
||||
|
||||
assert.Equal(t, s.CurrentJustifiedCheckpoint().Epoch, service.store.BestJustifiedCheckpt().Epoch, "Incorrect justified epoch in service")
|
||||
cp, err := service.store.BestJustifiedCheckpt()
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, s.CurrentJustifiedCheckpoint().Epoch, cp.Epoch, "Incorrect justified epoch in service")
|
||||
|
||||
// Could not update
|
||||
service.store.SetBestJustifiedCheckpt(ðpb.Checkpoint{Root: []byte{'A'}, Epoch: 2})
|
||||
require.NoError(t, service.updateJustified(context.Background(), s))
|
||||
|
||||
assert.Equal(t, types.Epoch(2), service.store.BestJustifiedCheckpt().Epoch, "Incorrect justified epoch in service")
|
||||
cp, err = service.store.BestJustifiedCheckpt()
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, types.Epoch(2), cp.Epoch, "Incorrect justified epoch in service")
|
||||
}
|
||||
|
||||
func TestFillForkChoiceMissingBlocks_CanSave_ProtoArray(t *testing.T) {
|
||||
@@ -1394,9 +1398,13 @@ func TestUpdateJustifiedInitSync(t *testing.T) {
|
||||
|
||||
require.NoError(t, service.updateJustifiedInitSync(ctx, newCp))
|
||||
|
||||
assert.DeepSSZEqual(t, currentCp, service.PreviousJustifiedCheckpt(), "Incorrect previous justified checkpoint")
|
||||
assert.DeepSSZEqual(t, newCp, service.CurrentJustifiedCheckpt(), "Incorrect current justified checkpoint in cache")
|
||||
cp, err := service.cfg.BeaconDB.JustifiedCheckpoint(ctx)
|
||||
cp, err := service.PreviousJustifiedCheckpt()
|
||||
require.NoError(t, err)
|
||||
assert.DeepSSZEqual(t, currentCp, cp, "Incorrect previous justified checkpoint")
|
||||
cp, err = service.CurrentJustifiedCheckpt()
|
||||
require.NoError(t, err)
|
||||
assert.DeepSSZEqual(t, newCp, cp, "Incorrect current justified checkpoint in cache")
|
||||
cp, err = service.cfg.BeaconDB.JustifiedCheckpoint(ctx)
|
||||
require.NoError(t, err)
|
||||
assert.DeepSSZEqual(t, newCp, cp, "Incorrect current justified checkpoint in db")
|
||||
}
|
||||
@@ -1464,16 +1472,24 @@ func TestOnBlock_CanFinalize(t *testing.T) {
|
||||
testState, err = service.cfg.StateGen.StateByRoot(ctx, r)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
require.Equal(t, types.Epoch(3), service.CurrentJustifiedCheckpt().Epoch)
|
||||
require.Equal(t, types.Epoch(2), service.FinalizedCheckpt().Epoch)
|
||||
cp, err := service.CurrentJustifiedCheckpt()
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, types.Epoch(3), cp.Epoch)
|
||||
cp, err = service.FinalizedCheckpt()
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, types.Epoch(2), cp.Epoch)
|
||||
|
||||
// The update should persist in DB.
|
||||
j, err := service.cfg.BeaconDB.JustifiedCheckpoint(ctx)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, j.Epoch, service.CurrentJustifiedCheckpt().Epoch)
|
||||
cp, err = service.CurrentJustifiedCheckpt()
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, j.Epoch, cp.Epoch)
|
||||
f, err := service.cfg.BeaconDB.FinalizedCheckpoint(ctx)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, f.Epoch, service.FinalizedCheckpt().Epoch)
|
||||
cp, err = service.FinalizedCheckpt()
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, f.Epoch, cp.Epoch)
|
||||
}
|
||||
|
||||
func TestOnBlock_NilBlock(t *testing.T) {
|
||||
|
||||
@@ -71,9 +71,9 @@ func (s *Service) VerifyFinalizedConsistency(ctx context.Context, root []byte) e
|
||||
return nil
|
||||
}
|
||||
|
||||
f := s.FinalizedCheckpt()
|
||||
if f == nil {
|
||||
return errNilFinalizedInStore
|
||||
f, err := s.FinalizedCheckpt()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ss, err := slots.EpochStart(f.Epoch)
|
||||
if err != nil {
|
||||
@@ -152,9 +152,9 @@ func (s *Service) UpdateHead(ctx context.Context) error {
|
||||
|
||||
s.processAttestations(ctx)
|
||||
|
||||
justified := s.store.JustifiedCheckpt()
|
||||
if justified == nil {
|
||||
return errNilJustifiedInStore
|
||||
justified, err := s.store.JustifiedCheckpt()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
balances, err := s.justifiedBalances.get(ctx, bytesutil.ToBytes32(justified.Root))
|
||||
if err != nil {
|
||||
|
||||
@@ -59,9 +59,9 @@ func (s *Service) ReceiveBlock(ctx context.Context, block interfaces.SignedBeaco
|
||||
}
|
||||
|
||||
// Reports on block and fork choice metrics.
|
||||
finalized := s.store.FinalizedCheckpt()
|
||||
if finalized == nil {
|
||||
return errNilFinalizedInStore
|
||||
finalized, err := s.store.FinalizedCheckpt()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "could not get finalized checkpoint")
|
||||
}
|
||||
reportSlotMetrics(blockCopy.Block().Slot(), s.HeadSlot(), s.CurrentSlot(), finalized)
|
||||
|
||||
@@ -106,9 +106,9 @@ func (s *Service) ReceiveBlockBatch(ctx context.Context, blocks []interfaces.Sig
|
||||
})
|
||||
|
||||
// Reports on blockCopy and fork choice metrics.
|
||||
finalized := s.store.FinalizedCheckpt()
|
||||
if finalized == nil {
|
||||
return errNilFinalizedInStore
|
||||
finalized, err := s.store.FinalizedCheckpt()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "could not get finalized checkpoint")
|
||||
}
|
||||
reportSlotMetrics(blockCopy.Block().Slot(), s.HeadSlot(), s.CurrentSlot(), finalized)
|
||||
}
|
||||
@@ -116,7 +116,10 @@ func (s *Service) ReceiveBlockBatch(ctx context.Context, blocks []interfaces.Sig
|
||||
if err := s.cfg.BeaconDB.SaveBlocks(ctx, s.getInitSyncBlocks()); err != nil {
|
||||
return err
|
||||
}
|
||||
finalized := s.store.FinalizedCheckpt()
|
||||
finalized, err := s.store.FinalizedCheckpt()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "could not get finalized checkpoint")
|
||||
}
|
||||
if finalized == nil {
|
||||
return errNilFinalizedInStore
|
||||
}
|
||||
@@ -169,7 +172,10 @@ func (s *Service) checkSaveHotStateDB(ctx context.Context) error {
|
||||
currentEpoch := slots.ToEpoch(s.CurrentSlot())
|
||||
// Prevent `sinceFinality` going underflow.
|
||||
var sinceFinality types.Epoch
|
||||
finalized := s.store.FinalizedCheckpt()
|
||||
finalized, err := s.store.FinalizedCheckpt()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if finalized == nil {
|
||||
return errNilFinalizedInStore
|
||||
}
|
||||
|
||||
@@ -277,8 +277,12 @@ func TestChainService_CorrectGenesisRoots(t *testing.T) {
|
||||
// Test the start function.
|
||||
chainService.Start()
|
||||
|
||||
require.DeepEqual(t, blkRoot[:], chainService.store.FinalizedCheckpt().Root, "Finalize Checkpoint root is incorrect")
|
||||
require.DeepEqual(t, params.BeaconConfig().ZeroHash[:], chainService.store.JustifiedCheckpt().Root, "Justified Checkpoint root is incorrect")
|
||||
cp, err := chainService.store.FinalizedCheckpt()
|
||||
require.NoError(t, err)
|
||||
require.DeepEqual(t, blkRoot[:], cp.Root, "Finalize Checkpoint root is incorrect")
|
||||
cp, err = chainService.store.JustifiedCheckpt()
|
||||
require.NoError(t, err)
|
||||
require.DeepEqual(t, params.BeaconConfig().ZeroHash[:], cp.Root, "Justified Checkpoint root is incorrect")
|
||||
|
||||
require.NoError(t, chainService.Stop(), "Unable to stop chain service")
|
||||
|
||||
|
||||
@@ -10,7 +10,10 @@ go_library(
|
||||
],
|
||||
importpath = "github.com/prysmaticlabs/prysm/beacon-chain/blockchain/store",
|
||||
visibility = ["//beacon-chain:__subpackages__"],
|
||||
deps = ["//proto/prysm/v1alpha1:go_default_library"],
|
||||
deps = [
|
||||
"//proto/prysm/v1alpha1:go_default_library",
|
||||
"@com_github_pkg_errors//:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
go_test(
|
||||
|
||||
@@ -17,9 +17,19 @@ func TestNew(t *testing.T) {
|
||||
Root: []byte("hello"),
|
||||
}
|
||||
s := New(j, f)
|
||||
require.DeepSSZEqual(t, s.JustifiedCheckpt(), j)
|
||||
require.DeepSSZEqual(t, s.BestJustifiedCheckpt(), j)
|
||||
require.DeepSSZEqual(t, s.PrevJustifiedCheckpt(), j)
|
||||
require.DeepSSZEqual(t, s.FinalizedCheckpt(), f)
|
||||
require.DeepSSZEqual(t, s.PrevFinalizedCheckpt(), f)
|
||||
cp, err := s.JustifiedCheckpt()
|
||||
require.NoError(t, err)
|
||||
require.DeepSSZEqual(t, j, cp)
|
||||
cp, err = s.BestJustifiedCheckpt()
|
||||
require.NoError(t, err)
|
||||
require.DeepSSZEqual(t, j, cp)
|
||||
cp, err = s.PrevJustifiedCheckpt()
|
||||
require.NoError(t, err)
|
||||
require.DeepSSZEqual(t, j, cp)
|
||||
cp, err = s.FinalizedCheckpt()
|
||||
require.NoError(t, err)
|
||||
require.DeepSSZEqual(t, f, cp)
|
||||
cp, err = s.PrevFinalizedCheckpt()
|
||||
require.NoError(t, err)
|
||||
require.DeepSSZEqual(t, f, cp)
|
||||
}
|
||||
|
||||
@@ -1,26 +1,42 @@
|
||||
package store
|
||||
|
||||
import ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
||||
import (
|
||||
"github.com/pkg/errors"
|
||||
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrNilCheckpoint = errors.New("nil checkpoint")
|
||||
)
|
||||
|
||||
// PrevJustifiedCheckpt returns the previous justified checkpoint in the Store.
|
||||
func (s *Store) PrevJustifiedCheckpt() *ethpb.Checkpoint {
|
||||
func (s *Store) PrevJustifiedCheckpt() (*ethpb.Checkpoint, error) {
|
||||
s.RLock()
|
||||
defer s.RUnlock()
|
||||
return s.prevJustifiedCheckpt
|
||||
if s.prevJustifiedCheckpt == nil {
|
||||
return nil, ErrNilCheckpoint
|
||||
}
|
||||
return s.prevJustifiedCheckpt, nil
|
||||
}
|
||||
|
||||
// BestJustifiedCheckpt returns the best justified checkpoint in the Store.
|
||||
func (s *Store) BestJustifiedCheckpt() *ethpb.Checkpoint {
|
||||
func (s *Store) BestJustifiedCheckpt() (*ethpb.Checkpoint, error) {
|
||||
s.RLock()
|
||||
defer s.RUnlock()
|
||||
return s.bestJustifiedCheckpt
|
||||
if s.bestJustifiedCheckpt == nil {
|
||||
return nil, ErrNilCheckpoint
|
||||
}
|
||||
return s.bestJustifiedCheckpt, nil
|
||||
}
|
||||
|
||||
// JustifiedCheckpt returns the justified checkpoint in the Store.
|
||||
func (s *Store) JustifiedCheckpt() *ethpb.Checkpoint {
|
||||
func (s *Store) JustifiedCheckpt() (*ethpb.Checkpoint, error) {
|
||||
s.RLock()
|
||||
defer s.RUnlock()
|
||||
return s.justifiedCheckpt
|
||||
if s.justifiedCheckpt == nil {
|
||||
return nil, ErrNilCheckpoint
|
||||
}
|
||||
return s.justifiedCheckpt, nil
|
||||
}
|
||||
|
||||
// JustifiedPayloadBlockHash returns the justified payload block hash reflecting justified check point.
|
||||
@@ -31,17 +47,23 @@ func (s *Store) JustifiedPayloadBlockHash() [32]byte {
|
||||
}
|
||||
|
||||
// PrevFinalizedCheckpt returns the previous finalized checkpoint in the Store.
|
||||
func (s *Store) PrevFinalizedCheckpt() *ethpb.Checkpoint {
|
||||
func (s *Store) PrevFinalizedCheckpt() (*ethpb.Checkpoint, error) {
|
||||
s.RLock()
|
||||
defer s.RUnlock()
|
||||
return s.prevFinalizedCheckpt
|
||||
if s.prevFinalizedCheckpt == nil {
|
||||
return nil, ErrNilCheckpoint
|
||||
}
|
||||
return s.prevFinalizedCheckpt, nil
|
||||
}
|
||||
|
||||
// FinalizedCheckpt returns the finalized checkpoint in the Store.
|
||||
func (s *Store) FinalizedCheckpt() *ethpb.Checkpoint {
|
||||
func (s *Store) FinalizedCheckpt() (*ethpb.Checkpoint, error) {
|
||||
s.RLock()
|
||||
defer s.RUnlock()
|
||||
return s.finalizedCheckpt
|
||||
if s.finalizedCheckpt == nil {
|
||||
return nil, ErrNilCheckpoint
|
||||
}
|
||||
return s.finalizedCheckpt, nil
|
||||
}
|
||||
|
||||
// FinalizedPayloadBlockHash returns the finalized payload block hash reflecting finalized check point.
|
||||
|
||||
@@ -10,48 +10,63 @@ import (
|
||||
func Test_store_PrevJustifiedCheckpt(t *testing.T) {
|
||||
s := &Store{}
|
||||
var cp *ethpb.Checkpoint
|
||||
require.Equal(t, cp, s.PrevJustifiedCheckpt())
|
||||
_, err := s.PrevJustifiedCheckpt()
|
||||
require.ErrorIs(t, ErrNilCheckpoint, err)
|
||||
cp = ðpb.Checkpoint{Epoch: 1, Root: []byte{'a'}}
|
||||
s.SetPrevJustifiedCheckpt(cp)
|
||||
require.Equal(t, cp, s.PrevJustifiedCheckpt())
|
||||
got, err := s.PrevJustifiedCheckpt()
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, cp, got)
|
||||
}
|
||||
|
||||
func Test_store_BestJustifiedCheckpt(t *testing.T) {
|
||||
s := &Store{}
|
||||
var cp *ethpb.Checkpoint
|
||||
require.Equal(t, cp, s.BestJustifiedCheckpt())
|
||||
_, err := s.BestJustifiedCheckpt()
|
||||
require.ErrorIs(t, ErrNilCheckpoint, err)
|
||||
cp = ðpb.Checkpoint{Epoch: 1, Root: []byte{'a'}}
|
||||
s.SetBestJustifiedCheckpt(cp)
|
||||
require.Equal(t, cp, s.BestJustifiedCheckpt())
|
||||
got, err := s.BestJustifiedCheckpt()
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, cp, got)
|
||||
}
|
||||
|
||||
func Test_store_JustifiedCheckpt(t *testing.T) {
|
||||
s := &Store{}
|
||||
var cp *ethpb.Checkpoint
|
||||
require.Equal(t, cp, s.JustifiedCheckpt())
|
||||
_, err := s.JustifiedCheckpt()
|
||||
require.ErrorIs(t, ErrNilCheckpoint, err)
|
||||
cp = ðpb.Checkpoint{Epoch: 1, Root: []byte{'a'}}
|
||||
h := [32]byte{'b'}
|
||||
s.SetJustifiedCheckptAndPayloadHash(cp, h)
|
||||
require.Equal(t, cp, s.JustifiedCheckpt())
|
||||
got, err := s.JustifiedCheckpt()
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, cp, got)
|
||||
require.Equal(t, h, s.JustifiedPayloadBlockHash())
|
||||
}
|
||||
|
||||
func Test_store_FinalizedCheckpt(t *testing.T) {
|
||||
s := &Store{}
|
||||
var cp *ethpb.Checkpoint
|
||||
require.Equal(t, cp, s.FinalizedCheckpt())
|
||||
_, err := s.FinalizedCheckpt()
|
||||
require.ErrorIs(t, ErrNilCheckpoint, err)
|
||||
cp = ðpb.Checkpoint{Epoch: 1, Root: []byte{'a'}}
|
||||
h := [32]byte{'b'}
|
||||
s.SetFinalizedCheckptAndPayloadHash(cp, h)
|
||||
require.Equal(t, cp, s.FinalizedCheckpt())
|
||||
got, err := s.FinalizedCheckpt()
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, cp, got)
|
||||
require.Equal(t, h, s.FinalizedPayloadBlockHash())
|
||||
}
|
||||
|
||||
func Test_store_PrevFinalizedCheckpt(t *testing.T) {
|
||||
s := &Store{}
|
||||
var cp *ethpb.Checkpoint
|
||||
require.Equal(t, cp, s.PrevFinalizedCheckpt())
|
||||
_, err := s.PrevFinalizedCheckpt()
|
||||
require.ErrorIs(t, ErrNilCheckpoint, err)
|
||||
cp = ðpb.Checkpoint{Epoch: 1, Root: []byte{'a'}}
|
||||
s.SetPrevFinalizedCheckpt(cp)
|
||||
require.Equal(t, cp, s.PrevFinalizedCheckpt())
|
||||
got, err := s.PrevFinalizedCheckpt()
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, cp, got)
|
||||
}
|
||||
|
||||
@@ -282,18 +282,18 @@ func (s *ChainService) CurrentFork() *ethpb.Fork {
|
||||
}
|
||||
|
||||
// FinalizedCheckpt mocks FinalizedCheckpt method in chain service.
|
||||
func (s *ChainService) FinalizedCheckpt() *ethpb.Checkpoint {
|
||||
return s.FinalizedCheckPoint
|
||||
func (s *ChainService) FinalizedCheckpt() (*ethpb.Checkpoint, error) {
|
||||
return s.FinalizedCheckPoint, nil
|
||||
}
|
||||
|
||||
// CurrentJustifiedCheckpt mocks CurrentJustifiedCheckpt method in chain service.
|
||||
func (s *ChainService) CurrentJustifiedCheckpt() *ethpb.Checkpoint {
|
||||
return s.CurrentJustifiedCheckPoint
|
||||
func (s *ChainService) CurrentJustifiedCheckpt() (*ethpb.Checkpoint, error) {
|
||||
return s.CurrentJustifiedCheckPoint, nil
|
||||
}
|
||||
|
||||
// PreviousJustifiedCheckpt mocks PreviousJustifiedCheckpt method in chain service.
|
||||
func (s *ChainService) PreviousJustifiedCheckpt() *ethpb.Checkpoint {
|
||||
return s.PreviousJustifiedCheckPoint
|
||||
func (s *ChainService) PreviousJustifiedCheckpt() (*ethpb.Checkpoint, error) {
|
||||
return s.PreviousJustifiedCheckPoint, nil
|
||||
}
|
||||
|
||||
// ReceiveAttestation mocks ReceiveAttestation method in chain service.
|
||||
|
||||
@@ -80,7 +80,9 @@ func TestService_VerifyWeakSubjectivityRoot(t *testing.T) {
|
||||
wsVerifier: wv,
|
||||
}
|
||||
s.store.SetFinalizedCheckptAndPayloadHash(ðpb.Checkpoint{Epoch: tt.finalizedEpoch}, [32]byte{})
|
||||
err = s.wsVerifier.VerifyWeakSubjectivity(context.Background(), s.store.FinalizedCheckpt().Epoch)
|
||||
cp, err := s.store.FinalizedCheckpt()
|
||||
require.NoError(t, err)
|
||||
err = s.wsVerifier.VerifyWeakSubjectivity(context.Background(), cp.Epoch)
|
||||
if tt.wantErr == nil {
|
||||
require.NoError(t, err)
|
||||
} else {
|
||||
|
||||
@@ -574,7 +574,10 @@ func (bs *Server) GetBlockRoot(ctx context.Context, req *ethpbv1.BlockRequest) (
|
||||
return nil, status.Errorf(codes.NotFound, "No head root was found")
|
||||
}
|
||||
case "finalized":
|
||||
finalized := bs.ChainInfoFetcher.FinalizedCheckpt()
|
||||
finalized, err := bs.ChainInfoFetcher.FinalizedCheckpt()
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.Internal, "Could not retrieve finalized checkpoint: %v", err)
|
||||
}
|
||||
root = finalized.Root
|
||||
case "genesis":
|
||||
blk, err := bs.BeaconDB.GenesisBlock(ctx)
|
||||
@@ -725,7 +728,10 @@ func (bs *Server) blockFromBlockID(ctx context.Context, blockId []byte) (interfa
|
||||
return nil, errors.Wrap(err, "could not retrieve head block")
|
||||
}
|
||||
case "finalized":
|
||||
finalized := bs.ChainInfoFetcher.FinalizedCheckpt()
|
||||
finalized, err := bs.ChainInfoFetcher.FinalizedCheckpt()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not retrieve finalized checkpoint")
|
||||
}
|
||||
finalizedRoot := bytesutil.ToBytes32(finalized.Root)
|
||||
blk, err = bs.BeaconDB.Block(ctx, finalizedRoot)
|
||||
if err != nil {
|
||||
|
||||
@@ -425,17 +425,26 @@ func (bs *Server) chainHeadRetrieval(ctx context.Context) (*ethpb.ChainHead, err
|
||||
return nil
|
||||
}
|
||||
|
||||
finalizedCheckpoint := bs.FinalizationFetcher.FinalizedCheckpt()
|
||||
finalizedCheckpoint, err := bs.FinalizationFetcher.FinalizedCheckpt()
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.Internal, "Could not get finalized checkpoint: %v", err)
|
||||
}
|
||||
if err := validateCP(finalizedCheckpoint, "finalized"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
justifiedCheckpoint := bs.FinalizationFetcher.CurrentJustifiedCheckpt()
|
||||
justifiedCheckpoint, err := bs.FinalizationFetcher.CurrentJustifiedCheckpt()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := validateCP(justifiedCheckpoint, "justified"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
prevJustifiedCheckpoint := bs.FinalizationFetcher.PreviousJustifiedCheckpt()
|
||||
prevJustifiedCheckpoint, err := bs.FinalizationFetcher.PreviousJustifiedCheckpt()
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.Internal, "Could not get previous justified checkpoint: %v", err)
|
||||
}
|
||||
if err := validateCP(prevJustifiedCheckpoint, "prev justified"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -540,10 +540,13 @@ func (bs *Server) GetValidatorParticipation(
|
||||
default:
|
||||
return nil, status.Errorf(codes.Internal, "Invalid state type retrieved with a version of %d", beaconState.Version())
|
||||
}
|
||||
|
||||
cp, err := bs.FinalizationFetcher.FinalizedCheckpt()
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.Internal, "Could not get finalized checkpoint: %v", err)
|
||||
}
|
||||
p := ðpb.ValidatorParticipationResponse{
|
||||
Epoch: requestedEpoch,
|
||||
Finalized: requestedEpoch <= bs.FinalizationFetcher.FinalizedCheckpt().Epoch,
|
||||
Finalized: requestedEpoch <= cp.Epoch,
|
||||
Participation: ðpb.ValidatorParticipation{
|
||||
// TODO(7130): Remove these three deprecated fields.
|
||||
GlobalParticipationRate: float32(b.PrevEpochTargetAttested) / float32(b.ActivePrevEpoch),
|
||||
|
||||
@@ -116,13 +116,19 @@ func (p *StateProvider) State(ctx context.Context, stateId []byte) (state.Beacon
|
||||
return nil, errors.Wrap(err, "could not get genesis state")
|
||||
}
|
||||
case "finalized":
|
||||
checkpoint := p.ChainInfoFetcher.FinalizedCheckpt()
|
||||
checkpoint, err := p.ChainInfoFetcher.FinalizedCheckpt()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not get finalized checkpoint")
|
||||
}
|
||||
s, err = p.StateGenService.StateByRoot(ctx, bytesutil.ToBytes32(checkpoint.Root))
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not get finalized state")
|
||||
}
|
||||
case "justified":
|
||||
checkpoint := p.ChainInfoFetcher.CurrentJustifiedCheckpt()
|
||||
checkpoint, err := p.ChainInfoFetcher.CurrentJustifiedCheckpt()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not get justified checkpoint")
|
||||
}
|
||||
s, err = p.StateGenService.StateByRoot(ctx, bytesutil.ToBytes32(checkpoint.Root))
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not get justified state")
|
||||
|
||||
@@ -73,7 +73,11 @@ func (f *blocksFetcher) waitForMinimumPeers(ctx context.Context) ([]peer.ID, err
|
||||
}
|
||||
var peers []peer.ID
|
||||
if f.mode == modeStopOnFinalizedEpoch {
|
||||
headEpoch := f.chain.FinalizedCheckpt().Epoch
|
||||
cp, err := f.chain.FinalizedCheckpt()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
headEpoch := cp.Epoch
|
||||
_, peers = f.p2p.Peers().BestFinalized(params.BeaconConfig().MaxPeersToSync, headEpoch)
|
||||
} else {
|
||||
headEpoch := slots.ToEpoch(f.chain.HeadSlot())
|
||||
|
||||
@@ -157,13 +157,17 @@ func (f *blocksFetcher) findFork(ctx context.Context, slot types.Slot) (*forkDat
|
||||
|
||||
// The current slot's epoch must be after the finalization epoch,
|
||||
// triggering backtracking on earlier epochs is unnecessary.
|
||||
finalizedEpoch := f.chain.FinalizedCheckpt().Epoch
|
||||
cp, err := f.chain.FinalizedCheckpt()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
finalizedEpoch := cp.Epoch
|
||||
epoch := slots.ToEpoch(slot)
|
||||
if epoch <= finalizedEpoch {
|
||||
return nil, errors.New("slot is not after the finalized epoch, no backtracking is necessary")
|
||||
}
|
||||
// Update slot to the beginning of the current epoch (preserve original slot for comparison).
|
||||
slot, err := slots.EpochStart(epoch)
|
||||
slot, err = slots.EpochStart(epoch)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -287,8 +291,13 @@ func (f *blocksFetcher) findAncestor(ctx context.Context, pid peer.ID, b interfa
|
||||
|
||||
// bestFinalizedSlot returns the highest finalized slot of the majority of connected peers.
|
||||
func (f *blocksFetcher) bestFinalizedSlot() types.Slot {
|
||||
cp, err := f.chain.FinalizedCheckpt()
|
||||
if err != nil {
|
||||
log.WithError(err).Error("Failed to get finalized checkpoint")
|
||||
return 0
|
||||
}
|
||||
finalizedEpoch, _ := f.p2p.Peers().BestFinalized(
|
||||
params.BeaconConfig().MaxPeersToSync, f.chain.FinalizedCheckpt().Epoch)
|
||||
params.BeaconConfig().MaxPeersToSync, cp.Epoch)
|
||||
return params.BeaconConfig().SlotsPerEpoch.Mul(uint64(finalizedEpoch))
|
||||
}
|
||||
|
||||
@@ -303,7 +312,12 @@ func (f *blocksFetcher) bestNonFinalizedSlot() types.Slot {
|
||||
// epoch. For the latter peers supporting that target epoch are returned as well.
|
||||
func (f *blocksFetcher) calculateHeadAndTargetEpochs() (headEpoch, targetEpoch types.Epoch, peers []peer.ID) {
|
||||
if f.mode == modeStopOnFinalizedEpoch {
|
||||
headEpoch = f.chain.FinalizedCheckpt().Epoch
|
||||
cp, err := f.chain.FinalizedCheckpt()
|
||||
if err != nil {
|
||||
log.WithError(err).Error("Failed to get finalized checkpoint")
|
||||
return 0, 0, peers
|
||||
}
|
||||
headEpoch = cp.Epoch
|
||||
targetEpoch, peers = f.p2p.Peers().BestFinalized(params.BeaconConfig().MaxPeersToSync, headEpoch)
|
||||
} else {
|
||||
headEpoch = slots.ToEpoch(f.chain.HeadSlot())
|
||||
|
||||
@@ -1321,7 +1321,9 @@ func TestBlocksQueue_stuckWhenHeadIsSetToOrphanedBlock(t *testing.T) {
|
||||
|
||||
require.NoError(t, queue.start())
|
||||
isProcessedBlock := func(ctx context.Context, blk interfaces.SignedBeaconBlock, blkRoot [32]byte) bool {
|
||||
finalizedSlot, err := slots.EpochStart(mc.FinalizedCheckpt().Epoch)
|
||||
cp, err := mc.FinalizedCheckpt()
|
||||
require.NoError(t, err)
|
||||
finalizedSlot, err := slots.EpochStart(cp.Epoch)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -308,7 +308,12 @@ func (s *Service) updatePeerScorerStats(pid peer.ID, startSlot types.Slot) {
|
||||
|
||||
// isProcessedBlock checks DB and local cache for presence of a given block, to avoid duplicates.
|
||||
func (s *Service) isProcessedBlock(ctx context.Context, blk interfaces.SignedBeaconBlock, blkRoot [32]byte) bool {
|
||||
finalizedSlot, err := slots.EpochStart(s.cfg.Chain.FinalizedCheckpt().Epoch)
|
||||
cp, err := s.cfg.Chain.FinalizedCheckpt()
|
||||
if err != nil {
|
||||
log.Errorf("could not get finalized checkpoint: %v", err)
|
||||
return false
|
||||
}
|
||||
finalizedSlot, err := slots.EpochStart(cp.Epoch)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -173,7 +173,12 @@ func (s *Service) waitForMinimumPeers() {
|
||||
required = flags.Get().MinimumSyncPeers
|
||||
}
|
||||
for {
|
||||
_, peers := s.cfg.P2P.Peers().BestNonFinalized(flags.Get().MinimumSyncPeers, s.cfg.Chain.FinalizedCheckpt().Epoch)
|
||||
cp, err := s.cfg.Chain.FinalizedCheckpt()
|
||||
if err != nil {
|
||||
log.WithError(err).Error("Could not retrieve finalized checkpoint")
|
||||
return
|
||||
}
|
||||
_, peers := s.cfg.P2P.Peers().BestNonFinalized(flags.Get().MinimumSyncPeers, cp.Epoch)
|
||||
if len(peers) >= required {
|
||||
break
|
||||
}
|
||||
|
||||
@@ -210,8 +210,11 @@ func (s *Service) sendBatchRootRequest(ctx context.Context, roots [][32]byte, ra
|
||||
if len(roots) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
_, bestPeers := s.cfg.p2p.Peers().BestFinalized(maxPeerRequest, s.cfg.chain.FinalizedCheckpt().Epoch)
|
||||
cp, err := s.cfg.chain.FinalizedCheckpt()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, bestPeers := s.cfg.p2p.Peers().BestFinalized(maxPeerRequest, cp.Epoch)
|
||||
if len(bestPeers) == 0 {
|
||||
return nil
|
||||
}
|
||||
@@ -272,7 +275,11 @@ func (s *Service) validatePendingSlots() error {
|
||||
defer s.pendingQueueLock.Unlock()
|
||||
oldBlockRoots := make(map[[32]byte]bool)
|
||||
|
||||
finalizedEpoch := s.cfg.chain.FinalizedCheckpt().Epoch
|
||||
cp, err := s.cfg.chain.FinalizedCheckpt()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
finalizedEpoch := cp.Epoch
|
||||
if s.slotToPendingBlocks == nil {
|
||||
return errors.New("slotToPendingBlocks cache can't be nil")
|
||||
}
|
||||
|
||||
@@ -131,10 +131,14 @@ func (s *Service) sendRPCStatusRequest(ctx context.Context, id peer.ID) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cp, err := s.cfg.chain.FinalizedCheckpt()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
resp := &pb.Status{
|
||||
ForkDigest: forkDigest[:],
|
||||
FinalizedRoot: s.cfg.chain.FinalizedCheckpt().Root,
|
||||
FinalizedEpoch: s.cfg.chain.FinalizedCheckpt().Epoch,
|
||||
FinalizedRoot: cp.Root,
|
||||
FinalizedEpoch: cp.Epoch,
|
||||
HeadRoot: headRoot,
|
||||
HeadSlot: s.cfg.chain.HeadSlot(),
|
||||
}
|
||||
@@ -260,10 +264,14 @@ func (s *Service) respondWithStatus(ctx context.Context, stream network.Stream)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cp, err := s.cfg.chain.FinalizedCheckpt()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
resp := &pb.Status{
|
||||
ForkDigest: forkDigest[:],
|
||||
FinalizedRoot: s.cfg.chain.FinalizedCheckpt().Root,
|
||||
FinalizedEpoch: s.cfg.chain.FinalizedCheckpt().Epoch,
|
||||
FinalizedRoot: cp.Root,
|
||||
FinalizedEpoch: cp.Epoch,
|
||||
HeadRoot: headRoot,
|
||||
HeadSlot: s.cfg.chain.HeadSlot(),
|
||||
}
|
||||
@@ -284,7 +292,11 @@ func (s *Service) validateStatusMessage(ctx context.Context, msg *pb.Status) err
|
||||
return p2ptypes.ErrWrongForkDigestVersion
|
||||
}
|
||||
genesis := s.cfg.chain.GenesisTime()
|
||||
finalizedEpoch := s.cfg.chain.FinalizedCheckpt().Epoch
|
||||
cp, err := s.cfg.chain.FinalizedCheckpt()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
finalizedEpoch := cp.Epoch
|
||||
maxEpoch := slots.EpochsSinceGenesis(genesis)
|
||||
// It would take a minimum of 2 epochs to finalize a
|
||||
// previous epoch
|
||||
|
||||
@@ -131,7 +131,11 @@ func (s *Service) validateBeaconBlockPubSub(ctx context.Context, pid peer.ID, ms
|
||||
return pubsub.ValidationIgnore, nil
|
||||
}
|
||||
|
||||
startSlot, err := slots.EpochStart(s.cfg.chain.FinalizedCheckpt().Epoch)
|
||||
cp, err := s.cfg.chain.FinalizedCheckpt()
|
||||
if err != nil {
|
||||
return pubsub.ValidationIgnore, nil
|
||||
}
|
||||
startSlot, err := slots.EpochStart(cp.Epoch)
|
||||
if err != nil {
|
||||
log.WithError(err).WithFields(getBlockFields(blk)).Debug("Ignored block: could not calculate epoch start slot")
|
||||
return pubsub.ValidationIgnore, nil
|
||||
|
||||
@@ -103,21 +103,27 @@ func (bb *Builder) Check(t testing.TB, c *Check) {
|
||||
Epoch: types.Epoch(c.JustifiedCheckPoint.Epoch),
|
||||
Root: common.FromHex(c.JustifiedCheckPoint.Root),
|
||||
}
|
||||
require.DeepEqual(t, cp, bb.service.CurrentJustifiedCheckpt())
|
||||
got, err := bb.service.CurrentJustifiedCheckpt()
|
||||
require.NoError(t, err)
|
||||
require.DeepEqual(t, cp, got)
|
||||
}
|
||||
if c.BestJustifiedCheckPoint != nil {
|
||||
cp := ðpb.Checkpoint{
|
||||
Epoch: types.Epoch(c.BestJustifiedCheckPoint.Epoch),
|
||||
Root: common.FromHex(c.BestJustifiedCheckPoint.Root),
|
||||
}
|
||||
require.DeepEqual(t, cp, bb.service.BestJustifiedCheckpt())
|
||||
got, err := bb.service.BestJustifiedCheckpt()
|
||||
require.NoError(t, err)
|
||||
require.DeepEqual(t, cp, got)
|
||||
}
|
||||
if c.FinalizedCheckPoint != nil {
|
||||
cp := ðpb.Checkpoint{
|
||||
Epoch: types.Epoch(c.FinalizedCheckPoint.Epoch),
|
||||
Root: common.FromHex(c.FinalizedCheckPoint.Root),
|
||||
}
|
||||
require.DeepSSZEqual(t, cp, bb.service.FinalizedCheckpt())
|
||||
got, err := bb.service.FinalizedCheckpt()
|
||||
require.NoError(t, err)
|
||||
require.DeepSSZEqual(t, cp, got)
|
||||
}
|
||||
if c.ProposerBoostRoot != nil {
|
||||
want := fmt.Sprintf("%#x", common.FromHex(*c.ProposerBoostRoot))
|
||||
|
||||
Reference in New Issue
Block a user