Verify nil block helper (#8447)

This commit is contained in:
terence tsao
2021-02-15 07:11:25 -08:00
committed by GitHub
parent 28839fbab2
commit 28631e7791
17 changed files with 69 additions and 43 deletions

View File

@@ -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
}

View File

@@ -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)

View File

@@ -311,7 +311,7 @@ func TestVerifyBeaconBlock_NoBlock(t *testing.T) {
require.NoError(t, err)
d := testutil.HydrateAttestationData(&ethpb.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) {

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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 {

View File

@@ -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.
//

View File

@@ -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

View File

@@ -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
}

View File

@@ -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)

View File

@@ -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",

View File

@@ -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
}

View File

@@ -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)

View File

@@ -319,10 +319,10 @@ func TestService_sortedPendingSlots(t *testing.T) {
}
var lastSlot uint64 = math.MaxUint64
require.NoError(t, r.insertBlockToPendingQueue(lastSlot, &ethpb.SignedBeaconBlock{Block: &ethpb.BeaconBlock{Slot: lastSlot}}, [32]byte{1}))
require.NoError(t, r.insertBlockToPendingQueue(lastSlot-3, &ethpb.SignedBeaconBlock{Block: &ethpb.BeaconBlock{Slot: lastSlot - 3}}, [32]byte{2}))
require.NoError(t, r.insertBlockToPendingQueue(lastSlot-5, &ethpb.SignedBeaconBlock{Block: &ethpb.BeaconBlock{Slot: lastSlot - 5}}, [32]byte{3}))
require.NoError(t, r.insertBlockToPendingQueue(lastSlot-2, &ethpb.SignedBeaconBlock{Block: &ethpb.BeaconBlock{Slot: lastSlot - 2}}, [32]byte{4}))
require.NoError(t, r.insertBlockToPendingQueue(lastSlot, testutil.HydrateSignedBeaconBlock(&ethpb.SignedBeaconBlock{Block: &ethpb.BeaconBlock{Slot: lastSlot}}), [32]byte{1}))
require.NoError(t, r.insertBlockToPendingQueue(lastSlot-3, testutil.HydrateSignedBeaconBlock(&ethpb.SignedBeaconBlock{Block: &ethpb.BeaconBlock{Slot: lastSlot - 3}}), [32]byte{2}))
require.NoError(t, r.insertBlockToPendingQueue(lastSlot-5, testutil.HydrateSignedBeaconBlock(&ethpb.SignedBeaconBlock{Block: &ethpb.BeaconBlock{Slot: lastSlot - 5}}), [32]byte{3}))
require.NoError(t, r.insertBlockToPendingQueue(lastSlot-2, testutil.HydrateSignedBeaconBlock(&ethpb.SignedBeaconBlock{Block: &ethpb.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")