github.com/prysmaticlabs/prysm@v1.4.4/beacon-chain/core/blocks/attestation_test.go (about)

     1  package blocks_test
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"testing"
     7  
     8  	types "github.com/prysmaticlabs/eth2-types"
     9  	"github.com/prysmaticlabs/go-bitfield"
    10  	"github.com/prysmaticlabs/prysm/beacon-chain/core/blocks"
    11  	"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
    12  	"github.com/prysmaticlabs/prysm/beacon-chain/state/v1"
    13  	pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
    14  	ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
    15  	"github.com/prysmaticlabs/prysm/proto/eth/v1alpha1/wrapper"
    16  	"github.com/prysmaticlabs/prysm/shared/aggregation"
    17  	attaggregation "github.com/prysmaticlabs/prysm/shared/aggregation/attestations"
    18  	"github.com/prysmaticlabs/prysm/shared/attestationutil"
    19  	"github.com/prysmaticlabs/prysm/shared/bls"
    20  	"github.com/prysmaticlabs/prysm/shared/bytesutil"
    21  	"github.com/prysmaticlabs/prysm/shared/params"
    22  	"github.com/prysmaticlabs/prysm/shared/testutil"
    23  	"github.com/prysmaticlabs/prysm/shared/testutil/assert"
    24  	"github.com/prysmaticlabs/prysm/shared/testutil/require"
    25  )
    26  
    27  func TestProcessAttestations_InclusionDelayFailure(t *testing.T) {
    28  	attestations := []*ethpb.Attestation{
    29  		testutil.HydrateAttestation(&ethpb.Attestation{
    30  			Data: &ethpb.AttestationData{
    31  				Target: &ethpb.Checkpoint{Epoch: 0, Root: make([]byte, 32)},
    32  				Slot:   5,
    33  			},
    34  		}),
    35  	}
    36  	b := testutil.NewBeaconBlock()
    37  	b.Block = &ethpb.BeaconBlock{
    38  		Body: &ethpb.BeaconBlockBody{
    39  			Attestations: attestations,
    40  		},
    41  	}
    42  	beaconState, _ := testutil.DeterministicGenesisState(t, 100)
    43  
    44  	want := fmt.Sprintf(
    45  		"attestation slot %d + inclusion delay %d > state slot %d",
    46  		attestations[0].Data.Slot,
    47  		params.BeaconConfig().MinAttestationInclusionDelay,
    48  		beaconState.Slot(),
    49  	)
    50  	_, err := blocks.ProcessAttestations(context.Background(), beaconState, wrapper.WrappedPhase0SignedBeaconBlock(b))
    51  	assert.ErrorContains(t, want, err)
    52  }
    53  
    54  func TestProcessAttestations_NeitherCurrentNorPrevEpoch(t *testing.T) {
    55  	att := testutil.HydrateAttestation(&ethpb.Attestation{
    56  		Data: &ethpb.AttestationData{
    57  			Source: &ethpb.Checkpoint{Epoch: 0, Root: []byte("hello-world")},
    58  			Target: &ethpb.Checkpoint{Epoch: 0}}})
    59  
    60  	b := testutil.NewBeaconBlock()
    61  	b.Block = &ethpb.BeaconBlock{
    62  		Body: &ethpb.BeaconBlockBody{
    63  			Attestations: []*ethpb.Attestation{att},
    64  		},
    65  	}
    66  	beaconState, _ := testutil.DeterministicGenesisState(t, 100)
    67  	err := beaconState.SetSlot(beaconState.Slot() + params.BeaconConfig().SlotsPerEpoch*4 + params.BeaconConfig().MinAttestationInclusionDelay)
    68  	require.NoError(t, err)
    69  	pfc := beaconState.PreviousJustifiedCheckpoint()
    70  	pfc.Root = []byte("hello-world")
    71  	require.NoError(t, beaconState.SetPreviousJustifiedCheckpoint(pfc))
    72  	require.NoError(t, beaconState.AppendPreviousEpochAttestations(&pb.PendingAttestation{}))
    73  
    74  	want := fmt.Sprintf(
    75  		"expected target epoch (%d) to be the previous epoch (%d) or the current epoch (%d)",
    76  		att.Data.Target.Epoch,
    77  		helpers.PrevEpoch(beaconState),
    78  		helpers.CurrentEpoch(beaconState),
    79  	)
    80  	_, err = blocks.ProcessAttestations(context.Background(), beaconState, wrapper.WrappedPhase0SignedBeaconBlock(b))
    81  	assert.ErrorContains(t, want, err)
    82  }
    83  
    84  func TestProcessAttestations_CurrentEpochFFGDataMismatches(t *testing.T) {
    85  	attestations := []*ethpb.Attestation{
    86  		{
    87  			Data: &ethpb.AttestationData{
    88  				Target: &ethpb.Checkpoint{Epoch: 0, Root: make([]byte, 32)},
    89  				Source: &ethpb.Checkpoint{Epoch: 1, Root: make([]byte, 32)},
    90  			},
    91  			AggregationBits: bitfield.Bitlist{0x09},
    92  		},
    93  	}
    94  	b := testutil.NewBeaconBlock()
    95  	b.Block = &ethpb.BeaconBlock{
    96  		Body: &ethpb.BeaconBlockBody{
    97  			Attestations: attestations,
    98  		},
    99  	}
   100  	beaconState, _ := testutil.DeterministicGenesisState(t, 100)
   101  	require.NoError(t, beaconState.SetSlot(beaconState.Slot()+params.BeaconConfig().MinAttestationInclusionDelay))
   102  	cfc := beaconState.CurrentJustifiedCheckpoint()
   103  	cfc.Root = []byte("hello-world")
   104  	require.NoError(t, beaconState.SetCurrentJustifiedCheckpoint(cfc))
   105  	require.NoError(t, beaconState.AppendCurrentEpochAttestations(&pb.PendingAttestation{}))
   106  
   107  	want := "source check point not equal to current justified checkpoint"
   108  	_, err := blocks.ProcessAttestations(context.Background(), beaconState, wrapper.WrappedPhase0SignedBeaconBlock(b))
   109  	assert.ErrorContains(t, want, err)
   110  	b.Block.Body.Attestations[0].Data.Source.Epoch = helpers.CurrentEpoch(beaconState)
   111  	b.Block.Body.Attestations[0].Data.Source.Root = []byte{}
   112  	_, err = blocks.ProcessAttestations(context.Background(), beaconState, wrapper.WrappedPhase0SignedBeaconBlock(b))
   113  	assert.ErrorContains(t, want, err)
   114  }
   115  
   116  func TestProcessAttestations_PrevEpochFFGDataMismatches(t *testing.T) {
   117  	beaconState, _ := testutil.DeterministicGenesisState(t, 100)
   118  
   119  	aggBits := bitfield.NewBitlist(3)
   120  	aggBits.SetBitAt(0, true)
   121  	attestations := []*ethpb.Attestation{
   122  		{
   123  			Data: &ethpb.AttestationData{
   124  				Source: &ethpb.Checkpoint{Epoch: 1, Root: make([]byte, 32)},
   125  				Target: &ethpb.Checkpoint{Epoch: 1, Root: make([]byte, 32)},
   126  				Slot:   params.BeaconConfig().SlotsPerEpoch,
   127  			},
   128  			AggregationBits: aggBits,
   129  		},
   130  	}
   131  	b := testutil.NewBeaconBlock()
   132  	b.Block = &ethpb.BeaconBlock{
   133  		Body: &ethpb.BeaconBlockBody{
   134  			Attestations: attestations,
   135  		},
   136  	}
   137  
   138  	err := beaconState.SetSlot(beaconState.Slot() + 2*params.BeaconConfig().SlotsPerEpoch)
   139  	require.NoError(t, err)
   140  	pfc := beaconState.PreviousJustifiedCheckpoint()
   141  	pfc.Root = []byte("hello-world")
   142  	require.NoError(t, beaconState.SetPreviousJustifiedCheckpoint(pfc))
   143  	require.NoError(t, beaconState.AppendPreviousEpochAttestations(&pb.PendingAttestation{}))
   144  
   145  	want := "source check point not equal to previous justified checkpoint"
   146  	_, err = blocks.ProcessAttestations(context.Background(), beaconState, wrapper.WrappedPhase0SignedBeaconBlock(b))
   147  	assert.ErrorContains(t, want, err)
   148  	b.Block.Body.Attestations[0].Data.Source.Epoch = helpers.PrevEpoch(beaconState)
   149  	b.Block.Body.Attestations[0].Data.Target.Epoch = helpers.PrevEpoch(beaconState)
   150  	b.Block.Body.Attestations[0].Data.Source.Root = []byte{}
   151  	_, err = blocks.ProcessAttestations(context.Background(), beaconState, wrapper.WrappedPhase0SignedBeaconBlock(b))
   152  	assert.ErrorContains(t, want, err)
   153  }
   154  
   155  func TestProcessAttestations_InvalidAggregationBitsLength(t *testing.T) {
   156  	beaconState, _ := testutil.DeterministicGenesisState(t, 100)
   157  
   158  	aggBits := bitfield.NewBitlist(4)
   159  	att := &ethpb.Attestation{
   160  		Data: &ethpb.AttestationData{
   161  			Source: &ethpb.Checkpoint{Epoch: 0, Root: []byte("hello-world")},
   162  			Target: &ethpb.Checkpoint{Epoch: 0}},
   163  		AggregationBits: aggBits,
   164  	}
   165  
   166  	b := testutil.NewBeaconBlock()
   167  	b.Block = &ethpb.BeaconBlock{
   168  		Body: &ethpb.BeaconBlockBody{
   169  			Attestations: []*ethpb.Attestation{att},
   170  		},
   171  	}
   172  
   173  	err := beaconState.SetSlot(beaconState.Slot() + params.BeaconConfig().MinAttestationInclusionDelay)
   174  	require.NoError(t, err)
   175  
   176  	cfc := beaconState.CurrentJustifiedCheckpoint()
   177  	cfc.Root = []byte("hello-world")
   178  	require.NoError(t, beaconState.SetCurrentJustifiedCheckpoint(cfc))
   179  	require.NoError(t, beaconState.AppendCurrentEpochAttestations(&pb.PendingAttestation{}))
   180  
   181  	expected := "failed to verify aggregation bitfield: wanted participants bitfield length 3, got: 4"
   182  	_, err = blocks.ProcessAttestations(context.Background(), beaconState, wrapper.WrappedPhase0SignedBeaconBlock(b))
   183  	assert.ErrorContains(t, expected, err)
   184  }
   185  
   186  func TestProcessAttestations_OK(t *testing.T) {
   187  	beaconState, privKeys := testutil.DeterministicGenesisState(t, 100)
   188  
   189  	aggBits := bitfield.NewBitlist(3)
   190  	aggBits.SetBitAt(0, true)
   191  	var mockRoot [32]byte
   192  	copy(mockRoot[:], "hello-world")
   193  	att := testutil.HydrateAttestation(&ethpb.Attestation{
   194  		Data: &ethpb.AttestationData{
   195  			Source: &ethpb.Checkpoint{Root: mockRoot[:]},
   196  			Target: &ethpb.Checkpoint{Root: mockRoot[:]},
   197  		},
   198  		AggregationBits: aggBits,
   199  	})
   200  
   201  	cfc := beaconState.CurrentJustifiedCheckpoint()
   202  	cfc.Root = mockRoot[:]
   203  	require.NoError(t, beaconState.SetCurrentJustifiedCheckpoint(cfc))
   204  	require.NoError(t, beaconState.AppendCurrentEpochAttestations(&pb.PendingAttestation{}))
   205  
   206  	committee, err := helpers.BeaconCommitteeFromState(beaconState, att.Data.Slot, att.Data.CommitteeIndex)
   207  	require.NoError(t, err)
   208  	attestingIndices, err := attestationutil.AttestingIndices(att.AggregationBits, committee)
   209  	require.NoError(t, err)
   210  	sigs := make([]bls.Signature, len(attestingIndices))
   211  	for i, indice := range attestingIndices {
   212  		sb, err := helpers.ComputeDomainAndSign(beaconState, 0, att.Data, params.BeaconConfig().DomainBeaconAttester, privKeys[indice])
   213  		require.NoError(t, err)
   214  		sig, err := bls.SignatureFromBytes(sb)
   215  		require.NoError(t, err)
   216  		sigs[i] = sig
   217  	}
   218  	att.Signature = bls.AggregateSignatures(sigs).Marshal()
   219  
   220  	block := testutil.NewBeaconBlock()
   221  	block.Block.Body.Attestations = []*ethpb.Attestation{att}
   222  
   223  	err = beaconState.SetSlot(beaconState.Slot() + params.BeaconConfig().MinAttestationInclusionDelay)
   224  	require.NoError(t, err)
   225  	_, err = blocks.ProcessAttestations(context.Background(), beaconState, wrapper.WrappedPhase0SignedBeaconBlock(block))
   226  	assert.NoError(t, err)
   227  }
   228  
   229  func TestProcessAggregatedAttestation_OverlappingBits(t *testing.T) {
   230  	beaconState, privKeys := testutil.DeterministicGenesisState(t, 100)
   231  	data := testutil.HydrateAttestationData(&ethpb.AttestationData{
   232  		Source: &ethpb.Checkpoint{Epoch: 0, Root: bytesutil.PadTo([]byte("hello-world"), 32)},
   233  		Target: &ethpb.Checkpoint{Epoch: 0, Root: bytesutil.PadTo([]byte("hello-world"), 32)},
   234  	})
   235  	aggBits1 := bitfield.NewBitlist(3)
   236  	aggBits1.SetBitAt(0, true)
   237  	aggBits1.SetBitAt(1, true)
   238  	att1 := &ethpb.Attestation{
   239  		Data:            data,
   240  		AggregationBits: aggBits1,
   241  	}
   242  
   243  	cfc := beaconState.CurrentJustifiedCheckpoint()
   244  	cfc.Root = bytesutil.PadTo([]byte("hello-world"), 32)
   245  	require.NoError(t, beaconState.SetCurrentJustifiedCheckpoint(cfc))
   246  	require.NoError(t, beaconState.AppendCurrentEpochAttestations(&pb.PendingAttestation{}))
   247  
   248  	committee, err := helpers.BeaconCommitteeFromState(beaconState, att1.Data.Slot, att1.Data.CommitteeIndex)
   249  	require.NoError(t, err)
   250  	attestingIndices1, err := attestationutil.AttestingIndices(att1.AggregationBits, committee)
   251  	require.NoError(t, err)
   252  	sigs := make([]bls.Signature, len(attestingIndices1))
   253  	for i, indice := range attestingIndices1 {
   254  		sb, err := helpers.ComputeDomainAndSign(beaconState, 0, att1.Data, params.BeaconConfig().DomainBeaconAttester, privKeys[indice])
   255  		require.NoError(t, err)
   256  		sig, err := bls.SignatureFromBytes(sb)
   257  		require.NoError(t, err)
   258  		sigs[i] = sig
   259  	}
   260  	att1.Signature = bls.AggregateSignatures(sigs).Marshal()
   261  
   262  	aggBits2 := bitfield.NewBitlist(3)
   263  	aggBits2.SetBitAt(1, true)
   264  	aggBits2.SetBitAt(2, true)
   265  	att2 := &ethpb.Attestation{
   266  		Data:            data,
   267  		AggregationBits: aggBits2,
   268  	}
   269  
   270  	committee, err = helpers.BeaconCommitteeFromState(beaconState, att2.Data.Slot, att2.Data.CommitteeIndex)
   271  	require.NoError(t, err)
   272  	attestingIndices2, err := attestationutil.AttestingIndices(att2.AggregationBits, committee)
   273  	require.NoError(t, err)
   274  	sigs = make([]bls.Signature, len(attestingIndices2))
   275  	for i, indice := range attestingIndices2 {
   276  		sb, err := helpers.ComputeDomainAndSign(beaconState, 0, att2.Data, params.BeaconConfig().DomainBeaconAttester, privKeys[indice])
   277  		require.NoError(t, err)
   278  		sig, err := bls.SignatureFromBytes(sb)
   279  		require.NoError(t, err)
   280  		sigs[i] = sig
   281  	}
   282  	att2.Signature = bls.AggregateSignatures(sigs).Marshal()
   283  
   284  	_, err = attaggregation.AggregatePair(att1, att2)
   285  	assert.ErrorContains(t, aggregation.ErrBitsOverlap.Error(), err)
   286  }
   287  
   288  func TestProcessAggregatedAttestation_NoOverlappingBits(t *testing.T) {
   289  	beaconState, privKeys := testutil.DeterministicGenesisState(t, 300)
   290  
   291  	var mockRoot [32]byte
   292  	copy(mockRoot[:], "hello-world")
   293  	data := testutil.HydrateAttestationData(&ethpb.AttestationData{
   294  		Source: &ethpb.Checkpoint{Epoch: 0, Root: mockRoot[:]},
   295  		Target: &ethpb.Checkpoint{Epoch: 0, Root: mockRoot[:]},
   296  	})
   297  	aggBits1 := bitfield.NewBitlist(9)
   298  	aggBits1.SetBitAt(0, true)
   299  	aggBits1.SetBitAt(1, true)
   300  	att1 := &ethpb.Attestation{
   301  		Data:            data,
   302  		AggregationBits: aggBits1,
   303  		Signature:       make([]byte, 32),
   304  	}
   305  
   306  	cfc := beaconState.CurrentJustifiedCheckpoint()
   307  	cfc.Root = mockRoot[:]
   308  	require.NoError(t, beaconState.SetCurrentJustifiedCheckpoint(cfc))
   309  	require.NoError(t, beaconState.AppendCurrentEpochAttestations(&pb.PendingAttestation{}))
   310  
   311  	committee, err := helpers.BeaconCommitteeFromState(beaconState, att1.Data.Slot, att1.Data.CommitteeIndex)
   312  	require.NoError(t, err)
   313  	attestingIndices1, err := attestationutil.AttestingIndices(att1.AggregationBits, committee)
   314  	require.NoError(t, err)
   315  	sigs := make([]bls.Signature, len(attestingIndices1))
   316  	for i, indice := range attestingIndices1 {
   317  		sb, err := helpers.ComputeDomainAndSign(beaconState, 0, data, params.BeaconConfig().DomainBeaconAttester, privKeys[indice])
   318  		require.NoError(t, err)
   319  		sig, err := bls.SignatureFromBytes(sb)
   320  		require.NoError(t, err)
   321  		sigs[i] = sig
   322  	}
   323  	att1.Signature = bls.AggregateSignatures(sigs).Marshal()
   324  
   325  	aggBits2 := bitfield.NewBitlist(9)
   326  	aggBits2.SetBitAt(2, true)
   327  	aggBits2.SetBitAt(3, true)
   328  	att2 := &ethpb.Attestation{
   329  		Data:            data,
   330  		AggregationBits: aggBits2,
   331  		Signature:       make([]byte, 32),
   332  	}
   333  
   334  	committee, err = helpers.BeaconCommitteeFromState(beaconState, att2.Data.Slot, att2.Data.CommitteeIndex)
   335  	require.NoError(t, err)
   336  	attestingIndices2, err := attestationutil.AttestingIndices(att2.AggregationBits, committee)
   337  	require.NoError(t, err)
   338  	sigs = make([]bls.Signature, len(attestingIndices2))
   339  	for i, indice := range attestingIndices2 {
   340  		sb, err := helpers.ComputeDomainAndSign(beaconState, 0, att2.Data, params.BeaconConfig().DomainBeaconAttester, privKeys[indice])
   341  		require.NoError(t, err)
   342  		sig, err := bls.SignatureFromBytes(sb)
   343  		require.NoError(t, err)
   344  		sigs[i] = sig
   345  	}
   346  	att2.Signature = bls.AggregateSignatures(sigs).Marshal()
   347  
   348  	aggregatedAtt, err := attaggregation.AggregatePair(att1, att2)
   349  	require.NoError(t, err)
   350  	block := testutil.NewBeaconBlock()
   351  	block.Block.Body.Attestations = []*ethpb.Attestation{aggregatedAtt}
   352  
   353  	err = beaconState.SetSlot(beaconState.Slot() + params.BeaconConfig().MinAttestationInclusionDelay)
   354  	require.NoError(t, err)
   355  
   356  	_, err = blocks.ProcessAttestations(context.Background(), beaconState, wrapper.WrappedPhase0SignedBeaconBlock(block))
   357  	assert.NoError(t, err)
   358  }
   359  
   360  func TestVerifyAttestationNoVerifySignature_IncorrectSlotTargetEpoch(t *testing.T) {
   361  	beaconState, _ := testutil.DeterministicGenesisState(t, 1)
   362  
   363  	att := testutil.HydrateAttestation(&ethpb.Attestation{
   364  		Data: &ethpb.AttestationData{
   365  			Slot:   params.BeaconConfig().SlotsPerEpoch,
   366  			Target: &ethpb.Checkpoint{Root: make([]byte, 32)},
   367  		},
   368  	})
   369  	wanted := "slot 32 does not match target epoch 0"
   370  	err := blocks.VerifyAttestationNoVerifySignature(context.TODO(), beaconState, att)
   371  	assert.ErrorContains(t, wanted, err)
   372  }
   373  
   374  func TestProcessAttestationsNoVerify_OK(t *testing.T) {
   375  	// Attestation with an empty signature
   376  
   377  	beaconState, _ := testutil.DeterministicGenesisState(t, 100)
   378  
   379  	aggBits := bitfield.NewBitlist(3)
   380  	aggBits.SetBitAt(1, true)
   381  	var mockRoot [32]byte
   382  	copy(mockRoot[:], "hello-world")
   383  	att := &ethpb.Attestation{
   384  		Data: &ethpb.AttestationData{
   385  			Source: &ethpb.Checkpoint{Epoch: 0, Root: mockRoot[:]},
   386  			Target: &ethpb.Checkpoint{Epoch: 0, Root: make([]byte, 32)},
   387  		},
   388  		AggregationBits: aggBits,
   389  	}
   390  
   391  	zeroSig := [96]byte{}
   392  	att.Signature = zeroSig[:]
   393  
   394  	err := beaconState.SetSlot(beaconState.Slot() + params.BeaconConfig().MinAttestationInclusionDelay)
   395  	require.NoError(t, err)
   396  	ckp := beaconState.CurrentJustifiedCheckpoint()
   397  	copy(ckp.Root, "hello-world")
   398  	require.NoError(t, beaconState.SetCurrentJustifiedCheckpoint(ckp))
   399  	require.NoError(t, beaconState.AppendCurrentEpochAttestations(&pb.PendingAttestation{}))
   400  
   401  	_, err = blocks.ProcessAttestationNoVerifySignature(context.TODO(), beaconState, att)
   402  	assert.NoError(t, err)
   403  }
   404  
   405  func TestVerifyAttestationNoVerifySignature_OK(t *testing.T) {
   406  	// Attestation with an empty signature
   407  
   408  	beaconState, _ := testutil.DeterministicGenesisState(t, 100)
   409  
   410  	aggBits := bitfield.NewBitlist(3)
   411  	aggBits.SetBitAt(1, true)
   412  	var mockRoot [32]byte
   413  	copy(mockRoot[:], "hello-world")
   414  	att := &ethpb.Attestation{
   415  		Data: &ethpb.AttestationData{
   416  			Source: &ethpb.Checkpoint{Epoch: 0, Root: mockRoot[:]},
   417  			Target: &ethpb.Checkpoint{Epoch: 0, Root: make([]byte, 32)},
   418  		},
   419  		AggregationBits: aggBits,
   420  	}
   421  
   422  	zeroSig := [96]byte{}
   423  	att.Signature = zeroSig[:]
   424  
   425  	err := beaconState.SetSlot(beaconState.Slot() + params.BeaconConfig().MinAttestationInclusionDelay)
   426  	require.NoError(t, err)
   427  	ckp := beaconState.CurrentJustifiedCheckpoint()
   428  	copy(ckp.Root, "hello-world")
   429  	require.NoError(t, beaconState.SetCurrentJustifiedCheckpoint(ckp))
   430  	require.NoError(t, beaconState.AppendCurrentEpochAttestations(&pb.PendingAttestation{}))
   431  
   432  	err = blocks.VerifyAttestationNoVerifySignature(context.TODO(), beaconState, att)
   433  	assert.NoError(t, err)
   434  }
   435  
   436  func TestVerifyAttestationNoVerifySignature_BadAttIdx(t *testing.T) {
   437  	beaconState, _ := testutil.DeterministicGenesisState(t, 100)
   438  	aggBits := bitfield.NewBitlist(3)
   439  	aggBits.SetBitAt(1, true)
   440  	var mockRoot [32]byte
   441  	copy(mockRoot[:], "hello-world")
   442  	att := &ethpb.Attestation{
   443  		Data: &ethpb.AttestationData{
   444  			CommitteeIndex: 100,
   445  			Source:         &ethpb.Checkpoint{Epoch: 0, Root: mockRoot[:]},
   446  			Target:         &ethpb.Checkpoint{Epoch: 0, Root: make([]byte, 32)},
   447  		},
   448  		AggregationBits: aggBits,
   449  	}
   450  	zeroSig := [96]byte{}
   451  	att.Signature = zeroSig[:]
   452  	require.NoError(t, beaconState.SetSlot(beaconState.Slot()+params.BeaconConfig().MinAttestationInclusionDelay))
   453  	ckp := beaconState.CurrentJustifiedCheckpoint()
   454  	copy(ckp.Root, "hello-world")
   455  	require.NoError(t, beaconState.SetCurrentJustifiedCheckpoint(ckp))
   456  	require.NoError(t, beaconState.AppendCurrentEpochAttestations(&pb.PendingAttestation{}))
   457  	err := blocks.VerifyAttestationNoVerifySignature(context.TODO(), beaconState, att)
   458  	require.ErrorContains(t, "committee index 100 >= committee count 1", err)
   459  }
   460  
   461  func TestConvertToIndexed_OK(t *testing.T) {
   462  	helpers.ClearCache()
   463  	validators := make([]*ethpb.Validator, 2*params.BeaconConfig().SlotsPerEpoch)
   464  	for i := 0; i < len(validators); i++ {
   465  		validators[i] = &ethpb.Validator{
   466  			ExitEpoch: params.BeaconConfig().FarFutureEpoch,
   467  		}
   468  	}
   469  
   470  	state, err := v1.InitializeFromProto(&pb.BeaconState{
   471  		Slot:        5,
   472  		Validators:  validators,
   473  		RandaoMixes: make([][]byte, params.BeaconConfig().EpochsPerHistoricalVector),
   474  	})
   475  	require.NoError(t, err)
   476  	tests := []struct {
   477  		aggregationBitfield    bitfield.Bitlist
   478  		wantedAttestingIndices []uint64
   479  	}{
   480  		{
   481  			aggregationBitfield:    bitfield.Bitlist{0x07},
   482  			wantedAttestingIndices: []uint64{43, 47},
   483  		},
   484  		{
   485  			aggregationBitfield:    bitfield.Bitlist{0x05},
   486  			wantedAttestingIndices: []uint64{47},
   487  		},
   488  		{
   489  			aggregationBitfield:    bitfield.Bitlist{0x04},
   490  			wantedAttestingIndices: []uint64{},
   491  		},
   492  	}
   493  
   494  	var sig [96]byte
   495  	copy(sig[:], "signed")
   496  	attestation := testutil.HydrateAttestation(&ethpb.Attestation{
   497  		Signature: sig[:],
   498  	})
   499  	for _, tt := range tests {
   500  		attestation.AggregationBits = tt.aggregationBitfield
   501  		wanted := &ethpb.IndexedAttestation{
   502  			AttestingIndices: tt.wantedAttestingIndices,
   503  			Data:             attestation.Data,
   504  			Signature:        attestation.Signature,
   505  		}
   506  
   507  		committee, err := helpers.BeaconCommitteeFromState(state, attestation.Data.Slot, attestation.Data.CommitteeIndex)
   508  		require.NoError(t, err)
   509  		ia, err := attestationutil.ConvertToIndexed(context.Background(), attestation, committee)
   510  		require.NoError(t, err)
   511  		assert.DeepEqual(t, wanted, ia, "Convert attestation to indexed attestation didn't result as wanted")
   512  	}
   513  }
   514  
   515  func TestVerifyIndexedAttestation_OK(t *testing.T) {
   516  	numOfValidators := uint64(params.BeaconConfig().SlotsPerEpoch.Mul(4))
   517  	validators := make([]*ethpb.Validator, numOfValidators)
   518  	_, keys, err := testutil.DeterministicDepositsAndKeys(numOfValidators)
   519  	require.NoError(t, err)
   520  	for i := 0; i < len(validators); i++ {
   521  		validators[i] = &ethpb.Validator{
   522  			ExitEpoch:             params.BeaconConfig().FarFutureEpoch,
   523  			PublicKey:             keys[i].PublicKey().Marshal(),
   524  			WithdrawalCredentials: make([]byte, 32),
   525  		}
   526  	}
   527  
   528  	state, err := v1.InitializeFromProto(&pb.BeaconState{
   529  		Slot:       5,
   530  		Validators: validators,
   531  		Fork: &pb.Fork{
   532  			Epoch:           0,
   533  			CurrentVersion:  params.BeaconConfig().GenesisForkVersion,
   534  			PreviousVersion: params.BeaconConfig().GenesisForkVersion,
   535  		},
   536  		RandaoMixes: make([][]byte, params.BeaconConfig().EpochsPerHistoricalVector),
   537  	})
   538  	require.NoError(t, err)
   539  	tests := []struct {
   540  		attestation *ethpb.IndexedAttestation
   541  	}{
   542  		{attestation: &ethpb.IndexedAttestation{
   543  			Data: testutil.HydrateAttestationData(&ethpb.AttestationData{
   544  				Target: &ethpb.Checkpoint{
   545  					Epoch: 2,
   546  				},
   547  				Source: &ethpb.Checkpoint{},
   548  			}),
   549  			AttestingIndices: []uint64{1},
   550  			Signature:        make([]byte, 96),
   551  		}},
   552  		{attestation: &ethpb.IndexedAttestation{
   553  			Data: testutil.HydrateAttestationData(&ethpb.AttestationData{
   554  				Target: &ethpb.Checkpoint{
   555  					Epoch: 1,
   556  				},
   557  			}),
   558  			AttestingIndices: []uint64{47, 99, 101},
   559  			Signature:        make([]byte, 96),
   560  		}},
   561  		{attestation: &ethpb.IndexedAttestation{
   562  			Data: testutil.HydrateAttestationData(&ethpb.AttestationData{
   563  				Target: &ethpb.Checkpoint{
   564  					Epoch: 4,
   565  				},
   566  			}),
   567  			AttestingIndices: []uint64{21, 72},
   568  			Signature:        make([]byte, 96),
   569  		}},
   570  		{attestation: &ethpb.IndexedAttestation{
   571  			Data: testutil.HydrateAttestationData(&ethpb.AttestationData{
   572  				Target: &ethpb.Checkpoint{
   573  					Epoch: 7,
   574  				},
   575  			}),
   576  			AttestingIndices: []uint64{100, 121, 122},
   577  			Signature:        make([]byte, 96),
   578  		}},
   579  	}
   580  
   581  	for _, tt := range tests {
   582  		var sig []bls.Signature
   583  		for _, idx := range tt.attestation.AttestingIndices {
   584  			sb, err := helpers.ComputeDomainAndSign(state, tt.attestation.Data.Target.Epoch, tt.attestation.Data, params.BeaconConfig().DomainBeaconAttester, keys[idx])
   585  			require.NoError(t, err)
   586  			validatorSig, err := bls.SignatureFromBytes(sb)
   587  			require.NoError(t, err)
   588  			sig = append(sig, validatorSig)
   589  		}
   590  		aggSig := bls.AggregateSignatures(sig)
   591  		marshalledSig := aggSig.Marshal()
   592  
   593  		tt.attestation.Signature = marshalledSig
   594  
   595  		err = blocks.VerifyIndexedAttestation(context.Background(), state, tt.attestation)
   596  		assert.NoError(t, err, "Failed to verify indexed attestation")
   597  	}
   598  }
   599  
   600  func TestValidateIndexedAttestation_AboveMaxLength(t *testing.T) {
   601  	indexedAtt1 := &ethpb.IndexedAttestation{
   602  		AttestingIndices: make([]uint64, params.BeaconConfig().MaxValidatorsPerCommittee+5),
   603  	}
   604  
   605  	for i := uint64(0); i < params.BeaconConfig().MaxValidatorsPerCommittee+5; i++ {
   606  		indexedAtt1.AttestingIndices[i] = i
   607  		indexedAtt1.Data = &ethpb.AttestationData{
   608  			Target: &ethpb.Checkpoint{
   609  				Epoch: types.Epoch(i),
   610  			},
   611  		}
   612  	}
   613  
   614  	want := "validator indices count exceeds MAX_VALIDATORS_PER_COMMITTEE"
   615  	err := blocks.VerifyIndexedAttestation(context.Background(), &v1.BeaconState{}, indexedAtt1)
   616  	assert.ErrorContains(t, want, err)
   617  }
   618  
   619  func TestValidateIndexedAttestation_BadAttestationsSignatureSet(t *testing.T) {
   620  	beaconState, keys := testutil.DeterministicGenesisState(t, 128)
   621  
   622  	sig := keys[0].Sign([]byte{'t', 'e', 's', 't'})
   623  	list := bitfield.Bitlist{0b11111}
   624  	var atts []*ethpb.Attestation
   625  	for i := uint64(0); i < 1000; i++ {
   626  		atts = append(atts, &ethpb.Attestation{
   627  			Data: &ethpb.AttestationData{
   628  				CommitteeIndex: 1,
   629  				Slot:           1,
   630  			},
   631  			Signature:       sig.Marshal(),
   632  			AggregationBits: list,
   633  		})
   634  	}
   635  
   636  	want := "nil or missing indexed attestation data"
   637  	_, err := blocks.AttestationSignatureSet(context.Background(), beaconState, atts)
   638  	assert.ErrorContains(t, want, err)
   639  
   640  	atts = []*ethpb.Attestation{}
   641  	list = bitfield.Bitlist{0b10000}
   642  	for i := uint64(0); i < 1000; i++ {
   643  		atts = append(atts, &ethpb.Attestation{
   644  			Data: &ethpb.AttestationData{
   645  				CommitteeIndex: 1,
   646  				Slot:           1,
   647  				Target: &ethpb.Checkpoint{
   648  					Root: []byte{},
   649  				},
   650  			},
   651  			Signature:       sig.Marshal(),
   652  			AggregationBits: list,
   653  		})
   654  	}
   655  
   656  	want = "expected non-empty attesting indices"
   657  	_, err = blocks.AttestationSignatureSet(context.Background(), beaconState, atts)
   658  	assert.ErrorContains(t, want, err)
   659  }
   660  
   661  func TestVerifyAttestations_HandlesPlannedFork(t *testing.T) {
   662  	// In this test, att1 is from the prior fork and att2 is from the new fork.
   663  	numOfValidators := uint64(params.BeaconConfig().SlotsPerEpoch.Mul(4))
   664  	validators := make([]*ethpb.Validator, numOfValidators)
   665  	_, keys, err := testutil.DeterministicDepositsAndKeys(numOfValidators)
   666  	require.NoError(t, err)
   667  	for i := 0; i < len(validators); i++ {
   668  		validators[i] = &ethpb.Validator{
   669  			ExitEpoch:             params.BeaconConfig().FarFutureEpoch,
   670  			PublicKey:             keys[i].PublicKey().Marshal(),
   671  			WithdrawalCredentials: make([]byte, 32),
   672  		}
   673  	}
   674  
   675  	st, err := testutil.NewBeaconState()
   676  	require.NoError(t, err)
   677  	require.NoError(t, st.SetSlot(35))
   678  	require.NoError(t, st.SetValidators(validators))
   679  	require.NoError(t, st.SetFork(&pb.Fork{
   680  		Epoch:           1,
   681  		CurrentVersion:  []byte{0, 1, 2, 3},
   682  		PreviousVersion: params.BeaconConfig().GenesisForkVersion,
   683  	}))
   684  
   685  	comm1, err := helpers.BeaconCommitteeFromState(st, 1 /*slot*/, 0 /*committeeIndex*/)
   686  	require.NoError(t, err)
   687  	att1 := testutil.HydrateAttestation(&ethpb.Attestation{
   688  		AggregationBits: bitfield.NewBitlist(uint64(len(comm1))),
   689  		Data: &ethpb.AttestationData{
   690  			Slot: 1,
   691  		},
   692  	})
   693  	prevDomain, err := helpers.Domain(st.Fork(), st.Fork().Epoch-1, params.BeaconConfig().DomainBeaconAttester, st.GenesisValidatorRoot())
   694  	require.NoError(t, err)
   695  	root, err := helpers.ComputeSigningRoot(att1.Data, prevDomain)
   696  	require.NoError(t, err)
   697  	var sigs []bls.Signature
   698  	for i, u := range comm1 {
   699  		att1.AggregationBits.SetBitAt(uint64(i), true)
   700  		sigs = append(sigs, keys[u].Sign(root[:]))
   701  	}
   702  	att1.Signature = bls.AggregateSignatures(sigs).Marshal()
   703  
   704  	comm2, err := helpers.BeaconCommitteeFromState(st, 1*params.BeaconConfig().SlotsPerEpoch+1 /*slot*/, 1 /*committeeIndex*/)
   705  	require.NoError(t, err)
   706  	att2 := testutil.HydrateAttestation(&ethpb.Attestation{
   707  		AggregationBits: bitfield.NewBitlist(uint64(len(comm2))),
   708  		Data: &ethpb.AttestationData{
   709  			Slot:           1*params.BeaconConfig().SlotsPerEpoch + 1,
   710  			CommitteeIndex: 1,
   711  		},
   712  	})
   713  	currDomain, err := helpers.Domain(st.Fork(), st.Fork().Epoch, params.BeaconConfig().DomainBeaconAttester, st.GenesisValidatorRoot())
   714  	require.NoError(t, err)
   715  	root, err = helpers.ComputeSigningRoot(att2.Data, currDomain)
   716  	require.NoError(t, err)
   717  	sigs = nil
   718  	for i, u := range comm2 {
   719  		att2.AggregationBits.SetBitAt(uint64(i), true)
   720  		sigs = append(sigs, keys[u].Sign(root[:]))
   721  	}
   722  	att2.Signature = bls.AggregateSignatures(sigs).Marshal()
   723  }
   724  
   725  func TestRetrieveAttestationSignatureSet_VerifiesMultipleAttestations(t *testing.T) {
   726  	ctx := context.Background()
   727  	numOfValidators := uint64(params.BeaconConfig().SlotsPerEpoch.Mul(4))
   728  	validators := make([]*ethpb.Validator, numOfValidators)
   729  	_, keys, err := testutil.DeterministicDepositsAndKeys(numOfValidators)
   730  	require.NoError(t, err)
   731  	for i := 0; i < len(validators); i++ {
   732  		validators[i] = &ethpb.Validator{
   733  			ExitEpoch:             params.BeaconConfig().FarFutureEpoch,
   734  			PublicKey:             keys[i].PublicKey().Marshal(),
   735  			WithdrawalCredentials: make([]byte, 32),
   736  		}
   737  	}
   738  
   739  	st, err := testutil.NewBeaconState()
   740  	require.NoError(t, err)
   741  	require.NoError(t, st.SetSlot(5))
   742  	require.NoError(t, st.SetValidators(validators))
   743  
   744  	comm1, err := helpers.BeaconCommitteeFromState(st, 1 /*slot*/, 0 /*committeeIndex*/)
   745  	require.NoError(t, err)
   746  	att1 := testutil.HydrateAttestation(&ethpb.Attestation{
   747  		AggregationBits: bitfield.NewBitlist(uint64(len(comm1))),
   748  		Data: &ethpb.AttestationData{
   749  			Slot: 1,
   750  		},
   751  	})
   752  	domain, err := helpers.Domain(st.Fork(), st.Fork().Epoch, params.BeaconConfig().DomainBeaconAttester, st.GenesisValidatorRoot())
   753  	require.NoError(t, err)
   754  	root, err := helpers.ComputeSigningRoot(att1.Data, domain)
   755  	require.NoError(t, err)
   756  	var sigs []bls.Signature
   757  	for i, u := range comm1 {
   758  		att1.AggregationBits.SetBitAt(uint64(i), true)
   759  		sigs = append(sigs, keys[u].Sign(root[:]))
   760  	}
   761  	att1.Signature = bls.AggregateSignatures(sigs).Marshal()
   762  
   763  	comm2, err := helpers.BeaconCommitteeFromState(st, 1 /*slot*/, 1 /*committeeIndex*/)
   764  	require.NoError(t, err)
   765  	att2 := testutil.HydrateAttestation(&ethpb.Attestation{
   766  		AggregationBits: bitfield.NewBitlist(uint64(len(comm2))),
   767  		Data: &ethpb.AttestationData{
   768  			Slot:           1,
   769  			CommitteeIndex: 1,
   770  		},
   771  	})
   772  	root, err = helpers.ComputeSigningRoot(att2.Data, domain)
   773  	require.NoError(t, err)
   774  	sigs = nil
   775  	for i, u := range comm2 {
   776  		att2.AggregationBits.SetBitAt(uint64(i), true)
   777  		sigs = append(sigs, keys[u].Sign(root[:]))
   778  	}
   779  	att2.Signature = bls.AggregateSignatures(sigs).Marshal()
   780  
   781  	set, err := blocks.AttestationSignatureSet(ctx, st, []*ethpb.Attestation{att1, att2})
   782  	require.NoError(t, err)
   783  	verified, err := set.Verify()
   784  	require.NoError(t, err)
   785  	assert.Equal(t, true, verified, "Multiple signatures were unable to be verified.")
   786  }
   787  
   788  func TestRetrieveAttestationSignatureSet_AcrossFork(t *testing.T) {
   789  	ctx := context.Background()
   790  	numOfValidators := uint64(params.BeaconConfig().SlotsPerEpoch.Mul(4))
   791  	validators := make([]*ethpb.Validator, numOfValidators)
   792  	_, keys, err := testutil.DeterministicDepositsAndKeys(numOfValidators)
   793  	require.NoError(t, err)
   794  	for i := 0; i < len(validators); i++ {
   795  		validators[i] = &ethpb.Validator{
   796  			ExitEpoch:             params.BeaconConfig().FarFutureEpoch,
   797  			PublicKey:             keys[i].PublicKey().Marshal(),
   798  			WithdrawalCredentials: make([]byte, 32),
   799  		}
   800  	}
   801  
   802  	st, err := testutil.NewBeaconState()
   803  	require.NoError(t, err)
   804  	require.NoError(t, st.SetSlot(5))
   805  	require.NoError(t, st.SetValidators(validators))
   806  	require.NoError(t, st.SetFork(&pb.Fork{Epoch: 1, CurrentVersion: []byte{0, 1, 2, 3}, PreviousVersion: []byte{0, 1, 1, 1}}))
   807  
   808  	comm1, err := helpers.BeaconCommitteeFromState(st, 1 /*slot*/, 0 /*committeeIndex*/)
   809  	require.NoError(t, err)
   810  	att1 := testutil.HydrateAttestation(&ethpb.Attestation{
   811  		AggregationBits: bitfield.NewBitlist(uint64(len(comm1))),
   812  		Data: &ethpb.AttestationData{
   813  			Slot: 1,
   814  		},
   815  	})
   816  	domain, err := helpers.Domain(st.Fork(), st.Fork().Epoch, params.BeaconConfig().DomainBeaconAttester, st.GenesisValidatorRoot())
   817  	require.NoError(t, err)
   818  	root, err := helpers.ComputeSigningRoot(att1.Data, domain)
   819  	require.NoError(t, err)
   820  	var sigs []bls.Signature
   821  	for i, u := range comm1 {
   822  		att1.AggregationBits.SetBitAt(uint64(i), true)
   823  		sigs = append(sigs, keys[u].Sign(root[:]))
   824  	}
   825  	att1.Signature = bls.AggregateSignatures(sigs).Marshal()
   826  
   827  	comm2, err := helpers.BeaconCommitteeFromState(st, 1 /*slot*/, 1 /*committeeIndex*/)
   828  	require.NoError(t, err)
   829  	att2 := testutil.HydrateAttestation(&ethpb.Attestation{
   830  		AggregationBits: bitfield.NewBitlist(uint64(len(comm2))),
   831  		Data: &ethpb.AttestationData{
   832  			Slot:           1,
   833  			CommitteeIndex: 1,
   834  		},
   835  	})
   836  	root, err = helpers.ComputeSigningRoot(att2.Data, domain)
   837  	require.NoError(t, err)
   838  	sigs = nil
   839  	for i, u := range comm2 {
   840  		att2.AggregationBits.SetBitAt(uint64(i), true)
   841  		sigs = append(sigs, keys[u].Sign(root[:]))
   842  	}
   843  	att2.Signature = bls.AggregateSignatures(sigs).Marshal()
   844  
   845  	_, err = blocks.AttestationSignatureSet(ctx, st, []*ethpb.Attestation{att1, att2})
   846  	require.NoError(t, err)
   847  }