mirror of
https://github.com/OffchainLabs/prysm.git
synced 2026-01-09 13:28:01 -05:00
Electra attestation interfaces (#13937)
* config values * block protos * get_committee_indices * proto and ssz * attestation interface * Revert "Auxiliary commit to revert individual files from deadb2183723511721b3288c7168808a4fa97c64" This reverts commit 32ad5009537bc5ec0e6caf9f52143d380d00be85. * todos * get_attesting_indices * Revert "Auxiliary commit to revert individual files from dd2789723f90b15eb1f874b561d88d11dcc9c0bf" This reverts commit f39644ed3cb6f3964fc6c86fdf4bd5de2a9668c8. * beacon spec changes * Fix pending attestation. Build ok * Electra: add electra version * Electra: consensus types * gocognit exclusion * @potuz's suggestion * build fix * interfaces for indexed att and slashing * indexed att usage * BuildSignedBeaconBlockFromExecutionPayload * slashing usage * grpc stubs * remove unused methods * Electra attestation interfaces * cleanup * tests * make linter happy * simple casting * test fixes * Fix spectest failures * Regen pb and ssz files * Handle "not ok" type assertion cases * Setters that check version should always return an error. SetAttesterSlashings and SetAttestations * gofmt * Fix TestMinSpanChunksSlice_CheckSlashable --------- Co-authored-by: terence tsao <terence@prysmaticlabs.com> Co-authored-by: Preston Van Loon <preston@pvl.dev>
This commit is contained in:
@@ -401,7 +401,7 @@ func (s *Service) saveOrphanedOperations(ctx context.Context, orphanedRoot [32]b
|
||||
}
|
||||
for _, a := range orphanedBlk.Block().Body().Attestations() {
|
||||
// if the attestation is one epoch older, it wouldn't been useful to save it.
|
||||
if a.Data.Slot+params.BeaconConfig().SlotsPerEpoch < s.CurrentSlot() {
|
||||
if a.GetData().Slot+params.BeaconConfig().SlotsPerEpoch < s.CurrentSlot() {
|
||||
continue
|
||||
}
|
||||
if helpers.IsAggregated(a) {
|
||||
|
||||
@@ -13,6 +13,7 @@ import (
|
||||
"github.com/prysmaticlabs/prysm/v5/beacon-chain/operations/blstoexec"
|
||||
"github.com/prysmaticlabs/prysm/v5/config/params"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/blocks"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/interfaces"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
|
||||
"github.com/prysmaticlabs/prysm/v5/encoding/bytesutil"
|
||||
ethpbv1 "github.com/prysmaticlabs/prysm/v5/proto/eth/v1"
|
||||
@@ -312,14 +313,14 @@ func TestSaveOrphanedAtts(t *testing.T) {
|
||||
|
||||
require.NoError(t, service.saveOrphanedOperations(ctx, r3, r4))
|
||||
require.Equal(t, 3, service.cfg.AttPool.AggregatedAttestationCount())
|
||||
wantAtts := []*ethpb.Attestation{
|
||||
wantAtts := []interfaces.Attestation{
|
||||
blk3.Block.Body.Attestations[0],
|
||||
blk2.Block.Body.Attestations[0],
|
||||
blk1.Block.Body.Attestations[0],
|
||||
}
|
||||
atts := service.cfg.AttPool.AggregatedAttestations()
|
||||
sort.Slice(atts, func(i, j int) bool {
|
||||
return atts[i].Data.Slot > atts[j].Data.Slot
|
||||
return atts[i].GetData().Slot > atts[j].GetData().Slot
|
||||
})
|
||||
require.DeepEqual(t, wantAtts, atts)
|
||||
}
|
||||
@@ -389,14 +390,14 @@ func TestSaveOrphanedOps(t *testing.T) {
|
||||
|
||||
require.NoError(t, service.saveOrphanedOperations(ctx, r3, r4))
|
||||
require.Equal(t, 3, service.cfg.AttPool.AggregatedAttestationCount())
|
||||
wantAtts := []*ethpb.Attestation{
|
||||
wantAtts := []interfaces.Attestation{
|
||||
blk3.Block.Body.Attestations[0],
|
||||
blk2.Block.Body.Attestations[0],
|
||||
blk1.Block.Body.Attestations[0],
|
||||
}
|
||||
atts := service.cfg.AttPool.AggregatedAttestations()
|
||||
sort.Slice(atts, func(i, j int) bool {
|
||||
return atts[i].Data.Slot > atts[j].Data.Slot
|
||||
return atts[i].GetData().Slot > atts[j].GetData().Slot
|
||||
})
|
||||
require.DeepEqual(t, wantAtts, atts)
|
||||
require.Equal(t, 1, len(service.cfg.SlashingPool.PendingProposerSlashings(ctx, st, false)))
|
||||
@@ -517,14 +518,14 @@ func TestSaveOrphanedAtts_DoublyLinkedTrie(t *testing.T) {
|
||||
|
||||
require.NoError(t, service.saveOrphanedOperations(ctx, r3, r4))
|
||||
require.Equal(t, 3, service.cfg.AttPool.AggregatedAttestationCount())
|
||||
wantAtts := []*ethpb.Attestation{
|
||||
wantAtts := []interfaces.Attestation{
|
||||
blk3.Block.Body.Attestations[0],
|
||||
blk2.Block.Body.Attestations[0],
|
||||
blk1.Block.Body.Attestations[0],
|
||||
}
|
||||
atts := service.cfg.AttPool.AggregatedAttestations()
|
||||
sort.Slice(atts, func(i, j int) bool {
|
||||
return atts[i].Data.Slot > atts[j].Data.Slot
|
||||
return atts[i].GetData().Slot > atts[j].GetData().Slot
|
||||
})
|
||||
require.DeepEqual(t, wantAtts, atts)
|
||||
}
|
||||
|
||||
@@ -369,6 +369,6 @@ func reportEpochMetrics(ctx context.Context, postState, headState state.BeaconSt
|
||||
|
||||
func reportAttestationInclusion(blk interfaces.ReadOnlyBeaconBlock) {
|
||||
for _, att := range blk.Body().Attestations() {
|
||||
attestationInclusionDelay.Observe(float64(blk.Slot() - att.Data.Slot))
|
||||
attestationInclusionDelay.Observe(float64(blk.Slot() - att.GetData().Slot))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/prysmaticlabs/prysm/v5/beacon-chain/core/helpers"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/interfaces"
|
||||
"github.com/prysmaticlabs/prysm/v5/encoding/bytesutil"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1/attestation"
|
||||
@@ -36,17 +37,17 @@ import (
|
||||
//
|
||||
// # Update latest messages for attesting indices
|
||||
// update_latest_messages(store, indexed_attestation.attesting_indices, attestation)
|
||||
func (s *Service) OnAttestation(ctx context.Context, a *ethpb.Attestation, disparity time.Duration) error {
|
||||
func (s *Service) OnAttestation(ctx context.Context, a interfaces.Attestation, disparity time.Duration) error {
|
||||
ctx, span := trace.StartSpan(ctx, "blockChain.onAttestation")
|
||||
defer span.End()
|
||||
|
||||
if err := helpers.ValidateNilAttestation(a); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := helpers.ValidateSlotTargetEpoch(a.Data); err != nil {
|
||||
if err := helpers.ValidateSlotTargetEpoch(a.GetData()); err != nil {
|
||||
return err
|
||||
}
|
||||
tgt := ethpb.CopyCheckpoint(a.Data.Target)
|
||||
tgt := ethpb.CopyCheckpoint(a.GetData().Target)
|
||||
|
||||
// Note that target root check is ignored here because it was performed in sync's validation pipeline:
|
||||
// validate_aggregate_proof.go and validate_beacon_attestation.go
|
||||
@@ -67,7 +68,7 @@ func (s *Service) OnAttestation(ctx context.Context, a *ethpb.Attestation, dispa
|
||||
}
|
||||
|
||||
// Verify attestation beacon block is known and not from the future.
|
||||
if err := s.verifyBeaconBlock(ctx, a.Data); err != nil {
|
||||
if err := s.verifyBeaconBlock(ctx, a.GetData()); err != nil {
|
||||
return errors.Wrap(err, "could not verify attestation beacon block")
|
||||
}
|
||||
|
||||
@@ -75,12 +76,12 @@ func (s *Service) OnAttestation(ctx context.Context, a *ethpb.Attestation, dispa
|
||||
// validate_aggregate_proof.go and validate_beacon_attestation.go
|
||||
|
||||
// Verify attestations can only affect the fork choice of subsequent slots.
|
||||
if err := slots.VerifyTime(genesisTime, a.Data.Slot+1, disparity); err != nil {
|
||||
if err := slots.VerifyTime(genesisTime, a.GetData().Slot+1, disparity); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Use the target state to verify attesting indices are valid.
|
||||
committee, err := helpers.BeaconCommitteeFromState(ctx, baseState, a.Data.Slot, a.Data.CommitteeIndex)
|
||||
committee, err := helpers.BeaconCommitteeFromState(ctx, baseState, a.GetData().Slot, a.GetData().CommitteeIndex)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -97,7 +98,7 @@ func (s *Service) OnAttestation(ctx context.Context, a *ethpb.Attestation, dispa
|
||||
// We assume trusted attestation in this function has verified signature.
|
||||
|
||||
// Update forkchoice store with the new attestation for updating weight.
|
||||
s.cfg.ForkChoiceStore.ProcessAttestation(ctx, indexedAtt.AttestingIndices, bytesutil.ToBytes32(a.Data.BeaconBlockRoot), a.Data.Target.Epoch)
|
||||
s.cfg.ForkChoiceStore.ProcessAttestation(ctx, indexedAtt.GetAttestingIndices(), bytesutil.ToBytes32(a.GetData().BeaconBlockRoot), a.GetData().Target.Epoch)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ import (
|
||||
"github.com/prysmaticlabs/prysm/v5/beacon-chain/core/transition"
|
||||
fieldparams "github.com/prysmaticlabs/prysm/v5/config/fieldparams"
|
||||
"github.com/prysmaticlabs/prysm/v5/config/params"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/interfaces"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
|
||||
"github.com/prysmaticlabs/prysm/v5/encoding/bytesutil"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
|
||||
@@ -73,7 +74,7 @@ func TestStore_OnAttestation_ErrorConditions(t *testing.T) {
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
a *ethpb.Attestation
|
||||
a interfaces.Attestation
|
||||
wantedErr string
|
||||
}{
|
||||
{
|
||||
|
||||
@@ -366,17 +366,17 @@ func (s *Service) handleEpochBoundary(ctx context.Context, slot primitives.Slot,
|
||||
func (s *Service) handleBlockAttestations(ctx context.Context, blk interfaces.ReadOnlyBeaconBlock, st state.BeaconState) error {
|
||||
// Feed in block's attestations to fork choice store.
|
||||
for _, a := range blk.Body().Attestations() {
|
||||
committee, err := helpers.BeaconCommitteeFromState(ctx, st, a.Data.Slot, a.Data.CommitteeIndex)
|
||||
committee, err := helpers.BeaconCommitteeFromState(ctx, st, a.GetData().Slot, a.GetData().CommitteeIndex)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
indices, err := attestation.AttestingIndices(a.AggregationBits, committee)
|
||||
indices, err := attestation.AttestingIndices(a.GetAggregationBits(), committee)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
r := bytesutil.ToBytes32(a.Data.BeaconBlockRoot)
|
||||
r := bytesutil.ToBytes32(a.GetData().BeaconBlockRoot)
|
||||
if s.cfg.ForkChoiceStore.HasNode(r) {
|
||||
s.cfg.ForkChoiceStore.ProcessAttestation(ctx, indices, r, a.Data.Target.Epoch)
|
||||
s.cfg.ForkChoiceStore.ProcessAttestation(ctx, indices, r, a.GetData().Target.Epoch)
|
||||
} else if err := s.cfg.AttPool.SaveBlockAttestation(a); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -387,7 +387,7 @@ func (s *Service) handleBlockAttestations(ctx context.Context, blk interfaces.Re
|
||||
// InsertSlashingsToForkChoiceStore inserts attester slashing indices to fork choice store.
|
||||
// To call this function, it's caller's responsibility to ensure the slashing object is valid.
|
||||
// This function requires a write lock on forkchoice.
|
||||
func (s *Service) InsertSlashingsToForkChoiceStore(ctx context.Context, slashings []*ethpb.AttesterSlashing) {
|
||||
func (s *Service) InsertSlashingsToForkChoiceStore(ctx context.Context, slashings []interfaces.AttesterSlashing) {
|
||||
for _, slashing := range slashings {
|
||||
indices := blocks.SlashableAttesterIndices(slashing)
|
||||
for _, index := range indices {
|
||||
|
||||
@@ -824,7 +824,10 @@ func TestRemoveBlockAttestationsInPool(t *testing.T) {
|
||||
require.NoError(t, service.cfg.BeaconDB.SaveStateSummary(ctx, ðpb.StateSummary{Root: r[:]}))
|
||||
require.NoError(t, service.cfg.BeaconDB.SaveGenesisBlockRoot(ctx, r))
|
||||
|
||||
atts := b.Block.Body.Attestations
|
||||
atts := make([]interfaces.Attestation, len(b.Block.Body.Attestations))
|
||||
for i, a := range b.Block.Body.Attestations {
|
||||
atts[i] = a
|
||||
}
|
||||
require.NoError(t, service.cfg.AttPool.SaveAggregatedAttestations(atts))
|
||||
wsb, err := consensusblocks.NewSignedBeaconBlock(b)
|
||||
require.NoError(t, err)
|
||||
@@ -2010,12 +2013,12 @@ func TestOnBlock_HandleBlockAttestations(t *testing.T) {
|
||||
|
||||
require.Equal(t, 1, len(wsb.Block().Body().Attestations()))
|
||||
a := wsb.Block().Body().Attestations()[0]
|
||||
r := bytesutil.ToBytes32(a.Data.BeaconBlockRoot)
|
||||
r := bytesutil.ToBytes32(a.GetData().BeaconBlockRoot)
|
||||
require.Equal(t, true, service.cfg.ForkChoiceStore.HasNode(r))
|
||||
|
||||
require.Equal(t, 1, len(wsb.Block().Body().Attestations()))
|
||||
a3 := wsb3.Block().Body().Attestations()[0]
|
||||
r3 := bytesutil.ToBytes32(a3.Data.BeaconBlockRoot)
|
||||
r3 := bytesutil.ToBytes32(a3.GetData().BeaconBlockRoot)
|
||||
require.Equal(t, false, service.cfg.ForkChoiceStore.HasNode(r3))
|
||||
|
||||
require.NoError(t, service.handleBlockAttestations(ctx, wsb.Block(), st)) // fine to use the same committee as st
|
||||
|
||||
@@ -10,6 +10,7 @@ import (
|
||||
"github.com/prysmaticlabs/prysm/v5/beacon-chain/core/helpers"
|
||||
"github.com/prysmaticlabs/prysm/v5/beacon-chain/state"
|
||||
"github.com/prysmaticlabs/prysm/v5/config/params"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/interfaces"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
|
||||
"github.com/prysmaticlabs/prysm/v5/encoding/bytesutil"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
|
||||
@@ -31,7 +32,7 @@ type AttestationStateFetcher interface {
|
||||
// AttestationReceiver interface defines the methods of chain service receive and processing new attestations.
|
||||
type AttestationReceiver interface {
|
||||
AttestationStateFetcher
|
||||
VerifyLmdFfgConsistency(ctx context.Context, att *ethpb.Attestation) error
|
||||
VerifyLmdFfgConsistency(ctx context.Context, att interfaces.Attestation) error
|
||||
InForkchoice([32]byte) bool
|
||||
}
|
||||
|
||||
@@ -51,13 +52,13 @@ func (s *Service) AttestationTargetState(ctx context.Context, target *ethpb.Chec
|
||||
}
|
||||
|
||||
// VerifyLmdFfgConsistency verifies that attestation's LMD and FFG votes are consistency to each other.
|
||||
func (s *Service) VerifyLmdFfgConsistency(ctx context.Context, a *ethpb.Attestation) error {
|
||||
r, err := s.TargetRootForEpoch([32]byte(a.Data.BeaconBlockRoot), a.Data.Target.Epoch)
|
||||
func (s *Service) VerifyLmdFfgConsistency(ctx context.Context, a interfaces.Attestation) error {
|
||||
r, err := s.TargetRootForEpoch([32]byte(a.GetData().BeaconBlockRoot), a.GetData().Target.Epoch)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !bytes.Equal(a.Data.Target.Root, r[:]) {
|
||||
return fmt.Errorf("FFG and LMD votes are not consistent, block root: %#x, target root: %#x, canonical target root: %#x", a.Data.BeaconBlockRoot, a.Data.Target.Root, r)
|
||||
if !bytes.Equal(a.GetData().Target.Root, r[:]) {
|
||||
return fmt.Errorf("FFG and LMD votes are not consistent, block root: %#x, target root: %#x, canonical target root: %#x", a.GetData().BeaconBlockRoot, a.GetData().Target.Root, r)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -170,13 +171,13 @@ func (s *Service) processAttestations(ctx context.Context, disparity time.Durati
|
||||
// Based on the spec, don't process the attestation until the subsequent slot.
|
||||
// This delays consideration in the fork choice until their slot is in the past.
|
||||
// https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/fork-choice.md#validate_on_attestation
|
||||
nextSlot := a.Data.Slot + 1
|
||||
nextSlot := a.GetData().Slot + 1
|
||||
if err := slots.VerifyTime(uint64(s.genesisTime.Unix()), nextSlot, disparity); err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
hasState := s.cfg.BeaconDB.HasStateSummary(ctx, bytesutil.ToBytes32(a.Data.BeaconBlockRoot))
|
||||
hasBlock := s.hasBlock(ctx, bytesutil.ToBytes32(a.Data.BeaconBlockRoot))
|
||||
hasState := s.cfg.BeaconDB.HasStateSummary(ctx, bytesutil.ToBytes32(a.GetData().BeaconBlockRoot))
|
||||
hasBlock := s.hasBlock(ctx, bytesutil.ToBytes32(a.GetData().BeaconBlockRoot))
|
||||
if !(hasState && hasBlock) {
|
||||
continue
|
||||
}
|
||||
@@ -185,17 +186,17 @@ func (s *Service) processAttestations(ctx context.Context, disparity time.Durati
|
||||
log.WithError(err).Error("Could not delete fork choice attestation in pool")
|
||||
}
|
||||
|
||||
if !helpers.VerifyCheckpointEpoch(a.Data.Target, s.genesisTime) {
|
||||
if !helpers.VerifyCheckpointEpoch(a.GetData().Target, s.genesisTime) {
|
||||
continue
|
||||
}
|
||||
|
||||
if err := s.receiveAttestationNoPubsub(ctx, a, disparity); err != nil {
|
||||
log.WithFields(logrus.Fields{
|
||||
"slot": a.Data.Slot,
|
||||
"committeeIndex": a.Data.CommitteeIndex,
|
||||
"beaconBlockRoot": fmt.Sprintf("%#x", bytesutil.Trunc(a.Data.BeaconBlockRoot)),
|
||||
"targetRoot": fmt.Sprintf("%#x", bytesutil.Trunc(a.Data.Target.Root)),
|
||||
"aggregationCount": a.AggregationBits.Count(),
|
||||
"slot": a.GetData().Slot,
|
||||
"committeeIndex": a.GetData().CommitteeIndex,
|
||||
"beaconBlockRoot": fmt.Sprintf("%#x", bytesutil.Trunc(a.GetData().BeaconBlockRoot)),
|
||||
"targetRoot": fmt.Sprintf("%#x", bytesutil.Trunc(a.GetData().Target.Root)),
|
||||
"aggregationCount": a.GetAggregationBits().Count(),
|
||||
}).WithError(err).Warn("Could not process attestation for fork choice")
|
||||
}
|
||||
}
|
||||
@@ -206,7 +207,7 @@ func (s *Service) processAttestations(ctx context.Context, disparity time.Durati
|
||||
// 1. Validate attestation, update validator's latest vote
|
||||
// 2. Apply fork choice to the processed attestation
|
||||
// 3. Save latest head info
|
||||
func (s *Service) receiveAttestationNoPubsub(ctx context.Context, att *ethpb.Attestation, disparity time.Duration) error {
|
||||
func (s *Service) receiveAttestationNoPubsub(ctx context.Context, att interfaces.Attestation, disparity time.Duration) error {
|
||||
ctx, span := trace.StartSpan(ctx, "beacon-chain.blockchain.receiveAttestationNoPubsub")
|
||||
defer span.End()
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ import (
|
||||
forkchoicetypes "github.com/prysmaticlabs/prysm/v5/beacon-chain/forkchoice/types"
|
||||
"github.com/prysmaticlabs/prysm/v5/config/params"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/blocks"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/interfaces"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
|
||||
"github.com/prysmaticlabs/prysm/v5/encoding/bytesutil"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
|
||||
@@ -83,7 +84,11 @@ func TestProcessAttestations_Ok(t *testing.T) {
|
||||
state, blkRoot, err := prepareForkchoiceState(ctx, 0, tRoot, tRoot, params.BeaconConfig().ZeroHash, ojc, ofc)
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, service.cfg.ForkChoiceStore.InsertNode(ctx, state, blkRoot))
|
||||
require.NoError(t, service.cfg.AttPool.SaveForkchoiceAttestations(atts))
|
||||
attsToSave := make([]interfaces.Attestation, len(atts))
|
||||
for i, a := range atts {
|
||||
attsToSave[i] = a
|
||||
}
|
||||
require.NoError(t, service.cfg.AttPool.SaveForkchoiceAttestations(attsToSave))
|
||||
service.processAttestations(ctx, 0)
|
||||
require.Equal(t, 0, len(service.cfg.AttPool.ForkchoiceAttestations()))
|
||||
require.LogsDoNotContain(t, hook, "Could not process attestation for fork choice")
|
||||
@@ -121,7 +126,11 @@ func TestService_ProcessAttestationsAndUpdateHead(t *testing.T) {
|
||||
// Generate attestations for this block in Slot 1
|
||||
atts, err := util.GenerateAttestations(copied, pks, 1, 1, false)
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, service.cfg.AttPool.SaveForkchoiceAttestations(atts))
|
||||
attsToSave := make([]interfaces.Attestation, len(atts))
|
||||
for i, a := range atts {
|
||||
attsToSave[i] = a
|
||||
}
|
||||
require.NoError(t, service.cfg.AttPool.SaveForkchoiceAttestations(attsToSave))
|
||||
// Verify the target is in forkchoice
|
||||
require.Equal(t, true, fcs.HasNode(bytesutil.ToBytes32(atts[0].Data.BeaconBlockRoot)))
|
||||
require.Equal(t, tRoot, bytesutil.ToBytes32(atts[0].Data.BeaconBlockRoot))
|
||||
|
||||
@@ -52,7 +52,7 @@ type BlobReceiver interface {
|
||||
|
||||
// SlashingReceiver interface defines the methods of chain service for receiving validated slashing over the wire.
|
||||
type SlashingReceiver interface {
|
||||
ReceiveAttesterSlashing(ctx context.Context, slashings *ethpb.AttesterSlashing)
|
||||
ReceiveAttesterSlashing(ctx context.Context, slashing interfaces.AttesterSlashing)
|
||||
}
|
||||
|
||||
// ReceiveBlock is a function that defines the operations (minus pubsub)
|
||||
@@ -295,10 +295,10 @@ func (s *Service) HasBlock(ctx context.Context, root [32]byte) bool {
|
||||
}
|
||||
|
||||
// ReceiveAttesterSlashing receives an attester slashing and inserts it to forkchoice
|
||||
func (s *Service) ReceiveAttesterSlashing(ctx context.Context, slashing *ethpb.AttesterSlashing) {
|
||||
func (s *Service) ReceiveAttesterSlashing(ctx context.Context, slashing interfaces.AttesterSlashing) {
|
||||
s.cfg.ForkChoiceStore.Lock()
|
||||
defer s.cfg.ForkChoiceStore.Unlock()
|
||||
s.InsertSlashingsToForkChoiceStore(ctx, []*ethpb.AttesterSlashing{slashing})
|
||||
s.InsertSlashingsToForkChoiceStore(ctx, []interfaces.AttesterSlashing{slashing})
|
||||
}
|
||||
|
||||
// prunePostBlockOperationPools only runs on new head otherwise should return a nil.
|
||||
@@ -479,7 +479,7 @@ func (s *Service) sendBlockAttestationsToSlasher(signed interfaces.ReadOnlySigne
|
||||
// is done in the background to avoid adding more load to this critical code path.
|
||||
ctx := context.TODO()
|
||||
for _, att := range signed.Block().Body().Attestations() {
|
||||
committee, err := helpers.BeaconCommitteeFromState(ctx, preState, att.Data.Slot, att.Data.CommitteeIndex)
|
||||
committee, err := helpers.BeaconCommitteeFromState(ctx, preState, att.GetData().Slot, att.GetData().CommitteeIndex)
|
||||
if err != nil {
|
||||
log.WithError(err).Error("Could not get attestation committee")
|
||||
return
|
||||
|
||||
@@ -20,6 +20,7 @@ import (
|
||||
"github.com/prysmaticlabs/prysm/v5/beacon-chain/p2p"
|
||||
"github.com/prysmaticlabs/prysm/v5/beacon-chain/startup"
|
||||
"github.com/prysmaticlabs/prysm/v5/beacon-chain/state/stategen"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/interfaces"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/v5/testing/require"
|
||||
"google.golang.org/protobuf/proto"
|
||||
@@ -49,7 +50,7 @@ func (mb *mockBroadcaster) Broadcast(_ context.Context, _ proto.Message) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (mb *mockBroadcaster) BroadcastAttestation(_ context.Context, _ uint64, _ *ethpb.Attestation) error {
|
||||
func (mb *mockBroadcaster) BroadcastAttestation(_ context.Context, _ uint64, _ interfaces.Attestation) error {
|
||||
mb.broadcastCalled = true
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -414,8 +414,8 @@ func (*ChainService) HeadGenesisValidatorsRoot() [32]byte {
|
||||
}
|
||||
|
||||
// VerifyLmdFfgConsistency mocks VerifyLmdFfgConsistency and always returns nil.
|
||||
func (*ChainService) VerifyLmdFfgConsistency(_ context.Context, a *ethpb.Attestation) error {
|
||||
if !bytes.Equal(a.Data.BeaconBlockRoot, a.Data.Target.Root) {
|
||||
func (*ChainService) VerifyLmdFfgConsistency(_ context.Context, a interfaces.Attestation) error {
|
||||
if !bytes.Equal(a.GetData().BeaconBlockRoot, a.GetData().Target.Root) {
|
||||
return errors.New("LMD and FFG miss matched")
|
||||
}
|
||||
return nil
|
||||
@@ -495,7 +495,7 @@ func (s *ChainService) UpdateHead(ctx context.Context, slot primitives.Slot) {
|
||||
}
|
||||
|
||||
// ReceiveAttesterSlashing mocks the same method in the chain service.
|
||||
func (*ChainService) ReceiveAttesterSlashing(context.Context, *ethpb.AttesterSlashing) {}
|
||||
func (*ChainService) ReceiveAttesterSlashing(context.Context, interfaces.AttesterSlashing) {}
|
||||
|
||||
// IsFinalized mocks the same method in the chain service.
|
||||
func (s *ChainService) IsFinalized(_ context.Context, blockRoot [32]byte) bool {
|
||||
|
||||
@@ -48,7 +48,7 @@ func ProcessAttestationsNoVerifySignature(
|
||||
func ProcessAttestationNoVerifySignature(
|
||||
ctx context.Context,
|
||||
beaconState state.BeaconState,
|
||||
att *ethpb.Attestation,
|
||||
att interfaces.Attestation,
|
||||
totalBalance uint64,
|
||||
) (state.BeaconState, error) {
|
||||
ctx, span := trace.StartSpan(ctx, "altair.ProcessAttestationNoVerifySignature")
|
||||
@@ -58,24 +58,24 @@ func ProcessAttestationNoVerifySignature(
|
||||
return nil, err
|
||||
}
|
||||
|
||||
delay, err := beaconState.Slot().SafeSubSlot(att.Data.Slot)
|
||||
delay, err := beaconState.Slot().SafeSubSlot(att.GetData().Slot)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("att slot %d can't be greater than state slot %d", att.Data.Slot, beaconState.Slot())
|
||||
return nil, fmt.Errorf("att slot %d can't be greater than state slot %d", att.GetData().Slot, beaconState.Slot())
|
||||
}
|
||||
participatedFlags, err := AttestationParticipationFlagIndices(beaconState, att.Data, delay)
|
||||
participatedFlags, err := AttestationParticipationFlagIndices(beaconState, att.GetData(), delay)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
committee, err := helpers.BeaconCommitteeFromState(ctx, beaconState, att.Data.Slot, att.Data.CommitteeIndex)
|
||||
committee, err := helpers.BeaconCommitteeFromState(ctx, beaconState, att.GetData().Slot, att.GetData().CommitteeIndex)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
indices, err := attestation.AttestingIndices(att.AggregationBits, committee)
|
||||
indices, err := attestation.AttestingIndices(att.GetAggregationBits(), committee)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return SetParticipationAndRewardProposer(ctx, beaconState, att.Data.Target.Epoch, indices, participatedFlags, totalBalance)
|
||||
return SetParticipationAndRewardProposer(ctx, beaconState, att.GetData().Target.Epoch, indices, participatedFlags, totalBalance)
|
||||
}
|
||||
|
||||
// SetParticipationAndRewardProposer retrieves and sets the epoch participation bits in state. Based on the epoch participation, it rewards
|
||||
|
||||
@@ -46,7 +46,7 @@ func ProcessAttestationsNoVerifySignature(
|
||||
func VerifyAttestationNoVerifySignature(
|
||||
ctx context.Context,
|
||||
beaconState state.ReadOnlyBeaconState,
|
||||
att *ethpb.Attestation,
|
||||
att interfaces.Attestation,
|
||||
) error {
|
||||
ctx, span := trace.StartSpan(ctx, "core.VerifyAttestationNoVerifySignature")
|
||||
defer span.End()
|
||||
@@ -56,7 +56,7 @@ func VerifyAttestationNoVerifySignature(
|
||||
}
|
||||
currEpoch := time.CurrentEpoch(beaconState)
|
||||
prevEpoch := time.PrevEpoch(beaconState)
|
||||
data := att.Data
|
||||
data := att.GetData()
|
||||
if data.Target.Epoch != prevEpoch && data.Target.Epoch != currEpoch {
|
||||
return fmt.Errorf(
|
||||
"expected target epoch (%d) to be the previous epoch (%d) or the current epoch (%d)",
|
||||
@@ -76,11 +76,11 @@ func VerifyAttestationNoVerifySignature(
|
||||
}
|
||||
}
|
||||
|
||||
if err := helpers.ValidateSlotTargetEpoch(att.Data); err != nil {
|
||||
if err := helpers.ValidateSlotTargetEpoch(att.GetData()); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
s := att.Data.Slot
|
||||
s := att.GetData().Slot
|
||||
minInclusionCheck := s+params.BeaconConfig().MinAttestationInclusionDelay <= beaconState.Slot()
|
||||
if !minInclusionCheck {
|
||||
return fmt.Errorf(
|
||||
@@ -102,13 +102,13 @@ func VerifyAttestationNoVerifySignature(
|
||||
)
|
||||
}
|
||||
}
|
||||
activeValidatorCount, err := helpers.ActiveValidatorCount(ctx, beaconState, att.Data.Target.Epoch)
|
||||
activeValidatorCount, err := helpers.ActiveValidatorCount(ctx, beaconState, att.GetData().Target.Epoch)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
c := helpers.SlotCommitteeCount(activeValidatorCount)
|
||||
if uint64(att.Data.CommitteeIndex) >= c {
|
||||
return fmt.Errorf("committee index %d >= committee count %d", att.Data.CommitteeIndex, c)
|
||||
if uint64(att.GetData().CommitteeIndex) >= c {
|
||||
return fmt.Errorf("committee index %d >= committee count %d", att.GetData().CommitteeIndex, c)
|
||||
}
|
||||
|
||||
if err := helpers.VerifyAttestationBitfieldLengths(ctx, beaconState, att); err != nil {
|
||||
@@ -116,7 +116,7 @@ func VerifyAttestationNoVerifySignature(
|
||||
}
|
||||
|
||||
// Verify attesting indices are correct.
|
||||
committee, err := helpers.BeaconCommitteeFromState(ctx, beaconState, att.Data.Slot, att.Data.CommitteeIndex)
|
||||
committee, err := helpers.BeaconCommitteeFromState(ctx, beaconState, att.GetData().Slot, att.GetData().CommitteeIndex)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -133,7 +133,7 @@ func VerifyAttestationNoVerifySignature(
|
||||
func ProcessAttestationNoVerifySignature(
|
||||
ctx context.Context,
|
||||
beaconState state.BeaconState,
|
||||
att *ethpb.Attestation,
|
||||
att interfaces.Attestation,
|
||||
) (state.BeaconState, error) {
|
||||
ctx, span := trace.StartSpan(ctx, "core.ProcessAttestationNoVerifySignature")
|
||||
defer span.End()
|
||||
@@ -143,15 +143,15 @@ func ProcessAttestationNoVerifySignature(
|
||||
}
|
||||
|
||||
currEpoch := time.CurrentEpoch(beaconState)
|
||||
data := att.Data
|
||||
s := att.Data.Slot
|
||||
data := att.GetData()
|
||||
s := att.GetData().Slot
|
||||
proposerIndex, err := helpers.BeaconProposerIndex(ctx, beaconState)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
pendingAtt := ðpb.PendingAttestation{
|
||||
Data: data,
|
||||
AggregationBits: att.AggregationBits,
|
||||
AggregationBits: att.GetAggregationBits(),
|
||||
InclusionDelay: beaconState.Slot() - s,
|
||||
ProposerIndex: proposerIndex,
|
||||
}
|
||||
@@ -171,11 +171,11 @@ func ProcessAttestationNoVerifySignature(
|
||||
|
||||
// VerifyAttestationSignature converts and attestation into an indexed attestation and verifies
|
||||
// the signature in that attestation.
|
||||
func VerifyAttestationSignature(ctx context.Context, beaconState state.ReadOnlyBeaconState, att *ethpb.Attestation) error {
|
||||
func VerifyAttestationSignature(ctx context.Context, beaconState state.ReadOnlyBeaconState, att interfaces.Attestation) error {
|
||||
if err := helpers.ValidateNilAttestation(att); err != nil {
|
||||
return err
|
||||
}
|
||||
committee, err := helpers.BeaconCommitteeFromState(ctx, beaconState, att.Data.Slot, att.Data.CommitteeIndex)
|
||||
committee, err := helpers.BeaconCommitteeFromState(ctx, beaconState, att.GetData().Slot, att.GetData().CommitteeIndex)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -203,7 +203,7 @@ func VerifyAttestationSignature(ctx context.Context, beaconState state.ReadOnlyB
|
||||
// domain = get_domain(state, DOMAIN_BEACON_ATTESTER, indexed_attestation.data.target.epoch)
|
||||
// signing_root = compute_signing_root(indexed_attestation.data, domain)
|
||||
// return bls.FastAggregateVerify(pubkeys, signing_root, indexed_attestation.signature)
|
||||
func VerifyIndexedAttestation(ctx context.Context, beaconState state.ReadOnlyBeaconState, indexedAtt *ethpb.IndexedAttestation) error {
|
||||
func VerifyIndexedAttestation(ctx context.Context, beaconState state.ReadOnlyBeaconState, indexedAtt ethpb.IndexedAtt) error {
|
||||
ctx, span := trace.StartSpan(ctx, "core.VerifyIndexedAttestation")
|
||||
defer span.End()
|
||||
|
||||
@@ -212,14 +212,14 @@ func VerifyIndexedAttestation(ctx context.Context, beaconState state.ReadOnlyBea
|
||||
}
|
||||
domain, err := signing.Domain(
|
||||
beaconState.Fork(),
|
||||
indexedAtt.Data.Target.Epoch,
|
||||
indexedAtt.GetData().Target.Epoch,
|
||||
params.BeaconConfig().DomainBeaconAttester,
|
||||
beaconState.GenesisValidatorsRoot(),
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
indices := indexedAtt.AttestingIndices
|
||||
indices := indexedAtt.GetAttestingIndices()
|
||||
var pubkeys []bls.PublicKey
|
||||
for i := 0; i < len(indices); i++ {
|
||||
pubkeyAtIdx := beaconState.PubkeyAtIndex(primitives.ValidatorIndex(indices[i]))
|
||||
|
||||
@@ -11,6 +11,7 @@ import (
|
||||
state_native "github.com/prysmaticlabs/prysm/v5/beacon-chain/state/state-native"
|
||||
fieldparams "github.com/prysmaticlabs/prysm/v5/config/fieldparams"
|
||||
"github.com/prysmaticlabs/prysm/v5/config/params"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/interfaces"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
|
||||
"github.com/prysmaticlabs/prysm/v5/crypto/bls"
|
||||
"github.com/prysmaticlabs/prysm/v5/encoding/bytesutil"
|
||||
@@ -386,7 +387,7 @@ func TestValidateIndexedAttestation_BadAttestationsSignatureSet(t *testing.T) {
|
||||
|
||||
sig := keys[0].Sign([]byte{'t', 'e', 's', 't'})
|
||||
list := bitfield.Bitlist{0b11111}
|
||||
var atts []*ethpb.Attestation
|
||||
var atts []interfaces.Attestation
|
||||
for i := uint64(0); i < 1000; i++ {
|
||||
atts = append(atts, ðpb.Attestation{
|
||||
Data: ðpb.AttestationData{
|
||||
@@ -402,7 +403,7 @@ func TestValidateIndexedAttestation_BadAttestationsSignatureSet(t *testing.T) {
|
||||
_, err := blocks.AttestationSignatureBatch(context.Background(), beaconState, atts)
|
||||
assert.ErrorContains(t, want, err)
|
||||
|
||||
atts = []*ethpb.Attestation{}
|
||||
atts = []interfaces.Attestation{}
|
||||
list = bitfield.Bitlist{0b10000}
|
||||
for i := uint64(0); i < 1000; i++ {
|
||||
atts = append(atts, ðpb.Attestation{
|
||||
@@ -543,7 +544,7 @@ func TestRetrieveAttestationSignatureSet_VerifiesMultipleAttestations(t *testing
|
||||
}
|
||||
att2.Signature = bls.AggregateSignatures(sigs).Marshal()
|
||||
|
||||
set, err := blocks.AttestationSignatureBatch(ctx, st, []*ethpb.Attestation{att1, att2})
|
||||
set, err := blocks.AttestationSignatureBatch(ctx, st, []interfaces.Attestation{att1, att2})
|
||||
require.NoError(t, err)
|
||||
verified, err := set.Verify()
|
||||
require.NoError(t, err)
|
||||
@@ -607,6 +608,6 @@ func TestRetrieveAttestationSignatureSet_AcrossFork(t *testing.T) {
|
||||
}
|
||||
att2.Signature = bls.AggregateSignatures(sigs).Marshal()
|
||||
|
||||
_, err = blocks.AttestationSignatureBatch(ctx, st, []*ethpb.Attestation{att1, att2})
|
||||
_, err = blocks.AttestationSignatureBatch(ctx, st, []interfaces.Attestation{att1, att2})
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
"github.com/prysmaticlabs/prysm/v5/beacon-chain/core/helpers"
|
||||
"github.com/prysmaticlabs/prysm/v5/beacon-chain/state"
|
||||
"github.com/prysmaticlabs/prysm/v5/config/params"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/interfaces"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
|
||||
"github.com/prysmaticlabs/prysm/v5/container/slice"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
|
||||
@@ -40,7 +41,7 @@ import (
|
||||
func ProcessAttesterSlashings(
|
||||
ctx context.Context,
|
||||
beaconState state.BeaconState,
|
||||
slashings []*ethpb.AttesterSlashing,
|
||||
slashings []interfaces.AttesterSlashing,
|
||||
slashFunc slashValidatorFunc,
|
||||
) (state.BeaconState, error) {
|
||||
var err error
|
||||
@@ -57,7 +58,7 @@ func ProcessAttesterSlashings(
|
||||
func ProcessAttesterSlashing(
|
||||
ctx context.Context,
|
||||
beaconState state.BeaconState,
|
||||
slashing *ethpb.AttesterSlashing,
|
||||
slashing interfaces.AttesterSlashing,
|
||||
slashFunc slashValidatorFunc,
|
||||
) (state.BeaconState, error) {
|
||||
if err := VerifyAttesterSlashing(ctx, beaconState, slashing); err != nil {
|
||||
@@ -104,20 +105,20 @@ func ProcessAttesterSlashing(
|
||||
}
|
||||
|
||||
// VerifyAttesterSlashing validates the attestation data in both attestations in the slashing object.
|
||||
func VerifyAttesterSlashing(ctx context.Context, beaconState state.ReadOnlyBeaconState, slashing *ethpb.AttesterSlashing) error {
|
||||
func VerifyAttesterSlashing(ctx context.Context, beaconState state.ReadOnlyBeaconState, slashing interfaces.AttesterSlashing) error {
|
||||
if slashing == nil {
|
||||
return errors.New("nil slashing")
|
||||
}
|
||||
if slashing.Attestation_1 == nil || slashing.Attestation_2 == nil {
|
||||
if slashing.GetFirstAttestation() == nil || slashing.GetSecondAttestation() == nil {
|
||||
return errors.New("nil attestation")
|
||||
}
|
||||
if slashing.Attestation_1.Data == nil || slashing.Attestation_2.Data == nil {
|
||||
if slashing.GetFirstAttestation().GetData() == nil || slashing.GetSecondAttestation().GetData() == nil {
|
||||
return errors.New("nil attestation data")
|
||||
}
|
||||
att1 := slashing.Attestation_1
|
||||
att2 := slashing.Attestation_2
|
||||
data1 := att1.Data
|
||||
data2 := att2.Data
|
||||
att1 := slashing.GetFirstAttestation()
|
||||
att2 := slashing.GetSecondAttestation()
|
||||
data1 := att1.GetData()
|
||||
data2 := att2.GetData()
|
||||
if !IsSlashableAttestationData(data1, data2) {
|
||||
return errors.New("attestations are not slashable")
|
||||
}
|
||||
@@ -157,11 +158,11 @@ func IsSlashableAttestationData(data1, data2 *ethpb.AttestationData) bool {
|
||||
}
|
||||
|
||||
// SlashableAttesterIndices returns the intersection of attester indices from both attestations in this slashing.
|
||||
func SlashableAttesterIndices(slashing *ethpb.AttesterSlashing) []uint64 {
|
||||
if slashing == nil || slashing.Attestation_1 == nil || slashing.Attestation_2 == nil {
|
||||
func SlashableAttesterIndices(slashing interfaces.AttesterSlashing) []uint64 {
|
||||
if slashing == nil || slashing.GetFirstAttestation() == nil || slashing.GetSecondAttestation() == nil {
|
||||
return nil
|
||||
}
|
||||
indices1 := slashing.Attestation_1.AttestingIndices
|
||||
indices2 := slashing.Attestation_2.AttestingIndices
|
||||
indices1 := slashing.GetFirstAttestation().GetAttestingIndices()
|
||||
indices2 := slashing.GetSecondAttestation().GetAttestingIndices()
|
||||
return slice.IntersectionUint64(indices1, indices2)
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ import (
|
||||
v "github.com/prysmaticlabs/prysm/v5/beacon-chain/core/validators"
|
||||
state_native "github.com/prysmaticlabs/prysm/v5/beacon-chain/state/state-native"
|
||||
"github.com/prysmaticlabs/prysm/v5/config/params"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/interfaces"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
|
||||
"github.com/prysmaticlabs/prysm/v5/crypto/bls"
|
||||
"github.com/prysmaticlabs/prysm/v5/encoding/bytesutil"
|
||||
@@ -57,7 +58,11 @@ func TestProcessAttesterSlashings_DataNotSlashable(t *testing.T) {
|
||||
AttesterSlashings: slashings,
|
||||
},
|
||||
}
|
||||
_, err = blocks.ProcessAttesterSlashings(context.Background(), beaconState, b.Block.Body.AttesterSlashings, v.SlashValidator)
|
||||
ss := make([]interfaces.AttesterSlashing, len(b.Block.Body.AttesterSlashings))
|
||||
for i, s := range b.Block.Body.AttesterSlashings {
|
||||
ss[i] = s
|
||||
}
|
||||
_, err = blocks.ProcessAttesterSlashings(context.Background(), beaconState, ss, v.SlashValidator)
|
||||
assert.ErrorContains(t, "attestations are not slashable", err)
|
||||
}
|
||||
|
||||
@@ -92,7 +97,11 @@ func TestProcessAttesterSlashings_IndexedAttestationFailedToVerify(t *testing.T)
|
||||
},
|
||||
}
|
||||
|
||||
_, err = blocks.ProcessAttesterSlashings(context.Background(), beaconState, b.Block.Body.AttesterSlashings, v.SlashValidator)
|
||||
ss := make([]interfaces.AttesterSlashing, len(b.Block.Body.AttesterSlashings))
|
||||
for i, s := range b.Block.Body.AttesterSlashings {
|
||||
ss[i] = s
|
||||
}
|
||||
_, err = blocks.ProcessAttesterSlashings(context.Background(), beaconState, ss, v.SlashValidator)
|
||||
assert.ErrorContains(t, "validator indices count exceeds MAX_VALIDATORS_PER_COMMITTEE", err)
|
||||
}
|
||||
|
||||
@@ -144,7 +153,11 @@ func TestProcessAttesterSlashings_AppliesCorrectStatus(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
newState, err := blocks.ProcessAttesterSlashings(context.Background(), beaconState, b.Block.Body.AttesterSlashings, v.SlashValidator)
|
||||
ss := make([]interfaces.AttesterSlashing, len(b.Block.Body.AttesterSlashings))
|
||||
for i, s := range b.Block.Body.AttesterSlashings {
|
||||
ss[i] = s
|
||||
}
|
||||
newState, err := blocks.ProcessAttesterSlashings(context.Background(), beaconState, ss, v.SlashValidator)
|
||||
require.NoError(t, err)
|
||||
newRegistry := newState.Validators()
|
||||
|
||||
@@ -213,7 +226,11 @@ func TestProcessAttesterSlashings_AppliesCorrectStatusAltair(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
newState, err := blocks.ProcessAttesterSlashings(context.Background(), beaconState, b.Block.Body.AttesterSlashings, v.SlashValidator)
|
||||
ss := make([]interfaces.AttesterSlashing, len(b.Block.Body.AttesterSlashings))
|
||||
for i, s := range b.Block.Body.AttesterSlashings {
|
||||
ss[i] = s
|
||||
}
|
||||
newState, err := blocks.ProcessAttesterSlashings(context.Background(), beaconState, ss, v.SlashValidator)
|
||||
require.NoError(t, err)
|
||||
newRegistry := newState.Validators()
|
||||
|
||||
@@ -282,7 +299,11 @@ func TestProcessAttesterSlashings_AppliesCorrectStatusBellatrix(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
newState, err := blocks.ProcessAttesterSlashings(context.Background(), beaconState, b.Block.Body.AttesterSlashings, v.SlashValidator)
|
||||
ss := make([]interfaces.AttesterSlashing, len(b.Block.Body.AttesterSlashings))
|
||||
for i, s := range b.Block.Body.AttesterSlashings {
|
||||
ss[i] = s
|
||||
}
|
||||
newState, err := blocks.ProcessAttesterSlashings(context.Background(), beaconState, ss, v.SlashValidator)
|
||||
require.NoError(t, err)
|
||||
newRegistry := newState.Validators()
|
||||
|
||||
@@ -351,7 +372,11 @@ func TestProcessAttesterSlashings_AppliesCorrectStatusCapella(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
newState, err := blocks.ProcessAttesterSlashings(context.Background(), beaconState, b.Block.Body.AttesterSlashings, v.SlashValidator)
|
||||
ss := make([]interfaces.AttesterSlashing, len(b.Block.Body.AttesterSlashings))
|
||||
for i, s := range b.Block.Body.AttesterSlashings {
|
||||
ss[i] = s
|
||||
}
|
||||
newState, err := blocks.ProcessAttesterSlashings(context.Background(), beaconState, ss, v.SlashValidator)
|
||||
require.NoError(t, err)
|
||||
newRegistry := newState.Validators()
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ import (
|
||||
fieldparams "github.com/prysmaticlabs/prysm/v5/config/fieldparams"
|
||||
"github.com/prysmaticlabs/prysm/v5/config/params"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/blocks"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/interfaces"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/v5/testing/require"
|
||||
@@ -216,7 +217,7 @@ func TestFuzzProcessAttesterSlashings_10000(t *testing.T) {
|
||||
fuzzer.Fuzz(a)
|
||||
s, err := state_native.InitializeFromProtoUnsafePhase0(state)
|
||||
require.NoError(t, err)
|
||||
r, err := ProcessAttesterSlashings(ctx, s, []*ethpb.AttesterSlashing{a}, v.SlashValidator)
|
||||
r, err := ProcessAttesterSlashings(ctx, s, []interfaces.AttesterSlashing{a}, v.SlashValidator)
|
||||
if err != nil && r != nil {
|
||||
t.Fatalf("return value should be nil on err. found: %v on error: %v for state: %v and slashing: %v", r, err, state, a)
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
"github.com/prysmaticlabs/prysm/v5/beacon-chain/core/signing"
|
||||
v "github.com/prysmaticlabs/prysm/v5/beacon-chain/core/validators"
|
||||
"github.com/prysmaticlabs/prysm/v5/config/params"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/interfaces"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
|
||||
"github.com/prysmaticlabs/prysm/v5/crypto/bls"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
|
||||
@@ -91,7 +92,11 @@ func TestProcessAttesterSlashings_RegressionSlashableIndices(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
newState, err := blocks.ProcessAttesterSlashings(context.Background(), beaconState, b.Block.Body.AttesterSlashings, v.SlashValidator)
|
||||
ss := make([]interfaces.AttesterSlashing, len(b.Block.Body.AttesterSlashings))
|
||||
for i, s := range b.Block.Body.AttesterSlashings {
|
||||
ss[i] = s
|
||||
}
|
||||
newState, err := blocks.ProcessAttesterSlashings(context.Background(), beaconState, ss, v.SlashValidator)
|
||||
require.NoError(t, err)
|
||||
newRegistry := newState.Validators()
|
||||
if !newRegistry[expectedSlashedVal].Slashed {
|
||||
|
||||
@@ -179,7 +179,7 @@ func randaoSigningData(ctx context.Context, beaconState state.ReadOnlyBeaconStat
|
||||
func createAttestationSignatureBatch(
|
||||
ctx context.Context,
|
||||
beaconState state.ReadOnlyBeaconState,
|
||||
atts []*ethpb.Attestation,
|
||||
atts []interfaces.Attestation,
|
||||
domain []byte,
|
||||
) (*bls.SignatureBatch, error) {
|
||||
if len(atts) == 0 {
|
||||
@@ -191,8 +191,8 @@ func createAttestationSignatureBatch(
|
||||
msgs := make([][32]byte, len(atts))
|
||||
descs := make([]string, len(atts))
|
||||
for i, a := range atts {
|
||||
sigs[i] = a.Signature
|
||||
c, err := helpers.BeaconCommitteeFromState(ctx, beaconState, a.Data.Slot, a.Data.CommitteeIndex)
|
||||
sigs[i] = a.GetSignature()
|
||||
c, err := helpers.BeaconCommitteeFromState(ctx, beaconState, a.GetData().Slot, a.GetData().CommitteeIndex)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -203,7 +203,7 @@ func createAttestationSignatureBatch(
|
||||
if err := attestation.IsValidAttestationIndices(ctx, ia); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
indices := ia.AttestingIndices
|
||||
indices := ia.GetAttestingIndices()
|
||||
pubkeys := make([][]byte, len(indices))
|
||||
for i := 0; i < len(indices); i++ {
|
||||
pubkeyAtIdx := beaconState.PubkeyAtIndex(primitives.ValidatorIndex(indices[i]))
|
||||
@@ -215,7 +215,7 @@ func createAttestationSignatureBatch(
|
||||
}
|
||||
pks[i] = aggP
|
||||
|
||||
root, err := signing.ComputeSigningRoot(ia.Data, domain)
|
||||
root, err := signing.ComputeSigningRoot(ia.GetData(), domain)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not get signing root of object")
|
||||
}
|
||||
@@ -233,7 +233,7 @@ func createAttestationSignatureBatch(
|
||||
|
||||
// AttestationSignatureBatch retrieves all the related attestation signature data such as the relevant public keys,
|
||||
// signatures and attestation signing data and collate it into a signature batch object.
|
||||
func AttestationSignatureBatch(ctx context.Context, beaconState state.ReadOnlyBeaconState, atts []*ethpb.Attestation) (*bls.SignatureBatch, error) {
|
||||
func AttestationSignatureBatch(ctx context.Context, beaconState state.ReadOnlyBeaconState, atts []interfaces.Attestation) (*bls.SignatureBatch, error) {
|
||||
if len(atts) == 0 {
|
||||
return bls.NewSet(), nil
|
||||
}
|
||||
@@ -243,10 +243,10 @@ func AttestationSignatureBatch(ctx context.Context, beaconState state.ReadOnlyBe
|
||||
dt := params.BeaconConfig().DomainBeaconAttester
|
||||
|
||||
// Split attestations by fork. Note: the signature domain will differ based on the fork.
|
||||
var preForkAtts []*ethpb.Attestation
|
||||
var postForkAtts []*ethpb.Attestation
|
||||
var preForkAtts []interfaces.Attestation
|
||||
var postForkAtts []interfaces.Attestation
|
||||
for _, a := range atts {
|
||||
if slots.ToEpoch(a.Data.Slot) < fork.Epoch {
|
||||
if slots.ToEpoch(a.GetData().Slot) < fork.Epoch {
|
||||
preForkAtts = append(preForkAtts, a)
|
||||
} else {
|
||||
postForkAtts = append(postForkAtts, a)
|
||||
|
||||
@@ -54,7 +54,7 @@ func ProcessAttestations(
|
||||
return nil, nil, errors.Wrap(err, "could not check validator attested previous epoch")
|
||||
}
|
||||
|
||||
committee, err := helpers.BeaconCommitteeFromState(ctx, state, a.Data.Slot, a.Data.CommitteeIndex)
|
||||
committee, err := helpers.BeaconCommitteeFromState(ctx, state, a.GetData().Slot, a.GetData().CommitteeIndex)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ go_library(
|
||||
deps = [
|
||||
"//async/event:go_default_library",
|
||||
"//consensus-types/blocks:go_default_library",
|
||||
"//consensus-types/interfaces:go_default_library",
|
||||
"//proto/prysm/v1alpha1:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -3,6 +3,7 @@ package operation
|
||||
|
||||
import (
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/blocks"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/interfaces"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
|
||||
)
|
||||
|
||||
@@ -37,7 +38,7 @@ const (
|
||||
// UnAggregatedAttReceivedData is the data sent with UnaggregatedAttReceived events.
|
||||
type UnAggregatedAttReceivedData struct {
|
||||
// Attestation is the unaggregated attestation object.
|
||||
Attestation *ethpb.Attestation
|
||||
Attestation interfaces.Attestation
|
||||
}
|
||||
|
||||
// AggregatedAttReceivedData is the data sent with AggregatedAttReceived events.
|
||||
@@ -75,5 +76,5 @@ type ProposerSlashingReceivedData struct {
|
||||
|
||||
// AttesterSlashingReceivedData is the data sent with AttesterSlashingReceived events.
|
||||
type AttesterSlashingReceivedData struct {
|
||||
AttesterSlashing *ethpb.AttesterSlashing
|
||||
AttesterSlashing interfaces.AttesterSlashing
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@ go_library(
|
||||
"//beacon-chain/state:go_default_library",
|
||||
"//config/fieldparams:go_default_library",
|
||||
"//config/params:go_default_library",
|
||||
"//consensus-types/interfaces:go_default_library",
|
||||
"//consensus-types/primitives:go_default_library",
|
||||
"//container/slice:go_default_library",
|
||||
"//container/trie:go_default_library",
|
||||
@@ -72,6 +73,7 @@ go_test(
|
||||
"//beacon-chain/state/state-native:go_default_library",
|
||||
"//config/fieldparams:go_default_library",
|
||||
"//config/params:go_default_library",
|
||||
"//consensus-types/interfaces:go_default_library",
|
||||
"//consensus-types/primitives:go_default_library",
|
||||
"//container/slice:go_default_library",
|
||||
"//crypto/hash:go_default_library",
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/prysmaticlabs/prysm/v5/config/params"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/interfaces"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
|
||||
"github.com/prysmaticlabs/prysm/v5/crypto/hash"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
|
||||
@@ -21,20 +22,20 @@ var (
|
||||
// ValidateNilAttestation checks if any composite field of input attestation is nil.
|
||||
// Access to these nil fields will result in run time panic,
|
||||
// it is recommended to run these checks as first line of defense.
|
||||
func ValidateNilAttestation(attestation *ethpb.Attestation) error {
|
||||
func ValidateNilAttestation(attestation interfaces.Attestation) error {
|
||||
if attestation == nil {
|
||||
return errors.New("attestation can't be nil")
|
||||
}
|
||||
if attestation.Data == nil {
|
||||
if attestation.GetData() == nil {
|
||||
return errors.New("attestation's data can't be nil")
|
||||
}
|
||||
if attestation.Data.Source == nil {
|
||||
if attestation.GetData().Source == nil {
|
||||
return errors.New("attestation's source can't be nil")
|
||||
}
|
||||
if attestation.Data.Target == nil {
|
||||
if attestation.GetData().Target == nil {
|
||||
return errors.New("attestation's target can't be nil")
|
||||
}
|
||||
if attestation.AggregationBits == nil {
|
||||
if attestation.GetAggregationBits() == nil {
|
||||
return errors.New("attestation's bitfield can't be nil")
|
||||
}
|
||||
return nil
|
||||
@@ -71,8 +72,8 @@ func IsAggregator(committeeCount uint64, slotSig []byte) (bool, error) {
|
||||
|
||||
// IsAggregated returns true if the attestation is an aggregated attestation,
|
||||
// false otherwise.
|
||||
func IsAggregated(attestation *ethpb.Attestation) bool {
|
||||
return attestation.AggregationBits.Count() > 1
|
||||
func IsAggregated(attestation interfaces.Attestation) bool {
|
||||
return attestation.GetAggregationBits().Count() > 1
|
||||
}
|
||||
|
||||
// ComputeSubnetForAttestation returns the subnet for which the provided attestation will be broadcasted to.
|
||||
@@ -90,8 +91,8 @@ func IsAggregated(attestation *ethpb.Attestation) bool {
|
||||
// committees_since_epoch_start = committees_per_slot * slots_since_epoch_start
|
||||
//
|
||||
// return uint64((committees_since_epoch_start + committee_index) % ATTESTATION_SUBNET_COUNT)
|
||||
func ComputeSubnetForAttestation(activeValCount uint64, att *ethpb.Attestation) uint64 {
|
||||
return ComputeSubnetFromCommitteeAndSlot(activeValCount, att.Data.CommitteeIndex, att.Data.Slot)
|
||||
func ComputeSubnetForAttestation(activeValCount uint64, att interfaces.Attestation) uint64 {
|
||||
return ComputeSubnetFromCommitteeAndSlot(activeValCount, att.GetData().CommitteeIndex, att.GetData().Slot)
|
||||
}
|
||||
|
||||
// ComputeSubnetFromCommitteeAndSlot is a flattened version of ComputeSubnetForAttestation where we only pass in
|
||||
|
||||
@@ -9,6 +9,7 @@ import (
|
||||
"github.com/prysmaticlabs/prysm/v5/beacon-chain/core/helpers"
|
||||
state_native "github.com/prysmaticlabs/prysm/v5/beacon-chain/state/state-native"
|
||||
"github.com/prysmaticlabs/prysm/v5/config/params"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/interfaces"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/v5/testing/assert"
|
||||
@@ -238,7 +239,7 @@ func TestVerifyCheckpointEpoch_Ok(t *testing.T) {
|
||||
func TestValidateNilAttestation(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
attestation *ethpb.Attestation
|
||||
attestation interfaces.Attestation
|
||||
errString string
|
||||
}{
|
||||
{
|
||||
|
||||
@@ -15,12 +15,12 @@ import (
|
||||
"github.com/prysmaticlabs/prysm/v5/beacon-chain/state"
|
||||
fieldparams "github.com/prysmaticlabs/prysm/v5/config/fieldparams"
|
||||
"github.com/prysmaticlabs/prysm/v5/config/params"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/interfaces"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
|
||||
"github.com/prysmaticlabs/prysm/v5/container/slice"
|
||||
"github.com/prysmaticlabs/prysm/v5/crypto/hash"
|
||||
"github.com/prysmaticlabs/prysm/v5/encoding/bytesutil"
|
||||
"github.com/prysmaticlabs/prysm/v5/math"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/v5/time/slots"
|
||||
)
|
||||
|
||||
@@ -257,8 +257,8 @@ func VerifyBitfieldLength(bf bitfield.Bitfield, committeeSize uint64) error {
|
||||
|
||||
// VerifyAttestationBitfieldLengths verifies that an attestations aggregation bitfields is
|
||||
// a valid length matching the size of the committee.
|
||||
func VerifyAttestationBitfieldLengths(ctx context.Context, state state.ReadOnlyBeaconState, att *ethpb.Attestation) error {
|
||||
committee, err := BeaconCommitteeFromState(ctx, state, att.Data.Slot, att.Data.CommitteeIndex)
|
||||
func VerifyAttestationBitfieldLengths(ctx context.Context, state state.ReadOnlyBeaconState, att interfaces.Attestation) error {
|
||||
committee, err := BeaconCommitteeFromState(ctx, state, att.GetData().Slot, att.GetData().CommitteeIndex)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "could not retrieve beacon committees")
|
||||
}
|
||||
@@ -267,7 +267,7 @@ func VerifyAttestationBitfieldLengths(ctx context.Context, state state.ReadOnlyB
|
||||
return errors.New("no committee exist for this attestation")
|
||||
}
|
||||
|
||||
if err := VerifyBitfieldLength(att.AggregationBits, uint64(len(committee))); err != nil {
|
||||
if err := VerifyBitfieldLength(att.GetAggregationBits(), uint64(len(committee))); err != nil {
|
||||
return errors.Wrap(err, "failed to verify aggregation bitfield")
|
||||
}
|
||||
return nil
|
||||
|
||||
@@ -671,5 +671,5 @@ func ValidatorMaxEffectiveBalance(val *ethpb.Validator) uint64 {
|
||||
if HasCompoundingWithdrawalCredential(val) {
|
||||
return params.BeaconConfig().MaxEffectiveBalanceElectra
|
||||
}
|
||||
return params.BeaconConfig().MinActivationBalance // TODO: Add test that MinActivationBalance == (old) MaxEffectiveBalance
|
||||
return params.BeaconConfig().MinActivationBalance
|
||||
}
|
||||
|
||||
@@ -156,10 +156,10 @@ func (s *Store) CheckAttesterDoubleVotes(
|
||||
signingRootsBkt := tx.Bucket(attestationDataRootsBucket)
|
||||
attRecordsBkt := tx.Bucket(attestationRecordsBucket)
|
||||
|
||||
encEpoch := encodeTargetEpoch(attToProcess.IndexedAttestation.Data.Target.Epoch)
|
||||
encEpoch := encodeTargetEpoch(attToProcess.IndexedAttestation.GetData().Target.Epoch)
|
||||
localDoubleVotes := make([]*slashertypes.AttesterDoubleVote, 0)
|
||||
|
||||
for _, valIdx := range attToProcess.IndexedAttestation.AttestingIndices {
|
||||
for _, valIdx := range attToProcess.IndexedAttestation.GetAttestingIndices() {
|
||||
// Check if there is signing root in the database for this combination
|
||||
// of validator index and target epoch.
|
||||
encIdx := encodeValidatorIndex(primitives.ValidatorIndex(valIdx))
|
||||
@@ -194,7 +194,7 @@ func (s *Store) CheckAttesterDoubleVotes(
|
||||
// Build the proof of double vote.
|
||||
slashAtt := &slashertypes.AttesterDoubleVote{
|
||||
ValidatorIndex: primitives.ValidatorIndex(valIdx),
|
||||
Target: attToProcess.IndexedAttestation.Data.Target.Epoch,
|
||||
Target: attToProcess.IndexedAttestation.GetData().Target.Epoch,
|
||||
Wrapper_1: existingAttRecord,
|
||||
Wrapper_2: attToProcess,
|
||||
}
|
||||
@@ -280,7 +280,7 @@ func (s *Store) SaveAttestationRecordsForValidators(
|
||||
encodedRecords := make([][]byte, attWrappersCount)
|
||||
|
||||
for i, attestation := range attWrappers {
|
||||
encEpoch := encodeTargetEpoch(attestation.IndexedAttestation.Data.Target.Epoch)
|
||||
encEpoch := encodeTargetEpoch(attestation.IndexedAttestation.GetData().Target.Epoch)
|
||||
|
||||
value, err := encodeAttestationRecord(attestation)
|
||||
if err != nil {
|
||||
@@ -325,7 +325,7 @@ func (s *Store) SaveAttestationRecordsForValidators(
|
||||
return err
|
||||
}
|
||||
|
||||
for _, validatorIndex := range attWrapper.IndexedAttestation.AttestingIndices {
|
||||
for _, validatorIndex := range attWrapper.IndexedAttestation.GetAttestingIndices() {
|
||||
encodedIndex := encodeValidatorIndex(primitives.ValidatorIndex(validatorIndex))
|
||||
|
||||
key := append(encodedTargetEpoch, encodedIndex...)
|
||||
@@ -638,8 +638,8 @@ func (s *Store) HighestAttestations(
|
||||
}
|
||||
highestAtt := ðpb.HighestAttestation{
|
||||
ValidatorIndex: uint64(indices[i]),
|
||||
HighestSourceEpoch: attWrapper.IndexedAttestation.Data.Source.Epoch,
|
||||
HighestTargetEpoch: attWrapper.IndexedAttestation.Data.Target.Epoch,
|
||||
HighestSourceEpoch: attWrapper.IndexedAttestation.GetData().Source.Epoch,
|
||||
HighestTargetEpoch: attWrapper.IndexedAttestation.GetData().Target.Epoch,
|
||||
}
|
||||
history = append(history, highestAtt)
|
||||
break
|
||||
|
||||
@@ -62,7 +62,7 @@ func TestStore_AttestationRecordForValidator_SaveRetrieve(t *testing.T) {
|
||||
actual, err := beaconDB.AttestationRecordForValidator(ctx, validatorIndex, primitives.Epoch(i+1))
|
||||
require.NoError(t, err)
|
||||
|
||||
require.DeepEqual(t, expected.IndexedAttestation.Data.Source.Epoch, actual.IndexedAttestation.Data.Source.Epoch)
|
||||
require.DeepEqual(t, expected.IndexedAttestation.GetData().Source.Epoch, actual.IndexedAttestation.GetData().Source.Epoch)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -544,7 +544,7 @@ func BenchmarkHighestAttestations(b *testing.B) {
|
||||
for i := 0; i < count; i++ {
|
||||
indicesForAtt := make([]primitives.ValidatorIndex, valsPerAtt)
|
||||
for r := 0; r < valsPerAtt; r++ {
|
||||
indicesForAtt[r] = primitives.ValidatorIndex(atts[i].IndexedAttestation.AttestingIndices[r])
|
||||
indicesForAtt[r] = primitives.ValidatorIndex(atts[i].IndexedAttestation.GetAttestingIndices()[r])
|
||||
}
|
||||
allIndices = append(allIndices, indicesForAtt...)
|
||||
}
|
||||
|
||||
@@ -33,12 +33,12 @@ func (s *Service) canUpdateAttestedValidator(idx primitives.ValidatorIndex, slot
|
||||
}
|
||||
|
||||
// attestingIndices returns the indices of validators that participated in the given aggregated attestation.
|
||||
func attestingIndices(ctx context.Context, state state.BeaconState, att *ethpb.Attestation) ([]uint64, error) {
|
||||
committee, err := helpers.BeaconCommitteeFromState(ctx, state, att.Data.Slot, att.Data.CommitteeIndex)
|
||||
func attestingIndices(ctx context.Context, state state.BeaconState, att interfaces.Attestation) ([]uint64, error) {
|
||||
committee, err := helpers.BeaconCommitteeFromState(ctx, state, att.GetData().Slot, att.GetData().CommitteeIndex)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return attestation.AttestingIndices(att.AggregationBits, committee)
|
||||
return attestation.AttestingIndices(att.GetAggregationBits(), committee)
|
||||
}
|
||||
|
||||
// logMessageTimelyFlagsForIndex returns the log message with performance info for the attestation (head, source, target)
|
||||
@@ -63,7 +63,7 @@ func (s *Service) processAttestations(ctx context.Context, state state.BeaconSta
|
||||
}
|
||||
|
||||
// processIncludedAttestation logs in the event for the tracked validators' and their latest attestation gets processed.
|
||||
func (s *Service) processIncludedAttestation(ctx context.Context, state state.BeaconState, att *ethpb.Attestation) {
|
||||
func (s *Service) processIncludedAttestation(ctx context.Context, state state.BeaconState, att interfaces.Attestation) {
|
||||
attestingIndices, err := attestingIndices(ctx, state, att)
|
||||
if err != nil {
|
||||
log.WithError(err).Error("Could not get attesting indices")
|
||||
@@ -72,8 +72,8 @@ func (s *Service) processIncludedAttestation(ctx context.Context, state state.Be
|
||||
s.Lock()
|
||||
defer s.Unlock()
|
||||
for _, idx := range attestingIndices {
|
||||
if s.canUpdateAttestedValidator(primitives.ValidatorIndex(idx), att.Data.Slot) {
|
||||
logFields := logMessageTimelyFlagsForIndex(primitives.ValidatorIndex(idx), att.Data)
|
||||
if s.canUpdateAttestedValidator(primitives.ValidatorIndex(idx), att.GetData().Slot) {
|
||||
logFields := logMessageTimelyFlagsForIndex(primitives.ValidatorIndex(idx), att.GetData())
|
||||
balance, err := state.BalanceAtIndex(primitives.ValidatorIndex(idx))
|
||||
if err != nil {
|
||||
log.WithError(err).Error("Could not get balance")
|
||||
@@ -88,7 +88,7 @@ func (s *Service) processIncludedAttestation(ctx context.Context, state state.Be
|
||||
balanceChg := int64(balance - latestPerf.balance)
|
||||
latestPerf.balanceChange = balanceChg
|
||||
latestPerf.balance = balance
|
||||
latestPerf.attestedSlot = att.Data.Slot
|
||||
latestPerf.attestedSlot = att.GetData().Slot
|
||||
latestPerf.inclusionSlot = state.Slot()
|
||||
inclusionSlotGauge.WithLabelValues(fmt.Sprintf("%d", idx)).Set(float64(latestPerf.inclusionSlot))
|
||||
aggregatedPerf.totalDistance += uint64(latestPerf.inclusionSlot - latestPerf.attestedSlot)
|
||||
@@ -161,10 +161,10 @@ func (s *Service) processIncludedAttestation(ctx context.Context, state state.Be
|
||||
}
|
||||
|
||||
// processUnaggregatedAttestation logs when the beacon node observes an unaggregated attestation from tracked validator.
|
||||
func (s *Service) processUnaggregatedAttestation(ctx context.Context, att *ethpb.Attestation) {
|
||||
func (s *Service) processUnaggregatedAttestation(ctx context.Context, att interfaces.Attestation) {
|
||||
s.RLock()
|
||||
defer s.RUnlock()
|
||||
root := bytesutil.ToBytes32(att.Data.BeaconBlockRoot)
|
||||
root := bytesutil.ToBytes32(att.GetData().BeaconBlockRoot)
|
||||
st := s.config.StateGen.StateByRootIfCachedNoCopy(root)
|
||||
if st == nil {
|
||||
log.WithField("beaconBlockRoot", fmt.Sprintf("%#x", bytesutil.Trunc(root[:]))).Debug(
|
||||
@@ -177,8 +177,8 @@ func (s *Service) processUnaggregatedAttestation(ctx context.Context, att *ethpb
|
||||
return
|
||||
}
|
||||
for _, idx := range attestingIndices {
|
||||
if s.canUpdateAttestedValidator(primitives.ValidatorIndex(idx), att.Data.Slot) {
|
||||
logFields := logMessageTimelyFlagsForIndex(primitives.ValidatorIndex(idx), att.Data)
|
||||
if s.canUpdateAttestedValidator(primitives.ValidatorIndex(idx), att.GetData().Slot) {
|
||||
logFields := logMessageTimelyFlagsForIndex(primitives.ValidatorIndex(idx), att.GetData())
|
||||
log.WithFields(logFields).Info("Processed unaggregated attestation")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -124,14 +124,14 @@ func (s *Service) processSlashings(blk interfaces.ReadOnlyBeaconBlock) {
|
||||
log.WithFields(logrus.Fields{
|
||||
"attesterIndex": idx,
|
||||
"blockInclusionSlot": blk.Slot(),
|
||||
"attestationSlot1": slashing.Attestation_1.Data.Slot,
|
||||
"beaconBlockRoot1": fmt.Sprintf("%#x", bytesutil.Trunc(slashing.Attestation_1.Data.BeaconBlockRoot)),
|
||||
"sourceEpoch1": slashing.Attestation_1.Data.Source.Epoch,
|
||||
"targetEpoch1": slashing.Attestation_1.Data.Target.Epoch,
|
||||
"attestationSlot2": slashing.Attestation_2.Data.Slot,
|
||||
"beaconBlockRoot2": fmt.Sprintf("%#x", bytesutil.Trunc(slashing.Attestation_2.Data.BeaconBlockRoot)),
|
||||
"sourceEpoch2": slashing.Attestation_2.Data.Source.Epoch,
|
||||
"targetEpoch2": slashing.Attestation_2.Data.Target.Epoch,
|
||||
"attestationSlot1": slashing.GetFirstAttestation().GetData().Slot,
|
||||
"beaconBlockRoot1": fmt.Sprintf("%#x", bytesutil.Trunc(slashing.GetFirstAttestation().GetData().BeaconBlockRoot)),
|
||||
"sourceEpoch1": slashing.GetFirstAttestation().GetData().Source.Epoch,
|
||||
"targetEpoch1": slashing.GetFirstAttestation().GetData().Target.Epoch,
|
||||
"attestationSlot2": slashing.GetSecondAttestation().GetData().Slot,
|
||||
"beaconBlockRoot2": fmt.Sprintf("%#x", bytesutil.Trunc(slashing.GetSecondAttestation().GetData().BeaconBlockRoot)),
|
||||
"sourceEpoch2": slashing.GetSecondAttestation().GetData().Source.Epoch,
|
||||
"targetEpoch2": slashing.GetSecondAttestation().GetData().Target.Epoch,
|
||||
}).Info("Attester slashing was included")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,9 +20,9 @@ go_library(
|
||||
"//cache/lru:go_default_library",
|
||||
"//config/features:go_default_library",
|
||||
"//config/params:go_default_library",
|
||||
"//consensus-types/interfaces:go_default_library",
|
||||
"//consensus-types/primitives:go_default_library",
|
||||
"//crypto/hash:go_default_library",
|
||||
"//proto/prysm/v1alpha1:go_default_library",
|
||||
"//proto/prysm/v1alpha1/attestation/aggregation/attestations:go_default_library",
|
||||
"//time:go_default_library",
|
||||
"//time/slots:go_default_library",
|
||||
@@ -49,6 +49,7 @@ go_test(
|
||||
"//beacon-chain/operations/attestations/kv:go_default_library",
|
||||
"//config/fieldparams:go_default_library",
|
||||
"//config/params:go_default_library",
|
||||
"//consensus-types/interfaces:go_default_library",
|
||||
"//consensus-types/primitives:go_default_library",
|
||||
"//crypto/bls:go_default_library",
|
||||
"//proto/prysm/v1alpha1:go_default_library",
|
||||
|
||||
@@ -15,9 +15,9 @@ go_library(
|
||||
deps = [
|
||||
"//beacon-chain/core/helpers:go_default_library",
|
||||
"//config/params:go_default_library",
|
||||
"//consensus-types/interfaces:go_default_library",
|
||||
"//consensus-types/primitives:go_default_library",
|
||||
"//crypto/hash:go_default_library",
|
||||
"//proto/prysm/v1alpha1:go_default_library",
|
||||
"//proto/prysm/v1alpha1/attestation/aggregation/attestations:go_default_library",
|
||||
"@com_github_patrickmn_go_cache//:go_default_library",
|
||||
"@com_github_pkg_errors//:go_default_library",
|
||||
@@ -39,6 +39,7 @@ go_test(
|
||||
embed = [":go_default_library"],
|
||||
deps = [
|
||||
"//config/fieldparams:go_default_library",
|
||||
"//consensus-types/interfaces:go_default_library",
|
||||
"//crypto/bls:go_default_library",
|
||||
"//proto/prysm/v1alpha1:go_default_library",
|
||||
"//testing/assert:go_default_library",
|
||||
|
||||
@@ -7,8 +7,8 @@ import (
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/prysmaticlabs/prysm/v5/beacon-chain/core/helpers"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/interfaces"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
|
||||
attaggregation "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1/attestation/aggregation/attestations"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"go.opencensus.io/trace"
|
||||
@@ -28,13 +28,13 @@ func (c *AttCaches) AggregateUnaggregatedAttestations(ctx context.Context) error
|
||||
return c.aggregateUnaggregatedAtts(ctx, unaggregatedAtts)
|
||||
}
|
||||
|
||||
func (c *AttCaches) aggregateUnaggregatedAtts(ctx context.Context, unaggregatedAtts []*ethpb.Attestation) error {
|
||||
func (c *AttCaches) aggregateUnaggregatedAtts(ctx context.Context, unaggregatedAtts []interfaces.Attestation) error {
|
||||
_, span := trace.StartSpan(ctx, "operations.attestations.kv.aggregateUnaggregatedAtts")
|
||||
defer span.End()
|
||||
|
||||
attsByDataRoot := make(map[[32]byte][]*ethpb.Attestation, len(unaggregatedAtts))
|
||||
attsByDataRoot := make(map[[32]byte][]interfaces.Attestation, len(unaggregatedAtts))
|
||||
for _, att := range unaggregatedAtts {
|
||||
attDataRoot, err := att.Data.HashTreeRoot()
|
||||
attDataRoot, err := att.GetData().HashTreeRoot()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -66,12 +66,12 @@ func (c *AttCaches) aggregateUnaggregatedAtts(ctx context.Context, unaggregatedA
|
||||
// aggregateParallel aggregates attestations in parallel for `atts` and saves them in the pool,
|
||||
// returns the unaggregated attestations that weren't able to aggregate.
|
||||
// Given `n` CPU cores, it creates a channel of size `n` and spawns `n` goroutines to aggregate attestations
|
||||
func (c *AttCaches) aggregateParallel(atts map[[32]byte][]*ethpb.Attestation, leftOver map[[32]byte]bool) map[[32]byte]bool {
|
||||
func (c *AttCaches) aggregateParallel(atts map[[32]byte][]interfaces.Attestation, leftOver map[[32]byte]bool) map[[32]byte]bool {
|
||||
var leftoverLock sync.Mutex
|
||||
wg := sync.WaitGroup{}
|
||||
|
||||
n := runtime.GOMAXPROCS(0) // defaults to the value of runtime.NumCPU
|
||||
ch := make(chan []*ethpb.Attestation, n)
|
||||
ch := make(chan []interfaces.Attestation, n)
|
||||
wg.Add(n)
|
||||
for i := 0; i < n; i++ {
|
||||
go func() {
|
||||
@@ -87,7 +87,7 @@ func (c *AttCaches) aggregateParallel(atts map[[32]byte][]*ethpb.Attestation, le
|
||||
continue
|
||||
}
|
||||
if helpers.IsAggregated(aggregated) {
|
||||
if err := c.SaveAggregatedAttestations([]*ethpb.Attestation{aggregated}); err != nil {
|
||||
if err := c.SaveAggregatedAttestations([]interfaces.Attestation{aggregated}); err != nil {
|
||||
log.WithError(err).Error("could not save aggregated attestation")
|
||||
continue
|
||||
}
|
||||
@@ -116,7 +116,7 @@ func (c *AttCaches) aggregateParallel(atts map[[32]byte][]*ethpb.Attestation, le
|
||||
}
|
||||
|
||||
// SaveAggregatedAttestation saves an aggregated attestation in cache.
|
||||
func (c *AttCaches) SaveAggregatedAttestation(att *ethpb.Attestation) error {
|
||||
func (c *AttCaches) SaveAggregatedAttestation(att interfaces.Attestation) error {
|
||||
if err := helpers.ValidateNilAttestation(att); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -139,16 +139,16 @@ func (c *AttCaches) SaveAggregatedAttestation(att *ethpb.Attestation) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
r, err := hashFn(att.Data)
|
||||
r, err := hashFn(att.GetData())
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "could not tree hash attestation")
|
||||
}
|
||||
copiedAtt := ethpb.CopyAttestation(att)
|
||||
copiedAtt := interfaces.CopyAttestation(att)
|
||||
c.aggregatedAttLock.Lock()
|
||||
defer c.aggregatedAttLock.Unlock()
|
||||
atts, ok := c.aggregatedAtt[r]
|
||||
if !ok {
|
||||
atts := []*ethpb.Attestation{copiedAtt}
|
||||
atts := []interfaces.Attestation{copiedAtt}
|
||||
c.aggregatedAtt[r] = atts
|
||||
return nil
|
||||
}
|
||||
@@ -163,7 +163,7 @@ func (c *AttCaches) SaveAggregatedAttestation(att *ethpb.Attestation) error {
|
||||
}
|
||||
|
||||
// SaveAggregatedAttestations saves a list of aggregated attestations in cache.
|
||||
func (c *AttCaches) SaveAggregatedAttestations(atts []*ethpb.Attestation) error {
|
||||
func (c *AttCaches) SaveAggregatedAttestations(atts []interfaces.Attestation) error {
|
||||
for _, att := range atts {
|
||||
if err := c.SaveAggregatedAttestation(att); err != nil {
|
||||
log.WithError(err).Debug("Could not save aggregated attestation")
|
||||
@@ -176,11 +176,11 @@ func (c *AttCaches) SaveAggregatedAttestations(atts []*ethpb.Attestation) error
|
||||
}
|
||||
|
||||
// AggregatedAttestations returns the aggregated attestations in cache.
|
||||
func (c *AttCaches) AggregatedAttestations() []*ethpb.Attestation {
|
||||
func (c *AttCaches) AggregatedAttestations() []interfaces.Attestation {
|
||||
c.aggregatedAttLock.RLock()
|
||||
defer c.aggregatedAttLock.RUnlock()
|
||||
|
||||
atts := make([]*ethpb.Attestation, 0)
|
||||
atts := make([]interfaces.Attestation, 0)
|
||||
|
||||
for _, a := range c.aggregatedAtt {
|
||||
atts = append(atts, a...)
|
||||
@@ -191,16 +191,16 @@ func (c *AttCaches) AggregatedAttestations() []*ethpb.Attestation {
|
||||
|
||||
// AggregatedAttestationsBySlotIndex returns the aggregated attestations in cache,
|
||||
// filtered by committee index and slot.
|
||||
func (c *AttCaches) AggregatedAttestationsBySlotIndex(ctx context.Context, slot primitives.Slot, committeeIndex primitives.CommitteeIndex) []*ethpb.Attestation {
|
||||
func (c *AttCaches) AggregatedAttestationsBySlotIndex(ctx context.Context, slot primitives.Slot, committeeIndex primitives.CommitteeIndex) []interfaces.Attestation {
|
||||
_, span := trace.StartSpan(ctx, "operations.attestations.kv.AggregatedAttestationsBySlotIndex")
|
||||
defer span.End()
|
||||
|
||||
atts := make([]*ethpb.Attestation, 0)
|
||||
atts := make([]interfaces.Attestation, 0)
|
||||
|
||||
c.aggregatedAttLock.RLock()
|
||||
defer c.aggregatedAttLock.RUnlock()
|
||||
for _, a := range c.aggregatedAtt {
|
||||
if slot == a[0].Data.Slot && committeeIndex == a[0].Data.CommitteeIndex {
|
||||
if slot == a[0].GetData().Slot && committeeIndex == a[0].GetData().CommitteeIndex {
|
||||
atts = append(atts, a...)
|
||||
}
|
||||
}
|
||||
@@ -209,14 +209,14 @@ func (c *AttCaches) AggregatedAttestationsBySlotIndex(ctx context.Context, slot
|
||||
}
|
||||
|
||||
// DeleteAggregatedAttestation deletes the aggregated attestations in cache.
|
||||
func (c *AttCaches) DeleteAggregatedAttestation(att *ethpb.Attestation) error {
|
||||
func (c *AttCaches) DeleteAggregatedAttestation(att interfaces.Attestation) error {
|
||||
if err := helpers.ValidateNilAttestation(att); err != nil {
|
||||
return err
|
||||
}
|
||||
if !helpers.IsAggregated(att) {
|
||||
return errors.New("attestation is not aggregated")
|
||||
}
|
||||
r, err := hashFn(att.Data)
|
||||
r, err := hashFn(att.GetData())
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "could not tree hash attestation data")
|
||||
}
|
||||
@@ -232,9 +232,9 @@ func (c *AttCaches) DeleteAggregatedAttestation(att *ethpb.Attestation) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
filtered := make([]*ethpb.Attestation, 0)
|
||||
filtered := make([]interfaces.Attestation, 0)
|
||||
for _, a := range attList {
|
||||
if c, err := att.AggregationBits.Contains(a.AggregationBits); err != nil {
|
||||
if c, err := att.GetAggregationBits().Contains(a.GetAggregationBits()); err != nil {
|
||||
return err
|
||||
} else if !c {
|
||||
filtered = append(filtered, a)
|
||||
@@ -250,11 +250,11 @@ func (c *AttCaches) DeleteAggregatedAttestation(att *ethpb.Attestation) error {
|
||||
}
|
||||
|
||||
// HasAggregatedAttestation checks if the input attestations has already existed in cache.
|
||||
func (c *AttCaches) HasAggregatedAttestation(att *ethpb.Attestation) (bool, error) {
|
||||
func (c *AttCaches) HasAggregatedAttestation(att interfaces.Attestation) (bool, error) {
|
||||
if err := helpers.ValidateNilAttestation(att); err != nil {
|
||||
return false, err
|
||||
}
|
||||
r, err := hashFn(att.Data)
|
||||
r, err := hashFn(att.GetData())
|
||||
if err != nil {
|
||||
return false, errors.Wrap(err, "could not tree hash attestation")
|
||||
}
|
||||
@@ -263,7 +263,7 @@ func (c *AttCaches) HasAggregatedAttestation(att *ethpb.Attestation) (bool, erro
|
||||
defer c.aggregatedAttLock.RUnlock()
|
||||
if atts, ok := c.aggregatedAtt[r]; ok {
|
||||
for _, a := range atts {
|
||||
if c, err := a.AggregationBits.Contains(att.AggregationBits); err != nil {
|
||||
if c, err := a.GetAggregationBits().Contains(att.GetAggregationBits()); err != nil {
|
||||
return false, err
|
||||
} else if c {
|
||||
return true, nil
|
||||
@@ -275,7 +275,7 @@ func (c *AttCaches) HasAggregatedAttestation(att *ethpb.Attestation) (bool, erro
|
||||
defer c.blockAttLock.RUnlock()
|
||||
if atts, ok := c.blockAtt[r]; ok {
|
||||
for _, a := range atts {
|
||||
if c, err := a.AggregationBits.Contains(att.AggregationBits); err != nil {
|
||||
if c, err := a.GetAggregationBits().Contains(att.GetAggregationBits()); err != nil {
|
||||
return false, err
|
||||
} else if c {
|
||||
return true, nil
|
||||
|
||||
@@ -9,6 +9,7 @@ import (
|
||||
"github.com/pkg/errors"
|
||||
fssz "github.com/prysmaticlabs/fastssz"
|
||||
"github.com/prysmaticlabs/go-bitfield"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/interfaces"
|
||||
"github.com/prysmaticlabs/prysm/v5/crypto/bls"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/v5/testing/assert"
|
||||
@@ -30,7 +31,7 @@ func TestKV_Aggregated_AggregateUnaggregatedAttestations(t *testing.T) {
|
||||
att6 := util.HydrateAttestation(ðpb.Attestation{Data: ðpb.AttestationData{Slot: 2}, AggregationBits: bitfield.Bitlist{0b1010}, Signature: sig1.Marshal()})
|
||||
att7 := util.HydrateAttestation(ðpb.Attestation{Data: ðpb.AttestationData{Slot: 2}, AggregationBits: bitfield.Bitlist{0b1100}, Signature: sig1.Marshal()})
|
||||
att8 := util.HydrateAttestation(ðpb.Attestation{Data: ðpb.AttestationData{Slot: 2}, AggregationBits: bitfield.Bitlist{0b1001}, Signature: sig2.Marshal()})
|
||||
atts := []*ethpb.Attestation{att1, att2, att3, att4, att5, att6, att7, att8}
|
||||
atts := []interfaces.Attestation{att1, att2, att3, att4, att5, att6, att7, att8}
|
||||
require.NoError(t, cache.SaveUnaggregatedAttestations(atts))
|
||||
require.NoError(t, cache.AggregateUnaggregatedAttestations(context.Background()))
|
||||
|
||||
@@ -41,7 +42,7 @@ func TestKV_Aggregated_AggregateUnaggregatedAttestations(t *testing.T) {
|
||||
func TestKV_Aggregated_SaveAggregatedAttestation(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
att *ethpb.Attestation
|
||||
att interfaces.Attestation
|
||||
count int
|
||||
wantErrString string
|
||||
}{
|
||||
@@ -118,13 +119,13 @@ func TestKV_Aggregated_SaveAggregatedAttestation(t *testing.T) {
|
||||
func TestKV_Aggregated_SaveAggregatedAttestations(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
atts []*ethpb.Attestation
|
||||
atts []interfaces.Attestation
|
||||
count int
|
||||
wantErrString string
|
||||
}{
|
||||
{
|
||||
name: "no duplicates",
|
||||
atts: []*ethpb.Attestation{
|
||||
atts: []interfaces.Attestation{
|
||||
util.HydrateAttestation(ðpb.Attestation{Data: ðpb.AttestationData{Slot: 1},
|
||||
AggregationBits: bitfield.Bitlist{0b1101}}),
|
||||
util.HydrateAttestation(ðpb.Attestation{Data: ðpb.AttestationData{Slot: 1},
|
||||
@@ -153,13 +154,13 @@ func TestKV_Aggregated_SaveAggregatedAttestations(t *testing.T) {
|
||||
func TestKV_Aggregated_SaveAggregatedAttestations_SomeGoodSomeBad(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
atts []*ethpb.Attestation
|
||||
atts []interfaces.Attestation
|
||||
count int
|
||||
wantErrString string
|
||||
}{
|
||||
{
|
||||
name: "the first attestation is bad",
|
||||
atts: []*ethpb.Attestation{
|
||||
atts: []interfaces.Attestation{
|
||||
util.HydrateAttestation(ðpb.Attestation{Data: ðpb.AttestationData{Slot: 1},
|
||||
AggregationBits: bitfield.Bitlist{0b1100}}),
|
||||
util.HydrateAttestation(ðpb.Attestation{Data: ðpb.AttestationData{Slot: 1},
|
||||
@@ -191,7 +192,7 @@ func TestKV_Aggregated_AggregatedAttestations(t *testing.T) {
|
||||
att1 := util.HydrateAttestation(ðpb.Attestation{Data: ðpb.AttestationData{Slot: 1}, AggregationBits: bitfield.Bitlist{0b1101}})
|
||||
att2 := util.HydrateAttestation(ðpb.Attestation{Data: ðpb.AttestationData{Slot: 2}, AggregationBits: bitfield.Bitlist{0b1101}})
|
||||
att3 := util.HydrateAttestation(ðpb.Attestation{Data: ðpb.AttestationData{Slot: 3}, AggregationBits: bitfield.Bitlist{0b1101}})
|
||||
atts := []*ethpb.Attestation{att1, att2, att3}
|
||||
atts := []interfaces.Attestation{att1, att2, att3}
|
||||
|
||||
for _, att := range atts {
|
||||
require.NoError(t, cache.SaveAggregatedAttestation(att))
|
||||
@@ -199,7 +200,7 @@ func TestKV_Aggregated_AggregatedAttestations(t *testing.T) {
|
||||
|
||||
returned := cache.AggregatedAttestations()
|
||||
sort.Slice(returned, func(i, j int) bool {
|
||||
return returned[i].Data.Slot < returned[j].Data.Slot
|
||||
return returned[i].GetData().Slot < returned[j].GetData().Slot
|
||||
})
|
||||
assert.DeepSSZEqual(t, atts, returned)
|
||||
}
|
||||
@@ -246,13 +247,13 @@ func TestKV_Aggregated_DeleteAggregatedAttestation(t *testing.T) {
|
||||
att2 := util.HydrateAttestation(ðpb.Attestation{Data: ðpb.AttestationData{Slot: 2}, AggregationBits: bitfield.Bitlist{0b11010}})
|
||||
att3 := util.HydrateAttestation(ðpb.Attestation{Data: ðpb.AttestationData{Slot: 3}, AggregationBits: bitfield.Bitlist{0b11010}})
|
||||
att4 := util.HydrateAttestation(ðpb.Attestation{Data: ðpb.AttestationData{Slot: 3}, AggregationBits: bitfield.Bitlist{0b10101}})
|
||||
atts := []*ethpb.Attestation{att1, att2, att3, att4}
|
||||
atts := []interfaces.Attestation{att1, att2, att3, att4}
|
||||
require.NoError(t, cache.SaveAggregatedAttestations(atts))
|
||||
require.NoError(t, cache.DeleteAggregatedAttestation(att1))
|
||||
require.NoError(t, cache.DeleteAggregatedAttestation(att3))
|
||||
|
||||
returned := cache.AggregatedAttestations()
|
||||
wanted := []*ethpb.Attestation{att2}
|
||||
wanted := []interfaces.Attestation{att2}
|
||||
assert.DeepEqual(t, wanted, returned)
|
||||
})
|
||||
|
||||
@@ -262,16 +263,16 @@ func TestKV_Aggregated_DeleteAggregatedAttestation(t *testing.T) {
|
||||
att2 := util.HydrateAttestation(ðpb.Attestation{Data: ðpb.AttestationData{Slot: 2}, AggregationBits: bitfield.Bitlist{0b110111}})
|
||||
att3 := util.HydrateAttestation(ðpb.Attestation{Data: ðpb.AttestationData{Slot: 2}, AggregationBits: bitfield.Bitlist{0b110100}})
|
||||
att4 := util.HydrateAttestation(ðpb.Attestation{Data: ðpb.AttestationData{Slot: 2}, AggregationBits: bitfield.Bitlist{0b110101}})
|
||||
atts := []*ethpb.Attestation{att1, att2, att3, att4}
|
||||
atts := []interfaces.Attestation{att1, att2, att3, att4}
|
||||
require.NoError(t, cache.SaveAggregatedAttestations(atts))
|
||||
|
||||
assert.Equal(t, 2, cache.AggregatedAttestationCount(), "Unexpected number of atts")
|
||||
require.NoError(t, cache.DeleteAggregatedAttestation(att4))
|
||||
|
||||
returned := cache.AggregatedAttestations()
|
||||
wanted := []*ethpb.Attestation{att1, att2}
|
||||
wanted := []interfaces.Attestation{att1, att2}
|
||||
sort.Slice(returned, func(i, j int) bool {
|
||||
return string(returned[i].AggregationBits) < string(returned[j].AggregationBits)
|
||||
return string(returned[i].GetAggregationBits()) < string(returned[j].GetAggregationBits())
|
||||
})
|
||||
assert.DeepEqual(t, wanted, returned)
|
||||
})
|
||||
@@ -280,7 +281,7 @@ func TestKV_Aggregated_DeleteAggregatedAttestation(t *testing.T) {
|
||||
func TestKV_Aggregated_HasAggregatedAttestation(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
existing []*ethpb.Attestation
|
||||
existing []interfaces.Attestation
|
||||
input *ethpb.Attestation
|
||||
want bool
|
||||
err error
|
||||
@@ -319,7 +320,7 @@ func TestKV_Aggregated_HasAggregatedAttestation(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "single attestation in cache with exact match",
|
||||
existing: []*ethpb.Attestation{{
|
||||
existing: []interfaces.Attestation{ðpb.Attestation{
|
||||
Data: util.HydrateAttestationData(ðpb.AttestationData{
|
||||
Slot: 1,
|
||||
}),
|
||||
@@ -334,7 +335,7 @@ func TestKV_Aggregated_HasAggregatedAttestation(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "single attestation in cache with subset aggregation",
|
||||
existing: []*ethpb.Attestation{{
|
||||
existing: []interfaces.Attestation{ðpb.Attestation{
|
||||
Data: util.HydrateAttestationData(ðpb.AttestationData{
|
||||
Slot: 1,
|
||||
}),
|
||||
@@ -349,7 +350,7 @@ func TestKV_Aggregated_HasAggregatedAttestation(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "single attestation in cache with superset aggregation",
|
||||
existing: []*ethpb.Attestation{{
|
||||
existing: []interfaces.Attestation{ðpb.Attestation{
|
||||
Data: util.HydrateAttestationData(ðpb.AttestationData{
|
||||
Slot: 1,
|
||||
}),
|
||||
@@ -364,14 +365,14 @@ func TestKV_Aggregated_HasAggregatedAttestation(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "multiple attestations with same data in cache with overlapping aggregation, input is subset",
|
||||
existing: []*ethpb.Attestation{
|
||||
{
|
||||
existing: []interfaces.Attestation{
|
||||
ðpb.Attestation{
|
||||
Data: util.HydrateAttestationData(ðpb.AttestationData{
|
||||
Slot: 1,
|
||||
}),
|
||||
AggregationBits: bitfield.Bitlist{0b1111000},
|
||||
},
|
||||
{
|
||||
ðpb.Attestation{
|
||||
Data: util.HydrateAttestationData(ðpb.AttestationData{
|
||||
Slot: 1,
|
||||
}),
|
||||
@@ -387,14 +388,14 @@ func TestKV_Aggregated_HasAggregatedAttestation(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "multiple attestations with same data in cache with overlapping aggregation and input is superset",
|
||||
existing: []*ethpb.Attestation{
|
||||
{
|
||||
existing: []interfaces.Attestation{
|
||||
ðpb.Attestation{
|
||||
Data: util.HydrateAttestationData(ðpb.AttestationData{
|
||||
Slot: 1,
|
||||
}),
|
||||
AggregationBits: bitfield.Bitlist{0b1111000},
|
||||
},
|
||||
{
|
||||
ðpb.Attestation{
|
||||
Data: util.HydrateAttestationData(ðpb.AttestationData{
|
||||
Slot: 1,
|
||||
}),
|
||||
@@ -410,14 +411,14 @@ func TestKV_Aggregated_HasAggregatedAttestation(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "multiple attestations with different data in cache",
|
||||
existing: []*ethpb.Attestation{
|
||||
{
|
||||
existing: []interfaces.Attestation{
|
||||
ðpb.Attestation{
|
||||
Data: util.HydrateAttestationData(ðpb.AttestationData{
|
||||
Slot: 2,
|
||||
}),
|
||||
AggregationBits: bitfield.Bitlist{0b1111000},
|
||||
},
|
||||
{
|
||||
ðpb.Attestation{
|
||||
Data: util.HydrateAttestationData(ðpb.AttestationData{
|
||||
Slot: 3,
|
||||
}),
|
||||
@@ -433,8 +434,8 @@ func TestKV_Aggregated_HasAggregatedAttestation(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "attestations with different bitlist lengths",
|
||||
existing: []*ethpb.Attestation{
|
||||
{
|
||||
existing: []interfaces.Attestation{
|
||||
ðpb.Attestation{
|
||||
Data: util.HydrateAttestationData(ðpb.AttestationData{
|
||||
Slot: 2,
|
||||
}),
|
||||
|
||||
@@ -2,15 +2,15 @@ package kv
|
||||
|
||||
import (
|
||||
"github.com/pkg/errors"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/interfaces"
|
||||
)
|
||||
|
||||
// SaveBlockAttestation saves an block attestation in cache.
|
||||
func (c *AttCaches) SaveBlockAttestation(att *ethpb.Attestation) error {
|
||||
func (c *AttCaches) SaveBlockAttestation(att interfaces.Attestation) error {
|
||||
if att == nil {
|
||||
return nil
|
||||
}
|
||||
r, err := hashFn(att.Data)
|
||||
r, err := hashFn(att.GetData())
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "could not tree hash attestation")
|
||||
}
|
||||
@@ -19,26 +19,26 @@ func (c *AttCaches) SaveBlockAttestation(att *ethpb.Attestation) error {
|
||||
defer c.blockAttLock.Unlock()
|
||||
atts, ok := c.blockAtt[r]
|
||||
if !ok {
|
||||
atts = make([]*ethpb.Attestation, 0, 1)
|
||||
atts = make([]interfaces.Attestation, 0, 1)
|
||||
}
|
||||
|
||||
// Ensure that this attestation is not already fully contained in an existing attestation.
|
||||
for _, a := range atts {
|
||||
if c, err := a.AggregationBits.Contains(att.AggregationBits); err != nil {
|
||||
if c, err := a.GetAggregationBits().Contains(att.GetAggregationBits()); err != nil {
|
||||
return err
|
||||
} else if c {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
c.blockAtt[r] = append(atts, ethpb.CopyAttestation(att))
|
||||
c.blockAtt[r] = append(atts, interfaces.CopyAttestation(att))
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// BlockAttestations returns the block attestations in cache.
|
||||
func (c *AttCaches) BlockAttestations() []*ethpb.Attestation {
|
||||
atts := make([]*ethpb.Attestation, 0)
|
||||
func (c *AttCaches) BlockAttestations() []interfaces.Attestation {
|
||||
atts := make([]interfaces.Attestation, 0)
|
||||
|
||||
c.blockAttLock.RLock()
|
||||
defer c.blockAttLock.RUnlock()
|
||||
@@ -50,11 +50,11 @@ func (c *AttCaches) BlockAttestations() []*ethpb.Attestation {
|
||||
}
|
||||
|
||||
// DeleteBlockAttestation deletes a block attestation in cache.
|
||||
func (c *AttCaches) DeleteBlockAttestation(att *ethpb.Attestation) error {
|
||||
func (c *AttCaches) DeleteBlockAttestation(att interfaces.Attestation) error {
|
||||
if att == nil {
|
||||
return nil
|
||||
}
|
||||
r, err := hashFn(att.Data)
|
||||
r, err := hashFn(att.GetData())
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "could not tree hash attestation")
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/prysmaticlabs/go-bitfield"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/interfaces"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/v5/testing/assert"
|
||||
"github.com/prysmaticlabs/prysm/v5/testing/require"
|
||||
@@ -17,7 +18,7 @@ func TestKV_BlockAttestation_CanSaveRetrieve(t *testing.T) {
|
||||
att1 := util.HydrateAttestation(ðpb.Attestation{Data: ðpb.AttestationData{Slot: 1}, AggregationBits: bitfield.Bitlist{0b1101}})
|
||||
att2 := util.HydrateAttestation(ðpb.Attestation{Data: ðpb.AttestationData{Slot: 2}, AggregationBits: bitfield.Bitlist{0b1101}})
|
||||
att3 := util.HydrateAttestation(ðpb.Attestation{Data: ðpb.AttestationData{Slot: 3}, AggregationBits: bitfield.Bitlist{0b1101}})
|
||||
atts := []*ethpb.Attestation{att1, att2, att3}
|
||||
atts := []interfaces.Attestation{att1, att2, att3}
|
||||
|
||||
for _, att := range atts {
|
||||
require.NoError(t, cache.SaveBlockAttestation(att))
|
||||
@@ -31,7 +32,7 @@ func TestKV_BlockAttestation_CanSaveRetrieve(t *testing.T) {
|
||||
returned := cache.BlockAttestations()
|
||||
|
||||
sort.Slice(returned, func(i, j int) bool {
|
||||
return returned[i].Data.Slot < returned[j].Data.Slot
|
||||
return returned[i].GetData().Slot < returned[j].GetData().Slot
|
||||
})
|
||||
|
||||
assert.DeepEqual(t, atts, returned)
|
||||
@@ -43,7 +44,7 @@ func TestKV_BlockAttestation_CanDelete(t *testing.T) {
|
||||
att1 := util.HydrateAttestation(ðpb.Attestation{Data: ðpb.AttestationData{Slot: 1}, AggregationBits: bitfield.Bitlist{0b1101}})
|
||||
att2 := util.HydrateAttestation(ðpb.Attestation{Data: ðpb.AttestationData{Slot: 2}, AggregationBits: bitfield.Bitlist{0b1101}})
|
||||
att3 := util.HydrateAttestation(ðpb.Attestation{Data: ðpb.AttestationData{Slot: 3}, AggregationBits: bitfield.Bitlist{0b1101}})
|
||||
atts := []*ethpb.Attestation{att1, att2, att3}
|
||||
atts := []interfaces.Attestation{att1, att2, att3}
|
||||
|
||||
for _, att := range atts {
|
||||
require.NoError(t, cache.SaveBlockAttestation(att))
|
||||
@@ -53,6 +54,6 @@ func TestKV_BlockAttestation_CanDelete(t *testing.T) {
|
||||
require.NoError(t, cache.DeleteBlockAttestation(att3))
|
||||
|
||||
returned := cache.BlockAttestations()
|
||||
wanted := []*ethpb.Attestation{att2}
|
||||
wanted := []interfaces.Attestation{att2}
|
||||
assert.DeepEqual(t, wanted, returned)
|
||||
}
|
||||
|
||||
@@ -2,11 +2,11 @@ package kv
|
||||
|
||||
import (
|
||||
"github.com/pkg/errors"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/interfaces"
|
||||
)
|
||||
|
||||
// SaveForkchoiceAttestation saves an forkchoice attestation in cache.
|
||||
func (c *AttCaches) SaveForkchoiceAttestation(att *ethpb.Attestation) error {
|
||||
func (c *AttCaches) SaveForkchoiceAttestation(att interfaces.Attestation) error {
|
||||
if att == nil {
|
||||
return nil
|
||||
}
|
||||
@@ -15,7 +15,7 @@ func (c *AttCaches) SaveForkchoiceAttestation(att *ethpb.Attestation) error {
|
||||
return errors.Wrap(err, "could not tree hash attestation")
|
||||
}
|
||||
|
||||
att = ethpb.CopyAttestation(att)
|
||||
att = interfaces.CopyAttestation(att)
|
||||
c.forkchoiceAttLock.Lock()
|
||||
defer c.forkchoiceAttLock.Unlock()
|
||||
c.forkchoiceAtt[r] = att
|
||||
@@ -24,7 +24,7 @@ func (c *AttCaches) SaveForkchoiceAttestation(att *ethpb.Attestation) error {
|
||||
}
|
||||
|
||||
// SaveForkchoiceAttestations saves a list of forkchoice attestations in cache.
|
||||
func (c *AttCaches) SaveForkchoiceAttestations(atts []*ethpb.Attestation) error {
|
||||
func (c *AttCaches) SaveForkchoiceAttestations(atts []interfaces.Attestation) error {
|
||||
for _, att := range atts {
|
||||
if err := c.SaveForkchoiceAttestation(att); err != nil {
|
||||
return err
|
||||
@@ -35,20 +35,20 @@ func (c *AttCaches) SaveForkchoiceAttestations(atts []*ethpb.Attestation) error
|
||||
}
|
||||
|
||||
// ForkchoiceAttestations returns the forkchoice attestations in cache.
|
||||
func (c *AttCaches) ForkchoiceAttestations() []*ethpb.Attestation {
|
||||
func (c *AttCaches) ForkchoiceAttestations() []interfaces.Attestation {
|
||||
c.forkchoiceAttLock.RLock()
|
||||
defer c.forkchoiceAttLock.RUnlock()
|
||||
|
||||
atts := make([]*ethpb.Attestation, 0, len(c.forkchoiceAtt))
|
||||
atts := make([]interfaces.Attestation, 0, len(c.forkchoiceAtt))
|
||||
for _, att := range c.forkchoiceAtt {
|
||||
atts = append(atts, ethpb.CopyAttestation(att) /* Copied */)
|
||||
atts = append(atts, interfaces.CopyAttestation(att) /* Copied */)
|
||||
}
|
||||
|
||||
return atts
|
||||
}
|
||||
|
||||
// DeleteForkchoiceAttestation deletes a forkchoice attestation in cache.
|
||||
func (c *AttCaches) DeleteForkchoiceAttestation(att *ethpb.Attestation) error {
|
||||
func (c *AttCaches) DeleteForkchoiceAttestation(att interfaces.Attestation) error {
|
||||
if att == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/prysmaticlabs/go-bitfield"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/interfaces"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/v5/testing/assert"
|
||||
"github.com/prysmaticlabs/prysm/v5/testing/require"
|
||||
@@ -17,7 +18,7 @@ func TestKV_Forkchoice_CanSaveRetrieve(t *testing.T) {
|
||||
att1 := util.HydrateAttestation(ðpb.Attestation{Data: ðpb.AttestationData{Slot: 1}, AggregationBits: bitfield.Bitlist{0b1101}})
|
||||
att2 := util.HydrateAttestation(ðpb.Attestation{Data: ðpb.AttestationData{Slot: 2}, AggregationBits: bitfield.Bitlist{0b1101}})
|
||||
att3 := util.HydrateAttestation(ðpb.Attestation{Data: ðpb.AttestationData{Slot: 3}, AggregationBits: bitfield.Bitlist{0b1101}})
|
||||
atts := []*ethpb.Attestation{att1, att2, att3}
|
||||
atts := []interfaces.Attestation{att1, att2, att3}
|
||||
|
||||
for _, att := range atts {
|
||||
require.NoError(t, cache.SaveForkchoiceAttestation(att))
|
||||
@@ -26,7 +27,7 @@ func TestKV_Forkchoice_CanSaveRetrieve(t *testing.T) {
|
||||
returned := cache.ForkchoiceAttestations()
|
||||
|
||||
sort.Slice(returned, func(i, j int) bool {
|
||||
return returned[i].Data.Slot < returned[j].Data.Slot
|
||||
return returned[i].GetData().Slot < returned[j].GetData().Slot
|
||||
})
|
||||
|
||||
assert.DeepEqual(t, atts, returned)
|
||||
@@ -38,7 +39,7 @@ func TestKV_Forkchoice_CanDelete(t *testing.T) {
|
||||
att1 := util.HydrateAttestation(ðpb.Attestation{Data: ðpb.AttestationData{Slot: 1}, AggregationBits: bitfield.Bitlist{0b1101}})
|
||||
att2 := util.HydrateAttestation(ðpb.Attestation{Data: ðpb.AttestationData{Slot: 2}, AggregationBits: bitfield.Bitlist{0b1101}})
|
||||
att3 := util.HydrateAttestation(ðpb.Attestation{Data: ðpb.AttestationData{Slot: 3}, AggregationBits: bitfield.Bitlist{0b1101}})
|
||||
atts := []*ethpb.Attestation{att1, att2, att3}
|
||||
atts := []interfaces.Attestation{att1, att2, att3}
|
||||
|
||||
for _, att := range atts {
|
||||
require.NoError(t, cache.SaveForkchoiceAttestation(att))
|
||||
@@ -48,7 +49,7 @@ func TestKV_Forkchoice_CanDelete(t *testing.T) {
|
||||
require.NoError(t, cache.DeleteForkchoiceAttestation(att3))
|
||||
|
||||
returned := cache.ForkchoiceAttestations()
|
||||
wanted := []*ethpb.Attestation{att2}
|
||||
wanted := []interfaces.Attestation{att2}
|
||||
assert.DeepEqual(t, wanted, returned)
|
||||
}
|
||||
|
||||
|
||||
@@ -9,8 +9,8 @@ import (
|
||||
|
||||
"github.com/patrickmn/go-cache"
|
||||
"github.com/prysmaticlabs/prysm/v5/config/params"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/interfaces"
|
||||
"github.com/prysmaticlabs/prysm/v5/crypto/hash"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
|
||||
)
|
||||
|
||||
var hashFn = hash.Proto
|
||||
@@ -20,13 +20,13 @@ var hashFn = hash.Proto
|
||||
// such are unaggregated, aggregated or attestations within a block.
|
||||
type AttCaches struct {
|
||||
aggregatedAttLock sync.RWMutex
|
||||
aggregatedAtt map[[32]byte][]*ethpb.Attestation
|
||||
aggregatedAtt map[[32]byte][]interfaces.Attestation
|
||||
unAggregateAttLock sync.RWMutex
|
||||
unAggregatedAtt map[[32]byte]*ethpb.Attestation
|
||||
unAggregatedAtt map[[32]byte]interfaces.Attestation
|
||||
forkchoiceAttLock sync.RWMutex
|
||||
forkchoiceAtt map[[32]byte]*ethpb.Attestation
|
||||
forkchoiceAtt map[[32]byte]interfaces.Attestation
|
||||
blockAttLock sync.RWMutex
|
||||
blockAtt map[[32]byte][]*ethpb.Attestation
|
||||
blockAtt map[[32]byte][]interfaces.Attestation
|
||||
seenAtt *cache.Cache
|
||||
}
|
||||
|
||||
@@ -36,10 +36,10 @@ func NewAttCaches() *AttCaches {
|
||||
secsInEpoch := time.Duration(params.BeaconConfig().SlotsPerEpoch.Mul(params.BeaconConfig().SecondsPerSlot))
|
||||
c := cache.New(secsInEpoch*time.Second, 2*secsInEpoch*time.Second)
|
||||
pool := &AttCaches{
|
||||
unAggregatedAtt: make(map[[32]byte]*ethpb.Attestation),
|
||||
aggregatedAtt: make(map[[32]byte][]*ethpb.Attestation),
|
||||
forkchoiceAtt: make(map[[32]byte]*ethpb.Attestation),
|
||||
blockAtt: make(map[[32]byte][]*ethpb.Attestation),
|
||||
unAggregatedAtt: make(map[[32]byte]interfaces.Attestation),
|
||||
aggregatedAtt: make(map[[32]byte][]interfaces.Attestation),
|
||||
forkchoiceAtt: make(map[[32]byte]interfaces.Attestation),
|
||||
blockAtt: make(map[[32]byte][]interfaces.Attestation),
|
||||
seenAtt: c,
|
||||
}
|
||||
|
||||
|
||||
@@ -4,11 +4,11 @@ import (
|
||||
"github.com/patrickmn/go-cache"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/prysmaticlabs/go-bitfield"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/interfaces"
|
||||
)
|
||||
|
||||
func (c *AttCaches) insertSeenBit(att *ethpb.Attestation) error {
|
||||
r, err := hashFn(att.Data)
|
||||
func (c *AttCaches) insertSeenBit(att interfaces.Attestation) error {
|
||||
r, err := hashFn(att.GetData())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -21,7 +21,7 @@ func (c *AttCaches) insertSeenBit(att *ethpb.Attestation) error {
|
||||
}
|
||||
alreadyExists := false
|
||||
for _, bit := range seenBits {
|
||||
if c, err := bit.Contains(att.AggregationBits); err != nil {
|
||||
if c, err := bit.Contains(att.GetAggregationBits()); err != nil {
|
||||
return err
|
||||
} else if c {
|
||||
alreadyExists = true
|
||||
@@ -29,18 +29,18 @@ func (c *AttCaches) insertSeenBit(att *ethpb.Attestation) error {
|
||||
}
|
||||
}
|
||||
if !alreadyExists {
|
||||
seenBits = append(seenBits, att.AggregationBits)
|
||||
seenBits = append(seenBits, att.GetAggregationBits())
|
||||
}
|
||||
c.seenAtt.Set(string(r[:]), seenBits, cache.DefaultExpiration /* one epoch */)
|
||||
return nil
|
||||
}
|
||||
|
||||
c.seenAtt.Set(string(r[:]), []bitfield.Bitlist{att.AggregationBits}, cache.DefaultExpiration /* one epoch */)
|
||||
c.seenAtt.Set(string(r[:]), []bitfield.Bitlist{att.GetAggregationBits()}, cache.DefaultExpiration /* one epoch */)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *AttCaches) hasSeenBit(att *ethpb.Attestation) (bool, error) {
|
||||
r, err := hashFn(att.Data)
|
||||
func (c *AttCaches) hasSeenBit(att interfaces.Attestation) (bool, error) {
|
||||
r, err := hashFn(att.GetData())
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
@@ -52,7 +52,7 @@ func (c *AttCaches) hasSeenBit(att *ethpb.Attestation) (bool, error) {
|
||||
return false, errors.New("could not convert to bitlist type")
|
||||
}
|
||||
for _, bit := range seenBits {
|
||||
if c, err := bit.Contains(att.AggregationBits); err != nil {
|
||||
if c, err := bit.Contains(att.GetAggregationBits()); err != nil {
|
||||
return false, err
|
||||
} else if c {
|
||||
return true, nil
|
||||
|
||||
@@ -5,13 +5,13 @@ import (
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/prysmaticlabs/prysm/v5/beacon-chain/core/helpers"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/interfaces"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
|
||||
"go.opencensus.io/trace"
|
||||
)
|
||||
|
||||
// SaveUnaggregatedAttestation saves an unaggregated attestation in cache.
|
||||
func (c *AttCaches) SaveUnaggregatedAttestation(att *ethpb.Attestation) error {
|
||||
func (c *AttCaches) SaveUnaggregatedAttestation(att interfaces.Attestation) error {
|
||||
if att == nil {
|
||||
return nil
|
||||
}
|
||||
@@ -31,7 +31,7 @@ func (c *AttCaches) SaveUnaggregatedAttestation(att *ethpb.Attestation) error {
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "could not tree hash attestation")
|
||||
}
|
||||
att = ethpb.CopyAttestation(att) // Copied.
|
||||
att = interfaces.CopyAttestation(att) // Copied.
|
||||
c.unAggregateAttLock.Lock()
|
||||
defer c.unAggregateAttLock.Unlock()
|
||||
c.unAggregatedAtt[r] = att
|
||||
@@ -40,7 +40,7 @@ func (c *AttCaches) SaveUnaggregatedAttestation(att *ethpb.Attestation) error {
|
||||
}
|
||||
|
||||
// SaveUnaggregatedAttestations saves a list of unaggregated attestations in cache.
|
||||
func (c *AttCaches) SaveUnaggregatedAttestations(atts []*ethpb.Attestation) error {
|
||||
func (c *AttCaches) SaveUnaggregatedAttestations(atts []interfaces.Attestation) error {
|
||||
for _, att := range atts {
|
||||
if err := c.SaveUnaggregatedAttestation(att); err != nil {
|
||||
return err
|
||||
@@ -51,18 +51,18 @@ func (c *AttCaches) SaveUnaggregatedAttestations(atts []*ethpb.Attestation) erro
|
||||
}
|
||||
|
||||
// UnaggregatedAttestations returns all the unaggregated attestations in cache.
|
||||
func (c *AttCaches) UnaggregatedAttestations() ([]*ethpb.Attestation, error) {
|
||||
func (c *AttCaches) UnaggregatedAttestations() ([]interfaces.Attestation, error) {
|
||||
c.unAggregateAttLock.RLock()
|
||||
defer c.unAggregateAttLock.RUnlock()
|
||||
unAggregatedAtts := c.unAggregatedAtt
|
||||
atts := make([]*ethpb.Attestation, 0, len(unAggregatedAtts))
|
||||
atts := make([]interfaces.Attestation, 0, len(unAggregatedAtts))
|
||||
for _, att := range unAggregatedAtts {
|
||||
seen, err := c.hasSeenBit(att)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !seen {
|
||||
atts = append(atts, ethpb.CopyAttestation(att) /* Copied */)
|
||||
atts = append(atts, interfaces.CopyAttestation(att) /* Copied */)
|
||||
}
|
||||
}
|
||||
return atts, nil
|
||||
@@ -70,18 +70,18 @@ func (c *AttCaches) UnaggregatedAttestations() ([]*ethpb.Attestation, error) {
|
||||
|
||||
// UnaggregatedAttestationsBySlotIndex returns the unaggregated attestations in cache,
|
||||
// filtered by committee index and slot.
|
||||
func (c *AttCaches) UnaggregatedAttestationsBySlotIndex(ctx context.Context, slot primitives.Slot, committeeIndex primitives.CommitteeIndex) []*ethpb.Attestation {
|
||||
func (c *AttCaches) UnaggregatedAttestationsBySlotIndex(ctx context.Context, slot primitives.Slot, committeeIndex primitives.CommitteeIndex) []interfaces.Attestation {
|
||||
_, span := trace.StartSpan(ctx, "operations.attestations.kv.UnaggregatedAttestationsBySlotIndex")
|
||||
defer span.End()
|
||||
|
||||
atts := make([]*ethpb.Attestation, 0)
|
||||
atts := make([]interfaces.Attestation, 0)
|
||||
|
||||
c.unAggregateAttLock.RLock()
|
||||
defer c.unAggregateAttLock.RUnlock()
|
||||
|
||||
unAggregatedAtts := c.unAggregatedAtt
|
||||
for _, a := range unAggregatedAtts {
|
||||
if slot == a.Data.Slot && committeeIndex == a.Data.CommitteeIndex {
|
||||
if slot == a.GetData().Slot && committeeIndex == a.GetData().CommitteeIndex {
|
||||
atts = append(atts, a)
|
||||
}
|
||||
}
|
||||
@@ -90,7 +90,7 @@ func (c *AttCaches) UnaggregatedAttestationsBySlotIndex(ctx context.Context, slo
|
||||
}
|
||||
|
||||
// DeleteUnaggregatedAttestation deletes the unaggregated attestations in cache.
|
||||
func (c *AttCaches) DeleteUnaggregatedAttestation(att *ethpb.Attestation) error {
|
||||
func (c *AttCaches) DeleteUnaggregatedAttestation(att interfaces.Attestation) error {
|
||||
if att == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ import (
|
||||
fssz "github.com/prysmaticlabs/fastssz"
|
||||
"github.com/prysmaticlabs/go-bitfield"
|
||||
fieldparams "github.com/prysmaticlabs/prysm/v5/config/fieldparams"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/interfaces"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/v5/testing/assert"
|
||||
"github.com/prysmaticlabs/prysm/v5/testing/require"
|
||||
@@ -19,7 +20,7 @@ import (
|
||||
func TestKV_Unaggregated_SaveUnaggregatedAttestation(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
att *ethpb.Attestation
|
||||
att interfaces.Attestation
|
||||
count int
|
||||
wantErrString string
|
||||
}{
|
||||
@@ -66,8 +67,8 @@ func TestKV_Unaggregated_SaveUnaggregatedAttestation(t *testing.T) {
|
||||
cache.seenAtt.Set(string(r[:]), []bitfield.Bitlist{{0xff}}, c.DefaultExpiration)
|
||||
assert.Equal(t, 0, len(cache.unAggregatedAtt), "Invalid start pool, atts: %d", len(cache.unAggregatedAtt))
|
||||
|
||||
if tt.att != nil && tt.att.Signature == nil {
|
||||
tt.att.Signature = make([]byte, fieldparams.BLSSignatureLength)
|
||||
if tt.att != nil && tt.att.GetSignature() == nil {
|
||||
tt.att.(*ethpb.Attestation).Signature = make([]byte, fieldparams.BLSSignatureLength)
|
||||
}
|
||||
|
||||
err := cache.SaveUnaggregatedAttestation(tt.att)
|
||||
@@ -85,13 +86,13 @@ func TestKV_Unaggregated_SaveUnaggregatedAttestation(t *testing.T) {
|
||||
func TestKV_Unaggregated_SaveUnaggregatedAttestations(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
atts []*ethpb.Attestation
|
||||
atts []interfaces.Attestation
|
||||
count int
|
||||
wantErrString string
|
||||
}{
|
||||
{
|
||||
name: "unaggregated only",
|
||||
atts: []*ethpb.Attestation{
|
||||
atts: []interfaces.Attestation{
|
||||
util.HydrateAttestation(ðpb.Attestation{Data: ðpb.AttestationData{Slot: 1}}),
|
||||
util.HydrateAttestation(ðpb.Attestation{Data: ðpb.AttestationData{Slot: 2}}),
|
||||
util.HydrateAttestation(ðpb.Attestation{Data: ðpb.AttestationData{Slot: 3}}),
|
||||
@@ -100,9 +101,9 @@ func TestKV_Unaggregated_SaveUnaggregatedAttestations(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "has aggregated",
|
||||
atts: []*ethpb.Attestation{
|
||||
atts: []interfaces.Attestation{
|
||||
util.HydrateAttestation(ðpb.Attestation{Data: ðpb.AttestationData{Slot: 1}}),
|
||||
{AggregationBits: bitfield.Bitlist{0b1111}, Data: ðpb.AttestationData{Slot: 2}},
|
||||
ðpb.Attestation{AggregationBits: bitfield.Bitlist{0b1111}, Data: ðpb.AttestationData{Slot: 2}},
|
||||
util.HydrateAttestation(ðpb.Attestation{Data: ðpb.AttestationData{Slot: 3}}),
|
||||
},
|
||||
wantErrString: "attestation is aggregated",
|
||||
@@ -145,14 +146,14 @@ func TestKV_Unaggregated_DeleteUnaggregatedAttestation(t *testing.T) {
|
||||
att1 := util.HydrateAttestation(ðpb.Attestation{Data: ðpb.AttestationData{Slot: 1}, AggregationBits: bitfield.Bitlist{0b101}})
|
||||
att2 := util.HydrateAttestation(ðpb.Attestation{Data: ðpb.AttestationData{Slot: 2}, AggregationBits: bitfield.Bitlist{0b110}})
|
||||
att3 := util.HydrateAttestation(ðpb.Attestation{Data: ðpb.AttestationData{Slot: 3}, AggregationBits: bitfield.Bitlist{0b110}})
|
||||
atts := []*ethpb.Attestation{att1, att2, att3}
|
||||
atts := []interfaces.Attestation{att1, att2, att3}
|
||||
require.NoError(t, cache.SaveUnaggregatedAttestations(atts))
|
||||
for _, att := range atts {
|
||||
assert.NoError(t, cache.DeleteUnaggregatedAttestation(att))
|
||||
}
|
||||
returned, err := cache.UnaggregatedAttestations()
|
||||
require.NoError(t, err)
|
||||
assert.DeepEqual(t, []*ethpb.Attestation{}, returned)
|
||||
assert.DeepEqual(t, []interfaces.Attestation{}, returned)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -168,7 +169,7 @@ func TestKV_Unaggregated_DeleteSeenUnaggregatedAttestations(t *testing.T) {
|
||||
|
||||
t.Run("none seen", func(t *testing.T) {
|
||||
cache := NewAttCaches()
|
||||
atts := []*ethpb.Attestation{
|
||||
atts := []interfaces.Attestation{
|
||||
util.HydrateAttestation(ðpb.Attestation{Data: d, AggregationBits: bitfield.Bitlist{0b1001}}),
|
||||
util.HydrateAttestation(ðpb.Attestation{Data: d, AggregationBits: bitfield.Bitlist{0b1010}}),
|
||||
util.HydrateAttestation(ðpb.Attestation{Data: d, AggregationBits: bitfield.Bitlist{0b1100}}),
|
||||
@@ -185,7 +186,7 @@ func TestKV_Unaggregated_DeleteSeenUnaggregatedAttestations(t *testing.T) {
|
||||
|
||||
t.Run("some seen", func(t *testing.T) {
|
||||
cache := NewAttCaches()
|
||||
atts := []*ethpb.Attestation{
|
||||
atts := []interfaces.Attestation{
|
||||
util.HydrateAttestation(ðpb.Attestation{Data: d, AggregationBits: bitfield.Bitlist{0b1001}}),
|
||||
util.HydrateAttestation(ðpb.Attestation{Data: d, AggregationBits: bitfield.Bitlist{0b1010}}),
|
||||
util.HydrateAttestation(ðpb.Attestation{Data: d, AggregationBits: bitfield.Bitlist{0b1100}}),
|
||||
@@ -202,15 +203,15 @@ func TestKV_Unaggregated_DeleteSeenUnaggregatedAttestations(t *testing.T) {
|
||||
assert.Equal(t, 2, cache.UnaggregatedAttestationCount())
|
||||
returned, err := cache.UnaggregatedAttestations()
|
||||
sort.Slice(returned, func(i, j int) bool {
|
||||
return bytes.Compare(returned[i].AggregationBits, returned[j].AggregationBits) < 0
|
||||
return bytes.Compare(returned[i].GetAggregationBits(), returned[j].GetAggregationBits()) < 0
|
||||
})
|
||||
require.NoError(t, err)
|
||||
assert.DeepEqual(t, []*ethpb.Attestation{atts[0], atts[2]}, returned)
|
||||
assert.DeepEqual(t, []interfaces.Attestation{atts[0], atts[2]}, returned)
|
||||
})
|
||||
|
||||
t.Run("all seen", func(t *testing.T) {
|
||||
cache := NewAttCaches()
|
||||
atts := []*ethpb.Attestation{
|
||||
atts := []interfaces.Attestation{
|
||||
util.HydrateAttestation(ðpb.Attestation{Data: d, AggregationBits: bitfield.Bitlist{0b1001}}),
|
||||
util.HydrateAttestation(ðpb.Attestation{Data: d, AggregationBits: bitfield.Bitlist{0b1010}}),
|
||||
util.HydrateAttestation(ðpb.Attestation{Data: d, AggregationBits: bitfield.Bitlist{0b1100}}),
|
||||
@@ -229,7 +230,7 @@ func TestKV_Unaggregated_DeleteSeenUnaggregatedAttestations(t *testing.T) {
|
||||
assert.Equal(t, 0, cache.UnaggregatedAttestationCount())
|
||||
returned, err := cache.UnaggregatedAttestations()
|
||||
require.NoError(t, err)
|
||||
assert.DeepEqual(t, []*ethpb.Attestation{}, returned)
|
||||
assert.DeepEqual(t, []interfaces.Attestation{}, returned)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -246,9 +247,9 @@ func TestKV_Unaggregated_UnaggregatedAttestationsBySlotIndex(t *testing.T) {
|
||||
}
|
||||
ctx := context.Background()
|
||||
returned := cache.UnaggregatedAttestationsBySlotIndex(ctx, 1, 1)
|
||||
assert.DeepEqual(t, []*ethpb.Attestation{att1}, returned)
|
||||
assert.DeepEqual(t, []interfaces.Attestation{att1}, returned)
|
||||
returned = cache.UnaggregatedAttestationsBySlotIndex(ctx, 1, 2)
|
||||
assert.DeepEqual(t, []*ethpb.Attestation{att2}, returned)
|
||||
assert.DeepEqual(t, []interfaces.Attestation{att2}, returned)
|
||||
returned = cache.UnaggregatedAttestationsBySlotIndex(ctx, 2, 1)
|
||||
assert.DeepEqual(t, []*ethpb.Attestation{att3}, returned)
|
||||
assert.DeepEqual(t, []interfaces.Attestation{att3}, returned)
|
||||
}
|
||||
|
||||
@@ -4,8 +4,8 @@ import (
|
||||
"context"
|
||||
|
||||
"github.com/prysmaticlabs/prysm/v5/beacon-chain/operations/attestations/kv"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/interfaces"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
|
||||
)
|
||||
|
||||
// Pool defines the necessary methods for Prysm attestations pool to serve
|
||||
@@ -15,30 +15,30 @@ import (
|
||||
type Pool interface {
|
||||
// For Aggregated attestations
|
||||
AggregateUnaggregatedAttestations(ctx context.Context) error
|
||||
SaveAggregatedAttestation(att *ethpb.Attestation) error
|
||||
SaveAggregatedAttestations(atts []*ethpb.Attestation) error
|
||||
AggregatedAttestations() []*ethpb.Attestation
|
||||
AggregatedAttestationsBySlotIndex(ctx context.Context, slot primitives.Slot, committeeIndex primitives.CommitteeIndex) []*ethpb.Attestation
|
||||
DeleteAggregatedAttestation(att *ethpb.Attestation) error
|
||||
HasAggregatedAttestation(att *ethpb.Attestation) (bool, error)
|
||||
SaveAggregatedAttestation(att interfaces.Attestation) error
|
||||
SaveAggregatedAttestations(atts []interfaces.Attestation) error
|
||||
AggregatedAttestations() []interfaces.Attestation
|
||||
AggregatedAttestationsBySlotIndex(ctx context.Context, slot primitives.Slot, committeeIndex primitives.CommitteeIndex) []interfaces.Attestation
|
||||
DeleteAggregatedAttestation(att interfaces.Attestation) error
|
||||
HasAggregatedAttestation(att interfaces.Attestation) (bool, error)
|
||||
AggregatedAttestationCount() int
|
||||
// For unaggregated attestations.
|
||||
SaveUnaggregatedAttestation(att *ethpb.Attestation) error
|
||||
SaveUnaggregatedAttestations(atts []*ethpb.Attestation) error
|
||||
UnaggregatedAttestations() ([]*ethpb.Attestation, error)
|
||||
UnaggregatedAttestationsBySlotIndex(ctx context.Context, slot primitives.Slot, committeeIndex primitives.CommitteeIndex) []*ethpb.Attestation
|
||||
DeleteUnaggregatedAttestation(att *ethpb.Attestation) error
|
||||
SaveUnaggregatedAttestation(att interfaces.Attestation) error
|
||||
SaveUnaggregatedAttestations(atts []interfaces.Attestation) error
|
||||
UnaggregatedAttestations() ([]interfaces.Attestation, error)
|
||||
UnaggregatedAttestationsBySlotIndex(ctx context.Context, slot primitives.Slot, committeeIndex primitives.CommitteeIndex) []interfaces.Attestation
|
||||
DeleteUnaggregatedAttestation(att interfaces.Attestation) error
|
||||
DeleteSeenUnaggregatedAttestations() (int, error)
|
||||
UnaggregatedAttestationCount() int
|
||||
// For attestations that were included in the block.
|
||||
SaveBlockAttestation(att *ethpb.Attestation) error
|
||||
BlockAttestations() []*ethpb.Attestation
|
||||
DeleteBlockAttestation(att *ethpb.Attestation) error
|
||||
SaveBlockAttestation(att interfaces.Attestation) error
|
||||
BlockAttestations() []interfaces.Attestation
|
||||
DeleteBlockAttestation(att interfaces.Attestation) error
|
||||
// For attestations to be passed to fork choice.
|
||||
SaveForkchoiceAttestation(att *ethpb.Attestation) error
|
||||
SaveForkchoiceAttestations(atts []*ethpb.Attestation) error
|
||||
ForkchoiceAttestations() []*ethpb.Attestation
|
||||
DeleteForkchoiceAttestation(att *ethpb.Attestation) error
|
||||
SaveForkchoiceAttestation(att interfaces.Attestation) error
|
||||
SaveForkchoiceAttestations(atts []interfaces.Attestation) error
|
||||
ForkchoiceAttestations() []interfaces.Attestation
|
||||
DeleteForkchoiceAttestation(att interfaces.Attestation) error
|
||||
ForkchoiceAttestationCount() int
|
||||
}
|
||||
|
||||
|
||||
@@ -9,8 +9,8 @@ import (
|
||||
"github.com/prysmaticlabs/go-bitfield"
|
||||
"github.com/prysmaticlabs/prysm/v5/config/features"
|
||||
"github.com/prysmaticlabs/prysm/v5/config/params"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/interfaces"
|
||||
"github.com/prysmaticlabs/prysm/v5/crypto/hash"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
|
||||
attaggregation "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1/attestation/aggregation/attestations"
|
||||
"github.com/prysmaticlabs/prysm/v5/time/slots"
|
||||
"go.opencensus.io/trace"
|
||||
@@ -67,7 +67,7 @@ func (s *Service) batchForkChoiceAtts(ctx context.Context) error {
|
||||
atts := append(s.cfg.Pool.AggregatedAttestations(), s.cfg.Pool.BlockAttestations()...)
|
||||
atts = append(atts, s.cfg.Pool.ForkchoiceAttestations()...)
|
||||
|
||||
attsByDataRoot := make(map[[32]byte][]*ethpb.Attestation, len(atts))
|
||||
attsByDataRoot := make(map[[32]byte][]interfaces.Attestation, len(atts))
|
||||
|
||||
// Consolidate attestations by aggregating them by similar data root.
|
||||
for _, att := range atts {
|
||||
@@ -79,7 +79,7 @@ func (s *Service) batchForkChoiceAtts(ctx context.Context) error {
|
||||
continue
|
||||
}
|
||||
|
||||
attDataRoot, err := att.Data.HashTreeRoot()
|
||||
attDataRoot, err := att.GetData().HashTreeRoot()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -103,10 +103,10 @@ func (s *Service) batchForkChoiceAtts(ctx context.Context) error {
|
||||
|
||||
// This aggregates a list of attestations using the aggregation algorithm defined in AggregateAttestations
|
||||
// and saves the attestations for fork choice.
|
||||
func (s *Service) aggregateAndSaveForkChoiceAtts(atts []*ethpb.Attestation) error {
|
||||
clonedAtts := make([]*ethpb.Attestation, len(atts))
|
||||
func (s *Service) aggregateAndSaveForkChoiceAtts(atts []interfaces.Attestation) error {
|
||||
clonedAtts := make([]interfaces.Attestation, len(atts))
|
||||
for i, a := range atts {
|
||||
clonedAtts[i] = ethpb.CopyAttestation(a)
|
||||
clonedAtts[i] = interfaces.CopyAttestation(a)
|
||||
}
|
||||
aggregatedAtts, err := attaggregation.Aggregate(clonedAtts)
|
||||
if err != nil {
|
||||
@@ -118,12 +118,12 @@ func (s *Service) aggregateAndSaveForkChoiceAtts(atts []*ethpb.Attestation) erro
|
||||
|
||||
// This checks if the attestation has previously been aggregated for fork choice
|
||||
// return true if yes, false if no.
|
||||
func (s *Service) seen(att *ethpb.Attestation) (bool, error) {
|
||||
attRoot, err := hash.Proto(att.Data)
|
||||
func (s *Service) seen(att interfaces.Attestation) (bool, error) {
|
||||
attRoot, err := hash.Proto(att.GetData())
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
incomingBits := att.AggregationBits
|
||||
incomingBits := att.GetAggregationBits()
|
||||
savedBits, ok := s.forkChoiceProcessedRoots.Get(attRoot)
|
||||
if ok {
|
||||
savedBitlist, ok := savedBits.(bitfield.Bitlist)
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/prysmaticlabs/go-bitfield"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/interfaces"
|
||||
"github.com/prysmaticlabs/prysm/v5/crypto/bls"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
|
||||
attaggregation "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1/attestation/aggregation/attestations"
|
||||
@@ -25,35 +26,35 @@ func TestBatchAttestations_Multiple(t *testing.T) {
|
||||
sig := priv.Sign([]byte("dummy_test_data"))
|
||||
var mockRoot [32]byte
|
||||
|
||||
unaggregatedAtts := []*ethpb.Attestation{
|
||||
{Data: ðpb.AttestationData{
|
||||
unaggregatedAtts := []interfaces.Attestation{
|
||||
ðpb.Attestation{Data: ðpb.AttestationData{
|
||||
Slot: 2,
|
||||
BeaconBlockRoot: mockRoot[:],
|
||||
Source: ðpb.Checkpoint{Root: mockRoot[:]},
|
||||
Target: ðpb.Checkpoint{Root: mockRoot[:]}}, AggregationBits: bitfield.Bitlist{0b100100}, Signature: sig.Marshal()},
|
||||
{Data: ðpb.AttestationData{
|
||||
ðpb.Attestation{Data: ðpb.AttestationData{
|
||||
Slot: 1,
|
||||
BeaconBlockRoot: mockRoot[:],
|
||||
Source: ðpb.Checkpoint{Root: mockRoot[:]},
|
||||
Target: ðpb.Checkpoint{Root: mockRoot[:]}}, AggregationBits: bitfield.Bitlist{0b101000}, Signature: sig.Marshal()},
|
||||
{Data: ðpb.AttestationData{
|
||||
ðpb.Attestation{Data: ðpb.AttestationData{
|
||||
Slot: 0,
|
||||
BeaconBlockRoot: mockRoot[:],
|
||||
Source: ðpb.Checkpoint{Root: mockRoot[:]},
|
||||
Target: ðpb.Checkpoint{Root: mockRoot[:]}}, AggregationBits: bitfield.Bitlist{0b100010}, Signature: sig.Marshal()},
|
||||
}
|
||||
aggregatedAtts := []*ethpb.Attestation{
|
||||
{Data: ðpb.AttestationData{
|
||||
aggregatedAtts := []interfaces.Attestation{
|
||||
ðpb.Attestation{Data: ðpb.AttestationData{
|
||||
Slot: 2,
|
||||
BeaconBlockRoot: mockRoot[:],
|
||||
Source: ðpb.Checkpoint{Root: mockRoot[:]},
|
||||
Target: ðpb.Checkpoint{Root: mockRoot[:]}}, AggregationBits: bitfield.Bitlist{0b111000}, Signature: sig.Marshal()},
|
||||
{Data: ðpb.AttestationData{
|
||||
ðpb.Attestation{Data: ðpb.AttestationData{
|
||||
Slot: 1,
|
||||
BeaconBlockRoot: mockRoot[:],
|
||||
Source: ðpb.Checkpoint{Root: mockRoot[:]},
|
||||
Target: ðpb.Checkpoint{Root: mockRoot[:]}}, AggregationBits: bitfield.Bitlist{0b100011}, Signature: sig.Marshal()},
|
||||
{Data: ðpb.AttestationData{
|
||||
ðpb.Attestation{Data: ðpb.AttestationData{
|
||||
Slot: 0,
|
||||
BeaconBlockRoot: mockRoot[:],
|
||||
Source: ðpb.Checkpoint{Root: mockRoot[:]},
|
||||
@@ -93,12 +94,12 @@ func TestBatchAttestations_Multiple(t *testing.T) {
|
||||
}
|
||||
require.NoError(t, s.batchForkChoiceAtts(context.Background()))
|
||||
|
||||
wanted, err := attaggregation.Aggregate([]*ethpb.Attestation{aggregatedAtts[0], blockAtts[0]})
|
||||
wanted, err := attaggregation.Aggregate([]interfaces.Attestation{aggregatedAtts[0], blockAtts[0]})
|
||||
require.NoError(t, err)
|
||||
aggregated, err := attaggregation.Aggregate([]*ethpb.Attestation{aggregatedAtts[1], blockAtts[1]})
|
||||
aggregated, err := attaggregation.Aggregate([]interfaces.Attestation{aggregatedAtts[1], blockAtts[1]})
|
||||
require.NoError(t, err)
|
||||
wanted = append(wanted, aggregated...)
|
||||
aggregated, err = attaggregation.Aggregate([]*ethpb.Attestation{aggregatedAtts[2], blockAtts[2]})
|
||||
aggregated, err = attaggregation.Aggregate([]interfaces.Attestation{aggregatedAtts[2], blockAtts[2]})
|
||||
require.NoError(t, err)
|
||||
|
||||
wanted = append(wanted, aggregated...)
|
||||
@@ -106,10 +107,10 @@ func TestBatchAttestations_Multiple(t *testing.T) {
|
||||
received := s.cfg.Pool.ForkchoiceAttestations()
|
||||
|
||||
sort.Slice(received, func(i, j int) bool {
|
||||
return received[i].Data.Slot < received[j].Data.Slot
|
||||
return received[i].GetData().Slot < received[j].GetData().Slot
|
||||
})
|
||||
sort.Slice(wanted, func(i, j int) bool {
|
||||
return wanted[i].Data.Slot < wanted[j].Data.Slot
|
||||
return wanted[i].GetData().Slot < wanted[j].GetData().Slot
|
||||
})
|
||||
|
||||
assert.DeepSSZEqual(t, wanted, received)
|
||||
@@ -129,18 +130,18 @@ func TestBatchAttestations_Single(t *testing.T) {
|
||||
Target: ðpb.Checkpoint{Root: mockRoot[:]},
|
||||
}
|
||||
|
||||
unaggregatedAtts := []*ethpb.Attestation{
|
||||
{Data: d, AggregationBits: bitfield.Bitlist{0b101000}, Signature: sig.Marshal()},
|
||||
{Data: d, AggregationBits: bitfield.Bitlist{0b100100}, Signature: sig.Marshal()},
|
||||
unaggregatedAtts := []interfaces.Attestation{
|
||||
ðpb.Attestation{Data: d, AggregationBits: bitfield.Bitlist{0b101000}, Signature: sig.Marshal()},
|
||||
ðpb.Attestation{Data: d, AggregationBits: bitfield.Bitlist{0b100100}, Signature: sig.Marshal()},
|
||||
}
|
||||
aggregatedAtts := []*ethpb.Attestation{
|
||||
{Data: d, AggregationBits: bitfield.Bitlist{0b101100}, Signature: sig.Marshal()},
|
||||
{Data: d, AggregationBits: bitfield.Bitlist{0b110010}, Signature: sig.Marshal()},
|
||||
aggregatedAtts := []interfaces.Attestation{
|
||||
ðpb.Attestation{Data: d, AggregationBits: bitfield.Bitlist{0b101100}, Signature: sig.Marshal()},
|
||||
ðpb.Attestation{Data: d, AggregationBits: bitfield.Bitlist{0b110010}, Signature: sig.Marshal()},
|
||||
}
|
||||
blockAtts := []*ethpb.Attestation{
|
||||
{Data: d, AggregationBits: bitfield.Bitlist{0b110010}, Signature: sig.Marshal()},
|
||||
{Data: d, AggregationBits: bitfield.Bitlist{0b100010}, Signature: sig.Marshal()},
|
||||
{Data: d, AggregationBits: bitfield.Bitlist{0b110010}, Signature: sig.Marshal()}, // Duplicated
|
||||
blockAtts := []interfaces.Attestation{
|
||||
ðpb.Attestation{Data: d, AggregationBits: bitfield.Bitlist{0b110010}, Signature: sig.Marshal()},
|
||||
ðpb.Attestation{Data: d, AggregationBits: bitfield.Bitlist{0b100010}, Signature: sig.Marshal()},
|
||||
ðpb.Attestation{Data: d, AggregationBits: bitfield.Bitlist{0b110010}, Signature: sig.Marshal()}, // Duplicated
|
||||
}
|
||||
require.NoError(t, s.cfg.Pool.SaveUnaggregatedAttestations(unaggregatedAtts))
|
||||
require.NoError(t, s.cfg.Pool.SaveAggregatedAttestations(aggregatedAtts))
|
||||
@@ -174,9 +175,9 @@ func TestAggregateAndSaveForkChoiceAtts_Single(t *testing.T) {
|
||||
Target: ðpb.Checkpoint{Root: mockRoot[:]},
|
||||
}
|
||||
|
||||
atts := []*ethpb.Attestation{
|
||||
{Data: d, AggregationBits: bitfield.Bitlist{0b101}, Signature: sig.Marshal()},
|
||||
{Data: d, AggregationBits: bitfield.Bitlist{0b110}, Signature: sig.Marshal()}}
|
||||
atts := []interfaces.Attestation{
|
||||
ðpb.Attestation{Data: d, AggregationBits: bitfield.Bitlist{0b101}, Signature: sig.Marshal()},
|
||||
ðpb.Attestation{Data: d, AggregationBits: bitfield.Bitlist{0b110}, Signature: sig.Marshal()}}
|
||||
require.NoError(t, s.aggregateAndSaveForkChoiceAtts(atts))
|
||||
|
||||
wanted, err := attaggregation.Aggregate(atts)
|
||||
@@ -204,19 +205,19 @@ func TestAggregateAndSaveForkChoiceAtts_Multiple(t *testing.T) {
|
||||
require.Equal(t, true, ok, "Entity is not of type *ethpb.AttestationData")
|
||||
d2.Slot = 2
|
||||
|
||||
atts1 := []*ethpb.Attestation{
|
||||
{Data: d, AggregationBits: bitfield.Bitlist{0b101}, Signature: sig.Marshal()},
|
||||
{Data: d, AggregationBits: bitfield.Bitlist{0b110}, Signature: sig.Marshal()},
|
||||
atts1 := []interfaces.Attestation{
|
||||
ðpb.Attestation{Data: d, AggregationBits: bitfield.Bitlist{0b101}, Signature: sig.Marshal()},
|
||||
ðpb.Attestation{Data: d, AggregationBits: bitfield.Bitlist{0b110}, Signature: sig.Marshal()},
|
||||
}
|
||||
require.NoError(t, s.aggregateAndSaveForkChoiceAtts(atts1))
|
||||
atts2 := []*ethpb.Attestation{
|
||||
{Data: d1, AggregationBits: bitfield.Bitlist{0b10110}, Signature: sig.Marshal()},
|
||||
{Data: d1, AggregationBits: bitfield.Bitlist{0b11100}, Signature: sig.Marshal()},
|
||||
{Data: d1, AggregationBits: bitfield.Bitlist{0b11000}, Signature: sig.Marshal()},
|
||||
atts2 := []interfaces.Attestation{
|
||||
ðpb.Attestation{Data: d1, AggregationBits: bitfield.Bitlist{0b10110}, Signature: sig.Marshal()},
|
||||
ðpb.Attestation{Data: d1, AggregationBits: bitfield.Bitlist{0b11100}, Signature: sig.Marshal()},
|
||||
ðpb.Attestation{Data: d1, AggregationBits: bitfield.Bitlist{0b11000}, Signature: sig.Marshal()},
|
||||
}
|
||||
require.NoError(t, s.aggregateAndSaveForkChoiceAtts(atts2))
|
||||
att3 := []*ethpb.Attestation{
|
||||
{Data: d2, AggregationBits: bitfield.Bitlist{0b1100}, Signature: sig.Marshal()},
|
||||
att3 := []interfaces.Attestation{
|
||||
ðpb.Attestation{Data: d2, AggregationBits: bitfield.Bitlist{0b1100}, Signature: sig.Marshal()},
|
||||
}
|
||||
require.NoError(t, s.aggregateAndSaveForkChoiceAtts(att3))
|
||||
|
||||
@@ -230,7 +231,7 @@ func TestAggregateAndSaveForkChoiceAtts_Multiple(t *testing.T) {
|
||||
|
||||
received := s.cfg.Pool.ForkchoiceAttestations()
|
||||
sort.Slice(received, func(i, j int) bool {
|
||||
return received[i].Data.Slot < received[j].Data.Slot
|
||||
return received[i].GetData().Slot < received[j].GetData().Slot
|
||||
})
|
||||
for i, a := range wanted {
|
||||
assert.Equal(t, true, proto.Equal(a, received[i]))
|
||||
|
||||
@@ -29,7 +29,7 @@ func (s *Service) pruneAttsPool() {
|
||||
func (s *Service) pruneExpiredAtts() {
|
||||
aggregatedAtts := s.cfg.Pool.AggregatedAttestations()
|
||||
for _, att := range aggregatedAtts {
|
||||
if s.expired(att.Data.Slot) {
|
||||
if s.expired(att.GetData().Slot) {
|
||||
if err := s.cfg.Pool.DeleteAggregatedAttestation(att); err != nil {
|
||||
log.WithError(err).Error("Could not delete expired aggregated attestation")
|
||||
}
|
||||
@@ -46,7 +46,7 @@ func (s *Service) pruneExpiredAtts() {
|
||||
return
|
||||
}
|
||||
for _, att := range unAggregatedAtts {
|
||||
if s.expired(att.Data.Slot) {
|
||||
if s.expired(att.GetData().Slot) {
|
||||
if err := s.cfg.Pool.DeleteUnaggregatedAttestation(att); err != nil {
|
||||
log.WithError(err).Error("Could not delete expired unaggregated attestation")
|
||||
}
|
||||
@@ -56,7 +56,7 @@ func (s *Service) pruneExpiredAtts() {
|
||||
|
||||
blockAtts := s.cfg.Pool.BlockAttestations()
|
||||
for _, att := range blockAtts {
|
||||
if s.expired(att.Data.Slot) {
|
||||
if s.expired(att.GetData().Slot) {
|
||||
if err := s.cfg.Pool.DeleteBlockAttestation(att); err != nil {
|
||||
log.WithError(err).Error("Could not delete expired block attestation")
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ import (
|
||||
"github.com/prysmaticlabs/prysm/v5/async"
|
||||
fieldparams "github.com/prysmaticlabs/prysm/v5/config/fieldparams"
|
||||
"github.com/prysmaticlabs/prysm/v5/config/params"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/interfaces"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/v5/testing/assert"
|
||||
@@ -31,15 +32,15 @@ func TestPruneExpired_Ticker(t *testing.T) {
|
||||
|
||||
ad2 := util.HydrateAttestationData(ðpb.AttestationData{Slot: 1})
|
||||
|
||||
atts := []*ethpb.Attestation{
|
||||
{Data: ad1, AggregationBits: bitfield.Bitlist{0b1000, 0b1}, Signature: make([]byte, fieldparams.BLSSignatureLength)},
|
||||
{Data: ad2, AggregationBits: bitfield.Bitlist{0b1000, 0b1}, Signature: make([]byte, fieldparams.BLSSignatureLength)},
|
||||
atts := []interfaces.Attestation{
|
||||
ðpb.Attestation{Data: ad1, AggregationBits: bitfield.Bitlist{0b1000, 0b1}, Signature: make([]byte, fieldparams.BLSSignatureLength)},
|
||||
ðpb.Attestation{Data: ad2, AggregationBits: bitfield.Bitlist{0b1000, 0b1}, Signature: make([]byte, fieldparams.BLSSignatureLength)},
|
||||
}
|
||||
require.NoError(t, s.cfg.Pool.SaveUnaggregatedAttestations(atts))
|
||||
require.Equal(t, 2, s.cfg.Pool.UnaggregatedAttestationCount(), "Unexpected number of attestations")
|
||||
atts = []*ethpb.Attestation{
|
||||
{Data: ad1, AggregationBits: bitfield.Bitlist{0b1101, 0b1}, Signature: make([]byte, fieldparams.BLSSignatureLength)},
|
||||
{Data: ad2, AggregationBits: bitfield.Bitlist{0b1101, 0b1}, Signature: make([]byte, fieldparams.BLSSignatureLength)},
|
||||
atts = []interfaces.Attestation{
|
||||
ðpb.Attestation{Data: ad1, AggregationBits: bitfield.Bitlist{0b1101, 0b1}, Signature: make([]byte, fieldparams.BLSSignatureLength)},
|
||||
ðpb.Attestation{Data: ad2, AggregationBits: bitfield.Bitlist{0b1101, 0b1}, Signature: make([]byte, fieldparams.BLSSignatureLength)},
|
||||
}
|
||||
require.NoError(t, s.cfg.Pool.SaveAggregatedAttestations(atts))
|
||||
assert.Equal(t, 2, s.cfg.Pool.AggregatedAttestationCount())
|
||||
@@ -57,17 +58,17 @@ func TestPruneExpired_Ticker(t *testing.T) {
|
||||
atts, err := s.cfg.Pool.UnaggregatedAttestations()
|
||||
require.NoError(t, err)
|
||||
for _, attestation := range atts {
|
||||
if attestation.Data.Slot == 0 {
|
||||
if attestation.GetData().Slot == 0 {
|
||||
return
|
||||
}
|
||||
}
|
||||
for _, attestation := range s.cfg.Pool.AggregatedAttestations() {
|
||||
if attestation.Data.Slot == 0 {
|
||||
if attestation.GetData().Slot == 0 {
|
||||
return
|
||||
}
|
||||
}
|
||||
for _, attestation := range s.cfg.Pool.BlockAttestations() {
|
||||
if attestation.Data.Slot == 0 {
|
||||
if attestation.GetData().Slot == 0 {
|
||||
return
|
||||
}
|
||||
}
|
||||
@@ -96,7 +97,7 @@ func TestPruneExpired_PruneExpiredAtts(t *testing.T) {
|
||||
att2 := ðpb.Attestation{Data: ad1, AggregationBits: bitfield.Bitlist{0b1111}}
|
||||
att3 := ðpb.Attestation{Data: ad2, AggregationBits: bitfield.Bitlist{0b1101}}
|
||||
att4 := ðpb.Attestation{Data: ad2, AggregationBits: bitfield.Bitlist{0b1110}}
|
||||
atts := []*ethpb.Attestation{att1, att2, att3, att4}
|
||||
atts := []interfaces.Attestation{att1, att2, att3, att4}
|
||||
require.NoError(t, s.cfg.Pool.SaveAggregatedAttestations(atts))
|
||||
for _, att := range atts {
|
||||
require.NoError(t, s.cfg.Pool.SaveBlockAttestation(att))
|
||||
@@ -108,12 +109,12 @@ func TestPruneExpired_PruneExpiredAtts(t *testing.T) {
|
||||
s.pruneExpiredAtts()
|
||||
// All the attestations on slot 0 should be pruned.
|
||||
for _, attestation := range s.cfg.Pool.AggregatedAttestations() {
|
||||
if attestation.Data.Slot == 0 {
|
||||
if attestation.GetData().Slot == 0 {
|
||||
t.Error("Should be pruned")
|
||||
}
|
||||
}
|
||||
for _, attestation := range s.cfg.Pool.BlockAttestations() {
|
||||
if attestation.Data.Slot == 0 {
|
||||
if attestation.GetData().Slot == 0 {
|
||||
t.Error("Should be pruned")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ go_library(
|
||||
"//beacon-chain/core/time:go_default_library",
|
||||
"//beacon-chain/state:go_default_library",
|
||||
"//config/params:go_default_library",
|
||||
"//consensus-types/interfaces:go_default_library",
|
||||
"//consensus-types/primitives:go_default_library",
|
||||
"//container/slice:go_default_library",
|
||||
"//proto/prysm/v1alpha1:go_default_library",
|
||||
@@ -47,6 +48,7 @@ go_test(
|
||||
"//beacon-chain/state:go_default_library",
|
||||
"//config/fieldparams:go_default_library",
|
||||
"//config/params:go_default_library",
|
||||
"//consensus-types/interfaces:go_default_library",
|
||||
"//consensus-types/primitives:go_default_library",
|
||||
"//crypto/bls:go_default_library",
|
||||
"//proto/prysm/v1alpha1:go_default_library",
|
||||
|
||||
@@ -8,6 +8,7 @@ go_library(
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//beacon-chain/state:go_default_library",
|
||||
"//consensus-types/interfaces:go_default_library",
|
||||
"//proto/prysm/v1alpha1:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -4,17 +4,18 @@ import (
|
||||
"context"
|
||||
|
||||
"github.com/prysmaticlabs/prysm/v5/beacon-chain/state"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/interfaces"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
|
||||
)
|
||||
|
||||
// PoolMock is a fake implementation of PoolManager.
|
||||
type PoolMock struct {
|
||||
PendingAttSlashings []*ethpb.AttesterSlashing
|
||||
PendingAttSlashings []interfaces.AttesterSlashing
|
||||
PendingPropSlashings []*ethpb.ProposerSlashing
|
||||
}
|
||||
|
||||
// PendingAttesterSlashings --
|
||||
func (m *PoolMock) PendingAttesterSlashings(_ context.Context, _ state.ReadOnlyBeaconState, _ bool) []*ethpb.AttesterSlashing {
|
||||
func (m *PoolMock) PendingAttesterSlashings(_ context.Context, _ state.ReadOnlyBeaconState, _ bool) []interfaces.AttesterSlashing {
|
||||
return m.PendingAttSlashings
|
||||
}
|
||||
|
||||
@@ -24,7 +25,7 @@ func (m *PoolMock) PendingProposerSlashings(_ context.Context, _ state.ReadOnlyB
|
||||
}
|
||||
|
||||
// InsertAttesterSlashing --
|
||||
func (m *PoolMock) InsertAttesterSlashing(_ context.Context, _ state.ReadOnlyBeaconState, slashing *ethpb.AttesterSlashing) error {
|
||||
func (m *PoolMock) InsertAttesterSlashing(_ context.Context, _ state.ReadOnlyBeaconState, slashing interfaces.AttesterSlashing) error {
|
||||
m.PendingAttSlashings = append(m.PendingAttSlashings, slashing)
|
||||
return nil
|
||||
}
|
||||
@@ -36,7 +37,7 @@ func (m *PoolMock) InsertProposerSlashing(_ context.Context, _ state.ReadOnlyBea
|
||||
}
|
||||
|
||||
// MarkIncludedAttesterSlashing --
|
||||
func (*PoolMock) MarkIncludedAttesterSlashing(_ *ethpb.AttesterSlashing) {
|
||||
func (*PoolMock) MarkIncludedAttesterSlashing(_ interfaces.AttesterSlashing) {
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ import (
|
||||
"github.com/prysmaticlabs/prysm/v5/beacon-chain/core/time"
|
||||
"github.com/prysmaticlabs/prysm/v5/beacon-chain/state"
|
||||
"github.com/prysmaticlabs/prysm/v5/config/params"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/interfaces"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
|
||||
"github.com/prysmaticlabs/prysm/v5/container/slice"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
|
||||
@@ -30,7 +31,7 @@ func NewPool() *Pool {
|
||||
// PendingAttesterSlashings returns attester slashings that are able to be included into a block.
|
||||
// This method will return the amount of pending attester slashings for a block transition unless parameter `noLimit` is true
|
||||
// to indicate the request is for noLimit pending items.
|
||||
func (p *Pool) PendingAttesterSlashings(ctx context.Context, state state.ReadOnlyBeaconState, noLimit bool) []*ethpb.AttesterSlashing {
|
||||
func (p *Pool) PendingAttesterSlashings(ctx context.Context, state state.ReadOnlyBeaconState, noLimit bool) []interfaces.AttesterSlashing {
|
||||
p.lock.Lock()
|
||||
defer p.lock.Unlock()
|
||||
_, span := trace.StartSpan(ctx, "operations.PendingAttesterSlashing")
|
||||
@@ -46,7 +47,7 @@ func (p *Pool) PendingAttesterSlashings(ctx context.Context, state state.ReadOnl
|
||||
if noLimit {
|
||||
maxSlashings = uint64(len(p.pendingAttesterSlashing))
|
||||
}
|
||||
pending := make([]*ethpb.AttesterSlashing, 0, maxSlashings)
|
||||
pending := make([]interfaces.AttesterSlashing, 0, maxSlashings)
|
||||
for i := 0; i < len(p.pendingAttesterSlashing); i++ {
|
||||
if uint64(len(pending)) >= maxSlashings {
|
||||
break
|
||||
@@ -63,7 +64,10 @@ func (p *Pool) PendingAttesterSlashings(ctx context.Context, state state.ReadOnl
|
||||
continue
|
||||
}
|
||||
attSlashing := slashing.attesterSlashing
|
||||
slashedVal := slice.IntersectionUint64(attSlashing.Attestation_1.AttestingIndices, attSlashing.Attestation_2.AttestingIndices)
|
||||
slashedVal := slice.IntersectionUint64(
|
||||
attSlashing.GetFirstAttestation().GetAttestingIndices(),
|
||||
attSlashing.GetSecondAttestation().GetAttestingIndices(),
|
||||
)
|
||||
for _, idx := range slashedVal {
|
||||
included[primitives.ValidatorIndex(idx)] = true
|
||||
}
|
||||
@@ -118,7 +122,7 @@ func (p *Pool) PendingProposerSlashings(ctx context.Context, state state.ReadOnl
|
||||
func (p *Pool) InsertAttesterSlashing(
|
||||
ctx context.Context,
|
||||
state state.ReadOnlyBeaconState,
|
||||
slashing *ethpb.AttesterSlashing,
|
||||
slashing interfaces.AttesterSlashing,
|
||||
) error {
|
||||
p.lock.Lock()
|
||||
defer p.lock.Unlock()
|
||||
@@ -129,7 +133,7 @@ func (p *Pool) InsertAttesterSlashing(
|
||||
return errors.Wrap(err, "could not verify attester slashing")
|
||||
}
|
||||
|
||||
slashedVal := slice.IntersectionUint64(slashing.Attestation_1.AttestingIndices, slashing.Attestation_2.AttestingIndices)
|
||||
slashedVal := slice.IntersectionUint64(slashing.GetFirstAttestation().GetAttestingIndices(), slashing.GetSecondAttestation().GetAttestingIndices())
|
||||
cantSlash := make([]uint64, 0, len(slashedVal))
|
||||
slashingReason := ""
|
||||
for _, val := range slashedVal {
|
||||
@@ -229,10 +233,10 @@ func (p *Pool) InsertProposerSlashing(
|
||||
// MarkIncludedAttesterSlashing is used when an attester slashing has been included in a beacon block.
|
||||
// Every block seen by this node that contains proposer slashings should call this method to include
|
||||
// the proposer slashings.
|
||||
func (p *Pool) MarkIncludedAttesterSlashing(as *ethpb.AttesterSlashing) {
|
||||
func (p *Pool) MarkIncludedAttesterSlashing(as interfaces.AttesterSlashing) {
|
||||
p.lock.Lock()
|
||||
defer p.lock.Unlock()
|
||||
slashedVal := slice.IntersectionUint64(as.Attestation_1.AttestingIndices, as.Attestation_2.AttestingIndices)
|
||||
slashedVal := slice.IntersectionUint64(as.GetFirstAttestation().GetAttestingIndices(), as.GetSecondAttestation().GetAttestingIndices())
|
||||
for _, val := range slashedVal {
|
||||
i := sort.Search(len(p.pendingAttesterSlashing), func(i int) bool {
|
||||
return uint64(p.pendingAttesterSlashing[i].validatorToSlash) >= val
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
|
||||
"github.com/prysmaticlabs/prysm/v5/beacon-chain/state"
|
||||
"github.com/prysmaticlabs/prysm/v5/config/params"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/interfaces"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
|
||||
"github.com/prysmaticlabs/prysm/v5/crypto/bls"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
|
||||
@@ -314,7 +315,7 @@ func TestPool_InsertAttesterSlashing_SigFailsVerify_ClearPool(t *testing.T) {
|
||||
// We mess up the signature of the second slashing.
|
||||
badSig := make([]byte, 96)
|
||||
copy(badSig, "muahaha")
|
||||
pendingSlashings[1].attesterSlashing.Attestation_1.Signature = badSig
|
||||
pendingSlashings[1].attesterSlashing.(*ethpb.AttesterSlashing).Attestation_1.Signature = badSig
|
||||
slashings[1].Attestation_1.Signature = badSig
|
||||
p := &Pool{
|
||||
pendingAttesterSlashing: make([]*PendingAttesterSlashing, 0),
|
||||
@@ -455,7 +456,7 @@ func TestPool_PendingAttesterSlashings(t *testing.T) {
|
||||
params.SetupTestConfigCleanup(t)
|
||||
beaconState, privKeys := util.DeterministicGenesisState(t, 64)
|
||||
pendingSlashings := make([]*PendingAttesterSlashing, 20)
|
||||
slashings := make([]*ethpb.AttesterSlashing, 20)
|
||||
slashings := make([]interfaces.AttesterSlashing, 20)
|
||||
for i := 0; i < len(pendingSlashings); i++ {
|
||||
sl, err := util.GenerateAttesterSlashingForValidator(beaconState, privKeys[i], primitives.ValidatorIndex(i))
|
||||
require.NoError(t, err)
|
||||
@@ -468,14 +469,14 @@ func TestPool_PendingAttesterSlashings(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
fields fields
|
||||
want []*ethpb.AttesterSlashing
|
||||
want []interfaces.AttesterSlashing
|
||||
}{
|
||||
{
|
||||
name: "Empty list",
|
||||
fields: fields{
|
||||
pending: []*PendingAttesterSlashing{},
|
||||
},
|
||||
want: []*ethpb.AttesterSlashing{},
|
||||
want: []interfaces.AttesterSlashing{},
|
||||
},
|
||||
{
|
||||
name: "All pending",
|
||||
@@ -530,7 +531,7 @@ func TestPool_PendingAttesterSlashings_Slashed(t *testing.T) {
|
||||
require.NoError(t, beaconState.UpdateValidatorAtIndex(5, val))
|
||||
pendingSlashings := make([]*PendingAttesterSlashing, 20)
|
||||
pendingSlashings2 := make([]*PendingAttesterSlashing, 20)
|
||||
slashings := make([]*ethpb.AttesterSlashing, 20)
|
||||
slashings := make([]interfaces.AttesterSlashing, 20)
|
||||
for i := 0; i < len(pendingSlashings); i++ {
|
||||
sl, err := util.GenerateAttesterSlashingForValidator(beaconState, privKeys[i], primitives.ValidatorIndex(i))
|
||||
require.NoError(t, err)
|
||||
@@ -548,7 +549,7 @@ func TestPool_PendingAttesterSlashings_Slashed(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
fields fields
|
||||
want []*ethpb.AttesterSlashing
|
||||
want []interfaces.AttesterSlashing
|
||||
}{
|
||||
{
|
||||
name: "One item",
|
||||
@@ -588,7 +589,7 @@ func TestPool_PendingAttesterSlashings_NoDuplicates(t *testing.T) {
|
||||
params.OverrideBeaconConfig(conf)
|
||||
beaconState, privKeys := util.DeterministicGenesisState(t, 64)
|
||||
pendingSlashings := make([]*PendingAttesterSlashing, 3)
|
||||
slashings := make([]*ethpb.AttesterSlashing, 3)
|
||||
slashings := make([]interfaces.AttesterSlashing, 3)
|
||||
for i := 0; i < 2; i++ {
|
||||
sl, err := util.GenerateAttesterSlashingForValidator(beaconState, privKeys[i], primitives.ValidatorIndex(i))
|
||||
require.NoError(t, err)
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"sync"
|
||||
|
||||
"github.com/prysmaticlabs/prysm/v5/beacon-chain/state"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/interfaces"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
|
||||
)
|
||||
@@ -14,7 +15,7 @@ type PoolInserter interface {
|
||||
InsertAttesterSlashing(
|
||||
ctx context.Context,
|
||||
state state.ReadOnlyBeaconState,
|
||||
slashing *ethpb.AttesterSlashing,
|
||||
slashing interfaces.AttesterSlashing,
|
||||
) error
|
||||
InsertProposerSlashing(
|
||||
ctx context.Context,
|
||||
@@ -27,9 +28,9 @@ type PoolInserter interface {
|
||||
// This pool is used by proposers to insert data into new blocks.
|
||||
type PoolManager interface {
|
||||
PoolInserter
|
||||
PendingAttesterSlashings(ctx context.Context, state state.ReadOnlyBeaconState, noLimit bool) []*ethpb.AttesterSlashing
|
||||
PendingAttesterSlashings(ctx context.Context, state state.ReadOnlyBeaconState, noLimit bool) []interfaces.AttesterSlashing
|
||||
PendingProposerSlashings(ctx context.Context, state state.ReadOnlyBeaconState, noLimit bool) []*ethpb.ProposerSlashing
|
||||
MarkIncludedAttesterSlashing(as *ethpb.AttesterSlashing)
|
||||
MarkIncludedAttesterSlashing(as interfaces.AttesterSlashing)
|
||||
MarkIncludedProposerSlashing(ps *ethpb.ProposerSlashing)
|
||||
}
|
||||
|
||||
@@ -44,6 +45,6 @@ type Pool struct {
|
||||
// PendingAttesterSlashing represents an attester slashing in the operation pool.
|
||||
// Allows for easy binary searching of included validator indexes.
|
||||
type PendingAttesterSlashing struct {
|
||||
attesterSlashing *ethpb.AttesterSlashing
|
||||
attesterSlashing interfaces.AttesterSlashing
|
||||
validatorToSlash primitives.ValidatorIndex
|
||||
}
|
||||
|
||||
@@ -57,6 +57,7 @@ go_library(
|
||||
"//cmd/beacon-chain/flags:go_default_library",
|
||||
"//config/features:go_default_library",
|
||||
"//config/params:go_default_library",
|
||||
"//consensus-types/interfaces:go_default_library",
|
||||
"//consensus-types/primitives:go_default_library",
|
||||
"//consensus-types/wrapper:go_default_library",
|
||||
"//container/leaky-bucket:go_default_library",
|
||||
|
||||
@@ -12,6 +12,7 @@ import (
|
||||
"github.com/prysmaticlabs/prysm/v5/beacon-chain/core/altair"
|
||||
"github.com/prysmaticlabs/prysm/v5/beacon-chain/core/helpers"
|
||||
"github.com/prysmaticlabs/prysm/v5/config/params"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/interfaces"
|
||||
"github.com/prysmaticlabs/prysm/v5/crypto/hash"
|
||||
"github.com/prysmaticlabs/prysm/v5/monitoring/tracing"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
|
||||
@@ -56,7 +57,7 @@ func (s *Service) Broadcast(ctx context.Context, msg proto.Message) error {
|
||||
|
||||
// BroadcastAttestation broadcasts an attestation to the p2p network, the message is assumed to be
|
||||
// broadcasted to the current fork.
|
||||
func (s *Service) BroadcastAttestation(ctx context.Context, subnet uint64, att *ethpb.Attestation) error {
|
||||
func (s *Service) BroadcastAttestation(ctx context.Context, subnet uint64, att interfaces.Attestation) error {
|
||||
if att == nil {
|
||||
return errors.New("attempted to broadcast nil attestation")
|
||||
}
|
||||
@@ -96,7 +97,7 @@ func (s *Service) BroadcastSyncCommitteeMessage(ctx context.Context, subnet uint
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *Service) internalBroadcastAttestation(ctx context.Context, subnet uint64, att *ethpb.Attestation, forkDigest [4]byte) {
|
||||
func (s *Service) internalBroadcastAttestation(ctx context.Context, subnet uint64, att interfaces.Attestation, forkDigest [4]byte) {
|
||||
_, span := trace.StartSpan(ctx, "p2p.internalBroadcastAttestation")
|
||||
defer span.End()
|
||||
ctx = trace.NewContext(context.Background(), span) // clear parent context / deadline.
|
||||
@@ -112,8 +113,8 @@ func (s *Service) internalBroadcastAttestation(ctx context.Context, subnet uint6
|
||||
|
||||
span.AddAttributes(
|
||||
trace.BoolAttribute("hasPeer", hasPeer),
|
||||
trace.Int64Attribute("slot", int64(att.Data.Slot)), // lint:ignore uintcast -- It's safe to do this for tracing.
|
||||
trace.Int64Attribute("subnet", int64(subnet)), // lint:ignore uintcast -- It's safe to do this for tracing.
|
||||
trace.Int64Attribute("slot", int64(att.GetData().Slot)), // lint:ignore uintcast -- It's safe to do this for tracing.
|
||||
trace.Int64Attribute("subnet", int64(subnet)), // lint:ignore uintcast -- It's safe to do this for tracing.
|
||||
)
|
||||
|
||||
if !hasPeer {
|
||||
@@ -138,9 +139,9 @@ func (s *Service) internalBroadcastAttestation(ctx context.Context, subnet uint6
|
||||
// In the event our attestation is outdated and beyond the
|
||||
// acceptable threshold, we exit early and do not broadcast it.
|
||||
currSlot := slots.CurrentSlot(uint64(s.genesisTime.Unix()))
|
||||
if err := helpers.ValidateAttestationTime(att.Data.Slot, s.genesisTime, params.BeaconConfig().MaximumGossipClockDisparityDuration()); err != nil {
|
||||
if err := helpers.ValidateAttestationTime(att.GetData().Slot, s.genesisTime, params.BeaconConfig().MaximumGossipClockDisparityDuration()); err != nil {
|
||||
log.WithFields(logrus.Fields{
|
||||
"attestationSlot": att.Data.Slot,
|
||||
"attestationSlot": att.GetData().Slot,
|
||||
"currentSlot": currSlot,
|
||||
}).WithError(err).Warning("Attestation is too old to broadcast, discarding it")
|
||||
return
|
||||
|
||||
@@ -12,6 +12,7 @@ import (
|
||||
"github.com/multiformats/go-multiaddr"
|
||||
"github.com/prysmaticlabs/prysm/v5/beacon-chain/p2p/encoder"
|
||||
"github.com/prysmaticlabs/prysm/v5/beacon-chain/p2p/peers"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/interfaces"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1/metadata"
|
||||
"google.golang.org/protobuf/proto"
|
||||
@@ -33,7 +34,7 @@ type P2P interface {
|
||||
// Broadcaster broadcasts messages to peers over the p2p pubsub protocol.
|
||||
type Broadcaster interface {
|
||||
Broadcast(context.Context, proto.Message) error
|
||||
BroadcastAttestation(ctx context.Context, subnet uint64, att *ethpb.Attestation) error
|
||||
BroadcastAttestation(ctx context.Context, subnet uint64, att interfaces.Attestation) error
|
||||
BroadcastSyncCommitteeMessage(ctx context.Context, subnet uint64, sMsg *ethpb.SyncCommitteeMessage) error
|
||||
BroadcastBlob(ctx context.Context, subnet uint64, blob *ethpb.BlobSidecar) error
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ go_library(
|
||||
"//beacon-chain/p2p/encoder:go_default_library",
|
||||
"//beacon-chain/p2p/peers:go_default_library",
|
||||
"//beacon-chain/p2p/peers/scorers:go_default_library",
|
||||
"//consensus-types/interfaces:go_default_library",
|
||||
"//proto/prysm/v1alpha1:go_default_library",
|
||||
"//proto/prysm/v1alpha1/metadata:go_default_library",
|
||||
"@com_github_ethereum_go_ethereum//crypto:go_default_library",
|
||||
|
||||
@@ -12,6 +12,7 @@ import (
|
||||
"github.com/multiformats/go-multiaddr"
|
||||
"github.com/prysmaticlabs/prysm/v5/beacon-chain/p2p/encoder"
|
||||
"github.com/prysmaticlabs/prysm/v5/beacon-chain/p2p/peers"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/interfaces"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1/metadata"
|
||||
"google.golang.org/protobuf/proto"
|
||||
@@ -134,7 +135,7 @@ func (_ *FakeP2P) Broadcast(_ context.Context, _ proto.Message) error {
|
||||
}
|
||||
|
||||
// BroadcastAttestation -- fake.
|
||||
func (_ *FakeP2P) BroadcastAttestation(_ context.Context, _ uint64, _ *ethpb.Attestation) error {
|
||||
func (_ *FakeP2P) BroadcastAttestation(_ context.Context, _ uint64, _ interfaces.Attestation) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/interfaces"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
|
||||
"google.golang.org/protobuf/proto"
|
||||
)
|
||||
@@ -13,7 +14,7 @@ import (
|
||||
type MockBroadcaster struct {
|
||||
BroadcastCalled atomic.Bool
|
||||
BroadcastMessages []proto.Message
|
||||
BroadcastAttestations []*ethpb.Attestation
|
||||
BroadcastAttestations []interfaces.Attestation
|
||||
msgLock sync.Mutex
|
||||
attLock sync.Mutex
|
||||
}
|
||||
@@ -28,7 +29,7 @@ func (m *MockBroadcaster) Broadcast(_ context.Context, msg proto.Message) error
|
||||
}
|
||||
|
||||
// BroadcastAttestation records a broadcast occurred.
|
||||
func (m *MockBroadcaster) BroadcastAttestation(_ context.Context, _ uint64, a *ethpb.Attestation) error {
|
||||
func (m *MockBroadcaster) BroadcastAttestation(_ context.Context, _ uint64, a interfaces.Attestation) error {
|
||||
m.BroadcastCalled.Store(true)
|
||||
m.attLock.Lock()
|
||||
defer m.attLock.Unlock()
|
||||
|
||||
@@ -25,6 +25,7 @@ import (
|
||||
"github.com/prysmaticlabs/prysm/v5/beacon-chain/p2p/encoder"
|
||||
"github.com/prysmaticlabs/prysm/v5/beacon-chain/p2p/peers"
|
||||
"github.com/prysmaticlabs/prysm/v5/beacon-chain/p2p/peers/scorers"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/interfaces"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1/metadata"
|
||||
"github.com/sirupsen/logrus"
|
||||
@@ -166,7 +167,7 @@ func (p *TestP2P) Broadcast(_ context.Context, _ proto.Message) error {
|
||||
}
|
||||
|
||||
// BroadcastAttestation broadcasts an attestation.
|
||||
func (p *TestP2P) BroadcastAttestation(_ context.Context, _ uint64, _ *ethpb.Attestation) error {
|
||||
func (p *TestP2P) BroadcastAttestation(_ context.Context, _ uint64, _ interfaces.Attestation) error {
|
||||
p.BroadcastCalled.Store(true)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -878,7 +878,13 @@ func (s *Server) GetBlockAttestations(w http.ResponseWriter, r *http.Request) {
|
||||
consensusAtts := blk.Block().Body().Attestations()
|
||||
atts := make([]*structs.Attestation, len(consensusAtts))
|
||||
for i, att := range consensusAtts {
|
||||
atts[i] = structs.AttFromConsensus(att)
|
||||
a, ok := att.(*eth.Attestation)
|
||||
if ok {
|
||||
atts[i] = structs.AttFromConsensus(a)
|
||||
} else {
|
||||
httputil.HandleError(w, fmt.Sprintf("unable to convert consensus attestations of type %T", att), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
}
|
||||
root, err := blk.Block().HashTreeRoot()
|
||||
if err != nil {
|
||||
|
||||
@@ -58,7 +58,13 @@ func (s *Server) ListAttestations(w http.ResponseWriter, r *http.Request) {
|
||||
if isEmptyReq {
|
||||
allAtts := make([]*structs.Attestation, len(attestations))
|
||||
for i, att := range attestations {
|
||||
allAtts[i] = structs.AttFromConsensus(att)
|
||||
a, ok := att.(*eth.Attestation)
|
||||
if ok {
|
||||
allAtts[i] = structs.AttFromConsensus(a)
|
||||
} else {
|
||||
httputil.HandleError(w, fmt.Sprintf("unable to convert attestations of type %T", att), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
}
|
||||
httputil.WriteJson(w, &structs.ListAttestationsResponse{Data: allAtts})
|
||||
return
|
||||
@@ -67,11 +73,17 @@ func (s *Server) ListAttestations(w http.ResponseWriter, r *http.Request) {
|
||||
bothDefined := rawSlot != "" && rawCommitteeIndex != ""
|
||||
filteredAtts := make([]*structs.Attestation, 0, len(attestations))
|
||||
for _, att := range attestations {
|
||||
committeeIndexMatch := rawCommitteeIndex != "" && att.Data.CommitteeIndex == primitives.CommitteeIndex(committeeIndex)
|
||||
slotMatch := rawSlot != "" && att.Data.Slot == primitives.Slot(slot)
|
||||
committeeIndexMatch := rawCommitteeIndex != "" && att.GetData().CommitteeIndex == primitives.CommitteeIndex(committeeIndex)
|
||||
slotMatch := rawSlot != "" && att.GetData().Slot == primitives.Slot(slot)
|
||||
shouldAppend := (bothDefined && committeeIndexMatch && slotMatch) || (!bothDefined && (committeeIndexMatch || slotMatch))
|
||||
if shouldAppend {
|
||||
filteredAtts = append(filteredAtts, structs.AttFromConsensus(att))
|
||||
a, ok := att.(*eth.Attestation)
|
||||
if ok {
|
||||
filteredAtts = append(filteredAtts, structs.AttFromConsensus(a))
|
||||
} else {
|
||||
httputil.HandleError(w, fmt.Sprintf("unable to convert attestations of type %T", att), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
httputil.WriteJson(w, &structs.ListAttestationsResponse{Data: filteredAtts})
|
||||
@@ -455,7 +467,17 @@ func (s *Server) GetAttesterSlashings(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
sourceSlashings := s.SlashingsPool.PendingAttesterSlashings(ctx, headState, true /* return unlimited slashings */)
|
||||
slashings := structs.AttesterSlashingsFromConsensus(sourceSlashings)
|
||||
ss := make([]*eth.AttesterSlashing, 0, len(sourceSlashings))
|
||||
for _, slashing := range sourceSlashings {
|
||||
s, ok := slashing.(*eth.AttesterSlashing)
|
||||
if ok {
|
||||
ss = append(ss, s)
|
||||
} else {
|
||||
httputil.HandleError(w, fmt.Sprintf("unable to convert slashing of type %T", slashing), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
}
|
||||
slashings := structs.AttesterSlashingsFromConsensus(ss)
|
||||
|
||||
httputil.WriteJson(w, &structs.GetAttesterSlashingsResponse{Data: slashings})
|
||||
}
|
||||
|
||||
@@ -29,6 +29,7 @@ import (
|
||||
"github.com/prysmaticlabs/prysm/v5/beacon-chain/rpc/core"
|
||||
state_native "github.com/prysmaticlabs/prysm/v5/beacon-chain/state/state-native"
|
||||
"github.com/prysmaticlabs/prysm/v5/config/params"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/interfaces"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
|
||||
"github.com/prysmaticlabs/prysm/v5/crypto/bls"
|
||||
"github.com/prysmaticlabs/prysm/v5/crypto/bls/common"
|
||||
@@ -115,8 +116,8 @@ func TestListAttestations(t *testing.T) {
|
||||
s := &Server{
|
||||
AttestationsPool: attestations.NewPool(),
|
||||
}
|
||||
require.NoError(t, s.AttestationsPool.SaveAggregatedAttestations([]*ethpbv1alpha1.Attestation{att1, att2}))
|
||||
require.NoError(t, s.AttestationsPool.SaveUnaggregatedAttestations([]*ethpbv1alpha1.Attestation{att3, att4}))
|
||||
require.NoError(t, s.AttestationsPool.SaveAggregatedAttestations([]interfaces.Attestation{att1, att2}))
|
||||
require.NoError(t, s.AttestationsPool.SaveUnaggregatedAttestations([]interfaces.Attestation{att3, att4}))
|
||||
|
||||
t.Run("empty request", func(t *testing.T) {
|
||||
url := "http://example.com"
|
||||
@@ -240,15 +241,15 @@ func TestSubmitAttestations(t *testing.T) {
|
||||
assert.Equal(t, http.StatusOK, writer.Code)
|
||||
assert.Equal(t, true, broadcaster.BroadcastCalled.Load())
|
||||
assert.Equal(t, 1, broadcaster.NumAttestations())
|
||||
assert.Equal(t, "0x03", hexutil.Encode(broadcaster.BroadcastAttestations[0].AggregationBits))
|
||||
assert.Equal(t, "0x8146f4397bfd8fd057ebbcd6a67327bdc7ed5fb650533edcb6377b650dea0b6da64c14ecd60846d5c0a0cd43893d6972092500f82c9d8a955e2b58c5ed3cbe885d84008ace6bd86ba9e23652f58e2ec207cec494c916063257abf285b9b15b15", hexutil.Encode(broadcaster.BroadcastAttestations[0].Signature))
|
||||
assert.Equal(t, primitives.Slot(0), broadcaster.BroadcastAttestations[0].Data.Slot)
|
||||
assert.Equal(t, primitives.CommitteeIndex(0), broadcaster.BroadcastAttestations[0].Data.CommitteeIndex)
|
||||
assert.Equal(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", hexutil.Encode(broadcaster.BroadcastAttestations[0].Data.BeaconBlockRoot))
|
||||
assert.Equal(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", hexutil.Encode(broadcaster.BroadcastAttestations[0].Data.Source.Root))
|
||||
assert.Equal(t, primitives.Epoch(0), broadcaster.BroadcastAttestations[0].Data.Source.Epoch)
|
||||
assert.Equal(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", hexutil.Encode(broadcaster.BroadcastAttestations[0].Data.Target.Root))
|
||||
assert.Equal(t, primitives.Epoch(0), broadcaster.BroadcastAttestations[0].Data.Target.Epoch)
|
||||
assert.Equal(t, "0x03", hexutil.Encode(broadcaster.BroadcastAttestations[0].GetAggregationBits()))
|
||||
assert.Equal(t, "0x8146f4397bfd8fd057ebbcd6a67327bdc7ed5fb650533edcb6377b650dea0b6da64c14ecd60846d5c0a0cd43893d6972092500f82c9d8a955e2b58c5ed3cbe885d84008ace6bd86ba9e23652f58e2ec207cec494c916063257abf285b9b15b15", hexutil.Encode(broadcaster.BroadcastAttestations[0].GetSignature()))
|
||||
assert.Equal(t, primitives.Slot(0), broadcaster.BroadcastAttestations[0].GetData().Slot)
|
||||
assert.Equal(t, primitives.CommitteeIndex(0), broadcaster.BroadcastAttestations[0].GetData().CommitteeIndex)
|
||||
assert.Equal(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", hexutil.Encode(broadcaster.BroadcastAttestations[0].GetData().BeaconBlockRoot))
|
||||
assert.Equal(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", hexutil.Encode(broadcaster.BroadcastAttestations[0].GetData().Source.Root))
|
||||
assert.Equal(t, primitives.Epoch(0), broadcaster.BroadcastAttestations[0].GetData().Source.Epoch)
|
||||
assert.Equal(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", hexutil.Encode(broadcaster.BroadcastAttestations[0].GetData().Target.Root))
|
||||
assert.Equal(t, primitives.Epoch(0), broadcaster.BroadcastAttestations[0].GetData().Target.Epoch)
|
||||
assert.Equal(t, 1, s.AttestationsPool.UnaggregatedAttestationCount())
|
||||
})
|
||||
t.Run("multiple", func(t *testing.T) {
|
||||
@@ -1060,7 +1061,7 @@ func TestGetAttesterSlashings(t *testing.T) {
|
||||
|
||||
s := &Server{
|
||||
ChainInfoFetcher: &blockchainmock.ChainService{State: bs},
|
||||
SlashingsPool: &slashingsmock.PoolMock{PendingAttSlashings: []*ethpbv1alpha1.AttesterSlashing{slashing1, slashing2}},
|
||||
SlashingsPool: &slashingsmock.PoolMock{PendingAttSlashings: []interfaces.AttesterSlashing{slashing1, slashing2}},
|
||||
}
|
||||
|
||||
request := httptest.NewRequest(http.MethodGet, "http://example.com/beacon/pool/attester_slashings", nil)
|
||||
|
||||
@@ -22,6 +22,7 @@ go_library(
|
||||
"//network/httputil:go_default_library",
|
||||
"//proto/eth/v1:go_default_library",
|
||||
"//proto/eth/v2:go_default_library",
|
||||
"//proto/prysm/v1alpha1:go_default_library",
|
||||
"//runtime/version:go_default_library",
|
||||
"//time/slots:go_default_library",
|
||||
"@com_github_ethereum_go_ethereum//common/hexutil:go_default_library",
|
||||
|
||||
@@ -22,6 +22,7 @@ import (
|
||||
"github.com/prysmaticlabs/prysm/v5/network/httputil"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v5/proto/eth/v1"
|
||||
ethpbv2 "github.com/prysmaticlabs/prysm/v5/proto/eth/v2"
|
||||
eth "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/v5/runtime/version"
|
||||
"github.com/prysmaticlabs/prysm/v5/time/slots"
|
||||
"go.opencensus.io/trace"
|
||||
@@ -173,7 +174,11 @@ func handleBlockOperationEvents(w http.ResponseWriter, flusher http.Flusher, req
|
||||
if !ok {
|
||||
return write(w, flusher, topicDataMismatch, event.Data, AttestationTopic)
|
||||
}
|
||||
att := structs.AttFromConsensus(attData.Attestation)
|
||||
a, ok := attData.Attestation.(*eth.Attestation)
|
||||
if !ok {
|
||||
return write(w, flusher, topicDataMismatch, event.Data, AttestationTopic)
|
||||
}
|
||||
att := structs.AttFromConsensus(a)
|
||||
return send(w, flusher, AttestationTopic, att)
|
||||
case operation.ExitReceived:
|
||||
if _, ok := requestedTopics[VoluntaryExitTopic]; !ok {
|
||||
@@ -229,7 +234,11 @@ func handleBlockOperationEvents(w http.ResponseWriter, flusher http.Flusher, req
|
||||
if !ok {
|
||||
return write(w, flusher, topicDataMismatch, event.Data, AttesterSlashingTopic)
|
||||
}
|
||||
return send(w, flusher, AttesterSlashingTopic, structs.AttesterSlashingFromConsensus(attesterSlashingData.AttesterSlashing))
|
||||
slashing, ok := attesterSlashingData.AttesterSlashing.(*eth.AttesterSlashing)
|
||||
if ok {
|
||||
return send(w, flusher, AttesterSlashingTopic, structs.AttesterSlashingFromConsensus(slashing))
|
||||
}
|
||||
// TODO: extend to Electra
|
||||
case operation.ProposerSlashingReceived:
|
||||
if _, ok := requestedTopics[ProposerSlashingTopic]; !ok {
|
||||
return nil
|
||||
|
||||
@@ -104,18 +104,18 @@ func BlockRewardTestSetup(t *testing.T, forkName string) (state.BeaconState, int
|
||||
sbb.SetSlot(2)
|
||||
// we have to set the proposer index to the value that will be randomly chosen (fortunately it's deterministic)
|
||||
sbb.SetProposerIndex(12)
|
||||
sbb.SetAttestations([]*eth.Attestation{
|
||||
{
|
||||
require.NoError(t, sbb.SetAttestations([]interfaces.Attestation{
|
||||
ð.Attestation{
|
||||
AggregationBits: bitfield.Bitlist{0b00000111},
|
||||
Data: util.HydrateAttestationData(ð.AttestationData{}),
|
||||
Signature: make([]byte, fieldparams.BLSSignatureLength),
|
||||
},
|
||||
{
|
||||
ð.Attestation{
|
||||
AggregationBits: bitfield.Bitlist{0b00000111},
|
||||
Data: util.HydrateAttestationData(ð.AttestationData{}),
|
||||
Signature: make([]byte, fieldparams.BLSSignatureLength),
|
||||
},
|
||||
})
|
||||
}))
|
||||
|
||||
attData1 := util.HydrateAttestationData(ð.AttestationData{BeaconBlockRoot: bytesutil.PadTo([]byte("root1"), 32)})
|
||||
attData2 := util.HydrateAttestationData(ð.AttestationData{BeaconBlockRoot: bytesutil.PadTo([]byte("root2"), 32)})
|
||||
@@ -125,8 +125,8 @@ func BlockRewardTestSetup(t *testing.T, forkName string) (state.BeaconState, int
|
||||
require.NoError(t, err)
|
||||
sigRoot2, err := signing.ComputeSigningRoot(attData2, domain)
|
||||
require.NoError(t, err)
|
||||
sbb.SetAttesterSlashings([]*eth.AttesterSlashing{
|
||||
{
|
||||
require.NoError(t, sbb.SetAttesterSlashings([]interfaces.AttesterSlashing{
|
||||
ð.AttesterSlashing{
|
||||
Attestation_1: ð.IndexedAttestation{
|
||||
AttestingIndices: []uint64{0},
|
||||
Data: attData1,
|
||||
@@ -138,7 +138,7 @@ func BlockRewardTestSetup(t *testing.T, forkName string) (state.BeaconState, int
|
||||
Signature: secretKeys[0].Sign(sigRoot2[:]).Marshal(),
|
||||
},
|
||||
},
|
||||
})
|
||||
}))
|
||||
header1 := ð.BeaconBlockHeader{
|
||||
Slot: 0,
|
||||
ProposerIndex: 1,
|
||||
|
||||
@@ -33,6 +33,7 @@ go_library(
|
||||
"//config/params:go_default_library",
|
||||
"//consensus-types:go_default_library",
|
||||
"//consensus-types/blocks:go_default_library",
|
||||
"//consensus-types/interfaces:go_default_library",
|
||||
"//consensus-types/primitives:go_default_library",
|
||||
"//consensus-types/validator:go_default_library",
|
||||
"//encoding/bytesutil:go_default_library",
|
||||
@@ -79,6 +80,7 @@ go_test(
|
||||
"//beacon-chain/sync/initial-sync/testing:go_default_library",
|
||||
"//config/fieldparams:go_default_library",
|
||||
"//config/params:go_default_library",
|
||||
"//consensus-types/interfaces:go_default_library",
|
||||
"//consensus-types/primitives:go_default_library",
|
||||
"//crypto/bls:go_default_library",
|
||||
"//encoding/bytesutil:go_default_library",
|
||||
|
||||
@@ -25,6 +25,7 @@ import (
|
||||
fieldparams "github.com/prysmaticlabs/prysm/v5/config/fieldparams"
|
||||
"github.com/prysmaticlabs/prysm/v5/config/params"
|
||||
consensus_types "github.com/prysmaticlabs/prysm/v5/consensus-types"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/interfaces"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
|
||||
validator2 "github.com/prysmaticlabs/prysm/v5/consensus-types/validator"
|
||||
"github.com/prysmaticlabs/prysm/v5/encoding/bytesutil"
|
||||
@@ -52,7 +53,7 @@ func (s *Server) GetAggregateAttestation(w http.ResponseWriter, r *http.Request)
|
||||
return
|
||||
}
|
||||
|
||||
var match *ethpbalpha.Attestation
|
||||
var match interfaces.Attestation
|
||||
var err error
|
||||
|
||||
match, err = matchingAtt(s.AttestationsPool.AggregatedAttestations(), primitives.Slot(slot), attDataRoot)
|
||||
@@ -79,29 +80,29 @@ func (s *Server) GetAggregateAttestation(w http.ResponseWriter, r *http.Request)
|
||||
|
||||
response := &structs.AggregateAttestationResponse{
|
||||
Data: &structs.Attestation{
|
||||
AggregationBits: hexutil.Encode(match.AggregationBits),
|
||||
AggregationBits: hexutil.Encode(match.GetAggregationBits()),
|
||||
Data: &structs.AttestationData{
|
||||
Slot: strconv.FormatUint(uint64(match.Data.Slot), 10),
|
||||
CommitteeIndex: strconv.FormatUint(uint64(match.Data.CommitteeIndex), 10),
|
||||
BeaconBlockRoot: hexutil.Encode(match.Data.BeaconBlockRoot),
|
||||
Slot: strconv.FormatUint(uint64(match.GetData().Slot), 10),
|
||||
CommitteeIndex: strconv.FormatUint(uint64(match.GetData().CommitteeIndex), 10),
|
||||
BeaconBlockRoot: hexutil.Encode(match.GetData().BeaconBlockRoot),
|
||||
Source: &structs.Checkpoint{
|
||||
Epoch: strconv.FormatUint(uint64(match.Data.Source.Epoch), 10),
|
||||
Root: hexutil.Encode(match.Data.Source.Root),
|
||||
Epoch: strconv.FormatUint(uint64(match.GetData().Source.Epoch), 10),
|
||||
Root: hexutil.Encode(match.GetData().Source.Root),
|
||||
},
|
||||
Target: &structs.Checkpoint{
|
||||
Epoch: strconv.FormatUint(uint64(match.Data.Target.Epoch), 10),
|
||||
Root: hexutil.Encode(match.Data.Target.Root),
|
||||
Epoch: strconv.FormatUint(uint64(match.GetData().Target.Epoch), 10),
|
||||
Root: hexutil.Encode(match.GetData().Target.Root),
|
||||
},
|
||||
},
|
||||
Signature: hexutil.Encode(match.Signature),
|
||||
Signature: hexutil.Encode(match.GetSignature()),
|
||||
}}
|
||||
httputil.WriteJson(w, response)
|
||||
}
|
||||
|
||||
func matchingAtt(atts []*ethpbalpha.Attestation, slot primitives.Slot, attDataRoot []byte) (*ethpbalpha.Attestation, error) {
|
||||
func matchingAtt(atts []interfaces.Attestation, slot primitives.Slot, attDataRoot []byte) (interfaces.Attestation, error) {
|
||||
for _, att := range atts {
|
||||
if att.Data.Slot == slot {
|
||||
root, err := att.Data.HashTreeRoot()
|
||||
if att.GetData().Slot == slot {
|
||||
root, err := att.GetData().HashTreeRoot()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not get attestation data root")
|
||||
}
|
||||
|
||||
@@ -33,6 +33,7 @@ import (
|
||||
mockSync "github.com/prysmaticlabs/prysm/v5/beacon-chain/sync/initial-sync/testing"
|
||||
fieldparams "github.com/prysmaticlabs/prysm/v5/config/fieldparams"
|
||||
"github.com/prysmaticlabs/prysm/v5/config/params"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/interfaces"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
|
||||
"github.com/prysmaticlabs/prysm/v5/crypto/bls"
|
||||
"github.com/prysmaticlabs/prysm/v5/encoding/bytesutil"
|
||||
@@ -143,9 +144,9 @@ func TestGetAggregateAttestation(t *testing.T) {
|
||||
}
|
||||
|
||||
pool := attestations.NewPool()
|
||||
err := pool.SaveAggregatedAttestations([]*ethpbalpha.Attestation{attSlot1, attslot21, attslot22})
|
||||
err := pool.SaveAggregatedAttestations([]interfaces.Attestation{attSlot1, attslot21, attslot22})
|
||||
assert.NoError(t, err)
|
||||
err = pool.SaveUnaggregatedAttestations([]*ethpbalpha.Attestation{attslot31, attslot32})
|
||||
err = pool.SaveUnaggregatedAttestations([]interfaces.Attestation{attslot31, attslot32})
|
||||
assert.NoError(t, err)
|
||||
|
||||
s := &Server{
|
||||
@@ -314,7 +315,7 @@ func TestGetAggregateAttestation_SameSlotAndRoot_ReturnMostAggregationBits(t *te
|
||||
Signature: sig,
|
||||
}
|
||||
pool := attestations.NewPool()
|
||||
err := pool.SaveAggregatedAttestations([]*ethpbalpha.Attestation{att1, att2})
|
||||
err := pool.SaveAggregatedAttestations([]interfaces.Attestation{att1, att2})
|
||||
assert.NoError(t, err)
|
||||
s := &Server{
|
||||
AttestationsPool: pool,
|
||||
|
||||
@@ -21,7 +21,7 @@ import (
|
||||
|
||||
// sortableAttestations implements the Sort interface to sort attestations
|
||||
// by slot as the canonical sorting attribute.
|
||||
type sortableAttestations []*ethpb.Attestation
|
||||
type sortableAttestations []interfaces.Attestation
|
||||
|
||||
// Len is the number of elements in the collection.
|
||||
func (s sortableAttestations) Len() int { return len(s) }
|
||||
@@ -31,16 +31,16 @@ func (s sortableAttestations) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
|
||||
|
||||
// Less reports whether the element with index i must sort before the element with index j.
|
||||
func (s sortableAttestations) Less(i, j int) bool {
|
||||
return s[i].Data.Slot < s[j].Data.Slot
|
||||
return s[i].GetData().Slot < s[j].GetData().Slot
|
||||
}
|
||||
|
||||
func mapAttestationsByTargetRoot(atts []*ethpb.Attestation) map[[32]byte][]*ethpb.Attestation {
|
||||
attsMap := make(map[[32]byte][]*ethpb.Attestation, len(atts))
|
||||
func mapAttestationsByTargetRoot(atts []interfaces.Attestation) map[[32]byte][]interfaces.Attestation {
|
||||
attsMap := make(map[[32]byte][]interfaces.Attestation, len(atts))
|
||||
if len(atts) == 0 {
|
||||
return attsMap
|
||||
}
|
||||
for _, att := range atts {
|
||||
attsMap[bytesutil.ToBytes32(att.Data.Target.Root)] = append(attsMap[bytesutil.ToBytes32(att.Data.Target.Root)], att)
|
||||
attsMap[bytesutil.ToBytes32(att.GetData().Target.Root)] = append(attsMap[bytesutil.ToBytes32(att.GetData().Target.Root)], att)
|
||||
}
|
||||
return attsMap
|
||||
}
|
||||
@@ -74,7 +74,7 @@ func (bs *Server) ListAttestations(
|
||||
default:
|
||||
return nil, status.Error(codes.InvalidArgument, "Must specify a filter criteria for fetching attestations")
|
||||
}
|
||||
atts := make([]*ethpb.Attestation, 0, params.BeaconConfig().MaxAttestations*uint64(len(blocks)))
|
||||
atts := make([]interfaces.Attestation, 0, params.BeaconConfig().MaxAttestations*uint64(len(blocks)))
|
||||
for _, blk := range blocks {
|
||||
atts = append(atts, blk.Block().Body().Attestations()...)
|
||||
}
|
||||
@@ -96,8 +96,15 @@ func (bs *Server) ListAttestations(
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.Internal, "Could not paginate attestations: %v", err)
|
||||
}
|
||||
attestations := make([]*ethpb.Attestation, 0, len(atts))
|
||||
for _, att := range atts {
|
||||
a, ok := att.(*ethpb.Attestation)
|
||||
if ok {
|
||||
attestations = append(attestations, a)
|
||||
}
|
||||
}
|
||||
return ðpb.ListAttestationsResponse{
|
||||
Attestations: atts[start:end],
|
||||
Attestations: attestations[start:end],
|
||||
TotalSize: int32(numAttestations),
|
||||
NextPageToken: nextPageToken,
|
||||
}, nil
|
||||
@@ -129,7 +136,7 @@ func (bs *Server) ListIndexedAttestations(
|
||||
return nil, status.Error(codes.InvalidArgument, "Must specify a filter criteria for fetching attestations")
|
||||
}
|
||||
|
||||
attsArray := make([]*ethpb.Attestation, 0, params.BeaconConfig().MaxAttestations*uint64(len(blocks)))
|
||||
attsArray := make([]interfaces.Attestation, 0, params.BeaconConfig().MaxAttestations*uint64(len(blocks)))
|
||||
for _, b := range blocks {
|
||||
attsArray = append(attsArray, b.Block().Body().Attestations()...)
|
||||
}
|
||||
@@ -166,7 +173,7 @@ func (bs *Server) ListIndexedAttestations(
|
||||
}
|
||||
for i := 0; i < len(atts); i++ {
|
||||
att := atts[i]
|
||||
committee, err := helpers.BeaconCommitteeFromState(ctx, attState, att.Data.Slot, att.Data.CommitteeIndex)
|
||||
committee, err := helpers.BeaconCommitteeFromState(ctx, attState, att.GetData().Slot, att.GetData().CommitteeIndex)
|
||||
if err != nil {
|
||||
return nil, status.Errorf(
|
||||
codes.Internal,
|
||||
@@ -178,7 +185,10 @@ func (bs *Server) ListIndexedAttestations(
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
indexedAtts = append(indexedAtts, idxAtt)
|
||||
a, ok := idxAtt.(*ethpb.IndexedAttestation)
|
||||
if ok {
|
||||
indexedAtts = append(indexedAtts, a)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -226,8 +236,15 @@ func (bs *Server) AttestationPool(
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.Internal, "Could not paginate attestations: %v", err)
|
||||
}
|
||||
attestations := make([]*ethpb.Attestation, 0, len(atts))
|
||||
for _, att := range atts {
|
||||
a, ok := att.(*ethpb.Attestation)
|
||||
if ok {
|
||||
attestations = append(attestations, a)
|
||||
}
|
||||
}
|
||||
return ðpb.AttestationPoolResponse{
|
||||
Attestations: atts[start:end],
|
||||
Attestations: attestations[start:end],
|
||||
TotalSize: int32(numAtts),
|
||||
NextPageToken: nextPageToken,
|
||||
}, nil
|
||||
|
||||
@@ -263,7 +263,7 @@ func TestServer_ListAttestations_Pagination_CustomPageParameters(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
|
||||
count := params.BeaconConfig().SlotsPerEpoch * 4
|
||||
atts := make([]*ethpb.Attestation, 0, count)
|
||||
atts := make([]interfaces.Attestation, 0, count)
|
||||
for i := primitives.Slot(0); i < params.BeaconConfig().SlotsPerEpoch; i++ {
|
||||
for s := primitives.CommitteeIndex(0); s < 4; s++ {
|
||||
blockExample := util.NewBeaconBlock()
|
||||
@@ -278,7 +278,11 @@ func TestServer_ListAttestations_Pagination_CustomPageParameters(t *testing.T) {
|
||||
}),
|
||||
}
|
||||
util.SaveBlock(t, ctx, db, blockExample)
|
||||
atts = append(atts, blockExample.Block.Body.Attestations...)
|
||||
as := make([]interfaces.Attestation, len(blockExample.Block.Body.Attestations))
|
||||
for i, a := range blockExample.Block.Body.Attestations {
|
||||
as[i] = a
|
||||
}
|
||||
atts = append(atts, as...)
|
||||
}
|
||||
}
|
||||
sort.Sort(sortableAttestations(atts))
|
||||
@@ -303,9 +307,9 @@ func TestServer_ListAttestations_Pagination_CustomPageParameters(t *testing.T) {
|
||||
},
|
||||
res: ðpb.ListAttestationsResponse{
|
||||
Attestations: []*ethpb.Attestation{
|
||||
atts[3],
|
||||
atts[4],
|
||||
atts[5],
|
||||
atts[3].(*ethpb.Attestation),
|
||||
atts[4].(*ethpb.Attestation),
|
||||
atts[5].(*ethpb.Attestation),
|
||||
},
|
||||
NextPageToken: strconv.Itoa(2),
|
||||
TotalSize: int32(count),
|
||||
@@ -322,7 +326,7 @@ func TestServer_ListAttestations_Pagination_CustomPageParameters(t *testing.T) {
|
||||
},
|
||||
res: ðpb.ListAttestationsResponse{
|
||||
Attestations: []*ethpb.Attestation{
|
||||
atts[10],
|
||||
atts[10].(*ethpb.Attestation),
|
||||
},
|
||||
NextPageToken: strconv.Itoa(11),
|
||||
TotalSize: int32(count),
|
||||
@@ -339,14 +343,14 @@ func TestServer_ListAttestations_Pagination_CustomPageParameters(t *testing.T) {
|
||||
},
|
||||
res: ðpb.ListAttestationsResponse{
|
||||
Attestations: []*ethpb.Attestation{
|
||||
atts[16],
|
||||
atts[17],
|
||||
atts[18],
|
||||
atts[19],
|
||||
atts[20],
|
||||
atts[21],
|
||||
atts[22],
|
||||
atts[23],
|
||||
atts[16].(*ethpb.Attestation),
|
||||
atts[17].(*ethpb.Attestation),
|
||||
atts[18].(*ethpb.Attestation),
|
||||
atts[19].(*ethpb.Attestation),
|
||||
atts[20].(*ethpb.Attestation),
|
||||
atts[21].(*ethpb.Attestation),
|
||||
atts[22].(*ethpb.Attestation),
|
||||
atts[23].(*ethpb.Attestation),
|
||||
},
|
||||
NextPageToken: strconv.Itoa(3),
|
||||
TotalSize: int32(count)},
|
||||
@@ -460,7 +464,7 @@ func TestServer_ListAttestations_Pagination_DefaultPageSize(t *testing.T) {
|
||||
|
||||
func TestServer_mapAttestationToTargetRoot(t *testing.T) {
|
||||
count := primitives.Slot(100)
|
||||
atts := make([]*ethpb.Attestation, count)
|
||||
atts := make([]interfaces.Attestation, count)
|
||||
targetRoot1 := bytesutil.ToBytes32([]byte("root1"))
|
||||
targetRoot2 := bytesutil.ToBytes32([]byte("root2"))
|
||||
|
||||
@@ -548,7 +552,9 @@ func TestServer_ListIndexedAttestations_GenesisEpoch(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
idxAtt, err := attestation.ConvertToIndexed(ctx, atts[i], committee)
|
||||
require.NoError(t, err, "Could not convert attestation to indexed")
|
||||
indexedAtts[i] = idxAtt
|
||||
a, ok := idxAtt.(*ethpb.IndexedAttestation)
|
||||
require.Equal(t, true, ok, "unexpected type of indexed attestation")
|
||||
indexedAtts[i] = a
|
||||
}
|
||||
for i := 0; i < len(atts2); i++ {
|
||||
att := atts2[i]
|
||||
@@ -556,7 +562,9 @@ func TestServer_ListIndexedAttestations_GenesisEpoch(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
idxAtt, err := attestation.ConvertToIndexed(ctx, atts2[i], committee)
|
||||
require.NoError(t, err, "Could not convert attestation to indexed")
|
||||
indexedAtts[i+len(atts)] = idxAtt
|
||||
a, ok := idxAtt.(*ethpb.IndexedAttestation)
|
||||
require.Equal(t, true, ok, "unexpected type of indexed attestation")
|
||||
indexedAtts[i+len(atts)] = a
|
||||
}
|
||||
|
||||
bs := &Server{
|
||||
@@ -588,7 +596,7 @@ func TestServer_ListIndexedAttestations_GenesisEpoch(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, len(indexedAtts), len(res.IndexedAttestations), "Incorrect indexted attestations length")
|
||||
sort.Slice(indexedAtts, func(i, j int) bool {
|
||||
return indexedAtts[i].Data.Slot < indexedAtts[j].Data.Slot
|
||||
return indexedAtts[i].GetData().Slot < indexedAtts[j].GetData().Slot
|
||||
})
|
||||
sort.Slice(res.IndexedAttestations, func(i, j int) bool {
|
||||
return res.IndexedAttestations[i].Data.Slot < res.IndexedAttestations[j].Data.Slot
|
||||
@@ -655,7 +663,9 @@ func TestServer_ListIndexedAttestations_OldEpoch(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
idxAtt, err := attestation.ConvertToIndexed(ctx, atts[i], committee)
|
||||
require.NoError(t, err, "Could not convert attestation to indexed")
|
||||
indexedAtts[i] = idxAtt
|
||||
a, ok := idxAtt.(*ethpb.IndexedAttestation)
|
||||
require.Equal(t, true, ok, "unexpected type of indexed attestation")
|
||||
indexedAtts[i] = a
|
||||
}
|
||||
|
||||
bs := &Server{
|
||||
@@ -697,8 +707,8 @@ func TestServer_AttestationPool_Pagination_OutOfRange(t *testing.T) {
|
||||
AttestationsPool: attestations.NewPool(),
|
||||
}
|
||||
|
||||
atts := []*ethpb.Attestation{
|
||||
{
|
||||
atts := []interfaces.Attestation{
|
||||
ðpb.Attestation{
|
||||
Data: ðpb.AttestationData{
|
||||
Slot: 1,
|
||||
BeaconBlockRoot: bytesutil.PadTo([]byte{1}, 32),
|
||||
@@ -708,7 +718,7 @@ func TestServer_AttestationPool_Pagination_OutOfRange(t *testing.T) {
|
||||
AggregationBits: bitfield.Bitlist{0b1101},
|
||||
Signature: bytesutil.PadTo([]byte{1}, fieldparams.BLSSignatureLength),
|
||||
},
|
||||
{
|
||||
ðpb.Attestation{
|
||||
Data: ðpb.AttestationData{
|
||||
Slot: 2,
|
||||
BeaconBlockRoot: bytesutil.PadTo([]byte{2}, 32),
|
||||
@@ -718,7 +728,7 @@ func TestServer_AttestationPool_Pagination_OutOfRange(t *testing.T) {
|
||||
AggregationBits: bitfield.Bitlist{0b1101},
|
||||
Signature: bytesutil.PadTo([]byte{2}, fieldparams.BLSSignatureLength),
|
||||
},
|
||||
{
|
||||
ðpb.Attestation{
|
||||
Data: ðpb.AttestationData{
|
||||
Slot: 3,
|
||||
BeaconBlockRoot: bytesutil.PadTo([]byte{3}, 32),
|
||||
@@ -746,7 +756,7 @@ func TestServer_AttestationPool_Pagination_DefaultPageSize(t *testing.T) {
|
||||
AttestationsPool: attestations.NewPool(),
|
||||
}
|
||||
|
||||
atts := make([]*ethpb.Attestation, params.BeaconConfig().DefaultPageSize+1)
|
||||
atts := make([]interfaces.Attestation, params.BeaconConfig().DefaultPageSize+1)
|
||||
for i := 0; i < len(atts); i++ {
|
||||
att := util.NewAttestation()
|
||||
att.Data.Slot = primitives.Slot(i)
|
||||
@@ -768,7 +778,7 @@ func TestServer_AttestationPool_Pagination_CustomPageSize(t *testing.T) {
|
||||
}
|
||||
|
||||
numAtts := 100
|
||||
atts := make([]*ethpb.Attestation, numAtts)
|
||||
atts := make([]interfaces.Attestation, numAtts)
|
||||
for i := 0; i < len(atts); i++ {
|
||||
att := util.NewAttestation()
|
||||
att.Data.Slot = primitives.Slot(i)
|
||||
|
||||
@@ -66,7 +66,7 @@ func (ds *Server) GetInclusionSlot(ctx context.Context, req *pbrpc.InclusionSlot
|
||||
targetStates := make(map[[32]byte]state.ReadOnlyBeaconState)
|
||||
for _, blk := range blks {
|
||||
for _, a := range blk.Block().Body().Attestations() {
|
||||
tr := bytesutil.ToBytes32(a.Data.Target.Root)
|
||||
tr := bytesutil.ToBytes32(a.GetData().Target.Root)
|
||||
s, ok := targetStates[tr]
|
||||
if !ok {
|
||||
s, err = ds.StateGen.StateByRoot(ctx, tr)
|
||||
@@ -75,16 +75,16 @@ func (ds *Server) GetInclusionSlot(ctx context.Context, req *pbrpc.InclusionSlot
|
||||
}
|
||||
targetStates[tr] = s
|
||||
}
|
||||
c, err := helpers.BeaconCommitteeFromState(ctx, s, a.Data.Slot, a.Data.CommitteeIndex)
|
||||
c, err := helpers.BeaconCommitteeFromState(ctx, s, a.GetData().Slot, a.GetData().CommitteeIndex)
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.Internal, "Could not get committee: %v", err)
|
||||
}
|
||||
indices, err := attestation.AttestingIndices(a.AggregationBits, c)
|
||||
indices, err := attestation.AttestingIndices(a.GetAggregationBits(), c)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, i := range indices {
|
||||
if req.Id == i && req.Slot == a.Data.Slot {
|
||||
if req.Id == i && req.Slot == a.GetData().Slot {
|
||||
inclusionSlot = blk.Block().Slot()
|
||||
break
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package validator
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/prysmaticlabs/prysm/v5/beacon-chain/core/helpers"
|
||||
"github.com/prysmaticlabs/prysm/v5/beacon-chain/rpc/core"
|
||||
@@ -85,22 +86,26 @@ func (vs *Server) SubmitAggregateSelectionProof(ctx context.Context, req *ethpb.
|
||||
// The aggregator should prefer an attestation that they have signed. We check this by
|
||||
// looking at the attestation's committee index against the validator's committee index
|
||||
// and check the aggregate bits to ensure the validator's index is set.
|
||||
if aggregatedAtt.Data.CommitteeIndex == req.CommitteeIndex &&
|
||||
aggregatedAtt.AggregationBits.BitAt(indexInCommittee) &&
|
||||
(!best.AggregationBits.BitAt(indexInCommittee) ||
|
||||
aggregatedAtt.AggregationBits.Count() > best.AggregationBits.Count()) {
|
||||
if aggregatedAtt.GetData().CommitteeIndex == req.CommitteeIndex &&
|
||||
aggregatedAtt.GetAggregationBits().BitAt(indexInCommittee) &&
|
||||
(!best.GetAggregationBits().BitAt(indexInCommittee) ||
|
||||
aggregatedAtt.GetAggregationBits().Count() > best.GetAggregationBits().Count()) {
|
||||
best = aggregatedAtt
|
||||
}
|
||||
|
||||
// If the "best" still doesn't contain the validator's index, check the aggregation bits to
|
||||
// choose the attestation with the most bits set.
|
||||
if !best.AggregationBits.BitAt(indexInCommittee) &&
|
||||
aggregatedAtt.AggregationBits.Count() > best.AggregationBits.Count() {
|
||||
if !best.GetAggregationBits().BitAt(indexInCommittee) &&
|
||||
aggregatedAtt.GetAggregationBits().Count() > best.GetAggregationBits().Count() {
|
||||
best = aggregatedAtt
|
||||
}
|
||||
}
|
||||
att, ok := best.(*ethpb.Attestation)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("best attestation has wrong type (expected %T, got %T)", ðpb.Attestation{}, best)
|
||||
}
|
||||
a := ðpb.AggregateAttestationAndProof{
|
||||
Aggregate: best,
|
||||
Aggregate: att,
|
||||
SelectionProof: req.SlotSignature,
|
||||
AggregatorIndex: validatorIndex,
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ import (
|
||||
mockSync "github.com/prysmaticlabs/prysm/v5/beacon-chain/sync/initial-sync/testing"
|
||||
fieldparams "github.com/prysmaticlabs/prysm/v5/config/fieldparams"
|
||||
"github.com/prysmaticlabs/prysm/v5/config/params"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/interfaces"
|
||||
"github.com/prysmaticlabs/prysm/v5/crypto/bls"
|
||||
"github.com/prysmaticlabs/prysm/v5/encoding/bytesutil"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
|
||||
@@ -336,7 +337,7 @@ func TestSubmitAggregateAndProof_PreferOwnAttestation(t *testing.T) {
|
||||
pubKey := v.PublicKey
|
||||
req := ðpb.AggregateSelectionRequest{CommitteeIndex: 1, SlotSignature: sig.Marshal(), PublicKey: pubKey}
|
||||
|
||||
err = aggregatorServer.AttPool.SaveAggregatedAttestations([]*ethpb.Attestation{
|
||||
err = aggregatorServer.AttPool.SaveAggregatedAttestations([]interfaces.Attestation{
|
||||
att0,
|
||||
att1,
|
||||
att2,
|
||||
@@ -387,7 +388,7 @@ func TestSubmitAggregateAndProof_SelectsMostBitsWhenOwnAttestationNotPresent(t *
|
||||
pubKey := v.PublicKey
|
||||
req := ðpb.AggregateSelectionRequest{CommitteeIndex: 1, SlotSignature: sig.Marshal(), PublicKey: pubKey}
|
||||
|
||||
err = aggregatorServer.AttPool.SaveAggregatedAttestations([]*ethpb.Attestation{
|
||||
err = aggregatorServer.AttPool.SaveAggregatedAttestations([]interfaces.Attestation{
|
||||
att0,
|
||||
att1,
|
||||
})
|
||||
|
||||
@@ -202,17 +202,23 @@ func (vs *Server) BuildBlockParallel(ctx context.Context, sBlk interfaces.Signed
|
||||
deposits, atts, err := vs.packDepositsAndAttestations(ctx, head, eth1Data) // TODO: split attestations and deposits
|
||||
if err != nil {
|
||||
sBlk.SetDeposits([]*ethpb.Deposit{})
|
||||
sBlk.SetAttestations([]*ethpb.Attestation{})
|
||||
if err := sBlk.SetAttestations([]interfaces.Attestation{}); err != nil {
|
||||
log.WithError(err).Error("Could not set attestations on block")
|
||||
}
|
||||
log.WithError(err).Error("Could not pack deposits and attestations")
|
||||
} else {
|
||||
sBlk.SetDeposits(deposits)
|
||||
sBlk.SetAttestations(atts)
|
||||
if err := sBlk.SetAttestations(atts); err != nil {
|
||||
log.WithError(err).Error("Could not set attestations on block")
|
||||
}
|
||||
}
|
||||
|
||||
// Set slashings.
|
||||
validProposerSlashings, validAttSlashings := vs.getSlashings(ctx, head)
|
||||
sBlk.SetProposerSlashings(validProposerSlashings)
|
||||
sBlk.SetAttesterSlashings(validAttSlashings)
|
||||
if err := sBlk.SetAttesterSlashings(validAttSlashings); err != nil {
|
||||
log.WithError(err).Error("Could not set attester slashings on block")
|
||||
}
|
||||
|
||||
// Set exits.
|
||||
sBlk.SetVoluntaryExits(vs.getExits(head, sBlk.Block().Slot()))
|
||||
|
||||
@@ -10,16 +10,16 @@ import (
|
||||
"github.com/prysmaticlabs/prysm/v5/beacon-chain/core/helpers"
|
||||
"github.com/prysmaticlabs/prysm/v5/beacon-chain/state"
|
||||
"github.com/prysmaticlabs/prysm/v5/config/params"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/interfaces"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1/attestation/aggregation"
|
||||
attaggregation "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1/attestation/aggregation/attestations"
|
||||
"go.opencensus.io/trace"
|
||||
)
|
||||
|
||||
type proposerAtts []*ethpb.Attestation
|
||||
type proposerAtts []interfaces.Attestation
|
||||
|
||||
func (vs *Server) packAttestations(ctx context.Context, latestState state.BeaconState) ([]*ethpb.Attestation, error) {
|
||||
func (vs *Server) packAttestations(ctx context.Context, latestState state.BeaconState) ([]interfaces.Attestation, error) {
|
||||
ctx, span := trace.StartSpan(ctx, "ProposerServer.packAttestations")
|
||||
defer span.End()
|
||||
|
||||
@@ -46,16 +46,16 @@ func (vs *Server) packAttestations(ctx context.Context, latestState state.Beacon
|
||||
return nil, err
|
||||
}
|
||||
|
||||
attsByDataRoot := make(map[[32]byte][]*ethpb.Attestation, len(atts))
|
||||
attsByDataRoot := make(map[[32]byte][]interfaces.Attestation, len(atts))
|
||||
for _, att := range atts {
|
||||
attDataRoot, err := att.Data.HashTreeRoot()
|
||||
attDataRoot, err := att.GetData().HashTreeRoot()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
attsByDataRoot[attDataRoot] = append(attsByDataRoot[attDataRoot], att)
|
||||
}
|
||||
|
||||
attsForInclusion := proposerAtts(make([]*ethpb.Attestation, 0))
|
||||
attsForInclusion := proposerAtts(make([]interfaces.Attestation, 0))
|
||||
for _, as := range attsByDataRoot {
|
||||
as, err := attaggregation.Aggregate(as)
|
||||
if err != nil {
|
||||
@@ -79,8 +79,8 @@ func (vs *Server) packAttestations(ctx context.Context, latestState state.Beacon
|
||||
// The first group passes the all the required checks for attestation to be considered for proposing.
|
||||
// And attestations from the second group should be deleted.
|
||||
func (a proposerAtts) filter(ctx context.Context, st state.BeaconState) (proposerAtts, proposerAtts) {
|
||||
validAtts := make([]*ethpb.Attestation, 0, len(a))
|
||||
invalidAtts := make([]*ethpb.Attestation, 0, len(a))
|
||||
validAtts := make([]interfaces.Attestation, 0, len(a))
|
||||
invalidAtts := make([]interfaces.Attestation, 0, len(a))
|
||||
|
||||
for _, att := range a {
|
||||
if err := blocks.VerifyAttestationNoVerifySignature(ctx, st, att); err == nil {
|
||||
@@ -107,10 +107,10 @@ func (a proposerAtts) sortByProfitabilityUsingMaxCover() (proposerAtts, error) {
|
||||
var slots []primitives.Slot
|
||||
attsBySlot := map[primitives.Slot]proposerAtts{}
|
||||
for _, att := range a {
|
||||
if _, ok := attsBySlot[att.Data.Slot]; !ok {
|
||||
slots = append(slots, att.Data.Slot)
|
||||
if _, ok := attsBySlot[att.GetData().Slot]; !ok {
|
||||
slots = append(slots, att.GetData().Slot)
|
||||
}
|
||||
attsBySlot[att.Data.Slot] = append(attsBySlot[att.Data.Slot], att)
|
||||
attsBySlot[att.GetData().Slot] = append(attsBySlot[att.GetData().Slot], att)
|
||||
}
|
||||
|
||||
selectAtts := func(atts proposerAtts) (proposerAtts, error) {
|
||||
@@ -120,7 +120,7 @@ func (a proposerAtts) sortByProfitabilityUsingMaxCover() (proposerAtts, error) {
|
||||
candidates := make([]*bitfield.Bitlist64, len(atts))
|
||||
for i := 0; i < len(atts); i++ {
|
||||
var err error
|
||||
candidates[i], err = atts[i].AggregationBits.ToBitlist64()
|
||||
candidates[i], err = atts[i].GetAggregationBits().ToBitlist64()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -139,10 +139,10 @@ func (a proposerAtts) sortByProfitabilityUsingMaxCover() (proposerAtts, error) {
|
||||
leftoverAtts[i] = atts[key]
|
||||
}
|
||||
sort.Slice(selectedAtts, func(i, j int) bool {
|
||||
return selectedAtts[i].AggregationBits.Count() > selectedAtts[j].AggregationBits.Count()
|
||||
return selectedAtts[i].GetAggregationBits().Count() > selectedAtts[j].GetAggregationBits().Count()
|
||||
})
|
||||
sort.Slice(leftoverAtts, func(i, j int) bool {
|
||||
return leftoverAtts[i].AggregationBits.Count() > leftoverAtts[j].AggregationBits.Count()
|
||||
return leftoverAtts[i].GetAggregationBits().Count() > leftoverAtts[j].GetAggregationBits().Count()
|
||||
})
|
||||
return append(selectedAtts, leftoverAtts...), nil
|
||||
}
|
||||
@@ -182,22 +182,22 @@ func (a proposerAtts) dedup() (proposerAtts, error) {
|
||||
if len(a) < 2 {
|
||||
return a, nil
|
||||
}
|
||||
attsByDataRoot := make(map[[32]byte][]*ethpb.Attestation, len(a))
|
||||
attsByDataRoot := make(map[[32]byte][]interfaces.Attestation, len(a))
|
||||
for _, att := range a {
|
||||
attDataRoot, err := att.Data.HashTreeRoot()
|
||||
attDataRoot, err := att.GetData().HashTreeRoot()
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
attsByDataRoot[attDataRoot] = append(attsByDataRoot[attDataRoot], att)
|
||||
}
|
||||
|
||||
uniqAtts := make([]*ethpb.Attestation, 0, len(a))
|
||||
uniqAtts := make([]interfaces.Attestation, 0, len(a))
|
||||
for _, atts := range attsByDataRoot {
|
||||
for i := 0; i < len(atts); i++ {
|
||||
a := atts[i]
|
||||
for j := i + 1; j < len(atts); j++ {
|
||||
b := atts[j]
|
||||
if c, err := a.AggregationBits.Contains(b.AggregationBits); err != nil {
|
||||
if c, err := a.GetAggregationBits().Contains(b.GetAggregationBits()); err != nil {
|
||||
return nil, err
|
||||
} else if c {
|
||||
// a contains b, b is redundant.
|
||||
@@ -205,7 +205,7 @@ func (a proposerAtts) dedup() (proposerAtts, error) {
|
||||
atts[len(atts)-1] = nil
|
||||
atts = atts[:len(atts)-1]
|
||||
j--
|
||||
} else if c, err := b.AggregationBits.Contains(a.AggregationBits); err != nil {
|
||||
} else if c, err := b.GetAggregationBits().Contains(a.GetAggregationBits()); err != nil {
|
||||
return nil, err
|
||||
} else if c {
|
||||
// b contains a, a is redundant.
|
||||
@@ -224,7 +224,7 @@ func (a proposerAtts) dedup() (proposerAtts, error) {
|
||||
}
|
||||
|
||||
// This filters the input attestations to return a list of valid attestations to be packaged inside a beacon block.
|
||||
func (vs *Server) validateAndDeleteAttsInPool(ctx context.Context, st state.BeaconState, atts []*ethpb.Attestation) ([]*ethpb.Attestation, error) {
|
||||
func (vs *Server) validateAndDeleteAttsInPool(ctx context.Context, st state.BeaconState, atts []interfaces.Attestation) ([]interfaces.Attestation, error) {
|
||||
ctx, span := trace.StartSpan(ctx, "ProposerServer.validateAndDeleteAttsInPool")
|
||||
defer span.End()
|
||||
|
||||
@@ -237,7 +237,7 @@ func (vs *Server) validateAndDeleteAttsInPool(ctx context.Context, st state.Beac
|
||||
|
||||
// The input attestations are processed and seen by the node, this deletes them from pool
|
||||
// so proposers don't include them in a block for the future.
|
||||
func (vs *Server) deleteAttsInPool(ctx context.Context, atts []*ethpb.Attestation) error {
|
||||
func (vs *Server) deleteAttsInPool(ctx context.Context, atts []interfaces.Attestation) error {
|
||||
ctx, span := trace.StartSpan(ctx, "ProposerServer.deleteAttsInPool")
|
||||
defer span.End()
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/prysmaticlabs/go-bitfield"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/interfaces"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/v5/testing/assert"
|
||||
@@ -14,7 +15,7 @@ import (
|
||||
)
|
||||
|
||||
func TestProposer_ProposerAtts_sortByProfitability(t *testing.T) {
|
||||
atts := proposerAtts([]*ethpb.Attestation{
|
||||
atts := proposerAtts([]interfaces.Attestation{
|
||||
util.HydrateAttestation(ðpb.Attestation{Data: ðpb.AttestationData{Slot: 4}, AggregationBits: bitfield.Bitlist{0b11100000}}),
|
||||
util.HydrateAttestation(ðpb.Attestation{Data: ðpb.AttestationData{Slot: 1}, AggregationBits: bitfield.Bitlist{0b11000000}}),
|
||||
util.HydrateAttestation(ðpb.Attestation{Data: ðpb.AttestationData{Slot: 2}, AggregationBits: bitfield.Bitlist{0b11100000}}),
|
||||
@@ -22,7 +23,7 @@ func TestProposer_ProposerAtts_sortByProfitability(t *testing.T) {
|
||||
util.HydrateAttestation(ðpb.Attestation{Data: ðpb.AttestationData{Slot: 1}, AggregationBits: bitfield.Bitlist{0b11100000}}),
|
||||
util.HydrateAttestation(ðpb.Attestation{Data: ðpb.AttestationData{Slot: 3}, AggregationBits: bitfield.Bitlist{0b11000000}}),
|
||||
})
|
||||
want := proposerAtts([]*ethpb.Attestation{
|
||||
want := proposerAtts([]interfaces.Attestation{
|
||||
util.HydrateAttestation(ðpb.Attestation{Data: ðpb.AttestationData{Slot: 4}, AggregationBits: bitfield.Bitlist{0b11110000}}),
|
||||
util.HydrateAttestation(ðpb.Attestation{Data: ðpb.AttestationData{Slot: 4}, AggregationBits: bitfield.Bitlist{0b11100000}}),
|
||||
util.HydrateAttestation(ðpb.Attestation{Data: ðpb.AttestationData{Slot: 3}, AggregationBits: bitfield.Bitlist{0b11000000}}),
|
||||
@@ -411,13 +412,13 @@ func TestProposer_ProposerAtts_dedup(t *testing.T) {
|
||||
t.Error(err)
|
||||
}
|
||||
sort.Slice(atts, func(i, j int) bool {
|
||||
if atts[i].AggregationBits.Count() == atts[j].AggregationBits.Count() {
|
||||
if atts[i].Data.Slot == atts[j].Data.Slot {
|
||||
return bytes.Compare(atts[i].AggregationBits, atts[j].AggregationBits) <= 0
|
||||
if atts[i].GetAggregationBits().Count() == atts[j].GetAggregationBits().Count() {
|
||||
if atts[i].GetData().Slot == atts[j].GetData().Slot {
|
||||
return bytes.Compare(atts[i].GetAggregationBits(), atts[j].GetAggregationBits()) <= 0
|
||||
}
|
||||
return atts[i].Data.Slot > atts[j].Data.Slot
|
||||
return atts[i].GetData().Slot > atts[j].GetData().Slot
|
||||
}
|
||||
return atts[i].AggregationBits.Count() > atts[j].AggregationBits.Count()
|
||||
return atts[i].GetAggregationBits().Count() > atts[j].GetAggregationBits().Count()
|
||||
})
|
||||
assert.DeepEqual(t, tt.want, atts)
|
||||
})
|
||||
|
||||
@@ -9,6 +9,7 @@ import (
|
||||
"github.com/prysmaticlabs/prysm/v5/beacon-chain/cache"
|
||||
"github.com/prysmaticlabs/prysm/v5/beacon-chain/state"
|
||||
"github.com/prysmaticlabs/prysm/v5/config/params"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/interfaces"
|
||||
"github.com/prysmaticlabs/prysm/v5/container/trie"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
|
||||
"github.com/sirupsen/logrus"
|
||||
@@ -18,10 +19,10 @@ import (
|
||||
"google.golang.org/grpc/status"
|
||||
)
|
||||
|
||||
func (vs *Server) packDepositsAndAttestations(ctx context.Context, head state.BeaconState, eth1Data *ethpb.Eth1Data) ([]*ethpb.Deposit, []*ethpb.Attestation, error) {
|
||||
func (vs *Server) packDepositsAndAttestations(ctx context.Context, head state.BeaconState, eth1Data *ethpb.Eth1Data) ([]*ethpb.Deposit, []interfaces.Attestation, error) {
|
||||
eg, egctx := errgroup.WithContext(ctx)
|
||||
var deposits []*ethpb.Deposit
|
||||
var atts []*ethpb.Attestation
|
||||
var atts []interfaces.Attestation
|
||||
|
||||
eg.Go(func() error {
|
||||
// Pack ETH1 deposits which have not been included in the beacon chain.
|
||||
|
||||
@@ -6,10 +6,11 @@ import (
|
||||
"github.com/prysmaticlabs/prysm/v5/beacon-chain/core/blocks"
|
||||
v "github.com/prysmaticlabs/prysm/v5/beacon-chain/core/validators"
|
||||
"github.com/prysmaticlabs/prysm/v5/beacon-chain/state"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/interfaces"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
|
||||
)
|
||||
|
||||
func (vs *Server) getSlashings(ctx context.Context, head state.BeaconState) ([]*ethpb.ProposerSlashing, []*ethpb.AttesterSlashing) {
|
||||
func (vs *Server) getSlashings(ctx context.Context, head state.BeaconState) ([]*ethpb.ProposerSlashing, []interfaces.AttesterSlashing) {
|
||||
proposerSlashings := vs.SlashingsPool.PendingProposerSlashings(ctx, head, false /*noLimit*/)
|
||||
validProposerSlashings := make([]*ethpb.ProposerSlashing, 0, len(proposerSlashings))
|
||||
for _, slashing := range proposerSlashings {
|
||||
@@ -21,7 +22,7 @@ func (vs *Server) getSlashings(ctx context.Context, head state.BeaconState) ([]*
|
||||
validProposerSlashings = append(validProposerSlashings, slashing)
|
||||
}
|
||||
attSlashings := vs.SlashingsPool.PendingAttesterSlashings(ctx, head, false /*noLimit*/)
|
||||
validAttSlashings := make([]*ethpb.AttesterSlashing, 0, len(attSlashings))
|
||||
validAttSlashings := make([]interfaces.AttesterSlashing, 0, len(attSlashings))
|
||||
for _, slashing := range attSlashings {
|
||||
_, err := blocks.ProcessAttesterSlashing(ctx, head, slashing, v.SlashValidator)
|
||||
if err != nil {
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
|
||||
"github.com/prysmaticlabs/prysm/v5/beacon-chain/operations/slashings"
|
||||
"github.com/prysmaticlabs/prysm/v5/config/params"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/interfaces"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/v5/testing/require"
|
||||
@@ -28,7 +29,7 @@ func TestServer_getSlashings(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
attSlashings := make([]*ethpb.AttesterSlashing, params.BeaconConfig().MaxAttesterSlashings)
|
||||
attSlashings := make([]interfaces.AttesterSlashing, params.BeaconConfig().MaxAttesterSlashings)
|
||||
for i := uint64(0); i < params.BeaconConfig().MaxAttesterSlashings; i++ {
|
||||
attesterSlashing, err := util.GenerateAttesterSlashingForValidator(
|
||||
beaconState,
|
||||
|
||||
@@ -38,6 +38,7 @@ import (
|
||||
fieldparams "github.com/prysmaticlabs/prysm/v5/config/fieldparams"
|
||||
"github.com/prysmaticlabs/prysm/v5/config/params"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/blocks"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/interfaces"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
|
||||
"github.com/prysmaticlabs/prysm/v5/container/trie"
|
||||
"github.com/prysmaticlabs/prysm/v5/crypto/bls"
|
||||
@@ -2396,22 +2397,22 @@ func TestProposer_FilterAttestation(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
wantedErr string
|
||||
inputAtts func() []*ethpb.Attestation
|
||||
expectedAtts func(inputAtts []*ethpb.Attestation) []*ethpb.Attestation
|
||||
inputAtts func() []interfaces.Attestation
|
||||
expectedAtts func(inputAtts []interfaces.Attestation) []interfaces.Attestation
|
||||
}{
|
||||
{
|
||||
name: "nil attestations",
|
||||
inputAtts: func() []*ethpb.Attestation {
|
||||
inputAtts: func() []interfaces.Attestation {
|
||||
return nil
|
||||
},
|
||||
expectedAtts: func(inputAtts []*ethpb.Attestation) []*ethpb.Attestation {
|
||||
return []*ethpb.Attestation{}
|
||||
expectedAtts: func(inputAtts []interfaces.Attestation) []interfaces.Attestation {
|
||||
return []interfaces.Attestation{}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "invalid attestations",
|
||||
inputAtts: func() []*ethpb.Attestation {
|
||||
atts := make([]*ethpb.Attestation, 10)
|
||||
inputAtts: func() []interfaces.Attestation {
|
||||
atts := make([]interfaces.Attestation, 10)
|
||||
for i := 0; i < len(atts); i++ {
|
||||
atts[i] = util.HydrateAttestation(ðpb.Attestation{
|
||||
Data: ðpb.AttestationData{
|
||||
@@ -2421,14 +2422,14 @@ func TestProposer_FilterAttestation(t *testing.T) {
|
||||
}
|
||||
return atts
|
||||
},
|
||||
expectedAtts: func(inputAtts []*ethpb.Attestation) []*ethpb.Attestation {
|
||||
return []*ethpb.Attestation{}
|
||||
expectedAtts: func(inputAtts []interfaces.Attestation) []interfaces.Attestation {
|
||||
return []interfaces.Attestation{}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "filter aggregates ok",
|
||||
inputAtts: func() []*ethpb.Attestation {
|
||||
atts := make([]*ethpb.Attestation, 10)
|
||||
inputAtts: func() []interfaces.Attestation {
|
||||
atts := make([]interfaces.Attestation, 10)
|
||||
for i := 0; i < len(atts); i++ {
|
||||
atts[i] = util.HydrateAttestation(ðpb.Attestation{
|
||||
Data: ðpb.AttestationData{
|
||||
@@ -2437,29 +2438,29 @@ func TestProposer_FilterAttestation(t *testing.T) {
|
||||
},
|
||||
AggregationBits: bitfield.Bitlist{0b00010010},
|
||||
})
|
||||
committee, err := helpers.BeaconCommitteeFromState(context.Background(), st, atts[i].Data.Slot, atts[i].Data.CommitteeIndex)
|
||||
committee, err := helpers.BeaconCommitteeFromState(context.Background(), st, atts[i].GetData().Slot, atts[i].GetData().CommitteeIndex)
|
||||
assert.NoError(t, err)
|
||||
attestingIndices, err := attestation.AttestingIndices(atts[i].AggregationBits, committee)
|
||||
attestingIndices, err := attestation.AttestingIndices(atts[i].GetAggregationBits(), committee)
|
||||
require.NoError(t, err)
|
||||
assert.NoError(t, err)
|
||||
domain, err := signing.Domain(st.Fork(), 0, params.BeaconConfig().DomainBeaconAttester, params.BeaconConfig().ZeroHash[:])
|
||||
require.NoError(t, err)
|
||||
sigs := make([]bls.Signature, len(attestingIndices))
|
||||
var zeroSig [96]byte
|
||||
atts[i].Signature = zeroSig[:]
|
||||
atts[i].(*ethpb.Attestation).Signature = zeroSig[:]
|
||||
|
||||
for i, indice := range attestingIndices {
|
||||
hashTreeRoot, err := signing.ComputeSigningRoot(atts[i].Data, domain)
|
||||
hashTreeRoot, err := signing.ComputeSigningRoot(atts[i].GetData(), domain)
|
||||
require.NoError(t, err)
|
||||
sig := privKeys[indice].Sign(hashTreeRoot[:])
|
||||
sigs[i] = sig
|
||||
}
|
||||
atts[i].Signature = bls.AggregateSignatures(sigs).Marshal()
|
||||
atts[i].(*ethpb.Attestation).Signature = bls.AggregateSignatures(sigs).Marshal()
|
||||
}
|
||||
return atts
|
||||
},
|
||||
expectedAtts: func(inputAtts []*ethpb.Attestation) []*ethpb.Attestation {
|
||||
return []*ethpb.Attestation{inputAtts[0], inputAtts[1]}
|
||||
expectedAtts: func(inputAtts []interfaces.Attestation) []interfaces.Attestation {
|
||||
return []interfaces.Attestation{inputAtts[0], inputAtts[1]}
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -2589,10 +2590,10 @@ func TestProposer_DeleteAttsInPool_Aggregated(t *testing.T) {
|
||||
priv, err := bls.RandKey()
|
||||
require.NoError(t, err)
|
||||
sig := priv.Sign([]byte("foo")).Marshal()
|
||||
aggregatedAtts := []*ethpb.Attestation{
|
||||
aggregatedAtts := []interfaces.Attestation{
|
||||
util.HydrateAttestation(ðpb.Attestation{Data: ðpb.AttestationData{Slot: 1}, AggregationBits: bitfield.Bitlist{0b10101}, Signature: sig}),
|
||||
util.HydrateAttestation(ðpb.Attestation{Data: ðpb.AttestationData{Slot: 1}, AggregationBits: bitfield.Bitlist{0b11010}, Signature: sig})}
|
||||
unaggregatedAtts := []*ethpb.Attestation{
|
||||
unaggregatedAtts := []interfaces.Attestation{
|
||||
util.HydrateAttestation(ðpb.Attestation{Data: ðpb.AttestationData{Slot: 1}, AggregationBits: bitfield.Bitlist{0b10010}, Signature: sig}),
|
||||
util.HydrateAttestation(ðpb.Attestation{Data: ðpb.AttestationData{Slot: 1}, AggregationBits: bitfield.Bitlist{0b10100}, Signature: sig})}
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
|
||||
"github.com/prysmaticlabs/go-bitfield"
|
||||
"github.com/prysmaticlabs/prysm/v5/config/params"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/interfaces"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
|
||||
aggtesting "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1/attestation/aggregation/testing"
|
||||
"github.com/prysmaticlabs/prysm/v5/testing/require"
|
||||
@@ -44,10 +45,10 @@ func BenchmarkProposerAtts_sortByProfitability(b *testing.B) {
|
||||
},
|
||||
}
|
||||
|
||||
runner := func(atts []*ethpb.Attestation) {
|
||||
runner := func(atts []interfaces.Attestation) {
|
||||
attsCopy := make(proposerAtts, len(atts))
|
||||
for i, att := range atts {
|
||||
attsCopy[i] = ethpb.CopyAttestation(att)
|
||||
attsCopy[i] = ethpb.CopyAttestation(att.(*ethpb.Attestation))
|
||||
}
|
||||
_, err := attsCopy.sortByProfitability()
|
||||
require.NoError(b, err, "Could not sort attestations by profitability")
|
||||
|
||||
@@ -36,6 +36,7 @@ go_library(
|
||||
"//beacon-chain/sync:go_default_library",
|
||||
"//config/fieldparams:go_default_library",
|
||||
"//config/params:go_default_library",
|
||||
"//consensus-types/interfaces:go_default_library",
|
||||
"//consensus-types/primitives:go_default_library",
|
||||
"//container/slice:go_default_library",
|
||||
"//encoding/bytesutil:go_default_library",
|
||||
@@ -78,6 +79,7 @@ go_test(
|
||||
"//beacon-chain/sync/initial-sync/testing:go_default_library",
|
||||
"//config/fieldparams:go_default_library",
|
||||
"//config/params:go_default_library",
|
||||
"//consensus-types/interfaces:go_default_library",
|
||||
"//consensus-types/primitives:go_default_library",
|
||||
"//crypto/bls:go_default_library",
|
||||
"//crypto/bls/common:go_default_library",
|
||||
|
||||
@@ -9,6 +9,7 @@ import (
|
||||
"github.com/pkg/errors"
|
||||
"github.com/prysmaticlabs/prysm/v5/beacon-chain/db"
|
||||
slashertypes "github.com/prysmaticlabs/prysm/v5/beacon-chain/slasher/types"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/interfaces"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
|
||||
"github.com/sirupsen/logrus"
|
||||
@@ -26,7 +27,7 @@ type Chunker interface {
|
||||
slasherDB db.SlasherDatabase,
|
||||
validatorIdx primitives.ValidatorIndex,
|
||||
attestation *slashertypes.IndexedAttestationWrapper,
|
||||
) (*ethpb.AttesterSlashing, error)
|
||||
) (interfaces.AttesterSlashing, error)
|
||||
Update(
|
||||
chunkIndex uint64,
|
||||
currentEpoch primitives.Epoch,
|
||||
@@ -185,9 +186,9 @@ func (m *MinSpanChunksSlice) CheckSlashable(
|
||||
slasherDB db.SlasherDatabase,
|
||||
validatorIdx primitives.ValidatorIndex,
|
||||
incomingAttWrapper *slashertypes.IndexedAttestationWrapper,
|
||||
) (*ethpb.AttesterSlashing, error) {
|
||||
sourceEpoch := incomingAttWrapper.IndexedAttestation.Data.Source.Epoch
|
||||
targetEpoch := incomingAttWrapper.IndexedAttestation.Data.Target.Epoch
|
||||
) (interfaces.AttesterSlashing, error) {
|
||||
sourceEpoch := incomingAttWrapper.IndexedAttestation.GetData().Source.Epoch
|
||||
targetEpoch := incomingAttWrapper.IndexedAttestation.GetData().Target.Epoch
|
||||
|
||||
minTarget, err := chunkDataAtEpoch(m.params, m.data, validatorIdx, sourceEpoch)
|
||||
if err != nil {
|
||||
@@ -221,7 +222,7 @@ func (m *MinSpanChunksSlice) CheckSlashable(
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
if existingAttWrapper.IndexedAttestation.Data.Source.Epoch <= sourceEpoch {
|
||||
if existingAttWrapper.IndexedAttestation.GetData().Source.Epoch <= sourceEpoch {
|
||||
// This case should normally not happen, since if we have targetEpoch > minTarget,
|
||||
// then there is at least one attestation we surround.
|
||||
// However, it can happens if we have multiple attestation with the same target
|
||||
@@ -232,16 +233,33 @@ func (m *MinSpanChunksSlice) CheckSlashable(
|
||||
|
||||
surroundingVotesTotal.Inc()
|
||||
|
||||
existing, ok := existingAttWrapper.IndexedAttestation.(*ethpb.IndexedAttestation)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf(
|
||||
"existing attestation has wrong type (expected %T, got %T)",
|
||||
ðpb.IndexedAttestation{},
|
||||
existingAttWrapper.IndexedAttestation,
|
||||
)
|
||||
}
|
||||
incoming, ok := incomingAttWrapper.IndexedAttestation.(*ethpb.IndexedAttestation)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf(
|
||||
"incoming attestation has wrong type (expected %T, got %T)",
|
||||
ðpb.IndexedAttestation{},
|
||||
incomingAttWrapper.IndexedAttestation,
|
||||
)
|
||||
}
|
||||
|
||||
slashing := ðpb.AttesterSlashing{
|
||||
Attestation_1: existingAttWrapper.IndexedAttestation,
|
||||
Attestation_2: incomingAttWrapper.IndexedAttestation,
|
||||
Attestation_1: existing,
|
||||
Attestation_2: incoming,
|
||||
}
|
||||
|
||||
// Ensure the attestation with the lower data root is the first attestation.
|
||||
if bytes.Compare(existingAttWrapper.DataRoot[:], incomingAttWrapper.DataRoot[:]) > 0 {
|
||||
slashing = ðpb.AttesterSlashing{
|
||||
Attestation_1: incomingAttWrapper.IndexedAttestation,
|
||||
Attestation_2: existingAttWrapper.IndexedAttestation,
|
||||
Attestation_1: incoming,
|
||||
Attestation_2: existing,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -264,9 +282,9 @@ func (m *MaxSpanChunksSlice) CheckSlashable(
|
||||
slasherDB db.SlasherDatabase,
|
||||
validatorIdx primitives.ValidatorIndex,
|
||||
incomingAttWrapper *slashertypes.IndexedAttestationWrapper,
|
||||
) (*ethpb.AttesterSlashing, error) {
|
||||
sourceEpoch := incomingAttWrapper.IndexedAttestation.Data.Source.Epoch
|
||||
targetEpoch := incomingAttWrapper.IndexedAttestation.Data.Target.Epoch
|
||||
) (interfaces.AttesterSlashing, error) {
|
||||
sourceEpoch := incomingAttWrapper.IndexedAttestation.GetData().Source.Epoch
|
||||
targetEpoch := incomingAttWrapper.IndexedAttestation.GetData().Target.Epoch
|
||||
|
||||
maxTarget, err := chunkDataAtEpoch(m.params, m.data, validatorIdx, sourceEpoch)
|
||||
if err != nil {
|
||||
@@ -300,7 +318,7 @@ func (m *MaxSpanChunksSlice) CheckSlashable(
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
if existingAttWrapper.IndexedAttestation.Data.Source.Epoch >= sourceEpoch {
|
||||
if existingAttWrapper.IndexedAttestation.GetData().Source.Epoch >= sourceEpoch {
|
||||
// This case should normally not happen, since if we have targetEpoch < maxTarget,
|
||||
// then there is at least one attestation that surrounds us.
|
||||
// However, it can happens if we have multiple attestation with the same target
|
||||
@@ -311,16 +329,33 @@ func (m *MaxSpanChunksSlice) CheckSlashable(
|
||||
|
||||
surroundedVotesTotal.Inc()
|
||||
|
||||
existing, ok := existingAttWrapper.IndexedAttestation.(*ethpb.IndexedAttestation)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf(
|
||||
"existing attestation has wrong type (expected %T, got %T)",
|
||||
ðpb.IndexedAttestation{},
|
||||
existingAttWrapper.IndexedAttestation,
|
||||
)
|
||||
}
|
||||
incoming, ok := incomingAttWrapper.IndexedAttestation.(*ethpb.IndexedAttestation)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf(
|
||||
"incoming attestation has wrong type (expected %T, got %T)",
|
||||
ðpb.IndexedAttestation{},
|
||||
incomingAttWrapper.IndexedAttestation,
|
||||
)
|
||||
}
|
||||
|
||||
slashing := ðpb.AttesterSlashing{
|
||||
Attestation_1: existingAttWrapper.IndexedAttestation,
|
||||
Attestation_2: incomingAttWrapper.IndexedAttestation,
|
||||
Attestation_1: existing,
|
||||
Attestation_2: incoming,
|
||||
}
|
||||
|
||||
// Ensure the attestation with the lower data root is the first attestation.
|
||||
if bytes.Compare(existingAttWrapper.DataRoot[:], incomingAttWrapper.DataRoot[:]) > 0 {
|
||||
slashing = ðpb.AttesterSlashing{
|
||||
Attestation_1: incomingAttWrapper.IndexedAttestation,
|
||||
Attestation_2: existingAttWrapper.IndexedAttestation,
|
||||
Attestation_1: incoming,
|
||||
Attestation_2: existing,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -115,11 +115,11 @@ func TestMinSpanChunksSlice_CheckSlashable(t *testing.T) {
|
||||
// based on our min chunk for either validator.
|
||||
slashing, err := chunk.CheckSlashable(ctx, slasherDB, validatorIdx, att)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, (*ethpb.AttesterSlashing)(nil), slashing)
|
||||
require.Equal(t, nil, slashing)
|
||||
|
||||
slashing, err = chunk.CheckSlashable(ctx, slasherDB, validatorIdx.Sub(1), att)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, (*ethpb.AttesterSlashing)(nil), slashing)
|
||||
require.Equal(t, nil, slashing)
|
||||
|
||||
// Next up we initialize an empty chunks slice and mark an attestation
|
||||
// with (source 1, target 2) as attested.
|
||||
@@ -141,11 +141,11 @@ func TestMinSpanChunksSlice_CheckSlashable(t *testing.T) {
|
||||
|
||||
slashing, err = chunk.CheckSlashable(ctx, slasherDB, validatorIdx, surroundingVote)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, (*ethpb.AttesterSlashing)(nil), slashing)
|
||||
require.Equal(t, nil, slashing)
|
||||
|
||||
// Next up, we save the old attestation record, then check if the
|
||||
// surrounding vote is indeed slashable.
|
||||
attData := att.IndexedAttestation.Data
|
||||
attData := att.IndexedAttestation.GetData()
|
||||
attRecord := createAttestationWrapperEmptySig(t, attData.Source.Epoch, attData.Target.Epoch, []uint64{uint64(validatorIdx)}, []byte{1})
|
||||
err = slasherDB.SaveAttestationRecordsForValidators(
|
||||
ctx,
|
||||
@@ -193,11 +193,11 @@ func TestMaxSpanChunksSlice_CheckSlashable(t *testing.T) {
|
||||
// based on our max chunk for either validator.
|
||||
slashing, err := chunk.CheckSlashable(ctx, slasherDB, validatorIdx, att)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, (*ethpb.AttesterSlashing)(nil), slashing)
|
||||
require.Equal(t, nil, slashing)
|
||||
|
||||
slashing, err = chunk.CheckSlashable(ctx, slasherDB, validatorIdx.Sub(1), att)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, (*ethpb.AttesterSlashing)(nil), slashing)
|
||||
require.Equal(t, nil, slashing)
|
||||
|
||||
// Next up we initialize an empty chunks slice and mark an attestation
|
||||
// with (source 0, target 3) as attested.
|
||||
@@ -219,11 +219,11 @@ func TestMaxSpanChunksSlice_CheckSlashable(t *testing.T) {
|
||||
|
||||
slashing, err = chunk.CheckSlashable(ctx, slasherDB, validatorIdx, surroundedVote)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, (*ethpb.AttesterSlashing)(nil), slashing)
|
||||
require.Equal(t, nil, slashing)
|
||||
|
||||
// Next up, we save the old attestation record, then check if the
|
||||
// surroundedVote vote is indeed slashable.
|
||||
attData := att.IndexedAttestation.Data
|
||||
attData := att.IndexedAttestation.GetData()
|
||||
signingRoot := [32]byte{1}
|
||||
attRecord := createAttestationWrapperEmptySig(
|
||||
t, attData.Source.Epoch, attData.Target.Epoch, []uint64{uint64(validatorIdx)}, signingRoot[:],
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
"github.com/pkg/errors"
|
||||
slashertypes "github.com/prysmaticlabs/prysm/v5/beacon-chain/slasher/types"
|
||||
fieldparams "github.com/prysmaticlabs/prysm/v5/config/fieldparams"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/interfaces"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
|
||||
"go.opencensus.io/trace"
|
||||
@@ -18,8 +19,8 @@ import (
|
||||
// found attester slashings to the caller.
|
||||
func (s *Service) checkSlashableAttestations(
|
||||
ctx context.Context, currentEpoch primitives.Epoch, atts []*slashertypes.IndexedAttestationWrapper,
|
||||
) (map[[fieldparams.RootLength]byte]*ethpb.AttesterSlashing, error) {
|
||||
slashings := map[[fieldparams.RootLength]byte]*ethpb.AttesterSlashing{}
|
||||
) (map[[fieldparams.RootLength]byte]interfaces.AttesterSlashing, error) {
|
||||
slashings := map[[fieldparams.RootLength]byte]interfaces.AttesterSlashing{}
|
||||
|
||||
// Double votes
|
||||
doubleVoteSlashings, err := s.checkDoubleVotes(ctx, atts)
|
||||
@@ -56,13 +57,13 @@ func (s *Service) checkSurroundVotes(
|
||||
ctx context.Context,
|
||||
attWrappers []*slashertypes.IndexedAttestationWrapper,
|
||||
currentEpoch primitives.Epoch,
|
||||
) (map[[fieldparams.RootLength]byte]*ethpb.AttesterSlashing, error) {
|
||||
) (map[[fieldparams.RootLength]byte]interfaces.AttesterSlashing, error) {
|
||||
// With 256 validators and 16 epochs per chunk, there is 4096 `uint16` elements per chunk.
|
||||
// 4096 `uint16` elements = 8192 bytes = 8KB
|
||||
// 25_600 chunks * 8KB = 200MB
|
||||
const maxChunkBeforeFlush = 25_600
|
||||
|
||||
slashings := map[[fieldparams.RootLength]byte]*ethpb.AttesterSlashing{}
|
||||
slashings := map[[fieldparams.RootLength]byte]interfaces.AttesterSlashing{}
|
||||
|
||||
// Group attestation wrappers by validator chunk index.
|
||||
attWrappersByValidatorChunkIndex := s.groupByValidatorChunkIndex(attWrappers)
|
||||
@@ -153,7 +154,7 @@ func (s *Service) checkSurroundVotes(
|
||||
// Check for double votes in our database given a list of incoming attestations.
|
||||
func (s *Service) checkDoubleVotes(
|
||||
ctx context.Context, incomingAttWrappers []*slashertypes.IndexedAttestationWrapper,
|
||||
) (map[[fieldparams.RootLength]byte]*ethpb.AttesterSlashing, error) {
|
||||
) (map[[fieldparams.RootLength]byte]interfaces.AttesterSlashing, error) {
|
||||
ctx, span := trace.StartSpan(ctx, "Slasher.checkDoubleVotesOnDisk")
|
||||
defer span.End()
|
||||
|
||||
@@ -162,15 +163,15 @@ func (s *Service) checkDoubleVotes(
|
||||
epoch primitives.Epoch
|
||||
}
|
||||
|
||||
slashings := map[[fieldparams.RootLength]byte]*ethpb.AttesterSlashing{}
|
||||
slashings := map[[fieldparams.RootLength]byte]interfaces.AttesterSlashing{}
|
||||
|
||||
// Check each incoming attestation for double votes against other incoming attestations.
|
||||
existingAttWrappers := make(map[attestationInfo]*slashertypes.IndexedAttestationWrapper)
|
||||
|
||||
for _, incomingAttWrapper := range incomingAttWrappers {
|
||||
targetEpoch := incomingAttWrapper.IndexedAttestation.Data.Target.Epoch
|
||||
targetEpoch := incomingAttWrapper.IndexedAttestation.GetData().Target.Epoch
|
||||
|
||||
for _, validatorIndex := range incomingAttWrapper.IndexedAttestation.AttestingIndices {
|
||||
for _, validatorIndex := range incomingAttWrapper.IndexedAttestation.GetAttestingIndices() {
|
||||
info := attestationInfo{
|
||||
validatorIndex: validatorIndex,
|
||||
epoch: targetEpoch,
|
||||
@@ -193,17 +194,33 @@ func (s *Service) checkDoubleVotes(
|
||||
// This is a double vote.
|
||||
doubleVotesTotal.Inc()
|
||||
|
||||
existing, ok := existingAttWrapper.IndexedAttestation.(*ethpb.IndexedAttestation)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf(
|
||||
"existing attestation has wrong type (expected %T, got %T)",
|
||||
ðpb.IndexedAttestation{},
|
||||
existingAttWrapper.IndexedAttestation,
|
||||
)
|
||||
}
|
||||
incoming, ok := incomingAttWrapper.IndexedAttestation.(*ethpb.IndexedAttestation)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf(
|
||||
"incoming attestation has wrong type (expected %T, got %T)",
|
||||
ðpb.IndexedAttestation{},
|
||||
incomingAttWrapper.IndexedAttestation,
|
||||
)
|
||||
}
|
||||
|
||||
slashing := ðpb.AttesterSlashing{
|
||||
Attestation_1: existingAttWrapper.IndexedAttestation,
|
||||
Attestation_2: incomingAttWrapper.IndexedAttestation,
|
||||
Attestation_1: existing,
|
||||
Attestation_2: incoming,
|
||||
}
|
||||
|
||||
// Ensure the attestation with the lower data root is the first attestation.
|
||||
// It will be useful for comparing with other double votes.
|
||||
if bytes.Compare(existingAttWrapper.DataRoot[:], incomingAttWrapper.DataRoot[:]) > 0 {
|
||||
slashing = ðpb.AttesterSlashing{
|
||||
Attestation_1: incomingAttWrapper.IndexedAttestation,
|
||||
Attestation_2: existingAttWrapper.IndexedAttestation,
|
||||
Attestation_1: incoming,
|
||||
Attestation_2: existing,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -229,16 +246,33 @@ func (s *Service) checkDoubleVotes(
|
||||
wrapper_1 := doubleVote.Wrapper_1
|
||||
wrapper_2 := doubleVote.Wrapper_2
|
||||
|
||||
att_1, ok := wrapper_1.IndexedAttestation.(*ethpb.IndexedAttestation)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf(
|
||||
"first attestation has wrong type (expected %T, got %T)",
|
||||
ðpb.IndexedAttestation{},
|
||||
wrapper_1.IndexedAttestation,
|
||||
)
|
||||
}
|
||||
att_2, ok := wrapper_2.IndexedAttestation.(*ethpb.IndexedAttestation)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf(
|
||||
"second attestation has wrong type (expected %T, got %T)",
|
||||
ðpb.IndexedAttestation{},
|
||||
wrapper_2.IndexedAttestation,
|
||||
)
|
||||
}
|
||||
|
||||
slashing := ðpb.AttesterSlashing{
|
||||
Attestation_1: wrapper_1.IndexedAttestation,
|
||||
Attestation_2: wrapper_2.IndexedAttestation,
|
||||
Attestation_1: att_1,
|
||||
Attestation_2: att_2,
|
||||
}
|
||||
|
||||
// Ensure the attestation with the lower data root is the first attestation.
|
||||
if bytes.Compare(wrapper_1.DataRoot[:], wrapper_2.DataRoot[:]) > 0 {
|
||||
slashing = ðpb.AttesterSlashing{
|
||||
Attestation_1: wrapper_2.IndexedAttestation,
|
||||
Attestation_2: wrapper_1.IndexedAttestation,
|
||||
Attestation_1: att_2,
|
||||
Attestation_2: att_1,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -428,17 +462,17 @@ func (s *Service) updateSpans(
|
||||
kind slashertypes.ChunkKind,
|
||||
validatorChunkIndex uint64,
|
||||
currentEpoch primitives.Epoch,
|
||||
) (map[[fieldparams.RootLength]byte]*ethpb.AttesterSlashing, error) {
|
||||
) (map[[fieldparams.RootLength]byte]interfaces.AttesterSlashing, error) {
|
||||
ctx, span := trace.StartSpan(ctx, "Slasher.updateSpans")
|
||||
defer span.End()
|
||||
|
||||
// Apply the attestations to the related chunks and find any
|
||||
// slashings along the way.
|
||||
slashings := map[[fieldparams.RootLength]byte]*ethpb.AttesterSlashing{}
|
||||
slashings := map[[fieldparams.RootLength]byte]interfaces.AttesterSlashing{}
|
||||
|
||||
for _, attWrappers := range attWrapperByChunkIdx {
|
||||
for _, attWrapper := range attWrappers {
|
||||
for _, validatorIdx := range attWrapper.IndexedAttestation.AttestingIndices {
|
||||
for _, validatorIdx := range attWrapper.IndexedAttestation.GetAttestingIndices() {
|
||||
validatorIndex := primitives.ValidatorIndex(validatorIdx)
|
||||
computedValidatorChunkIdx := s.params.validatorChunkIndex(validatorIndex)
|
||||
|
||||
@@ -493,14 +527,14 @@ func (s *Service) applyAttestationForValidator(
|
||||
validatorChunkIndex uint64,
|
||||
validatorIndex primitives.ValidatorIndex,
|
||||
currentEpoch primitives.Epoch,
|
||||
) (*ethpb.AttesterSlashing, error) {
|
||||
) (interfaces.AttesterSlashing, error) {
|
||||
ctx, span := trace.StartSpan(ctx, "Slasher.applyAttestationForValidator")
|
||||
defer span.End()
|
||||
|
||||
var err error
|
||||
|
||||
sourceEpoch := attestation.IndexedAttestation.Data.Source.Epoch
|
||||
targetEpoch := attestation.IndexedAttestation.Data.Target.Epoch
|
||||
sourceEpoch := attestation.IndexedAttestation.GetData().Source.Epoch
|
||||
targetEpoch := attestation.IndexedAttestation.GetData().Target.Epoch
|
||||
|
||||
attestationDistance.Observe(float64(targetEpoch) - float64(sourceEpoch))
|
||||
chunkIndex := s.params.chunkIndex(sourceEpoch)
|
||||
|
||||
@@ -668,8 +668,8 @@ func Test_processAttestations(t *testing.T) {
|
||||
|
||||
// Create the attester slashing.
|
||||
expectedSlashing := ðpb.AttesterSlashing{
|
||||
Attestation_1: wrapper_1.IndexedAttestation,
|
||||
Attestation_2: wrapper_2.IndexedAttestation,
|
||||
Attestation_1: wrapper_1.IndexedAttestation.(*ethpb.IndexedAttestation),
|
||||
Attestation_2: wrapper_2.IndexedAttestation.(*ethpb.IndexedAttestation),
|
||||
}
|
||||
|
||||
root, err := expectedSlashing.HashTreeRoot()
|
||||
@@ -821,7 +821,7 @@ func Test_processQueuedAttestations_OverlappingChunkIndices(t *testing.T) {
|
||||
s.attsQueue = newAttestationsQueue()
|
||||
s.attsQueue.push(att1)
|
||||
s.attsQueue.push(att2)
|
||||
slot, err := slots.EpochStart(att2.IndexedAttestation.Data.Target.Epoch)
|
||||
slot, err := slots.EpochStart(att2.IndexedAttestation.GetData().Target.Epoch)
|
||||
require.NoError(t, err)
|
||||
mockChain.Slot = &slot
|
||||
s.serviceCfg.HeadStateFetcher = mockChain
|
||||
@@ -1164,7 +1164,7 @@ func Test_applyAttestationForValidator_MinSpanChunk(t *testing.T) {
|
||||
)
|
||||
require.NoError(t, err)
|
||||
require.IsNil(t, slashing)
|
||||
att.IndexedAttestation.AttestingIndices = []uint64{uint64(validatorIdx)}
|
||||
att.IndexedAttestation.(*ethpb.IndexedAttestation).AttestingIndices = []uint64{uint64(validatorIdx)}
|
||||
err = slasherDB.SaveAttestationRecordsForValidators(
|
||||
ctx,
|
||||
[]*slashertypes.IndexedAttestationWrapper{att},
|
||||
@@ -1221,7 +1221,7 @@ func Test_applyAttestationForValidator_MaxSpanChunk(t *testing.T) {
|
||||
)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, true, slashing == nil)
|
||||
att.IndexedAttestation.AttestingIndices = []uint64{uint64(validatorIdx)}
|
||||
att.IndexedAttestation.(*ethpb.IndexedAttestation).AttestingIndices = []uint64{uint64(validatorIdx)}
|
||||
err = slasherDB.SaveAttestationRecordsForValidators(
|
||||
ctx,
|
||||
[]*slashertypes.IndexedAttestationWrapper{att},
|
||||
|
||||
@@ -10,6 +10,7 @@ import (
|
||||
slashertypes "github.com/prysmaticlabs/prysm/v5/beacon-chain/slasher/types"
|
||||
fieldparams "github.com/prysmaticlabs/prysm/v5/config/fieldparams"
|
||||
"github.com/prysmaticlabs/prysm/v5/config/params"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/interfaces"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
|
||||
"github.com/prysmaticlabs/prysm/v5/container/slice"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
|
||||
@@ -28,7 +29,7 @@ func (s *Service) groupByValidatorChunkIndex(
|
||||
for _, attestation := range attestations {
|
||||
validatorChunkIndexes := make(map[uint64]bool)
|
||||
|
||||
for _, validatorIndex := range attestation.IndexedAttestation.AttestingIndices {
|
||||
for _, validatorIndex := range attestation.IndexedAttestation.GetAttestingIndices() {
|
||||
validatorChunkIndex := s.params.validatorChunkIndex(primitives.ValidatorIndex(validatorIndex))
|
||||
validatorChunkIndexes[validatorChunkIndex] = true
|
||||
}
|
||||
@@ -51,7 +52,7 @@ func (s *Service) groupByChunkIndex(
|
||||
attestationsByChunkIndex := make(map[uint64][]*slashertypes.IndexedAttestationWrapper)
|
||||
|
||||
for _, attestation := range attestations {
|
||||
chunkIndex := s.params.chunkIndex(attestation.IndexedAttestation.Data.Source.Epoch)
|
||||
chunkIndex := s.params.chunkIndex(attestation.IndexedAttestation.GetData().Source.Epoch)
|
||||
attestationsByChunkIndex[chunkIndex] = append(attestationsByChunkIndex[chunkIndex], attestation)
|
||||
}
|
||||
|
||||
@@ -74,13 +75,13 @@ func (s *Service) filterAttestations(
|
||||
|
||||
// If an attestation's source is epoch is older than the max history length
|
||||
// we keep track of for slashing detection, we drop it.
|
||||
if attWrapper.IndexedAttestation.Data.Source.Epoch+s.params.historyLength <= currentEpoch {
|
||||
if attWrapper.IndexedAttestation.GetData().Source.Epoch+s.params.historyLength <= currentEpoch {
|
||||
numDropped++
|
||||
continue
|
||||
}
|
||||
|
||||
// If an attestation's target epoch is in the future, we defer processing for later.
|
||||
if attWrapper.IndexedAttestation.Data.Target.Epoch > currentEpoch {
|
||||
if attWrapper.IndexedAttestation.GetData().Target.Epoch > currentEpoch {
|
||||
validInFuture = append(validInFuture, attWrapper)
|
||||
continue
|
||||
}
|
||||
@@ -95,17 +96,17 @@ func (s *Service) filterAttestations(
|
||||
// source and target epochs, and that the source epoch of the attestation must
|
||||
// be less than the target epoch, which is a precondition for performing slashing
|
||||
// detection (except for the genesis epoch).
|
||||
func validateAttestationIntegrity(att *ethpb.IndexedAttestation) bool {
|
||||
func validateAttestationIntegrity(att ethpb.IndexedAtt) bool {
|
||||
// If an attestation is malformed, we drop it.
|
||||
if att == nil ||
|
||||
att.Data == nil ||
|
||||
att.Data.Source == nil ||
|
||||
att.Data.Target == nil {
|
||||
att.GetData() == nil ||
|
||||
att.GetData().Source == nil ||
|
||||
att.GetData().Target == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
sourceEpoch := att.Data.Source.Epoch
|
||||
targetEpoch := att.Data.Target.Epoch
|
||||
sourceEpoch := att.GetData().Source.Epoch
|
||||
targetEpoch := att.GetData().Target.Epoch
|
||||
|
||||
// The genesis epoch is a special case, since all attestations formed in it
|
||||
// will have source and target 0, and they should be considered valid.
|
||||
@@ -129,14 +130,14 @@ func validateBlockHeaderIntegrity(header *ethpb.SignedBeaconBlockHeader) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func logAttesterSlashing(slashing *ethpb.AttesterSlashing) {
|
||||
indices := slice.IntersectionUint64(slashing.Attestation_1.AttestingIndices, slashing.Attestation_2.AttestingIndices)
|
||||
func logAttesterSlashing(slashing interfaces.AttesterSlashing) {
|
||||
indices := slice.IntersectionUint64(slashing.GetFirstAttestation().GetAttestingIndices(), slashing.GetSecondAttestation().GetAttestingIndices())
|
||||
log.WithFields(logrus.Fields{
|
||||
"validatorIndex": indices,
|
||||
"prevSourceEpoch": slashing.Attestation_1.Data.Source.Epoch,
|
||||
"prevTargetEpoch": slashing.Attestation_1.Data.Target.Epoch,
|
||||
"sourceEpoch": slashing.Attestation_2.Data.Source.Epoch,
|
||||
"targetEpoch": slashing.Attestation_2.Data.Target.Epoch,
|
||||
"prevSourceEpoch": slashing.GetFirstAttestation().GetData().Source.Epoch,
|
||||
"prevTargetEpoch": slashing.GetFirstAttestation().GetData().Target.Epoch,
|
||||
"sourceEpoch": slashing.GetSecondAttestation().GetData().Source.Epoch,
|
||||
"targetEpoch": slashing.GetSecondAttestation().GetData().Target.Epoch,
|
||||
}).Info("Attester slashing detected")
|
||||
}
|
||||
|
||||
|
||||
@@ -271,22 +271,22 @@ func Test_logSlashingEvent(t *testing.T) {
|
||||
{
|
||||
name: "Surrounding vote",
|
||||
slashing: ðpb.AttesterSlashing{
|
||||
Attestation_1: createAttestationWrapperEmptySig(t, 0, 0, nil, nil).IndexedAttestation,
|
||||
Attestation_2: createAttestationWrapperEmptySig(t, 0, 0, nil, nil).IndexedAttestation,
|
||||
Attestation_1: createAttestationWrapperEmptySig(t, 0, 0, nil, nil).IndexedAttestation.(*ethpb.IndexedAttestation),
|
||||
Attestation_2: createAttestationWrapperEmptySig(t, 0, 0, nil, nil).IndexedAttestation.(*ethpb.IndexedAttestation),
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Surrounded vote",
|
||||
slashing: ðpb.AttesterSlashing{
|
||||
Attestation_1: createAttestationWrapperEmptySig(t, 0, 0, nil, nil).IndexedAttestation,
|
||||
Attestation_2: createAttestationWrapperEmptySig(t, 0, 0, nil, nil).IndexedAttestation,
|
||||
Attestation_1: createAttestationWrapperEmptySig(t, 0, 0, nil, nil).IndexedAttestation.(*ethpb.IndexedAttestation),
|
||||
Attestation_2: createAttestationWrapperEmptySig(t, 0, 0, nil, nil).IndexedAttestation.(*ethpb.IndexedAttestation),
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Double vote",
|
||||
slashing: ðpb.AttesterSlashing{
|
||||
Attestation_1: createAttestationWrapperEmptySig(t, 0, 0, nil, nil).IndexedAttestation,
|
||||
Attestation_2: createAttestationWrapperEmptySig(t, 0, 0, nil, nil).IndexedAttestation,
|
||||
Attestation_1: createAttestationWrapperEmptySig(t, 0, 0, nil, nil).IndexedAttestation.(*ethpb.IndexedAttestation),
|
||||
Attestation_2: createAttestationWrapperEmptySig(t, 0, 0, nil, nil).IndexedAttestation.(*ethpb.IndexedAttestation),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
"github.com/pkg/errors"
|
||||
"github.com/prysmaticlabs/prysm/v5/beacon-chain/core/blocks"
|
||||
fieldparams "github.com/prysmaticlabs/prysm/v5/config/fieldparams"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/interfaces"
|
||||
"github.com/prysmaticlabs/prysm/v5/encoding/bytesutil"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
|
||||
)
|
||||
@@ -13,9 +14,9 @@ import (
|
||||
// Verifies attester slashings, logs them, and submits them to the slashing operations pool
|
||||
// in the beacon node if they pass validation.
|
||||
func (s *Service) processAttesterSlashings(
|
||||
ctx context.Context, slashings map[[fieldparams.RootLength]byte]*ethpb.AttesterSlashing,
|
||||
) (map[[fieldparams.RootLength]byte]*ethpb.AttesterSlashing, error) {
|
||||
processedSlashings := map[[fieldparams.RootLength]byte]*ethpb.AttesterSlashing{}
|
||||
ctx context.Context, slashings map[[fieldparams.RootLength]byte]interfaces.AttesterSlashing,
|
||||
) (map[[fieldparams.RootLength]byte]interfaces.AttesterSlashing, error) {
|
||||
processedSlashings := map[[fieldparams.RootLength]byte]interfaces.AttesterSlashing{}
|
||||
|
||||
// If no slashings, return early.
|
||||
if len(slashings) == 0 {
|
||||
@@ -30,8 +31,8 @@ func (s *Service) processAttesterSlashings(
|
||||
|
||||
for root, slashing := range slashings {
|
||||
// Verify the signature of the first attestation.
|
||||
if err := s.verifyAttSignature(ctx, slashing.Attestation_1); err != nil {
|
||||
log.WithError(err).WithField("a", slashing.Attestation_1).Warn(
|
||||
if err := s.verifyAttSignature(ctx, slashing.GetFirstAttestation()); err != nil {
|
||||
log.WithError(err).WithField("a", slashing.GetFirstAttestation()).Warn(
|
||||
"Invalid signature for attestation in detected slashing offense",
|
||||
)
|
||||
|
||||
@@ -39,8 +40,8 @@ func (s *Service) processAttesterSlashings(
|
||||
}
|
||||
|
||||
// Verify the signature of the second attestation.
|
||||
if err := s.verifyAttSignature(ctx, slashing.Attestation_2); err != nil {
|
||||
log.WithError(err).WithField("b", slashing.Attestation_2).Warn(
|
||||
if err := s.verifyAttSignature(ctx, slashing.GetSecondAttestation()); err != nil {
|
||||
log.WithError(err).WithField("b", slashing.GetSecondAttestation()).Warn(
|
||||
"Invalid signature for attestation in detected slashing offense",
|
||||
)
|
||||
|
||||
@@ -110,8 +111,8 @@ func (s *Service) verifyBlockSignature(ctx context.Context, header *ethpb.Signed
|
||||
return blocks.VerifyBlockHeaderSignature(parentState, header)
|
||||
}
|
||||
|
||||
func (s *Service) verifyAttSignature(ctx context.Context, att *ethpb.IndexedAttestation) error {
|
||||
preState, err := s.serviceCfg.AttestationStateFetcher.AttestationTargetState(ctx, att.Data.Target)
|
||||
func (s *Service) verifyAttSignature(ctx context.Context, att ethpb.IndexedAtt) error {
|
||||
preState, err := s.serviceCfg.AttestationStateFetcher.AttestationTargetState(ctx, att.GetData().Target)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ import (
|
||||
"github.com/prysmaticlabs/prysm/v5/beacon-chain/state/stategen"
|
||||
fieldparams "github.com/prysmaticlabs/prysm/v5/config/fieldparams"
|
||||
"github.com/prysmaticlabs/prysm/v5/config/params"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/interfaces"
|
||||
"github.com/prysmaticlabs/prysm/v5/crypto/bls"
|
||||
"github.com/prysmaticlabs/prysm/v5/encoding/bytesutil"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
|
||||
@@ -84,7 +85,7 @@ func TestService_processAttesterSlashings(t *testing.T) {
|
||||
root, err := slashing.HashTreeRoot()
|
||||
require.NoError(tt, err, "failed to hash tree root")
|
||||
|
||||
slashings := map[[fieldparams.RootLength]byte]*ethpb.AttesterSlashing{
|
||||
slashings := map[[fieldparams.RootLength]byte]interfaces.AttesterSlashing{
|
||||
root: slashing,
|
||||
}
|
||||
|
||||
@@ -108,7 +109,7 @@ func TestService_processAttesterSlashings(t *testing.T) {
|
||||
root, err := slashing.HashTreeRoot()
|
||||
require.NoError(tt, err, "failed to hash tree root")
|
||||
|
||||
slashings := map[[fieldparams.RootLength]byte]*ethpb.AttesterSlashing{
|
||||
slashings := map[[fieldparams.RootLength]byte]interfaces.AttesterSlashing{
|
||||
root: slashing,
|
||||
}
|
||||
|
||||
@@ -132,7 +133,7 @@ func TestService_processAttesterSlashings(t *testing.T) {
|
||||
root, err := slashing.HashTreeRoot()
|
||||
require.NoError(tt, err, "failed to hash tree root")
|
||||
|
||||
slashings := map[[fieldparams.RootLength]byte]*ethpb.AttesterSlashing{
|
||||
slashings := map[[fieldparams.RootLength]byte]interfaces.AttesterSlashing{
|
||||
root: slashing,
|
||||
}
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
"github.com/pkg/errors"
|
||||
slashertypes "github.com/prysmaticlabs/prysm/v5/beacon-chain/slasher/types"
|
||||
fieldparams "github.com/prysmaticlabs/prysm/v5/config/fieldparams"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/interfaces"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/v5/time/slots"
|
||||
@@ -22,7 +23,7 @@ const (
|
||||
// Receive indexed attestations from some source event feed,
|
||||
// validating their integrity before appending them to an attestation queue
|
||||
// for batch processing in a separate routine.
|
||||
func (s *Service) receiveAttestations(ctx context.Context, indexedAttsChan chan *ethpb.IndexedAttestation) {
|
||||
func (s *Service) receiveAttestations(ctx context.Context, indexedAttsChan chan ethpb.IndexedAtt) {
|
||||
defer s.wg.Done()
|
||||
|
||||
sub := s.serviceCfg.IndexedAttestationsFeed.Subscribe(indexedAttsChan)
|
||||
@@ -33,7 +34,7 @@ func (s *Service) receiveAttestations(ctx context.Context, indexedAttsChan chan
|
||||
if !validateAttestationIntegrity(att) {
|
||||
continue
|
||||
}
|
||||
dataRoot, err := att.Data.HashTreeRoot()
|
||||
dataRoot, err := att.GetData().HashTreeRoot()
|
||||
if err != nil {
|
||||
log.WithError(err).Error("Could not get hash tree root of attestation")
|
||||
continue
|
||||
@@ -108,7 +109,7 @@ func (s *Service) processAttestations(
|
||||
ctx context.Context,
|
||||
attestations []*slashertypes.IndexedAttestationWrapper,
|
||||
currentSlot primitives.Slot,
|
||||
) map[[fieldparams.RootLength]byte]*ethpb.AttesterSlashing {
|
||||
) map[[fieldparams.RootLength]byte]interfaces.AttesterSlashing {
|
||||
// Get the current epoch from the current slot.
|
||||
currentEpoch := slots.ToEpoch(currentSlot)
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ func TestSlasher_receiveAttestations_OK(t *testing.T) {
|
||||
},
|
||||
attsQueue: newAttestationsQueue(),
|
||||
}
|
||||
indexedAttsChan := make(chan *ethpb.IndexedAttestation)
|
||||
indexedAttsChan := make(chan ethpb.IndexedAtt)
|
||||
defer close(indexedAttsChan)
|
||||
|
||||
s.wg.Add(1)
|
||||
@@ -212,7 +212,7 @@ func TestSlasher_receiveAttestations_OnlyValidAttestations(t *testing.T) {
|
||||
},
|
||||
attsQueue: newAttestationsQueue(),
|
||||
}
|
||||
indexedAttsChan := make(chan *ethpb.IndexedAttestation)
|
||||
indexedAttsChan := make(chan ethpb.IndexedAtt)
|
||||
defer close(indexedAttsChan)
|
||||
|
||||
s.wg.Add(1)
|
||||
|
||||
@@ -48,7 +48,7 @@ type ServiceConfig struct {
|
||||
type Service struct {
|
||||
params *Parameters
|
||||
serviceCfg *ServiceConfig
|
||||
indexedAttsChan chan *ethpb.IndexedAttestation
|
||||
indexedAttsChan chan ethpb.IndexedAtt
|
||||
beaconBlockHeadersChan chan *ethpb.SignedBeaconBlockHeader
|
||||
attsQueue *attestationsQueue
|
||||
blksQueue *blocksQueue
|
||||
@@ -68,7 +68,7 @@ func New(ctx context.Context, srvCfg *ServiceConfig) (*Service, error) {
|
||||
return &Service{
|
||||
params: DefaultParams(),
|
||||
serviceCfg: srvCfg,
|
||||
indexedAttsChan: make(chan *ethpb.IndexedAttestation, 1),
|
||||
indexedAttsChan: make(chan ethpb.IndexedAtt, 1),
|
||||
beaconBlockHeadersChan: make(chan *ethpb.SignedBeaconBlockHeader, 1),
|
||||
attsQueue: newAttestationsQueue(),
|
||||
blksQueue: newBlocksQueue(),
|
||||
@@ -117,7 +117,7 @@ func (s *Service) run() {
|
||||
"Finished retrieving last epoch written per validator",
|
||||
)
|
||||
|
||||
indexedAttsChan := make(chan *ethpb.IndexedAttestation, 1)
|
||||
indexedAttsChan := make(chan ethpb.IndexedAtt, 1)
|
||||
beaconBlockHeadersChan := make(chan *ethpb.SignedBeaconBlockHeader, 1)
|
||||
|
||||
s.wg.Add(1)
|
||||
|
||||
@@ -29,7 +29,7 @@ func (c ChunkKind) String() string {
|
||||
// IndexedAttestationWrapper contains an indexed attestation with its
|
||||
// data root to reduce duplicated computation.
|
||||
type IndexedAttestationWrapper struct {
|
||||
IndexedAttestation *ethpb.IndexedAttestation
|
||||
IndexedAttestation ethpb.IndexedAtt
|
||||
DataRoot [32]byte
|
||||
}
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ import (
|
||||
"github.com/prysmaticlabs/prysm/v5/beacon-chain/operations/attestations"
|
||||
lruwrpr "github.com/prysmaticlabs/prysm/v5/cache/lru"
|
||||
fieldparams "github.com/prysmaticlabs/prysm/v5/config/fieldparams"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/interfaces"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
|
||||
"github.com/prysmaticlabs/prysm/v5/testing/assert"
|
||||
"github.com/prysmaticlabs/prysm/v5/testing/require"
|
||||
@@ -34,7 +35,7 @@ func TestBeaconAggregateProofSubscriber_CanSaveAggregatedAttestation(t *testing.
|
||||
Signature: make([]byte, fieldparams.BLSSignatureLength),
|
||||
}
|
||||
require.NoError(t, r.beaconAggregateProofSubscriber(context.Background(), a))
|
||||
assert.DeepSSZEqual(t, []*ethpb.Attestation{a.Message.Aggregate}, r.cfg.attPool.AggregatedAttestations(), "Did not save aggregated attestation")
|
||||
assert.DeepSSZEqual(t, []interfaces.Attestation{a.Message.Aggregate}, r.cfg.attPool.AggregatedAttestations(), "Did not save aggregated attestation")
|
||||
}
|
||||
|
||||
func TestBeaconAggregateProofSubscriber_CanSaveUnaggregatedAttestation(t *testing.T) {
|
||||
@@ -59,5 +60,5 @@ func TestBeaconAggregateProofSubscriber_CanSaveUnaggregatedAttestation(t *testin
|
||||
|
||||
atts, err := r.cfg.attPool.UnaggregatedAttestations()
|
||||
require.NoError(t, err)
|
||||
assert.DeepEqual(t, []*ethpb.Attestation{a.Message.Aggregate}, atts, "Did not save unaggregated attestation")
|
||||
assert.DeepEqual(t, []interfaces.Attestation{a.Message.Aggregate}, atts, "Did not save unaggregated attestation")
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"fmt"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/interfaces"
|
||||
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
|
||||
"google.golang.org/protobuf/proto"
|
||||
)
|
||||
@@ -25,13 +26,13 @@ func (s *Service) voluntaryExitSubscriber(_ context.Context, msg proto.Message)
|
||||
}
|
||||
|
||||
func (s *Service) attesterSlashingSubscriber(ctx context.Context, msg proto.Message) error {
|
||||
aSlashing, ok := msg.(*ethpb.AttesterSlashing)
|
||||
aSlashing, ok := msg.(interfaces.AttesterSlashing)
|
||||
if !ok {
|
||||
return fmt.Errorf("wrong type, expected: *ethpb.AttesterSlashing got: %T", msg)
|
||||
}
|
||||
// Do some nil checks to prevent easy DoS'ing of this handler.
|
||||
aSlashing1IsNil := aSlashing == nil || aSlashing.Attestation_1 == nil || aSlashing.Attestation_1.AttestingIndices == nil
|
||||
aSlashing2IsNil := aSlashing == nil || aSlashing.Attestation_2 == nil || aSlashing.Attestation_2.AttestingIndices == nil
|
||||
aSlashing1IsNil := aSlashing == nil || aSlashing.GetFirstAttestation() == nil || aSlashing.GetFirstAttestation().GetAttestingIndices() == nil
|
||||
aSlashing2IsNil := aSlashing == nil || aSlashing.GetSecondAttestation() == nil || aSlashing.GetSecondAttestation().GetAttestingIndices() == nil
|
||||
if !aSlashing1IsNil && !aSlashing2IsNil {
|
||||
headState, err := s.cfg.chain.HeadState(ctx)
|
||||
if err != nil {
|
||||
@@ -40,7 +41,7 @@ func (s *Service) attesterSlashingSubscriber(ctx context.Context, msg proto.Mess
|
||||
if err := s.cfg.slashingPool.InsertAttesterSlashing(ctx, headState, aSlashing); err != nil {
|
||||
return errors.Wrap(err, "could not insert attester slashing into pool")
|
||||
}
|
||||
s.setAttesterSlashingIndicesSeen(aSlashing.Attestation_1.AttestingIndices, aSlashing.Attestation_2.AttestingIndices)
|
||||
s.setAttesterSlashingIndicesSeen(aSlashing.GetFirstAttestation().GetAttestingIndices(), aSlashing.GetSecondAttestation().GetAttestingIndices())
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ import (
|
||||
"github.com/prysmaticlabs/prysm/v5/beacon-chain/core/signing"
|
||||
"github.com/prysmaticlabs/prysm/v5/beacon-chain/state"
|
||||
"github.com/prysmaticlabs/prysm/v5/config/params"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/interfaces"
|
||||
"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives"
|
||||
"github.com/prysmaticlabs/prysm/v5/crypto/bls"
|
||||
"github.com/prysmaticlabs/prysm/v5/encoding/bytesutil"
|
||||
@@ -176,7 +177,7 @@ func (s *Service) validateAggregatedAtt(ctx context.Context, signed *ethpb.Signe
|
||||
tracing.AnnotateError(span, wrappedErr)
|
||||
return pubsub.ValidationIgnore, wrappedErr
|
||||
}
|
||||
attSigSet, err := blocks.AttestationSignatureBatch(ctx, bs, []*ethpb.Attestation{signed.Message.Aggregate})
|
||||
attSigSet, err := blocks.AttestationSignatureBatch(ctx, bs, []interfaces.Attestation{signed.Message.Aggregate})
|
||||
if err != nil {
|
||||
wrappedErr := errors.Wrapf(err, "Could not verify aggregator signature %d", signed.Message.AggregatorIndex)
|
||||
tracing.AnnotateError(span, wrappedErr)
|
||||
@@ -225,7 +226,7 @@ func (s *Service) setAggregatorIndexEpochSeen(epoch primitives.Epoch, aggregator
|
||||
// - [REJECT] The aggregate attestation has participants -- that is, len(get_attesting_indices(state, aggregate.data, aggregate.aggregation_bits)) >= 1.
|
||||
// - [REJECT] The aggregator's validator index is within the committee --
|
||||
// i.e. `aggregate_and_proof.aggregator_index in get_beacon_committee(state, aggregate.data.slot, aggregate.data.index)`.
|
||||
func (s *Service) validateIndexInCommittee(ctx context.Context, bs state.ReadOnlyBeaconState, a *ethpb.Attestation, validatorIndex primitives.ValidatorIndex) (pubsub.ValidationResult, error) {
|
||||
func (s *Service) validateIndexInCommittee(ctx context.Context, bs state.ReadOnlyBeaconState, a interfaces.Attestation, validatorIndex primitives.ValidatorIndex) (pubsub.ValidationResult, error) {
|
||||
ctx, span := trace.StartSpan(ctx, "sync.validateIndexInCommittee")
|
||||
defer span.End()
|
||||
|
||||
@@ -239,7 +240,7 @@ func (s *Service) validateIndexInCommittee(ctx context.Context, bs state.ReadOnl
|
||||
return result, err
|
||||
}
|
||||
|
||||
if a.AggregationBits.Count() == 0 {
|
||||
if a.GetAggregationBits().Count() == 0 {
|
||||
return pubsub.ValidationReject, errors.New("no attesting indices")
|
||||
}
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user