diff --git a/chain/sub/bcast/consistent.go b/chain/sub/bcast/consistent.go index af31389ee..3ee1997e8 100644 --- a/chain/sub/bcast/consistent.go +++ b/chain/sub/bcast/consistent.go @@ -85,6 +85,10 @@ func (bInfo *blksInfo) eqErr() error { return fmt.Errorf("equivocation error detected. Different block with the same ticket already seen") } +func (cb *ConsistentBCast) Len() int { + return len(cb.m) +} + func (cb *ConsistentBCast) RcvBlock(ctx context.Context, blk *types.BlockMsg) error { cb.lk.Lock() bcastDict, ok := cb.m[blk.Header.Height] @@ -146,6 +150,8 @@ func (cb *ConsistentBCast) GarbageCollect(currEpoch abi.ChainEpoch) { // without delivery, and the garbage collection wasn't triggered // for a few epochs. for i := 0; i < GC_SANITY_CHECK; i++ { - delete(cb.m, currEpoch-abi.ChainEpoch(2-i)) + if currEpoch > GC_LOOKBACK { + delete(cb.m, currEpoch-abi.ChainEpoch(GC_LOOKBACK+i)) + } } } diff --git a/chain/sub/bcast/consistent_test.go b/chain/sub/bcast/consistent_test.go index a2945b46b..1b1f4f34a 100644 --- a/chain/sub/bcast/consistent_test.go +++ b/chain/sub/bcast/consistent_test.go @@ -38,6 +38,7 @@ func testSimpleDelivery(t *testing.T, cb *bcast.ConsistentBCast, epoch abi.Chain wg.Add(numBlocks) for i := 0; i < numBlocks; i++ { go func(i int) { + defer wg.Done() // Add a random delay in block reception r := mrand.Intn(200) time.Sleep(time.Duration(r) * time.Millisecond) @@ -47,7 +48,6 @@ func testSimpleDelivery(t *testing.T, cb *bcast.ConsistentBCast, epoch abi.Chain if err != nil { errs = append(errs, err) } - wg.Done() }(i) } wg.Wait() @@ -64,6 +64,7 @@ func TestSeveralEpochs(t *testing.T) { wg.Add(numEpochs) for i := 0; i < numEpochs; i++ { go func(i int) { + defer wg.Done() // Add a random delay between epochs r := mrand.Intn(500) time.Sleep(time.Duration(i*TEST_DELAY)*time.Second + time.Duration(r)*time.Millisecond) @@ -76,10 +77,11 @@ func TestSeveralEpochs(t *testing.T) { } else { testEquivocation(t, cb, abi.ChainEpoch(i), rNumBlocks) } - wg.Done() + cb.GarbageCollect(abi.ChainEpoch(i)) }(i) } wg.Wait() + require.Equal(t, cb.Len(), bcast.GC_LOOKBACK) } // bias is expected to be 0-1 @@ -101,28 +103,28 @@ func testEquivocation(t *testing.T, cb *bcast.ConsistentBCast, epoch abi.ChainEp proof := randomProof(t) // Valid blocks go func(i int, proof []byte) { + defer wg.Done() r := mrand.Intn(200) time.Sleep(time.Duration(r) * time.Millisecond) - blk := newBlock(t, 100, proof, []byte("valid"+strconv.Itoa(i))) + blk := newBlock(t, epoch, proof, []byte("valid"+strconv.Itoa(i))) cb.RcvBlock(ctx, blk) err := cb.WaitForDelivery(blk.Header) if err != nil { errs = append(errs, err) } - wg.Done() }(i, proof) // Equivocation for the last block if i == numBlocks-1 { // Attempting equivocation go func(i int, proof []byte) { + defer wg.Done() // Use the same proof and the same epoch - blk := newBlock(t, 100, proof, []byte("invalid"+strconv.Itoa(i))) + blk := newBlock(t, epoch, proof, []byte("invalid"+strconv.Itoa(i))) cb.RcvBlock(ctx, blk) err := cb.WaitForDelivery(blk.Header) // Equivocation detected require.Error(t, err) - wg.Done() }(i, proof) } } @@ -150,6 +152,7 @@ func TestFailedEquivocation(t *testing.T) { proof := randomProof(t) // Valid blocks go func(i int, proof []byte) { + defer wg.Done() r := mrand.Intn(200) time.Sleep(time.Duration(r) * time.Millisecond) blk := newBlock(t, 100, proof, []byte("valid"+strconv.Itoa(i))) @@ -158,13 +161,13 @@ func TestFailedEquivocation(t *testing.T) { if err != nil { errs = append(errs, err) } - wg.Done() }(i, proof) // Equivocation for the last block if i == numBlocks-1 { // Attempting equivocation go func(i int, proof []byte) { + defer wg.Done() // The equivocated block arrives late time.Sleep(2 * TEST_DELAY * time.Second) // Use the same proof and the same epoch @@ -173,7 +176,6 @@ func TestFailedEquivocation(t *testing.T) { err := cb.WaitForDelivery(blk.Header) // Equivocation detected require.Error(t, err) - wg.Done() }(i, proof) } }