diff --git a/api/server/structs/BUILD.bazel b/api/server/structs/BUILD.bazel index 54ed0b02a9..1651247213 100644 --- a/api/server/structs/BUILD.bazel +++ b/api/server/structs/BUILD.bazel @@ -28,6 +28,7 @@ go_library( "//api/server:go_default_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", "//consensus-types/validator:go_default_library", diff --git a/api/server/structs/conversions.go b/api/server/structs/conversions.go index 780ebb50e3..25db9676a8 100644 --- a/api/server/structs/conversions.go +++ b/api/server/structs/conversions.go @@ -9,6 +9,7 @@ import ( "github.com/pkg/errors" "github.com/prysmaticlabs/prysm/v5/api/server" fieldparams "github.com/prysmaticlabs/prysm/v5/config/fieldparams" + "github.com/prysmaticlabs/prysm/v5/config/params" "github.com/prysmaticlabs/prysm/v5/consensus-types/primitives" "github.com/prysmaticlabs/prysm/v5/consensus-types/validator" "github.com/prysmaticlabs/prysm/v5/container/slice" @@ -243,7 +244,7 @@ func (c *ContributionAndProof) ToConsensus() (*eth.ContributionAndProof, error) if err != nil { return nil, server.NewDecodeError(err, "AggregatorIndex") } - selectionProof, err := bytesutil.DecodeHexWithLength(c.SelectionProof, 96) + selectionProof, err := bytesutil.DecodeHexWithLength(c.SelectionProof, fieldparams.BLSSignatureLength) if err != nil { return nil, server.NewDecodeError(err, "SelectionProof") } @@ -330,7 +331,7 @@ func (a *AggregateAttestationAndProof) ToConsensus() (*eth.AggregateAttestationA if err != nil { return nil, server.NewDecodeError(err, "Aggregate") } - proof, err := bytesutil.DecodeHexWithLength(a.SelectionProof, 96) + proof, err := bytesutil.DecodeHexWithLength(a.SelectionProof, fieldparams.BLSSignatureLength) if err != nil { return nil, server.NewDecodeError(err, "SelectionProof") } @@ -366,7 +367,7 @@ func (a *AggregateAttestationAndProofElectra) ToConsensus() (*eth.AggregateAttes if err != nil { return nil, server.NewDecodeError(err, "Aggregate") } - proof, err := bytesutil.DecodeHexWithLength(a.SelectionProof, 96) + proof, err := bytesutil.DecodeHexWithLength(a.SelectionProof, fieldparams.BLSSignatureLength) if err != nil { return nil, server.NewDecodeError(err, "SelectionProof") } @@ -734,6 +735,10 @@ func (s *AttesterSlashingElectra) ToConsensus() (*eth.AttesterSlashingElectra, e } func (a *IndexedAttestation) ToConsensus() (*eth.IndexedAttestation, error) { + if err := slice.VerifyMaxLength(a.AttestingIndices, params.BeaconConfig().MaxValidatorsPerCommittee); err != nil { + return nil, err + } + indices := make([]uint64, len(a.AttestingIndices)) var err error for i, ix := range a.AttestingIndices { @@ -759,6 +764,13 @@ func (a *IndexedAttestation) ToConsensus() (*eth.IndexedAttestation, error) { } func (a *IndexedAttestationElectra) ToConsensus() (*eth.IndexedAttestationElectra, error) { + if err := slice.VerifyMaxLength( + a.AttestingIndices, + params.BeaconConfig().MaxValidatorsPerCommittee*params.BeaconConfig().MaxCommitteesPerSlot, + ); err != nil { + return nil, err + } + indices := make([]uint64, len(a.AttestingIndices)) var err error for i, ix := range a.AttestingIndices { @@ -1189,7 +1201,7 @@ func AttesterSlashingsElectraToConsensus(src []*AttesterSlashingElectra) ([]*eth if src == nil { return nil, errNilValue } - err := slice.VerifyMaxLength(src, 2) + err := slice.VerifyMaxLength(src, fieldparams.MaxAttesterSlashingsElectra) if err != nil { return nil, err } @@ -1210,7 +1222,7 @@ func AttesterSlashingsElectraToConsensus(src []*AttesterSlashingElectra) ([]*eth if err != nil { return nil, server.NewDecodeError(err, fmt.Sprintf("[%d].Attestation1.Signature", i)) } - err = slice.VerifyMaxLength(s.Attestation1.AttestingIndices, 2048) + err = slice.VerifyMaxLength(s.Attestation1.AttestingIndices, params.BeaconConfig().MaxValidatorsPerCommittee*params.BeaconConfig().MaxCommitteesPerSlot) if err != nil { return nil, server.NewDecodeError(err, fmt.Sprintf("[%d].Attestation1.AttestingIndices", i)) } @@ -1230,7 +1242,7 @@ func AttesterSlashingsElectraToConsensus(src []*AttesterSlashingElectra) ([]*eth if err != nil { return nil, server.NewDecodeError(err, fmt.Sprintf("[%d].Attestation2.Signature", i)) } - err = slice.VerifyMaxLength(s.Attestation2.AttestingIndices, 2048) + err = slice.VerifyMaxLength(s.Attestation2.AttestingIndices, params.BeaconConfig().MaxValidatorsPerCommittee*params.BeaconConfig().MaxCommitteesPerSlot) if err != nil { return nil, server.NewDecodeError(err, fmt.Sprintf("[%d].Attestation2.AttestingIndices", i)) } diff --git a/api/server/structs/conversions_block.go b/api/server/structs/conversions_block.go index d3258b4052..accad96aec 100644 --- a/api/server/structs/conversions_block.go +++ b/api/server/structs/conversions_block.go @@ -9,6 +9,7 @@ import ( "github.com/pkg/errors" "github.com/prysmaticlabs/prysm/v5/api/server" 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" @@ -2519,6 +2520,7 @@ func (b *BeaconBlockContentsElectra) ToConsensus() (*eth.BeaconBlockContentsElec }, nil } +// nolint:gocognit func (b *BeaconBlockElectra) ToConsensus() (*eth.BeaconBlockElectra, error) { if b == nil { return nil, errNilValue @@ -2706,6 +2708,9 @@ func (b *BeaconBlockElectra) ToConsensus() (*eth.BeaconBlockElectra, error) { return nil, server.NewDecodeError(errors.New("nil execution requests"), "Body.ExequtionRequests") } + if err = slice.VerifyMaxLength(b.Body.ExecutionRequests.Deposits, params.BeaconConfig().MaxDepositRequestsPerPayload); err != nil { + return nil, err + } depositRequests := make([]*enginev1.DepositRequest, len(b.Body.ExecutionRequests.Deposits)) for i, d := range b.Body.ExecutionRequests.Deposits { depositRequests[i], err = d.ToConsensus() @@ -2714,6 +2719,9 @@ func (b *BeaconBlockElectra) ToConsensus() (*eth.BeaconBlockElectra, error) { } } + if err = slice.VerifyMaxLength(b.Body.ExecutionRequests.Withdrawals, params.BeaconConfig().MaxWithdrawalRequestsPerPayload); err != nil { + return nil, err + } withdrawalRequests := make([]*enginev1.WithdrawalRequest, len(b.Body.ExecutionRequests.Withdrawals)) for i, w := range b.Body.ExecutionRequests.Withdrawals { withdrawalRequests[i], err = w.ToConsensus() @@ -2722,6 +2730,9 @@ func (b *BeaconBlockElectra) ToConsensus() (*eth.BeaconBlockElectra, error) { } } + if err = slice.VerifyMaxLength(b.Body.ExecutionRequests.Consolidations, params.BeaconConfig().MaxConsolidationsRequestsPerPayload); err != nil { + return nil, err + } consolidationRequests := make([]*enginev1.ConsolidationRequest, len(b.Body.ExecutionRequests.Consolidations)) for i, c := range b.Body.ExecutionRequests.Consolidations { consolidationRequests[i], err = c.ToConsensus() @@ -3003,9 +3014,14 @@ func (b *BlindedBeaconBlockElectra) ToConsensus() (*eth.BlindedBeaconBlockElectr if err != nil { return nil, server.NewDecodeError(err, "Body.ExecutionPayload.ExcessBlobGas") } + if b.Body.ExecutionRequests == nil { return nil, server.NewDecodeError(errors.New("nil execution requests"), "Body.ExecutionRequests") } + + if err = slice.VerifyMaxLength(b.Body.ExecutionRequests.Deposits, params.BeaconConfig().MaxDepositRequestsPerPayload); err != nil { + return nil, err + } depositRequests := make([]*enginev1.DepositRequest, len(b.Body.ExecutionRequests.Deposits)) for i, d := range b.Body.ExecutionRequests.Deposits { depositRequests[i], err = d.ToConsensus() @@ -3014,6 +3030,9 @@ func (b *BlindedBeaconBlockElectra) ToConsensus() (*eth.BlindedBeaconBlockElectr } } + if err = slice.VerifyMaxLength(b.Body.ExecutionRequests.Withdrawals, params.BeaconConfig().MaxWithdrawalRequestsPerPayload); err != nil { + return nil, err + } withdrawalRequests := make([]*enginev1.WithdrawalRequest, len(b.Body.ExecutionRequests.Withdrawals)) for i, w := range b.Body.ExecutionRequests.Withdrawals { withdrawalRequests[i], err = w.ToConsensus() @@ -3022,6 +3041,9 @@ func (b *BlindedBeaconBlockElectra) ToConsensus() (*eth.BlindedBeaconBlockElectr } } + if err = slice.VerifyMaxLength(b.Body.ExecutionRequests.Consolidations, params.BeaconConfig().MaxConsolidationsRequestsPerPayload); err != nil { + return nil, err + } consolidationRequests := make([]*enginev1.ConsolidationRequest, len(b.Body.ExecutionRequests.Consolidations)) for i, c := range b.Body.ExecutionRequests.Consolidations { consolidationRequests[i], err = c.ToConsensus() diff --git a/beacon-chain/core/electra/consolidations.go b/beacon-chain/core/electra/consolidations.go index 3861729389..978b72ad1d 100644 --- a/beacon-chain/core/electra/consolidations.go +++ b/beacon-chain/core/electra/consolidations.go @@ -265,7 +265,7 @@ func ProcessConsolidationRequests(ctx context.Context, st state.BeaconState, req if !helpers.IsActiveValidator(srcV, curEpoch) || !helpers.IsActiveValidatorUsingTrie(tgtV, curEpoch) { continue } - // Neither validator are exiting. + // Neither validator is exiting. if srcV.ExitEpoch != ffe || tgtV.ExitEpoch() != ffe { continue } diff --git a/beacon-chain/core/helpers/validator_churn.go b/beacon-chain/core/helpers/validator_churn.go index a038e32b7d..d6a2e55b7c 100644 --- a/beacon-chain/core/helpers/validator_churn.go +++ b/beacon-chain/core/helpers/validator_churn.go @@ -22,7 +22,7 @@ import ( func BalanceChurnLimit(activeBalance primitives.Gwei) primitives.Gwei { churn := max( params.BeaconConfig().MinPerEpochChurnLimitElectra, - (uint64(activeBalance) / params.BeaconConfig().ChurnLimitQuotient), + uint64(activeBalance)/params.BeaconConfig().ChurnLimitQuotient, ) return primitives.Gwei(churn - churn%params.BeaconConfig().EffectiveBalanceIncrement) } diff --git a/beacon-chain/core/helpers/validators.go b/beacon-chain/core/helpers/validators.go index 879876c25e..be387d2bc9 100644 --- a/beacon-chain/core/helpers/validators.go +++ b/beacon-chain/core/helpers/validators.go @@ -393,9 +393,9 @@ func ComputeProposerIndex(bState state.ReadOnlyBeaconState, activeIndices []prim effectiveBal := v.EffectiveBalance() if bState.Version() >= version.Electra { binary.LittleEndian.PutUint64(seedBuffer[len(seed):], i/16) - randomByte := hashFunc(seedBuffer) + randomBytes := hashFunc(seedBuffer) offset := (i % 16) * 2 - randomValue := uint64(randomByte[offset]) | uint64(randomByte[offset+1])<<8 + randomValue := uint64(randomBytes[offset]) | uint64(randomBytes[offset+1])<<8 if effectiveBal*fieldparams.MaxRandomValueElectra >= beaconConfig.MaxEffectiveBalanceElectra*randomValue { return candidateIndex, nil @@ -579,7 +579,7 @@ func IsPartiallyWithdrawableValidator(val state.ReadOnlyValidator, balance uint6 // """ // Check if ``validator`` is partially withdrawable. // """ -// max_effective_balance = get_validator_max_effective_balance(validator) +// max_effective_balance = get_max_effective_balance(validator) // has_max_effective_balance = validator.effective_balance == max_effective_balance # [Modified in Electra:EIP7251] // has_excess_balance = balance > max_effective_balance # [Modified in Electra:EIP7251] // return ( @@ -619,7 +619,7 @@ func isPartiallyWithdrawableValidatorCapella(val state.ReadOnlyValidator, balanc // // Spec definition: // -// def get_validator_max_effective_balance(validator: Validator) -> Gwei: +// def get_max_effective_balance(validator: Validator) -> Gwei: // """ // Get max effective balance for ``validator``. // """ diff --git a/beacon-chain/core/validators/validator.go b/beacon-chain/core/validators/validator.go index 56805d5f0b..a68264d9c9 100644 --- a/beacon-chain/core/validators/validator.go +++ b/beacon-chain/core/validators/validator.go @@ -75,7 +75,7 @@ func InitiateValidatorExit(ctx context.Context, s state.BeaconState, idx primiti // Compute exit queue epoch. if s.Version() < version.Electra { - // Relevant spec code from deneb: + // Relevant spec code from phase0: // // exit_epochs = [v.exit_epoch for v in state.validators if v.exit_epoch != FAR_FUTURE_EPOCH] // exit_queue_epoch = max(exit_epochs + [compute_activation_exit_epoch(get_current_epoch(state))]) diff --git a/beacon-chain/rpc/eth/beacon/handlers_pool_test.go b/beacon-chain/rpc/eth/beacon/handlers_pool_test.go index f612f942c8..6bfe978ced 100644 --- a/beacon-chain/rpc/eth/beacon/handlers_pool_test.go +++ b/beacon-chain/rpc/eth/beacon/handlers_pool_test.go @@ -1559,7 +1559,7 @@ func TestGetAttesterSlashings(t *testing.T) { Signature: bytesutil.PadTo([]byte("signature4"), 96), }, } - slashing1PostElectra := ðpbv1alpha1.AttesterSlashingElectra{ + slashingPostElectra := ðpbv1alpha1.AttesterSlashingElectra{ Attestation_1: ðpbv1alpha1.IndexedAttestationElectra{ AttestingIndices: []uint64{1, 10}, Data: ðpbv1alpha1.AttestationData{ @@ -1595,42 +1595,6 @@ func TestGetAttesterSlashings(t *testing.T) { Signature: bytesutil.PadTo([]byte("signature2"), 96), }, } - slashing2PostElectra := ðpbv1alpha1.AttesterSlashingElectra{ - Attestation_1: ðpbv1alpha1.IndexedAttestationElectra{ - AttestingIndices: []uint64{3, 30}, - Data: ðpbv1alpha1.AttestationData{ - Slot: 3, - CommitteeIndex: 3, - BeaconBlockRoot: bytesutil.PadTo([]byte("blockroot3"), 32), - Source: ðpbv1alpha1.Checkpoint{ - Epoch: 3, - Root: bytesutil.PadTo([]byte("sourceroot3"), 32), - }, - Target: ðpbv1alpha1.Checkpoint{ - Epoch: 30, - Root: bytesutil.PadTo([]byte("targetroot3"), 32), - }, - }, - Signature: bytesutil.PadTo([]byte("signature3"), 96), - }, - Attestation_2: ðpbv1alpha1.IndexedAttestationElectra{ - AttestingIndices: []uint64{4, 40}, - Data: ðpbv1alpha1.AttestationData{ - Slot: 4, - CommitteeIndex: 4, - BeaconBlockRoot: bytesutil.PadTo([]byte("blockroot4"), 32), - Source: ðpbv1alpha1.Checkpoint{ - Epoch: 4, - Root: bytesutil.PadTo([]byte("sourceroot4"), 32), - }, - Target: ðpbv1alpha1.Checkpoint{ - Epoch: 40, - Root: bytesutil.PadTo([]byte("targetroot4"), 32), - }, - }, - Signature: bytesutil.PadTo([]byte("signature4"), 96), - }, - } t.Run("V1", func(t *testing.T) { t.Run("ok", func(t *testing.T) { @@ -1702,7 +1666,7 @@ func TestGetAttesterSlashings(t *testing.T) { s := &Server{ ChainInfoFetcher: chainService, TimeFetcher: chainService, - SlashingsPool: &slashingsmock.PoolMock{PendingAttSlashings: []ethpbv1alpha1.AttSlashing{slashing1PostElectra, slashing2PostElectra, slashing1PreElectra}}, + SlashingsPool: &slashingsmock.PoolMock{PendingAttSlashings: []ethpbv1alpha1.AttSlashing{slashingPostElectra, slashing1PreElectra}}, } request := httptest.NewRequest(http.MethodGet, "http://example.com/eth/v2/beacon/pool/attester_slashings", nil) @@ -1724,8 +1688,7 @@ func TestGetAttesterSlashings(t *testing.T) { ss, err := structs.AttesterSlashingsElectraToConsensus(slashings) require.NoError(t, err) - require.DeepEqual(t, slashing1PostElectra, ss[0]) - require.DeepEqual(t, slashing2PostElectra, ss[1]) + require.DeepEqual(t, slashingPostElectra, ss[0]) }) t.Run("post-electra-ok", func(t *testing.T) { bs, err := util.NewBeaconStateElectra() @@ -1741,7 +1704,7 @@ func TestGetAttesterSlashings(t *testing.T) { s := &Server{ ChainInfoFetcher: chainService, TimeFetcher: chainService, - SlashingsPool: &slashingsmock.PoolMock{PendingAttSlashings: []ethpbv1alpha1.AttSlashing{slashing1PostElectra, slashing2PostElectra}}, + SlashingsPool: &slashingsmock.PoolMock{PendingAttSlashings: []ethpbv1alpha1.AttSlashing{slashingPostElectra}}, } request := httptest.NewRequest(http.MethodGet, "http://example.com/eth/v2/beacon/pool/attester_slashings", nil) @@ -1763,8 +1726,7 @@ func TestGetAttesterSlashings(t *testing.T) { ss, err := structs.AttesterSlashingsElectraToConsensus(slashings) require.NoError(t, err) - require.DeepEqual(t, slashing1PostElectra, ss[0]) - require.DeepEqual(t, slashing2PostElectra, ss[1]) + require.DeepEqual(t, slashingPostElectra, ss[0]) }) t.Run("pre-electra-ok", func(t *testing.T) { bs, err := util.NewBeaconState() diff --git a/beacon-chain/rpc/eth/config/handlers_test.go b/beacon-chain/rpc/eth/config/handlers_test.go index 86f530752b..87fc0e63af 100644 --- a/beacon-chain/rpc/eth/config/handlers_test.go +++ b/beacon-chain/rpc/eth/config/handlers_test.go @@ -140,7 +140,7 @@ func TestGetSpec(t *testing.T) { config.WhistleBlowerRewardQuotientElectra = 79 config.PendingPartialWithdrawalsLimit = 80 config.MinActivationBalance = 81 - config.PendingDepositLimit = 82 + config.PendingDepositsLimit = 82 config.MaxPendingPartialsPerWithdrawalsSweep = 83 config.PendingConsolidationsLimit = 84 config.MaxPartialWithdrawalsPerPayload = 85 diff --git a/beacon-chain/state/state-native/getters_withdrawal.go b/beacon-chain/state/state-native/getters_withdrawal.go index 95e15deb47..2c53c1c399 100644 --- a/beacon-chain/state/state-native/getters_withdrawal.go +++ b/beacon-chain/state/state-native/getters_withdrawal.go @@ -95,7 +95,7 @@ func (b *BeaconState) NextWithdrawalValidatorIndex() (primitives.ValidatorIndex, // index=withdrawal_index, // validator_index=validator_index, // address=ExecutionAddress(validator.withdrawal_credentials[12:]), -// amount=balance - get_validator_max_effective_balance(validator), # [Modified in Electra:EIP7251] +// amount=balance - get_max_effective_balance(validator), # [Modified in Electra:EIP7251] // )) // withdrawal_index += WithdrawalIndex(1) // if len(withdrawals) == MAX_WITHDRAWALS_PER_PAYLOAD: diff --git a/changelog/radek_electra-nits.md b/changelog/radek_electra-nits.md new file mode 100644 index 0000000000..794366a0e9 --- /dev/null +++ b/changelog/radek_electra-nits.md @@ -0,0 +1,7 @@ +### Fixed + +- Fixed incorrect attester slashing length check. + +### Ignored + +- Addressed many small suggestions from @jtraglia. \ No newline at end of file diff --git a/config/params/config.go b/config/params/config.go index d9d39eb7c2..bfb24a1459 100644 --- a/config/params/config.go +++ b/config/params/config.go @@ -241,15 +241,13 @@ type BeaconChainConfig struct { MaxRequestBlobSidecarsElectra uint64 `yaml:"MAX_REQUEST_BLOB_SIDECARS_ELECTRA" spec:"true"` // MaxRequestBlobSidecarsElectra is the maximum number of blobs to request in a single request. MaxRequestBlocksDeneb uint64 `yaml:"MAX_REQUEST_BLOCKS_DENEB" spec:"true"` // MaxRequestBlocksDeneb is the maximum number of blocks in a single request after the deneb epoch. - // Values introduce in Electra upgrade - DataColumnSidecarSubnetCount uint64 `yaml:"DATA_COLUMN_SIDECAR_SUBNET_COUNT" spec:"true"` // DataColumnSidecarSubnetCount is the number of data column sidecar subnets used in the gossipsub protocol + // Values introduced in Electra upgrade MaxPerEpochActivationExitChurnLimit uint64 `yaml:"MAX_PER_EPOCH_ACTIVATION_EXIT_CHURN_LIMIT" spec:"true"` // MaxPerEpochActivationExitChurnLimit represents the maximum combined activation and exit churn. MinPerEpochChurnLimitElectra uint64 `yaml:"MIN_PER_EPOCH_CHURN_LIMIT_ELECTRA" spec:"true"` // MinPerEpochChurnLimitElectra is the minimum amount of churn allotted for validator rotations for electra. - MaxRequestDataColumnSidecars uint64 `yaml:"MAX_REQUEST_DATA_COLUMN_SIDECARS" spec:"true"` // MaxRequestDataColumnSidecars is the maximum number of data column sidecars in a single request MaxEffectiveBalanceElectra uint64 `yaml:"MAX_EFFECTIVE_BALANCE_ELECTRA" spec:"true"` // MaxEffectiveBalanceElectra is the maximal amount of Gwei that is effective for staking, increased in electra. MinSlashingPenaltyQuotientElectra uint64 `yaml:"MIN_SLASHING_PENALTY_QUOTIENT_ELECTRA" spec:"true"` // MinSlashingPenaltyQuotientElectra is used to calculate the minimum penalty to prevent DoS attacks, modified for electra. WhistleBlowerRewardQuotientElectra uint64 `yaml:"WHISTLEBLOWER_REWARD_QUOTIENT_ELECTRA" spec:"true"` // WhistleBlowerRewardQuotientElectra is used to calculate whistle blower reward, modified in electra. - PendingDepositLimit uint64 `yaml:"PENDING_DEPOSITS_LIMIT" spec:"true"` // PendingDepositLimit is the maximum number of pending balance deposits allowed in the beacon state. + PendingDepositsLimit uint64 `yaml:"PENDING_DEPOSITS_LIMIT" spec:"true"` // PendingDepositsLimit is the maximum number of pending balance deposits allowed in the beacon state. PendingPartialWithdrawalsLimit uint64 `yaml:"PENDING_PARTIAL_WITHDRAWALS_LIMIT" spec:"true"` // PendingPartialWithdrawalsLimit is the maximum number of pending partial withdrawals allowed in the beacon state. PendingConsolidationsLimit uint64 `yaml:"PENDING_CONSOLIDATIONS_LIMIT" spec:"true"` // PendingConsolidationsLimit is the maximum number of pending validator consolidations allowed in the beacon state. MaxConsolidationsRequestsPerPayload uint64 `yaml:"MAX_CONSOLIDATION_REQUESTS_PER_PAYLOAD" spec:"true"` // MaxConsolidationsRequestsPerPayload is the maximum number of consolidations in a block. @@ -264,8 +262,10 @@ type BeaconChainConfig struct { SamplesPerSlot uint64 `yaml:"SAMPLES_PER_SLOT"` // SamplesPerSlot refers to the number of random samples a node queries per slot. CustodyRequirement uint64 `yaml:"CUSTODY_REQUIREMENT"` // CustodyRequirement refers to the minimum amount of subnets a peer must custody and serve samples from. MinEpochsForDataColumnSidecarsRequest primitives.Epoch `yaml:"MIN_EPOCHS_FOR_DATA_COLUMN_SIDECARS_REQUESTS"` // MinEpochsForDataColumnSidecarsRequest is the minimum number of epochs the node will keep the data columns for. + MaxRequestDataColumnSidecars uint64 `yaml:"MAX_REQUEST_DATA_COLUMN_SIDECARS" spec:"true"` // MaxRequestDataColumnSidecars is the maximum number of data column sidecars in a single request MaxCellsInExtendedMatrix uint64 `yaml:"MAX_CELLS_IN_EXTENDED_MATRIX" spec:"true"` // MaxCellsInExtendedMatrix is the full data of one-dimensional erasure coding extended blobs (in row major format). NumberOfColumns uint64 `yaml:"NUMBER_OF_COLUMNS" spec:"true"` // NumberOfColumns in the extended data matrix. + DataColumnSidecarSubnetCount uint64 `yaml:"DATA_COLUMN_SIDECAR_SUBNET_COUNT" spec:"true"` // DataColumnSidecarSubnetCount is the number of data column sidecar subnets used in the gossipsub protocol // Networking Specific Parameters GossipMaxSize uint64 `yaml:"GOSSIP_MAX_SIZE" spec:"true"` // GossipMaxSize is the maximum allowed size of uncompressed gossip messages. diff --git a/config/params/mainnet_config.go b/config/params/mainnet_config.go index c5072878a2..5fb3d1cb1d 100644 --- a/config/params/mainnet_config.go +++ b/config/params/mainnet_config.go @@ -288,7 +288,7 @@ var mainnetBeaconConfig = &BeaconChainConfig{ MaxEffectiveBalanceElectra: 2048_000_000_000, MinSlashingPenaltyQuotientElectra: 4096, WhistleBlowerRewardQuotientElectra: 4096, - PendingDepositLimit: 134_217_728, + PendingDepositsLimit: 134_217_728, PendingPartialWithdrawalsLimit: 134_217_728, PendingConsolidationsLimit: 262_144, MinActivationBalance: 32_000_000_000, diff --git a/config/params/minimal_config.go b/config/params/minimal_config.go index b097210613..b50d1a553d 100644 --- a/config/params/minimal_config.go +++ b/config/params/minimal_config.go @@ -112,7 +112,7 @@ func MinimalSpecConfig() *BeaconChainConfig { minimalConfig.MaxDepositRequestsPerPayload = 4 minimalConfig.PendingPartialWithdrawalsLimit = 64 minimalConfig.MaxPendingPartialsPerWithdrawalsSweep = 2 - minimalConfig.PendingDepositLimit = 134217728 + minimalConfig.PendingDepositsLimit = 134217728 minimalConfig.MaxPendingDepositsPerEpoch = 16 // Ethereum PoW parameters. diff --git a/consensus-types/blocks/factory.go b/consensus-types/blocks/factory.go index 0d8f61f9e3..0b4cf98df1 100644 --- a/consensus-types/blocks/factory.go +++ b/consensus-types/blocks/factory.go @@ -349,7 +349,7 @@ func BuildSignedBeaconBlockFromExecutionPayload(blk interfaces.ReadOnlySignedBea case version.Bellatrix: p, ok := payload.(*enginev1.ExecutionPayload) if !ok { - return nil, errors.New("payload not of Bellatrix type") + return nil, fmt.Errorf("payload has wrong type (expected %T, got %T)", &enginev1.ExecutionPayload{}, payload) } var atts []*eth.Attestation if b.Body().Attestations() != nil { @@ -397,7 +397,7 @@ func BuildSignedBeaconBlockFromExecutionPayload(blk interfaces.ReadOnlySignedBea case version.Capella: p, ok := payload.(*enginev1.ExecutionPayloadCapella) if !ok { - return nil, errors.New("payload not of Capella type") + return nil, fmt.Errorf("payload has wrong type (expected %T, got %T)", &enginev1.ExecutionPayloadCapella{}, payload) } blsToExecutionChanges, err := b.Body().BLSToExecutionChanges() if err != nil { @@ -450,7 +450,7 @@ func BuildSignedBeaconBlockFromExecutionPayload(blk interfaces.ReadOnlySignedBea case version.Deneb: p, ok := payload.(*enginev1.ExecutionPayloadDeneb) if !ok { - return nil, errors.New("payload not of Deneb type") + return nil, fmt.Errorf("payload has wrong type (expected %T, got %T)", &enginev1.ExecutionPayloadDeneb{}, payload) } blsToExecutionChanges, err := b.Body().BLSToExecutionChanges() if err != nil { @@ -508,7 +508,7 @@ func BuildSignedBeaconBlockFromExecutionPayload(blk interfaces.ReadOnlySignedBea case version.Electra: p, ok := payload.(*enginev1.ExecutionPayloadDeneb) if !ok { - return nil, errors.New("payload not of Electra type") + return nil, fmt.Errorf("payload has wrong type (expected %T, got %T)", &enginev1.ExecutionPayloadDeneb{}, payload) } blsToExecutionChanges, err := b.Body().BLSToExecutionChanges() if err != nil { @@ -524,7 +524,7 @@ func BuildSignedBeaconBlockFromExecutionPayload(blk interfaces.ReadOnlySignedBea for i, att := range b.Body().Attestations() { a, ok := att.(*eth.AttestationElectra) if !ok { - return nil, fmt.Errorf("attestation has wrong type (expected %T, got %T)", ð.Attestation{}, att) + return nil, fmt.Errorf("attestation has wrong type (expected %T, got %T)", ð.AttestationElectra{}, att) } atts[i] = a } @@ -535,7 +535,7 @@ func BuildSignedBeaconBlockFromExecutionPayload(blk interfaces.ReadOnlySignedBea for i, slashing := range b.Body().AttesterSlashings() { s, ok := slashing.(*eth.AttesterSlashingElectra) if !ok { - return nil, fmt.Errorf("attester slashing has wrong type (expected %T, got %T)", ð.AttesterSlashing{}, slashing) + return nil, fmt.Errorf("attester slashing has wrong type (expected %T, got %T)", ð.AttesterSlashingElectra{}, slashing) } attSlashings[i] = s } @@ -573,7 +573,7 @@ func BuildSignedBeaconBlockFromExecutionPayload(blk interfaces.ReadOnlySignedBea case version.Fulu: p, ok := payload.(*enginev1.ExecutionPayloadDeneb) if !ok { - return nil, errors.New("payload not of Fulu type") + return nil, fmt.Errorf("payload has wrong type (expected %T, got %T)", &enginev1.ExecutionPayloadDeneb{}, payload) } blsToExecutionChanges, err := b.Body().BLSToExecutionChanges() if err != nil { @@ -646,6 +646,10 @@ func BuildSignedBeaconBlockFromExecutionPayload(blk interfaces.ReadOnlySignedBea // This is particularly useful for using the values from API calls. func BeaconBlockContainerToSignedBeaconBlock(obj *eth.BeaconBlockContainer) (interfaces.ReadOnlySignedBeaconBlock, error) { switch obj.Block.(type) { + case *eth.BeaconBlockContainer_BlindedElectraBlock: + return NewSignedBeaconBlock(obj.GetBlindedElectraBlock()) + case *eth.BeaconBlockContainer_ElectraBlock: + return NewSignedBeaconBlock(obj.GetElectraBlock()) case *eth.BeaconBlockContainer_BlindedDenebBlock: return NewSignedBeaconBlock(obj.GetBlindedDenebBlock()) case *eth.BeaconBlockContainer_DenebBlock: diff --git a/container/slice/slice.go b/container/slice/slice.go index 7332bcfd63..a6a7406fa8 100644 --- a/container/slice/slice.go +++ b/container/slice/slice.go @@ -380,8 +380,8 @@ func Reverse[E any](s []E) []E { } // VerifyMaxLength takes a slice and a maximum length and validates the length. -func VerifyMaxLength[T any](v []T, max int) error { - l := len(v) +func VerifyMaxLength[T any](v []T, max uint64) error { + l := uint64(len(v)) if l > max { return fmt.Errorf("length of %d exceeds max of %d", l, max) } diff --git a/encoding/bytesutil/hex.go b/encoding/bytesutil/hex.go index 049c10e93d..3c9939e167 100644 --- a/encoding/bytesutil/hex.go +++ b/encoding/bytesutil/hex.go @@ -34,7 +34,7 @@ func DecodeHexWithLength(s string, length int) ([]byte, error) { // DecodeHexWithMaxLength takes a string and a length in bytes, // and validates whether the string is a hex and has the correct length. -func DecodeHexWithMaxLength(s string, maxLength int) ([]byte, error) { +func DecodeHexWithMaxLength(s string, maxLength uint64) ([]byte, error) { bytes, err := hexutil.Decode(s) if err != nil { return nil, errors.Wrap(err, fmt.Sprintf("%s is not a valid hex", s)) diff --git a/proto/engine/v1/electra.go b/proto/engine/v1/electra.go index 5c61941469..f46a356a31 100644 --- a/proto/engine/v1/electra.go +++ b/proto/engine/v1/electra.go @@ -63,7 +63,7 @@ func (ebe *ExecutionBundleElectra) GetDecodedExecutionRequests() (*ExecutionRequ func unmarshalDeposits(requestListInSSZBytes []byte) ([]*DepositRequest, error) { if len(requestListInSSZBytes) < drSize { - return nil, errors.New("invalid deposit requests length, requests should be at least the size of 1 request") + return nil, fmt.Errorf("invalid deposit requests length, requests should be at least the size of %d", drSize) } if uint64(len(requestListInSSZBytes)) > uint64(drSize)*params.BeaconConfig().MaxDepositRequestsPerPayload { return nil, fmt.Errorf("invalid deposit requests length, requests should not be more than the max per payload, got %d max %d", len(requestListInSSZBytes), drSize) @@ -73,7 +73,7 @@ func unmarshalDeposits(requestListInSSZBytes []byte) ([]*DepositRequest, error) func unmarshalWithdrawals(requestListInSSZBytes []byte) ([]*WithdrawalRequest, error) { if len(requestListInSSZBytes) < wrSize { - return nil, errors.New("invalid withdrawal request length, requests should be at least the size of 1 request") + return nil, fmt.Errorf("invalid withdrawal requests length, requests should be at least the size of %d", wrSize) } if uint64(len(requestListInSSZBytes)) > uint64(wrSize)*params.BeaconConfig().MaxWithdrawalRequestsPerPayload { return nil, fmt.Errorf("invalid withdrawal requests length, requests should not be more than the max per payload, got %d max %d", len(requestListInSSZBytes), wrSize) @@ -83,7 +83,7 @@ func unmarshalWithdrawals(requestListInSSZBytes []byte) ([]*WithdrawalRequest, e func unmarshalConsolidations(requestListInSSZBytes []byte) ([]*ConsolidationRequest, error) { if len(requestListInSSZBytes) < crSize { - return nil, errors.New("invalid consolidations request length, requests should be at least the size of 1 request") + return nil, fmt.Errorf("invalid consolidation requests length, requests should be at least the size of %d", crSize) } if uint64(len(requestListInSSZBytes)) > uint64(crSize)*params.BeaconConfig().MaxConsolidationsRequestsPerPayload { return nil, fmt.Errorf("invalid consolidation requests length, requests should not be more than the max per payload, got %d max %d", len(requestListInSSZBytes), crSize) diff --git a/proto/prysm/v1alpha1/attestation.pb.go b/proto/prysm/v1alpha1/attestation.pb.go index 6275ea69be..4f2968ef1f 100755 --- a/proto/prysm/v1alpha1/attestation.pb.go +++ b/proto/prysm/v1alpha1/attestation.pb.go @@ -400,8 +400,8 @@ type AggregateAttestationAndProofElectra struct { unknownFields protoimpl.UnknownFields AggregatorIndex github_com_prysmaticlabs_prysm_v5_consensus_types_primitives.ValidatorIndex `protobuf:"varint,1,opt,name=aggregator_index,json=aggregatorIndex,proto3" json:"aggregator_index,omitempty" cast-type:"github.com/prysmaticlabs/prysm/v5/consensus-types/primitives.ValidatorIndex"` - Aggregate *AttestationElectra `protobuf:"bytes,3,opt,name=aggregate,proto3" json:"aggregate,omitempty"` - SelectionProof []byte `protobuf:"bytes,2,opt,name=selection_proof,json=selectionProof,proto3" json:"selection_proof,omitempty" ssz-size:"96"` + Aggregate *AttestationElectra `protobuf:"bytes,2,opt,name=aggregate,proto3" json:"aggregate,omitempty"` + SelectionProof []byte `protobuf:"bytes,3,opt,name=selection_proof,json=selectionProof,proto3" json:"selection_proof,omitempty" ssz-size:"96"` } func (x *AggregateAttestationAndProofElectra) Reset() { @@ -821,12 +821,12 @@ var file_proto_prysm_v1alpha1_attestation_proto_rawDesc = []byte{ 0x72, 0x69, 0x6d, 0x69, 0x74, 0x69, 0x76, 0x65, 0x73, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x52, 0x0f, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x6f, 0x72, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x47, 0x0a, 0x09, 0x61, 0x67, 0x67, - 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x65, + 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x41, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x6c, 0x65, 0x63, 0x74, 0x72, 0x61, 0x52, 0x09, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x12, 0x2f, 0x0a, 0x0f, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, - 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x06, 0x8a, 0xb5, 0x18, + 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x06, 0x8a, 0xb5, 0x18, 0x02, 0x39, 0x36, 0x52, 0x0e, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x22, 0xbf, 0x02, 0x0a, 0x12, 0x41, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x6c, 0x65, 0x63, 0x74, 0x72, 0x61, 0x12, 0x65, 0x0a, 0x10, 0x61, 0x67, diff --git a/proto/prysm/v1alpha1/attestation.proto b/proto/prysm/v1alpha1/attestation.proto index 205249fec8..80b3ac791d 100644 --- a/proto/prysm/v1alpha1/attestation.proto +++ b/proto/prysm/v1alpha1/attestation.proto @@ -127,11 +127,10 @@ message AggregateAttestationAndProofElectra { "primitives.ValidatorIndex" ]; // The aggregated attestation that was submitted. - AttestationElectra aggregate = 3; + AttestationElectra aggregate = 2; - // 96 byte selection proof signed by the aggregator, which is the signature of - // the slot to aggregate. - bytes selection_proof = 2 [ (ethereum.eth.ext.ssz_size) = "96" ]; + // 96 byte selection proof signed by the aggregator, which is the signature of the slot to aggregate. + bytes selection_proof = 3 [ (ethereum.eth.ext.ssz_size) = "96" ]; } message AttestationElectra { diff --git a/proto/prysm/v1alpha1/beacon_state.proto b/proto/prysm/v1alpha1/beacon_state.proto index 148a80c9b9..b3d5ec38af 100644 --- a/proto/prysm/v1alpha1/beacon_state.proto +++ b/proto/prysm/v1alpha1/beacon_state.proto @@ -604,7 +604,7 @@ message BeaconStateElectra { repeated HistoricalSummary historical_summaries = 11003 [ (ethereum.eth.ext.ssz_max) = "16777216" ]; - // Fields introduced in EIP-7251 fork [12001-13000] + // Fields introduced in Electra fork [12001-13000] uint64 deposit_requests_start_index = 12001; uint64 deposit_balance_to_consume = 12002 [ (ethereum.eth.ext.cast_type) = diff --git a/proto/prysm/v1alpha1/validator.proto b/proto/prysm/v1alpha1/validator.proto index fb825d02f2..5c5bb045e7 100644 --- a/proto/prysm/v1alpha1/validator.proto +++ b/proto/prysm/v1alpha1/validator.proto @@ -466,7 +466,7 @@ message StreamBlocksResponse { // Representing a deneb block. SignedBeaconBlockDeneb deneb_block = 5; - // Representing a electra block. + // Representing an electra block. SignedBeaconBlockElectra electra_block = 6; // Representing a fulu block. diff --git a/proto/ssz_proto_library.bzl b/proto/ssz_proto_library.bzl index ba845c6cae..868c727a3f 100644 --- a/proto/ssz_proto_library.bzl +++ b/proto/ssz_proto_library.bzl @@ -26,7 +26,7 @@ mainnet = { "max_blobs_per_block.size": "6", "max_blob_commitments.size": "4096", "kzg_commitment_inclusion_proof_depth.size": "17", - "max_withdrawal_requests_per_payload.size":"16", + "max_withdrawal_requests_per_payload.size": "16", "max_deposit_requests_per_payload.size": "8192", "max_attesting_indices.size": "131072", "max_committees_per_slot.size": "64", @@ -63,7 +63,7 @@ minimal = { "max_blobs_per_block.size": "6", "max_blob_commitments.size": "32", "kzg_commitment_inclusion_proof_depth.size": "10", - "max_withdrawal_requests_per_payload.size":"2", + "max_withdrawal_requests_per_payload.size": "2", "max_deposit_requests_per_payload.size": "4", "max_attesting_indices.size": "8192", "max_committees_per_slot.size": "4", diff --git a/validator/client/beacon-api/test-helpers/electra_beacon_block_test_helpers.go b/validator/client/beacon-api/test-helpers/electra_beacon_block_test_helpers.go index 829d201318..3cd0640931 100644 --- a/validator/client/beacon-api/test-helpers/electra_beacon_block_test_helpers.go +++ b/validator/client/beacon-api/test-helpers/electra_beacon_block_test_helpers.go @@ -105,42 +105,6 @@ func GenerateProtoElectraBeaconBlockContents() *ethpb.BeaconBlockContentsElectra Signature: FillByteSlice(96, 53), }, }, - { - Attestation_1: ðpb.IndexedAttestationElectra{ - AttestingIndices: []uint64{54, 55}, - Data: ðpb.AttestationData{ - Slot: 56, - CommitteeIndex: 57, - BeaconBlockRoot: FillByteSlice(32, 38), - Source: ðpb.Checkpoint{ - Epoch: 59, - Root: FillByteSlice(32, 60), - }, - Target: ðpb.Checkpoint{ - Epoch: 61, - Root: FillByteSlice(32, 62), - }, - }, - Signature: FillByteSlice(96, 63), - }, - Attestation_2: ðpb.IndexedAttestationElectra{ - AttestingIndices: []uint64{64, 65}, - Data: ðpb.AttestationData{ - Slot: 66, - CommitteeIndex: 67, - BeaconBlockRoot: FillByteSlice(32, 38), - Source: ðpb.Checkpoint{ - Epoch: 69, - Root: FillByteSlice(32, 70), - }, - Target: ðpb.Checkpoint{ - Epoch: 71, - Root: FillByteSlice(32, 72), - }, - }, - Signature: FillByteSlice(96, 73), - }, - }, }, Attestations: []*ethpb.AttestationElectra{ { @@ -401,42 +365,6 @@ func GenerateProtoBlindedElectraBeaconBlock() *ethpb.BlindedBeaconBlockElectra { Signature: FillByteSlice(96, 53), }, }, - { - Attestation_1: ðpb.IndexedAttestationElectra{ - AttestingIndices: []uint64{54, 55}, - Data: ðpb.AttestationData{ - Slot: 56, - CommitteeIndex: 57, - BeaconBlockRoot: FillByteSlice(32, 38), - Source: ðpb.Checkpoint{ - Epoch: 59, - Root: FillByteSlice(32, 60), - }, - Target: ðpb.Checkpoint{ - Epoch: 61, - Root: FillByteSlice(32, 62), - }, - }, - Signature: FillByteSlice(96, 63), - }, - Attestation_2: ðpb.IndexedAttestationElectra{ - AttestingIndices: []uint64{64, 65}, - Data: ðpb.AttestationData{ - Slot: 66, - CommitteeIndex: 67, - BeaconBlockRoot: FillByteSlice(32, 38), - Source: ðpb.Checkpoint{ - Epoch: 69, - Root: FillByteSlice(32, 70), - }, - Target: ðpb.Checkpoint{ - Epoch: 71, - Root: FillByteSlice(32, 72), - }, - }, - Signature: FillByteSlice(96, 73), - }, - }, }, Attestations: []*ethpb.AttestationElectra{ { @@ -679,42 +607,6 @@ func GenerateJsonElectraBeaconBlockContents() *structs.BeaconBlockContentsElectr Signature: FillEncodedByteSlice(96, 53), }, }, - { - Attestation1: &structs.IndexedAttestationElectra{ - AttestingIndices: []string{"54", "55"}, - Data: &structs.AttestationData{ - Slot: "56", - CommitteeIndex: "57", - BeaconBlockRoot: FillEncodedByteSlice(32, 38), - Source: &structs.Checkpoint{ - Epoch: "59", - Root: FillEncodedByteSlice(32, 60), - }, - Target: &structs.Checkpoint{ - Epoch: "61", - Root: FillEncodedByteSlice(32, 62), - }, - }, - Signature: FillEncodedByteSlice(96, 63), - }, - Attestation2: &structs.IndexedAttestationElectra{ - AttestingIndices: []string{"64", "65"}, - Data: &structs.AttestationData{ - Slot: "66", - CommitteeIndex: "67", - BeaconBlockRoot: FillEncodedByteSlice(32, 38), - Source: &structs.Checkpoint{ - Epoch: "69", - Root: FillEncodedByteSlice(32, 70), - }, - Target: &structs.Checkpoint{ - Epoch: "71", - Root: FillEncodedByteSlice(32, 72), - }, - }, - Signature: FillEncodedByteSlice(96, 73), - }, - }, }, Attestations: []*structs.AttestationElectra{ { @@ -975,42 +867,6 @@ func GenerateJsonBlindedElectraBeaconBlock() *structs.BlindedBeaconBlockElectra Signature: FillEncodedByteSlice(96, 53), }, }, - { - Attestation1: &structs.IndexedAttestationElectra{ - AttestingIndices: []string{"54", "55"}, - Data: &structs.AttestationData{ - Slot: "56", - CommitteeIndex: "57", - BeaconBlockRoot: FillEncodedByteSlice(32, 38), - Source: &structs.Checkpoint{ - Epoch: "59", - Root: FillEncodedByteSlice(32, 60), - }, - Target: &structs.Checkpoint{ - Epoch: "61", - Root: FillEncodedByteSlice(32, 62), - }, - }, - Signature: FillEncodedByteSlice(96, 63), - }, - Attestation2: &structs.IndexedAttestationElectra{ - AttestingIndices: []string{"64", "65"}, - Data: &structs.AttestationData{ - Slot: "66", - CommitteeIndex: "67", - BeaconBlockRoot: FillEncodedByteSlice(32, 38), - Source: &structs.Checkpoint{ - Epoch: "69", - Root: FillEncodedByteSlice(32, 70), - }, - Target: &structs.Checkpoint{ - Epoch: "71", - Root: FillEncodedByteSlice(32, 72), - }, - }, - Signature: FillEncodedByteSlice(96, 73), - }, - }, }, Attestations: []*structs.AttestationElectra{ {