mirror of
https://github.com/OffchainLabs/prysm.git
synced 2026-01-09 21:38:05 -05:00
Don't submit duplicate aggregated SignedContributionAndProof messages (#15571)
This commit is contained in:
3
changelog/radek_duplicate-sync-aggregate.md
Normal file
3
changelog/radek_duplicate-sync-aggregate.md
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Don't submit duplicate `SignedContributionAndProof` messages.
|
||||||
@@ -130,6 +130,7 @@ func (v *validator) SubmitSignedContributionAndProof(ctx context.Context, slot p
|
|||||||
|
|
||||||
v.waitToSlotTwoThirds(ctx, slot)
|
v.waitToSlotTwoThirds(ctx, slot)
|
||||||
|
|
||||||
|
coveredSubnets := make(map[uint64]bool)
|
||||||
for i, comIdx := range indexRes.Indices {
|
for i, comIdx := range indexRes.Indices {
|
||||||
isAggregator, err := altair.IsSyncCommitteeAggregator(selectionProofs[i])
|
isAggregator, err := altair.IsSyncCommitteeAggregator(selectionProofs[i])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -141,6 +142,10 @@ func (v *validator) SubmitSignedContributionAndProof(ctx context.Context, slot p
|
|||||||
}
|
}
|
||||||
subCommitteeSize := params.BeaconConfig().SyncCommitteeSize / params.BeaconConfig().SyncCommitteeSubnetCount
|
subCommitteeSize := params.BeaconConfig().SyncCommitteeSize / params.BeaconConfig().SyncCommitteeSubnetCount
|
||||||
subnet := uint64(comIdx) / subCommitteeSize
|
subnet := uint64(comIdx) / subCommitteeSize
|
||||||
|
if coveredSubnets[subnet] {
|
||||||
|
// Don't submit a message for the same subnet multiple times
|
||||||
|
continue
|
||||||
|
}
|
||||||
contribution, err := v.validatorClient.SyncCommitteeContribution(ctx, ðpb.SyncCommitteeContributionRequest{
|
contribution, err := v.validatorClient.SyncCommitteeContribution(ctx, ðpb.SyncCommitteeContributionRequest{
|
||||||
Slot: slot,
|
Slot: slot,
|
||||||
PublicKey: pubKey[:],
|
PublicKey: pubKey[:],
|
||||||
@@ -178,6 +183,8 @@ func (v *validator) SubmitSignedContributionAndProof(ctx context.Context, slot p
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
coveredSubnets[subnet] = true
|
||||||
|
|
||||||
contributionSlot := contributionAndProof.Contribution.Slot
|
contributionSlot := contributionAndProof.Contribution.Slot
|
||||||
slotTime, err := slots.StartTime(v.genesisTime, contributionSlot)
|
slotTime, err := slots.StartTime(v.genesisTime, contributionSlot)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -512,3 +512,87 @@ func TestSubmitSignedContributionAndProof_Ok(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 = ðpb.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
|
||||||
|
ðpb.SyncSubcommitteeIndexRequest{
|
||||||
|
Slot: 1,
|
||||||
|
PublicKey: pubKey[:],
|
||||||
|
},
|
||||||
|
).Return(ðpb.SyncSubcommitteeIndexResponse{Indices: aggregatorCommitteeIndices}, nil)
|
||||||
|
|
||||||
|
m.validatorClient.EXPECT().
|
||||||
|
DomainData(gomock.Any(), // ctx
|
||||||
|
gomock.Any()). // epoch
|
||||||
|
Times(2).
|
||||||
|
Return(ðpb.DomainResponse{
|
||||||
|
SignatureDomain: make([]byte, 32),
|
||||||
|
}, nil)
|
||||||
|
|
||||||
|
aggBits := bitfield.NewBitvector128()
|
||||||
|
aggBits.SetBitAt(0, true)
|
||||||
|
m.validatorClient.EXPECT().SyncCommitteeContribution(
|
||||||
|
gomock.Any(), // ctx
|
||||||
|
ðpb.SyncCommitteeContributionRequest{
|
||||||
|
Slot: 1,
|
||||||
|
PublicKey: pubKey[:],
|
||||||
|
SubnetId: 0,
|
||||||
|
},
|
||||||
|
).Return(ðpb.SyncCommitteeContribution{
|
||||||
|
BlockRoot: make([]byte, fieldparams.RootLength),
|
||||||
|
Signature: make([]byte, 96),
|
||||||
|
AggregationBits: aggBits,
|
||||||
|
}, nil)
|
||||||
|
|
||||||
|
m.validatorClient.EXPECT().
|
||||||
|
DomainData(gomock.Any(), // ctx
|
||||||
|
gomock.Any()). // epoch
|
||||||
|
Return(ðpb.DomainResponse{
|
||||||
|
SignatureDomain: make([]byte, 32),
|
||||||
|
}, nil)
|
||||||
|
|
||||||
|
m.validatorClient.EXPECT().SubmitSignedContributionAndProof(
|
||||||
|
gomock.Any(), // ctx
|
||||||
|
gomock.AssignableToTypeOf(ðpb.SignedContributionAndProof{
|
||||||
|
Message: ðpb.ContributionAndProof{
|
||||||
|
AggregatorIndex: 7,
|
||||||
|
Contribution: ðpb.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)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user