github.com/prysmaticlabs/prysm@v1.4.4/beacon-chain/sync/pending_attestations_queue_test.go (about)

     1  package sync
     2  
     3  import (
     4  	"context"
     5  	"testing"
     6  	"time"
     7  
     8  	"github.com/ethereum/go-ethereum/p2p/enr"
     9  	lru "github.com/hashicorp/golang-lru"
    10  	"github.com/libp2p/go-libp2p-core/network"
    11  	types "github.com/prysmaticlabs/eth2-types"
    12  	"github.com/prysmaticlabs/go-bitfield"
    13  	mock "github.com/prysmaticlabs/prysm/beacon-chain/blockchain/testing"
    14  	"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
    15  	dbtest "github.com/prysmaticlabs/prysm/beacon-chain/db/testing"
    16  	"github.com/prysmaticlabs/prysm/beacon-chain/operations/attestations"
    17  	"github.com/prysmaticlabs/prysm/beacon-chain/p2p/peers"
    18  	p2ptest "github.com/prysmaticlabs/prysm/beacon-chain/p2p/testing"
    19  	pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
    20  	ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
    21  	"github.com/prysmaticlabs/prysm/proto/eth/v1alpha1/wrapper"
    22  	"github.com/prysmaticlabs/prysm/shared/abool"
    23  	"github.com/prysmaticlabs/prysm/shared/attestationutil"
    24  	"github.com/prysmaticlabs/prysm/shared/bls"
    25  	"github.com/prysmaticlabs/prysm/shared/bytesutil"
    26  	"github.com/prysmaticlabs/prysm/shared/params"
    27  	"github.com/prysmaticlabs/prysm/shared/testutil"
    28  	"github.com/prysmaticlabs/prysm/shared/testutil/assert"
    29  	"github.com/prysmaticlabs/prysm/shared/testutil/require"
    30  	"github.com/prysmaticlabs/prysm/shared/timeutils"
    31  	logTest "github.com/sirupsen/logrus/hooks/test"
    32  )
    33  
    34  func TestProcessPendingAtts_NoBlockRequestBlock(t *testing.T) {
    35  	hook := logTest.NewGlobal()
    36  	db := dbtest.SetupDB(t)
    37  	p1 := p2ptest.NewTestP2P(t)
    38  	p2 := p2ptest.NewTestP2P(t)
    39  	p1.Connect(p2)
    40  	assert.Equal(t, 1, len(p1.BHost.Network().Peers()), "Expected peers to be connected")
    41  	p1.Peers().Add(new(enr.Record), p2.PeerID(), nil, network.DirOutbound)
    42  	p1.Peers().SetConnectionState(p2.PeerID(), peers.PeerConnected)
    43  	p1.Peers().SetChainState(p2.PeerID(), &pb.Status{})
    44  
    45  	r := &Service{
    46  		cfg:                  &Config{P2P: p1, DB: db, Chain: &mock.ChainService{Genesis: timeutils.Now(), FinalizedCheckPoint: &ethpb.Checkpoint{}}},
    47  		blkRootToPendingAtts: make(map[[32]byte][]*ethpb.SignedAggregateAttestationAndProof),
    48  		chainStarted:         abool.New(),
    49  	}
    50  
    51  	a := &ethpb.AggregateAttestationAndProof{Aggregate: &ethpb.Attestation{Data: &ethpb.AttestationData{Target: &ethpb.Checkpoint{Root: make([]byte, 32)}}}}
    52  	r.blkRootToPendingAtts[[32]byte{'A'}] = []*ethpb.SignedAggregateAttestationAndProof{{Message: a}}
    53  	require.NoError(t, r.processPendingAtts(context.Background()))
    54  	require.LogsContain(t, hook, "Requesting block for pending attestation")
    55  }
    56  
    57  func TestProcessPendingAtts_HasBlockSaveUnAggregatedAtt(t *testing.T) {
    58  	hook := logTest.NewGlobal()
    59  	db := dbtest.SetupDB(t)
    60  	p1 := p2ptest.NewTestP2P(t)
    61  	validators := uint64(256)
    62  
    63  	beaconState, privKeys := testutil.DeterministicGenesisState(t, validators)
    64  
    65  	sb := testutil.NewBeaconBlock()
    66  	require.NoError(t, db.SaveBlock(context.Background(), wrapper.WrappedPhase0SignedBeaconBlock(sb)))
    67  	root, err := sb.Block.HashTreeRoot()
    68  	require.NoError(t, err)
    69  
    70  	aggBits := bitfield.NewBitlist(8)
    71  	aggBits.SetBitAt(1, true)
    72  	att := &ethpb.Attestation{
    73  		Data: &ethpb.AttestationData{
    74  			BeaconBlockRoot: root[:],
    75  			Source:          &ethpb.Checkpoint{Epoch: 0, Root: bytesutil.PadTo([]byte("hello-world"), 32)},
    76  			Target:          &ethpb.Checkpoint{Epoch: 0, Root: root[:]},
    77  		},
    78  		AggregationBits: aggBits,
    79  	}
    80  
    81  	committee, err := helpers.BeaconCommitteeFromState(beaconState, att.Data.Slot, att.Data.CommitteeIndex)
    82  	assert.NoError(t, err)
    83  	attestingIndices, err := attestationutil.AttestingIndices(att.AggregationBits, committee)
    84  	require.NoError(t, err)
    85  	assert.NoError(t, err)
    86  	attesterDomain, err := helpers.Domain(beaconState.Fork(), 0, params.BeaconConfig().DomainBeaconAttester, beaconState.GenesisValidatorRoot())
    87  	require.NoError(t, err)
    88  	hashTreeRoot, err := helpers.ComputeSigningRoot(att.Data, attesterDomain)
    89  	assert.NoError(t, err)
    90  	for _, i := range attestingIndices {
    91  		att.Signature = privKeys[i].Sign(hashTreeRoot[:]).Marshal()
    92  	}
    93  
    94  	// Arbitrary aggregator index for testing purposes.
    95  	aggregatorIndex := committee[0]
    96  	sszUint := types.SSZUint64(att.Data.Slot)
    97  	sig, err := helpers.ComputeDomainAndSign(beaconState, 0, &sszUint, params.BeaconConfig().DomainSelectionProof, privKeys[aggregatorIndex])
    98  	require.NoError(t, err)
    99  	aggregateAndProof := &ethpb.AggregateAttestationAndProof{
   100  		SelectionProof:  sig,
   101  		Aggregate:       att,
   102  		AggregatorIndex: aggregatorIndex,
   103  	}
   104  	aggreSig, err := helpers.ComputeDomainAndSign(beaconState, 0, aggregateAndProof, params.BeaconConfig().DomainAggregateAndProof, privKeys[aggregatorIndex])
   105  	require.NoError(t, err)
   106  
   107  	require.NoError(t, beaconState.SetGenesisTime(uint64(time.Now().Unix())))
   108  
   109  	c, err := lru.New(10)
   110  	require.NoError(t, err)
   111  	r := &Service{
   112  		cfg: &Config{
   113  			P2P: p1,
   114  			DB:  db,
   115  			Chain: &mock.ChainService{Genesis: time.Now(),
   116  				State: beaconState,
   117  				FinalizedCheckPoint: &ethpb.Checkpoint{
   118  					Root:  aggregateAndProof.Aggregate.Data.BeaconBlockRoot,
   119  					Epoch: 0,
   120  				}},
   121  			AttPool: attestations.NewPool(),
   122  		},
   123  		blkRootToPendingAtts:             make(map[[32]byte][]*ethpb.SignedAggregateAttestationAndProof),
   124  		seenUnAggregatedAttestationCache: c,
   125  	}
   126  
   127  	sb = testutil.NewBeaconBlock()
   128  	r32, err := sb.Block.HashTreeRoot()
   129  	require.NoError(t, err)
   130  	require.NoError(t, r.cfg.DB.SaveBlock(context.Background(), wrapper.WrappedPhase0SignedBeaconBlock(sb)))
   131  	s, err := testutil.NewBeaconState()
   132  	require.NoError(t, err)
   133  	require.NoError(t, r.cfg.DB.SaveState(context.Background(), s, r32))
   134  
   135  	r.blkRootToPendingAtts[r32] = []*ethpb.SignedAggregateAttestationAndProof{{Message: aggregateAndProof, Signature: aggreSig}}
   136  	require.NoError(t, r.processPendingAtts(context.Background()))
   137  
   138  	atts, err := r.cfg.AttPool.UnaggregatedAttestations()
   139  	require.NoError(t, err)
   140  	assert.Equal(t, 1, len(atts), "Did not save unaggregated att")
   141  	assert.DeepEqual(t, att, atts[0], "Incorrect saved att")
   142  	assert.Equal(t, 0, len(r.cfg.AttPool.AggregatedAttestations()), "Did save aggregated att")
   143  	require.LogsContain(t, hook, "Verified and saved pending attestations to pool")
   144  }
   145  
   146  func TestProcessPendingAtts_NoBroadcastWithBadSignature(t *testing.T) {
   147  	db := dbtest.SetupDB(t)
   148  	p1 := p2ptest.NewTestP2P(t)
   149  
   150  	s, _ := testutil.DeterministicGenesisState(t, 256)
   151  	r := &Service{
   152  		cfg: &Config{
   153  			P2P:     p1,
   154  			DB:      db,
   155  			Chain:   &mock.ChainService{State: s, Genesis: timeutils.Now(), FinalizedCheckPoint: &ethpb.Checkpoint{Root: make([]byte, 32)}},
   156  			AttPool: attestations.NewPool(),
   157  		},
   158  		blkRootToPendingAtts: make(map[[32]byte][]*ethpb.SignedAggregateAttestationAndProof),
   159  	}
   160  
   161  	priv, err := bls.RandKey()
   162  	require.NoError(t, err)
   163  	a := &ethpb.AggregateAttestationAndProof{
   164  		Aggregate: &ethpb.Attestation{
   165  			Signature:       priv.Sign([]byte("foo")).Marshal(),
   166  			AggregationBits: bitfield.Bitlist{0x02},
   167  			Data:            testutil.HydrateAttestationData(&ethpb.AttestationData{}),
   168  		},
   169  		SelectionProof: make([]byte, 96),
   170  	}
   171  
   172  	b := testutil.NewBeaconBlock()
   173  	r32, err := b.Block.HashTreeRoot()
   174  	require.NoError(t, err)
   175  	require.NoError(t, r.cfg.DB.SaveBlock(context.Background(), wrapper.WrappedPhase0SignedBeaconBlock(b)))
   176  	require.NoError(t, r.cfg.DB.SaveState(context.Background(), s, r32))
   177  
   178  	r.blkRootToPendingAtts[r32] = []*ethpb.SignedAggregateAttestationAndProof{{Message: a, Signature: make([]byte, 96)}}
   179  	require.NoError(t, r.processPendingAtts(context.Background()))
   180  
   181  	assert.Equal(t, false, p1.BroadcastCalled, "Broadcasted bad aggregate")
   182  	// Clear pool.
   183  	err = r.cfg.AttPool.DeleteUnaggregatedAttestation(a.Aggregate)
   184  	require.NoError(t, err)
   185  
   186  	validators := uint64(256)
   187  
   188  	_, privKeys := testutil.DeterministicGenesisState(t, validators)
   189  	aggBits := bitfield.NewBitlist(8)
   190  	aggBits.SetBitAt(1, true)
   191  	att := &ethpb.Attestation{
   192  		Data: &ethpb.AttestationData{
   193  			BeaconBlockRoot: r32[:],
   194  			Source:          &ethpb.Checkpoint{Epoch: 0, Root: bytesutil.PadTo([]byte("hello-world"), 32)},
   195  			Target:          &ethpb.Checkpoint{Epoch: 0, Root: r32[:]},
   196  		},
   197  		AggregationBits: aggBits,
   198  	}
   199  	committee, err := helpers.BeaconCommitteeFromState(s, att.Data.Slot, att.Data.CommitteeIndex)
   200  	assert.NoError(t, err)
   201  	attestingIndices, err := attestationutil.AttestingIndices(att.AggregationBits, committee)
   202  	require.NoError(t, err)
   203  	assert.NoError(t, err)
   204  	attesterDomain, err := helpers.Domain(s.Fork(), 0, params.BeaconConfig().DomainBeaconAttester, s.GenesisValidatorRoot())
   205  	require.NoError(t, err)
   206  	hashTreeRoot, err := helpers.ComputeSigningRoot(att.Data, attesterDomain)
   207  	assert.NoError(t, err)
   208  	for _, i := range attestingIndices {
   209  		att.Signature = privKeys[i].Sign(hashTreeRoot[:]).Marshal()
   210  	}
   211  
   212  	// Arbitrary aggregator index for testing purposes.
   213  	aggregatorIndex := committee[0]
   214  	sszSlot := types.SSZUint64(att.Data.Slot)
   215  	sig, err := helpers.ComputeDomainAndSign(s, 0, &sszSlot, params.BeaconConfig().DomainSelectionProof, privKeys[aggregatorIndex])
   216  	require.NoError(t, err)
   217  	aggregateAndProof := &ethpb.AggregateAttestationAndProof{
   218  		SelectionProof:  sig,
   219  		Aggregate:       att,
   220  		AggregatorIndex: aggregatorIndex,
   221  	}
   222  	aggreSig, err := helpers.ComputeDomainAndSign(s, 0, aggregateAndProof, params.BeaconConfig().DomainAggregateAndProof, privKeys[aggregatorIndex])
   223  	require.NoError(t, err)
   224  
   225  	require.NoError(t, s.SetGenesisTime(uint64(time.Now().Unix())))
   226  	c, err := lru.New(10)
   227  	require.NoError(t, err)
   228  	r = &Service{
   229  		cfg: &Config{
   230  			P2P: p1,
   231  			DB:  db,
   232  			Chain: &mock.ChainService{Genesis: time.Now(),
   233  				State: s,
   234  				FinalizedCheckPoint: &ethpb.Checkpoint{
   235  					Root:  aggregateAndProof.Aggregate.Data.BeaconBlockRoot,
   236  					Epoch: 0,
   237  				}},
   238  			AttPool: attestations.NewPool(),
   239  		},
   240  		blkRootToPendingAtts:             make(map[[32]byte][]*ethpb.SignedAggregateAttestationAndProof),
   241  		seenUnAggregatedAttestationCache: c,
   242  	}
   243  
   244  	r.blkRootToPendingAtts[r32] = []*ethpb.SignedAggregateAttestationAndProof{{Message: aggregateAndProof, Signature: aggreSig}}
   245  	require.NoError(t, r.processPendingAtts(context.Background()))
   246  
   247  	assert.Equal(t, true, p1.BroadcastCalled, "Could not broadcast the good aggregate")
   248  }
   249  
   250  func TestProcessPendingAtts_HasBlockSaveAggregatedAtt(t *testing.T) {
   251  	hook := logTest.NewGlobal()
   252  	db := dbtest.SetupDB(t)
   253  	p1 := p2ptest.NewTestP2P(t)
   254  	validators := uint64(256)
   255  
   256  	beaconState, privKeys := testutil.DeterministicGenesisState(t, validators)
   257  
   258  	sb := testutil.NewBeaconBlock()
   259  	require.NoError(t, db.SaveBlock(context.Background(), wrapper.WrappedPhase0SignedBeaconBlock(sb)))
   260  	root, err := sb.Block.HashTreeRoot()
   261  	require.NoError(t, err)
   262  
   263  	aggBits := bitfield.NewBitlist(validators / uint64(params.BeaconConfig().SlotsPerEpoch))
   264  	aggBits.SetBitAt(0, true)
   265  	aggBits.SetBitAt(1, true)
   266  	att := &ethpb.Attestation{
   267  		Data: &ethpb.AttestationData{
   268  			BeaconBlockRoot: root[:],
   269  			Source:          &ethpb.Checkpoint{Epoch: 0, Root: bytesutil.PadTo([]byte("hello-world"), 32)},
   270  			Target:          &ethpb.Checkpoint{Epoch: 0, Root: root[:]},
   271  		},
   272  		AggregationBits: aggBits,
   273  	}
   274  
   275  	committee, err := helpers.BeaconCommitteeFromState(beaconState, att.Data.Slot, att.Data.CommitteeIndex)
   276  	assert.NoError(t, err)
   277  	attestingIndices, err := attestationutil.AttestingIndices(att.AggregationBits, committee)
   278  	require.NoError(t, err)
   279  	assert.NoError(t, err)
   280  	attesterDomain, err := helpers.Domain(beaconState.Fork(), 0, params.BeaconConfig().DomainBeaconAttester, beaconState.GenesisValidatorRoot())
   281  	require.NoError(t, err)
   282  	hashTreeRoot, err := helpers.ComputeSigningRoot(att.Data, attesterDomain)
   283  	assert.NoError(t, err)
   284  	sigs := make([]bls.Signature, len(attestingIndices))
   285  	for i, indice := range attestingIndices {
   286  		sig := privKeys[indice].Sign(hashTreeRoot[:])
   287  		sigs[i] = sig
   288  	}
   289  	att.Signature = bls.AggregateSignatures(sigs).Marshal()
   290  
   291  	// Arbitrary aggregator index for testing purposes.
   292  	aggregatorIndex := committee[0]
   293  	sszUint := types.SSZUint64(att.Data.Slot)
   294  	sig, err := helpers.ComputeDomainAndSign(beaconState, 0, &sszUint, params.BeaconConfig().DomainSelectionProof, privKeys[aggregatorIndex])
   295  	require.NoError(t, err)
   296  	aggregateAndProof := &ethpb.AggregateAttestationAndProof{
   297  		SelectionProof:  sig,
   298  		Aggregate:       att,
   299  		AggregatorIndex: aggregatorIndex,
   300  	}
   301  	aggreSig, err := helpers.ComputeDomainAndSign(beaconState, 0, aggregateAndProof, params.BeaconConfig().DomainAggregateAndProof, privKeys[aggregatorIndex])
   302  	require.NoError(t, err)
   303  
   304  	require.NoError(t, beaconState.SetGenesisTime(uint64(time.Now().Unix())))
   305  
   306  	c, err := lru.New(10)
   307  	require.NoError(t, err)
   308  	r := &Service{
   309  		cfg: &Config{
   310  			P2P: p1,
   311  			DB:  db,
   312  			Chain: &mock.ChainService{Genesis: time.Now(),
   313  				State: beaconState,
   314  				FinalizedCheckPoint: &ethpb.Checkpoint{
   315  					Root:  aggregateAndProof.Aggregate.Data.BeaconBlockRoot,
   316  					Epoch: 0,
   317  				}},
   318  			AttPool: attestations.NewPool(),
   319  		},
   320  		blkRootToPendingAtts:           make(map[[32]byte][]*ethpb.SignedAggregateAttestationAndProof),
   321  		seenAggregatedAttestationCache: c,
   322  	}
   323  
   324  	sb = testutil.NewBeaconBlock()
   325  	r32, err := sb.Block.HashTreeRoot()
   326  	require.NoError(t, err)
   327  	require.NoError(t, r.cfg.DB.SaveBlock(context.Background(), wrapper.WrappedPhase0SignedBeaconBlock(sb)))
   328  	s, err := testutil.NewBeaconState()
   329  	require.NoError(t, err)
   330  	require.NoError(t, r.cfg.DB.SaveState(context.Background(), s, r32))
   331  
   332  	r.blkRootToPendingAtts[r32] = []*ethpb.SignedAggregateAttestationAndProof{{Message: aggregateAndProof, Signature: aggreSig}}
   333  	require.NoError(t, r.processPendingAtts(context.Background()))
   334  
   335  	assert.Equal(t, 1, len(r.cfg.AttPool.AggregatedAttestations()), "Did not save aggregated att")
   336  	assert.DeepEqual(t, att, r.cfg.AttPool.AggregatedAttestations()[0], "Incorrect saved att")
   337  	atts, err := r.cfg.AttPool.UnaggregatedAttestations()
   338  	require.NoError(t, err)
   339  	assert.Equal(t, 0, len(atts), "Did save aggregated att")
   340  	require.LogsContain(t, hook, "Verified and saved pending attestations to pool")
   341  }
   342  
   343  func TestValidatePendingAtts_CanPruneOldAtts(t *testing.T) {
   344  	s := &Service{
   345  		blkRootToPendingAtts: make(map[[32]byte][]*ethpb.SignedAggregateAttestationAndProof),
   346  	}
   347  
   348  	// 100 Attestations per block root.
   349  	r1 := [32]byte{'A'}
   350  	r2 := [32]byte{'B'}
   351  	r3 := [32]byte{'C'}
   352  
   353  	for i := types.Slot(0); i < 100; i++ {
   354  		s.savePendingAtt(&ethpb.SignedAggregateAttestationAndProof{
   355  			Message: &ethpb.AggregateAttestationAndProof{
   356  				AggregatorIndex: types.ValidatorIndex(i),
   357  				Aggregate: &ethpb.Attestation{
   358  					Data: &ethpb.AttestationData{Slot: i, BeaconBlockRoot: r1[:]}}}})
   359  		s.savePendingAtt(&ethpb.SignedAggregateAttestationAndProof{
   360  			Message: &ethpb.AggregateAttestationAndProof{
   361  				AggregatorIndex: types.ValidatorIndex(i*2 + i),
   362  				Aggregate: &ethpb.Attestation{
   363  					Data: &ethpb.AttestationData{Slot: i, BeaconBlockRoot: r2[:]}}}})
   364  		s.savePendingAtt(&ethpb.SignedAggregateAttestationAndProof{
   365  			Message: &ethpb.AggregateAttestationAndProof{
   366  				AggregatorIndex: types.ValidatorIndex(i*3 + i),
   367  				Aggregate: &ethpb.Attestation{
   368  					Data: &ethpb.AttestationData{Slot: i, BeaconBlockRoot: r3[:]}}}})
   369  	}
   370  
   371  	assert.Equal(t, 100, len(s.blkRootToPendingAtts[r1]), "Did not save pending atts")
   372  	assert.Equal(t, 100, len(s.blkRootToPendingAtts[r2]), "Did not save pending atts")
   373  	assert.Equal(t, 100, len(s.blkRootToPendingAtts[r3]), "Did not save pending atts")
   374  
   375  	// Set current slot to 50, it should prune 19 attestations. (50 - 31)
   376  	s.validatePendingAtts(context.Background(), 50)
   377  	assert.Equal(t, 81, len(s.blkRootToPendingAtts[r1]), "Did not delete pending atts")
   378  	assert.Equal(t, 81, len(s.blkRootToPendingAtts[r2]), "Did not delete pending atts")
   379  	assert.Equal(t, 81, len(s.blkRootToPendingAtts[r3]), "Did not delete pending atts")
   380  
   381  	// Set current slot to 100 + slot_duration, it should prune all the attestations.
   382  	s.validatePendingAtts(context.Background(), 100+params.BeaconConfig().SlotsPerEpoch)
   383  	assert.Equal(t, 0, len(s.blkRootToPendingAtts[r1]), "Did not delete pending atts")
   384  	assert.Equal(t, 0, len(s.blkRootToPendingAtts[r2]), "Did not delete pending atts")
   385  	assert.Equal(t, 0, len(s.blkRootToPendingAtts[r3]), "Did not delete pending atts")
   386  
   387  	// Verify the keys are deleted.
   388  	assert.Equal(t, 0, len(s.blkRootToPendingAtts), "Did not delete block keys")
   389  }
   390  
   391  func TestValidatePendingAtts_NoDuplicatingAggregatorIndex(t *testing.T) {
   392  	s := &Service{
   393  		blkRootToPendingAtts: make(map[[32]byte][]*ethpb.SignedAggregateAttestationAndProof),
   394  	}
   395  
   396  	r1 := [32]byte{'A'}
   397  	r2 := [32]byte{'B'}
   398  	s.savePendingAtt(&ethpb.SignedAggregateAttestationAndProof{
   399  		Message: &ethpb.AggregateAttestationAndProof{
   400  			AggregatorIndex: 1,
   401  			Aggregate: &ethpb.Attestation{
   402  				Data: &ethpb.AttestationData{Slot: 1, BeaconBlockRoot: r1[:]}}}})
   403  	s.savePendingAtt(&ethpb.SignedAggregateAttestationAndProof{
   404  		Message: &ethpb.AggregateAttestationAndProof{
   405  			AggregatorIndex: 2,
   406  			Aggregate: &ethpb.Attestation{
   407  				Data: &ethpb.AttestationData{Slot: 2, BeaconBlockRoot: r2[:]}}}})
   408  	s.savePendingAtt(&ethpb.SignedAggregateAttestationAndProof{
   409  		Message: &ethpb.AggregateAttestationAndProof{
   410  			AggregatorIndex: 2,
   411  			Aggregate: &ethpb.Attestation{
   412  				Data: &ethpb.AttestationData{Slot: 3, BeaconBlockRoot: r2[:]}}}})
   413  
   414  	assert.Equal(t, 1, len(s.blkRootToPendingAtts[r1]), "Did not save pending atts")
   415  	assert.Equal(t, 1, len(s.blkRootToPendingAtts[r2]), "Did not save pending atts")
   416  }