Implement cache for bad blocks

This commit is contained in:
whyrusleeping 2019-10-09 17:50:57 +09:00
parent a71772ae18
commit da08ab9fd8
2 changed files with 45 additions and 5 deletions

31
chain/badtscache.go Normal file
View File

@ -0,0 +1,31 @@
package chain
import (
"sync"
"github.com/ipfs/go-cid"
)
type BadBlockCache struct {
lk sync.Mutex
badBlocks map[cid.Cid]struct{}
}
func NewBadBlockCache() *BadBlockCache {
return &BadBlockCache{
badBlocks: make(map[cid.Cid]struct{}),
}
}
func (bts *BadBlockCache) Add(c cid.Cid) {
bts.lk.Lock()
defer bts.lk.Unlock()
bts.badBlocks[c] = struct{}{}
}
func (bts *BadBlockCache) Has(c cid.Cid) bool {
bts.lk.Lock()
defer bts.lk.Unlock()
_, ok := bts.badBlocks[c]
return ok
}

View File

@ -44,7 +44,7 @@ type Syncer struct {
syncLock sync.Mutex syncLock sync.Mutex
// TipSets known to be invalid // TipSets known to be invalid
bad BadTipSetCache bad *BadBlockCache
// handle to the block sync service // handle to the block sync service
Bsync *BlockSync Bsync *BlockSync
@ -71,6 +71,7 @@ func NewSyncer(sm *stmgr.StateManager, bsync *BlockSync, self peer.ID) (*Syncer,
} }
return &Syncer{ return &Syncer{
bad: NewBadBlockCache(),
Genesis: gent, Genesis: gent,
Bsync: bsync, Bsync: bsync,
peerHeads: make(map[peer.ID]*types.TipSet), peerHeads: make(map[peer.ID]*types.TipSet),
@ -80,10 +81,6 @@ func NewSyncer(sm *stmgr.StateManager, bsync *BlockSync, self peer.ID) (*Syncer,
}, nil }, nil
} }
type BadTipSetCache struct {
badBlocks map[cid.Cid]struct{}
}
const BootstrapPeerThreshold = 1 const BootstrapPeerThreshold = 1
// InformNewHead informs the syncer about a new potential tipset // InformNewHead informs the syncer about a new potential tipset
@ -359,6 +356,7 @@ func (syncer *Syncer) ValidateTipSet(ctx context.Context, fts *store.FullTipSet)
for _, b := range fts.Blocks { for _, b := range fts.Blocks {
if err := syncer.ValidateBlock(ctx, b); err != nil { if err := syncer.ValidateBlock(ctx, b); err != nil {
syncer.bad.Add(b.Cid())
return xerrors.Errorf("validating block %s: %w", b.Cid(), err) return xerrors.Errorf("validating block %s: %w", b.Cid(), err)
} }
} }
@ -610,6 +608,12 @@ func (syncer *Syncer) collectHeaders(ctx context.Context, from *types.TipSet, to
// If, for some reason, we have a suffix of the chain locally, handle that here // If, for some reason, we have a suffix of the chain locally, handle that here
for blockSet[len(blockSet)-1].Height() > untilHeight { for blockSet[len(blockSet)-1].Height() > untilHeight {
log.Warn("syncing local: ", at) log.Warn("syncing local: ", at)
for _, bc := range at {
if syncer.bad.Has(bc) {
return nil, xerrors.Errorf("chain contained block marked previously as bad (%s, %s)", from.Cids(), bc)
}
}
ts, err := syncer.store.LoadTipSet(at) ts, err := syncer.store.LoadTipSet(at)
if err != nil { if err != nil {
if xerrors.Is(err, bstore.ErrNotFound) { if xerrors.Is(err, bstore.ErrNotFound) {
@ -651,6 +655,11 @@ loop:
if b.Height() < untilHeight { if b.Height() < untilHeight {
break loop break loop
} }
for _, bc := range b.Cids() {
if syncer.bad.Has(bc) {
return nil, xerrors.Errorf("chain contained block marked previously as bad (%s, %s)", from.Cids(), bc)
}
}
blockSet = append(blockSet, b) blockSet = append(blockSet, b)
} }