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

     1  package sync
     2  
     3  import (
     4  	"bytes"
     5  	"context"
     6  	"reflect"
     7  	"testing"
     8  	"time"
     9  
    10  	lru "github.com/hashicorp/golang-lru"
    11  	pubsub "github.com/libp2p/go-libp2p-pubsub"
    12  	pubsubpb "github.com/libp2p/go-libp2p-pubsub/pb"
    13  	types "github.com/prysmaticlabs/eth2-types"
    14  	"github.com/prysmaticlabs/go-bitfield"
    15  	mock "github.com/prysmaticlabs/prysm/beacon-chain/blockchain/testing"
    16  	"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
    17  	dbtest "github.com/prysmaticlabs/prysm/beacon-chain/db/testing"
    18  	"github.com/prysmaticlabs/prysm/beacon-chain/operations/attestations"
    19  	"github.com/prysmaticlabs/prysm/beacon-chain/p2p"
    20  	p2ptest "github.com/prysmaticlabs/prysm/beacon-chain/p2p/testing"
    21  	mockSync "github.com/prysmaticlabs/prysm/beacon-chain/sync/initial-sync/testing"
    22  	ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
    23  	"github.com/prysmaticlabs/prysm/proto/eth/v1alpha1/wrapper"
    24  	"github.com/prysmaticlabs/prysm/shared/attestationutil"
    25  	"github.com/prysmaticlabs/prysm/shared/bls"
    26  	"github.com/prysmaticlabs/prysm/shared/bytesutil"
    27  	"github.com/prysmaticlabs/prysm/shared/params"
    28  	"github.com/prysmaticlabs/prysm/shared/testutil"
    29  	"github.com/prysmaticlabs/prysm/shared/testutil/assert"
    30  	"github.com/prysmaticlabs/prysm/shared/testutil/require"
    31  )
    32  
    33  func TestVerifyIndexInCommittee_CanVerify(t *testing.T) {
    34  	ctx := context.Background()
    35  	params.UseMinimalConfig()
    36  	defer params.UseMainnetConfig()
    37  
    38  	validators := uint64(32)
    39  	s, _ := testutil.DeterministicGenesisState(t, validators)
    40  	require.NoError(t, s.SetSlot(params.BeaconConfig().SlotsPerEpoch))
    41  
    42  	bf := bitfield.NewBitlist(validators / uint64(params.BeaconConfig().SlotsPerEpoch))
    43  	bf.SetBitAt(0, true)
    44  	att := &ethpb.Attestation{Data: &ethpb.AttestationData{
    45  		Target: &ethpb.Checkpoint{Epoch: 0}},
    46  		AggregationBits: bf}
    47  
    48  	committee, err := helpers.BeaconCommitteeFromState(s, att.Data.Slot, att.Data.CommitteeIndex)
    49  	assert.NoError(t, err)
    50  	indices, err := attestationutil.AttestingIndices(att.AggregationBits, committee)
    51  	require.NoError(t, err)
    52  	require.NoError(t, validateIndexInCommittee(ctx, s, att, types.ValidatorIndex(indices[0])))
    53  
    54  	wanted := "validator index 1000 is not within the committee"
    55  	assert.ErrorContains(t, wanted, validateIndexInCommittee(ctx, s, att, 1000))
    56  }
    57  
    58  func TestVerifyIndexInCommittee_ExistsInBeaconCommittee(t *testing.T) {
    59  	ctx := context.Background()
    60  	params.UseMinimalConfig()
    61  	defer params.UseMainnetConfig()
    62  
    63  	validators := uint64(64)
    64  	s, _ := testutil.DeterministicGenesisState(t, validators)
    65  	require.NoError(t, s.SetSlot(params.BeaconConfig().SlotsPerEpoch))
    66  
    67  	bf := []byte{0xff}
    68  	att := &ethpb.Attestation{Data: &ethpb.AttestationData{
    69  		Target: &ethpb.Checkpoint{Epoch: 0}},
    70  		AggregationBits: bf}
    71  
    72  	committee, err := helpers.BeaconCommitteeFromState(s, att.Data.Slot, att.Data.CommitteeIndex)
    73  	require.NoError(t, err)
    74  
    75  	require.NoError(t, validateIndexInCommittee(ctx, s, att, committee[0]))
    76  
    77  	wanted := "validator index 1000 is not within the committee"
    78  	assert.ErrorContains(t, wanted, validateIndexInCommittee(ctx, s, att, 1000))
    79  }
    80  
    81  func TestVerifySelection_NotAnAggregator(t *testing.T) {
    82  	ctx := context.Background()
    83  	params.UseMinimalConfig()
    84  	defer params.UseMainnetConfig()
    85  	validators := uint64(2048)
    86  	beaconState, privKeys := testutil.DeterministicGenesisState(t, validators)
    87  
    88  	sig := privKeys[0].Sign([]byte{'A'})
    89  	data := testutil.HydrateAttestationData(&ethpb.AttestationData{})
    90  
    91  	_, err := validateSelectionIndex(ctx, beaconState, data, 0, sig.Marshal())
    92  	wanted := "validator is not an aggregator for slot"
    93  	assert.ErrorContains(t, wanted, err)
    94  }
    95  
    96  func TestValidateAggregateAndProof_NoBlock(t *testing.T) {
    97  	db := dbtest.SetupDB(t)
    98  	p := p2ptest.NewTestP2P(t)
    99  
   100  	att := testutil.HydrateAttestation(&ethpb.Attestation{
   101  		Data: &ethpb.AttestationData{
   102  			Source: &ethpb.Checkpoint{Root: bytesutil.PadTo([]byte("hello-world"), 32)},
   103  			Target: &ethpb.Checkpoint{Root: bytesutil.PadTo([]byte("hello-world"), 32)},
   104  		},
   105  	})
   106  
   107  	aggregateAndProof := &ethpb.AggregateAttestationAndProof{
   108  		SelectionProof:  bytesutil.PadTo([]byte{'A'}, 96),
   109  		Aggregate:       att,
   110  		AggregatorIndex: 0,
   111  	}
   112  	signedAggregateAndProof := &ethpb.SignedAggregateAttestationAndProof{Message: aggregateAndProof, Signature: make([]byte, 96)}
   113  
   114  	c, err := lru.New(10)
   115  	require.NoError(t, err)
   116  	r := &Service{
   117  		cfg: &Config{
   118  			P2P:         p,
   119  			DB:          db,
   120  			InitialSync: &mockSync.Sync{IsSyncing: false},
   121  			AttPool:     attestations.NewPool(),
   122  			Chain:       &mock.ChainService{},
   123  		},
   124  		blkRootToPendingAtts:           make(map[[32]byte][]*ethpb.SignedAggregateAttestationAndProof),
   125  		seenAggregatedAttestationCache: c,
   126  	}
   127  	err = r.initCaches()
   128  	require.NoError(t, err)
   129  
   130  	buf := new(bytes.Buffer)
   131  	_, err = p.Encoding().EncodeGossip(buf, signedAggregateAndProof)
   132  	require.NoError(t, err)
   133  
   134  	topic := p2p.GossipTypeMapping[reflect.TypeOf(signedAggregateAndProof)]
   135  	msg := &pubsub.Message{
   136  		Message: &pubsubpb.Message{
   137  			Data:  buf.Bytes(),
   138  			Topic: &topic,
   139  		},
   140  	}
   141  
   142  	if r.validateAggregateAndProof(context.Background(), "", msg) == pubsub.ValidationAccept {
   143  		t.Error("Expected validate to fail")
   144  	}
   145  }
   146  
   147  func TestValidateAggregateAndProof_NotWithinSlotRange(t *testing.T) {
   148  	db := dbtest.SetupDB(t)
   149  	p := p2ptest.NewTestP2P(t)
   150  
   151  	validators := uint64(256)
   152  	beaconState, _ := testutil.DeterministicGenesisState(t, validators)
   153  
   154  	b := testutil.NewBeaconBlock()
   155  	require.NoError(t, db.SaveBlock(context.Background(), wrapper.WrappedPhase0SignedBeaconBlock(b)))
   156  	root, err := b.Block.HashTreeRoot()
   157  	require.NoError(t, err)
   158  	s, err := testutil.NewBeaconState()
   159  	require.NoError(t, err)
   160  	require.NoError(t, db.SaveState(context.Background(), s, root))
   161  
   162  	aggBits := bitfield.NewBitlist(3)
   163  	aggBits.SetBitAt(0, true)
   164  	att := &ethpb.Attestation{
   165  		Data: &ethpb.AttestationData{
   166  			Slot:            1,
   167  			BeaconBlockRoot: root[:],
   168  			Source:          &ethpb.Checkpoint{Epoch: 0, Root: bytesutil.PadTo([]byte("hello-world"), 32)},
   169  			Target:          &ethpb.Checkpoint{Epoch: 0, Root: bytesutil.PadTo([]byte("hello-world"), 32)},
   170  		},
   171  		AggregationBits: aggBits,
   172  		Signature:       make([]byte, 96),
   173  	}
   174  
   175  	aggregateAndProof := &ethpb.AggregateAttestationAndProof{
   176  		Aggregate:      att,
   177  		SelectionProof: make([]byte, 96),
   178  	}
   179  	signedAggregateAndProof := &ethpb.SignedAggregateAttestationAndProof{Message: aggregateAndProof, Signature: make([]byte, 96)}
   180  
   181  	require.NoError(t, beaconState.SetGenesisTime(uint64(time.Now().Unix())))
   182  
   183  	c, err := lru.New(10)
   184  	require.NoError(t, err)
   185  	r := &Service{
   186  		cfg: &Config{
   187  			P2P:         p,
   188  			DB:          db,
   189  			InitialSync: &mockSync.Sync{IsSyncing: false},
   190  			Chain: &mock.ChainService{
   191  				Genesis: time.Now(),
   192  				State:   beaconState,
   193  			},
   194  			AttPool:             attestations.NewPool(),
   195  			AttestationNotifier: (&mock.ChainService{}).OperationNotifier(),
   196  		},
   197  		seenAggregatedAttestationCache: c,
   198  	}
   199  	err = r.initCaches()
   200  	require.NoError(t, err)
   201  
   202  	buf := new(bytes.Buffer)
   203  	_, err = p.Encoding().EncodeGossip(buf, signedAggregateAndProof)
   204  	require.NoError(t, err)
   205  
   206  	topic := p2p.GossipTypeMapping[reflect.TypeOf(signedAggregateAndProof)]
   207  	msg := &pubsub.Message{
   208  		Message: &pubsubpb.Message{
   209  			Data:  buf.Bytes(),
   210  			Topic: &topic,
   211  		},
   212  	}
   213  
   214  	if r.validateAggregateAndProof(context.Background(), "", msg) == pubsub.ValidationAccept {
   215  		t.Error("Expected validate to fail")
   216  	}
   217  
   218  	att.Data.Slot = 1<<32 - 1
   219  
   220  	buf = new(bytes.Buffer)
   221  	_, err = p.Encoding().EncodeGossip(buf, signedAggregateAndProof)
   222  	require.NoError(t, err)
   223  
   224  	msg = &pubsub.Message{
   225  		Message: &pubsubpb.Message{
   226  			Data:  buf.Bytes(),
   227  			Topic: &topic,
   228  		},
   229  	}
   230  	if r.validateAggregateAndProof(context.Background(), "", msg) == pubsub.ValidationAccept {
   231  		t.Error("Expected validate to fail")
   232  	}
   233  }
   234  
   235  func TestValidateAggregateAndProof_ExistedInPool(t *testing.T) {
   236  	db := dbtest.SetupDB(t)
   237  	p := p2ptest.NewTestP2P(t)
   238  
   239  	validators := uint64(256)
   240  	beaconState, _ := testutil.DeterministicGenesisState(t, validators)
   241  
   242  	b := testutil.NewBeaconBlock()
   243  	require.NoError(t, db.SaveBlock(context.Background(), wrapper.WrappedPhase0SignedBeaconBlock(b)))
   244  	root, err := b.Block.HashTreeRoot()
   245  	require.NoError(t, err)
   246  
   247  	aggBits := bitfield.NewBitlist(3)
   248  	aggBits.SetBitAt(0, true)
   249  	att := &ethpb.Attestation{
   250  		Data: &ethpb.AttestationData{
   251  			Slot:            1,
   252  			BeaconBlockRoot: root[:],
   253  			Source:          &ethpb.Checkpoint{Epoch: 0, Root: bytesutil.PadTo([]byte("hello-world"), 32)},
   254  			Target:          &ethpb.Checkpoint{Epoch: 0, Root: bytesutil.PadTo([]byte("hello-world"), 32)},
   255  		},
   256  		AggregationBits: aggBits,
   257  		Signature:       make([]byte, 96),
   258  	}
   259  
   260  	aggregateAndProof := &ethpb.AggregateAttestationAndProof{
   261  		Aggregate:      att,
   262  		SelectionProof: make([]byte, 96),
   263  	}
   264  	signedAggregateAndProof := &ethpb.SignedAggregateAttestationAndProof{Message: aggregateAndProof, Signature: make([]byte, 96)}
   265  
   266  	require.NoError(t, beaconState.SetGenesisTime(uint64(time.Now().Unix())))
   267  	c, err := lru.New(10)
   268  	require.NoError(t, err)
   269  	r := &Service{
   270  		cfg: &Config{
   271  			AttPool:     attestations.NewPool(),
   272  			P2P:         p,
   273  			DB:          db,
   274  			InitialSync: &mockSync.Sync{IsSyncing: false},
   275  			Chain: &mock.ChainService{Genesis: time.Now(),
   276  				State: beaconState},
   277  			AttestationNotifier: (&mock.ChainService{}).OperationNotifier(),
   278  		},
   279  		seenAggregatedAttestationCache: c,
   280  		blkRootToPendingAtts:           make(map[[32]byte][]*ethpb.SignedAggregateAttestationAndProof),
   281  	}
   282  	err = r.initCaches()
   283  	require.NoError(t, err)
   284  
   285  	buf := new(bytes.Buffer)
   286  	_, err = p.Encoding().EncodeGossip(buf, signedAggregateAndProof)
   287  	require.NoError(t, err)
   288  
   289  	topic := p2p.GossipTypeMapping[reflect.TypeOf(signedAggregateAndProof)]
   290  	msg := &pubsub.Message{
   291  		Message: &pubsubpb.Message{
   292  			Data:  buf.Bytes(),
   293  			Topic: &topic,
   294  		},
   295  	}
   296  
   297  	require.NoError(t, r.cfg.AttPool.SaveBlockAttestation(att))
   298  	if r.validateAggregateAndProof(context.Background(), "", msg) == pubsub.ValidationAccept {
   299  		t.Error("Expected validate to fail")
   300  	}
   301  }
   302  
   303  func TestValidateAggregateAndProof_CanValidate(t *testing.T) {
   304  	db := dbtest.SetupDB(t)
   305  	p := p2ptest.NewTestP2P(t)
   306  
   307  	validators := uint64(256)
   308  	beaconState, privKeys := testutil.DeterministicGenesisState(t, validators)
   309  
   310  	b := testutil.NewBeaconBlock()
   311  	require.NoError(t, db.SaveBlock(context.Background(), wrapper.WrappedPhase0SignedBeaconBlock(b)))
   312  	root, err := b.Block.HashTreeRoot()
   313  	require.NoError(t, err)
   314  	s, err := testutil.NewBeaconState()
   315  	require.NoError(t, err)
   316  	require.NoError(t, db.SaveState(context.Background(), s, root))
   317  
   318  	aggBits := bitfield.NewBitlist(validators / uint64(params.BeaconConfig().SlotsPerEpoch))
   319  	aggBits.SetBitAt(0, true)
   320  	att := &ethpb.Attestation{
   321  		Data: &ethpb.AttestationData{
   322  			BeaconBlockRoot: root[:],
   323  			Source:          &ethpb.Checkpoint{Epoch: 0, Root: bytesutil.PadTo([]byte("hello-world"), 32)},
   324  			Target:          &ethpb.Checkpoint{Epoch: 0, Root: root[:]},
   325  		},
   326  		AggregationBits: aggBits,
   327  	}
   328  
   329  	committee, err := helpers.BeaconCommitteeFromState(beaconState, att.Data.Slot, att.Data.CommitteeIndex)
   330  	assert.NoError(t, err)
   331  	attestingIndices, err := attestationutil.AttestingIndices(att.AggregationBits, committee)
   332  	require.NoError(t, err)
   333  	assert.NoError(t, err)
   334  	attesterDomain, err := helpers.Domain(beaconState.Fork(), 0, params.BeaconConfig().DomainBeaconAttester, beaconState.GenesisValidatorRoot())
   335  	assert.NoError(t, err)
   336  	hashTreeRoot, err := helpers.ComputeSigningRoot(att.Data, attesterDomain)
   337  	assert.NoError(t, err)
   338  	sigs := make([]bls.Signature, len(attestingIndices))
   339  	for i, indice := range attestingIndices {
   340  		sig := privKeys[indice].Sign(hashTreeRoot[:])
   341  		sigs[i] = sig
   342  	}
   343  	att.Signature = bls.AggregateSignatures(sigs).Marshal()
   344  	ai := committee[0]
   345  	sszUint := types.SSZUint64(att.Data.Slot)
   346  	sig, err := helpers.ComputeDomainAndSign(beaconState, 0, &sszUint, params.BeaconConfig().DomainSelectionProof, privKeys[ai])
   347  	require.NoError(t, err)
   348  	aggregateAndProof := &ethpb.AggregateAttestationAndProof{
   349  		SelectionProof:  sig,
   350  		Aggregate:       att,
   351  		AggregatorIndex: ai,
   352  	}
   353  	signedAggregateAndProof := &ethpb.SignedAggregateAttestationAndProof{Message: aggregateAndProof}
   354  	signedAggregateAndProof.Signature, err = helpers.ComputeDomainAndSign(beaconState, 0, signedAggregateAndProof.Message, params.BeaconConfig().DomainAggregateAndProof, privKeys[ai])
   355  	require.NoError(t, err)
   356  
   357  	require.NoError(t, beaconState.SetGenesisTime(uint64(time.Now().Unix())))
   358  	c, err := lru.New(10)
   359  	require.NoError(t, err)
   360  	r := &Service{
   361  		cfg: &Config{
   362  			P2P:         p,
   363  			DB:          db,
   364  			InitialSync: &mockSync.Sync{IsSyncing: false},
   365  			Chain: &mock.ChainService{Genesis: time.Now(),
   366  				State:            beaconState,
   367  				ValidAttestation: true,
   368  				FinalizedCheckPoint: &ethpb.Checkpoint{
   369  					Epoch: 0,
   370  					Root:  att.Data.BeaconBlockRoot,
   371  				}},
   372  			AttPool:             attestations.NewPool(),
   373  			AttestationNotifier: (&mock.ChainService{}).OperationNotifier(),
   374  		},
   375  		seenAggregatedAttestationCache: c,
   376  	}
   377  	err = r.initCaches()
   378  	require.NoError(t, err)
   379  
   380  	buf := new(bytes.Buffer)
   381  	_, err = p.Encoding().EncodeGossip(buf, signedAggregateAndProof)
   382  	require.NoError(t, err)
   383  
   384  	topic := p2p.GossipTypeMapping[reflect.TypeOf(signedAggregateAndProof)]
   385  	msg := &pubsub.Message{
   386  		Message: &pubsubpb.Message{
   387  			Data:  buf.Bytes(),
   388  			Topic: &topic,
   389  		},
   390  	}
   391  
   392  	assert.Equal(t, pubsub.ValidationAccept, r.validateAggregateAndProof(context.Background(), "", msg), "Validated status is false")
   393  	assert.NotNil(t, msg.ValidatorData, "Did not set validator data")
   394  }
   395  
   396  func TestVerifyIndexInCommittee_SeenAggregatorEpoch(t *testing.T) {
   397  	db := dbtest.SetupDB(t)
   398  	p := p2ptest.NewTestP2P(t)
   399  
   400  	validators := uint64(256)
   401  	beaconState, privKeys := testutil.DeterministicGenesisState(t, validators)
   402  
   403  	b := testutil.NewBeaconBlock()
   404  	require.NoError(t, db.SaveBlock(context.Background(), wrapper.WrappedPhase0SignedBeaconBlock(b)))
   405  	root, err := b.Block.HashTreeRoot()
   406  	require.NoError(t, err)
   407  	s, err := testutil.NewBeaconState()
   408  	require.NoError(t, err)
   409  	require.NoError(t, db.SaveState(context.Background(), s, root))
   410  
   411  	aggBits := bitfield.NewBitlist(validators / uint64(params.BeaconConfig().SlotsPerEpoch))
   412  	aggBits.SetBitAt(0, true)
   413  	att := &ethpb.Attestation{
   414  		Data: &ethpb.AttestationData{
   415  			BeaconBlockRoot: root[:],
   416  			Source:          &ethpb.Checkpoint{Epoch: 0, Root: bytesutil.PadTo([]byte("hello-world"), 32)},
   417  			Target:          &ethpb.Checkpoint{Epoch: 0, Root: root[:]},
   418  		},
   419  		AggregationBits: aggBits,
   420  	}
   421  
   422  	committee, err := helpers.BeaconCommitteeFromState(beaconState, att.Data.Slot, att.Data.CommitteeIndex)
   423  	require.NoError(t, err)
   424  	attestingIndices, err := attestationutil.AttestingIndices(att.AggregationBits, committee)
   425  	require.NoError(t, err)
   426  	attesterDomain, err := helpers.Domain(beaconState.Fork(), 0, params.BeaconConfig().DomainBeaconAttester, beaconState.GenesisValidatorRoot())
   427  	require.NoError(t, err)
   428  	hashTreeRoot, err := helpers.ComputeSigningRoot(att.Data, attesterDomain)
   429  	assert.NoError(t, err)
   430  	sigs := make([]bls.Signature, len(attestingIndices))
   431  	for i, indice := range attestingIndices {
   432  		sig := privKeys[indice].Sign(hashTreeRoot[:])
   433  		sigs[i] = sig
   434  	}
   435  	att.Signature = bls.AggregateSignatures(sigs).Marshal()
   436  	ai := committee[0]
   437  	sszUint := types.SSZUint64(att.Data.Slot)
   438  	sig, err := helpers.ComputeDomainAndSign(beaconState, 0, &sszUint, params.BeaconConfig().DomainSelectionProof, privKeys[ai])
   439  	require.NoError(t, err)
   440  	aggregateAndProof := &ethpb.AggregateAttestationAndProof{
   441  		SelectionProof:  sig,
   442  		Aggregate:       att,
   443  		AggregatorIndex: ai,
   444  	}
   445  	signedAggregateAndProof := &ethpb.SignedAggregateAttestationAndProof{Message: aggregateAndProof}
   446  	signedAggregateAndProof.Signature, err = helpers.ComputeDomainAndSign(beaconState, 0, signedAggregateAndProof.Message, params.BeaconConfig().DomainAggregateAndProof, privKeys[ai])
   447  	require.NoError(t, err)
   448  	require.NoError(t, beaconState.SetGenesisTime(uint64(time.Now().Unix())))
   449  
   450  	c, err := lru.New(10)
   451  	require.NoError(t, err)
   452  	r := &Service{
   453  		cfg: &Config{
   454  			P2P:         p,
   455  			DB:          db,
   456  			InitialSync: &mockSync.Sync{IsSyncing: false},
   457  			Chain: &mock.ChainService{Genesis: time.Now(),
   458  				ValidatorsRoot:   [32]byte{'A'},
   459  				State:            beaconState,
   460  				ValidAttestation: true,
   461  				FinalizedCheckPoint: &ethpb.Checkpoint{
   462  					Epoch: 0,
   463  					Root:  signedAggregateAndProof.Message.Aggregate.Data.BeaconBlockRoot,
   464  				}},
   465  
   466  			AttPool:             attestations.NewPool(),
   467  			AttestationNotifier: (&mock.ChainService{}).OperationNotifier(),
   468  		},
   469  		seenAggregatedAttestationCache: c,
   470  	}
   471  	err = r.initCaches()
   472  	require.NoError(t, err)
   473  
   474  	buf := new(bytes.Buffer)
   475  	_, err = p.Encoding().EncodeGossip(buf, signedAggregateAndProof)
   476  	require.NoError(t, err)
   477  
   478  	topic := p2p.GossipTypeMapping[reflect.TypeOf(signedAggregateAndProof)]
   479  	msg := &pubsub.Message{
   480  		Message: &pubsubpb.Message{
   481  			Data:  buf.Bytes(),
   482  			Topic: &topic,
   483  		},
   484  	}
   485  
   486  	require.Equal(t, pubsub.ValidationAccept, r.validateAggregateAndProof(context.Background(), "", msg), "Validated status is false")
   487  
   488  	// Should fail with another attestation in the same epoch.
   489  	signedAggregateAndProof.Message.Aggregate.Data.Slot++
   490  	buf = new(bytes.Buffer)
   491  	_, err = p.Encoding().EncodeGossip(buf, signedAggregateAndProof)
   492  	require.NoError(t, err)
   493  	msg = &pubsub.Message{
   494  		Message: &pubsubpb.Message{
   495  			Data:  buf.Bytes(),
   496  			Topic: &topic,
   497  		},
   498  	}
   499  
   500  	time.Sleep(10 * time.Millisecond) // Wait for cached value to pass through buffers.
   501  	if r.validateAggregateAndProof(context.Background(), "", msg) == pubsub.ValidationAccept {
   502  		t.Fatal("Validated status is true")
   503  	}
   504  }
   505  
   506  func TestValidateAggregateAndProof_BadBlock(t *testing.T) {
   507  
   508  	db := dbtest.SetupDB(t)
   509  	p := p2ptest.NewTestP2P(t)
   510  
   511  	validators := uint64(256)
   512  	beaconState, privKeys := testutil.DeterministicGenesisState(t, validators)
   513  
   514  	b := testutil.NewBeaconBlock()
   515  	root, err := b.Block.HashTreeRoot()
   516  	require.NoError(t, err)
   517  	s, err := testutil.NewBeaconState()
   518  	require.NoError(t, err)
   519  	require.NoError(t, db.SaveState(context.Background(), s, root))
   520  
   521  	aggBits := bitfield.NewBitlist(validators / uint64(params.BeaconConfig().SlotsPerEpoch))
   522  	aggBits.SetBitAt(0, true)
   523  	att := &ethpb.Attestation{
   524  		Data: &ethpb.AttestationData{
   525  			BeaconBlockRoot: root[:],
   526  			Source:          &ethpb.Checkpoint{Epoch: 0, Root: bytesutil.PadTo([]byte("hello-world"), 32)},
   527  			Target:          &ethpb.Checkpoint{Epoch: 0, Root: root[:]},
   528  		},
   529  		AggregationBits: aggBits,
   530  	}
   531  
   532  	committee, err := helpers.BeaconCommitteeFromState(beaconState, att.Data.Slot, att.Data.CommitteeIndex)
   533  	assert.NoError(t, err)
   534  	attestingIndices, err := attestationutil.AttestingIndices(att.AggregationBits, committee)
   535  	require.NoError(t, err)
   536  	assert.NoError(t, err)
   537  	attesterDomain, err := helpers.Domain(beaconState.Fork(), 0, params.BeaconConfig().DomainBeaconAttester, beaconState.GenesisValidatorRoot())
   538  	assert.NoError(t, err)
   539  	hashTreeRoot, err := helpers.ComputeSigningRoot(att.Data, attesterDomain)
   540  	assert.NoError(t, err)
   541  	sigs := make([]bls.Signature, len(attestingIndices))
   542  	for i, indice := range attestingIndices {
   543  		sig := privKeys[indice].Sign(hashTreeRoot[:])
   544  		sigs[i] = sig
   545  	}
   546  	att.Signature = bls.AggregateSignatures(sigs).Marshal()
   547  	ai := committee[0]
   548  	sszUint := types.SSZUint64(att.Data.Slot)
   549  	sig, err := helpers.ComputeDomainAndSign(beaconState, 0, &sszUint, params.BeaconConfig().DomainSelectionProof, privKeys[ai])
   550  	require.NoError(t, err)
   551  
   552  	aggregateAndProof := &ethpb.AggregateAttestationAndProof{
   553  		SelectionProof:  sig,
   554  		Aggregate:       att,
   555  		AggregatorIndex: ai,
   556  	}
   557  	signedAggregateAndProof := &ethpb.SignedAggregateAttestationAndProof{Message: aggregateAndProof}
   558  	signedAggregateAndProof.Signature, err = helpers.ComputeDomainAndSign(beaconState, 0, signedAggregateAndProof.Message, params.BeaconConfig().DomainAggregateAndProof, privKeys[ai])
   559  	require.NoError(t, err)
   560  
   561  	require.NoError(t, beaconState.SetGenesisTime(uint64(time.Now().Unix())))
   562  	c, err := lru.New(10)
   563  	require.NoError(t, err)
   564  	r := &Service{
   565  		cfg: &Config{
   566  			P2P:         p,
   567  			DB:          db,
   568  			InitialSync: &mockSync.Sync{IsSyncing: false},
   569  			Chain: &mock.ChainService{Genesis: time.Now(),
   570  				State:            beaconState,
   571  				ValidAttestation: true,
   572  				FinalizedCheckPoint: &ethpb.Checkpoint{
   573  					Epoch: 0,
   574  				}},
   575  			AttPool:             attestations.NewPool(),
   576  			AttestationNotifier: (&mock.ChainService{}).OperationNotifier(),
   577  		},
   578  		seenAggregatedAttestationCache: c,
   579  	}
   580  	err = r.initCaches()
   581  	require.NoError(t, err)
   582  	// Set beacon block as bad.
   583  	r.setBadBlock(context.Background(), root)
   584  	buf := new(bytes.Buffer)
   585  	_, err = p.Encoding().EncodeGossip(buf, signedAggregateAndProof)
   586  	require.NoError(t, err)
   587  
   588  	topic := p2p.GossipTypeMapping[reflect.TypeOf(signedAggregateAndProof)]
   589  	msg := &pubsub.Message{
   590  		Message: &pubsubpb.Message{
   591  			Data:  buf.Bytes(),
   592  			Topic: &topic,
   593  		},
   594  	}
   595  
   596  	assert.Equal(t, pubsub.ValidationReject, r.validateAggregateAndProof(context.Background(), "", msg), "Validated status is true")
   597  }
   598  
   599  func TestValidateAggregateAndProof_RejectWhenAttEpochDoesntEqualTargetEpoch(t *testing.T) {
   600  	db := dbtest.SetupDB(t)
   601  	p := p2ptest.NewTestP2P(t)
   602  
   603  	validators := uint64(256)
   604  	beaconState, privKeys := testutil.DeterministicGenesisState(t, validators)
   605  
   606  	b := testutil.NewBeaconBlock()
   607  	require.NoError(t, db.SaveBlock(context.Background(), wrapper.WrappedPhase0SignedBeaconBlock(b)))
   608  	root, err := b.Block.HashTreeRoot()
   609  	require.NoError(t, err)
   610  	s, err := testutil.NewBeaconState()
   611  	require.NoError(t, err)
   612  	require.NoError(t, db.SaveState(context.Background(), s, root))
   613  
   614  	aggBits := bitfield.NewBitlist(validators / uint64(params.BeaconConfig().SlotsPerEpoch))
   615  	aggBits.SetBitAt(0, true)
   616  	att := &ethpb.Attestation{
   617  		Data: &ethpb.AttestationData{
   618  			BeaconBlockRoot: root[:],
   619  			Source:          &ethpb.Checkpoint{Epoch: 0, Root: bytesutil.PadTo([]byte("hello-world"), 32)},
   620  			Target:          &ethpb.Checkpoint{Epoch: 1, Root: root[:]},
   621  		},
   622  		AggregationBits: aggBits,
   623  	}
   624  
   625  	committee, err := helpers.BeaconCommitteeFromState(beaconState, att.Data.Slot, att.Data.CommitteeIndex)
   626  	assert.NoError(t, err)
   627  	attestingIndices, err := attestationutil.AttestingIndices(att.AggregationBits, committee)
   628  	require.NoError(t, err)
   629  	assert.NoError(t, err)
   630  	attesterDomain, err := helpers.Domain(beaconState.Fork(), 0, params.BeaconConfig().DomainBeaconAttester, beaconState.GenesisValidatorRoot())
   631  	assert.NoError(t, err)
   632  	hashTreeRoot, err := helpers.ComputeSigningRoot(att.Data, attesterDomain)
   633  	assert.NoError(t, err)
   634  	sigs := make([]bls.Signature, len(attestingIndices))
   635  	for i, indice := range attestingIndices {
   636  		sig := privKeys[indice].Sign(hashTreeRoot[:])
   637  		sigs[i] = sig
   638  	}
   639  	att.Signature = bls.AggregateSignatures(sigs).Marshal()
   640  	ai := committee[0]
   641  	sszUint := types.SSZUint64(att.Data.Slot)
   642  	sig, err := helpers.ComputeDomainAndSign(beaconState, 0, &sszUint, params.BeaconConfig().DomainSelectionProof, privKeys[ai])
   643  	require.NoError(t, err)
   644  	aggregateAndProof := &ethpb.AggregateAttestationAndProof{
   645  		SelectionProof:  sig,
   646  		Aggregate:       att,
   647  		AggregatorIndex: ai,
   648  	}
   649  	signedAggregateAndProof := &ethpb.SignedAggregateAttestationAndProof{Message: aggregateAndProof}
   650  	signedAggregateAndProof.Signature, err = helpers.ComputeDomainAndSign(beaconState, 0, signedAggregateAndProof.Message, params.BeaconConfig().DomainAggregateAndProof, privKeys[ai])
   651  	require.NoError(t, err)
   652  
   653  	require.NoError(t, beaconState.SetGenesisTime(uint64(time.Now().Unix())))
   654  	c, err := lru.New(10)
   655  	require.NoError(t, err)
   656  	r := &Service{
   657  		cfg: &Config{
   658  			P2P:         p,
   659  			DB:          db,
   660  			InitialSync: &mockSync.Sync{IsSyncing: false},
   661  			Chain: &mock.ChainService{Genesis: time.Now(),
   662  				State:            beaconState,
   663  				ValidAttestation: true,
   664  				FinalizedCheckPoint: &ethpb.Checkpoint{
   665  					Epoch: 0,
   666  					Root:  att.Data.BeaconBlockRoot,
   667  				}},
   668  			AttPool:             attestations.NewPool(),
   669  			AttestationNotifier: (&mock.ChainService{}).OperationNotifier(),
   670  		},
   671  		seenAggregatedAttestationCache: c,
   672  	}
   673  	err = r.initCaches()
   674  	require.NoError(t, err)
   675  
   676  	buf := new(bytes.Buffer)
   677  	_, err = p.Encoding().EncodeGossip(buf, signedAggregateAndProof)
   678  	require.NoError(t, err)
   679  
   680  	topic := p2p.GossipTypeMapping[reflect.TypeOf(signedAggregateAndProof)]
   681  	msg := &pubsub.Message{
   682  		Message: &pubsubpb.Message{
   683  			Data:  buf.Bytes(),
   684  			Topic: &topic,
   685  		},
   686  	}
   687  
   688  	assert.Equal(t, pubsub.ValidationReject, r.validateAggregateAndProof(context.Background(), "", msg))
   689  }