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:
commit
e4cb28a310
@ -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,
|
||||
|
@ -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)
|
||||
}
|
||||
|
||||
|
@ -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")
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user