mirror of
https://github.com/OffchainLabs/prysm.git
synced 2026-01-09 23:48:06 -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:
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user