From 8a69467982745b481a955bb843aab2cddbd29ca0 Mon Sep 17 00:00:00 2001 From: Jeromy Date: Fri, 8 May 2020 10:59:18 -0700 Subject: [PATCH] add some simple sanity checking to incoming blocks in the syncer --- chain/gen/genesis/genesis.go | 1 + chain/sync.go | 17 ++++++++++++++--- chain/sync_test.go | 28 ++++++++++++++++++++++++++++ chain/types/blockheader.go | 9 +++++++++ 4 files changed, 52 insertions(+), 3 deletions(-) diff --git a/chain/gen/genesis/genesis.go b/chain/gen/genesis/genesis.go index 8e108dcb4..d79696e0f 100644 --- a/chain/gen/genesis/genesis.go +++ b/chain/gen/genesis/genesis.go @@ -273,6 +273,7 @@ func MakeGenesisBlock(ctx context.Context, bs bstore.Blockstore, sys runtime.Sys BLSAggregate: nil, BlockSig: nil, Timestamp: template.Timestamp, + ElectionProof: new(types.ElectionProof), BeaconEntries: []types.BeaconEntry{ { Round: 0, diff --git a/chain/sync.go b/chain/sync.go index e2a78ff46..5a3bf5806 100644 --- a/chain/sync.go +++ b/chain/sync.go @@ -88,7 +88,7 @@ type Syncer struct { func NewSyncer(sm *stmgr.StateManager, bsync *blocksync.BlockSync, connmgr connmgr.ConnManager, self peer.ID, beacon beacon.RandomBeacon, verifier ffiwrapper.Verifier) (*Syncer, error) { gen, err := sm.ChainStore().GetGenesis() if err != nil { - return nil, err + return nil, xerrors.Errorf("getting genesis block: %w", err) } gent, err := types.NewTipSet([]*types.BlockHeader{gen}) @@ -505,6 +505,14 @@ func (syncer *Syncer) minerIsValid(ctx context.Context, maddr address.Address, b var ErrTemporal = errors.New("temporal error") +func blockSanityChecks(h *types.BlockHeader) error { + if h.ElectionProof == nil { + return fmt.Errorf("block cannot have nil election proof") + } + + return nil +} + // Should match up with 'Semantical Validation' in validation.md in the spec func (syncer *Syncer) ValidateBlock(ctx context.Context, b *types.FullBlock) error { ctx, span := trace.StartSpan(ctx, "validateBlock") @@ -513,6 +521,10 @@ func (syncer *Syncer) ValidateBlock(ctx context.Context, b *types.FullBlock) err log.Warn("insecure test validation is enabled, if you see this outside of a test, it is a severe bug!") } + if err := blockSanityChecks(b.Header); err != nil { + return xerrors.Errorf("incoming header failed basic sanity checks: %w", err) + } + h := b.Header baseTs, err := syncer.store.LoadTipSet(types.NewTipSetKey(h.Parents...)) @@ -617,8 +629,7 @@ func (syncer *Syncer) ValidateBlock(ctx context.Context, b *types.FullBlock) err return xerrors.Errorf("could not draw randomness: %w", err) } - err = gen.VerifyVRF(ctx, waddr, vrfBase, h.ElectionProof.VRFProof) - if err != nil { + if err := gen.VerifyVRF(ctx, waddr, vrfBase, h.ElectionProof.VRFProof); err != nil { return xerrors.Errorf("validating block election proof failed: %w", err) } diff --git a/chain/sync_test.go b/chain/sync_test.go index 70c3232e2..80310a85f 100644 --- a/chain/sync_test.go +++ b/chain/sync_test.go @@ -21,6 +21,7 @@ import ( "github.com/filecoin-project/lotus/chain/gen" "github.com/filecoin-project/lotus/chain/store" "github.com/filecoin-project/lotus/chain/types" + mocktypes "github.com/filecoin-project/lotus/chain/types/mock" "github.com/filecoin-project/lotus/node" "github.com/filecoin-project/lotus/node/impl" "github.com/filecoin-project/lotus/node/modules" @@ -511,3 +512,30 @@ func runSyncBenchLength(b *testing.B, l int) { tu.waitUntilSync(0, client) } + +func TestSyncInputs(t *testing.T) { + H := 10 + tu := prepSyncTest(t, H) + + p1 := tu.addClientNode() + + fn := tu.nds[p1].(*impl.FullNodeAPI) + + s := fn.SyncAPI.Syncer + + err := s.ValidateBlock(context.TODO(), &types.FullBlock{ + Header: &types.BlockHeader{}, + }) + if err == nil { + t.Fatal("should error on empty block") + } + + h := mocktypes.MkBlock(nil, 123, 432) + + h.ElectionProof = nil + + err = s.ValidateBlock(context.TODO(), &types.FullBlock{Header: h}) + if err == nil { + t.Fatal("should error on block with nil election proof") + } +} diff --git a/chain/types/blockheader.go b/chain/types/blockheader.go index 86d516f98..adbb13c95 100644 --- a/chain/types/blockheader.go +++ b/chain/types/blockheader.go @@ -2,6 +2,7 @@ package types import ( "bytes" + "fmt" "math/big" "github.com/minio/blake2b-simd" @@ -101,6 +102,14 @@ func DecodeBlock(b []byte) (*BlockHeader, error) { return nil, err } + if blk.ElectionProof == nil { + return nil, fmt.Errorf("block cannot have nil election proof") + } + + if blk.Ticket == nil { + return nil, fmt.Errorf("block cannot have nil ticket") + } + return &blk, nil }