Files
prysm/validator/client/sync_committee_test.go
Bastin 92bd211e4d upgrade v6 to v7 (#15989)
* upgrade v6 to v7

* changelog

* update-go-ssz
2025-11-06 16:16:23 +00:00

599 lines
22 KiB
Go

package client
import (
"context"
"encoding/hex"
"fmt"
"testing"
"github.com/OffchainLabs/go-bitfield"
fieldparams "github.com/OffchainLabs/prysm/v7/config/fieldparams"
"github.com/OffchainLabs/prysm/v7/consensus-types/primitives"
"github.com/OffchainLabs/prysm/v7/crypto/bls"
"github.com/OffchainLabs/prysm/v7/encoding/bytesutil"
ethpb "github.com/OffchainLabs/prysm/v7/proto/prysm/v1alpha1"
"github.com/OffchainLabs/prysm/v7/testing/assert"
"github.com/OffchainLabs/prysm/v7/testing/require"
"github.com/pkg/errors"
logTest "github.com/sirupsen/logrus/hooks/test"
"go.uber.org/mock/gomock"
"google.golang.org/protobuf/types/known/emptypb"
)
func TestSubmitSyncCommitteeMessage_ValidatorDutiesRequestFailure(t *testing.T) {
for _, isSlashingProtectionMinimal := range [...]bool{false, true} {
t.Run(fmt.Sprintf("SlashingProtectionMinimal:%v", isSlashingProtectionMinimal), func(t *testing.T) {
hook := logTest.NewGlobal()
validator, m, validatorKey, finish := setup(t, isSlashingProtectionMinimal)
validator.duties = &ethpb.ValidatorDutiesContainer{CurrentEpochDuties: []*ethpb.ValidatorDuty{}}
defer finish()
m.validatorClient.EXPECT().SyncMessageBlockRoot(
gomock.Any(), // ctx
&emptypb.Empty{},
).Return(&ethpb.SyncMessageBlockRootResponse{
Root: bytesutil.PadTo([]byte{}, 32),
}, nil)
var pubKey [fieldparams.BLSPubkeyLength]byte
copy(pubKey[:], validatorKey.PublicKey().Marshal())
validator.SubmitSyncCommitteeMessage(t.Context(), 1, pubKey)
require.LogsContain(t, hook, "Could not fetch validator assignment")
})
}
}
func TestSubmitSyncCommitteeMessage_BadDomainData(t *testing.T) {
for _, isSlashingProtectionMinimal := range [...]bool{false, true} {
t.Run(fmt.Sprintf("SlashingProtectionMinimal:%v", isSlashingProtectionMinimal), func(t *testing.T) {
validator, m, validatorKey, finish := setup(t, isSlashingProtectionMinimal)
defer finish()
hook := logTest.NewGlobal()
validatorIndex := primitives.ValidatorIndex(7)
committee := []primitives.ValidatorIndex{0, 3, 4, 2, validatorIndex, 6, 8, 9, 10}
validator.duties = &ethpb.ValidatorDutiesContainer{CurrentEpochDuties: []*ethpb.ValidatorDuty{
{
PublicKey: validatorKey.PublicKey().Marshal(),
CommitteeLength: uint64(len(committee)),
ValidatorIndex: validatorIndex,
},
}}
r := []byte{'a'}
m.validatorClient.EXPECT().SyncMessageBlockRoot(
gomock.Any(), // ctx
&emptypb.Empty{},
).Return(&ethpb.SyncMessageBlockRootResponse{
Root: bytesutil.PadTo(r, 32),
}, nil)
m.validatorClient.EXPECT().
DomainData(gomock.Any(), gomock.Any()).
Return(nil, errors.New("uh oh"))
var pubKey [fieldparams.BLSPubkeyLength]byte
copy(pubKey[:], validatorKey.PublicKey().Marshal())
validator.SubmitSyncCommitteeMessage(t.Context(), 1, pubKey)
require.LogsContain(t, hook, "Could not get sync committee domain data")
})
}
}
func TestSubmitSyncCommitteeMessage_CouldNotSubmit(t *testing.T) {
for _, isSlashingProtectionMinimal := range [...]bool{false, true} {
t.Run(fmt.Sprintf("SlashingProtectionMinimal:%v", isSlashingProtectionMinimal), func(t *testing.T) {
validator, m, validatorKey, finish := setup(t, isSlashingProtectionMinimal)
defer finish()
hook := logTest.NewGlobal()
validatorIndex := primitives.ValidatorIndex(7)
committee := []primitives.ValidatorIndex{0, 3, 4, 2, validatorIndex, 6, 8, 9, 10}
validator.duties = &ethpb.ValidatorDutiesContainer{CurrentEpochDuties: []*ethpb.ValidatorDuty{
{
PublicKey: validatorKey.PublicKey().Marshal(),
CommitteeLength: uint64(len(committee)),
ValidatorIndex: validatorIndex,
},
}}
r := []byte{'a'}
m.validatorClient.EXPECT().SyncMessageBlockRoot(
gomock.Any(), // ctx
&emptypb.Empty{},
).Return(&ethpb.SyncMessageBlockRootResponse{
Root: bytesutil.PadTo(r, 32),
}, nil)
m.validatorClient.EXPECT().
DomainData(gomock.Any(), // ctx
gomock.Any()). // epoch
Return(&ethpb.DomainResponse{
SignatureDomain: make([]byte, 32),
}, nil)
m.validatorClient.EXPECT().SubmitSyncMessage(
gomock.Any(), // ctx
gomock.AssignableToTypeOf(&ethpb.SyncCommitteeMessage{}),
).Return(&emptypb.Empty{}, errors.New("uh oh") /* error */)
var pubKey [fieldparams.BLSPubkeyLength]byte
copy(pubKey[:], validatorKey.PublicKey().Marshal())
validator.SubmitSyncCommitteeMessage(t.Context(), 1, pubKey)
require.LogsContain(t, hook, "Could not submit sync committee message")
})
}
}
func TestSubmitSyncCommitteeMessage_OK(t *testing.T) {
for _, isSlashingProtectionMinimal := range [...]bool{false, true} {
t.Run(fmt.Sprintf("SlashingProtectionMinimal:%v", isSlashingProtectionMinimal), func(t *testing.T) {
validator, m, validatorKey, finish := setup(t, isSlashingProtectionMinimal)
defer finish()
hook := logTest.NewGlobal()
validatorIndex := primitives.ValidatorIndex(7)
committee := []primitives.ValidatorIndex{0, 3, 4, 2, validatorIndex, 6, 8, 9, 10}
validator.duties = &ethpb.ValidatorDutiesContainer{CurrentEpochDuties: []*ethpb.ValidatorDuty{
{
PublicKey: validatorKey.PublicKey().Marshal(),
CommitteeLength: uint64(len(committee)),
ValidatorIndex: validatorIndex,
},
}}
r := []byte{'a'}
m.validatorClient.EXPECT().SyncMessageBlockRoot(
gomock.Any(), // ctx
&emptypb.Empty{},
).Return(&ethpb.SyncMessageBlockRootResponse{
Root: bytesutil.PadTo(r, 32),
}, nil)
m.validatorClient.EXPECT().
DomainData(gomock.Any(), // ctx
gomock.Any()). // epoch
Return(&ethpb.DomainResponse{
SignatureDomain: make([]byte, 32),
}, nil)
var generatedMsg *ethpb.SyncCommitteeMessage
m.validatorClient.EXPECT().SubmitSyncMessage(
gomock.Any(), // ctx
gomock.AssignableToTypeOf(&ethpb.SyncCommitteeMessage{}),
).Do(func(_ context.Context, msg *ethpb.SyncCommitteeMessage) {
generatedMsg = msg
}).Return(&emptypb.Empty{}, nil /* error */)
var pubKey [fieldparams.BLSPubkeyLength]byte
copy(pubKey[:], validatorKey.PublicKey().Marshal())
validator.SubmitSyncCommitteeMessage(t.Context(), 1, pubKey)
require.LogsDoNotContain(t, hook, "Could not")
require.Equal(t, primitives.Slot(1), generatedMsg.Slot)
require.Equal(t, validatorIndex, generatedMsg.ValidatorIndex)
require.DeepEqual(t, bytesutil.PadTo(r, 32), generatedMsg.BlockRoot)
})
}
}
func TestSubmitSignedContributionAndProof_ValidatorDutiesRequestFailure(t *testing.T) {
for _, isSlashingProtectionMinimal := range [...]bool{false, true} {
t.Run(fmt.Sprintf("SlashingProtectionMinimal:%v", isSlashingProtectionMinimal), func(t *testing.T) {
hook := logTest.NewGlobal()
validator, _, validatorKey, finish := setup(t, isSlashingProtectionMinimal)
validator.duties = &ethpb.ValidatorDutiesContainer{CurrentEpochDuties: []*ethpb.ValidatorDuty{}}
defer finish()
var pubKey [fieldparams.BLSPubkeyLength]byte
copy(pubKey[:], validatorKey.PublicKey().Marshal())
validator.SubmitSignedContributionAndProof(t.Context(), 1, pubKey)
require.LogsContain(t, hook, "Could not fetch validator assignment")
})
}
}
func TestSubmitSignedContributionAndProof_SyncSubcommitteeIndexFailure(t *testing.T) {
for _, isSlashingProtectionMinimal := range [...]bool{false, true} {
t.Run(fmt.Sprintf("SlashingProtectionMinimal:%v", isSlashingProtectionMinimal), func(t *testing.T) {
hook := logTest.NewGlobal()
validator, m, validatorKey, finish := setup(t, isSlashingProtectionMinimal)
validatorIndex := primitives.ValidatorIndex(7)
committee := []primitives.ValidatorIndex{0, 3, 4, 2, validatorIndex, 6, 8, 9, 10}
validator.duties = &ethpb.ValidatorDutiesContainer{CurrentEpochDuties: []*ethpb.ValidatorDuty{
{
PublicKey: validatorKey.PublicKey().Marshal(),
CommitteeLength: uint64(len(committee)),
ValidatorIndex: validatorIndex,
},
}}
defer finish()
var pubKey [fieldparams.BLSPubkeyLength]byte
copy(pubKey[:], validatorKey.PublicKey().Marshal())
m.validatorClient.EXPECT().SyncSubcommitteeIndex(
gomock.Any(), // ctx
&ethpb.SyncSubcommitteeIndexRequest{
Slot: 1,
PublicKey: pubKey[:],
},
).Return(&ethpb.SyncSubcommitteeIndexResponse{}, errors.New("Bad index"))
validator.SubmitSignedContributionAndProof(t.Context(), 1, pubKey)
require.LogsContain(t, hook, "Could not get sync subcommittee index")
})
}
}
func TestSubmitSignedContributionAndProof_NothingToDo(t *testing.T) {
for _, isSlashingProtectionMinimal := range [...]bool{false, true} {
t.Run(fmt.Sprintf("SlashingProtectionMinimal:%v", isSlashingProtectionMinimal), func(t *testing.T) {
hook := logTest.NewGlobal()
validator, m, validatorKey, finish := setup(t, isSlashingProtectionMinimal)
validatorIndex := primitives.ValidatorIndex(7)
committee := []primitives.ValidatorIndex{0, 3, 4, 2, validatorIndex, 6, 8, 9, 10}
validator.duties = &ethpb.ValidatorDutiesContainer{CurrentEpochDuties: []*ethpb.ValidatorDuty{
{
PublicKey: validatorKey.PublicKey().Marshal(),
CommitteeLength: uint64(len(committee)),
ValidatorIndex: validatorIndex,
},
}}
defer finish()
var pubKey [fieldparams.BLSPubkeyLength]byte
copy(pubKey[:], validatorKey.PublicKey().Marshal())
m.validatorClient.EXPECT().SyncSubcommitteeIndex(
gomock.Any(), // ctx
&ethpb.SyncSubcommitteeIndexRequest{
Slot: 1,
PublicKey: pubKey[:],
},
).Return(&ethpb.SyncSubcommitteeIndexResponse{Indices: []primitives.CommitteeIndex{}}, nil)
validator.SubmitSignedContributionAndProof(t.Context(), 1, pubKey)
require.LogsContain(t, hook, "Empty subcommittee index list, do nothing")
})
}
}
func TestSubmitSignedContributionAndProof_BadDomain(t *testing.T) {
for _, isSlashingProtectionMinimal := range [...]bool{false, true} {
t.Run(fmt.Sprintf("SlashingProtectionMinimal:%v", isSlashingProtectionMinimal), func(t *testing.T) {
hook := logTest.NewGlobal()
validator, m, validatorKey, finish := setup(t, isSlashingProtectionMinimal)
validatorIndex := primitives.ValidatorIndex(7)
committee := []primitives.ValidatorIndex{0, 3, 4, 2, validatorIndex, 6, 8, 9, 10}
validator.duties = &ethpb.ValidatorDutiesContainer{CurrentEpochDuties: []*ethpb.ValidatorDuty{
{
PublicKey: validatorKey.PublicKey().Marshal(),
CommitteeLength: uint64(len(committee)),
ValidatorIndex: validatorIndex,
},
}}
defer finish()
var pubKey [fieldparams.BLSPubkeyLength]byte
copy(pubKey[:], validatorKey.PublicKey().Marshal())
m.validatorClient.EXPECT().SyncSubcommitteeIndex(
gomock.Any(), // ctx
&ethpb.SyncSubcommitteeIndexRequest{
Slot: 1,
PublicKey: pubKey[:],
},
).Return(&ethpb.SyncSubcommitteeIndexResponse{Indices: []primitives.CommitteeIndex{1}}, nil)
m.validatorClient.EXPECT().
DomainData(gomock.Any(), // ctx
gomock.Any()). // epoch
Return(&ethpb.DomainResponse{
SignatureDomain: make([]byte, 32),
}, errors.New("bad domain response"))
validator.SubmitSignedContributionAndProof(t.Context(), 1, pubKey)
require.LogsContain(t, hook, "Could not get selection proofs")
require.LogsContain(t, hook, "bad domain response")
})
}
}
func TestSubmitSignedContributionAndProof_CouldNotGetContribution(t *testing.T) {
hook := logTest.NewGlobal()
// Hardcode secret key in order to have a valid aggregator signature.
rawKey, err := hex.DecodeString("659e875e1b062c03f2f2a57332974d475b97df6cfc581d322e79642d39aca8fd")
assert.NoError(t, err)
validatorKey, err := bls.SecretKeyFromBytes(rawKey)
assert.NoError(t, err)
for _, isSlashingProtectionMinimal := range [...]bool{false, true} {
t.Run(fmt.Sprintf("SlashingProtectionMinimal:%v", isSlashingProtectionMinimal), func(t *testing.T) {
validator, m, validatorKey, finish := setupWithKey(t, validatorKey, isSlashingProtectionMinimal)
validatorIndex := primitives.ValidatorIndex(7)
committee := []primitives.ValidatorIndex{0, 3, 4, 2, validatorIndex, 6, 8, 9, 10}
validator.duties = &ethpb.ValidatorDutiesContainer{CurrentEpochDuties: []*ethpb.ValidatorDuty{
{
PublicKey: validatorKey.PublicKey().Marshal(),
CommitteeLength: uint64(len(committee)),
ValidatorIndex: validatorIndex,
},
}}
defer finish()
var pubKey [fieldparams.BLSPubkeyLength]byte
copy(pubKey[:], validatorKey.PublicKey().Marshal())
m.validatorClient.EXPECT().SyncSubcommitteeIndex(
gomock.Any(), // ctx
&ethpb.SyncSubcommitteeIndexRequest{
Slot: 1,
PublicKey: pubKey[:],
},
).Return(&ethpb.SyncSubcommitteeIndexResponse{Indices: []primitives.CommitteeIndex{1}}, nil)
m.validatorClient.EXPECT().
DomainData(gomock.Any(), // ctx
gomock.Any()). // epoch
Return(&ethpb.DomainResponse{
SignatureDomain: make([]byte, 32),
}, nil)
m.validatorClient.EXPECT().SyncCommitteeContribution(
gomock.Any(), // ctx
&ethpb.SyncCommitteeContributionRequest{
Slot: 1,
PublicKey: pubKey[:],
SubnetId: 0,
},
).Return(nil, errors.New("Bad contribution"))
validator.SubmitSignedContributionAndProof(t.Context(), 1, pubKey)
require.LogsContain(t, hook, "Could not get sync committee contribution")
})
}
}
func TestSubmitSignedContributionAndProof_CouldNotSubmitContribution(t *testing.T) {
hook := logTest.NewGlobal()
// Hardcode secret key in order to have a valid aggregator signature.
rawKey, err := hex.DecodeString("659e875e1b062c03f2f2a57332974d475b97df6cfc581d322e79642d39aca8fd")
assert.NoError(t, err)
validatorKey, err := bls.SecretKeyFromBytes(rawKey)
assert.NoError(t, err)
for _, isSlashingProtectionMinimal := range [...]bool{false, true} {
t.Run(fmt.Sprintf("SlashingProtectionMinimal:%v", isSlashingProtectionMinimal), func(t *testing.T) {
validator, m, validatorKey, finish := setupWithKey(t, validatorKey, isSlashingProtectionMinimal)
validatorIndex := primitives.ValidatorIndex(7)
committee := []primitives.ValidatorIndex{0, 3, 4, 2, validatorIndex, 6, 8, 9, 10}
validator.duties = &ethpb.ValidatorDutiesContainer{CurrentEpochDuties: []*ethpb.ValidatorDuty{
{
PublicKey: validatorKey.PublicKey().Marshal(),
CommitteeLength: uint64(len(committee)),
ValidatorIndex: validatorIndex,
},
}}
defer finish()
var pubKey [fieldparams.BLSPubkeyLength]byte
copy(pubKey[:], validatorKey.PublicKey().Marshal())
m.validatorClient.EXPECT().SyncSubcommitteeIndex(
gomock.Any(), // ctx
&ethpb.SyncSubcommitteeIndexRequest{
Slot: 1,
PublicKey: pubKey[:],
},
).Return(&ethpb.SyncSubcommitteeIndexResponse{Indices: []primitives.CommitteeIndex{1}}, nil)
m.validatorClient.EXPECT().
DomainData(gomock.Any(), // ctx
gomock.Any()). // epoch
Return(&ethpb.DomainResponse{
SignatureDomain: make([]byte, 32),
}, nil)
aggBits := bitfield.NewBitvector128()
aggBits.SetBitAt(0, true)
m.validatorClient.EXPECT().SyncCommitteeContribution(
gomock.Any(), // ctx
&ethpb.SyncCommitteeContributionRequest{
Slot: 1,
PublicKey: pubKey[:],
SubnetId: 0,
},
).Return(&ethpb.SyncCommitteeContribution{
BlockRoot: make([]byte, fieldparams.RootLength),
Signature: make([]byte, 96),
AggregationBits: aggBits,
}, nil)
m.validatorClient.EXPECT().
DomainData(gomock.Any(), // ctx
gomock.Any()). // epoch
Return(&ethpb.DomainResponse{
SignatureDomain: make([]byte, 32),
}, nil)
m.validatorClient.EXPECT().SubmitSignedContributionAndProof(
gomock.Any(), // ctx
gomock.AssignableToTypeOf(&ethpb.SignedContributionAndProof{
Message: &ethpb.ContributionAndProof{
AggregatorIndex: 7,
Contribution: &ethpb.SyncCommitteeContribution{
BlockRoot: make([]byte, fieldparams.RootLength),
Signature: make([]byte, 96),
AggregationBits: bitfield.NewBitvector128(),
Slot: 1,
SubcommitteeIndex: 1,
},
},
}),
).Return(&emptypb.Empty{}, errors.New("Could not submit contribution"))
validator.SubmitSignedContributionAndProof(t.Context(), 1, pubKey)
require.LogsContain(t, hook, "Could not submit signed contribution and proof")
})
}
}
func TestSubmitSignedContributionAndProof_Ok(t *testing.T) {
// Hardcode secret key in order to have a valid aggregator signature.
rawKey, err := hex.DecodeString("659e875e1b062c03f2f2a57332974d475b97df6cfc581d322e79642d39aca8fd")
assert.NoError(t, err)
validatorKey, err := bls.SecretKeyFromBytes(rawKey)
assert.NoError(t, err)
for _, isSlashingProtectionMinimal := range [...]bool{false, true} {
t.Run(fmt.Sprintf("SlashingProtectionMinimal:%v", isSlashingProtectionMinimal), func(t *testing.T) {
validator, m, validatorKey, finish := setupWithKey(t, validatorKey, isSlashingProtectionMinimal)
validatorIndex := primitives.ValidatorIndex(7)
committee := []primitives.ValidatorIndex{0, 3, 4, 2, validatorIndex, 6, 8, 9, 10}
validator.duties = &ethpb.ValidatorDutiesContainer{CurrentEpochDuties: []*ethpb.ValidatorDuty{
{
PublicKey: validatorKey.PublicKey().Marshal(),
CommitteeLength: uint64(len(committee)),
ValidatorIndex: validatorIndex,
},
}}
defer finish()
var pubKey [fieldparams.BLSPubkeyLength]byte
copy(pubKey[:], validatorKey.PublicKey().Marshal())
m.validatorClient.EXPECT().SyncSubcommitteeIndex(
gomock.Any(), // ctx
&ethpb.SyncSubcommitteeIndexRequest{
Slot: 1,
PublicKey: pubKey[:],
},
).Return(&ethpb.SyncSubcommitteeIndexResponse{Indices: []primitives.CommitteeIndex{1}}, nil)
m.validatorClient.EXPECT().
DomainData(gomock.Any(), // ctx
gomock.Any()). // epoch
Return(&ethpb.DomainResponse{
SignatureDomain: make([]byte, 32),
}, nil)
aggBits := bitfield.NewBitvector128()
aggBits.SetBitAt(0, true)
m.validatorClient.EXPECT().SyncCommitteeContribution(
gomock.Any(), // ctx
&ethpb.SyncCommitteeContributionRequest{
Slot: 1,
PublicKey: pubKey[:],
SubnetId: 0,
},
).Return(&ethpb.SyncCommitteeContribution{
BlockRoot: make([]byte, fieldparams.RootLength),
Signature: make([]byte, 96),
AggregationBits: aggBits,
}, nil)
m.validatorClient.EXPECT().
DomainData(gomock.Any(), // ctx
gomock.Any()). // epoch
Return(&ethpb.DomainResponse{
SignatureDomain: make([]byte, 32),
}, nil)
m.validatorClient.EXPECT().SubmitSignedContributionAndProof(
gomock.Any(), // ctx
gomock.AssignableToTypeOf(&ethpb.SignedContributionAndProof{
Message: &ethpb.ContributionAndProof{
AggregatorIndex: 7,
Contribution: &ethpb.SyncCommitteeContribution{
BlockRoot: make([]byte, 32),
Signature: make([]byte, 96),
AggregationBits: bitfield.NewBitvector128(),
Slot: 1,
SubcommitteeIndex: 1,
},
},
}),
).Return(&emptypb.Empty{}, nil)
validator.SubmitSignedContributionAndProof(t.Context(), 1, pubKey)
})
}
}
func TestSubmitSignedContributionAndProof_OncePerPubkeyAndSubcommittee(t *testing.T) {
// Hardcode secret key in order to have a valid aggregator signature.
rawKey, err := hex.DecodeString("659e875e1b062c03f2f2a57332974d475b97df6cfc581d322e79642d39aca8fd")
assert.NoError(t, err)
validatorKey, err := bls.SecretKeyFromBytes(rawKey)
assert.NoError(t, err)
for _, isSlashingProtectionMinimal := range [...]bool{false, true} {
t.Run(fmt.Sprintf("SlashingProtectionMinimal:%v", isSlashingProtectionMinimal), func(t *testing.T) {
validator, m, validatorKey, finish := setupWithKey(t, validatorKey, isSlashingProtectionMinimal)
validatorIndex := primitives.ValidatorIndex(7)
committee := []primitives.ValidatorIndex{0, 3, 4, 2, validatorIndex, 6, 8, 9, 10}
validator.duties = &ethpb.ValidatorDutiesContainer{CurrentEpochDuties: []*ethpb.ValidatorDuty{
{
PublicKey: validatorKey.PublicKey().Marshal(),
CommitteeLength: uint64(len(committee)),
ValidatorIndex: validatorIndex,
},
}}
defer finish()
// Sync committee aggregator is selected twice in the sync committee
aggregatorCommitteeIndices := []primitives.CommitteeIndex{1, 2}
var pubKey [fieldparams.BLSPubkeyLength]byte
copy(pubKey[:], validatorKey.PublicKey().Marshal())
m.validatorClient.EXPECT().SyncSubcommitteeIndex(
gomock.Any(), // ctx
&ethpb.SyncSubcommitteeIndexRequest{
Slot: 1,
PublicKey: pubKey[:],
},
).Return(&ethpb.SyncSubcommitteeIndexResponse{Indices: aggregatorCommitteeIndices}, nil)
m.validatorClient.EXPECT().
DomainData(gomock.Any(), // ctx
gomock.Any()). // epoch
Times(2).
Return(&ethpb.DomainResponse{
SignatureDomain: make([]byte, 32),
}, nil)
aggBits := bitfield.NewBitvector128()
aggBits.SetBitAt(0, true)
m.validatorClient.EXPECT().SyncCommitteeContribution(
gomock.Any(), // ctx
&ethpb.SyncCommitteeContributionRequest{
Slot: 1,
PublicKey: pubKey[:],
SubnetId: 0,
},
).Return(&ethpb.SyncCommitteeContribution{
BlockRoot: make([]byte, fieldparams.RootLength),
Signature: make([]byte, 96),
AggregationBits: aggBits,
}, nil)
m.validatorClient.EXPECT().
DomainData(gomock.Any(), // ctx
gomock.Any()). // epoch
Return(&ethpb.DomainResponse{
SignatureDomain: make([]byte, 32),
}, nil)
m.validatorClient.EXPECT().SubmitSignedContributionAndProof(
gomock.Any(), // ctx
gomock.AssignableToTypeOf(&ethpb.SignedContributionAndProof{
Message: &ethpb.ContributionAndProof{
AggregatorIndex: 7,
Contribution: &ethpb.SyncCommitteeContribution{
BlockRoot: make([]byte, 32),
Signature: make([]byte, 96),
AggregationBits: bitfield.NewBitvector128(),
Slot: 1,
SubcommitteeIndex: 1,
},
},
}),
).Return(&emptypb.Empty{}, nil)
validator.SubmitSignedContributionAndProof(t.Context(), 1, pubKey)
})
}
}