diff --git a/chain/store/store.go b/chain/store/store.go index a7075f4cc72..e930d6652a5 100644 --- a/chain/store/store.go +++ b/chain/store/store.go @@ -446,13 +446,15 @@ func (cs *ChainStore) RefreshHeaviestTipSet(ctx context.Context, newTsHeight abi } } - if newHeaviest == nil { - return xerrors.Errorf("failed to refresh to a new valid tipset") - } - - errTake := cs.takeHeaviestTipSet(ctx, newHeaviest) - if errTake != nil { - return xerrors.Errorf("failed to take newHeaviest tipset as head: %w", err) + // if we've found something, we know it's the heaviest equivocation-free head, take it IMMEDIATELY + if newHeaviest != nil { + errTake := cs.takeHeaviestTipSet(ctx, newHeaviest) + if errTake != nil { + return xerrors.Errorf("failed to take newHeaviest tipset as head: %w", err) + } + } else { + // if we haven't found something, just stay with our equivocation-y head + newHeaviest = cs.heaviest } } diff --git a/chain/store/store_test.go b/chain/store/store_test.go index 14ba8cf0f97..9c717fdbef4 100644 --- a/chain/store/store_test.go +++ b/chain/store/store_test.go @@ -396,8 +396,9 @@ func TestEquivocations(t *testing.T) { require.Nil(t, tryTs2) require.True(t, tryTsWeight2.IsZero()) - // now we "notify" at this height -- it should fail, because we cannot refresh our head due to equivocation and nulls - require.ErrorContains(t, cg.ChainStore().RefreshHeaviestTipSet(ctx, blkAfterNulls.Height), "failed to refresh to a new valid tipset") + // now we "notify" at this height -- it should lead to no head change because there's no formable head in near epochs + require.NoError(t, cg.ChainStore().RefreshHeaviestTipSet(ctx, blkAfterNulls.Height)) + require.True(t, headAfterNulls.TipSet.TipSet().Equals(cg.ChainStore().GetHeaviestTipSet())) } func addBlockToTracker(t *testing.T, cs *store.ChainStore, blk *types.BlockHeader) {