mirror of
https://github.com/OffchainLabs/prysm.git
synced 2026-01-09 21:38:05 -05:00
Verify nil block helper (#8447)
This commit is contained in:
@@ -148,6 +148,9 @@ func (s *Service) saveHead(ctx context.Context, headRoot [32]byte) error {
|
||||
// root in DB. With the inception of initial-sync-cache-state flag, it uses finalized
|
||||
// check point as anchors to resume sync therefore head is no longer needed to be saved on per slot basis.
|
||||
func (s *Service) saveHeadNoDB(ctx context.Context, b *ethpb.SignedBeaconBlock, r [32]byte, hs *stateTrie.BeaconState) error {
|
||||
if err := helpers.VerifyNilBeaconBlock(b); err != nil {
|
||||
return err
|
||||
}
|
||||
cachedHeadRoot, err := s.HeadRoot(ctx)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "could not get head root from cache")
|
||||
@@ -156,10 +159,6 @@ func (s *Service) saveHeadNoDB(ctx context.Context, b *ethpb.SignedBeaconBlock,
|
||||
return nil
|
||||
}
|
||||
|
||||
if b == nil || b.Block == nil {
|
||||
return errors.New("cannot save nil head block")
|
||||
}
|
||||
|
||||
s.setHeadInitialSync(r, stateTrie.CopySignedBeaconBlock(b), hs)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -102,8 +102,8 @@ func (s *Service) verifyBeaconBlock(ctx context.Context, data *ethpb.Attestation
|
||||
if b == nil && s.hasInitSyncBlock(r) {
|
||||
b = s.getInitSyncBlock(r)
|
||||
}
|
||||
if b == nil || b.Block == nil {
|
||||
return fmt.Errorf("beacon block %#x does not exist", bytesutil.Trunc(data.BeaconBlockRoot))
|
||||
if err := helpers.VerifyNilBeaconBlock(b); err != nil {
|
||||
return err
|
||||
}
|
||||
if b.Block.Slot > data.Slot {
|
||||
return fmt.Errorf("could not process attestation for future block, block.Slot=%d > attestation.Data.Slot=%d", b.Block.Slot, data.Slot)
|
||||
|
||||
@@ -311,7 +311,7 @@ func TestVerifyBeaconBlock_NoBlock(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
|
||||
d := testutil.HydrateAttestationData(ðpb.AttestationData{})
|
||||
assert.ErrorContains(t, "beacon block 0x000000000000 does not exist", service.verifyBeaconBlock(ctx, d))
|
||||
assert.ErrorContains(t, "signed beacon block can't be nil", service.verifyBeaconBlock(ctx, d))
|
||||
}
|
||||
|
||||
func TestVerifyBeaconBlock_futureBlock(t *testing.T) {
|
||||
|
||||
@@ -22,8 +22,8 @@ func ProcessAttestations(
|
||||
beaconState *stateTrie.BeaconState,
|
||||
b *ethpb.SignedBeaconBlock,
|
||||
) (*stateTrie.BeaconState, error) {
|
||||
if b.Block == nil || b.Block.Body == nil {
|
||||
return nil, errors.New("block and block body can't be nil")
|
||||
if err := helpers.VerifyNilBeaconBlock(b); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var err error
|
||||
@@ -84,8 +84,8 @@ func ProcessAttestationsNoVerifySignature(
|
||||
beaconState *stateTrie.BeaconState,
|
||||
b *ethpb.SignedBeaconBlock,
|
||||
) (*stateTrie.BeaconState, error) {
|
||||
if b.Block == nil || b.Block.Body == nil {
|
||||
return nil, errors.New("block and block body can't be nil")
|
||||
if err := helpers.VerifyNilBeaconBlock(b); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
body := b.Block.Body
|
||||
var err error
|
||||
|
||||
@@ -38,8 +38,8 @@ func ProcessAttesterSlashings(
|
||||
beaconState *stateTrie.BeaconState,
|
||||
b *ethpb.SignedBeaconBlock,
|
||||
) (*stateTrie.BeaconState, error) {
|
||||
if b.Block == nil || b.Block.Body == nil {
|
||||
return nil, errors.New("block and block body can't be nil")
|
||||
if err := helpers.VerifyNilBeaconBlock(b); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
body := b.Block.Body
|
||||
|
||||
@@ -70,8 +70,8 @@ func ProcessDeposits(
|
||||
beaconState *stateTrie.BeaconState,
|
||||
b *ethpb.SignedBeaconBlock,
|
||||
) (*stateTrie.BeaconState, error) {
|
||||
if b.Block == nil || b.Block.Body == nil {
|
||||
return nil, errors.New("block and block body can't be nil")
|
||||
if err := helpers.VerifyNilBeaconBlock(b); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
deposits := b.Block.Body.Deposits
|
||||
|
||||
@@ -48,8 +48,8 @@ func ProcessVoluntaryExits(
|
||||
beaconState *stateTrie.BeaconState,
|
||||
b *ethpb.SignedBeaconBlock,
|
||||
) (*stateTrie.BeaconState, error) {
|
||||
if b.Block == nil || b.Block.Body == nil {
|
||||
return nil, errors.New("block and block body can't be nil")
|
||||
if err := helpers.VerifyNilBeaconBlock(b); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
body := b.Block.Body
|
||||
|
||||
@@ -41,8 +41,8 @@ func ProcessProposerSlashings(
|
||||
beaconState *stateTrie.BeaconState,
|
||||
b *ethpb.SignedBeaconBlock,
|
||||
) (*stateTrie.BeaconState, error) {
|
||||
if b.Block == nil || b.Block.Body == nil {
|
||||
return nil, errors.New("block and block body can't be nil")
|
||||
if err := helpers.VerifyNilBeaconBlock(b); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
body := b.Block.Body
|
||||
|
||||
@@ -30,10 +30,9 @@ func ProcessRandao(
|
||||
beaconState *stateTrie.BeaconState,
|
||||
b *ethpb.SignedBeaconBlock,
|
||||
) (*stateTrie.BeaconState, error) {
|
||||
if b.Block == nil || b.Block.Body == nil {
|
||||
return nil, errors.New("block and block body can't be nil")
|
||||
if err := helpers.VerifyNilBeaconBlock(b); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
body := b.Block.Body
|
||||
buf, proposerPub, domain, err := randaoSigningData(beaconState)
|
||||
if err != nil {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package helpers
|
||||
|
||||
import (
|
||||
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
|
||||
"math"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
@@ -9,6 +10,22 @@ import (
|
||||
"github.com/prysmaticlabs/prysm/shared/params"
|
||||
)
|
||||
|
||||
// VerifyNilBeaconBlock checks if any composite field of input signed beacon block is nil.
|
||||
// Access to these nil fields will result in run time panic,
|
||||
// it is recommended to run these checks as first line of defense.
|
||||
func VerifyNilBeaconBlock(b *ethpb.SignedBeaconBlock) error {
|
||||
if b == nil {
|
||||
return errors.New("signed beacon block can't be nil")
|
||||
}
|
||||
if b.Block == nil {
|
||||
return errors.New("beacon block can't be nil")
|
||||
}
|
||||
if b.Block.Body == nil {
|
||||
return errors.New("beacon block body can't be nil")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// BlockRootAtSlot returns the block root stored in the BeaconState for a recent slot.
|
||||
// It returns an error if the requested block root is not within the slot range.
|
||||
//
|
||||
|
||||
@@ -556,8 +556,8 @@ func ProcessOperationsNoVerifyAttsSigs(
|
||||
|
||||
// VerifyOperationLengths verifies that block operation lengths are valid.
|
||||
func VerifyOperationLengths(_ context.Context, state *stateTrie.BeaconState, b *ethpb.SignedBeaconBlock) (*stateTrie.BeaconState, error) {
|
||||
if b.Block == nil || b.Block.Body == nil {
|
||||
return nil, errors.New("block and block body can't be nil")
|
||||
if err := helpers.VerifyNilBeaconBlock(b); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
body := b.Block.Body
|
||||
|
||||
|
||||
@@ -225,8 +225,8 @@ func slotByBlockRoot(ctx context.Context, tx *bolt.Tx, blockRoot []byte) (uint64
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
if b.Block == nil {
|
||||
return 0, errors.New("block can't be nil")
|
||||
if err := helpers.VerifyNilBeaconBlock(b); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return b.Block.Slot, nil
|
||||
}
|
||||
|
||||
@@ -304,25 +304,34 @@ func (bs *Server) chainHeadRetrieval(ctx context.Context) (*ethpb.ChainHead, err
|
||||
finalizedCheckpoint := bs.FinalizationFetcher.FinalizedCheckpt()
|
||||
if !isGenesis(finalizedCheckpoint) {
|
||||
b, err := bs.BeaconDB.Block(ctx, bytesutil.ToBytes32(finalizedCheckpoint.Root))
|
||||
if err != nil || b == nil || b.Block == nil {
|
||||
if err != nil {
|
||||
return nil, status.Error(codes.Internal, "Could not get finalized block")
|
||||
}
|
||||
if err := helpers.VerifyNilBeaconBlock(b); err != nil {
|
||||
return nil, status.Errorf(codes.Internal, "Could not get finalized block: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
justifiedCheckpoint := bs.FinalizationFetcher.CurrentJustifiedCheckpt()
|
||||
if !isGenesis(justifiedCheckpoint) {
|
||||
b, err := bs.BeaconDB.Block(ctx, bytesutil.ToBytes32(justifiedCheckpoint.Root))
|
||||
if err != nil || b == nil || b.Block == nil {
|
||||
if err != nil {
|
||||
return nil, status.Error(codes.Internal, "Could not get justified block")
|
||||
}
|
||||
if err := helpers.VerifyNilBeaconBlock(b); err != nil {
|
||||
return nil, status.Errorf(codes.Internal, "Could not get justified block: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
prevJustifiedCheckpoint := bs.FinalizationFetcher.PreviousJustifiedCheckpt()
|
||||
if !isGenesis(prevJustifiedCheckpoint) {
|
||||
b, err := bs.BeaconDB.Block(ctx, bytesutil.ToBytes32(prevJustifiedCheckpoint.Root))
|
||||
if err != nil || b == nil || b.Block == nil {
|
||||
if err != nil {
|
||||
return nil, status.Error(codes.Internal, "Could not get prev justified block")
|
||||
}
|
||||
if err := helpers.VerifyNilBeaconBlock(b); err != nil {
|
||||
return nil, status.Errorf(codes.Internal, "Could not get prev justified block: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
fSlot, err := helpers.StartSlot(finalizedCheckpoint.Epoch)
|
||||
|
||||
@@ -21,6 +21,7 @@ go_library(
|
||||
"//beacon-chain/core/feed/block:go_default_library",
|
||||
"//beacon-chain/core/feed/operation:go_default_library",
|
||||
"//beacon-chain/core/feed/state:go_default_library",
|
||||
"//beacon-chain/core/helpers:go_default_library",
|
||||
"//beacon-chain/db:go_default_library",
|
||||
"//beacon-chain/db/filters:go_default_library",
|
||||
"//beacon-chain/operations/attestations:go_default_library",
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"bytes"
|
||||
"context"
|
||||
"errors"
|
||||
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
@@ -106,8 +107,8 @@ func (bs *Server) headStateRoot(ctx context.Context) ([]byte, error) {
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.Internal, "Could not get head block: %v", err)
|
||||
}
|
||||
if b == nil || b.Block == nil {
|
||||
return nil, status.Error(codes.Internal, "Nil block")
|
||||
if err := helpers.VerifyNilBeaconBlock(b); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return b.Block.StateRoot, nil
|
||||
}
|
||||
@@ -117,8 +118,8 @@ func (bs *Server) genesisStateRoot(ctx context.Context) ([]byte, error) {
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.Internal, "Could not get genesis block: %v", err)
|
||||
}
|
||||
if b == nil || b.Block == nil {
|
||||
return nil, status.Error(codes.Internal, "Nil block")
|
||||
if err := helpers.VerifyNilBeaconBlock(b); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return b.Block.StateRoot, nil
|
||||
}
|
||||
@@ -132,8 +133,8 @@ func (bs *Server) finalizedStateRoot(ctx context.Context) ([]byte, error) {
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.Internal, "Could not get finalized block: %v", err)
|
||||
}
|
||||
if b == nil || b.Block == nil {
|
||||
return nil, status.Error(codes.Internal, "Nil block")
|
||||
if err := helpers.VerifyNilBeaconBlock(b); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return b.Block.StateRoot, nil
|
||||
}
|
||||
@@ -147,8 +148,8 @@ func (bs *Server) justifiedStateRoot(ctx context.Context) ([]byte, error) {
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.Internal, "Could not get justified block: %v", err)
|
||||
}
|
||||
if b == nil || b.Block == nil {
|
||||
return nil, status.Error(codes.Internal, "Nil block")
|
||||
if err := helpers.VerifyNilBeaconBlock(b); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return b.Block.StateRoot, nil
|
||||
}
|
||||
|
||||
@@ -354,8 +354,8 @@ func (s *Service) pendingBlocksInCache(slot uint64) []*ethpb.SignedBeaconBlock {
|
||||
|
||||
// This adds input signed beacon block to slotToPendingBlocks cache.
|
||||
func (s *Service) addPendingBlockToCache(b *ethpb.SignedBeaconBlock) error {
|
||||
if b == nil || b.Block == nil {
|
||||
return errors.New("nil block")
|
||||
if err := helpers.VerifyNilBeaconBlock(b); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
blks := s.pendingBlocksInCache(b.Block.Slot)
|
||||
|
||||
@@ -319,10 +319,10 @@ func TestService_sortedPendingSlots(t *testing.T) {
|
||||
}
|
||||
|
||||
var lastSlot uint64 = math.MaxUint64
|
||||
require.NoError(t, r.insertBlockToPendingQueue(lastSlot, ðpb.SignedBeaconBlock{Block: ðpb.BeaconBlock{Slot: lastSlot}}, [32]byte{1}))
|
||||
require.NoError(t, r.insertBlockToPendingQueue(lastSlot-3, ðpb.SignedBeaconBlock{Block: ðpb.BeaconBlock{Slot: lastSlot - 3}}, [32]byte{2}))
|
||||
require.NoError(t, r.insertBlockToPendingQueue(lastSlot-5, ðpb.SignedBeaconBlock{Block: ðpb.BeaconBlock{Slot: lastSlot - 5}}, [32]byte{3}))
|
||||
require.NoError(t, r.insertBlockToPendingQueue(lastSlot-2, ðpb.SignedBeaconBlock{Block: ðpb.BeaconBlock{Slot: lastSlot - 2}}, [32]byte{4}))
|
||||
require.NoError(t, r.insertBlockToPendingQueue(lastSlot, testutil.HydrateSignedBeaconBlock(ðpb.SignedBeaconBlock{Block: ðpb.BeaconBlock{Slot: lastSlot}}), [32]byte{1}))
|
||||
require.NoError(t, r.insertBlockToPendingQueue(lastSlot-3, testutil.HydrateSignedBeaconBlock(ðpb.SignedBeaconBlock{Block: ðpb.BeaconBlock{Slot: lastSlot - 3}}), [32]byte{2}))
|
||||
require.NoError(t, r.insertBlockToPendingQueue(lastSlot-5, testutil.HydrateSignedBeaconBlock(ðpb.SignedBeaconBlock{Block: ðpb.BeaconBlock{Slot: lastSlot - 5}}), [32]byte{3}))
|
||||
require.NoError(t, r.insertBlockToPendingQueue(lastSlot-2, testutil.HydrateSignedBeaconBlock(ðpb.SignedBeaconBlock{Block: ðpb.BeaconBlock{Slot: lastSlot - 2}}), [32]byte{4}))
|
||||
|
||||
want := []uint64{lastSlot - 5, lastSlot - 3, lastSlot - 2, lastSlot}
|
||||
assert.DeepEqual(t, want, r.sortedPendingSlots(), "Unexpected pending slots list")
|
||||
|
||||
Reference in New Issue
Block a user