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:
Radosław Kapka
2024-05-01 06:29:38 +09:00
committed by GitHub
parent ae16d5f52c
commit 2c5a2e8ec7
174 changed files with 3463 additions and 1792 deletions

View File

@@ -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)",
&ethpb.IndexedAttestation{},
existingAttWrapper.IndexedAttestation,
)
}
incoming, ok := incomingAttWrapper.IndexedAttestation.(*ethpb.IndexedAttestation)
if !ok {
return nil, fmt.Errorf(
"incoming attestation has wrong type (expected %T, got %T)",
&ethpb.IndexedAttestation{},
incomingAttWrapper.IndexedAttestation,
)
}
slashing := &ethpb.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 = &ethpb.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)",
&ethpb.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)",
&ethpb.IndexedAttestation{},
wrapper_2.IndexedAttestation,
)
}
slashing := &ethpb.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 = &ethpb.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)