Merge pull request #1694 from filecoin-project/fix/nil-protections

add some simple sanity checking to incoming blocks in the syncer
This commit is contained in:
Łukasz Magiera 2020-05-08 20:26:50 +02:00 committed by GitHub
commit e4cb28a310
3 changed files with 55 additions and 6 deletions

View File

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

View File

@ -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,26 @@ 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 xerrors.Errorf("block cannot have nil election proof")
}
if h.Ticket == nil {
return xerrors.Errorf("block cannot have nil ticket")
}
if h.BlockSig == nil {
return xerrors.Errorf("block had nil signature")
}
if h.BLSAggregate == nil {
return xerrors.Errorf("block had nil bls aggregate signature")
}
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 +533,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...))
@ -538,9 +562,6 @@ func (syncer *Syncer) ValidateBlock(ctx context.Context, b *types.FullBlock) err
//nulls := h.Height - (baseTs.Height() + 1)
// fast checks first
if h.BlockSig == nil {
return xerrors.Errorf("block had nil signature")
}
now := uint64(time.Now().Unix())
if h.Timestamp > now+build.AllowableClockDrift {
@ -617,8 +638,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)
}

View File

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