github.com/prysmaticlabs/prysm@v1.4.4/beacon-chain/operations/attestations/prune_expired_test.go (about)

     1  package attestations
     2  
     3  import (
     4  	"context"
     5  	"testing"
     6  	"time"
     7  
     8  	"github.com/prysmaticlabs/go-bitfield"
     9  	ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
    10  	"github.com/prysmaticlabs/prysm/shared/params"
    11  	"github.com/prysmaticlabs/prysm/shared/runutil"
    12  	"github.com/prysmaticlabs/prysm/shared/testutil"
    13  	"github.com/prysmaticlabs/prysm/shared/testutil/assert"
    14  	"github.com/prysmaticlabs/prysm/shared/testutil/require"
    15  	"github.com/prysmaticlabs/prysm/shared/timeutils"
    16  )
    17  
    18  func TestPruneExpired_Ticker(t *testing.T) {
    19  	ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
    20  	defer cancel()
    21  
    22  	s, err := NewService(ctx, &Config{
    23  		Pool:          NewPool(),
    24  		pruneInterval: 250 * time.Millisecond,
    25  	})
    26  	require.NoError(t, err)
    27  
    28  	ad1 := testutil.HydrateAttestationData(&ethpb.AttestationData{})
    29  
    30  	ad2 := testutil.HydrateAttestationData(&ethpb.AttestationData{Slot: 1})
    31  
    32  	atts := []*ethpb.Attestation{
    33  		{Data: ad1, AggregationBits: bitfield.Bitlist{0b1000, 0b1}, Signature: make([]byte, 96)},
    34  		{Data: ad2, AggregationBits: bitfield.Bitlist{0b1000, 0b1}, Signature: make([]byte, 96)},
    35  	}
    36  	require.NoError(t, s.cfg.Pool.SaveUnaggregatedAttestations(atts))
    37  	require.Equal(t, 2, s.cfg.Pool.UnaggregatedAttestationCount(), "Unexpected number of attestations")
    38  	atts = []*ethpb.Attestation{
    39  		{Data: ad1, AggregationBits: bitfield.Bitlist{0b1101, 0b1}, Signature: make([]byte, 96)},
    40  		{Data: ad2, AggregationBits: bitfield.Bitlist{0b1101, 0b1}, Signature: make([]byte, 96)},
    41  	}
    42  	require.NoError(t, s.cfg.Pool.SaveAggregatedAttestations(atts))
    43  	assert.Equal(t, 2, s.cfg.Pool.AggregatedAttestationCount())
    44  	require.NoError(t, s.cfg.Pool.SaveBlockAttestations(atts))
    45  
    46  	// Rewind back one epoch worth of time.
    47  	s.genesisTime = uint64(timeutils.Now().Unix()) - uint64(params.BeaconConfig().SlotsPerEpoch.Mul(params.BeaconConfig().SecondsPerSlot))
    48  
    49  	go s.pruneAttsPool()
    50  
    51  	done := make(chan struct{}, 1)
    52  	runutil.RunEvery(ctx, 500*time.Millisecond, func() {
    53  		atts, err := s.cfg.Pool.UnaggregatedAttestations()
    54  		require.NoError(t, err)
    55  		for _, attestation := range atts {
    56  			if attestation.Data.Slot == 0 {
    57  				return
    58  			}
    59  		}
    60  		for _, attestation := range s.cfg.Pool.AggregatedAttestations() {
    61  			if attestation.Data.Slot == 0 {
    62  				return
    63  			}
    64  		}
    65  		for _, attestation := range s.cfg.Pool.BlockAttestations() {
    66  			if attestation.Data.Slot == 0 {
    67  				return
    68  			}
    69  		}
    70  		if s.cfg.Pool.UnaggregatedAttestationCount() != 1 || s.cfg.Pool.AggregatedAttestationCount() != 1 {
    71  			return
    72  		}
    73  		done <- struct{}{}
    74  	})
    75  	select {
    76  	case <-done:
    77  		// All checks are passed.
    78  	case <-ctx.Done():
    79  		t.Error("Test case takes too long to complete")
    80  	}
    81  }
    82  
    83  func TestPruneExpired_PruneExpiredAtts(t *testing.T) {
    84  	s, err := NewService(context.Background(), &Config{Pool: NewPool()})
    85  	require.NoError(t, err)
    86  
    87  	ad1 := testutil.HydrateAttestationData(&ethpb.AttestationData{})
    88  
    89  	ad2 := testutil.HydrateAttestationData(&ethpb.AttestationData{})
    90  
    91  	att1 := &ethpb.Attestation{Data: ad1, AggregationBits: bitfield.Bitlist{0b1101}}
    92  	att2 := &ethpb.Attestation{Data: ad1, AggregationBits: bitfield.Bitlist{0b1111}}
    93  	att3 := &ethpb.Attestation{Data: ad2, AggregationBits: bitfield.Bitlist{0b1101}}
    94  	att4 := &ethpb.Attestation{Data: ad2, AggregationBits: bitfield.Bitlist{0b1110}}
    95  	atts := []*ethpb.Attestation{att1, att2, att3, att4}
    96  	require.NoError(t, s.cfg.Pool.SaveAggregatedAttestations(atts))
    97  	require.NoError(t, s.cfg.Pool.SaveBlockAttestations(atts))
    98  
    99  	// Rewind back one epoch worth of time.
   100  	s.genesisTime = uint64(timeutils.Now().Unix()) - uint64(params.BeaconConfig().SlotsPerEpoch.Mul(params.BeaconConfig().SecondsPerSlot))
   101  
   102  	s.pruneExpiredAtts()
   103  	// All the attestations on slot 0 should be pruned.
   104  	for _, attestation := range s.cfg.Pool.AggregatedAttestations() {
   105  		if attestation.Data.Slot == 0 {
   106  			t.Error("Should be pruned")
   107  		}
   108  	}
   109  	for _, attestation := range s.cfg.Pool.BlockAttestations() {
   110  		if attestation.Data.Slot == 0 {
   111  			t.Error("Should be pruned")
   112  		}
   113  	}
   114  }
   115  
   116  func TestPruneExpired_Expired(t *testing.T) {
   117  	s, err := NewService(context.Background(), &Config{Pool: NewPool()})
   118  	require.NoError(t, err)
   119  
   120  	// Rewind back one epoch worth of time.
   121  	s.genesisTime = uint64(timeutils.Now().Unix()) - uint64(params.BeaconConfig().SlotsPerEpoch.Mul(params.BeaconConfig().SecondsPerSlot))
   122  	assert.Equal(t, true, s.expired(0), "Should be expired")
   123  	assert.Equal(t, false, s.expired(1), "Should not be expired")
   124  }