Merge pull request #1253 from filecoin-project/feat/bad-ts-cache-reasons

mark down reason for block inclusion in bad tipset cache
This commit is contained in:
Whyrusleeping 2020-02-17 12:20:20 -08:00 committed by GitHub
commit 4750f32ab6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 78 additions and 18 deletions

View File

@ -46,6 +46,7 @@ type FullNode interface {
SyncSubmitBlock(ctx context.Context, blk *types.BlockMsg) error SyncSubmitBlock(ctx context.Context, blk *types.BlockMsg) error
SyncIncomingBlocks(ctx context.Context) (<-chan *types.BlockHeader, error) SyncIncomingBlocks(ctx context.Context) (<-chan *types.BlockHeader, error)
SyncMarkBad(ctx context.Context, bcid cid.Cid) error SyncMarkBad(ctx context.Context, bcid cid.Cid) error
SyncCheckBad(ctx context.Context, bcid cid.Cid) (string, error)
// messages // messages
MpoolPending(context.Context, *types.TipSet) ([]*types.SignedMessage, error) MpoolPending(context.Context, *types.TipSet) ([]*types.SignedMessage, error)

View File

@ -66,6 +66,7 @@ type FullNodeStruct struct {
SyncSubmitBlock func(ctx context.Context, blk *types.BlockMsg) error `perm:"write"` SyncSubmitBlock func(ctx context.Context, blk *types.BlockMsg) error `perm:"write"`
SyncIncomingBlocks func(ctx context.Context) (<-chan *types.BlockHeader, error) `perm:"read"` SyncIncomingBlocks func(ctx context.Context) (<-chan *types.BlockHeader, error) `perm:"read"`
SyncMarkBad func(ctx context.Context, bcid cid.Cid) error `perm:"admin"` SyncMarkBad func(ctx context.Context, bcid cid.Cid) error `perm:"admin"`
SyncCheckBad func(ctx context.Context, bcid cid.Cid) (string, error) `perm:"read"`
MpoolPending func(context.Context, *types.TipSet) ([]*types.SignedMessage, error) `perm:"read"` MpoolPending func(context.Context, *types.TipSet) ([]*types.SignedMessage, error) `perm:"read"`
MpoolPush func(context.Context, *types.SignedMessage) (cid.Cid, error) `perm:"write"` MpoolPush func(context.Context, *types.SignedMessage) (cid.Cid, error) `perm:"write"`
@ -401,6 +402,10 @@ func (c *FullNodeStruct) SyncMarkBad(ctx context.Context, bcid cid.Cid) error {
return c.Internal.SyncMarkBad(ctx, bcid) return c.Internal.SyncMarkBad(ctx, bcid)
} }
func (c *FullNodeStruct) SyncCheckBad(ctx context.Context, bcid cid.Cid) (string, error) {
return c.Internal.SyncCheckBad(ctx, bcid)
}
func (c *FullNodeStruct) StateMinerSectors(ctx context.Context, addr address.Address, ts *types.TipSet) ([]*api.ChainSectorInfo, error) { func (c *FullNodeStruct) StateMinerSectors(ctx context.Context, addr address.Address, ts *types.TipSet) ([]*api.ChainSectorInfo, error) {
return c.Internal.StateMinerSectors(ctx, addr, ts) return c.Internal.StateMinerSectors(ctx, addr, ts)
} }

View File

@ -21,10 +21,15 @@ func NewBadBlockCache() *BadBlockCache {
} }
} }
func (bts *BadBlockCache) Add(c cid.Cid) { func (bts *BadBlockCache) Add(c cid.Cid, reason string) {
bts.badBlocks.Add(c, nil) bts.badBlocks.Add(c, reason)
} }
func (bts *BadBlockCache) Has(c cid.Cid) bool { func (bts *BadBlockCache) Has(c cid.Cid) (string, bool) {
return bts.badBlocks.Contains(c) rval, ok := bts.badBlocks.Get(c)
if !ok {
return "", false
}
return rval.(string), true
} }

View File

@ -118,8 +118,8 @@ func (syncer *Syncer) InformNewHead(from peer.ID, fts *store.FullTipSet) bool {
} }
for _, b := range fts.Blocks { for _, b := range fts.Blocks {
if syncer.bad.Has(b.Cid()) { if reason, ok := syncer.bad.Has(b.Cid()); ok {
log.Warnf("InformNewHead called on block marked as bad: %s", b.Cid()) log.Warnf("InformNewHead called on block marked as bad: %s (reason: %s)", b.Cid(), reason)
return false return false
} }
if err := syncer.ValidateMsgMeta(b); err != nil { if err := syncer.ValidateMsgMeta(b); err != nil {
@ -450,7 +450,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 {
if isPermanent(err) { if isPermanent(err) {
syncer.bad.Add(b.Cid()) syncer.bad.Add(b.Cid(), err.Error())
} }
return xerrors.Errorf("validating block %s: %w", b.Cid(), err) return xerrors.Errorf("validating block %s: %w", b.Cid(), err)
} }
@ -876,11 +876,11 @@ func (syncer *Syncer) collectHeaders(ctx context.Context, from *types.TipSet, to
) )
for _, pcid := range from.Parents().Cids() { for _, pcid := range from.Parents().Cids() {
if syncer.bad.Has(pcid) { if reason, ok := syncer.bad.Has(pcid); ok {
for _, b := range from.Cids() { for _, b := range from.Cids() {
syncer.bad.Add(b) syncer.bad.Add(b, fmt.Sprintf("linked to %s", pcid))
} }
return nil, xerrors.Errorf("chain linked to block marked previously as bad (%s, %s)", from.Cids(), pcid) return nil, xerrors.Errorf("chain linked to block marked previously as bad (%s, %s) (reason: %s)", from.Cids(), pcid, reason)
} }
} }
@ -898,12 +898,12 @@ func (syncer *Syncer) collectHeaders(ctx context.Context, from *types.TipSet, to
loop: loop:
for blockSet[len(blockSet)-1].Height() > untilHeight { for blockSet[len(blockSet)-1].Height() > untilHeight {
for _, bc := range at.Cids() { for _, bc := range at.Cids() {
if syncer.bad.Has(bc) { if reason, ok := syncer.bad.Has(bc); ok {
for _, b := range acceptedBlocks { for _, b := range acceptedBlocks {
syncer.bad.Add(b) syncer.bad.Add(b, fmt.Sprintf("chain contained %s", bc))
} }
return nil, xerrors.Errorf("chain contained block marked previously as bad (%s, %s)", from.Cids(), bc) return nil, xerrors.Errorf("chain contained block marked previously as bad (%s, %s) (reason: %s)", from.Cids(), bc, reason)
} }
} }
@ -946,12 +946,12 @@ loop:
break loop break loop
} }
for _, bc := range b.Cids() { for _, bc := range b.Cids() {
if syncer.bad.Has(bc) { if reason, ok := syncer.bad.Has(bc); ok {
for _, b := range acceptedBlocks { for _, b := range acceptedBlocks {
syncer.bad.Add(b) syncer.bad.Add(b, fmt.Sprintf("chain contained %s", bc))
} }
return nil, xerrors.Errorf("chain contained block marked previously as bad (%s, %s)", from.Cids(), bc) return nil, xerrors.Errorf("chain contained block marked previously as bad (%s, %s) (reason: %s)", from.Cids(), bc, reason)
} }
} }
blockSet = append(blockSet, b) blockSet = append(blockSet, b)
@ -978,7 +978,7 @@ loop:
// TODO: we're marking this block bad in the same way that we mark invalid blocks bad. Maybe distinguish? // TODO: we're marking this block bad in the same way that we mark invalid blocks bad. Maybe distinguish?
log.Warn("adding forked chain to our bad tipset cache") log.Warn("adding forked chain to our bad tipset cache")
for _, b := range from.Blocks() { for _, b := range from.Blocks() {
syncer.bad.Add(b.Cid()) syncer.bad.Add(b.Cid(), "fork past finality")
} }
} }
return nil, xerrors.Errorf("failed to sync fork: %w", err) return nil, xerrors.Errorf("failed to sync fork: %w", err)
@ -1195,5 +1195,9 @@ func (syncer *Syncer) State() []SyncerState {
} }
func (syncer *Syncer) MarkBad(blk cid.Cid) { func (syncer *Syncer) MarkBad(blk cid.Cid) {
syncer.bad.Add(blk) syncer.bad.Add(blk, "manually marked bad")
}
func (syncer *Syncer) CheckBadBlockCache(blk cid.Cid) (string, bool) {
return syncer.bad.Has(blk)
} }

View File

@ -20,6 +20,7 @@ var syncCmd = &cli.Command{
syncStatusCmd, syncStatusCmd,
syncWaitCmd, syncWaitCmd,
syncMarkBadCmd, syncMarkBadCmd,
syncCheckBadCmd,
}, },
} }
@ -115,6 +116,41 @@ var syncMarkBadCmd = &cli.Command{
}, },
} }
var syncCheckBadCmd = &cli.Command{
Name: "check-bad",
Usage: "check if the given block was marked bad, and for what reason",
Action: func(cctx *cli.Context) error {
napi, closer, err := GetFullNodeAPI(cctx)
if err != nil {
return err
}
defer closer()
ctx := ReqContext(cctx)
if !cctx.Args().Present() {
return fmt.Errorf("must specify block cid to check")
}
bcid, err := cid.Decode(cctx.Args().First())
if err != nil {
return fmt.Errorf("failed to decode input as a cid: %s", err)
}
reason, err := napi.SyncCheckBad(ctx, bcid)
if err != nil {
return err
}
if reason == "" {
fmt.Println("block was not marked as bad")
return nil
}
fmt.Println(reason)
return nil
},
}
func SyncWait(ctx context.Context, napi api.FullNode) error { func SyncWait(ctx context.Context, napi api.FullNode) error {
for { for {
state, err := napi.SyncState(ctx) state, err := napi.SyncState(ctx)

View File

@ -88,3 +88,12 @@ func (a *SyncAPI) SyncMarkBad(ctx context.Context, bcid cid.Cid) error {
a.Syncer.MarkBad(bcid) a.Syncer.MarkBad(bcid)
return nil return nil
} }
func (a *SyncAPI) SyncCheckBad(ctx context.Context, bcid cid.Cid) (string, error) {
reason, ok := a.Syncer.CheckBadBlockCache(bcid)
if !ok {
return "", nil
}
return reason, nil
}