Merge pull request #305 from filecoin-project/feat/bad-block-cache
Implement cache for bad blocks
This commit is contained in:
commit
5448ba6a3c
@ -85,3 +85,6 @@ func init() {
|
|||||||
panic("could not parse InitialRewardStr")
|
panic("could not parse InitialRewardStr")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Sync
|
||||||
|
const BadBlockCacheSize = 8192
|
||||||
|
30
chain/badtscache.go
Normal file
30
chain/badtscache.go
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
package chain
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/filecoin-project/go-lotus/build"
|
||||||
|
lru "github.com/hashicorp/golang-lru"
|
||||||
|
"github.com/ipfs/go-cid"
|
||||||
|
)
|
||||||
|
|
||||||
|
type BadBlockCache struct {
|
||||||
|
badBlocks *lru.ARCCache
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewBadBlockCache() *BadBlockCache {
|
||||||
|
cache, err := lru.NewARC(build.BadBlockCacheSize)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &BadBlockCache{
|
||||||
|
badBlocks: cache,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (bts *BadBlockCache) Add(c cid.Cid) {
|
||||||
|
bts.badBlocks.Add(c, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (bts *BadBlockCache) Has(c cid.Cid) bool {
|
||||||
|
return bts.badBlocks.Contains(c)
|
||||||
|
}
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
1
go.mod
1
go.mod
@ -14,6 +14,7 @@ require (
|
|||||||
github.com/gbrlsnchs/jwt/v3 v3.0.0-beta.1
|
github.com/gbrlsnchs/jwt/v3 v3.0.0-beta.1
|
||||||
github.com/go-ole/go-ole v1.2.4 // indirect
|
github.com/go-ole/go-ole v1.2.4 // indirect
|
||||||
github.com/gorilla/websocket v1.4.0
|
github.com/gorilla/websocket v1.4.0
|
||||||
|
github.com/hashicorp/golang-lru v0.5.3
|
||||||
github.com/ipfs/go-bitswap v0.1.8
|
github.com/ipfs/go-bitswap v0.1.8
|
||||||
github.com/ipfs/go-block-format v0.0.2
|
github.com/ipfs/go-block-format v0.0.2
|
||||||
github.com/ipfs/go-blockservice v0.1.3-0.20190908200855-f22eea50656c
|
github.com/ipfs/go-blockservice v0.1.3-0.20190908200855-f22eea50656c
|
||||||
|
Loading…
Reference in New Issue
Block a user