diff --git a/.ethspecify.yml b/.ethspecify.yml
index 728fb97b4e25..e42563b4c44f 100644
--- a/.ethspecify.yml
+++ b/.ethspecify.yml
@@ -1,4 +1,4 @@
-version: v1.7.0-alpha.2
+version: v1.7.0-alpha.4
style: full
specrefs:
@@ -23,6 +23,8 @@ exceptions:
- PTC_SIZE#gloas
constants:
+ # heze
+ - DOMAIN_INCLUSION_LIST_COMMITTEE#heze
# phase0
- BASIS_POINTS#phase0
- ENDIANNESS#phase0
@@ -72,10 +74,30 @@ exceptions:
- GLOAS_FORK_EPOCH#gloas
- GLOAS_FORK_VERSION#gloas
- SYNC_MESSAGE_DUE_BPS_GLOAS#gloas
+ # heze
+ - HEZE_FORK_EPOCH#heze
+ - HEZE_FORK_VERSION#heze
+ - INCLUSION_LIST_SUBMISSION_DUE_BPS#heze
+ - MAX_BYTES_PER_INCLUSION_LIST#heze
+ - MAX_REQUEST_INCLUSION_LIST#heze
+ - PROPOSER_INCLUSION_LIST_CUTOFF_BPS#heze
+ - VIEW_FREEZE_CUTOFF_BPS#heze
ssz_objects:
# phase0
- Eth1Block#phase0
+ # fulu
+ - PartialDataColumnHeader#fulu
+ - PartialDataColumnPartsMetadata#fulu
+ - PartialDataColumnSidecar#fulu
+ # gloas
+ - PartialDataColumnHeader#gloas
+ # heze
+ - BeaconState#heze
+ - ExecutionPayloadBid#heze
+ - InclusionList#heze
+ - SignedExecutionPayloadBid#heze
+ - SignedInclusionList#heze
# capella
- LightClientBootstrap#capella
- LightClientFinalityUpdate#capella
@@ -105,6 +127,7 @@ exceptions:
dataclasses:
# phase0
- LatestMessage#phase0
+ - Seen#phase0
- Store#phase0
# altair
- LightClientStore#altair
@@ -121,6 +144,11 @@ exceptions:
- ExpectedWithdrawals#gloas
- LatestMessage#gloas
- Store#gloas
+ # heze
+ - GetInclusionListResponse#heze
+ - InclusionListStore#heze
+ - PayloadAttributes#heze
+ - Store#heze
functions:
# Functions implemented by KZG library for EIP-4844
@@ -177,11 +205,22 @@ exceptions:
- verify_cell_kzg_proof_batch_impl#fulu
# phase0
+ - compute_attestation_subnet_prefix_bits#phase0
+ - compute_min_epochs_for_block_requests#phase0
+ - compute_time_at_slot_ms#phase0
+ - is_not_from_future_slot#phase0
+ - is_within_slot_range#phase0
- update_proposer_boost_root#phase0
- is_proposer_equivocation#phase0
- record_block_timeliness#phase0
- compute_proposer_score#phase0
- get_attestation_score#phase0
+ - validate_attester_slashing_gossip#phase0
+ - validate_beacon_aggregate_and_proof_gossip#phase0
+ - validate_beacon_attestation_gossip#phase0
+ - validate_beacon_block_gossip#phase0
+ - validate_proposer_slashing_gossip#phase0
+ - validate_voluntary_exit_gossip#phase0
- calculate_committee_fraction#phase0
- compute_fork_version#phase0
- compute_pulled_up_tip#phase0
@@ -272,6 +311,7 @@ exceptions:
- upgrade_lc_store_to_capella#capella
- upgrade_lc_update_to_capella#capella
# deneb
+ - compute_max_request_blob_sidecars#deneb
- get_lc_execution_root#deneb
- is_valid_light_client_header#deneb
- prepare_execution_payload#deneb
@@ -282,6 +322,7 @@ exceptions:
- upgrade_lc_store_to_deneb#deneb
- upgrade_lc_update_to_deneb#deneb
# electra
+ - compute_max_request_blob_sidecars#electra
- compute_weak_subjectivity_period#electra
- current_sync_committee_gindex_at_slot#electra
- finalized_root_gindex_at_slot#electra
@@ -303,12 +344,20 @@ exceptions:
- upgrade_lc_store_to_electra#electra
- upgrade_lc_update_to_electra#electra
# fulu
+ - compute_max_request_data_column_sidecars#fulu
- compute_matrix#fulu
+ - verify_partial_data_column_header_inclusion_proof#fulu
+ - verify_partial_data_column_sidecar_kzg_proofs#fulu
- get_blob_parameters#fulu
- get_data_column_sidecars_from_block#fulu
- get_data_column_sidecars_from_column_sidecar#fulu
- recover_matrix#fulu
# gloas
+ - compute_ptc#gloas
+ - initialize_ptc_window#gloas
+ - is_payload_data_available#gloas
+ - is_pending_validator#gloas
+ - process_ptc_window#gloas
- compute_balance_weighted_acceptance#gloas
- compute_balance_weighted_selection#gloas
- compute_fork_version#gloas
@@ -406,6 +455,28 @@ exceptions:
- update_next_withdrawal_builder_index#gloas
- update_payload_expected_withdrawals#gloas
- update_proposer_boost_root#gloas
+ # heze
+ - compute_fork_version#heze
+ - get_forkchoice_store#heze
+ - get_inclusion_list_bits#heze
+ - get_inclusion_list_committee_assignment#heze
+ - get_inclusion_list_committee#heze
+ - get_inclusion_list_signature#heze
+ - get_inclusion_list_store#heze
+ - get_inclusion_list_submission_due_ms#heze
+ - get_inclusion_list_transactions#heze
+ - get_proposer_inclusion_list_cutoff_ms#heze
+ - get_view_freeze_cutoff_ms#heze
+ - is_inclusion_list_bits_inclusive#heze
+ - is_payload_inclusion_list_satisfied#heze
+ - is_valid_inclusion_list_signature#heze
+ - on_execution_payload#heze
+ - on_inclusion_list#heze
+ - prepare_execution_payload#heze
+ - process_inclusion_list#heze
+ - record_payload_inclusion_list_satisfaction#heze
+ - should_extend_payload#heze
+ - upgrade_to_heze#heze
presets:
# gloas
@@ -414,3 +485,5 @@ exceptions:
- MAX_BUILDERS_PER_WITHDRAWALS_SWEEP#gloas
- MAX_PAYLOAD_ATTESTATIONS#gloas
- PTC_SIZE#gloas
+ # heze
+ - INCLUSION_LIST_COMMITTEE_SIZE#heze
diff --git a/WORKSPACE b/WORKSPACE
index e79919e0003c..75fa7a15ff5d 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -273,16 +273,16 @@ filegroup(
url = "https://github.com/ethereum/EIPs/archive/5480440fe51742ed23342b68cf106cefd427e39d.tar.gz",
)
-consensus_spec_version = "v1.7.0-alpha.2"
+consensus_spec_version = "v1.7.0-alpha.4"
load("@prysm//tools:download_spectests.bzl", "consensus_spec_tests")
consensus_spec_tests(
name = "consensus_spec_tests",
flavors = {
- "general": "sha256-iGQsGZ1cHah+2CSod9jC3kN8Ku4n6KO0hIwfINrn/po=",
- "minimal": "sha256-TgcYt8N8sXSttdHTGvOa+exUZ1zn1UzlAMz0V7i37xc=",
- "mainnet": "sha256-LnXyiLoJtrvEvbqLDSAAqpLMdN/lXv92SAgYG8fNjCs=",
+ "general": "sha256-kNJxuhCtW4RbuS9nb4U6JXHlPgTSg6G3hWeHFVB9gZ4=",
+ "minimal": "sha256-U1tCkXxtdI6mkEdk80i8z9LU2hAyf7Ztz5SBYo5oMzo=",
+ "mainnet": "sha256-Ga8VDOcNhTTdXDj8tSyBVYrwya9f1HO94ehJ5vv91r4=",
},
version = consensus_spec_version,
)
@@ -298,7 +298,7 @@ filegroup(
visibility = ["//visibility:public"],
)
""",
- integrity = "sha256-Y/67Dg393PksZj5rTFNLntiJ6hNdB7Rxbu5gZE2gebY=",
+ integrity = "sha256-XHu5K/65mue+5po63L9yGTFjGfU1RGj4S56dmcHc2Rs=",
strip_prefix = "consensus-specs-" + consensus_spec_version[1:],
url = "https://github.com/ethereum/consensus-specs/archive/refs/tags/%s.tar.gz" % consensus_spec_version,
)
diff --git a/beacon-chain/blockchain/BUILD.bazel b/beacon-chain/blockchain/BUILD.bazel
index f6d529317c6a..09e41c1ad71c 100644
--- a/beacon-chain/blockchain/BUILD.bazel
+++ b/beacon-chain/blockchain/BUILD.bazel
@@ -154,7 +154,6 @@ go_test(
"//beacon-chain/core/altair:go_default_library",
"//beacon-chain/core/blocks:go_default_library",
"//beacon-chain/core/feed/state:go_default_library",
- "//beacon-chain/core/gloas:go_default_library",
"//beacon-chain/core/helpers:go_default_library",
"//beacon-chain/core/peerdas:go_default_library",
"//beacon-chain/core/signing:go_default_library",
diff --git a/beacon-chain/blockchain/chain_info_test.go b/beacon-chain/blockchain/chain_info_test.go
index 574372145ad1..c993dceddd12 100644
--- a/beacon-chain/blockchain/chain_info_test.go
+++ b/beacon-chain/blockchain/chain_info_test.go
@@ -17,10 +17,10 @@ import (
"github.com/OffchainLabs/prysm/v7/genesis"
enginev1 "github.com/OffchainLabs/prysm/v7/proto/engine/v1"
ethpb "github.com/OffchainLabs/prysm/v7/proto/prysm/v1alpha1"
- "github.com/OffchainLabs/prysm/v7/time/slots"
"github.com/OffchainLabs/prysm/v7/testing/assert"
"github.com/OffchainLabs/prysm/v7/testing/require"
"github.com/OffchainLabs/prysm/v7/testing/util"
+ "github.com/OffchainLabs/prysm/v7/time/slots"
"google.golang.org/protobuf/proto"
)
diff --git a/beacon-chain/blockchain/process_block.go b/beacon-chain/blockchain/process_block.go
index 7e502ad0c307..033f21909e50 100644
--- a/beacon-chain/blockchain/process_block.go
+++ b/beacon-chain/blockchain/process_block.go
@@ -686,7 +686,7 @@ func (s *Service) handleBlockPayloadAttestations(ctx context.Context, blk interf
if len(atts) == 0 {
return nil
}
- committee, err := gloas.PayloadCommittee(ctx, st, blk.Slot()-1)
+ committee, err := st.PayloadCommitteeReadOnly(blk.Slot() - 1)
if err != nil {
return err
}
diff --git a/beacon-chain/blockchain/process_block_test.go b/beacon-chain/blockchain/process_block_test.go
index 809025bc96e2..af4d802e91c1 100644
--- a/beacon-chain/blockchain/process_block_test.go
+++ b/beacon-chain/blockchain/process_block_test.go
@@ -14,7 +14,6 @@ import (
"github.com/OffchainLabs/prysm/v7/beacon-chain/cache"
"github.com/OffchainLabs/prysm/v7/beacon-chain/core/blocks"
statefeed "github.com/OffchainLabs/prysm/v7/beacon-chain/core/feed/state"
- "github.com/OffchainLabs/prysm/v7/beacon-chain/core/gloas"
"github.com/OffchainLabs/prysm/v7/beacon-chain/core/helpers"
"github.com/OffchainLabs/prysm/v7/beacon-chain/core/peerdas"
"github.com/OffchainLabs/prysm/v7/beacon-chain/core/signing"
@@ -3556,7 +3555,7 @@ func TestHandleBlockPayloadAttestations(t *testing.T) {
base, insertBlk := testGloasState(t, 1, parentRoot, blockHash)
insertGloasBlock(t, s, base, insertBlk, blockRoot)
- ptc, err := gloas.PayloadCommittee(ctx, headState, 1)
+ ptc, err := headState.PayloadCommitteeReadOnly(1)
require.NoError(t, err)
require.NotEqual(t, 0, len(ptc))
diff --git a/beacon-chain/blockchain/receive_payload_attestation_message_test.go b/beacon-chain/blockchain/receive_payload_attestation_message_test.go
index 2559ec187984..b5f251fb5a83 100644
--- a/beacon-chain/blockchain/receive_payload_attestation_message_test.go
+++ b/beacon-chain/blockchain/receive_payload_attestation_message_test.go
@@ -3,7 +3,6 @@ package blockchain
import (
"testing"
- "github.com/OffchainLabs/prysm/v7/beacon-chain/core/gloas"
mockExecution "github.com/OffchainLabs/prysm/v7/beacon-chain/execution/testing"
"github.com/OffchainLabs/prysm/v7/beacon-chain/state"
"github.com/OffchainLabs/prysm/v7/config/params"
@@ -51,7 +50,7 @@ func TestReceivePayloadAttestationMessage_ValidatorNotInPTC(t *testing.T) {
require.NoError(t, err)
s.head = &head{root: blockRoot, block: wsb, state: headState, slot: 1}
- ptc, err := gloas.PayloadCommittee(ctx, headState, 1)
+ ptc, err := headState.PayloadCommitteeReadOnly(1)
require.NoError(t, err)
// Pick a validator index not in the PTC.
@@ -100,7 +99,7 @@ func TestReceivePayloadAttestationMessage_OK(t *testing.T) {
require.NoError(t, err)
s.head = &head{root: blockRoot, block: wsb, state: headState, slot: 1}
- ptc, err := gloas.PayloadCommittee(ctx, headState, 1)
+ ptc, err := headState.PayloadCommitteeReadOnly(1)
require.NoError(t, err)
require.NotEqual(t, 0, len(ptc))
diff --git a/beacon-chain/core/gloas/BUILD.bazel b/beacon-chain/core/gloas/BUILD.bazel
index d35f090adb62..f5ce1efcad50 100644
--- a/beacon-chain/core/gloas/BUILD.bazel
+++ b/beacon-chain/core/gloas/BUILD.bazel
@@ -35,6 +35,7 @@ go_library(
"//crypto/bls/common:go_default_library",
"//crypto/hash:go_default_library",
"//encoding/bytesutil:go_default_library",
+ "//monitoring/tracing/trace:go_default_library",
"//proto/engine/v1:go_default_library",
"//proto/prysm/v1alpha1:go_default_library",
"//runtime/version:go_default_library",
diff --git a/beacon-chain/core/gloas/deposit_request.go b/beacon-chain/core/gloas/deposit_request.go
index 26420a4f5975..affc25eef6f0 100644
--- a/beacon-chain/core/gloas/deposit_request.go
+++ b/beacon-chain/core/gloas/deposit_request.go
@@ -29,7 +29,7 @@ func processDepositRequests(ctx context.Context, beaconState state.BeaconState,
// processDepositRequest processes the specific deposit request
//
-//
+//
// def process_deposit_request(state: BeaconState, deposit_request: DepositRequest) -> None:
// # [New in Gloas:EIP7732]
// builder_pubkeys = [b.pubkey for b in state.builders]
@@ -40,8 +40,11 @@ func processDepositRequests(ctx context.Context, beaconState state.BeaconState,
// # already exists with this pubkey, apply the deposit to their balance
// is_builder = deposit_request.pubkey in builder_pubkeys
// is_validator = deposit_request.pubkey in validator_pubkeys
-// is_builder_prefix = is_builder_withdrawal_credential(deposit_request.withdrawal_credentials)
-// if is_builder or (is_builder_prefix and not is_validator):
+// if is_builder or (
+// is_builder_withdrawal_credential(deposit_request.withdrawal_credentials)
+// and not is_validator
+// and not is_pending_validator(state, deposit_request.pubkey)
+// ):
// # Apply builder deposits immediately
// apply_deposit_for_builder(
// state,
diff --git a/beacon-chain/core/gloas/payload_attestation.go b/beacon-chain/core/gloas/payload_attestation.go
index 27c84b4556f3..aea9a41309b8 100644
--- a/beacon-chain/core/gloas/payload_attestation.go
+++ b/beacon-chain/core/gloas/payload_attestation.go
@@ -19,6 +19,7 @@ import (
"github.com/OffchainLabs/prysm/v7/crypto/bls"
"github.com/OffchainLabs/prysm/v7/crypto/hash"
"github.com/OffchainLabs/prysm/v7/encoding/bytesutil"
+ "github.com/OffchainLabs/prysm/v7/monitoring/tracing/trace"
eth "github.com/OffchainLabs/prysm/v7/proto/prysm/v1alpha1"
"github.com/OffchainLabs/prysm/v7/time/slots"
"github.com/pkg/errors"
@@ -80,7 +81,7 @@ func ProcessPayloadAttestations(ctx context.Context, st state.BeaconState, body
// indexedPayloadAttestation converts a payload attestation into its indexed form.
func indexedPayloadAttestation(ctx context.Context, st state.ReadOnlyBeaconState, att *eth.PayloadAttestation) (*consensus_types.IndexedPayloadAttestation, error) {
- committee, err := PayloadCommittee(ctx, st, att.Data.Slot)
+ committee, err := st.PayloadCommitteeReadOnly(att.Data.Slot)
if err != nil {
return nil, err
}
@@ -99,10 +100,10 @@ func indexedPayloadAttestation(ctx context.Context, st state.ReadOnlyBeaconState
}, nil
}
-// PayloadCommittee returns the payload timeliness committee for a given slot for the state.
+// computePTC computes the payload timeliness committee for a given slot.
//
-//
-// def get_ptc(state: BeaconState, slot: Slot) -> Vector[ValidatorIndex, PTC_SIZE]:
+//
+// def compute_ptc(state: BeaconState, slot: Slot) -> Vector[ValidatorIndex, PTC_SIZE]:
// """
// Get the payload timeliness committee for the given ``slot``.
// """
@@ -118,7 +119,7 @@ func indexedPayloadAttestation(ctx context.Context, st state.ReadOnlyBeaconState
// state, indices, seed, size=PTC_SIZE, shuffle_indices=False
// )
//
-func PayloadCommittee(ctx context.Context, st state.ReadOnlyBeaconState, slot primitives.Slot) ([]primitives.ValidatorIndex, error) {
+func computePTC(ctx context.Context, st state.ReadOnlyBeaconState, slot primitives.Slot) ([]primitives.ValidatorIndex, error) {
epoch := slots.ToEpoch(slot)
seed, err := ptcSeed(st, epoch, slot)
if err != nil {
@@ -166,7 +167,7 @@ func PayloadCommitteeIndex(
slot primitives.Slot,
validatorIndex primitives.ValidatorIndex,
) (uint64, error) {
- ptc, err := PayloadCommittee(ctx, st, slot)
+ ptc, err := st.PayloadCommitteeReadOnly(slot)
if err != nil {
return 0, err
}
@@ -342,3 +343,43 @@ func validIndexedPayloadAttestation(st state.ReadOnlyBeaconState, att *consensus
}
return nil
}
+
+// ProcessPTCWindow rotates the cached PTC window at epoch boundaries by computing
+// PTC assignments for the new lookahead epoch and shifting the window.
+//
+//
+// def process_ptc_window(state: BeaconState) -> None:
+// """
+// Update the cached PTC window.
+// """
+// # Shift all epochs forward by one
+// state.ptc_window[: len(state.ptc_window) - SLOTS_PER_EPOCH] = state.ptc_window[SLOTS_PER_EPOCH:]
+// # Fill in the last epoch
+// next_epoch = Epoch(get_current_epoch(state) + MIN_SEED_LOOKAHEAD + 1)
+// start_slot = compute_start_slot_at_epoch(next_epoch)
+// state.ptc_window[len(state.ptc_window) - SLOTS_PER_EPOCH :] = [
+// compute_ptc(state, Slot(slot)) for slot in range(start_slot, start_slot + SLOTS_PER_EPOCH)
+// ]
+//
+func ProcessPTCWindow(ctx context.Context, st state.BeaconState) error {
+ _, span := trace.StartSpan(ctx, "gloas.ProcessPTCWindow")
+ defer span.End()
+
+ slotsPerEpoch := params.BeaconConfig().SlotsPerEpoch
+ lastEpoch := slots.ToEpoch(st.Slot()) + params.BeaconConfig().MinSeedLookahead + 1
+ startSlot, err := slots.EpochStart(lastEpoch)
+ if err != nil {
+ return err
+ }
+
+ newSlots := make([]*eth.PTCs, slotsPerEpoch)
+ for i := range slotsPerEpoch {
+ ptc, err := computePTC(ctx, st, startSlot+primitives.Slot(i))
+ if err != nil {
+ return err
+ }
+ newSlots[i] = ð.PTCs{ValidatorIndices: ptc}
+ }
+
+ return st.RotatePTCWindow(newSlots)
+}
diff --git a/beacon-chain/core/gloas/payload_attestation_test.go b/beacon-chain/core/gloas/payload_attestation_test.go
index 5c609ffd566c..e42a09804d5b 100644
--- a/beacon-chain/core/gloas/payload_attestation_test.go
+++ b/beacon-chain/core/gloas/payload_attestation_test.go
@@ -2,13 +2,14 @@ package gloas_test
import (
"bytes"
+ "slices"
"testing"
"github.com/OffchainLabs/go-bitfield"
"github.com/OffchainLabs/prysm/v7/beacon-chain/core/gloas"
- "github.com/OffchainLabs/prysm/v7/beacon-chain/core/helpers"
"github.com/OffchainLabs/prysm/v7/beacon-chain/core/signing"
"github.com/OffchainLabs/prysm/v7/beacon-chain/state"
+ fieldparams "github.com/OffchainLabs/prysm/v7/config/fieldparams"
"github.com/OffchainLabs/prysm/v7/config/params"
"github.com/OffchainLabs/prysm/v7/consensus-types/blocks"
"github.com/OffchainLabs/prysm/v7/consensus-types/interfaces"
@@ -119,7 +120,6 @@ func TestProcessPayloadAttestations_EmptyAggregationBits(t *testing.T) {
}
func TestProcessPayloadAttestations_HappyPath(t *testing.T) {
- helpers.ClearCache()
setupTestConfig(t)
sk1, pk1 := newKey(t)
@@ -150,7 +150,6 @@ func TestProcessPayloadAttestations_HappyPath(t *testing.T) {
}
func TestProcessPayloadAttestations_MultipleAttestations(t *testing.T) {
- helpers.ClearCache()
setupTestConfig(t)
sk1, pk1 := newKey(t)
@@ -211,12 +210,30 @@ func TestProcessPayloadAttestations_IndexedVerificationError(t *testing.T) {
errIndex: 0,
}
err := gloas.ProcessPayloadAttestations(t.Context(), errState, body)
- require.ErrorContains(t, "failed to convert to indexed form", err)
- require.ErrorContains(t, "failed to sample beacon committee 0", err)
+ require.ErrorContains(t, "failed to verify indexed form", err)
require.ErrorContains(t, "validator 0", err)
}
func newTestState(t *testing.T, vals []*eth.Validator, slot primitives.Slot) state.BeaconState {
+ t.Helper()
+
+ st, err := testutil.NewBeaconStateGloas(func(seed *eth.BeaconStateGloas) error {
+ seed.Slot = slot
+ seed.Validators = vals
+ seed.Balances = make([]uint64, len(vals))
+ for i, v := range vals {
+ seed.Balances[i] = v.EffectiveBalance
+ }
+ seed.PtcWindow = deterministicPTCWindow(len(vals))
+ return nil
+ })
+ require.NoError(t, err)
+ return st
+}
+
+func newPhase0TestState(t *testing.T, vals []*eth.Validator, slot primitives.Slot) state.BeaconState {
+ t.Helper()
+
st, err := testutil.NewBeaconState()
require.NoError(t, err)
for _, v := range vals {
@@ -224,10 +241,25 @@ func newTestState(t *testing.T, vals []*eth.Validator, slot primitives.Slot) sta
require.NoError(t, st.AppendBalance(v.EffectiveBalance))
}
require.NoError(t, st.SetSlot(slot))
- require.NoError(t, helpers.UpdateCommitteeCache(t.Context(), st, slots.ToEpoch(slot)))
return st
}
+func deterministicPTCWindow(validatorCount int) []*eth.PTCs {
+ window := make([]*eth.PTCs, 3*params.BeaconConfig().SlotsPerEpoch)
+ indices := make([]primitives.ValidatorIndex, fieldparams.PTCSize)
+ if validatorCount > 0 {
+ for i := range indices {
+ indices[i] = primitives.ValidatorIndex(i % validatorCount)
+ }
+ }
+ for i := range window {
+ window[i] = ð.PTCs{
+ ValidatorIndices: slices.Clone(indices),
+ }
+ }
+ return window
+}
+
func setupTestConfig(t *testing.T) {
params.SetupTestConfigCleanup(t)
cfg := params.BeaconConfig().Copy()
@@ -292,6 +324,50 @@ func signAttestation(t *testing.T, st state.ReadOnlyBeaconState, data *eth.Paylo
return agg.Marshal()
}
+func TestProcessPTCWindow(t *testing.T) {
+ fuluSt, _ := testutil.DeterministicGenesisStateFulu(t, 256)
+ st, err := gloas.UpgradeToGloas(fuluSt)
+ require.NoError(t, err)
+
+ slotsPerEpoch := params.BeaconConfig().SlotsPerEpoch
+
+ // Get original window.
+ origWindow, err := st.PTCWindow()
+ require.NoError(t, err)
+ windowSize := int(slotsPerEpoch.Mul(uint64(2 + params.BeaconConfig().MinSeedLookahead)))
+ require.Equal(t, windowSize, len(origWindow))
+
+ // Advance state to next epoch boundary so process_ptc_window sees a new epoch.
+ require.NoError(t, st.SetSlot(slotsPerEpoch))
+
+ // Process PTC window — should rotate.
+ require.NoError(t, gloas.ProcessPTCWindow(t.Context(), st))
+
+ newWindow, err := st.PTCWindow()
+ require.NoError(t, err)
+ require.Equal(t, windowSize, len(newWindow))
+
+ // The first two epochs should be the old epochs 1 and 2 (shifted left by one epoch).
+ for i := range 2 * slotsPerEpoch {
+ require.DeepEqual(t, origWindow[slotsPerEpoch+i], newWindow[i])
+ }
+
+ // The last epoch should be freshly computed — not all zeros.
+ lastStart := 2 * slotsPerEpoch
+ for i := range slotsPerEpoch {
+ ptcSlot := newWindow[lastStart+i]
+ require.NotNil(t, ptcSlot)
+ nonZero := false
+ for _, idx := range ptcSlot.ValidatorIndices {
+ if idx != 0 {
+ nonZero = true
+ break
+ }
+ }
+ require.Equal(t, true, nonZero, "last epoch slot %d should have non-zero validator indices", i)
+ }
+}
+
type validatorLookupErrState struct {
state.BeaconState
errIndex primitives.ValidatorIndex
diff --git a/beacon-chain/core/gloas/upgrade.go b/beacon-chain/core/gloas/upgrade.go
index d72c4d7d663f..40229589887e 100644
--- a/beacon-chain/core/gloas/upgrade.go
+++ b/beacon-chain/core/gloas/upgrade.go
@@ -1,6 +1,8 @@
package gloas
import (
+ "context"
+
"github.com/OffchainLabs/prysm/v7/beacon-chain/core/time"
"github.com/OffchainLabs/prysm/v7/beacon-chain/state"
state_native "github.com/OffchainLabs/prysm/v7/beacon-chain/state/state-native"
@@ -9,12 +11,13 @@ import (
"github.com/OffchainLabs/prysm/v7/consensus-types/primitives"
enginev1 "github.com/OffchainLabs/prysm/v7/proto/engine/v1"
ethpb "github.com/OffchainLabs/prysm/v7/proto/prysm/v1alpha1"
+ "github.com/OffchainLabs/prysm/v7/time/slots"
"github.com/pkg/errors"
)
// UpgradeToGloas updates inputs a generic state to return the version Gloas state.
//
-//
+//
// def upgrade_to_gloas(pre: fulu.BeaconState) -> BeaconState:
// epoch = fulu.get_current_epoch(pre)
//
@@ -81,6 +84,8 @@ import (
// latest_block_hash=pre.latest_execution_payload_header.block_hash,
// # [New in Gloas:EIP7732]
// payload_expected_withdrawals=[],
+// # [New in Gloas:EIP7732]
+// ptc_window=initialize_ptc_window(pre),
// )
//
// # [New in Gloas:EIP7732]
@@ -143,12 +148,73 @@ func UpgradeToGloas(beaconState state.BeaconState) (state.BeaconState, error) {
if err != nil {
return nil, errors.Wrap(err, "could not convert to gloas")
}
+ ptcWindow, err := initializePTCWindow(context.Background(), s)
+ if err != nil {
+ return nil, errors.Wrap(err, "failed to initialize ptc window")
+ }
+ if err := s.SetPTCWindow(ptcWindow); err != nil {
+ return nil, errors.Wrap(err, "failed to set ptc window")
+ }
if err := s.OnboardBuildersFromPendingDeposits(); err != nil {
return nil, errors.Wrap(err, "failed to onboard builders from pending deposits")
}
return s, nil
}
+// initializePTCWindow builds the initial PTC window for the Gloas fork upgrade.
+//
+//
+// def initialize_ptc_window(
+// state: BeaconState,
+// ) -> Vector[Vector[ValidatorIndex, PTC_SIZE], (2 + MIN_SEED_LOOKAHEAD) * SLOTS_PER_EPOCH]:
+// """
+// Return the cached PTC window starting from the current epoch.
+// Used to initialize the ``ptc_window`` field in the beacon state at genesis and after forks.
+// """
+// empty_previous_epoch = [
+// Vector[ValidatorIndex, PTC_SIZE]([ValidatorIndex(0) for _ in range(PTC_SIZE)])
+// for _ in range(SLOTS_PER_EPOCH)
+// ]
+//
+// ptcs = []
+// current_epoch = get_current_epoch(state)
+// for e in range(1 + MIN_SEED_LOOKAHEAD):
+// epoch = Epoch(current_epoch + e)
+// start_slot = compute_start_slot_at_epoch(epoch)
+// ptcs += [compute_ptc(state, Slot(start_slot + i)) for i in range(SLOTS_PER_EPOCH)]
+//
+// return empty_previous_epoch + ptcs
+//
+func initializePTCWindow(ctx context.Context, st state.ReadOnlyBeaconState) ([]*ethpb.PTCs, error) {
+ currentEpoch := slots.ToEpoch(st.Slot())
+ slotsPerEpoch := params.BeaconConfig().SlotsPerEpoch
+ windowSize := slotsPerEpoch.Mul(uint64(2 + params.BeaconConfig().MinSeedLookahead))
+ window := make([]*ethpb.PTCs, 0, windowSize)
+
+ // Previous epoch has no cached data at fork time — fill with empty slots.
+ for range slotsPerEpoch {
+ window = append(window, ðpb.PTCs{
+ ValidatorIndices: make([]primitives.ValidatorIndex, fieldparams.PTCSize),
+ })
+ }
+
+ // Compute PTC for current epoch through lookahead.
+ startSlot, err := slots.EpochStart(currentEpoch)
+ if err != nil {
+ return nil, err
+ }
+ totalSlots := slotsPerEpoch.Mul(uint64(1 + params.BeaconConfig().MinSeedLookahead))
+ for i := range totalSlots {
+ ptc, err := computePTC(ctx, st, startSlot+i)
+ if err != nil {
+ return nil, err
+ }
+ window = append(window, ðpb.PTCs{ValidatorIndices: ptc})
+ }
+
+ return window, nil
+}
+
func upgradeToGloas(beaconState state.BeaconState) (state.BeaconState, error) {
currentSyncCommittee, err := beaconState.CurrentSyncCommittee()
if err != nil {
diff --git a/beacon-chain/core/gloas/upgrade_test.go b/beacon-chain/core/gloas/upgrade_test.go
index 58de5ecdd3e8..193d41f9b102 100644
--- a/beacon-chain/core/gloas/upgrade_test.go
+++ b/beacon-chain/core/gloas/upgrade_test.go
@@ -103,7 +103,7 @@ func TestUpgradeToGloas_Basic(t *testing.T) {
}
func TestUpgradeToGloas_OnboardsBuilderDeposit(t *testing.T) {
- st, _ := util.DeterministicGenesisStateFulu(t, 4)
+ st, _ := util.DeterministicGenesisStateFulu(t, params.BeaconConfig().MaxValidatorsPerCommittee)
sk, err := bls.RandKey()
require.NoError(t, err)
diff --git a/beacon-chain/core/transition/gloas.go b/beacon-chain/core/transition/gloas.go
index 382cbf327374..6046a16172df 100644
--- a/beacon-chain/core/transition/gloas.go
+++ b/beacon-chain/core/transition/gloas.go
@@ -130,7 +130,7 @@ func gloasOperations(ctx context.Context, st state.BeaconState, block interfaces
//
// Spec definition:
//
-//
+//
// def process_epoch(state: BeaconState) -> None:
// process_justification_and_finalization(state)
// process_inactivity_updates(state)
@@ -149,6 +149,8 @@ func gloasOperations(ctx context.Context, st state.BeaconState, block interfaces
// process_participation_flag_updates(state)
// process_sync_committee_updates(state)
// process_proposer_lookahead(state)
+// # [New in Gloas:EIP7732]
+// process_ptc_window(state)
//
func processEpochGloas(ctx context.Context, state state.BeaconState) error {
_, span := trace.StartSpan(ctx, "gloas.ProcessEpoch")
@@ -222,5 +224,5 @@ func processEpochGloas(ctx context.Context, state state.BeaconState) error {
if err := fulu.ProcessProposerLookahead(ctx, state); err != nil {
return err
}
- return nil
+ return gloas.ProcessPTCWindow(ctx, state)
}
diff --git a/beacon-chain/rpc/core/BUILD.bazel b/beacon-chain/rpc/core/BUILD.bazel
index d5d63be88a81..b982a3a1c2e6 100644
--- a/beacon-chain/rpc/core/BUILD.bazel
+++ b/beacon-chain/rpc/core/BUILD.bazel
@@ -20,7 +20,6 @@ go_library(
"//beacon-chain/core/epoch/precompute:go_default_library",
"//beacon-chain/core/feed:go_default_library",
"//beacon-chain/core/feed/operation:go_default_library",
- "//beacon-chain/core/gloas:go_default_library",
"//beacon-chain/core/helpers:go_default_library",
"//beacon-chain/core/time:go_default_library",
"//beacon-chain/core/transition:go_default_library",
diff --git a/beacon-chain/rpc/core/duties.go b/beacon-chain/rpc/core/duties.go
index 5218da6ecb58..42cdc33e16fa 100644
--- a/beacon-chain/rpc/core/duties.go
+++ b/beacon-chain/rpc/core/duties.go
@@ -5,7 +5,6 @@ import (
"context"
"sort"
- "github.com/OffchainLabs/prysm/v7/beacon-chain/core/gloas"
"github.com/OffchainLabs/prysm/v7/beacon-chain/core/helpers"
coreTime "github.com/OffchainLabs/prysm/v7/beacon-chain/core/time"
"github.com/OffchainLabs/prysm/v7/beacon-chain/state"
@@ -221,7 +220,7 @@ func (s *Service) PTCDuties(ctx context.Context, st state.BeaconState, epoch pri
return nil, &RpcError{Err: ctx.Err(), Reason: Internal}
}
- ptc, err := gloas.PayloadCommittee(ctx, st, slot)
+ ptc, err := st.PayloadCommitteeReadOnly(slot)
if err != nil {
return nil, &RpcError{Err: err, Reason: Internal}
}
diff --git a/beacon-chain/rpc/eth/validator/BUILD.bazel b/beacon-chain/rpc/eth/validator/BUILD.bazel
index 8a5139530dfa..5b9a8bc01604 100644
--- a/beacon-chain/rpc/eth/validator/BUILD.bazel
+++ b/beacon-chain/rpc/eth/validator/BUILD.bazel
@@ -19,7 +19,6 @@ go_library(
"//beacon-chain/builder:go_default_library",
"//beacon-chain/cache:go_default_library",
"//beacon-chain/core/feed/operation:go_default_library",
- "//beacon-chain/core/gloas:go_default_library",
"//beacon-chain/core/helpers:go_default_library",
"//beacon-chain/db:go_default_library",
"//beacon-chain/operations/attestations:go_default_library",
@@ -67,7 +66,6 @@ go_test(
"//beacon-chain/blockchain/testing:go_default_library",
"//beacon-chain/builder/testing:go_default_library",
"//beacon-chain/cache:go_default_library",
- "//beacon-chain/core/gloas:go_default_library",
"//beacon-chain/core/helpers:go_default_library",
"//beacon-chain/core/transition:go_default_library",
"//beacon-chain/db/testing:go_default_library",
diff --git a/beacon-chain/rpc/eth/validator/handlers.go b/beacon-chain/rpc/eth/validator/handlers.go
index 56137cff6289..3119bf00ac48 100644
--- a/beacon-chain/rpc/eth/validator/handlers.go
+++ b/beacon-chain/rpc/eth/validator/handlers.go
@@ -17,7 +17,6 @@ import (
"github.com/OffchainLabs/prysm/v7/api/server/structs"
"github.com/OffchainLabs/prysm/v7/beacon-chain/builder"
"github.com/OffchainLabs/prysm/v7/beacon-chain/cache"
- "github.com/OffchainLabs/prysm/v7/beacon-chain/core/gloas"
"github.com/OffchainLabs/prysm/v7/beacon-chain/core/helpers"
"github.com/OffchainLabs/prysm/v7/beacon-chain/rpc/core"
rpchelpers "github.com/OffchainLabs/prysm/v7/beacon-chain/rpc/eth/helpers"
@@ -1261,7 +1260,7 @@ func ptcDuties(
return nil, ctx.Err()
}
- ptc, err := gloas.PayloadCommittee(ctx, st, slot)
+ ptc, err := st.PayloadCommitteeReadOnly(slot)
if err != nil {
return nil, errors.Wrapf(err, "failed to get PTC for slot %d", slot)
}
diff --git a/beacon-chain/rpc/eth/validator/handlers_test.go b/beacon-chain/rpc/eth/validator/handlers_test.go
index afba74635f0a..fb6bcd9add76 100644
--- a/beacon-chain/rpc/eth/validator/handlers_test.go
+++ b/beacon-chain/rpc/eth/validator/handlers_test.go
@@ -17,7 +17,6 @@ import (
mockChain "github.com/OffchainLabs/prysm/v7/beacon-chain/blockchain/testing"
builderTest "github.com/OffchainLabs/prysm/v7/beacon-chain/builder/testing"
"github.com/OffchainLabs/prysm/v7/beacon-chain/cache"
- "github.com/OffchainLabs/prysm/v7/beacon-chain/core/gloas"
"github.com/OffchainLabs/prysm/v7/beacon-chain/core/helpers"
"github.com/OffchainLabs/prysm/v7/beacon-chain/core/transition"
dbutil "github.com/OffchainLabs/prysm/v7/beacon-chain/db/testing"
@@ -3226,9 +3225,7 @@ func TestGetPTCDuties(t *testing.T) {
genesisTime := time.Now()
// Need enough validators for PTC selection (PTC_SIZE is 512 on mainnet, 2 on minimal)
numVals := uint64(fieldparams.PTCSize * 2)
- fuluSt, _ := util.DeterministicGenesisStateFulu(t, numVals)
- st, err := gloas.UpgradeToGloas(fuluSt)
- require.NoError(t, err)
+ st, _ := util.DeterministicGenesisStateGloas(t, numVals)
require.NoError(t, st.SetGenesisTime(genesisTime))
// Initialize the committee cache for epoch 0.
require.NoError(t, helpers.UpdateCommitteeCache(t.Context(), st, 0))
diff --git a/beacon-chain/rpc/prysm/v1alpha1/validator/duties_v2_test.go b/beacon-chain/rpc/prysm/v1alpha1/validator/duties_v2_test.go
index a84a885935c3..457847d38acd 100644
--- a/beacon-chain/rpc/prysm/v1alpha1/validator/duties_v2_test.go
+++ b/beacon-chain/rpc/prysm/v1alpha1/validator/duties_v2_test.go
@@ -10,7 +10,6 @@ import (
"github.com/OffchainLabs/prysm/v7/beacon-chain/cache/depositsnapshot"
"github.com/OffchainLabs/prysm/v7/beacon-chain/core/altair"
"github.com/OffchainLabs/prysm/v7/beacon-chain/core/execution"
- "github.com/OffchainLabs/prysm/v7/beacon-chain/core/gloas"
"github.com/OffchainLabs/prysm/v7/beacon-chain/core/helpers"
"github.com/OffchainLabs/prysm/v7/beacon-chain/core/transition"
mockExecution "github.com/OffchainLabs/prysm/v7/beacon-chain/execution/testing"
@@ -124,18 +123,24 @@ func TestGetDutiesV2_NextEpochProposerSlots(t *testing.T) {
params.OverrideBeaconConfig(cfg)
genesis := util.NewBeaconBlock()
- deposits, _, err := util.DeterministicDepositsAndKeys(params.BeaconConfig().MinGenesisActiveValidatorCount)
- require.NoError(t, err)
- eth1Data, err := util.DeterministicEth1Data(len(deposits))
- require.NoError(t, err)
- bs, err := transition.GenesisBeaconState(t.Context(), deposits, 0, eth1Data)
- require.NoError(t, err)
+ var bs beaconstate.BeaconState
+ if tt.gloasForkEpoch == 0 {
+ bs, _ = util.DeterministicGenesisStateGloas(t, params.BeaconConfig().MinGenesisActiveValidatorCount)
+ } else {
+ deposits, _, err := util.DeterministicDepositsAndKeys(params.BeaconConfig().MinGenesisActiveValidatorCount)
+ require.NoError(t, err)
+ eth1Data, err := util.DeterministicEth1Data(len(deposits))
+ require.NoError(t, err)
+ bs, err = transition.GenesisBeaconState(t.Context(), deposits, 0, eth1Data)
+ require.NoError(t, err)
+ }
genesisRoot, err := genesis.Block.HashTreeRoot()
require.NoError(t, err)
- pubKeys := make([][]byte, len(deposits))
- for i := range deposits {
- pubKeys[i] = deposits[i].Data.PublicKey
+ pubKeys := make([][]byte, len(bs.Validators()))
+ for i := range bs.Validators() {
+ pk := bs.PubkeyAtIndex(primitives.ValidatorIndex(i))
+ pubKeys[i] = pk[:]
}
chain := &mockChain.ChainService{
@@ -649,13 +654,12 @@ func TestGetDutiesV2_SyncNotReady(t *testing.T) {
// GloasForkEpoch and MaxEffectiveBalanceElectra in the beacon config.
func ptcTestState(t *testing.T) (beaconstate.BeaconState, [][]byte) {
t.Helper()
- numVals := params.BeaconConfig().MinGenesisActiveValidatorCount
- fuluSt, keys := util.DeterministicGenesisStateFulu(t, numVals)
- st, err := gloas.UpgradeToGloas(fuluSt)
- require.NoError(t, err)
- pubKeys := make([][]byte, numVals)
- for i := range numVals {
- pubKeys[i] = keys[i].PublicKey().Marshal()
+ depChainStart := params.BeaconConfig().MinGenesisActiveValidatorCount
+ st, _ := util.DeterministicGenesisStateGloas(t, depChainStart)
+ pubKeys := make([][]byte, depChainStart)
+ for i := range depChainStart {
+ pk := st.PubkeyAtIndex(primitives.ValidatorIndex(i))
+ pubKeys[i] = pk[:]
}
return st, pubKeys
}
@@ -691,7 +695,7 @@ func TestPTCDuties_PreGloasEpoch(t *testing.T) {
}
// TestPTCDuties_EmptyIndices verifies that an empty validator
-// index list short-circuits and returns an empty map without calling PayloadCommittee.
+// index list short-circuits and returns an empty map without calling PayloadCommitteeReadOnly.
func TestPTCDuties_EmptyIndices(t *testing.T) {
ptcTestConfig(t)
@@ -771,7 +775,7 @@ func TestPTCDuties_CollectsAllSlots(t *testing.T) {
for valIdx, assignedSlots := range result {
expected := make([]primitives.Slot, 0)
for s := epochStart; s < epochEnd; s++ {
- ptc, err := gloas.PayloadCommittee(t.Context(), st, s)
+ ptc, err := st.PayloadCommitteeReadOnly(s)
require.NoError(t, err)
found := slices.Contains(ptc, valIdx)
if found {
diff --git a/beacon-chain/rpc/prysm/v1alpha1/validator/duties_v3_test.go b/beacon-chain/rpc/prysm/v1alpha1/validator/duties_v3_test.go
index 614b80e8de34..d897cb1b9f06 100644
--- a/beacon-chain/rpc/prysm/v1alpha1/validator/duties_v3_test.go
+++ b/beacon-chain/rpc/prysm/v1alpha1/validator/duties_v3_test.go
@@ -6,7 +6,6 @@ import (
mockChain "github.com/OffchainLabs/prysm/v7/beacon-chain/blockchain/testing"
"github.com/OffchainLabs/prysm/v7/beacon-chain/core/altair"
- "github.com/OffchainLabs/prysm/v7/beacon-chain/core/gloas"
"github.com/OffchainLabs/prysm/v7/beacon-chain/core/helpers"
"github.com/OffchainLabs/prysm/v7/beacon-chain/core/transition"
dbutil "github.com/OffchainLabs/prysm/v7/beacon-chain/db/testing"
@@ -321,9 +320,7 @@ func TestGetPTCDuties_OK(t *testing.T) {
params.OverrideBeaconConfig(cfg)
numVals := uint64(fieldparams.PTCSize + 64)
- fuluSt, _ := util.DeterministicGenesisStateFulu(t, numVals)
- bs, err := gloas.UpgradeToGloas(fuluSt)
- require.NoError(t, err)
+ bs, _ := util.DeterministicGenesisStateGloas(t, numVals)
require.NoError(t, helpers.UpdateCommitteeCache(t.Context(), bs, 0))
genesisRoot := [32]byte{0xaa}
diff --git a/beacon-chain/rpc/prysm/v1alpha1/validator/payload_attestation_test.go b/beacon-chain/rpc/prysm/v1alpha1/validator/payload_attestation_test.go
index 3cffb8ec9754..babb6ed05df2 100644
--- a/beacon-chain/rpc/prysm/v1alpha1/validator/payload_attestation_test.go
+++ b/beacon-chain/rpc/prysm/v1alpha1/validator/payload_attestation_test.go
@@ -5,7 +5,6 @@ import (
"testing"
chainMock "github.com/OffchainLabs/prysm/v7/beacon-chain/blockchain/testing"
- "github.com/OffchainLabs/prysm/v7/beacon-chain/core/gloas"
payloadattestation "github.com/OffchainLabs/prysm/v7/beacon-chain/operations/payloadattestation"
p2pmock "github.com/OffchainLabs/prysm/v7/beacon-chain/p2p/testing"
mockSync "github.com/OffchainLabs/prysm/v7/beacon-chain/sync/initial-sync/testing"
@@ -90,8 +89,8 @@ func TestSubmitPayloadAttestation_OK(t *testing.T) {
slot := primitives.Slot(0)
root := bytesutil.PadTo([]byte{0xBB}, 32)
- st, _ := util.DeterministicGenesisState(t, 64)
- ptc, err := gloas.PayloadCommittee(t.Context(), st, slot)
+ st, _ := util.DeterministicGenesisStateGloas(t, 64)
+ ptc, err := st.PayloadCommitteeReadOnly(slot)
require.NoError(t, err)
require.NotEqual(t, 0, len(ptc))
diff --git a/beacon-chain/state/interfaces_gloas.go b/beacon-chain/state/interfaces_gloas.go
index 55ab05552310..830b7b2a0153 100644
--- a/beacon-chain/state/interfaces_gloas.go
+++ b/beacon-chain/state/interfaces_gloas.go
@@ -11,6 +11,8 @@ import (
type writeOnlyGloasFields interface {
// Bids.
SetExecutionPayloadBid(h interfaces.ROExecutionPayloadBid) error
+ SetPTCWindow([]*ethpb.PTCs) error
+ RotatePTCWindow([]*ethpb.PTCs) error
// Builder pending payments / withdrawals.
SetBuilderPendingPayment(index primitives.Slot, payment *ethpb.BuilderPendingPayment) error
@@ -43,6 +45,8 @@ type writeOnlyGloasFields interface {
type readOnlyGloasFields interface {
// Bids.
LatestExecutionPayloadBid() (interfaces.ROExecutionPayloadBid, error)
+ PTCWindow() ([]*ethpb.PTCs, error)
+ PayloadCommitteeReadOnly(slot primitives.Slot) ([]primitives.ValidatorIndex, error)
// Builder pending payments / withdrawals.
BuilderPendingPayments() ([]*ethpb.BuilderPendingPayment, error)
diff --git a/beacon-chain/state/state-native/beacon_state.go b/beacon-chain/state/state-native/beacon_state.go
index a879a26f21e8..741c1482741b 100644
--- a/beacon-chain/state/state-native/beacon_state.go
+++ b/beacon-chain/state/state-native/beacon_state.go
@@ -79,6 +79,7 @@ type BeaconState struct {
builderPendingWithdrawals []*ethpb.BuilderPendingWithdrawal
latestBlockHash []byte
payloadExpectedWithdrawals []*enginev1.Withdrawal
+ ptcWindow []*ethpb.PTCs
id uint64
lock sync.RWMutex
@@ -143,6 +144,7 @@ type beaconStateMarshalable struct {
BuilderPendingWithdrawals []*ethpb.BuilderPendingWithdrawal `json:"builder_pending_withdrawals" yaml:"builder_pending_withdrawals"`
LatestBlockHash []byte `json:"latest_block_hash" yaml:"latest_block_hash"`
PayloadExpectedWithdrawals []*enginev1.Withdrawal `json:"payload_expected_withdrawals" yaml:"payload_expected_withdrawals"`
+ PtcWindow []*ethpb.PTCs `json:"ptc_window" yaml:"ptc_window"`
}
func (b *BeaconState) MarshalJSON() ([]byte, error) {
@@ -205,6 +207,7 @@ func (b *BeaconState) MarshalJSON() ([]byte, error) {
BuilderPendingWithdrawals: b.builderPendingWithdrawals,
LatestBlockHash: b.latestBlockHash,
PayloadExpectedWithdrawals: b.payloadExpectedWithdrawals,
+ PtcWindow: b.ptcWindow,
}
return json.Marshal(marshalable)
}
diff --git a/beacon-chain/state/state-native/getters_gloas.go b/beacon-chain/state/state-native/getters_gloas.go
index 2b63e8c97da2..73ee12bada57 100644
--- a/beacon-chain/state/state-native/getters_gloas.go
+++ b/beacon-chain/state/state-native/getters_gloas.go
@@ -34,6 +34,18 @@ func (b *BeaconState) LatestBlockHash() ([32]byte, error) {
return [32]byte(b.latestBlockHash), nil
}
+// PTCWindow returns a copy of the cached PTC window.
+func (b *BeaconState) PTCWindow() ([]*ethpb.PTCs, error) {
+ if b.version < version.Gloas {
+ return nil, errNotSupported("PTCWindow", b.version)
+ }
+
+ b.lock.RLock()
+ defer b.lock.RUnlock()
+
+ return b.ptcWindowVal(), nil
+}
+
// IsAttestationSameSlot checks if the attestation is for the same slot as the block root in the state.
// Spec v1.7.0-alpha pseudocode:
//
@@ -689,3 +701,64 @@ func (b *BeaconState) NextWithdrawalBuilderIndex() (primitives.BuilderIndex, err
return b.nextWithdrawalBuilderIndex, nil
}
+
+// PayloadCommitteeReadOnly returns the payload timeliness committee for a given slot
+// by looking up the cached PTC window in state.
+//
+//
+// def get_ptc(state: BeaconState, slot: Slot) -> Vector[ValidatorIndex, PTC_SIZE]:
+// """
+// Get the payload timeliness committee for the given ``slot``.
+// """
+// epoch = compute_epoch_at_slot(slot)
+// state_epoch = get_current_epoch(state)
+// if epoch < state_epoch:
+// assert epoch + 1 == state_epoch
+// return state.ptc_window[slot % SLOTS_PER_EPOCH]
+// assert epoch <= state_epoch + MIN_SEED_LOOKAHEAD
+// offset = (epoch - state_epoch + 1) * SLOTS_PER_EPOCH
+// return state.ptc_window[offset + slot % SLOTS_PER_EPOCH]
+//
+func (b *BeaconState) PayloadCommitteeReadOnly(slot primitives.Slot) ([]primitives.ValidatorIndex, error) {
+ if b.version < version.Gloas {
+ return nil, errNotSupported("PayloadCommitteeReadOnly", b.version)
+ }
+
+ b.lock.RLock()
+ defer b.lock.RUnlock()
+
+ offset, err := ptcWindowOffset(b.slot, slot)
+ if err != nil {
+ return nil, err
+ }
+
+ if uint64(offset) >= uint64(len(b.ptcWindow)) {
+ return nil, fmt.Errorf("ptc window offset %d out of range for size %d", offset, len(b.ptcWindow))
+ }
+ ptcSlot := b.ptcWindow[offset]
+ if ptcSlot == nil {
+ return nil, fmt.Errorf("ptc window slot %d is nil", offset)
+ }
+
+ return ptcSlot.ValidatorIndices, nil
+}
+
+func ptcWindowOffset(stateSlot, slot primitives.Slot) (primitives.Slot, error) {
+ epoch := slots.ToEpoch(slot)
+ stateEpoch := slots.ToEpoch(stateSlot)
+ slotsPerEpoch := params.BeaconConfig().SlotsPerEpoch
+
+ if epoch < stateEpoch {
+ if epoch+1 != stateEpoch {
+ return 0, fmt.Errorf("ptc window only supports previous epoch lookups: state_epoch=%d slot_epoch=%d", stateEpoch, epoch)
+ }
+ return slot % slotsPerEpoch, nil
+ }
+
+ if epoch > stateEpoch+params.BeaconConfig().MinSeedLookahead {
+ return 0, fmt.Errorf("ptc window lookup out of range: state_epoch=%d slot_epoch=%d", stateEpoch, epoch)
+ }
+
+ offset := slotsPerEpoch.Mul(uint64(epoch-stateEpoch+1)) + (slot % slotsPerEpoch)
+ return offset, nil
+}
diff --git a/beacon-chain/state/state-native/getters_gloas_test.go b/beacon-chain/state/state-native/getters_gloas_test.go
index 924b88bea91a..3c7526781bbd 100644
--- a/beacon-chain/state/state-native/getters_gloas_test.go
+++ b/beacon-chain/state/state-native/getters_gloas_test.go
@@ -2,6 +2,7 @@ package state_native
import (
"bytes"
+ "fmt"
"testing"
fieldparams "github.com/OffchainLabs/prysm/v7/config/fieldparams"
@@ -910,3 +911,207 @@ func TestExecutionPayloadAvailabilityVector(t *testing.T) {
require.DeepEqual(t, availability, got2)
})
}
+
+// testPTCWindow creates a PTC window of the expected size where each slot's
+// first validator index encodes the slot offset for easy identification.
+func testPTCWindow(t *testing.T) []*ethpb.PTCs {
+ t.Helper()
+ size := int(expectedPTCWindowSize())
+ window := make([]*ethpb.PTCs, size)
+ for i := range window {
+ indices := make([]primitives.ValidatorIndex, fieldparams.PTCSize)
+ indices[0] = primitives.ValidatorIndex(i) + 1 // non-zero marker
+ window[i] = ðpb.PTCs{ValidatorIndices: indices}
+ }
+ return window
+}
+
+func TestPtcWindowOffset(t *testing.T) {
+ params.SetupTestConfigCleanup(t)
+ slotsPerEpoch := params.BeaconConfig().SlotsPerEpoch
+
+ t.Run("current epoch slot", func(t *testing.T) {
+ // State at epoch 2, query slot in epoch 2 → offset = (2-2+1)*32 + slot%32 = 32 + slot%32
+ stateSlot := slotsPerEpoch * 2 // slot 64, epoch 2
+ querySlot := stateSlot + 3 // slot 67, epoch 2
+ offset, err := ptcWindowOffset(stateSlot, querySlot)
+ require.NoError(t, err)
+ expected := slotsPerEpoch + (querySlot % slotsPerEpoch) // offset in "current epoch" region
+ require.Equal(t, expected, offset)
+ })
+
+ t.Run("previous epoch slot", func(t *testing.T) {
+ stateSlot := slotsPerEpoch * 2 // epoch 2
+ querySlot := slotsPerEpoch + 5 // slot 37, epoch 1 (previous)
+ offset, err := ptcWindowOffset(stateSlot, querySlot)
+ require.NoError(t, err)
+ require.Equal(t, querySlot%slotsPerEpoch, offset) // previous epoch region
+ })
+
+ t.Run("lookahead epoch slot", func(t *testing.T) {
+ stateSlot := slotsPerEpoch * 2 // epoch 2
+ querySlot := slotsPerEpoch*3 + 10 // slot 106, epoch 3 (lookahead with MinSeedLookahead=1)
+ offset, err := ptcWindowOffset(stateSlot, querySlot)
+ require.NoError(t, err)
+ // epoch_diff = 3-2 = 1, offset = (1+1)*32 + 10 = 74
+ expected := slotsPerEpoch.Mul(uint64(slots.ToEpoch(querySlot)-slots.ToEpoch(stateSlot)+1)) + (querySlot % slotsPerEpoch)
+ require.Equal(t, expected, offset)
+ })
+
+ t.Run("error: epoch too far in past", func(t *testing.T) {
+ stateSlot := slotsPerEpoch * 3 // epoch 3
+ querySlot := slotsPerEpoch + 1 // slot 33, epoch 1 (two epochs back)
+ _, err := ptcWindowOffset(stateSlot, querySlot)
+ require.ErrorContains(t, "only supports previous epoch lookups", err)
+ })
+
+ t.Run("error: epoch too far in future", func(t *testing.T) {
+ stateSlot := slotsPerEpoch * 2 // epoch 2
+ querySlot := slotsPerEpoch*4 + 1 // epoch 4 (beyond MinSeedLookahead=1 from epoch 2)
+ _, err := ptcWindowOffset(stateSlot, querySlot)
+ require.ErrorContains(t, "out of range", err)
+ })
+}
+
+func TestPayloadCommitteeReadOnly(t *testing.T) {
+ params.SetupTestConfigCleanup(t)
+ slotsPerEpoch := params.BeaconConfig().SlotsPerEpoch
+
+ t.Run("returns error before gloas", func(t *testing.T) {
+ st := &BeaconState{version: version.Fulu}
+ _, err := st.PayloadCommitteeReadOnly(0)
+ require.ErrorContains(t, "PayloadCommitteeReadOnly", err)
+ })
+
+ t.Run("returns committee from current epoch", func(t *testing.T) {
+ window := testPTCWindow(t)
+ st := &BeaconState{
+ version: version.Gloas,
+ slot: slotsPerEpoch * 2, // epoch 2
+ ptcWindow: window,
+ }
+ // Query slot 64 (first slot of epoch 2) → offset = 32
+ ptc, err := st.PayloadCommitteeReadOnly(slotsPerEpoch * 2)
+ require.NoError(t, err)
+ require.Equal(t, primitives.ValidatorIndex(slotsPerEpoch+1), ptc[0])
+ })
+
+ t.Run("returns committee from previous epoch", func(t *testing.T) {
+ window := testPTCWindow(t)
+ st := &BeaconState{
+ version: version.Gloas,
+ slot: slotsPerEpoch * 2, // epoch 2
+ ptcWindow: window,
+ }
+ // Query slot 35 (epoch 1, offset 3) → previous epoch region, offset = 3
+ ptc, err := st.PayloadCommitteeReadOnly(slotsPerEpoch + 3)
+ require.NoError(t, err)
+ require.Equal(t, primitives.ValidatorIndex(4), ptc[0]) // window[3] has marker 4
+ })
+
+ t.Run("error on nil ptc slot", func(t *testing.T) {
+ window := testPTCWindow(t)
+ window[slotsPerEpoch] = nil // nil out the first current-epoch slot
+ st := &BeaconState{
+ version: version.Gloas,
+ slot: slotsPerEpoch * 2,
+ ptcWindow: window,
+ }
+ _, err := st.PayloadCommitteeReadOnly(slotsPerEpoch * 2)
+ require.ErrorContains(t, "is nil", err)
+ })
+}
+
+func TestSetPTCWindow(t *testing.T) {
+ params.SetupTestConfigCleanup(t)
+
+ t.Run("returns error before gloas", func(t *testing.T) {
+ st := &BeaconState{version: version.Fulu}
+ err := st.SetPTCWindow(nil)
+ require.ErrorContains(t, "SetPTCWindow", err)
+ })
+
+ t.Run("rejects wrong size", func(t *testing.T) {
+ st, err := InitializeFromProtoGloas(ðpb.BeaconStateGloas{
+ PtcWindow: testPTCWindow(t),
+ })
+ require.NoError(t, err)
+ err = st.SetPTCWindow(make([]*ethpb.PTCs, 10))
+ require.ErrorContains(t, "invalid size", err)
+ })
+
+ t.Run("sets and copies window", func(t *testing.T) {
+ st, err := InitializeFromProtoGloas(ðpb.BeaconStateGloas{
+ PtcWindow: testPTCWindow(t),
+ })
+ require.NoError(t, err)
+
+ newWindow := testPTCWindow(t)
+ newWindow[0].ValidatorIndices[0] = 999
+ require.NoError(t, st.SetPTCWindow(newWindow))
+
+ got, err := st.PTCWindow()
+ require.NoError(t, err)
+ require.Equal(t, primitives.ValidatorIndex(999), got[0].ValidatorIndices[0])
+
+ // Verify it's a copy — mutating the input doesn't affect state.
+ newWindow[0].ValidatorIndices[0] = 0
+ got2, err := st.PTCWindow()
+ require.NoError(t, err)
+ require.Equal(t, primitives.ValidatorIndex(999), got2[0].ValidatorIndices[0])
+ })
+}
+
+func TestRotatePTCWindow(t *testing.T) {
+ params.SetupTestConfigCleanup(t)
+ slotsPerEpoch := params.BeaconConfig().SlotsPerEpoch
+
+ t.Run("returns error before gloas", func(t *testing.T) {
+ st := &BeaconState{version: version.Fulu}
+ err := st.RotatePTCWindow(nil)
+ require.ErrorContains(t, "RotatePTCWindow", err)
+ })
+
+ t.Run("rejects wrong new epoch size", func(t *testing.T) {
+ st, err := InitializeFromProtoGloas(ðpb.BeaconStateGloas{
+ PtcWindow: testPTCWindow(t),
+ })
+ require.NoError(t, err)
+ err = st.RotatePTCWindow(make([]*ethpb.PTCs, 5))
+ require.ErrorContains(t, "invalid new epoch slots size", err)
+ })
+
+ t.Run("rotates window correctly", func(t *testing.T) {
+ origWindow := testPTCWindow(t)
+ st, err := InitializeFromProtoGloas(ðpb.BeaconStateGloas{
+ PtcWindow: origWindow,
+ })
+ require.NoError(t, err)
+
+ // Build new epoch slots with distinct markers.
+ newEpoch := make([]*ethpb.PTCs, slotsPerEpoch)
+ for i := range newEpoch {
+ indices := make([]primitives.ValidatorIndex, fieldparams.PTCSize)
+ indices[0] = primitives.ValidatorIndex(1000 + i)
+ newEpoch[i] = ðpb.PTCs{ValidatorIndices: indices}
+ }
+ require.NoError(t, st.RotatePTCWindow(newEpoch))
+
+ got, err := st.PTCWindow()
+ require.NoError(t, err)
+
+ // First two epochs should be shifted from original epochs 1 and 2.
+ for i := range 2 * slotsPerEpoch {
+ expected := origWindow[slotsPerEpoch+i].ValidatorIndices[0]
+ require.Equal(t, expected, got[i].ValidatorIndices[0],
+ fmt.Sprintf("mismatch at shifted slot %d", i))
+ }
+
+ // Last epoch should be the new epoch slots.
+ lastStart := 2 * slotsPerEpoch
+ for i := range slotsPerEpoch {
+ require.Equal(t, primitives.ValidatorIndex(1000+i), got[lastStart+i].ValidatorIndices[0],
+ fmt.Sprintf("mismatch at new slot %d", i))
+ }
+ })
+}
diff --git a/beacon-chain/state/state-native/getters_state.go b/beacon-chain/state/state-native/getters_state.go
index 7ceaaa731a88..7f9ac312b2b1 100644
--- a/beacon-chain/state/state-native/getters_state.go
+++ b/beacon-chain/state/state-native/getters_state.go
@@ -312,6 +312,7 @@ func (b *BeaconState) ToProtoUnsafe() any {
BuilderPendingWithdrawals: b.builderPendingWithdrawals,
LatestBlockHash: b.latestBlockHash,
PayloadExpectedWithdrawals: b.payloadExpectedWithdrawals,
+ PtcWindow: b.ptcWindow,
}
default:
return nil
@@ -616,6 +617,7 @@ func (b *BeaconState) ToProto() any {
BuilderPendingWithdrawals: b.builderPendingWithdrawalsVal(),
LatestBlockHash: b.latestBlockHashVal(),
PayloadExpectedWithdrawals: b.payloadExpectedWithdrawalsVal(),
+ PtcWindow: b.ptcWindowVal(),
}
default:
return nil
diff --git a/beacon-chain/state/state-native/gloas.go b/beacon-chain/state/state-native/gloas.go
index 0b00374c0f50..22c6247be20f 100644
--- a/beacon-chain/state/state-native/gloas.go
+++ b/beacon-chain/state/state-native/gloas.go
@@ -91,3 +91,9 @@ func (b *BeaconState) payloadExpectedWithdrawalsVal() []*enginev1.Withdrawal {
return withdrawals
}
+
+// ptcWindowVal returns a copy of the cached PTC window.
+// This assumes that a lock is already held on BeaconState.
+func (b *BeaconState) ptcWindowVal() []*ethpb.PTCs {
+ return ethpb.CopyPTCWindow(b.ptcWindow)
+}
diff --git a/beacon-chain/state/state-native/gloas_test.go b/beacon-chain/state/state-native/gloas_test.go
index 2e74103fd198..fa5157cc0714 100644
--- a/beacon-chain/state/state-native/gloas_test.go
+++ b/beacon-chain/state/state-native/gloas_test.go
@@ -3,6 +3,7 @@ package state_native
import (
"testing"
+ "github.com/OffchainLabs/prysm/v7/consensus-types/primitives"
enginev1 "github.com/OffchainLabs/prysm/v7/proto/engine/v1"
ethpb "github.com/OffchainLabs/prysm/v7/proto/prysm/v1alpha1"
"github.com/stretchr/testify/require"
@@ -41,3 +42,23 @@ func TestPayloadExpectedWithdrawalsVal(t *testing.T) {
require.Equal(t, st.payloadExpectedWithdrawals[0], got[0])
require.NotSame(t, st.payloadExpectedWithdrawals[0], got[0])
}
+
+func TestPTCWindowVal(t *testing.T) {
+ st := &BeaconState{}
+
+ require.Nil(t, st.ptcWindowVal())
+
+ st.ptcWindow = []*ethpb.PTCs{
+ {ValidatorIndices: []primitives.ValidatorIndex{1, 2}},
+ nil,
+ }
+
+ got := st.ptcWindowVal()
+ require.Len(t, got, 2)
+ require.Nil(t, got[1])
+ require.Equal(t, st.ptcWindow[0], got[0])
+ require.NotSame(t, st.ptcWindow[0], got[0])
+
+ got[0].ValidatorIndices[0] = 99
+ require.Equal(t, primitives.ValidatorIndex(1), st.ptcWindow[0].ValidatorIndices[0])
+}
diff --git a/beacon-chain/state/state-native/hasher.go b/beacon-chain/state/state-native/hasher.go
index 3ca5f853734a..bca6a7fb5ff7 100644
--- a/beacon-chain/state/state-native/hasher.go
+++ b/beacon-chain/state/state-native/hasher.go
@@ -381,6 +381,13 @@ func ComputeFieldRootsWithHasher(ctx context.Context, state *BeaconState) ([][]b
}
fieldRoots[types.PayloadExpectedWithdrawals.RealPosition()] = expectedWithdrawalsRoot[:]
+
+ ptcWindowRoot, err := stateutil.PTCWindowRoot(state.ptcWindow)
+ if err != nil {
+ return nil, errors.Wrap(err, "could not compute ptc window merkleization")
+ }
+
+ fieldRoots[types.PTCWindow.RealPosition()] = ptcWindowRoot[:]
}
return fieldRoots, nil
}
diff --git a/beacon-chain/state/state-native/setters_gloas.go b/beacon-chain/state/state-native/setters_gloas.go
index ac4a3058eedd..e9232f3d710e 100644
--- a/beacon-chain/state/state-native/setters_gloas.go
+++ b/beacon-chain/state/state-native/setters_gloas.go
@@ -642,7 +642,7 @@ func decreaseBalanceWithVal(currBalance, delta primitives.Gwei) primitives.Gwei
// OnboardBuildersFromPendingDeposits applies any pending builder deposits at the fork.
// It mutates the state and prunes pending deposits accordingly.
//
-//
+//
// def onboard_builders_from_pending_deposits(state: BeaconState) -> None:
// """
// Applies any pending deposit for builders, effectively
@@ -767,3 +767,66 @@ func (b *BeaconState) OnboardBuildersFromPendingDeposits() error {
return nil
}
+
+// SetPTCWindow is a mutating call to the beacon state which sets the cached PTC window.
+func (b *BeaconState) SetPTCWindow(window []*ethpb.PTCs) error {
+ if b.version < version.Gloas {
+ return errNotSupported("SetPTCWindow", b.version)
+ }
+
+ expected := expectedPTCWindowSize()
+ if uint64(len(window)) != uint64(expected) {
+ return fmt.Errorf("invalid size for ptc window: got %d want %d", len(window), expected)
+ }
+
+ b.lock.Lock()
+ defer b.lock.Unlock()
+
+ b.sharedFieldReferences[types.PTCWindow].MinusRef()
+ b.sharedFieldReferences[types.PTCWindow] = stateutil.NewRef(1)
+ b.ptcWindow = ethpb.CopyPTCWindow(window)
+ b.markFieldAsDirty(types.PTCWindow)
+ return nil
+}
+
+// RotatePTCWindow shifts the PTC window left by one epoch and fills the last epoch
+// with the provided new slots. This performs the rotation in-place under lock.
+func (b *BeaconState) RotatePTCWindow(newEpochSlots []*ethpb.PTCs) error {
+ if b.version < version.Gloas {
+ return errNotSupported("RotatePTCWindow", b.version)
+ }
+
+ slotsPerEpoch := params.BeaconConfig().SlotsPerEpoch
+ if uint64(len(newEpochSlots)) != uint64(slotsPerEpoch) {
+ return fmt.Errorf("invalid new epoch slots size: got %d want %d", len(newEpochSlots), slotsPerEpoch)
+ }
+
+ b.lock.Lock()
+ defer b.lock.Unlock()
+
+ expected := expectedPTCWindowSize()
+ if uint64(len(b.ptcWindow)) != uint64(expected) {
+ return fmt.Errorf("invalid ptc window size: got %d want %d", len(b.ptcWindow), expected)
+ }
+
+ b.sharedFieldReferences[types.PTCWindow].MinusRef()
+ b.sharedFieldReferences[types.PTCWindow] = stateutil.NewRef(1)
+
+ newWindow := make([]*ethpb.PTCs, expected)
+
+ // Shift left by one epoch.
+ lastEpochStart := expected - slotsPerEpoch
+ copy(newWindow[:lastEpochStart], b.ptcWindow[slotsPerEpoch:])
+
+ // Fill the last epoch with copied new slots.
+ copy(newWindow[lastEpochStart:], ethpb.CopyPTCWindow(newEpochSlots))
+
+ b.ptcWindow = newWindow
+
+ b.markFieldAsDirty(types.PTCWindow)
+ return nil
+}
+
+func expectedPTCWindowSize() primitives.Slot {
+ return params.BeaconConfig().SlotsPerEpoch.Mul(uint64(2 + params.BeaconConfig().MinSeedLookahead))
+}
diff --git a/beacon-chain/state/state-native/state_trie.go b/beacon-chain/state/state-native/state_trie.go
index 959f9f725828..b43485b78e2c 100644
--- a/beacon-chain/state/state-native/state_trie.go
+++ b/beacon-chain/state/state-native/state_trie.go
@@ -128,6 +128,7 @@ var (
types.BuilderPendingWithdrawals,
types.LatestBlockHash,
types.PayloadExpectedWithdrawals,
+ types.PTCWindow,
}
gloasFields = slices.Concat(
@@ -148,7 +149,7 @@ const (
denebSharedFieldRefCount = 7
electraSharedFieldRefCount = 10
fuluSharedFieldRefCount = 11
- gloasSharedFieldRefCount = 13 // Adds Builders + BuilderPendingWithdrawals to the shared-ref set and LatestExecutionPayloadHeader is removed
+ gloasSharedFieldRefCount = 14 // Adds Builders + BuilderPendingWithdrawals + PTCWindow to the shared-ref set and LatestExecutionPayloadHeader is removed
)
// InitializeFromProtoPhase0 the beacon state from a protobuf representation.
@@ -827,6 +828,7 @@ func InitializeFromProtoUnsafeGloas(st *ethpb.BeaconStateGloas) (state.BeaconSta
builderPendingWithdrawals: st.BuilderPendingWithdrawals,
latestBlockHash: st.LatestBlockHash,
payloadExpectedWithdrawals: st.PayloadExpectedWithdrawals,
+ ptcWindow: st.PtcWindow,
dirtyFields: make(map[types.FieldIndex]bool, fieldCount),
dirtyIndices: make(map[types.FieldIndex][]uint64, fieldCount),
stateFieldLeaves: make(map[types.FieldIndex]*fieldtrie.FieldTrie, fieldCount),
@@ -868,6 +870,7 @@ func InitializeFromProtoUnsafeGloas(st *ethpb.BeaconStateGloas) (state.BeaconSta
b.sharedFieldReferences[types.ProposerLookahead] = stateutil.NewRef(1)
b.sharedFieldReferences[types.Builders] = stateutil.NewRef(1) // New in Gloas.
b.sharedFieldReferences[types.BuilderPendingWithdrawals] = stateutil.NewRef(1) // New in Gloas.
+ b.sharedFieldReferences[types.PTCWindow] = stateutil.NewRef(1) // New in Gloas.
state.Count.Inc()
// Finalizer runs when dst is being destroyed in garbage collection.
@@ -926,6 +929,7 @@ func (b *BeaconState) Copy() state.BeaconState {
eth1DataVotes: b.eth1DataVotes,
slashings: b.slashings,
proposerLookahead: b.proposerLookahead,
+ ptcWindow: b.ptcWindow,
// Large arrays, increases over time.
balancesMultiValue: b.balancesMultiValue,
@@ -1411,6 +1415,8 @@ func (b *BeaconState) rootSelector(ctx context.Context, field types.FieldIndex)
return bytesutil.ToBytes32(b.latestBlockHash), nil
case types.PayloadExpectedWithdrawals:
return ssz.WithdrawalSliceRoot(b.payloadExpectedWithdrawals, fieldparams.MaxWithdrawalsPerPayload)
+ case types.PTCWindow:
+ return stateutil.PTCWindowRoot(b.ptcWindow)
}
return [32]byte{}, errors.New("invalid field index provided")
}
diff --git a/beacon-chain/state/state-native/types/types.go b/beacon-chain/state/state-native/types/types.go
index 158f9d01aba1..d4adb875281a 100644
--- a/beacon-chain/state/state-native/types/types.go
+++ b/beacon-chain/state/state-native/types/types.go
@@ -130,6 +130,8 @@ func (f FieldIndex) String() string {
return "latestBlockHash"
case PayloadExpectedWithdrawals:
return "payloadExpectedWithdrawals"
+ case PTCWindow:
+ return "ptcWindow"
default:
return fmt.Sprintf("unknown field index number: %d", f)
}
@@ -229,6 +231,8 @@ func (f FieldIndex) RealPosition() int {
return 43
case PayloadExpectedWithdrawals:
return 44
+ case PTCWindow:
+ return 45
default:
return -1
}
@@ -302,6 +306,7 @@ const (
BuilderPendingWithdrawals // Gloas: EIP-7732
LatestBlockHash // Gloas: EIP-7732
PayloadExpectedWithdrawals // Gloas: EIP-7732
+ PTCWindow // Gloas: EIP-7732
)
// Enumerator keeps track of the number of states created since the node's start.
diff --git a/beacon-chain/state/stateutil/BUILD.bazel b/beacon-chain/state/stateutil/BUILD.bazel
index 9f6d39887cf8..f3955b342c2e 100644
--- a/beacon-chain/state/stateutil/BUILD.bazel
+++ b/beacon-chain/state/stateutil/BUILD.bazel
@@ -22,6 +22,7 @@ go_library(
"pending_deposits_root.go",
"pending_partial_withdrawals_root.go",
"proposer_lookahead_root.go",
+ "ptc_window_root.go",
"reference.go",
"sync_committee.root.go",
"trie_helpers.go",
diff --git a/beacon-chain/state/stateutil/ptc_window_root.go b/beacon-chain/state/stateutil/ptc_window_root.go
new file mode 100644
index 000000000000..014f883f45f6
--- /dev/null
+++ b/beacon-chain/state/stateutil/ptc_window_root.go
@@ -0,0 +1,28 @@
+package stateutil
+
+import (
+ "fmt"
+
+ "github.com/OffchainLabs/prysm/v7/encoding/ssz"
+ ethpb "github.com/OffchainLabs/prysm/v7/proto/prysm/v1alpha1"
+)
+
+// PTCWindowRoot computes the merkle root of the cached PTC window.
+func PTCWindowRoot(ptcs []*ethpb.PTCs) ([32]byte, error) {
+ roots := make([][32]byte, len(ptcs))
+
+ for i, ptc := range ptcs {
+ if ptc == nil {
+ return [32]byte{}, fmt.Errorf("invalid PTC at position %d", i)
+ }
+
+ r, err := ptc.HashTreeRoot()
+ if err != nil {
+ return [32]byte{}, err
+ }
+
+ roots[i] = r
+ }
+
+ return ssz.MerkleizeVector(roots, uint64(len(roots))), nil
+}
diff --git a/beacon-chain/sync/BUILD.bazel b/beacon-chain/sync/BUILD.bazel
index 9553ded53ab8..16c2e21af7d6 100644
--- a/beacon-chain/sync/BUILD.bazel
+++ b/beacon-chain/sync/BUILD.bazel
@@ -253,7 +253,6 @@ go_test(
"//beacon-chain/core/altair:go_default_library",
"//beacon-chain/core/feed:go_default_library",
"//beacon-chain/core/feed/operation:go_default_library",
- "//beacon-chain/core/gloas:go_default_library",
"//beacon-chain/core/helpers:go_default_library",
"//beacon-chain/core/peerdas:go_default_library",
"//beacon-chain/core/signing:go_default_library",
diff --git a/beacon-chain/sync/subscriber_payload_attestation_test.go b/beacon-chain/sync/subscriber_payload_attestation_test.go
index 206f30cf3eee..5c38d7053bb7 100644
--- a/beacon-chain/sync/subscriber_payload_attestation_test.go
+++ b/beacon-chain/sync/subscriber_payload_attestation_test.go
@@ -6,7 +6,6 @@ import (
mock "github.com/OffchainLabs/prysm/v7/beacon-chain/blockchain/testing"
"github.com/OffchainLabs/prysm/v7/beacon-chain/cache"
- "github.com/OffchainLabs/prysm/v7/beacon-chain/core/gloas"
"github.com/OffchainLabs/prysm/v7/beacon-chain/operations/payloadattestation"
"github.com/OffchainLabs/prysm/v7/consensus-types/primitives"
ethpb "github.com/OffchainLabs/prysm/v7/proto/prysm/v1alpha1"
@@ -33,8 +32,8 @@ func TestPayloadAttestationSubscriber_NilData(t *testing.T) {
}
func TestPayloadAttestationSubscriber_NoPool(t *testing.T) {
- st, _ := util.DeterministicGenesisState(t, 64)
- ptc, err := gloas.PayloadCommittee(t.Context(), st, 0)
+ st, _ := util.DeterministicGenesisStateGloas(t, 64)
+ ptc, err := st.PayloadCommitteeReadOnly(0)
require.NoError(t, err)
require.NotEmpty(t, ptc)
@@ -81,8 +80,8 @@ func TestPayloadAttestationSubscriber_HeadStateError(t *testing.T) {
}
func TestPayloadAttestationSubscriber_ValidatorInPTC(t *testing.T) {
- st, _ := util.DeterministicGenesisState(t, 64)
- ptc, err := gloas.PayloadCommittee(t.Context(), st, 0)
+ st, _ := util.DeterministicGenesisStateGloas(t, 64)
+ ptc, err := st.PayloadCommitteeReadOnly(0)
require.NoError(t, err)
require.NotEmpty(t, ptc)
@@ -108,8 +107,8 @@ func TestPayloadAttestationSubscriber_ValidatorInPTC(t *testing.T) {
}
func TestPayloadAttestationSubscriber_ValidatorNotInPTC(t *testing.T) {
- st, _ := util.DeterministicGenesisState(t, 64)
- ptc, err := gloas.PayloadCommittee(t.Context(), st, 0)
+ st, _ := util.DeterministicGenesisStateGloas(t, 64)
+ ptc, err := st.PayloadCommitteeReadOnly(0)
require.NoError(t, err)
ptcSet := make(map[primitives.ValidatorIndex]bool, len(ptc))
diff --git a/changelog/terence_gloas-cached-ptc-window.md b/changelog/terence_gloas-cached-ptc-window.md
new file mode 100644
index 000000000000..3f4a040b1747
--- /dev/null
+++ b/changelog/terence_gloas-cached-ptc-window.md
@@ -0,0 +1,3 @@
+### Changed
+
+- Implement the Gloas cached payload timeliness committee window in state, including fork initialization, epoch rotation, and cached committee lookups.
diff --git a/config/params/loader_test.go b/config/params/loader_test.go
index e36a1e1a90a7..ea2e997698be 100644
--- a/config/params/loader_test.go
+++ b/config/params/loader_test.go
@@ -31,31 +31,24 @@ var placeholderFields = []string{
"EIP6110_FORK_VERSION",
"EIP7002_FORK_EPOCH",
"EIP7002_FORK_VERSION",
- "EIP7441_FORK_EPOCH",
- "EIP7441_FORK_VERSION",
"EIP7732_FORK_EPOCH",
"EIP7732_FORK_VERSION",
- "EIP7805_FORK_EPOCH",
- "EIP7805_FORK_VERSION",
"EIP7928_FORK_EPOCH",
"EIP7928_FORK_VERSION",
- "EPOCHS_PER_SHUFFLING_PHASE",
"FIELD_ELEMENTS_PER_CELL", // Configured as a constant in config/fieldparams/mainnet.go
"FIELD_ELEMENTS_PER_EXT_BLOB", // Configured in proto/ssz_proto_library.bzl
- "INCLUSION_LIST_SUBMISSION_DEADLINE",
+ "HEZE_FORK_EPOCH",
+ "HEZE_FORK_VERSION",
+ "INCLUSION_LIST_COMMITTEE_SIZE",
"INCLUSION_LIST_SUBMISSION_DUE_BPS",
"KZG_COMMITMENTS_INCLUSION_PROOF_DEPTH", // Configured in proto/ssz_proto_library.bzl
"MAX_BYTES_PER_INCLUSION_LIST",
- "MAX_REQUEST_BLOB_SIDECARS_FULU",
"MAX_REQUEST_INCLUSION_LIST",
"NUMBER_OF_COLUMNS", // Configured as a constant in config/fieldparams/mainnet.go
- "PROPOSER_INCLUSION_LIST_CUTOFF",
"PROPOSER_INCLUSION_LIST_CUTOFF_BPS",
- "PROPOSER_SELECTION_GAP",
"TARGET_NUMBER_OF_PEERS",
"UPDATE_TIMEOUT",
"VIEW_FREEZE_CUTOFF_BPS",
- "VIEW_FREEZE_DEADLINE",
"WHISK_EPOCHS_PER_SHUFFLING_PHASE",
"WHISK_FORK_EPOCH",
"WHISK_FORK_VERSION",
diff --git a/config/params/mainnet_config.go b/config/params/mainnet_config.go
index 8d2ccb4eedd5..04ad7dc43a7b 100644
--- a/config/params/mainnet_config.go
+++ b/config/params/mainnet_config.go
@@ -220,7 +220,7 @@ var mainnetBeaconConfig = &BeaconChainConfig{
BeaconStateDenebFieldCount: 28,
BeaconStateElectraFieldCount: 37,
BeaconStateFuluFieldCount: 38,
- BeaconStateGloasFieldCount: 45,
+ BeaconStateGloasFieldCount: 46,
// Slasher related values.
WeakSubjectivityPeriod: 54000,
diff --git a/proto/prysm/v1alpha1/BUILD.bazel b/proto/prysm/v1alpha1/BUILD.bazel
index 07d1b566349c..29b4f8a0b2ac 100644
--- a/proto/prysm/v1alpha1/BUILD.bazel
+++ b/proto/prysm/v1alpha1/BUILD.bazel
@@ -201,6 +201,7 @@ ssz_gloas_objs = [
"BuilderPendingWithdrawal",
"DataColumnSidecarGloas",
"ExecutionPayloadEnvelope",
+ "PTCs",
"ProposerPreferences",
"SignedProposerPreferences",
"PayloadAttestation",
diff --git a/proto/prysm/v1alpha1/cloners.go b/proto/prysm/v1alpha1/cloners.go
index 0a2681e78e25..4c69ffdcdfaa 100644
--- a/proto/prysm/v1alpha1/cloners.go
+++ b/proto/prysm/v1alpha1/cloners.go
@@ -1,6 +1,7 @@
package eth
import (
+ "github.com/OffchainLabs/prysm/v7/consensus-types/primitives"
"github.com/OffchainLabs/prysm/v7/encoding/bytesutil"
)
@@ -245,6 +246,28 @@ func copyBlindedExecutionPayloadEnvelope(env *BlindedExecutionPayloadEnvelope) *
}
}
+// CopyPTCs creates a deep copy of a PTC slot.
+func CopyPTCs(slot *PTCs) *PTCs {
+ if slot == nil {
+ return nil
+ }
+ indices := make([]primitives.ValidatorIndex, len(slot.ValidatorIndices))
+ copy(indices, slot.ValidatorIndices)
+ return &PTCs{ValidatorIndices: indices}
+}
+
+// CopyPTCWindow creates a deep copy of a PTC window.
+func CopyPTCWindow(window []*PTCs) []*PTCs {
+ if window == nil {
+ return nil
+ }
+ copied := make([]*PTCs, len(window))
+ for i, slot := range window {
+ copied[i] = CopyPTCs(slot)
+ }
+ return copied
+}
+
// CopyBuilderPendingPayment creates a deep copy of a builder pending payment.
func CopyBuilderPendingPayment(original *BuilderPendingPayment) *BuilderPendingPayment {
if original == nil {
diff --git a/proto/prysm/v1alpha1/gloas.pb.go b/proto/prysm/v1alpha1/gloas.pb.go
index 07d18b7ea04c..81db34a72c60 100755
--- a/proto/prysm/v1alpha1/gloas.pb.go
+++ b/proto/prysm/v1alpha1/gloas.pb.go
@@ -860,6 +860,7 @@ type BeaconStateGloas struct {
BuilderPendingWithdrawals []*BuilderPendingWithdrawal `protobuf:"bytes,14005,rep,name=builder_pending_withdrawals,json=builderPendingWithdrawals,proto3" json:"builder_pending_withdrawals,omitempty" ssz-max:"1048576"`
LatestBlockHash []byte `protobuf:"bytes,14006,opt,name=latest_block_hash,json=latestBlockHash,proto3" json:"latest_block_hash,omitempty" ssz-size:"32"`
PayloadExpectedWithdrawals []*v1.Withdrawal `protobuf:"bytes,14007,rep,name=payload_expected_withdrawals,json=payloadExpectedWithdrawals,proto3" json:"payload_expected_withdrawals,omitempty" ssz-max:"16"`
+ PtcWindow []*PTCs `protobuf:"bytes,14008,rep,name=ptc_window,json=ptcWindow,proto3" json:"ptc_window,omitempty" ssz-size:"96"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
@@ -1209,6 +1210,57 @@ func (x *BeaconStateGloas) GetPayloadExpectedWithdrawals() []*v1.Withdrawal {
return nil
}
+func (x *BeaconStateGloas) GetPtcWindow() []*PTCs {
+ if x != nil {
+ return x.PtcWindow
+ }
+ return nil
+}
+
+type PTCs struct {
+ state protoimpl.MessageState `protogen:"open.v1"`
+ ValidatorIndices []github_com_OffchainLabs_prysm_v7_consensus_types_primitives.ValidatorIndex `protobuf:"varint,1,rep,packed,name=validator_indices,json=validatorIndices,proto3" json:"validator_indices,omitempty" cast-type:"github.com/OffchainLabs/prysm/v7/consensus-types/primitives.ValidatorIndex" ssz-size:"512"`
+ unknownFields protoimpl.UnknownFields
+ sizeCache protoimpl.SizeCache
+}
+
+func (x *PTCs) Reset() {
+ *x = PTCs{}
+ mi := &file_proto_prysm_v1alpha1_gloas_proto_msgTypes[12]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+}
+
+func (x *PTCs) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*PTCs) ProtoMessage() {}
+
+func (x *PTCs) ProtoReflect() protoreflect.Message {
+ mi := &file_proto_prysm_v1alpha1_gloas_proto_msgTypes[12]
+ if x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use PTCs.ProtoReflect.Descriptor instead.
+func (*PTCs) Descriptor() ([]byte, []int) {
+ return file_proto_prysm_v1alpha1_gloas_proto_rawDescGZIP(), []int{12}
+}
+
+func (x *PTCs) GetValidatorIndices() []github_com_OffchainLabs_prysm_v7_consensus_types_primitives.ValidatorIndex {
+ if x != nil {
+ return x.ValidatorIndices
+ }
+ return []github_com_OffchainLabs_prysm_v7_consensus_types_primitives.ValidatorIndex(nil)
+}
+
type BuilderPendingPayment struct {
state protoimpl.MessageState `protogen:"open.v1"`
Weight github_com_OffchainLabs_prysm_v7_consensus_types_primitives.Gwei `protobuf:"varint,1,opt,name=weight,proto3" json:"weight,omitempty" cast-type:"github.com/OffchainLabs/prysm/v7/consensus-types/primitives.Gwei"`
@@ -1219,7 +1271,7 @@ type BuilderPendingPayment struct {
func (x *BuilderPendingPayment) Reset() {
*x = BuilderPendingPayment{}
- mi := &file_proto_prysm_v1alpha1_gloas_proto_msgTypes[12]
+ mi := &file_proto_prysm_v1alpha1_gloas_proto_msgTypes[13]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -1231,7 +1283,7 @@ func (x *BuilderPendingPayment) String() string {
func (*BuilderPendingPayment) ProtoMessage() {}
func (x *BuilderPendingPayment) ProtoReflect() protoreflect.Message {
- mi := &file_proto_prysm_v1alpha1_gloas_proto_msgTypes[12]
+ mi := &file_proto_prysm_v1alpha1_gloas_proto_msgTypes[13]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -1244,7 +1296,7 @@ func (x *BuilderPendingPayment) ProtoReflect() protoreflect.Message {
// Deprecated: Use BuilderPendingPayment.ProtoReflect.Descriptor instead.
func (*BuilderPendingPayment) Descriptor() ([]byte, []int) {
- return file_proto_prysm_v1alpha1_gloas_proto_rawDescGZIP(), []int{12}
+ return file_proto_prysm_v1alpha1_gloas_proto_rawDescGZIP(), []int{13}
}
func (x *BuilderPendingPayment) GetWeight() github_com_OffchainLabs_prysm_v7_consensus_types_primitives.Gwei {
@@ -1272,7 +1324,7 @@ type BuilderPendingWithdrawal struct {
func (x *BuilderPendingWithdrawal) Reset() {
*x = BuilderPendingWithdrawal{}
- mi := &file_proto_prysm_v1alpha1_gloas_proto_msgTypes[13]
+ mi := &file_proto_prysm_v1alpha1_gloas_proto_msgTypes[14]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -1284,7 +1336,7 @@ func (x *BuilderPendingWithdrawal) String() string {
func (*BuilderPendingWithdrawal) ProtoMessage() {}
func (x *BuilderPendingWithdrawal) ProtoReflect() protoreflect.Message {
- mi := &file_proto_prysm_v1alpha1_gloas_proto_msgTypes[13]
+ mi := &file_proto_prysm_v1alpha1_gloas_proto_msgTypes[14]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -1297,7 +1349,7 @@ func (x *BuilderPendingWithdrawal) ProtoReflect() protoreflect.Message {
// Deprecated: Use BuilderPendingWithdrawal.ProtoReflect.Descriptor instead.
func (*BuilderPendingWithdrawal) Descriptor() ([]byte, []int) {
- return file_proto_prysm_v1alpha1_gloas_proto_rawDescGZIP(), []int{13}
+ return file_proto_prysm_v1alpha1_gloas_proto_rawDescGZIP(), []int{14}
}
func (x *BuilderPendingWithdrawal) GetFeeRecipient() []byte {
@@ -1334,7 +1386,7 @@ type DataColumnSidecarGloas struct {
func (x *DataColumnSidecarGloas) Reset() {
*x = DataColumnSidecarGloas{}
- mi := &file_proto_prysm_v1alpha1_gloas_proto_msgTypes[14]
+ mi := &file_proto_prysm_v1alpha1_gloas_proto_msgTypes[15]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -1346,7 +1398,7 @@ func (x *DataColumnSidecarGloas) String() string {
func (*DataColumnSidecarGloas) ProtoMessage() {}
func (x *DataColumnSidecarGloas) ProtoReflect() protoreflect.Message {
- mi := &file_proto_prysm_v1alpha1_gloas_proto_msgTypes[14]
+ mi := &file_proto_prysm_v1alpha1_gloas_proto_msgTypes[15]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -1359,7 +1411,7 @@ func (x *DataColumnSidecarGloas) ProtoReflect() protoreflect.Message {
// Deprecated: Use DataColumnSidecarGloas.ProtoReflect.Descriptor instead.
func (*DataColumnSidecarGloas) Descriptor() ([]byte, []int) {
- return file_proto_prysm_v1alpha1_gloas_proto_rawDescGZIP(), []int{14}
+ return file_proto_prysm_v1alpha1_gloas_proto_rawDescGZIP(), []int{15}
}
func (x *DataColumnSidecarGloas) GetIndex() uint64 {
@@ -1411,7 +1463,7 @@ type ExecutionPayloadEnvelope struct {
func (x *ExecutionPayloadEnvelope) Reset() {
*x = ExecutionPayloadEnvelope{}
- mi := &file_proto_prysm_v1alpha1_gloas_proto_msgTypes[15]
+ mi := &file_proto_prysm_v1alpha1_gloas_proto_msgTypes[16]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -1423,7 +1475,7 @@ func (x *ExecutionPayloadEnvelope) String() string {
func (*ExecutionPayloadEnvelope) ProtoMessage() {}
func (x *ExecutionPayloadEnvelope) ProtoReflect() protoreflect.Message {
- mi := &file_proto_prysm_v1alpha1_gloas_proto_msgTypes[15]
+ mi := &file_proto_prysm_v1alpha1_gloas_proto_msgTypes[16]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -1436,7 +1488,7 @@ func (x *ExecutionPayloadEnvelope) ProtoReflect() protoreflect.Message {
// Deprecated: Use ExecutionPayloadEnvelope.ProtoReflect.Descriptor instead.
func (*ExecutionPayloadEnvelope) Descriptor() ([]byte, []int) {
- return file_proto_prysm_v1alpha1_gloas_proto_rawDescGZIP(), []int{15}
+ return file_proto_prysm_v1alpha1_gloas_proto_rawDescGZIP(), []int{16}
}
func (x *ExecutionPayloadEnvelope) GetPayload() *v1.ExecutionPayloadDeneb {
@@ -1491,7 +1543,7 @@ type SignedExecutionPayloadEnvelope struct {
func (x *SignedExecutionPayloadEnvelope) Reset() {
*x = SignedExecutionPayloadEnvelope{}
- mi := &file_proto_prysm_v1alpha1_gloas_proto_msgTypes[16]
+ mi := &file_proto_prysm_v1alpha1_gloas_proto_msgTypes[17]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -1503,7 +1555,7 @@ func (x *SignedExecutionPayloadEnvelope) String() string {
func (*SignedExecutionPayloadEnvelope) ProtoMessage() {}
func (x *SignedExecutionPayloadEnvelope) ProtoReflect() protoreflect.Message {
- mi := &file_proto_prysm_v1alpha1_gloas_proto_msgTypes[16]
+ mi := &file_proto_prysm_v1alpha1_gloas_proto_msgTypes[17]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -1516,7 +1568,7 @@ func (x *SignedExecutionPayloadEnvelope) ProtoReflect() protoreflect.Message {
// Deprecated: Use SignedExecutionPayloadEnvelope.ProtoReflect.Descriptor instead.
func (*SignedExecutionPayloadEnvelope) Descriptor() ([]byte, []int) {
- return file_proto_prysm_v1alpha1_gloas_proto_rawDescGZIP(), []int{16}
+ return file_proto_prysm_v1alpha1_gloas_proto_rawDescGZIP(), []int{17}
}
func (x *SignedExecutionPayloadEnvelope) GetMessage() *ExecutionPayloadEnvelope {
@@ -1548,7 +1600,7 @@ type BlindedExecutionPayloadEnvelope struct {
func (x *BlindedExecutionPayloadEnvelope) Reset() {
*x = BlindedExecutionPayloadEnvelope{}
- mi := &file_proto_prysm_v1alpha1_gloas_proto_msgTypes[17]
+ mi := &file_proto_prysm_v1alpha1_gloas_proto_msgTypes[18]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -1560,7 +1612,7 @@ func (x *BlindedExecutionPayloadEnvelope) String() string {
func (*BlindedExecutionPayloadEnvelope) ProtoMessage() {}
func (x *BlindedExecutionPayloadEnvelope) ProtoReflect() protoreflect.Message {
- mi := &file_proto_prysm_v1alpha1_gloas_proto_msgTypes[17]
+ mi := &file_proto_prysm_v1alpha1_gloas_proto_msgTypes[18]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -1573,7 +1625,7 @@ func (x *BlindedExecutionPayloadEnvelope) ProtoReflect() protoreflect.Message {
// Deprecated: Use BlindedExecutionPayloadEnvelope.ProtoReflect.Descriptor instead.
func (*BlindedExecutionPayloadEnvelope) Descriptor() ([]byte, []int) {
- return file_proto_prysm_v1alpha1_gloas_proto_rawDescGZIP(), []int{17}
+ return file_proto_prysm_v1alpha1_gloas_proto_rawDescGZIP(), []int{18}
}
func (x *BlindedExecutionPayloadEnvelope) GetBlockHash() []byte {
@@ -1635,7 +1687,7 @@ type SignedBlindedExecutionPayloadEnvelope struct {
func (x *SignedBlindedExecutionPayloadEnvelope) Reset() {
*x = SignedBlindedExecutionPayloadEnvelope{}
- mi := &file_proto_prysm_v1alpha1_gloas_proto_msgTypes[18]
+ mi := &file_proto_prysm_v1alpha1_gloas_proto_msgTypes[19]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -1647,7 +1699,7 @@ func (x *SignedBlindedExecutionPayloadEnvelope) String() string {
func (*SignedBlindedExecutionPayloadEnvelope) ProtoMessage() {}
func (x *SignedBlindedExecutionPayloadEnvelope) ProtoReflect() protoreflect.Message {
- mi := &file_proto_prysm_v1alpha1_gloas_proto_msgTypes[18]
+ mi := &file_proto_prysm_v1alpha1_gloas_proto_msgTypes[19]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -1660,7 +1712,7 @@ func (x *SignedBlindedExecutionPayloadEnvelope) ProtoReflect() protoreflect.Mess
// Deprecated: Use SignedBlindedExecutionPayloadEnvelope.ProtoReflect.Descriptor instead.
func (*SignedBlindedExecutionPayloadEnvelope) Descriptor() ([]byte, []int) {
- return file_proto_prysm_v1alpha1_gloas_proto_rawDescGZIP(), []int{18}
+ return file_proto_prysm_v1alpha1_gloas_proto_rawDescGZIP(), []int{19}
}
func (x *SignedBlindedExecutionPayloadEnvelope) GetMessage() *BlindedExecutionPayloadEnvelope {
@@ -1691,7 +1743,7 @@ type Builder struct {
func (x *Builder) Reset() {
*x = Builder{}
- mi := &file_proto_prysm_v1alpha1_gloas_proto_msgTypes[19]
+ mi := &file_proto_prysm_v1alpha1_gloas_proto_msgTypes[20]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -1703,7 +1755,7 @@ func (x *Builder) String() string {
func (*Builder) ProtoMessage() {}
func (x *Builder) ProtoReflect() protoreflect.Message {
- mi := &file_proto_prysm_v1alpha1_gloas_proto_msgTypes[19]
+ mi := &file_proto_prysm_v1alpha1_gloas_proto_msgTypes[20]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -1716,7 +1768,7 @@ func (x *Builder) ProtoReflect() protoreflect.Message {
// Deprecated: Use Builder.ProtoReflect.Descriptor instead.
func (*Builder) Descriptor() ([]byte, []int) {
- return file_proto_prysm_v1alpha1_gloas_proto_rawDescGZIP(), []int{19}
+ return file_proto_prysm_v1alpha1_gloas_proto_rawDescGZIP(), []int{20}
}
func (x *Builder) GetPubkey() []byte {
@@ -2020,7 +2072,7 @@ var file_proto_prysm_v1alpha1_gloas_proto_rawDesc = []byte{
0x2e, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x47, 0x6c, 0x6f, 0x61,
0x73, 0x52, 0x05, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x24, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e,
0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x06, 0x8a, 0xb5, 0x18,
- 0x02, 0x39, 0x36, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x22, 0xa0,
+ 0x02, 0x39, 0x36, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x22, 0xe5,
0x1f, 0x0a, 0x10, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x47, 0x6c,
0x6f, 0x61, 0x73, 0x12, 0x22, 0x0a, 0x0c, 0x67, 0x65, 0x6e, 0x65, 0x73, 0x69, 0x73, 0x5f, 0x74,
0x69, 0x6d, 0x65, 0x18, 0xe9, 0x07, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x67, 0x65, 0x6e, 0x65,
@@ -2271,61 +2323,112 @@ var file_proto_prysm_v1alpha1_gloas_proto_rawDesc = []byte{
0x76, 0x31, 0x2e, 0x57, 0x69, 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, 0x61, 0x6c, 0x42, 0x06, 0x92,
0xb5, 0x18, 0x02, 0x31, 0x36, 0x52, 0x1a, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x45, 0x78,
0x70, 0x65, 0x63, 0x74, 0x65, 0x64, 0x57, 0x69, 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, 0x61, 0x6c,
- 0x73, 0x22, 0xc6, 0x01, 0x0a, 0x15, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x65, 0x72, 0x50, 0x65, 0x6e,
- 0x64, 0x69, 0x6e, 0x67, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x5c, 0x0a, 0x06, 0x77,
- 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x42, 0x44, 0x82, 0xb5, 0x18,
- 0x40, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x4f, 0x66, 0x66, 0x63,
+ 0x73, 0x12, 0x43, 0x0a, 0x0a, 0x70, 0x74, 0x63, 0x5f, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x18,
+ 0xb8, 0x6d, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75,
+ 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x50,
+ 0x54, 0x43, 0x73, 0x42, 0x06, 0x8a, 0xb5, 0x18, 0x02, 0x39, 0x36, 0x52, 0x09, 0x70, 0x74, 0x63,
+ 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x22, 0x8b, 0x01, 0x0a, 0x04, 0x50, 0x54, 0x43, 0x73, 0x12,
+ 0x82, 0x01, 0x0a, 0x11, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x5f, 0x69, 0x6e,
+ 0x64, 0x69, 0x63, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x04, 0x42, 0x55, 0x82, 0xb5, 0x18,
+ 0x4a, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x4f, 0x66, 0x66, 0x63,
0x68, 0x61, 0x69, 0x6e, 0x4c, 0x61, 0x62, 0x73, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x2f, 0x76,
0x37, 0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x65, 0x6e, 0x73, 0x75, 0x73, 0x2d, 0x74, 0x79, 0x70, 0x65,
- 0x73, 0x2f, 0x70, 0x72, 0x69, 0x6d, 0x69, 0x74, 0x69, 0x76, 0x65, 0x73, 0x2e, 0x47, 0x77, 0x65,
- 0x69, 0x52, 0x06, 0x77, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x4f, 0x0a, 0x0a, 0x77, 0x69, 0x74,
- 0x68, 0x64, 0x72, 0x61, 0x77, 0x61, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2f, 0x2e,
- 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61,
- 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x65, 0x72, 0x50, 0x65, 0x6e,
- 0x64, 0x69, 0x6e, 0x67, 0x57, 0x69, 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, 0x61, 0x6c, 0x52, 0x0a,
- 0x77, 0x69, 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, 0x61, 0x6c, 0x22, 0x98, 0x02, 0x0a, 0x18, 0x42,
- 0x75, 0x69, 0x6c, 0x64, 0x65, 0x72, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x57, 0x69, 0x74,
- 0x68, 0x64, 0x72, 0x61, 0x77, 0x61, 0x6c, 0x12, 0x2b, 0x0a, 0x0d, 0x66, 0x65, 0x65, 0x5f, 0x72,
- 0x65, 0x63, 0x69, 0x70, 0x69, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x06,
- 0x8a, 0xb5, 0x18, 0x02, 0x32, 0x30, 0x52, 0x0c, 0x66, 0x65, 0x65, 0x52, 0x65, 0x63, 0x69, 0x70,
- 0x69, 0x65, 0x6e, 0x74, 0x12, 0x5c, 0x0a, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x02,
+ 0x73, 0x2f, 0x70, 0x72, 0x69, 0x6d, 0x69, 0x74, 0x69, 0x76, 0x65, 0x73, 0x2e, 0x56, 0x61, 0x6c,
+ 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x8a, 0xb5, 0x18, 0x03, 0x35,
+ 0x31, 0x32, 0x52, 0x10, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x49, 0x6e, 0x64,
+ 0x69, 0x63, 0x65, 0x73, 0x22, 0xc6, 0x01, 0x0a, 0x15, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x65, 0x72,
+ 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x5c,
+ 0x0a, 0x06, 0x77, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x42, 0x44,
+ 0x82, 0xb5, 0x18, 0x40, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x4f,
+ 0x66, 0x66, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x4c, 0x61, 0x62, 0x73, 0x2f, 0x70, 0x72, 0x79, 0x73,
+ 0x6d, 0x2f, 0x76, 0x37, 0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x65, 0x6e, 0x73, 0x75, 0x73, 0x2d, 0x74,
+ 0x79, 0x70, 0x65, 0x73, 0x2f, 0x70, 0x72, 0x69, 0x6d, 0x69, 0x74, 0x69, 0x76, 0x65, 0x73, 0x2e,
+ 0x47, 0x77, 0x65, 0x69, 0x52, 0x06, 0x77, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x4f, 0x0a, 0x0a,
+ 0x77, 0x69, 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, 0x61, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b,
+ 0x32, 0x2f, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e,
+ 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x65, 0x72,
+ 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x57, 0x69, 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, 0x61,
+ 0x6c, 0x52, 0x0a, 0x77, 0x69, 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, 0x61, 0x6c, 0x22, 0x98, 0x02,
+ 0x0a, 0x18, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x65, 0x72, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67,
+ 0x57, 0x69, 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, 0x61, 0x6c, 0x12, 0x2b, 0x0a, 0x0d, 0x66, 0x65,
+ 0x65, 0x5f, 0x72, 0x65, 0x63, 0x69, 0x70, 0x69, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28,
+ 0x0c, 0x42, 0x06, 0x8a, 0xb5, 0x18, 0x02, 0x32, 0x30, 0x52, 0x0c, 0x66, 0x65, 0x65, 0x52, 0x65,
+ 0x63, 0x69, 0x70, 0x69, 0x65, 0x6e, 0x74, 0x12, 0x5c, 0x0a, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e,
+ 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x42, 0x44, 0x82, 0xb5, 0x18, 0x40, 0x67, 0x69, 0x74,
+ 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x4f, 0x66, 0x66, 0x63, 0x68, 0x61, 0x69, 0x6e,
+ 0x4c, 0x61, 0x62, 0x73, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x2f, 0x76, 0x37, 0x2f, 0x63, 0x6f,
+ 0x6e, 0x73, 0x65, 0x6e, 0x73, 0x75, 0x73, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2f, 0x70, 0x72,
+ 0x69, 0x6d, 0x69, 0x74, 0x69, 0x76, 0x65, 0x73, 0x2e, 0x47, 0x77, 0x65, 0x69, 0x52, 0x06, 0x61,
+ 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x71, 0x0a, 0x0d, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x65, 0x72,
+ 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x42, 0x4c, 0x82, 0xb5,
+ 0x18, 0x48, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x4f, 0x66, 0x66,
+ 0x63, 0x68, 0x61, 0x69, 0x6e, 0x4c, 0x61, 0x62, 0x73, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x2f,
+ 0x76, 0x37, 0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x65, 0x6e, 0x73, 0x75, 0x73, 0x2d, 0x74, 0x79, 0x70,
+ 0x65, 0x73, 0x2f, 0x70, 0x72, 0x69, 0x6d, 0x69, 0x74, 0x69, 0x76, 0x65, 0x73, 0x2e, 0x42, 0x75,
+ 0x69, 0x6c, 0x64, 0x65, 0x72, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x52, 0x0c, 0x62, 0x75, 0x69, 0x6c,
+ 0x64, 0x65, 0x72, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x22, 0x99, 0x02, 0x0a, 0x16, 0x44, 0x61, 0x74,
+ 0x61, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x53, 0x69, 0x64, 0x65, 0x63, 0x61, 0x72, 0x47, 0x6c,
+ 0x6f, 0x61, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x01, 0x20, 0x01,
+ 0x28, 0x04, 0x52, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x2a, 0x0a, 0x06, 0x63, 0x6f, 0x6c,
+ 0x75, 0x6d, 0x6e, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0c, 0x42, 0x12, 0x8a, 0xb5, 0x18, 0x06, 0x3f,
+ 0x2c, 0x32, 0x30, 0x34, 0x38, 0x92, 0xb5, 0x18, 0x04, 0x34, 0x30, 0x39, 0x36, 0x52, 0x06, 0x63,
+ 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x12, 0x2f, 0x0a, 0x0a, 0x6b, 0x7a, 0x67, 0x5f, 0x70, 0x72, 0x6f,
+ 0x6f, 0x66, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0c, 0x42, 0x10, 0x8a, 0xb5, 0x18, 0x04, 0x3f,
+ 0x2c, 0x34, 0x38, 0x92, 0xb5, 0x18, 0x04, 0x34, 0x30, 0x39, 0x36, 0x52, 0x09, 0x6b, 0x7a, 0x67,
+ 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x73, 0x12, 0x58, 0x0a, 0x04, 0x73, 0x6c, 0x6f, 0x74, 0x18, 0x05,
0x20, 0x01, 0x28, 0x04, 0x42, 0x44, 0x82, 0xb5, 0x18, 0x40, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62,
0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x4f, 0x66, 0x66, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x4c, 0x61, 0x62,
0x73, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x2f, 0x76, 0x37, 0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x65,
0x6e, 0x73, 0x75, 0x73, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2f, 0x70, 0x72, 0x69, 0x6d, 0x69,
- 0x74, 0x69, 0x76, 0x65, 0x73, 0x2e, 0x47, 0x77, 0x65, 0x69, 0x52, 0x06, 0x61, 0x6d, 0x6f, 0x75,
- 0x6e, 0x74, 0x12, 0x71, 0x0a, 0x0d, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x65, 0x72, 0x5f, 0x69, 0x6e,
- 0x64, 0x65, 0x78, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x42, 0x4c, 0x82, 0xb5, 0x18, 0x48, 0x67,
- 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x4f, 0x66, 0x66, 0x63, 0x68, 0x61,
- 0x69, 0x6e, 0x4c, 0x61, 0x62, 0x73, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x2f, 0x76, 0x37, 0x2f,
- 0x63, 0x6f, 0x6e, 0x73, 0x65, 0x6e, 0x73, 0x75, 0x73, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2f,
- 0x70, 0x72, 0x69, 0x6d, 0x69, 0x74, 0x69, 0x76, 0x65, 0x73, 0x2e, 0x42, 0x75, 0x69, 0x6c, 0x64,
- 0x65, 0x72, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x52, 0x0c, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x65, 0x72,
- 0x49, 0x6e, 0x64, 0x65, 0x78, 0x22, 0x99, 0x02, 0x0a, 0x16, 0x44, 0x61, 0x74, 0x61, 0x43, 0x6f,
- 0x6c, 0x75, 0x6d, 0x6e, 0x53, 0x69, 0x64, 0x65, 0x63, 0x61, 0x72, 0x47, 0x6c, 0x6f, 0x61, 0x73,
- 0x12, 0x14, 0x0a, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52,
- 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x2a, 0x0a, 0x06, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e,
- 0x18, 0x02, 0x20, 0x03, 0x28, 0x0c, 0x42, 0x12, 0x8a, 0xb5, 0x18, 0x06, 0x3f, 0x2c, 0x32, 0x30,
- 0x34, 0x38, 0x92, 0xb5, 0x18, 0x04, 0x34, 0x30, 0x39, 0x36, 0x52, 0x06, 0x63, 0x6f, 0x6c, 0x75,
- 0x6d, 0x6e, 0x12, 0x2f, 0x0a, 0x0a, 0x6b, 0x7a, 0x67, 0x5f, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x73,
- 0x18, 0x04, 0x20, 0x03, 0x28, 0x0c, 0x42, 0x10, 0x8a, 0xb5, 0x18, 0x04, 0x3f, 0x2c, 0x34, 0x38,
- 0x92, 0xb5, 0x18, 0x04, 0x34, 0x30, 0x39, 0x36, 0x52, 0x09, 0x6b, 0x7a, 0x67, 0x50, 0x72, 0x6f,
- 0x6f, 0x66, 0x73, 0x12, 0x58, 0x0a, 0x04, 0x73, 0x6c, 0x6f, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28,
+ 0x74, 0x69, 0x76, 0x65, 0x73, 0x2e, 0x53, 0x6c, 0x6f, 0x74, 0x52, 0x04, 0x73, 0x6c, 0x6f, 0x74,
+ 0x12, 0x32, 0x0a, 0x11, 0x62, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b,
+ 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x06, 0x8a, 0xb5, 0x18,
+ 0x02, 0x33, 0x32, 0x52, 0x0f, 0x62, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x42, 0x6c, 0x6f, 0x63, 0x6b,
+ 0x52, 0x6f, 0x6f, 0x74, 0x22, 0xdd, 0x03, 0x0a, 0x18, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69,
+ 0x6f, 0x6e, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x45, 0x6e, 0x76, 0x65, 0x6c, 0x6f, 0x70,
+ 0x65, 0x12, 0x43, 0x0a, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x01, 0x20, 0x01,
+ 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x6e,
+ 0x67, 0x69, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f,
+ 0x6e, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x44, 0x65, 0x6e, 0x65, 0x62, 0x52, 0x07, 0x70,
+ 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x54, 0x0a, 0x12, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74,
+ 0x69, 0x6f, 0x6e, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x18, 0x02, 0x20, 0x01,
+ 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x6e,
+ 0x67, 0x69, 0x6e, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f,
+ 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x52, 0x11, 0x65, 0x78, 0x65, 0x63, 0x75,
+ 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x12, 0x71, 0x0a, 0x0d,
+ 0x62, 0x75, 0x69, 0x6c, 0x64, 0x65, 0x72, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x03, 0x20,
+ 0x01, 0x28, 0x04, 0x42, 0x4c, 0x82, 0xb5, 0x18, 0x48, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e,
+ 0x63, 0x6f, 0x6d, 0x2f, 0x4f, 0x66, 0x66, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x4c, 0x61, 0x62, 0x73,
+ 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x2f, 0x76, 0x37, 0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x65, 0x6e,
+ 0x73, 0x75, 0x73, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2f, 0x70, 0x72, 0x69, 0x6d, 0x69, 0x74,
+ 0x69, 0x76, 0x65, 0x73, 0x2e, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x65, 0x72, 0x49, 0x6e, 0x64, 0x65,
+ 0x78, 0x52, 0x0c, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x65, 0x72, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12,
+ 0x32, 0x0a, 0x11, 0x62, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f,
+ 0x72, 0x6f, 0x6f, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x06, 0x8a, 0xb5, 0x18, 0x02,
+ 0x33, 0x32, 0x52, 0x0f, 0x62, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52,
+ 0x6f, 0x6f, 0x74, 0x12, 0x58, 0x0a, 0x04, 0x73, 0x6c, 0x6f, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28,
0x04, 0x42, 0x44, 0x82, 0xb5, 0x18, 0x40, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f,
0x6d, 0x2f, 0x4f, 0x66, 0x66, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x4c, 0x61, 0x62, 0x73, 0x2f, 0x70,
0x72, 0x79, 0x73, 0x6d, 0x2f, 0x76, 0x37, 0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x65, 0x6e, 0x73, 0x75,
0x73, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2f, 0x70, 0x72, 0x69, 0x6d, 0x69, 0x74, 0x69, 0x76,
- 0x65, 0x73, 0x2e, 0x53, 0x6c, 0x6f, 0x74, 0x52, 0x04, 0x73, 0x6c, 0x6f, 0x74, 0x12, 0x32, 0x0a,
- 0x11, 0x62, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x72, 0x6f,
- 0x6f, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x06, 0x8a, 0xb5, 0x18, 0x02, 0x33, 0x32,
- 0x52, 0x0f, 0x62, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x6f, 0x6f,
- 0x74, 0x22, 0xdd, 0x03, 0x0a, 0x18, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x50,
- 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x45, 0x6e, 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x65, 0x12, 0x43,
- 0x0a, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32,
- 0x29, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x6e, 0x67, 0x69, 0x6e,
- 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x61,
- 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x44, 0x65, 0x6e, 0x65, 0x62, 0x52, 0x07, 0x70, 0x61, 0x79, 0x6c,
- 0x6f, 0x61, 0x64, 0x12, 0x54, 0x0a, 0x12, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e,
+ 0x65, 0x73, 0x2e, 0x53, 0x6c, 0x6f, 0x74, 0x52, 0x04, 0x73, 0x6c, 0x6f, 0x74, 0x12, 0x25, 0x0a,
+ 0x0a, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28,
+ 0x0c, 0x42, 0x06, 0x8a, 0xb5, 0x18, 0x02, 0x33, 0x32, 0x52, 0x09, 0x73, 0x74, 0x61, 0x74, 0x65,
+ 0x52, 0x6f, 0x6f, 0x74, 0x22, 0x91, 0x01, 0x0a, 0x1e, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x45,
+ 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x45,
+ 0x6e, 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x65, 0x12, 0x49, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61,
+ 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72,
+ 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31,
+ 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61,
+ 0x64, 0x45, 0x6e, 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x65, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61,
+ 0x67, 0x65, 0x12, 0x24, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18,
+ 0x02, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x06, 0x8a, 0xb5, 0x18, 0x02, 0x39, 0x36, 0x52, 0x09, 0x73,
+ 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x22, 0xfa, 0x03, 0x0a, 0x1f, 0x42, 0x6c, 0x69,
+ 0x6e, 0x64, 0x65, 0x64, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x61, 0x79,
+ 0x6c, 0x6f, 0x61, 0x64, 0x45, 0x6e, 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x65, 0x12, 0x25, 0x0a, 0x0a,
+ 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c,
+ 0x42, 0x06, 0x8a, 0xb5, 0x18, 0x02, 0x33, 0x32, 0x52, 0x09, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x48,
+ 0x61, 0x73, 0x68, 0x12, 0x54, 0x0a, 0x12, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e,
0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32,
0x25, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x6e, 0x67, 0x69, 0x6e,
0x65, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65,
@@ -2349,90 +2452,52 @@ var file_proto_prysm_v1alpha1_gloas_proto_rawDesc = []byte{
0x53, 0x6c, 0x6f, 0x74, 0x52, 0x04, 0x73, 0x6c, 0x6f, 0x74, 0x12, 0x25, 0x0a, 0x0a, 0x73, 0x74,
0x61, 0x74, 0x65, 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x06,
0x8a, 0xb5, 0x18, 0x02, 0x33, 0x32, 0x52, 0x09, 0x73, 0x74, 0x61, 0x74, 0x65, 0x52, 0x6f, 0x6f,
- 0x74, 0x22, 0x91, 0x01, 0x0a, 0x1e, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x45, 0x78, 0x65, 0x63,
- 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x45, 0x6e, 0x76, 0x65,
- 0x6c, 0x6f, 0x70, 0x65, 0x12, 0x49, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18,
- 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d,
- 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x45, 0x78,
- 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x45, 0x6e,
- 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x65, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12,
- 0x24, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01,
- 0x28, 0x0c, 0x42, 0x06, 0x8a, 0xb5, 0x18, 0x02, 0x39, 0x36, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e,
- 0x61, 0x74, 0x75, 0x72, 0x65, 0x22, 0xfa, 0x03, 0x0a, 0x1f, 0x42, 0x6c, 0x69, 0x6e, 0x64, 0x65,
- 0x64, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61,
- 0x64, 0x45, 0x6e, 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x65, 0x12, 0x25, 0x0a, 0x0a, 0x62, 0x6c, 0x6f,
- 0x63, 0x6b, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x06, 0x8a,
- 0xb5, 0x18, 0x02, 0x33, 0x32, 0x52, 0x09, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x61, 0x73, 0x68,
- 0x12, 0x54, 0x0a, 0x12, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x72, 0x65,
- 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x65,
- 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x2e, 0x76,
- 0x31, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65,
- 0x73, 0x74, 0x73, 0x52, 0x11, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65,
- 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x12, 0x71, 0x0a, 0x0d, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x65,
- 0x72, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x42, 0x4c, 0x82,
- 0xb5, 0x18, 0x48, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x4f, 0x66,
- 0x66, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x4c, 0x61, 0x62, 0x73, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d,
- 0x2f, 0x76, 0x37, 0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x65, 0x6e, 0x73, 0x75, 0x73, 0x2d, 0x74, 0x79,
- 0x70, 0x65, 0x73, 0x2f, 0x70, 0x72, 0x69, 0x6d, 0x69, 0x74, 0x69, 0x76, 0x65, 0x73, 0x2e, 0x42,
- 0x75, 0x69, 0x6c, 0x64, 0x65, 0x72, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x52, 0x0c, 0x62, 0x75, 0x69,
- 0x6c, 0x64, 0x65, 0x72, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x32, 0x0a, 0x11, 0x62, 0x65, 0x61,
- 0x63, 0x6f, 0x6e, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x18, 0x04,
- 0x20, 0x01, 0x28, 0x0c, 0x42, 0x06, 0x8a, 0xb5, 0x18, 0x02, 0x33, 0x32, 0x52, 0x0f, 0x62, 0x65,
- 0x61, 0x63, 0x6f, 0x6e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x6f, 0x6f, 0x74, 0x12, 0x58, 0x0a,
- 0x04, 0x73, 0x6c, 0x6f, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x42, 0x44, 0x82, 0xb5, 0x18,
- 0x40, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x4f, 0x66, 0x66, 0x63,
- 0x68, 0x61, 0x69, 0x6e, 0x4c, 0x61, 0x62, 0x73, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x2f, 0x76,
- 0x37, 0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x65, 0x6e, 0x73, 0x75, 0x73, 0x2d, 0x74, 0x79, 0x70, 0x65,
- 0x73, 0x2f, 0x70, 0x72, 0x69, 0x6d, 0x69, 0x74, 0x69, 0x76, 0x65, 0x73, 0x2e, 0x53, 0x6c, 0x6f,
- 0x74, 0x52, 0x04, 0x73, 0x6c, 0x6f, 0x74, 0x12, 0x25, 0x0a, 0x0a, 0x73, 0x74, 0x61, 0x74, 0x65,
- 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x06, 0x8a, 0xb5, 0x18,
- 0x02, 0x33, 0x32, 0x52, 0x09, 0x73, 0x74, 0x61, 0x74, 0x65, 0x52, 0x6f, 0x6f, 0x74, 0x12, 0x32,
- 0x0a, 0x11, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x68,
- 0x61, 0x73, 0x68, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x06, 0x8a, 0xb5, 0x18, 0x02, 0x33,
- 0x32, 0x52, 0x0f, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x61,
- 0x73, 0x68, 0x22, 0x9f, 0x01, 0x0a, 0x25, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x42, 0x6c, 0x69,
- 0x6e, 0x64, 0x65, 0x64, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x61, 0x79,
- 0x6c, 0x6f, 0x61, 0x64, 0x45, 0x6e, 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x65, 0x12, 0x50, 0x0a, 0x07,
- 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x36, 0x2e,
- 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61,
- 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x42, 0x6c, 0x69, 0x6e, 0x64, 0x65, 0x64, 0x45, 0x78, 0x65,
- 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x45, 0x6e, 0x76,
- 0x65, 0x6c, 0x6f, 0x70, 0x65, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x24,
- 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28,
- 0x0c, 0x42, 0x06, 0x8a, 0xb5, 0x18, 0x02, 0x39, 0x36, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61,
- 0x74, 0x75, 0x72, 0x65, 0x22, 0xc1, 0x03, 0x0a, 0x07, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x65, 0x72,
- 0x12, 0x1e, 0x0a, 0x06, 0x70, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c,
- 0x42, 0x06, 0x8a, 0xb5, 0x18, 0x02, 0x34, 0x38, 0x52, 0x06, 0x70, 0x75, 0x62, 0x6b, 0x65, 0x79,
- 0x12, 0x1f, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28,
- 0x0c, 0x42, 0x05, 0x8a, 0xb5, 0x18, 0x01, 0x31, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f,
- 0x6e, 0x12, 0x33, 0x0a, 0x11, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x61,
- 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x06, 0x8a, 0xb5,
- 0x18, 0x02, 0x32, 0x30, 0x52, 0x10, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x41,
- 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x5e, 0x0a, 0x07, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63,
- 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x42, 0x44, 0x82, 0xb5, 0x18, 0x40, 0x67, 0x69, 0x74,
- 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x4f, 0x66, 0x66, 0x63, 0x68, 0x61, 0x69, 0x6e,
- 0x4c, 0x61, 0x62, 0x73, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x2f, 0x76, 0x37, 0x2f, 0x63, 0x6f,
- 0x6e, 0x73, 0x65, 0x6e, 0x73, 0x75, 0x73, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2f, 0x70, 0x72,
- 0x69, 0x6d, 0x69, 0x74, 0x69, 0x76, 0x65, 0x73, 0x2e, 0x47, 0x77, 0x65, 0x69, 0x52, 0x07, 0x62,
- 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x12, 0x6a, 0x0a, 0x0d, 0x64, 0x65, 0x70, 0x6f, 0x73, 0x69,
- 0x74, 0x5f, 0x65, 0x70, 0x6f, 0x63, 0x68, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x42, 0x45, 0x82,
- 0xb5, 0x18, 0x41, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x4f, 0x66,
- 0x66, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x4c, 0x61, 0x62, 0x73, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d,
- 0x2f, 0x76, 0x37, 0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x65, 0x6e, 0x73, 0x75, 0x73, 0x2d, 0x74, 0x79,
- 0x70, 0x65, 0x73, 0x2f, 0x70, 0x72, 0x69, 0x6d, 0x69, 0x74, 0x69, 0x76, 0x65, 0x73, 0x2e, 0x45,
- 0x70, 0x6f, 0x63, 0x68, 0x52, 0x0c, 0x64, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x45, 0x70, 0x6f,
- 0x63, 0x68, 0x12, 0x74, 0x0a, 0x12, 0x77, 0x69, 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, 0x61, 0x62,
- 0x6c, 0x65, 0x5f, 0x65, 0x70, 0x6f, 0x63, 0x68, 0x18, 0x06, 0x20, 0x01, 0x28, 0x04, 0x42, 0x45,
- 0x82, 0xb5, 0x18, 0x41, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x4f,
- 0x66, 0x66, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x4c, 0x61, 0x62, 0x73, 0x2f, 0x70, 0x72, 0x79, 0x73,
- 0x6d, 0x2f, 0x76, 0x37, 0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x65, 0x6e, 0x73, 0x75, 0x73, 0x2d, 0x74,
- 0x79, 0x70, 0x65, 0x73, 0x2f, 0x70, 0x72, 0x69, 0x6d, 0x69, 0x74, 0x69, 0x76, 0x65, 0x73, 0x2e,
- 0x45, 0x70, 0x6f, 0x63, 0x68, 0x52, 0x11, 0x77, 0x69, 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, 0x61,
- 0x62, 0x6c, 0x65, 0x45, 0x70, 0x6f, 0x63, 0x68, 0x42, 0x3b, 0x5a, 0x39, 0x67, 0x69, 0x74, 0x68,
- 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x4f, 0x66, 0x66, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x4c,
- 0x61, 0x62, 0x73, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x2f, 0x76, 0x37, 0x2f, 0x70, 0x72, 0x6f,
- 0x74, 0x6f, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61,
- 0x31, 0x3b, 0x65, 0x74, 0x68, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
+ 0x74, 0x12, 0x32, 0x0a, 0x11, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x62, 0x6c, 0x6f, 0x63,
+ 0x6b, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x06, 0x8a, 0xb5,
+ 0x18, 0x02, 0x33, 0x32, 0x52, 0x0f, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x42, 0x6c, 0x6f, 0x63,
+ 0x6b, 0x48, 0x61, 0x73, 0x68, 0x22, 0x9f, 0x01, 0x0a, 0x25, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64,
+ 0x42, 0x6c, 0x69, 0x6e, 0x64, 0x65, 0x64, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e,
+ 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x45, 0x6e, 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x65, 0x12,
+ 0x50, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b,
+ 0x32, 0x36, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e,
+ 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x42, 0x6c, 0x69, 0x6e, 0x64, 0x65, 0x64,
+ 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64,
+ 0x45, 0x6e, 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x65, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67,
+ 0x65, 0x12, 0x24, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x02,
+ 0x20, 0x01, 0x28, 0x0c, 0x42, 0x06, 0x8a, 0xb5, 0x18, 0x02, 0x39, 0x36, 0x52, 0x09, 0x73, 0x69,
+ 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x22, 0xc1, 0x03, 0x0a, 0x07, 0x42, 0x75, 0x69, 0x6c,
+ 0x64, 0x65, 0x72, 0x12, 0x1e, 0x0a, 0x06, 0x70, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20,
+ 0x01, 0x28, 0x0c, 0x42, 0x06, 0x8a, 0xb5, 0x18, 0x02, 0x34, 0x38, 0x52, 0x06, 0x70, 0x75, 0x62,
+ 0x6b, 0x65, 0x79, 0x12, 0x1f, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02,
+ 0x20, 0x01, 0x28, 0x0c, 0x42, 0x05, 0x8a, 0xb5, 0x18, 0x01, 0x31, 0x52, 0x07, 0x76, 0x65, 0x72,
+ 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x33, 0x0a, 0x11, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f,
+ 0x6e, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x42,
+ 0x06, 0x8a, 0xb5, 0x18, 0x02, 0x32, 0x30, 0x52, 0x10, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69,
+ 0x6f, 0x6e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x5e, 0x0a, 0x07, 0x62, 0x61, 0x6c,
+ 0x61, 0x6e, 0x63, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x42, 0x44, 0x82, 0xb5, 0x18, 0x40,
+ 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x4f, 0x66, 0x66, 0x63, 0x68,
+ 0x61, 0x69, 0x6e, 0x4c, 0x61, 0x62, 0x73, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x2f, 0x76, 0x37,
+ 0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x65, 0x6e, 0x73, 0x75, 0x73, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x73,
+ 0x2f, 0x70, 0x72, 0x69, 0x6d, 0x69, 0x74, 0x69, 0x76, 0x65, 0x73, 0x2e, 0x47, 0x77, 0x65, 0x69,
+ 0x52, 0x07, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x12, 0x6a, 0x0a, 0x0d, 0x64, 0x65, 0x70,
+ 0x6f, 0x73, 0x69, 0x74, 0x5f, 0x65, 0x70, 0x6f, 0x63, 0x68, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04,
+ 0x42, 0x45, 0x82, 0xb5, 0x18, 0x41, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d,
+ 0x2f, 0x4f, 0x66, 0x66, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x4c, 0x61, 0x62, 0x73, 0x2f, 0x70, 0x72,
+ 0x79, 0x73, 0x6d, 0x2f, 0x76, 0x37, 0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x65, 0x6e, 0x73, 0x75, 0x73,
+ 0x2d, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2f, 0x70, 0x72, 0x69, 0x6d, 0x69, 0x74, 0x69, 0x76, 0x65,
+ 0x73, 0x2e, 0x45, 0x70, 0x6f, 0x63, 0x68, 0x52, 0x0c, 0x64, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74,
+ 0x45, 0x70, 0x6f, 0x63, 0x68, 0x12, 0x74, 0x0a, 0x12, 0x77, 0x69, 0x74, 0x68, 0x64, 0x72, 0x61,
+ 0x77, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x65, 0x70, 0x6f, 0x63, 0x68, 0x18, 0x06, 0x20, 0x01, 0x28,
+ 0x04, 0x42, 0x45, 0x82, 0xb5, 0x18, 0x41, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f,
+ 0x6d, 0x2f, 0x4f, 0x66, 0x66, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x4c, 0x61, 0x62, 0x73, 0x2f, 0x70,
+ 0x72, 0x79, 0x73, 0x6d, 0x2f, 0x76, 0x37, 0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x65, 0x6e, 0x73, 0x75,
+ 0x73, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2f, 0x70, 0x72, 0x69, 0x6d, 0x69, 0x74, 0x69, 0x76,
+ 0x65, 0x73, 0x2e, 0x45, 0x70, 0x6f, 0x63, 0x68, 0x52, 0x11, 0x77, 0x69, 0x74, 0x68, 0x64, 0x72,
+ 0x61, 0x77, 0x61, 0x62, 0x6c, 0x65, 0x45, 0x70, 0x6f, 0x63, 0x68, 0x42, 0x3b, 0x5a, 0x39, 0x67,
+ 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x4f, 0x66, 0x66, 0x63, 0x68, 0x61,
+ 0x69, 0x6e, 0x4c, 0x61, 0x62, 0x73, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x2f, 0x76, 0x37, 0x2f,
+ 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x2f, 0x76, 0x31, 0x61, 0x6c,
+ 0x70, 0x68, 0x61, 0x31, 0x3b, 0x65, 0x74, 0x68, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
@@ -2447,7 +2512,7 @@ func file_proto_prysm_v1alpha1_gloas_proto_rawDescGZIP() []byte {
return file_proto_prysm_v1alpha1_gloas_proto_rawDescData
}
-var file_proto_prysm_v1alpha1_gloas_proto_msgTypes = make([]protoimpl.MessageInfo, 20)
+var file_proto_prysm_v1alpha1_gloas_proto_msgTypes = make([]protoimpl.MessageInfo, 21)
var file_proto_prysm_v1alpha1_gloas_proto_goTypes = []any{
(*ExecutionPayloadBid)(nil), // 0: ethereum.eth.v1alpha1.ExecutionPayloadBid
(*SignedExecutionPayloadBid)(nil), // 1: ethereum.eth.v1alpha1.SignedExecutionPayloadBid
@@ -2461,34 +2526,35 @@ var file_proto_prysm_v1alpha1_gloas_proto_goTypes = []any{
(*BeaconBlockBodyGloas)(nil), // 9: ethereum.eth.v1alpha1.BeaconBlockBodyGloas
(*SignedBeaconBlockGloas)(nil), // 10: ethereum.eth.v1alpha1.SignedBeaconBlockGloas
(*BeaconStateGloas)(nil), // 11: ethereum.eth.v1alpha1.BeaconStateGloas
- (*BuilderPendingPayment)(nil), // 12: ethereum.eth.v1alpha1.BuilderPendingPayment
- (*BuilderPendingWithdrawal)(nil), // 13: ethereum.eth.v1alpha1.BuilderPendingWithdrawal
- (*DataColumnSidecarGloas)(nil), // 14: ethereum.eth.v1alpha1.DataColumnSidecarGloas
- (*ExecutionPayloadEnvelope)(nil), // 15: ethereum.eth.v1alpha1.ExecutionPayloadEnvelope
- (*SignedExecutionPayloadEnvelope)(nil), // 16: ethereum.eth.v1alpha1.SignedExecutionPayloadEnvelope
- (*BlindedExecutionPayloadEnvelope)(nil), // 17: ethereum.eth.v1alpha1.BlindedExecutionPayloadEnvelope
- (*SignedBlindedExecutionPayloadEnvelope)(nil), // 18: ethereum.eth.v1alpha1.SignedBlindedExecutionPayloadEnvelope
- (*Builder)(nil), // 19: ethereum.eth.v1alpha1.Builder
- (*Eth1Data)(nil), // 20: ethereum.eth.v1alpha1.Eth1Data
- (*ProposerSlashing)(nil), // 21: ethereum.eth.v1alpha1.ProposerSlashing
- (*AttesterSlashingElectra)(nil), // 22: ethereum.eth.v1alpha1.AttesterSlashingElectra
- (*AttestationElectra)(nil), // 23: ethereum.eth.v1alpha1.AttestationElectra
- (*Deposit)(nil), // 24: ethereum.eth.v1alpha1.Deposit
- (*SignedVoluntaryExit)(nil), // 25: ethereum.eth.v1alpha1.SignedVoluntaryExit
- (*SyncAggregate)(nil), // 26: ethereum.eth.v1alpha1.SyncAggregate
- (*SignedBLSToExecutionChange)(nil), // 27: ethereum.eth.v1alpha1.SignedBLSToExecutionChange
- (*Fork)(nil), // 28: ethereum.eth.v1alpha1.Fork
- (*BeaconBlockHeader)(nil), // 29: ethereum.eth.v1alpha1.BeaconBlockHeader
- (*Validator)(nil), // 30: ethereum.eth.v1alpha1.Validator
- (*Checkpoint)(nil), // 31: ethereum.eth.v1alpha1.Checkpoint
- (*SyncCommittee)(nil), // 32: ethereum.eth.v1alpha1.SyncCommittee
- (*HistoricalSummary)(nil), // 33: ethereum.eth.v1alpha1.HistoricalSummary
- (*PendingDeposit)(nil), // 34: ethereum.eth.v1alpha1.PendingDeposit
- (*PendingPartialWithdrawal)(nil), // 35: ethereum.eth.v1alpha1.PendingPartialWithdrawal
- (*PendingConsolidation)(nil), // 36: ethereum.eth.v1alpha1.PendingConsolidation
- (*v1.Withdrawal)(nil), // 37: ethereum.engine.v1.Withdrawal
- (*v1.ExecutionPayloadDeneb)(nil), // 38: ethereum.engine.v1.ExecutionPayloadDeneb
- (*v1.ExecutionRequests)(nil), // 39: ethereum.engine.v1.ExecutionRequests
+ (*PTCs)(nil), // 12: ethereum.eth.v1alpha1.PTCs
+ (*BuilderPendingPayment)(nil), // 13: ethereum.eth.v1alpha1.BuilderPendingPayment
+ (*BuilderPendingWithdrawal)(nil), // 14: ethereum.eth.v1alpha1.BuilderPendingWithdrawal
+ (*DataColumnSidecarGloas)(nil), // 15: ethereum.eth.v1alpha1.DataColumnSidecarGloas
+ (*ExecutionPayloadEnvelope)(nil), // 16: ethereum.eth.v1alpha1.ExecutionPayloadEnvelope
+ (*SignedExecutionPayloadEnvelope)(nil), // 17: ethereum.eth.v1alpha1.SignedExecutionPayloadEnvelope
+ (*BlindedExecutionPayloadEnvelope)(nil), // 18: ethereum.eth.v1alpha1.BlindedExecutionPayloadEnvelope
+ (*SignedBlindedExecutionPayloadEnvelope)(nil), // 19: ethereum.eth.v1alpha1.SignedBlindedExecutionPayloadEnvelope
+ (*Builder)(nil), // 20: ethereum.eth.v1alpha1.Builder
+ (*Eth1Data)(nil), // 21: ethereum.eth.v1alpha1.Eth1Data
+ (*ProposerSlashing)(nil), // 22: ethereum.eth.v1alpha1.ProposerSlashing
+ (*AttesterSlashingElectra)(nil), // 23: ethereum.eth.v1alpha1.AttesterSlashingElectra
+ (*AttestationElectra)(nil), // 24: ethereum.eth.v1alpha1.AttestationElectra
+ (*Deposit)(nil), // 25: ethereum.eth.v1alpha1.Deposit
+ (*SignedVoluntaryExit)(nil), // 26: ethereum.eth.v1alpha1.SignedVoluntaryExit
+ (*SyncAggregate)(nil), // 27: ethereum.eth.v1alpha1.SyncAggregate
+ (*SignedBLSToExecutionChange)(nil), // 28: ethereum.eth.v1alpha1.SignedBLSToExecutionChange
+ (*Fork)(nil), // 29: ethereum.eth.v1alpha1.Fork
+ (*BeaconBlockHeader)(nil), // 30: ethereum.eth.v1alpha1.BeaconBlockHeader
+ (*Validator)(nil), // 31: ethereum.eth.v1alpha1.Validator
+ (*Checkpoint)(nil), // 32: ethereum.eth.v1alpha1.Checkpoint
+ (*SyncCommittee)(nil), // 33: ethereum.eth.v1alpha1.SyncCommittee
+ (*HistoricalSummary)(nil), // 34: ethereum.eth.v1alpha1.HistoricalSummary
+ (*PendingDeposit)(nil), // 35: ethereum.eth.v1alpha1.PendingDeposit
+ (*PendingPartialWithdrawal)(nil), // 36: ethereum.eth.v1alpha1.PendingPartialWithdrawal
+ (*PendingConsolidation)(nil), // 37: ethereum.eth.v1alpha1.PendingConsolidation
+ (*v1.Withdrawal)(nil), // 38: ethereum.engine.v1.Withdrawal
+ (*v1.ExecutionPayloadDeneb)(nil), // 39: ethereum.engine.v1.ExecutionPayloadDeneb
+ (*v1.ExecutionRequests)(nil), // 40: ethereum.engine.v1.ExecutionRequests
}
var file_proto_prysm_v1alpha1_gloas_proto_depIdxs = []int32{
0, // 0: ethereum.eth.v1alpha1.SignedExecutionPayloadBid.message:type_name -> ethereum.eth.v1alpha1.ExecutionPayloadBid
@@ -2497,47 +2563,48 @@ var file_proto_prysm_v1alpha1_gloas_proto_depIdxs = []int32{
5, // 3: ethereum.eth.v1alpha1.PayloadAttestation.data:type_name -> ethereum.eth.v1alpha1.PayloadAttestationData
5, // 4: ethereum.eth.v1alpha1.PayloadAttestationMessage.data:type_name -> ethereum.eth.v1alpha1.PayloadAttestationData
9, // 5: ethereum.eth.v1alpha1.BeaconBlockGloas.body:type_name -> ethereum.eth.v1alpha1.BeaconBlockBodyGloas
- 20, // 6: ethereum.eth.v1alpha1.BeaconBlockBodyGloas.eth1_data:type_name -> ethereum.eth.v1alpha1.Eth1Data
- 21, // 7: ethereum.eth.v1alpha1.BeaconBlockBodyGloas.proposer_slashings:type_name -> ethereum.eth.v1alpha1.ProposerSlashing
- 22, // 8: ethereum.eth.v1alpha1.BeaconBlockBodyGloas.attester_slashings:type_name -> ethereum.eth.v1alpha1.AttesterSlashingElectra
- 23, // 9: ethereum.eth.v1alpha1.BeaconBlockBodyGloas.attestations:type_name -> ethereum.eth.v1alpha1.AttestationElectra
- 24, // 10: ethereum.eth.v1alpha1.BeaconBlockBodyGloas.deposits:type_name -> ethereum.eth.v1alpha1.Deposit
- 25, // 11: ethereum.eth.v1alpha1.BeaconBlockBodyGloas.voluntary_exits:type_name -> ethereum.eth.v1alpha1.SignedVoluntaryExit
- 26, // 12: ethereum.eth.v1alpha1.BeaconBlockBodyGloas.sync_aggregate:type_name -> ethereum.eth.v1alpha1.SyncAggregate
- 27, // 13: ethereum.eth.v1alpha1.BeaconBlockBodyGloas.bls_to_execution_changes:type_name -> ethereum.eth.v1alpha1.SignedBLSToExecutionChange
+ 21, // 6: ethereum.eth.v1alpha1.BeaconBlockBodyGloas.eth1_data:type_name -> ethereum.eth.v1alpha1.Eth1Data
+ 22, // 7: ethereum.eth.v1alpha1.BeaconBlockBodyGloas.proposer_slashings:type_name -> ethereum.eth.v1alpha1.ProposerSlashing
+ 23, // 8: ethereum.eth.v1alpha1.BeaconBlockBodyGloas.attester_slashings:type_name -> ethereum.eth.v1alpha1.AttesterSlashingElectra
+ 24, // 9: ethereum.eth.v1alpha1.BeaconBlockBodyGloas.attestations:type_name -> ethereum.eth.v1alpha1.AttestationElectra
+ 25, // 10: ethereum.eth.v1alpha1.BeaconBlockBodyGloas.deposits:type_name -> ethereum.eth.v1alpha1.Deposit
+ 26, // 11: ethereum.eth.v1alpha1.BeaconBlockBodyGloas.voluntary_exits:type_name -> ethereum.eth.v1alpha1.SignedVoluntaryExit
+ 27, // 12: ethereum.eth.v1alpha1.BeaconBlockBodyGloas.sync_aggregate:type_name -> ethereum.eth.v1alpha1.SyncAggregate
+ 28, // 13: ethereum.eth.v1alpha1.BeaconBlockBodyGloas.bls_to_execution_changes:type_name -> ethereum.eth.v1alpha1.SignedBLSToExecutionChange
1, // 14: ethereum.eth.v1alpha1.BeaconBlockBodyGloas.signed_execution_payload_bid:type_name -> ethereum.eth.v1alpha1.SignedExecutionPayloadBid
6, // 15: ethereum.eth.v1alpha1.BeaconBlockBodyGloas.payload_attestations:type_name -> ethereum.eth.v1alpha1.PayloadAttestation
8, // 16: ethereum.eth.v1alpha1.SignedBeaconBlockGloas.block:type_name -> ethereum.eth.v1alpha1.BeaconBlockGloas
- 28, // 17: ethereum.eth.v1alpha1.BeaconStateGloas.fork:type_name -> ethereum.eth.v1alpha1.Fork
- 29, // 18: ethereum.eth.v1alpha1.BeaconStateGloas.latest_block_header:type_name -> ethereum.eth.v1alpha1.BeaconBlockHeader
- 20, // 19: ethereum.eth.v1alpha1.BeaconStateGloas.eth1_data:type_name -> ethereum.eth.v1alpha1.Eth1Data
- 20, // 20: ethereum.eth.v1alpha1.BeaconStateGloas.eth1_data_votes:type_name -> ethereum.eth.v1alpha1.Eth1Data
- 30, // 21: ethereum.eth.v1alpha1.BeaconStateGloas.validators:type_name -> ethereum.eth.v1alpha1.Validator
- 31, // 22: ethereum.eth.v1alpha1.BeaconStateGloas.previous_justified_checkpoint:type_name -> ethereum.eth.v1alpha1.Checkpoint
- 31, // 23: ethereum.eth.v1alpha1.BeaconStateGloas.current_justified_checkpoint:type_name -> ethereum.eth.v1alpha1.Checkpoint
- 31, // 24: ethereum.eth.v1alpha1.BeaconStateGloas.finalized_checkpoint:type_name -> ethereum.eth.v1alpha1.Checkpoint
- 32, // 25: ethereum.eth.v1alpha1.BeaconStateGloas.current_sync_committee:type_name -> ethereum.eth.v1alpha1.SyncCommittee
- 32, // 26: ethereum.eth.v1alpha1.BeaconStateGloas.next_sync_committee:type_name -> ethereum.eth.v1alpha1.SyncCommittee
+ 29, // 17: ethereum.eth.v1alpha1.BeaconStateGloas.fork:type_name -> ethereum.eth.v1alpha1.Fork
+ 30, // 18: ethereum.eth.v1alpha1.BeaconStateGloas.latest_block_header:type_name -> ethereum.eth.v1alpha1.BeaconBlockHeader
+ 21, // 19: ethereum.eth.v1alpha1.BeaconStateGloas.eth1_data:type_name -> ethereum.eth.v1alpha1.Eth1Data
+ 21, // 20: ethereum.eth.v1alpha1.BeaconStateGloas.eth1_data_votes:type_name -> ethereum.eth.v1alpha1.Eth1Data
+ 31, // 21: ethereum.eth.v1alpha1.BeaconStateGloas.validators:type_name -> ethereum.eth.v1alpha1.Validator
+ 32, // 22: ethereum.eth.v1alpha1.BeaconStateGloas.previous_justified_checkpoint:type_name -> ethereum.eth.v1alpha1.Checkpoint
+ 32, // 23: ethereum.eth.v1alpha1.BeaconStateGloas.current_justified_checkpoint:type_name -> ethereum.eth.v1alpha1.Checkpoint
+ 32, // 24: ethereum.eth.v1alpha1.BeaconStateGloas.finalized_checkpoint:type_name -> ethereum.eth.v1alpha1.Checkpoint
+ 33, // 25: ethereum.eth.v1alpha1.BeaconStateGloas.current_sync_committee:type_name -> ethereum.eth.v1alpha1.SyncCommittee
+ 33, // 26: ethereum.eth.v1alpha1.BeaconStateGloas.next_sync_committee:type_name -> ethereum.eth.v1alpha1.SyncCommittee
0, // 27: ethereum.eth.v1alpha1.BeaconStateGloas.latest_execution_payload_bid:type_name -> ethereum.eth.v1alpha1.ExecutionPayloadBid
- 33, // 28: ethereum.eth.v1alpha1.BeaconStateGloas.historical_summaries:type_name -> ethereum.eth.v1alpha1.HistoricalSummary
- 34, // 29: ethereum.eth.v1alpha1.BeaconStateGloas.pending_deposits:type_name -> ethereum.eth.v1alpha1.PendingDeposit
- 35, // 30: ethereum.eth.v1alpha1.BeaconStateGloas.pending_partial_withdrawals:type_name -> ethereum.eth.v1alpha1.PendingPartialWithdrawal
- 36, // 31: ethereum.eth.v1alpha1.BeaconStateGloas.pending_consolidations:type_name -> ethereum.eth.v1alpha1.PendingConsolidation
- 19, // 32: ethereum.eth.v1alpha1.BeaconStateGloas.builders:type_name -> ethereum.eth.v1alpha1.Builder
- 12, // 33: ethereum.eth.v1alpha1.BeaconStateGloas.builder_pending_payments:type_name -> ethereum.eth.v1alpha1.BuilderPendingPayment
- 13, // 34: ethereum.eth.v1alpha1.BeaconStateGloas.builder_pending_withdrawals:type_name -> ethereum.eth.v1alpha1.BuilderPendingWithdrawal
- 37, // 35: ethereum.eth.v1alpha1.BeaconStateGloas.payload_expected_withdrawals:type_name -> ethereum.engine.v1.Withdrawal
- 13, // 36: ethereum.eth.v1alpha1.BuilderPendingPayment.withdrawal:type_name -> ethereum.eth.v1alpha1.BuilderPendingWithdrawal
- 38, // 37: ethereum.eth.v1alpha1.ExecutionPayloadEnvelope.payload:type_name -> ethereum.engine.v1.ExecutionPayloadDeneb
- 39, // 38: ethereum.eth.v1alpha1.ExecutionPayloadEnvelope.execution_requests:type_name -> ethereum.engine.v1.ExecutionRequests
- 15, // 39: ethereum.eth.v1alpha1.SignedExecutionPayloadEnvelope.message:type_name -> ethereum.eth.v1alpha1.ExecutionPayloadEnvelope
- 39, // 40: ethereum.eth.v1alpha1.BlindedExecutionPayloadEnvelope.execution_requests:type_name -> ethereum.engine.v1.ExecutionRequests
- 17, // 41: ethereum.eth.v1alpha1.SignedBlindedExecutionPayloadEnvelope.message:type_name -> ethereum.eth.v1alpha1.BlindedExecutionPayloadEnvelope
- 42, // [42:42] is the sub-list for method output_type
- 42, // [42:42] is the sub-list for method input_type
- 42, // [42:42] is the sub-list for extension type_name
- 42, // [42:42] is the sub-list for extension extendee
- 0, // [0:42] is the sub-list for field type_name
+ 34, // 28: ethereum.eth.v1alpha1.BeaconStateGloas.historical_summaries:type_name -> ethereum.eth.v1alpha1.HistoricalSummary
+ 35, // 29: ethereum.eth.v1alpha1.BeaconStateGloas.pending_deposits:type_name -> ethereum.eth.v1alpha1.PendingDeposit
+ 36, // 30: ethereum.eth.v1alpha1.BeaconStateGloas.pending_partial_withdrawals:type_name -> ethereum.eth.v1alpha1.PendingPartialWithdrawal
+ 37, // 31: ethereum.eth.v1alpha1.BeaconStateGloas.pending_consolidations:type_name -> ethereum.eth.v1alpha1.PendingConsolidation
+ 20, // 32: ethereum.eth.v1alpha1.BeaconStateGloas.builders:type_name -> ethereum.eth.v1alpha1.Builder
+ 13, // 33: ethereum.eth.v1alpha1.BeaconStateGloas.builder_pending_payments:type_name -> ethereum.eth.v1alpha1.BuilderPendingPayment
+ 14, // 34: ethereum.eth.v1alpha1.BeaconStateGloas.builder_pending_withdrawals:type_name -> ethereum.eth.v1alpha1.BuilderPendingWithdrawal
+ 38, // 35: ethereum.eth.v1alpha1.BeaconStateGloas.payload_expected_withdrawals:type_name -> ethereum.engine.v1.Withdrawal
+ 12, // 36: ethereum.eth.v1alpha1.BeaconStateGloas.ptc_window:type_name -> ethereum.eth.v1alpha1.PTCs
+ 14, // 37: ethereum.eth.v1alpha1.BuilderPendingPayment.withdrawal:type_name -> ethereum.eth.v1alpha1.BuilderPendingWithdrawal
+ 39, // 38: ethereum.eth.v1alpha1.ExecutionPayloadEnvelope.payload:type_name -> ethereum.engine.v1.ExecutionPayloadDeneb
+ 40, // 39: ethereum.eth.v1alpha1.ExecutionPayloadEnvelope.execution_requests:type_name -> ethereum.engine.v1.ExecutionRequests
+ 16, // 40: ethereum.eth.v1alpha1.SignedExecutionPayloadEnvelope.message:type_name -> ethereum.eth.v1alpha1.ExecutionPayloadEnvelope
+ 40, // 41: ethereum.eth.v1alpha1.BlindedExecutionPayloadEnvelope.execution_requests:type_name -> ethereum.engine.v1.ExecutionRequests
+ 18, // 42: ethereum.eth.v1alpha1.SignedBlindedExecutionPayloadEnvelope.message:type_name -> ethereum.eth.v1alpha1.BlindedExecutionPayloadEnvelope
+ 43, // [43:43] is the sub-list for method output_type
+ 43, // [43:43] is the sub-list for method input_type
+ 43, // [43:43] is the sub-list for extension type_name
+ 43, // [43:43] is the sub-list for extension extendee
+ 0, // [0:43] is the sub-list for field type_name
}
func init() { file_proto_prysm_v1alpha1_gloas_proto_init() }
@@ -2555,7 +2622,7 @@ func file_proto_prysm_v1alpha1_gloas_proto_init() {
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_proto_prysm_v1alpha1_gloas_proto_rawDesc,
NumEnums: 0,
- NumMessages: 20,
+ NumMessages: 21,
NumExtensions: 0,
NumServices: 0,
},
diff --git a/proto/prysm/v1alpha1/gloas.proto b/proto/prysm/v1alpha1/gloas.proto
index bba14d5b14d1..f287d04bc795 100644
--- a/proto/prysm/v1alpha1/gloas.proto
+++ b/proto/prysm/v1alpha1/gloas.proto
@@ -250,6 +250,8 @@ message SignedBeaconBlockGloas {
// latest_block_hash: Hash32
// payload_expected_withdrawals: List[Withdrawal,
// MAX_WITHDRAWALS_PER_PAYLOAD]
+// ptc_window:
+// Vector[PTCs, (2 + MIN_SEED_LOOKAHEAD) * SLOTS_PER_EPOCH]
message BeaconStateGloas {
// Versioning [1001-2000]
uint64 genesis_time = 1001;
@@ -375,6 +377,21 @@ message BeaconStateGloas {
bytes latest_block_hash = 14006 [ (ethereum.eth.ext.ssz_size) = "32" ];
repeated ethereum.engine.v1.Withdrawal payload_expected_withdrawals = 14007
[ (ethereum.eth.ext.ssz_max) = "withdrawal.size" ];
+ repeated PTCs ptc_window = 14008
+ [ (ethereum.eth.ext.ssz_size) = "ptc_window.size" ];
+}
+
+// PTCs represents the payload timeliness committee for a single slot.
+//
+// Spec:
+// Vector[ValidatorIndex, PTC_SIZE]
+message PTCs {
+ repeated uint64 validator_indices = 1 [
+ (ethereum.eth.ext.ssz_size) = "ptc_committee_indices.size",
+ (ethereum.eth.ext.cast_type) =
+ "github.com/OffchainLabs/prysm/v7/consensus-types/"
+ "primitives.ValidatorIndex"
+ ];
}
// BuilderPendingPayment represents a pending payment to a builder.
diff --git a/proto/prysm/v1alpha1/gloas.ssz.go b/proto/prysm/v1alpha1/gloas.ssz.go
index 3147a1e07221..d6141840c81f 100644
--- a/proto/prysm/v1alpha1/gloas.ssz.go
+++ b/proto/prysm/v1alpha1/gloas.ssz.go
@@ -1701,7 +1701,7 @@ func (b *BeaconStateGloas) MarshalSSZ() ([]byte, error) {
// MarshalSSZTo ssz marshals the BeaconStateGloas object to a target array
func (b *BeaconStateGloas) MarshalSSZTo(buf []byte) (dst []byte, err error) {
dst = buf
- offset := int(2741117)
+ offset := int(3134333)
// Field (0) 'GenesisTime'
dst = ssz.MarshalUint(dst, b.GenesisTime)
@@ -1962,6 +1962,17 @@ func (b *BeaconStateGloas) MarshalSSZTo(buf []byte) (dst []byte, err error) {
dst = ssz.WriteOffset(dst, offset)
offset += len(b.PayloadExpectedWithdrawals) * 44
+ // Field (45) 'PtcWindow'
+ if size := len(b.PtcWindow); size != 96 {
+ err = ssz.ErrVectorLengthFn("--.PtcWindow", size, 96)
+ return
+ }
+ for ii := 0; ii < 96; ii++ {
+ if dst, err = b.PtcWindow[ii].MarshalSSZTo(dst); err != nil {
+ return
+ }
+ }
+
// Field (7) 'HistoricalRoots'
if size := len(b.HistoricalRoots); size > 16777216 {
err = ssz.ErrListTooBigFn("--.HistoricalRoots", size, 16777216)
@@ -2118,7 +2129,7 @@ func (b *BeaconStateGloas) MarshalSSZTo(buf []byte) (dst []byte, err error) {
func (b *BeaconStateGloas) UnmarshalSSZ(buf []byte) error {
var err error
size := uint64(len(buf))
- if size < 2741117 {
+ if size < 3134333 {
return ssz.ErrSize
}
@@ -2176,7 +2187,7 @@ func (b *BeaconStateGloas) UnmarshalSSZ(buf []byte) error {
return ssz.ErrOffset
}
- if o7 != 2741117 {
+ if o7 != 3134333 {
return ssz.ErrInvalidVariableOffset
}
@@ -2378,6 +2389,17 @@ func (b *BeaconStateGloas) UnmarshalSSZ(buf []byte) error {
return ssz.ErrOffset
}
+ // Field (45) 'PtcWindow'
+ b.PtcWindow = make([]*PTCs, 96)
+ for ii := 0; ii < 96; ii++ {
+ if b.PtcWindow[ii] == nil {
+ b.PtcWindow[ii] = new(PTCs)
+ }
+ if err = b.PtcWindow[ii].UnmarshalSSZ(buf[2741117:3134333][ii*4096 : (ii+1)*4096]); err != nil {
+ return err
+ }
+ }
+
// Field (7) 'HistoricalRoots'
{
buf = tail[o7:o9]
@@ -2621,7 +2643,7 @@ func (b *BeaconStateGloas) UnmarshalSSZ(buf []byte) error {
// SizeSSZ returns the ssz encoded size in bytes for the BeaconStateGloas object
func (b *BeaconStateGloas) SizeSSZ() (size int) {
- size = 2741117
+ size = 3134333
// Field (7) 'HistoricalRoots'
size += len(b.HistoricalRoots) * 32
@@ -3099,6 +3121,87 @@ func (b *BeaconStateGloas) HashTreeRootWith(hh *ssz.Hasher) (err error) {
hh.MerkleizeWithMixin(subIndx, num, 16)
}
+ // Field (45) 'PtcWindow'
+ {
+ subIndx := hh.Index()
+ for _, elem := range b.PtcWindow {
+ if err = elem.HashTreeRootWith(hh); err != nil {
+ return
+ }
+ }
+ hh.Merkleize(subIndx)
+ }
+
+ hh.Merkleize(indx)
+ return
+}
+
+// MarshalSSZ ssz marshals the PTCs object
+func (p *PTCs) MarshalSSZ() ([]byte, error) {
+ return ssz.MarshalSSZ(p)
+}
+
+// MarshalSSZTo ssz marshals the PTCs object to a target array
+func (p *PTCs) MarshalSSZTo(buf []byte) (dst []byte, err error) {
+ dst = buf
+
+ // Field (0) 'ValidatorIndices'
+ if size := len(p.ValidatorIndices); size != 512 {
+ err = ssz.ErrVectorLengthFn("--.ValidatorIndices", size, 512)
+ return
+ }
+ for ii := 0; ii < 512; ii++ {
+ dst = ssz.MarshalUint(dst, p.ValidatorIndices[ii])
+ }
+
+ return
+}
+
+// UnmarshalSSZ ssz unmarshals the PTCs object
+func (p *PTCs) UnmarshalSSZ(buf []byte) error {
+ var err error
+ size := uint64(len(buf))
+ if size != 4096 {
+ return ssz.ErrSize
+ }
+
+ // Field (0) 'ValidatorIndices'
+ p.ValidatorIndices = ssz.ExtendUint(p.ValidatorIndices, 512)
+ for ii := 0; ii < 512; ii++ {
+ p.ValidatorIndices[ii] = ssz.UnmarshallUint[github_com_OffchainLabs_prysm_v7_consensus_types_primitives.ValidatorIndex](buf[0:4096][ii*8 : (ii+1)*8])
+ }
+
+ return err
+}
+
+// SizeSSZ returns the ssz encoded size in bytes for the PTCs object
+func (p *PTCs) SizeSSZ() (size int) {
+ size = 4096
+ return
+}
+
+// HashTreeRoot ssz hashes the PTCs object
+func (p *PTCs) HashTreeRoot() ([32]byte, error) {
+ return ssz.HashWithDefaultHasher(p)
+}
+
+// HashTreeRootWith ssz hashes the PTCs object with a hasher
+func (p *PTCs) HashTreeRootWith(hh *ssz.Hasher) (err error) {
+ indx := hh.Index()
+
+ // Field (0) 'ValidatorIndices'
+ {
+ if size := len(p.ValidatorIndices); size != 512 {
+ err = ssz.ErrVectorLengthFn("--.ValidatorIndices", size, 512)
+ return
+ }
+ subIndx := hh.Index()
+ for _, i := range p.ValidatorIndices {
+ ssz.AppendUint(hh, i)
+ }
+ hh.Merkleize(subIndx)
+ }
+
hh.Merkleize(indx)
return
}
diff --git a/proto/ssz_proto_library.bzl b/proto/ssz_proto_library.bzl
index f3a424696cd0..2501e8611a6b 100644
--- a/proto/ssz_proto_library.bzl
+++ b/proto/ssz_proto_library.bzl
@@ -43,6 +43,8 @@ mainnet = {
"cells_per_blob.size": "128",
"kzg_commitments_inclusion_proof_depth.size": "4",
"proposer_lookahead_size": "64", # (MIN_SEED_LOOKAHEAD + 1) * SLOTS_PER_EPOCH
+ "ptc_window.size": "96", # (2 + MIN_SEED_LOOKAHEAD) * SLOTS_PER_EPOCH
+ "ptc_committee_indices.size": "512", # PTC_SIZE
"ptc.size": "64", # Gloas: Payload Timeliness Committee aggregation bits (PTC_SIZE = 512)
"ptc.type": "github.com/OffchainLabs/go-bitfield.Bitvector512",
"payload_attestation.size": "4", # Gloas: MAX_PAYLOAD_ATTESTATIONS defined in block body
@@ -88,6 +90,8 @@ minimal = {
"cells_per_blob.size": "128",
"kzg_commitments_inclusion_proof_depth.size": "4",
"proposer_lookahead_size": "16", # (MIN_SEED_LOOKAHEAD + 1) * SLOTS_PER_EPOCH
+ "ptc_window.size": "24", # (2 + MIN_SEED_LOOKAHEAD) * SLOTS_PER_EPOCH
+ "ptc_committee_indices.size": "2", # PTC_SIZE
"ptc.size": "1", # Gloas: Payload Timeliness Committee aggregation bits
"ptc.type": "github.com/OffchainLabs/go-bitfield.Bitvector2",
"payload_attestation.size": "4", # Gloas: MAX_PAYLOAD_ATTESTATIONS defined in block body
diff --git a/specrefs/configs.yml b/specrefs/configs.yml
index 3f35ef0d3b57..88110c9b84d6 100644
--- a/specrefs/configs.yml
+++ b/specrefs/configs.yml
@@ -82,16 +82,6 @@
ATTESTATION_SUBNET_EXTRA_BITS = 0
-- name: ATTESTATION_SUBNET_PREFIX_BITS#phase0
- sources:
- - file: config/params/config.go
- search: AttestationSubnetPrefixBits\s+uint64
- regex: true
- spec: |
-
- ATTESTATION_SUBNET_PREFIX_BITS: int = 6
-
-
- name: BALANCE_PER_ADDITIONAL_CUSTODY_GROUP#fulu
sources:
- file: config/params/config.go
@@ -352,6 +342,20 @@
GLOAS_FORK_VERSION: Version = '0x07000000'
+- name: HEZE_FORK_EPOCH#heze
+ sources: []
+ spec: |
+
+ HEZE_FORK_EPOCH: Epoch = 18446744073709551615
+
+
+- name: HEZE_FORK_VERSION#heze
+ sources: []
+ spec: |
+
+ HEZE_FORK_VERSION: Version = '0x08000000'
+
+
- name: INACTIVITY_SCORE_BIAS#altair
sources:
- file: config/params/config.go
@@ -372,6 +376,13 @@
INACTIVITY_SCORE_RECOVERY_RATE: uint64 = 16
+- name: INCLUSION_LIST_SUBMISSION_DUE_BPS#heze
+ sources: []
+ spec: |
+
+ INCLUSION_LIST_SUBMISSION_DUE_BPS: uint64 = 6667
+
+
- name: MAXIMUM_GOSSIP_CLOCK_DISPARITY#phase0
sources:
- file: config/params/config.go
@@ -402,6 +413,13 @@
MAX_BLOBS_PER_BLOCK_ELECTRA: uint64 = 9
+- name: MAX_BYTES_PER_INCLUSION_LIST#heze
+ sources: []
+ spec: |
+
+ MAX_BYTES_PER_INCLUSION_LIST = 8192
+
+
- name: MAX_PAYLOAD_SIZE#phase0
sources:
- file: config/params/config.go
@@ -432,26 +450,6 @@
MAX_PER_EPOCH_ACTIVATION_EXIT_CHURN_LIMIT: Gwei = 256000000000
-- name: MAX_REQUEST_BLOB_SIDECARS#deneb
- sources:
- - file: config/params/config.go
- search: MaxRequestBlobSidecars\s+uint64
- regex: true
- spec: |
-
- MAX_REQUEST_BLOB_SIDECARS = 768
-
-
-- name: MAX_REQUEST_BLOB_SIDECARS_ELECTRA#electra
- sources:
- - file: config/params/config.go
- search: MaxRequestBlobSidecarsElectra\s+uint64
- regex: true
- spec: |
-
- MAX_REQUEST_BLOB_SIDECARS_ELECTRA = 1152
-
-
- name: MAX_REQUEST_BLOCKS#phase0
sources:
- file: config/params/config.go
@@ -472,14 +470,11 @@
MAX_REQUEST_BLOCKS_DENEB = 128
-- name: MAX_REQUEST_DATA_COLUMN_SIDECARS#fulu
- sources:
- - file: config/params/config.go
- search: MaxRequestDataColumnSidecars\s+uint64
- regex: true
+- name: MAX_REQUEST_INCLUSION_LIST#heze
+ sources: []
spec: |
-
- MAX_REQUEST_DATA_COLUMN_SIDECARS = 16384
+
+ MAX_REQUEST_INCLUSION_LIST = 16
- name: MAX_REQUEST_PAYLOADS#gloas
@@ -531,16 +526,6 @@
MIN_EPOCHS_FOR_BLOB_SIDECARS_REQUESTS = 4096
-- name: MIN_EPOCHS_FOR_BLOCK_REQUESTS#phase0
- sources:
- - file: config/params/config.go
- search: MinEpochsForBlockRequests\s+uint64
- regex: true
- spec: |
-
- MIN_EPOCHS_FOR_BLOCK_REQUESTS = 33024
-
-
- name: MIN_EPOCHS_FOR_DATA_COLUMN_SIDECARS_REQUESTS#fulu
sources:
- file: config/params/config.go
@@ -621,6 +606,13 @@
PAYLOAD_ATTESTATION_DUE_BPS: uint64 = 7500
+- name: PROPOSER_INCLUSION_LIST_CUTOFF_BPS#heze
+ sources: []
+ spec: |
+
+ PROPOSER_INCLUSION_LIST_CUTOFF_BPS: uint64 = 9167
+
+
- name: PROPOSER_REORG_CUTOFF_BPS#phase0
sources:
- file: config/params/config.go
@@ -691,16 +683,6 @@
SECONDS_PER_ETH1_BLOCK: uint64 = 14
-- name: SECONDS_PER_SLOT#phase0
- sources:
- - file: config/params/config.go
- search: SecondsPerSlot\s+uint64
- regex: true
- spec: |
-
- SECONDS_PER_SLOT: uint64 = 12
-
-
- name: SHARD_COMMITTEE_PERIOD#phase0
sources:
- file: config/params/config.go
@@ -787,3 +769,10 @@
VALIDATOR_CUSTODY_REQUIREMENT = 8
+
+- name: VIEW_FREEZE_CUTOFF_BPS#heze
+ sources: []
+ spec: |
+
+ VIEW_FREEZE_CUTOFF_BPS: uint64 = 7500
+
diff --git a/specrefs/constants.yml b/specrefs/constants.yml
index 8dc0b78ea011..45373098ecc6 100644
--- a/specrefs/constants.yml
+++ b/specrefs/constants.yml
@@ -212,6 +212,13 @@
DOMAIN_DEPOSIT: DomainType = '0x03000000'
+- name: DOMAIN_INCLUSION_LIST_COMMITTEE#heze
+ sources: []
+ spec: |
+
+ DOMAIN_INCLUSION_LIST_COMMITTEE: DomainType = '0x0E000000'
+
+
- name: DOMAIN_PROPOSER_PREFERENCES#gloas
sources:
- file: config/params/config.go
@@ -445,22 +452,22 @@
- name: PAYLOAD_STATUS_EMPTY#gloas
sources: []
spec: |
-
- PAYLOAD_STATUS_EMPTY: PayloadStatus = 1
+
+ PAYLOAD_STATUS_EMPTY: PayloadStatus = 0
- name: PAYLOAD_STATUS_FULL#gloas
sources: []
spec: |
-
- PAYLOAD_STATUS_FULL: PayloadStatus = 2
+
+ PAYLOAD_STATUS_FULL: PayloadStatus = 1
- name: PAYLOAD_STATUS_PENDING#gloas
sources: []
spec: |
-
- PAYLOAD_STATUS_PENDING: PayloadStatus = 0
+
+ PAYLOAD_STATUS_PENDING: PayloadStatus = 2
- name: PRIMITIVE_ROOT_OF_UNITY#deneb
diff --git a/specrefs/containers.yml b/specrefs/containers.yml
index 29d8da7a3244..c9c69d8d55a2 100644
--- a/specrefs/containers.yml
+++ b/specrefs/containers.yml
@@ -568,7 +568,7 @@
- name: BeaconState#gloas
sources: []
spec: |
-
+
class BeaconState(Container):
genesis_time: uint64
genesis_validators_root: Root
@@ -625,6 +625,62 @@
latest_block_hash: Hash32
# [New in Gloas:EIP7732]
payload_expected_withdrawals: List[Withdrawal, MAX_WITHDRAWALS_PER_PAYLOAD]
+ # [New in Gloas:EIP7732]
+ ptc_window: Vector[Vector[ValidatorIndex, PTC_SIZE], (2 + MIN_SEED_LOOKAHEAD) * SLOTS_PER_EPOCH]
+
+
+- name: BeaconState#heze
+ sources: []
+ spec: |
+
+ class BeaconState(Container):
+ genesis_time: uint64
+ genesis_validators_root: Root
+ slot: Slot
+ fork: Fork
+ latest_block_header: BeaconBlockHeader
+ block_roots: Vector[Root, SLOTS_PER_HISTORICAL_ROOT]
+ state_roots: Vector[Root, SLOTS_PER_HISTORICAL_ROOT]
+ historical_roots: List[Root, HISTORICAL_ROOTS_LIMIT]
+ eth1_data: Eth1Data
+ eth1_data_votes: List[Eth1Data, EPOCHS_PER_ETH1_VOTING_PERIOD * SLOTS_PER_EPOCH]
+ eth1_deposit_index: uint64
+ validators: List[Validator, VALIDATOR_REGISTRY_LIMIT]
+ balances: List[Gwei, VALIDATOR_REGISTRY_LIMIT]
+ randao_mixes: Vector[Bytes32, EPOCHS_PER_HISTORICAL_VECTOR]
+ slashings: Vector[Gwei, EPOCHS_PER_SLASHINGS_VECTOR]
+ previous_epoch_participation: List[ParticipationFlags, VALIDATOR_REGISTRY_LIMIT]
+ current_epoch_participation: List[ParticipationFlags, VALIDATOR_REGISTRY_LIMIT]
+ justification_bits: Bitvector[JUSTIFICATION_BITS_LENGTH]
+ previous_justified_checkpoint: Checkpoint
+ current_justified_checkpoint: Checkpoint
+ finalized_checkpoint: Checkpoint
+ inactivity_scores: List[uint64, VALIDATOR_REGISTRY_LIMIT]
+ current_sync_committee: SyncCommittee
+ next_sync_committee: SyncCommittee
+ # [Modified in Heze:EIP7805]
+ latest_execution_payload_bid: ExecutionPayloadBid
+ next_withdrawal_index: WithdrawalIndex
+ next_withdrawal_validator_index: ValidatorIndex
+ historical_summaries: List[HistoricalSummary, HISTORICAL_ROOTS_LIMIT]
+ deposit_requests_start_index: uint64
+ deposit_balance_to_consume: Gwei
+ exit_balance_to_consume: Gwei
+ earliest_exit_epoch: Epoch
+ consolidation_balance_to_consume: Gwei
+ earliest_consolidation_epoch: Epoch
+ pending_deposits: List[PendingDeposit, PENDING_DEPOSITS_LIMIT]
+ pending_partial_withdrawals: List[PendingPartialWithdrawal, PENDING_PARTIAL_WITHDRAWALS_LIMIT]
+ pending_consolidations: List[PendingConsolidation, PENDING_CONSOLIDATIONS_LIMIT]
+ proposer_lookahead: Vector[ValidatorIndex, (MIN_SEED_LOOKAHEAD + 1) * SLOTS_PER_EPOCH]
+ builders: List[Builder, BUILDER_REGISTRY_LIMIT]
+ next_withdrawal_builder_index: BuilderIndex
+ execution_payload_availability: Bitvector[SLOTS_PER_HISTORICAL_ROOT]
+ builder_pending_payments: Vector[BuilderPendingPayment, 2 * SLOTS_PER_EPOCH]
+ builder_pending_withdrawals: List[BuilderPendingWithdrawal, BUILDER_PENDING_WITHDRAWALS_LIMIT]
+ latest_block_hash: Hash32
+ payload_expected_withdrawals: List[Withdrawal, MAX_WITHDRAWALS_PER_PAYLOAD]
+ ptc_window: Vector[Vector[ValidatorIndex, PTC_SIZE], (2 + MIN_SEED_LOOKAHEAD) * SLOTS_PER_EPOCH]
- name: BlobIdentifier#deneb
@@ -932,6 +988,26 @@
blob_kzg_commitments: List[KZGCommitment, MAX_BLOB_COMMITMENTS_PER_BLOCK]
+- name: ExecutionPayloadBid#heze
+ sources: []
+ spec: |
+
+ class ExecutionPayloadBid(Container):
+ parent_block_hash: Hash32
+ parent_block_root: Root
+ block_hash: Hash32
+ prev_randao: Bytes32
+ fee_recipient: ExecutionAddress
+ gas_limit: uint64
+ builder_index: BuilderIndex
+ slot: Slot
+ value: Gwei
+ execution_payment: Gwei
+ blob_kzg_commitments: List[KZGCommitment, MAX_BLOB_COMMITMENTS_PER_BLOCK]
+ # [New in Heze:EIP7805]
+ inclusion_list_bits: Bitvector[INCLUSION_LIST_COMMITTEE_SIZE]
+
+
- name: ExecutionPayloadEnvelope#gloas
sources: []
spec: |
@@ -1090,6 +1166,17 @@
state_summary_root: Root
+- name: InclusionList#heze
+ sources: []
+ spec: |
+
+ class InclusionList(Container):
+ slot: Slot
+ validator_index: ValidatorIndex
+ inclusion_list_committee_root: Root
+ transactions: List[Transaction, MAX_TRANSACTIONS_PER_PAYLOAD]
+
+
- name: IndexedAttestation#phase0
sources:
- file: proto/prysm/v1alpha1/beacon_block.proto
@@ -1280,6 +1367,53 @@
row_index: RowIndex
+- name: PartialDataColumnHeader#fulu
+ sources: []
+ spec: |
+
+ class PartialDataColumnHeader(Container):
+ kzg_commitments: List[KZGCommitment, MAX_BLOB_COMMITMENTS_PER_BLOCK]
+ signed_block_header: SignedBeaconBlockHeader
+ kzg_commitments_inclusion_proof: Vector[Bytes32, KZG_COMMITMENTS_INCLUSION_PROOF_DEPTH]
+
+
+- name: PartialDataColumnHeader#gloas
+ sources: []
+ spec: |
+
+ class PartialDataColumnHeader(Container):
+ kzg_commitments: List[KZGCommitment, MAX_BLOB_COMMITMENTS_PER_BLOCK]
+ # [Modified in Gloas:EIP7732]
+ # Removed `signed_block_header`
+ # [Modified in Gloas:EIP7732]
+ # Removed `kzg_commitments_inclusion_proof`
+ # [New in Gloas:EIP7732]
+ slot: Slot
+ # [New in Gloas:EIP7732]
+ beacon_block_root: Root
+
+
+- name: PartialDataColumnPartsMetadata#fulu
+ sources: []
+ spec: |
+
+ class PartialDataColumnPartsMetadata(Container):
+ available: Bitlist[MAX_BLOB_COMMITMENTS_PER_BLOCK]
+ requests: Bitlist[MAX_BLOB_COMMITMENTS_PER_BLOCK]
+
+
+- name: PartialDataColumnSidecar#fulu
+ sources: []
+ spec: |
+
+ class PartialDataColumnSidecar(Container):
+ cells_present_bitmap: Bitlist[MAX_BLOB_COMMITMENTS_PER_BLOCK]
+ partial_column: List[Cell, MAX_BLOB_COMMITMENTS_PER_BLOCK]
+ kzg_proofs: List[KZGProof, MAX_BLOB_COMMITMENTS_PER_BLOCK]
+ # Optional header, only sent on eager pushes
+ header: List[PartialDataColumnHeader, 1]
+
+
- name: PayloadAttestation#gloas
sources: []
spec: |
@@ -1471,6 +1605,16 @@
signature: BLSSignature
+- name: SignedExecutionPayloadBid#heze
+ sources: []
+ spec: |
+
+ class SignedExecutionPayloadBid(Container):
+ # [Modified in Heze:EIP7805]
+ message: ExecutionPayloadBid
+ signature: BLSSignature
+
+
- name: SignedExecutionPayloadEnvelope#gloas
sources: []
spec: |
@@ -1480,6 +1624,15 @@
signature: BLSSignature
+- name: SignedInclusionList#heze
+ sources: []
+ spec: |
+
+ class SignedInclusionList(Container):
+ message: InclusionList
+ signature: BLSSignature
+
+
- name: SignedProposerPreferences#gloas
sources: []
spec: |
diff --git a/specrefs/dataclasses.yml b/specrefs/dataclasses.yml
index 7d02bfc4ddcd..3ba15f0c765b 100644
--- a/specrefs/dataclasses.yml
+++ b/specrefs/dataclasses.yml
@@ -68,6 +68,14 @@
processed_sweep_withdrawals_count: uint64
+- name: GetInclusionListResponse#heze
+ sources: []
+ spec: |
+
+ class GetInclusionListResponse(object):
+ inclusion_list_transactions: Sequence[Transaction]
+
+
- name: GetPayloadResponse#bellatrix
sources:
- file: consensus-types/blocks/get_payload.go
@@ -140,6 +148,19 @@
execution_requests: Sequence[bytes]
+- name: InclusionListStore#heze
+ sources: []
+ spec: |
+
+ class InclusionListStore(object):
+ inclusion_lists: DefaultDict[Tuple[Slot, Root], Set[InclusionList]] = field(
+ default_factory=lambda: defaultdict(set)
+ )
+ equivocators: DefaultDict[Tuple[Slot, Root], Set[ValidatorIndex]] = field(
+ default_factory=lambda: defaultdict(set)
+ )
+
+
- name: LatestMessage#phase0
sources: []
spec: |
@@ -288,6 +309,34 @@
parent_beacon_block_root: Root
+- name: PayloadAttributes#heze
+ sources: []
+ spec: |
+
+ class PayloadAttributes(object):
+ timestamp: uint64
+ prev_randao: Bytes32
+ suggested_fee_recipient: ExecutionAddress
+ withdrawals: Sequence[Withdrawal]
+ parent_beacon_block_root: Root
+ # [New in Heze:EIP7805]
+ inclusion_list_transactions: Sequence[Transaction]
+
+
+- name: Seen#phase0
+ sources: []
+ spec: |
+
+ class Seen(object):
+ proposer_slots: Set[Tuple[ValidatorIndex, Slot]]
+ aggregator_epochs: Set[Tuple[ValidatorIndex, Epoch]]
+ aggregate_data_roots: Dict[Root, Set[Tuple[boolean, ...]]]
+ voluntary_exit_indices: Set[ValidatorIndex]
+ proposer_slashing_indices: Set[ValidatorIndex]
+ attester_slashing_indices: Set[ValidatorIndex]
+ attestation_validator_epochs: Set[Tuple[ValidatorIndex, Epoch]]
+
+
- name: Store#phase0
sources: []
spec: |
@@ -312,7 +361,7 @@
- name: Store#gloas
sources: []
spec: |
-
+
class Store(object):
time: uint64
genesis_time: uint64
@@ -331,7 +380,41 @@
latest_messages: Dict[ValidatorIndex, LatestMessage] = field(default_factory=dict)
unrealized_justifications: Dict[Root, Checkpoint] = field(default_factory=dict)
# [New in Gloas:EIP7732]
- execution_payload_states: Dict[Root, BeaconState] = field(default_factory=dict)
+ payload_states: Dict[Root, BeaconState] = field(default_factory=dict)
+ # [New in Gloas:EIP7732]
+ payload_timeliness_vote: Dict[Root, Vector[boolean, PTC_SIZE]] = field(default_factory=dict)
# [New in Gloas:EIP7732]
- ptc_vote: Dict[Root, Vector[boolean, PTC_SIZE]] = field(default_factory=dict)
+ payload_data_availability_vote: Dict[Root, Vector[boolean, PTC_SIZE]] = field(
+ default_factory=dict
+ )
+
+
+- name: Store#heze
+ sources: []
+ spec: |
+
+ class Store(object):
+ time: uint64
+ genesis_time: uint64
+ justified_checkpoint: Checkpoint
+ finalized_checkpoint: Checkpoint
+ unrealized_justified_checkpoint: Checkpoint
+ unrealized_finalized_checkpoint: Checkpoint
+ proposer_boost_root: Root
+ equivocating_indices: Set[ValidatorIndex]
+ blocks: Dict[Root, BeaconBlock] = field(default_factory=dict)
+ block_states: Dict[Root, BeaconState] = field(default_factory=dict)
+ block_timeliness: Dict[Root, Vector[boolean, NUM_BLOCK_TIMELINESS_DEADLINES]] = field(
+ default_factory=dict
+ )
+ checkpoint_states: Dict[Checkpoint, BeaconState] = field(default_factory=dict)
+ latest_messages: Dict[ValidatorIndex, LatestMessage] = field(default_factory=dict)
+ unrealized_justifications: Dict[Root, Checkpoint] = field(default_factory=dict)
+ payload_states: Dict[Root, BeaconState] = field(default_factory=dict)
+ payload_timeliness_vote: Dict[Root, Vector[boolean, PTC_SIZE]] = field(default_factory=dict)
+ payload_data_availability_vote: Dict[Root, Vector[boolean, PTC_SIZE]] = field(
+ default_factory=dict
+ )
+ # [New in Heze:EIP7805]
+ payload_inclusion_list_satisfaction: Dict[Root, boolean] = field(default_factory=dict)
diff --git a/specrefs/functions.yml b/specrefs/functions.yml
index 94a3fa3c33f8..378b8d65dfbd 100644
--- a/specrefs/functions.yml
+++ b/specrefs/functions.yml
@@ -440,6 +440,17 @@
return Epoch(epoch + 1 + MAX_SEED_LOOKAHEAD)
+- name: compute_attestation_subnet_prefix_bits#phase0
+ sources: []
+ spec: |
+
+ def compute_attestation_subnet_prefix_bits() -> uint64:
+ """
+ Return the number of NodeId bits to use when mapping to a subscribed subnet.
+ """
+ return uint64(ceillog2(ATTESTATION_SUBNET_COUNT) + ATTESTATION_SUBNET_EXTRA_BITS)
+
+
- name: compute_balance_weighted_acceptance#gloas
sources: []
spec: |
@@ -871,6 +882,33 @@
return GENESIS_FORK_VERSION
+- name: compute_fork_version#heze
+ sources: []
+ spec: |
+
+ def compute_fork_version(epoch: Epoch) -> Version:
+ """
+ Return the fork version at the given ``epoch``.
+ """
+ if epoch >= HEZE_FORK_EPOCH:
+ return HEZE_FORK_VERSION
+ if epoch >= GLOAS_FORK_EPOCH:
+ return GLOAS_FORK_VERSION
+ if epoch >= FULU_FORK_EPOCH:
+ return FULU_FORK_VERSION
+ if epoch >= ELECTRA_FORK_EPOCH:
+ return ELECTRA_FORK_VERSION
+ if epoch >= DENEB_FORK_EPOCH:
+ return DENEB_FORK_VERSION
+ if epoch >= CAPELLA_FORK_EPOCH:
+ return CAPELLA_FORK_VERSION
+ if epoch >= BELLATRIX_FORK_EPOCH:
+ return BELLATRIX_FORK_VERSION
+ if epoch >= ALTAIR_FORK_EPOCH:
+ return ALTAIR_FORK_VERSION
+ return GENESIS_FORK_VERSION
+
+
- name: compute_matrix#fulu
sources: []
spec: |
@@ -897,6 +935,40 @@
return matrix
+- name: compute_max_request_blob_sidecars#deneb
+ sources: []
+ spec: |
+
+ def compute_max_request_blob_sidecars() -> uint64:
+ """
+ Return the maximum number of blob sidecars in a single request.
+ """
+ return uint64(MAX_REQUEST_BLOCKS_DENEB * MAX_BLOBS_PER_BLOCK)
+
+
+- name: compute_max_request_blob_sidecars#electra
+ sources: []
+ spec: |
+
+ def compute_max_request_blob_sidecars() -> uint64:
+ """
+ Return the maximum number of blob sidecars in a single request.
+ """
+ # [Modified in Electra:EIP7691]
+ return uint64(MAX_REQUEST_BLOCKS_DENEB * MAX_BLOBS_PER_BLOCK_ELECTRA)
+
+
+- name: compute_max_request_data_column_sidecars#fulu
+ sources: []
+ spec: |
+
+ def compute_max_request_data_column_sidecars() -> uint64:
+ """
+ Return the maximum number of data column sidecars in a single request.
+ """
+ return uint64(MAX_REQUEST_BLOCKS_DENEB * NUMBER_OF_COLUMNS)
+
+
- name: compute_merkle_proof#altair
sources: []
spec: |
@@ -904,6 +976,17 @@
def compute_merkle_proof(object: SSZObject, index: GeneralizedIndex) -> Sequence[Bytes32]: ...
+- name: compute_min_epochs_for_block_requests#phase0
+ sources: []
+ spec: |
+
+ def compute_min_epochs_for_block_requests() -> uint64:
+ """
+ Return the minimum epoch range over which a node must serve blocks.
+ """
+ return uint64(MIN_VALIDATOR_WITHDRAWABILITY_DELAY + CHURN_LIMIT_QUOTIENT // 2)
+
+
- name: compute_new_state_root#phase0
sources:
- file: beacon-chain/rpc/prysm/v1alpha1/validator/proposer.go
@@ -1050,6 +1133,27 @@
return (committee_weight * PROPOSER_SCORE_BOOST) // 100
+- name: compute_ptc#gloas
+ sources: []
+ spec: |
+
+ def compute_ptc(state: BeaconState, slot: Slot) -> Vector[ValidatorIndex, PTC_SIZE]:
+ """
+ Get the payload timeliness committee for the given ``slot``.
+ """
+ epoch = compute_epoch_at_slot(slot)
+ seed = hash(get_seed(state, epoch, DOMAIN_PTC_ATTESTER) + uint_to_bytes(slot))
+ indices: List[ValidatorIndex] = []
+ # Concatenate all committees for this slot in order
+ committees_per_slot = get_committee_count_per_slot(state, epoch)
+ for i in range(committees_per_slot):
+ committee = get_beacon_committee(state, slot, CommitteeIndex(i))
+ indices.extend(committee)
+ return compute_balance_weighted_selection(
+ state, indices, seed, size=PTC_SIZE, shuffle_indices=False
+ )
+
+
- name: compute_pulled_up_tip#phase0
sources: []
spec: |
@@ -1243,16 +1347,17 @@
- file: beacon-chain/p2p/subnets.go
search: func computeSubscribedSubnet(
spec: |
-
+
def compute_subscribed_subnet(node_id: NodeID, epoch: Epoch, index: int) -> SubnetID:
- node_id_prefix = node_id >> (NODE_ID_BITS - ATTESTATION_SUBNET_PREFIX_BITS)
+ prefix_bits = int(compute_attestation_subnet_prefix_bits())
+ node_id_prefix = node_id >> (NODE_ID_BITS - prefix_bits)
node_offset = node_id % EPOCHS_PER_SUBNET_SUBSCRIPTION
permutation_seed = hash(
uint_to_bytes(uint64((epoch + node_offset) // EPOCHS_PER_SUBNET_SUBSCRIPTION))
)
permutated_prefix = compute_shuffled_index(
node_id_prefix,
- 1 << ATTESTATION_SUBNET_PREFIX_BITS,
+ 1 << prefix_bits,
permutation_seed,
)
return SubnetID((permutated_prefix + index) % ATTESTATION_SUBNET_COUNT)
@@ -1291,10 +1396,22 @@
- file: time/slots/slottime.go
search: func StartTime(
spec: |
-
+
def compute_time_at_slot(state: BeaconState, slot: Slot) -> uint64:
slots_since_genesis = slot - GENESIS_SLOT
- return uint64(state.genesis_time + slots_since_genesis * SECONDS_PER_SLOT)
+ return uint64(state.genesis_time + slots_since_genesis * SLOT_DURATION_MS // 1000)
+
+
+- name: compute_time_at_slot_ms#phase0
+ sources: []
+ spec: |
+
+ def compute_time_at_slot_ms(state: BeaconState, slot: Slot) -> uint64:
+ """
+ Return the time in milliseconds at the start of the given slot.
+ """
+ slots_since_genesis = slot - GENESIS_SLOT
+ return uint64(state.genesis_time * 1000 + slots_since_genesis * SLOT_DURATION_MS)
- name: compute_weak_subjectivity_period#phase0
@@ -3220,7 +3337,7 @@
- name: get_forkchoice_store#phase0
sources: []
spec: |
-
+
def get_forkchoice_store(anchor_state: BeaconState, anchor_block: BeaconBlock) -> Store:
assert anchor_block.state_root == hash_tree_root(anchor_state)
anchor_root = hash_tree_root(anchor_block)
@@ -3229,7 +3346,7 @@
finalized_checkpoint = Checkpoint(epoch=anchor_epoch, root=anchor_root)
proposer_boost_root = Root()
return Store(
- time=uint64(anchor_state.genesis_time + SECONDS_PER_SLOT * anchor_state.slot),
+ time=uint64(anchor_state.genesis_time + SLOT_DURATION_MS * anchor_state.slot // 1000),
genesis_time=anchor_state.genesis_time,
justified_checkpoint=justified_checkpoint,
finalized_checkpoint=finalized_checkpoint,
@@ -3247,7 +3364,7 @@
- name: get_forkchoice_store#gloas
sources: []
spec: |
-
+
def get_forkchoice_store(anchor_state: BeaconState, anchor_block: BeaconBlock) -> Store:
assert anchor_block.state_root == hash_tree_root(anchor_state)
anchor_root = hash_tree_root(anchor_block)
@@ -3256,7 +3373,7 @@
finalized_checkpoint = Checkpoint(epoch=anchor_epoch, root=anchor_root)
proposer_boost_root = Root()
return Store(
- time=uint64(anchor_state.genesis_time + SECONDS_PER_SLOT * anchor_state.slot),
+ time=uint64(anchor_state.genesis_time + SLOT_DURATION_MS * anchor_state.slot // 1000),
genesis_time=anchor_state.genesis_time,
justified_checkpoint=justified_checkpoint,
finalized_checkpoint=finalized_checkpoint,
@@ -3266,12 +3383,57 @@
equivocating_indices=set(),
blocks={anchor_root: copy(anchor_block)},
block_states={anchor_root: copy(anchor_state)},
+ # [New in Gloas:EIP7732]
+ block_timeliness={anchor_root: [True, True]},
checkpoint_states={justified_checkpoint: copy(anchor_state)},
unrealized_justifications={anchor_root: justified_checkpoint},
# [New in Gloas:EIP7732]
- execution_payload_states={anchor_root: copy(anchor_state)},
- ptc_vote={anchor_root: Vector[boolean, PTC_SIZE]()},
+ payload_states={anchor_root: copy(anchor_state)},
+ # [New in Gloas:EIP7732]
+ payload_timeliness_vote={
+ anchor_root: Vector[boolean, PTC_SIZE](True for _ in range(PTC_SIZE))
+ },
+ # [New in Gloas:EIP7732]
+ payload_data_availability_vote={
+ anchor_root: Vector[boolean, PTC_SIZE](True for _ in range(PTC_SIZE))
+ },
+ )
+
+
+- name: get_forkchoice_store#heze
+ sources: []
+ spec: |
+
+ def get_forkchoice_store(anchor_state: BeaconState, anchor_block: BeaconBlock) -> Store:
+ assert anchor_block.state_root == hash_tree_root(anchor_state)
+ anchor_root = hash_tree_root(anchor_block)
+ anchor_epoch = get_current_epoch(anchor_state)
+ justified_checkpoint = Checkpoint(epoch=anchor_epoch, root=anchor_root)
+ finalized_checkpoint = Checkpoint(epoch=anchor_epoch, root=anchor_root)
+ proposer_boost_root = Root()
+ return Store(
+ time=uint64(anchor_state.genesis_time + SLOT_DURATION_MS * anchor_state.slot // 1000),
+ genesis_time=anchor_state.genesis_time,
+ justified_checkpoint=justified_checkpoint,
+ finalized_checkpoint=finalized_checkpoint,
+ unrealized_justified_checkpoint=justified_checkpoint,
+ unrealized_finalized_checkpoint=finalized_checkpoint,
+ proposer_boost_root=proposer_boost_root,
+ equivocating_indices=set(),
+ blocks={anchor_root: copy(anchor_block)},
+ block_states={anchor_root: copy(anchor_state)},
block_timeliness={anchor_root: [True, True]},
+ checkpoint_states={justified_checkpoint: copy(anchor_state)},
+ unrealized_justifications={anchor_root: justified_checkpoint},
+ payload_states={anchor_root: copy(anchor_state)},
+ payload_timeliness_vote={
+ anchor_root: Vector[boolean, PTC_SIZE](True for _ in range(PTC_SIZE))
+ },
+ payload_data_availability_vote={
+ anchor_root: Vector[boolean, PTC_SIZE](True for _ in range(PTC_SIZE))
+ },
+ # [New in Heze:EIP7805]
+ payload_inclusion_list_satisfaction={anchor_root: True},
)
@@ -3455,6 +3617,133 @@
return rewards, penalties
+- name: get_inclusion_list_bits#heze
+ sources: []
+ spec: |
+
+ def get_inclusion_list_bits(
+ store: InclusionListStore, state: BeaconState, slot: Slot
+ ) -> Bitvector[INCLUSION_LIST_COMMITTEE_SIZE]:
+ """
+ Return a ``Bitvector`` over inclusion list committee indices with bits set
+ for valid, non-equivocating inclusion list submissions for the given ``slot``.
+ """
+ inclusion_list_committee = get_inclusion_list_committee(state, slot)
+ inclusion_list_committee_root = hash_tree_root(inclusion_list_committee)
+ key = (slot, inclusion_list_committee_root)
+
+ validator_indices = [
+ inclusion_list.validator_index
+ for inclusion_list in store.inclusion_lists[key]
+ if inclusion_list.validator_index not in store.equivocators[key]
+ ]
+
+ return Bitvector[INCLUSION_LIST_COMMITTEE_SIZE](
+ validator_index in validator_indices for validator_index in inclusion_list_committee
+ )
+
+
+- name: get_inclusion_list_committee#heze
+ sources: []
+ spec: |
+
+ def get_inclusion_list_committee(
+ state: BeaconState, slot: Slot
+ ) -> Vector[ValidatorIndex, INCLUSION_LIST_COMMITTEE_SIZE]:
+ """
+ Get the inclusion list committee for the given ``slot``.
+ """
+ epoch = compute_epoch_at_slot(slot)
+ indices: List[ValidatorIndex] = []
+ # Concatenate all committees for this slot in order
+ committees_per_slot = get_committee_count_per_slot(state, epoch)
+ for i in range(committees_per_slot):
+ committee = get_beacon_committee(state, slot, CommitteeIndex(i))
+ indices.extend(committee)
+ return Vector[ValidatorIndex, INCLUSION_LIST_COMMITTEE_SIZE](
+ [indices[i % len(indices)] for i in range(INCLUSION_LIST_COMMITTEE_SIZE)]
+ )
+
+
+- name: get_inclusion_list_committee_assignment#heze
+ sources: []
+ spec: |
+
+ def get_inclusion_list_committee_assignment(
+ state: BeaconState, epoch: Epoch, validator_index: ValidatorIndex
+ ) -> Optional[Slot]:
+ """
+ Returns the slot during the requested epoch in which the validator with
+ index ``validator_index`` is a member of the inclusion list committee.
+ Returns None if no assignment is found.
+ """
+ next_epoch = Epoch(get_current_epoch(state) + 1)
+ assert epoch <= next_epoch
+
+ start_slot = compute_start_slot_at_epoch(epoch)
+ for slot in range(start_slot, start_slot + SLOTS_PER_EPOCH):
+ if validator_index in get_inclusion_list_committee(state, Slot(slot)):
+ return Slot(slot)
+ return None
+
+
+- name: get_inclusion_list_signature#heze
+ sources: []
+ spec: |
+
+ def get_inclusion_list_signature(
+ state: BeaconState, inclusion_list: InclusionList, privkey: int
+ ) -> BLSSignature:
+ domain = get_domain(
+ state, DOMAIN_INCLUSION_LIST_COMMITTEE, compute_epoch_at_slot(inclusion_list.slot)
+ )
+ signing_root = compute_signing_root(inclusion_list, domain)
+ return bls.Sign(privkey, signing_root)
+
+
+- name: get_inclusion_list_store#heze
+ sources: []
+ spec: |
+
+ def get_inclusion_list_store() -> InclusionListStore:
+ # `cached_or_new_inclusion_list_store` is implementation and context dependent.
+ # It returns the cached `InclusionListStore`; if none exists,
+ # it initializes a new instance, caches it and returns it.
+ inclusion_list_store = cached_or_new_inclusion_list_store()
+
+ return inclusion_list_store
+
+
+- name: get_inclusion_list_submission_due_ms#heze
+ sources: []
+ spec: |
+
+ def get_inclusion_list_submission_due_ms(epoch: Epoch) -> uint64:
+ return get_slot_component_duration_ms(INCLUSION_LIST_SUBMISSION_DUE_BPS)
+
+
+- name: get_inclusion_list_transactions#heze
+ sources: []
+ spec: |
+
+ def get_inclusion_list_transactions(
+ store: InclusionListStore, state: BeaconState, slot: Slot
+ ) -> Sequence[Transaction]:
+ inclusion_list_committee = get_inclusion_list_committee(state, slot)
+ inclusion_list_committee_root = hash_tree_root(inclusion_list_committee)
+ key = (slot, inclusion_list_committee_root)
+
+ inclusion_list_transactions = [
+ transaction
+ for inclusion_list in store.inclusion_lists[key]
+ if inclusion_list.validator_index not in store.equivocators[key]
+ for transaction in inclusion_list.transactions
+ ]
+
+ # Deduplicate inclusion list transactions. Order does not need to be preserved.
+ return list(set(inclusion_list_transactions))
+
+
- name: get_index_for_new_builder#gloas
sources: []
spec: |
@@ -3783,13 +4072,13 @@
- name: get_node_children#gloas
sources: []
spec: |
-
+
def get_node_children(
store: Store, blocks: Dict[Root, BeaconBlock], node: ForkChoiceNode
) -> Sequence[ForkChoiceNode]:
if node.payload_status == PAYLOAD_STATUS_PENDING:
children = [ForkChoiceNode(root=node.root, payload_status=PAYLOAD_STATUS_EMPTY)]
- if node.root in store.execution_payload_states:
+ if node.root in store.payload_states:
children.append(ForkChoiceNode(root=node.root, payload_status=PAYLOAD_STATUS_FULL))
return children
else:
@@ -4028,6 +4317,14 @@
return head_root
+- name: get_proposer_inclusion_list_cutoff_ms#heze
+ sources: []
+ spec: |
+
+ def get_proposer_inclusion_list_cutoff_ms(epoch: Epoch) -> uint64:
+ return get_slot_component_duration_ms(PROPOSER_INCLUSION_LIST_CUTOFF_BPS)
+
+
- name: get_proposer_preferences_signature#gloas
sources: []
spec: |
@@ -4072,28 +4369,25 @@
- name: get_ptc#gloas
sources: []
spec: |
-
+
def get_ptc(state: BeaconState, slot: Slot) -> Vector[ValidatorIndex, PTC_SIZE]:
"""
Get the payload timeliness committee for the given ``slot``.
"""
epoch = compute_epoch_at_slot(slot)
- seed = hash(get_seed(state, epoch, DOMAIN_PTC_ATTESTER) + uint_to_bytes(slot))
- indices: List[ValidatorIndex] = []
- # Concatenate all committees for this slot in order
- committees_per_slot = get_committee_count_per_slot(state, epoch)
- for i in range(committees_per_slot):
- committee = get_beacon_committee(state, slot, CommitteeIndex(i))
- indices.extend(committee)
- return compute_balance_weighted_selection(
- state, indices, seed, size=PTC_SIZE, shuffle_indices=False
- )
+ state_epoch = get_current_epoch(state)
+ if epoch < state_epoch:
+ assert epoch + 1 == state_epoch
+ return state.ptc_window[slot % SLOTS_PER_EPOCH]
+ assert epoch <= state_epoch + MIN_SEED_LOOKAHEAD
+ offset = (epoch - state_epoch + 1) * SLOTS_PER_EPOCH
+ return state.ptc_window[offset + slot % SLOTS_PER_EPOCH]
- name: get_ptc_assignment#gloas
sources: []
spec: |
-
+
def get_ptc_assignment(
state: BeaconState, epoch: Epoch, validator_index: ValidatorIndex
) -> Optional[Slot]:
@@ -4102,8 +4396,8 @@
index ``validator_index`` is a member of the PTC. Returns None if no
assignment is found.
"""
- next_epoch = Epoch(get_current_epoch(state) + 1)
- assert epoch <= next_epoch
+ max_epoch = Epoch(get_current_epoch(state) + MIN_SEED_LOOKAHEAD)
+ assert epoch <= max_epoch
start_slot = compute_start_slot_at_epoch(epoch)
for slot in range(start_slot, start_slot + SLOTS_PER_EPOCH):
@@ -4181,9 +4475,9 @@
- file: time/slots/slottime.go
search: func CurrentSlot(
spec: |
-
+
def get_slots_since_genesis(store: Store) -> int:
- return (store.time - store.genesis_time) // SECONDS_PER_SLOT
+ return (store.time - store.genesis_time) * 1000 // SLOT_DURATION_MS
- name: get_source_deltas#phase0
@@ -4397,18 +4691,23 @@
- name: get_upcoming_proposal_slots#gloas
sources: []
spec: |
-
+
def get_upcoming_proposal_slots(
state: BeaconState, validator_index: ValidatorIndex
) -> Sequence[Slot]:
"""
- Get the slots in the next epoch for which ``validator_index`` is proposing.
+ Get the future slots in the current epoch and the slots in the next
+ epoch for which ``validator_index`` is proposing.
"""
- return [
- Slot(compute_start_slot_at_epoch(get_current_epoch(state) + Epoch(1)) + offset)
- for offset, proposer_index in enumerate(state.proposer_lookahead[SLOTS_PER_EPOCH:])
- if validator_index == proposer_index
- ]
+ current_epoch_start_slot = compute_start_slot_at_epoch(get_current_epoch(state))
+ upcoming_proposal_slots = []
+ for offset, proposer_index in enumerate(state.proposer_lookahead):
+ slot = Slot(current_epoch_start_slot + offset)
+ if slot <= state.slot:
+ continue
+ if validator_index == proposer_index:
+ upcoming_proposal_slots.append(slot)
+ return upcoming_proposal_slots
- name: get_validator_activation_churn_limit#deneb
@@ -4615,6 +4914,14 @@
return withdrawals, withdrawal_index, processed_count
+- name: get_view_freeze_cutoff_ms#heze
+ sources: []
+ spec: |
+
+ def get_view_freeze_cutoff_ms(epoch: Epoch) -> uint64:
+ return get_slot_component_duration_ms(VIEW_FREEZE_CUTOFF_BPS)
+
+
- name: get_voting_source#phase0
sources: []
spec: |
@@ -4859,6 +5166,32 @@
return lookahead
+- name: initialize_ptc_window#gloas
+ sources: []
+ spec: |
+
+ def initialize_ptc_window(
+ state: BeaconState,
+ ) -> Vector[Vector[ValidatorIndex, PTC_SIZE], (2 + MIN_SEED_LOOKAHEAD) * SLOTS_PER_EPOCH]:
+ """
+ Return the cached PTC window starting from the current epoch.
+ Used to initialize the ``ptc_window`` field in the beacon state at genesis and after forks.
+ """
+ empty_previous_epoch = [
+ Vector[ValidatorIndex, PTC_SIZE]([ValidatorIndex(0) for _ in range(PTC_SIZE)])
+ for _ in range(SLOTS_PER_EPOCH)
+ ]
+
+ ptcs = []
+ current_epoch = get_current_epoch(state)
+ for e in range(1 + MIN_SEED_LOOKAHEAD):
+ epoch = Epoch(current_epoch + e)
+ start_slot = compute_start_slot_at_epoch(epoch)
+ ptcs += [compute_ptc(state, Slot(start_slot + i)) for i in range(SLOTS_PER_EPOCH)]
+
+ return empty_previous_epoch + ptcs
+
+
- name: initiate_builder_exit#gloas
sources:
- file: beacon-chain/core/gloas/builder_exit.go
@@ -5383,6 +5716,30 @@
return get_finality_delay(state) > MIN_EPOCHS_TO_INACTIVITY_PENALTY
+- name: is_inclusion_list_bits_inclusive#heze
+ sources: []
+ spec: |
+
+ def is_inclusion_list_bits_inclusive(
+ store: InclusionListStore,
+ state: BeaconState,
+ slot: Slot,
+ inclusion_list_bits: Bitvector[INCLUSION_LIST_COMMITTEE_SIZE],
+ ) -> bool:
+ """
+ Return ``True`` if and only if ``inclusion_list_bits`` is a superset of
+ the locally observed inclusion list bits for the given ``slot``.
+ """
+ local_inclusion_list_bits = get_inclusion_list_bits(store, state, slot)
+
+ return all(
+ inclusion_bit or not local_inclusion_bit
+ for inclusion_bit, local_inclusion_bit in zip(
+ inclusion_list_bits, local_inclusion_list_bits
+ )
+ )
+
+
- name: is_merge_transition_block#bellatrix
sources: []
spec: |
@@ -5409,6 +5766,23 @@
return store.next_sync_committee != SyncCommittee()
+- name: is_not_from_future_slot#phase0
+ sources: []
+ spec: |
+
+ def is_not_from_future_slot(
+ state: BeaconState,
+ slot: Slot,
+ current_time_ms: uint64,
+ ) -> bool:
+ """
+ Check if the given slot is not from the future
+ (with MAXIMUM_GOSSIP_CLOCK_DISPARITY allowance).
+ """
+ slot_time_ms = compute_time_at_slot_ms(state, slot)
+ return current_time_ms + MAXIMUM_GOSSIP_CLOCK_DISPARITY >= slot_time_ms
+
+
- name: is_optimistic#bellatrix
sources:
- file: beacon-chain/blockchain/chain_info.go
@@ -5523,48 +5897,109 @@
)
-- name: is_payload_timely#gloas
+- name: is_payload_data_available#gloas
sources: []
spec: |
-
- def is_payload_timely(store: Store, root: Root) -> bool:
+
+ def is_payload_data_available(store: Store, root: Root) -> bool:
"""
- Return whether the execution payload for the beacon block with root ``root``
+ Return whether the blob data for the beacon block with root ``root``
was voted as present by the PTC, and was locally determined to be available.
"""
# The beacon block root must be known
- assert root in store.ptc_vote
+ assert root in store.payload_data_availability_vote
- # If the payload is not locally available, the payload
+ # If the payload is not locally available, the blob data
# is not considered available regardless of the PTC vote
- if root not in store.execution_payload_states:
+ if root not in store.payload_states:
return False
- return sum(store.ptc_vote[root]) > PAYLOAD_TIMELY_THRESHOLD
+ return sum(store.payload_data_availability_vote[root]) > DATA_AVAILABILITY_TIMELY_THRESHOLD
-- name: is_proposer#phase0
+- name: is_payload_inclusion_list_satisfied#heze
sources: []
spec: |
-
- def is_proposer(state: BeaconState, validator_index: ValidatorIndex) -> bool:
- return get_beacon_proposer_index(state) == validator_index
+
+ def is_payload_inclusion_list_satisfied(store: Store, root: Root) -> bool:
+ """
+ Return whether the execution payload for the beacon block with root ``root``
+ satisfied the inclusion list constraints, and was locally determined to be available.
+ """
+ # The beacon block root must be known
+ assert root in store.payload_inclusion_list_satisfaction
+
+ # If the payload is not locally available, the payload
+ # is not considered to satisfy the inclusion list constraints
+ if root not in store.payload_states:
+ return False
+
+ return store.payload_inclusion_list_satisfaction[root]
-- name: is_proposer_equivocation#phase0
+- name: is_payload_timely#gloas
sources: []
spec: |
-
- def is_proposer_equivocation(store: Store, root: Root) -> bool:
- block = store.blocks[root]
- proposer_index = block.proposer_index
- slot = block.slot
- # roots from the same slot and proposer
- matching_roots = [
- root
- for root, block in store.blocks.items()
- if (block.proposer_index == proposer_index and block.slot == slot)
- ]
+
+ def is_payload_timely(store: Store, root: Root) -> bool:
+ """
+ Return whether the execution payload for the beacon block with root ``root``
+ was voted as present by the PTC, and was locally determined to be available.
+ """
+ # The beacon block root must be known
+ assert root in store.payload_timeliness_vote
+
+ # If the payload is not locally available, the payload
+ # is not considered available regardless of the PTC vote
+ if root not in store.payload_states:
+ return False
+
+ return sum(store.payload_timeliness_vote[root]) > PAYLOAD_TIMELY_THRESHOLD
+
+
+- name: is_pending_validator#gloas
+ sources: []
+ spec: |
+
+ def is_pending_validator(state: BeaconState, pubkey: BLSPubkey) -> bool:
+ """
+ Check if a pending deposit with a valid signature is in the queue for the given pubkey.
+ """
+ for pending_deposit in state.pending_deposits:
+ if pending_deposit.pubkey != pubkey:
+ continue
+ if is_valid_deposit_signature(
+ pending_deposit.pubkey,
+ pending_deposit.withdrawal_credentials,
+ pending_deposit.amount,
+ pending_deposit.signature,
+ ):
+ return True
+ return False
+
+
+- name: is_proposer#phase0
+ sources: []
+ spec: |
+
+ def is_proposer(state: BeaconState, validator_index: ValidatorIndex) -> bool:
+ return get_beacon_proposer_index(state) == validator_index
+
+
+- name: is_proposer_equivocation#phase0
+ sources: []
+ spec: |
+
+ def is_proposer_equivocation(store: Store, root: Root) -> bool:
+ block = store.blocks[root]
+ proposer_index = block.proposer_index
+ slot = block.slot
+ # roots from the same slot and proposer
+ matching_roots = [
+ root
+ for root, block in store.blocks.items()
+ if (block.proposer_index == proposer_index and block.slot == slot)
+ ]
return len(matching_roots) > 1
@@ -5625,11 +6060,11 @@
- name: is_supporting_vote#gloas
sources: []
spec: |
-
+
def is_supporting_vote(store: Store, node: ForkChoiceNode, message: LatestMessage) -> bool:
"""
- Returns whether a vote for ``message.root`` supports the chain containing the beacon block ``node.root`` with the
- payload contents indicated by ``node.payload_status`` as head during slot ``node.slot``.
+ Returns whether the vote ``message`` supports the chain containing the
+ forkchoice node ``node``.
"""
block = store.blocks[node.root]
if node.root == message.root:
@@ -5711,6 +6146,24 @@
return True
+- name: is_valid_inclusion_list_signature#heze
+ sources: []
+ spec: |
+
+ def is_valid_inclusion_list_signature(
+ state: BeaconState, signed_inclusion_list: SignedInclusionList
+ ) -> bool:
+ """
+ Check if ``signed_inclusion_list`` has a valid signature.
+ """
+ message = signed_inclusion_list.message
+ index = message.validator_index
+ pubkey = state.validators[index].pubkey
+ domain = get_domain(state, DOMAIN_INCLUSION_LIST_COMMITTEE, compute_epoch_at_slot(message.slot))
+ signing_root = compute_signing_root(message, domain)
+ return bls.Verify(pubkey, signing_root, signed_inclusion_list.signature)
+
+
- name: is_valid_indexed_attestation#phase0
sources:
- file: beacon-chain/core/blocks/attestation.go
@@ -5854,12 +6307,21 @@
- name: is_valid_proposal_slot#gloas
sources: []
spec: |
-
+
def is_valid_proposal_slot(state: BeaconState, preferences: ProposerPreferences) -> bool:
"""
- Check if the validator is the proposer for the given slot in the next epoch.
+ Check if the validator is the proposer for the given slot in the current or
+ next epoch.
"""
- index = SLOTS_PER_EPOCH + preferences.proposal_slot % SLOTS_PER_EPOCH
+ current_epoch = get_current_epoch(state)
+ proposal_epoch = compute_epoch_at_slot(preferences.proposal_slot)
+ if proposal_epoch < current_epoch:
+ return False
+ if proposal_epoch > current_epoch + Epoch(1):
+ return False
+
+ index = (proposal_epoch - current_epoch) * SLOTS_PER_EPOCH
+ index += preferences.proposal_slot % SLOTS_PER_EPOCH
return state.proposer_lookahead[index] == preferences.validator_index
@@ -5916,6 +6378,29 @@
return is_total_difficulty_reached and is_parent_total_difficulty_valid
+- name: is_within_slot_range#phase0
+ sources: []
+ spec: |
+
+ def is_within_slot_range(
+ state: BeaconState,
+ slot: Slot,
+ slot_range: uint64,
+ current_time_ms: uint64,
+ ) -> bool:
+ """
+ Check if the current time is within the inclusive slot range ``[slot, slot + slot_range]``
+ (with MAXIMUM_GOSSIP_CLOCK_DISPARITY allowance on both ends).
+ """
+ start_time_ms = compute_time_at_slot_ms(state, slot)
+ if current_time_ms + MAXIMUM_GOSSIP_CLOCK_DISPARITY < start_time_ms:
+ return False
+ end_time_ms = compute_time_at_slot_ms(state, Slot(slot + slot_range + 1))
+ if end_time_ms + MAXIMUM_GOSSIP_CLOCK_DISPARITY < current_time_ms:
+ return False
+ return True
+
+
- name: is_within_weak_subjectivity_period#phase0
sources:
- file: beacon-chain/core/helpers/weak_subjectivity.go
@@ -6367,7 +6852,7 @@
- name: on_block#gloas
sources: []
spec: |
-
+
def on_block(store: Store, signed_block: SignedBeaconBlock) -> None:
"""
Run ``on_block`` upon receiving a new block.
@@ -6382,8 +6867,8 @@
parent_bid = parent_block.body.signed_execution_payload_bid.message
# Make a copy of the state to avoid mutability issues
if is_parent_node_full(store, block):
- assert block.parent_root in store.execution_payload_states
- state = copy(store.execution_payload_states[block.parent_root])
+ assert block.parent_root in store.payload_states
+ state = copy(store.payload_states[block.parent_root])
else:
assert bid.parent_block_hash == parent_bid.parent_block_hash
state = copy(store.block_states[block.parent_root])
@@ -6412,7 +6897,8 @@
# Add new state for this block to the store
store.block_states[block_root] = state
# Add a new PTC voting for this block to the store
- store.ptc_vote[block_root] = [False] * PTC_SIZE
+ store.payload_timeliness_vote[block_root] = [False] * PTC_SIZE
+ store.payload_data_availability_vote[block_root] = [False] * PTC_SIZE
# Notify the store about the payload_attestations in the block
notify_ptc_messages(store, state, block.body.payload_attestations)
@@ -6430,7 +6916,33 @@
- name: on_execution_payload#gloas
sources: []
spec: |
-
+
+ def on_execution_payload(store: Store, signed_envelope: SignedExecutionPayloadEnvelope) -> None:
+ """
+ Run ``on_execution_payload`` upon receiving a new execution payload.
+ """
+ envelope = signed_envelope.message
+ # The corresponding beacon block root needs to be known
+ assert envelope.beacon_block_root in store.block_states
+
+ # Check if blob data is available
+ # If not, this payload MAY be queued and subsequently considered when blob data becomes available
+ assert is_data_available(envelope.beacon_block_root)
+
+ # Make a copy of the state to avoid mutability issues
+ state = copy(store.block_states[envelope.beacon_block_root])
+
+ # Process the execution payload
+ process_execution_payload(state, signed_envelope, EXECUTION_ENGINE)
+
+ # Add new state for this payload to the store
+ store.payload_states[envelope.beacon_block_root] = state
+
+
+- name: on_execution_payload#heze
+ sources: []
+ spec: |
+
def on_execution_payload(store: Store, signed_envelope: SignedExecutionPayloadEnvelope) -> None:
"""
Run ``on_execution_payload`` upon receiving a new execution payload.
@@ -6449,14 +6961,40 @@
# Process the execution payload
process_execution_payload(state, signed_envelope, EXECUTION_ENGINE)
+ # [New in Heze:EIP7805]
+ # Check if this payload satisfies the inclusion list constraints
+ # If not, add this payload to the store as inclusion list constraints unsatisfied
+ record_payload_inclusion_list_satisfaction(
+ store, state, envelope.beacon_block_root, envelope.payload, EXECUTION_ENGINE
+ )
+
# Add new state for this payload to the store
- store.execution_payload_states[envelope.beacon_block_root] = state
+ store.payload_states[envelope.beacon_block_root] = state
+
+
+- name: on_inclusion_list#heze
+ sources: []
+ spec: |
+
+ def on_inclusion_list(store: Store, signed_inclusion_list: SignedInclusionList) -> None:
+ """
+ Run ``on_inclusion_list`` upon receiving a new inclusion list.
+ """
+ inclusion_list = signed_inclusion_list.message
+
+ seconds_since_genesis = store.time - store.genesis_time
+ time_into_slot_ms = seconds_to_milliseconds(seconds_since_genesis) % SLOT_DURATION_MS
+ epoch = get_current_store_epoch(store)
+ view_freeze_cutoff_ms = get_view_freeze_cutoff_ms(epoch)
+ is_before_view_freeze_cutoff = time_into_slot_ms < view_freeze_cutoff_ms
+
+ process_inclusion_list(get_inclusion_list_store(), inclusion_list, is_before_view_freeze_cutoff)
- name: on_payload_attestation_message#gloas
sources: []
spec: |
-
+
def on_payload_attestation_message(
store: Store, ptc_message: PayloadAttestationMessage, is_from_block: bool = False
) -> None:
@@ -6467,6 +7005,7 @@
# The beacon block root must be known
data = ptc_message.data
# PTC attestation must be for a known block. If block is unknown, delay consideration until the block is found
+ assert data.beacon_block_root in store.block_states
state = store.block_states[data.beacon_block_root]
ptc = get_ptc(state, data.slot)
# PTC votes can only change the vote for their assigned beacon block, return early otherwise
@@ -6488,22 +7027,26 @@
signature=ptc_message.signature,
),
)
- # Update the ptc vote for the block
+ # Update the votes for the block
ptc_index = ptc.index(ptc_message.validator_index)
- ptc_vote = store.ptc_vote[data.beacon_block_root]
- ptc_vote[ptc_index] = data.payload_present
+ payload_timeliness_vote = store.payload_timeliness_vote[data.beacon_block_root]
+ payload_timeliness_vote[ptc_index] = data.payload_present
+ payload_data_availability_vote = store.payload_data_availability_vote[data.beacon_block_root]
+ payload_data_availability_vote[ptc_index] = data.blob_data_available
- name: on_tick#phase0
sources: []
spec: |
-
+
def on_tick(store: Store, time: uint64) -> None:
# If the ``store.time`` falls behind, while loop catches up slot by slot
# to ensure that every previous slot is processed with ``on_tick_per_slot``
- tick_slot = (time - store.genesis_time) // SECONDS_PER_SLOT
+ tick_slot = (time - store.genesis_time) * 1000 // SLOT_DURATION_MS
while get_current_slot(store) < tick_slot:
- previous_time = store.genesis_time + (get_current_slot(store) + 1) * SECONDS_PER_SLOT
+ previous_time = (
+ store.genesis_time + (get_current_slot(store) + 1) * SLOT_DURATION_MS // 1000
+ )
on_tick_per_slot(store, previous_time)
on_tick_per_slot(store, time)
@@ -6672,6 +7215,37 @@
)
+- name: prepare_execution_payload#heze
+ sources: []
+ spec: |
+
+ def prepare_execution_payload(
+ state: BeaconState,
+ safe_block_hash: Hash32,
+ finalized_block_hash: Hash32,
+ suggested_fee_recipient: ExecutionAddress,
+ execution_engine: ExecutionEngine,
+ ) -> Optional[PayloadId]:
+ # Set the forkchoice head and initiate the payload build process
+ payload_attributes = PayloadAttributes(
+ timestamp=compute_time_at_slot(state, state.slot),
+ prev_randao=get_randao_mix(state, get_current_epoch(state)),
+ suggested_fee_recipient=suggested_fee_recipient,
+ withdrawals=get_expected_withdrawals(state).withdrawals,
+ parent_beacon_block_root=hash_tree_root(state.latest_block_header),
+ # [New in Heze:EIP7805]
+ inclusion_list_transactions=get_inclusion_list_transactions(
+ get_inclusion_list_store(), state, Slot(state.slot - 1)
+ ),
+ )
+ return execution_engine.notify_forkchoice_updated(
+ head_block_hash=state.latest_block_hash,
+ safe_block_hash=safe_block_hash,
+ finalized_block_hash=finalized_block_hash,
+ payload_attributes=payload_attributes,
+ )
+
+
- name: process_attestation#phase0
sources:
- file: beacon-chain/core/blocks/attestation.go
@@ -7319,7 +7893,7 @@
- name: process_deposit_request#gloas
sources: []
spec: |
-
+
def process_deposit_request(state: BeaconState, deposit_request: DepositRequest) -> None:
# [New in Gloas:EIP7732]
builder_pubkeys = [b.pubkey for b in state.builders]
@@ -7330,8 +7904,11 @@
# already exists with this pubkey, apply the deposit to their balance
is_builder = deposit_request.pubkey in builder_pubkeys
is_validator = deposit_request.pubkey in validator_pubkeys
- is_builder_prefix = is_builder_withdrawal_credential(deposit_request.withdrawal_credentials)
- if is_builder or (is_builder_prefix and not is_validator):
+ if is_builder or (
+ is_builder_withdrawal_credential(deposit_request.withdrawal_credentials)
+ and not is_validator
+ and not is_pending_validator(state, deposit_request.pubkey)
+ ):
# Apply builder deposits immediately
apply_deposit_for_builder(
state,
@@ -7532,7 +8109,7 @@
- name: process_epoch#gloas
sources: []
spec: |
-
+
def process_epoch(state: BeaconState) -> None:
process_justification_and_finalization(state)
process_inactivity_updates(state)
@@ -7551,6 +8128,8 @@
process_participation_flag_updates(state)
process_sync_committee_updates(state)
process_proposer_lookahead(state)
+ # [New in Gloas:EIP7732]
+ process_ptc_window(state)
- name: process_eth1_data#phase0
@@ -8047,6 +8626,35 @@
)
+- name: process_inclusion_list#heze
+ sources: []
+ spec: |
+
+ def process_inclusion_list(
+ store: InclusionListStore, inclusion_list: InclusionList, is_before_view_freeze_cutoff: bool
+ ) -> None:
+ key = (inclusion_list.slot, inclusion_list.inclusion_list_committee_root)
+
+ # Ignore `inclusion_list` from equivocators.
+ if inclusion_list.validator_index in store.equivocators[key]:
+ return
+
+ for stored_inclusion_list in store.inclusion_lists[key]:
+ if stored_inclusion_list.validator_index != inclusion_list.validator_index:
+ continue
+
+ if stored_inclusion_list != inclusion_list:
+ store.equivocators[key].add(inclusion_list.validator_index)
+ store.inclusion_lists[key].remove(stored_inclusion_list)
+
+ # Whether it was an equivocation or not, we have processed this `inclusion_list`.
+ return
+
+ # Only store `inclusion_list` if it arrived before the view freeze cutoff.
+ if is_before_view_freeze_cutoff:
+ store.inclusion_lists[key].add(inclusion_list)
+
+
- name: process_justification_and_finalization#phase0
sources:
- file: beacon-chain/core/epoch/precompute/justification_finalization.go
@@ -8572,6 +9180,24 @@
slash_validator(state, header_1.proposer_index)
+- name: process_ptc_window#gloas
+ sources: []
+ spec: |
+
+ def process_ptc_window(state: BeaconState) -> None:
+ """
+ Update the cached PTC window.
+ """
+ # Shift all epochs forward by one
+ state.ptc_window[: len(state.ptc_window) - SLOTS_PER_EPOCH] = state.ptc_window[SLOTS_PER_EPOCH:]
+ # Fill in the last epoch
+ next_epoch = Epoch(get_current_epoch(state) + MIN_SEED_LOOKAHEAD + 1)
+ start_slot = compute_start_slot_at_epoch(next_epoch)
+ state.ptc_window[len(state.ptc_window) - SLOTS_PER_EPOCH :] = [
+ compute_ptc(state, Slot(slot)) for slot in range(start_slot, start_slot + SLOTS_PER_EPOCH)
+ ]
+
+
- name: process_randao#phase0
sources:
- file: beacon-chain/core/blocks/randao.go
@@ -9350,6 +9976,26 @@
]
+- name: record_payload_inclusion_list_satisfaction#heze
+ sources: []
+ spec: |
+
+ def record_payload_inclusion_list_satisfaction(
+ store: Store,
+ state: BeaconState,
+ root: Root,
+ payload: ExecutionPayload,
+ execution_engine: ExecutionEngine,
+ ) -> None:
+ inclusion_list_transactions = get_inclusion_list_transactions(
+ get_inclusion_list_store(), state, Slot(state.slot - 1)
+ )
+ is_inclusion_list_satisfied = execution_engine.is_inclusion_list_satisfied(
+ payload, inclusion_list_transactions
+ )
+ store.payload_inclusion_list_satisfaction[root] = is_inclusion_list_satisfied
+
+
- name: recover_matrix#fulu
sources: []
spec: |
@@ -9458,11 +10104,29 @@
- name: should_extend_payload#gloas
sources: []
spec: |
-
+
def should_extend_payload(store: Store, root: Root) -> bool:
proposer_root = store.proposer_boost_root
return (
- is_payload_timely(store, root)
+ (is_payload_timely(store, root) and is_payload_data_available(store, root))
+ or proposer_root == Root()
+ or store.blocks[proposer_root].parent_root != root
+ or is_parent_node_full(store, store.blocks[proposer_root])
+ )
+
+
+- name: should_extend_payload#heze
+ sources: []
+ spec: |
+
+ def should_extend_payload(store: Store, root: Root) -> bool:
+ # [New in Heze:EIP7805]
+ if not is_payload_inclusion_list_satisfied(store, root):
+ return False
+
+ proposer_root = store.proposer_boost_root
+ return (
+ (is_payload_timely(store, root) and is_payload_data_available(store, root))
or proposer_root == Root()
or store.blocks[proposer_root].parent_root != root
or is_parent_node_full(store, store.blocks[proposer_root])
@@ -9807,7 +10471,7 @@
- name: update_latest_messages#gloas
sources: []
spec: |
-
+
def update_latest_messages(
store: Store, attesting_indices: Sequence[ValidatorIndex], attestation: Attestation
) -> None:
@@ -9819,8 +10483,11 @@
]
for i in non_equivocating_attesting_indices:
if i not in store.latest_messages or slot > store.latest_messages[i].slot:
+ # [Modified in Gloas:EIP7732]
store.latest_messages[i] = LatestMessage(
- slot=slot, root=beacon_block_root, payload_present=payload_present
+ slot=slot,
+ root=beacon_block_root,
+ payload_present=payload_present,
)
@@ -10654,7 +11321,7 @@
- name: upgrade_to_gloas#gloas
sources: []
spec: |
-
+
def upgrade_to_gloas(pre: fulu.BeaconState) -> BeaconState:
epoch = fulu.get_current_epoch(pre)
@@ -10721,6 +11388,8 @@
latest_block_hash=pre.latest_execution_payload_header.block_hash,
# [New in Gloas:EIP7732]
payload_expected_withdrawals=[],
+ # [New in Gloas:EIP7732]
+ ptc_window=initialize_ptc_window(pre),
)
# [New in Gloas:EIP7732]
@@ -10729,6 +11398,431 @@
return post
+- name: upgrade_to_heze#heze
+ sources: []
+ spec: |
+
+ def upgrade_to_heze(pre: gloas.BeaconState) -> BeaconState:
+ epoch = gloas.get_current_epoch(pre)
+ latest_execution_payload_bid = ExecutionPayloadBid(
+ parent_block_hash=pre.latest_execution_payload_bid.parent_block_hash,
+ parent_block_root=pre.latest_execution_payload_bid.parent_block_root,
+ block_hash=pre.latest_execution_payload_bid.block_hash,
+ prev_randao=pre.latest_execution_payload_bid.prev_randao,
+ fee_recipient=pre.latest_execution_payload_bid.fee_recipient,
+ gas_limit=pre.latest_execution_payload_bid.gas_limit,
+ builder_index=pre.latest_execution_payload_bid.builder_index,
+ slot=pre.latest_execution_payload_bid.slot,
+ value=pre.latest_execution_payload_bid.value,
+ execution_payment=pre.latest_execution_payload_bid.execution_payment,
+ blob_kzg_commitments=pre.latest_execution_payload_bid.blob_kzg_commitments,
+ # [New in Heze:EIP7805]
+ inclusion_list_bits=Bitvector[INCLUSION_LIST_COMMITTEE_SIZE](),
+ )
+
+ post = BeaconState(
+ genesis_time=pre.genesis_time,
+ genesis_validators_root=pre.genesis_validators_root,
+ slot=pre.slot,
+ fork=Fork(
+ previous_version=pre.fork.current_version,
+ # [Modified in Heze:EIP7805]
+ current_version=HEZE_FORK_VERSION,
+ epoch=epoch,
+ ),
+ latest_block_header=pre.latest_block_header,
+ block_roots=pre.block_roots,
+ state_roots=pre.state_roots,
+ historical_roots=pre.historical_roots,
+ eth1_data=pre.eth1_data,
+ eth1_data_votes=pre.eth1_data_votes,
+ eth1_deposit_index=pre.eth1_deposit_index,
+ validators=pre.validators,
+ balances=pre.balances,
+ randao_mixes=pre.randao_mixes,
+ slashings=pre.slashings,
+ previous_epoch_participation=pre.previous_epoch_participation,
+ current_epoch_participation=pre.current_epoch_participation,
+ justification_bits=pre.justification_bits,
+ previous_justified_checkpoint=pre.previous_justified_checkpoint,
+ current_justified_checkpoint=pre.current_justified_checkpoint,
+ finalized_checkpoint=pre.finalized_checkpoint,
+ inactivity_scores=pre.inactivity_scores,
+ current_sync_committee=pre.current_sync_committee,
+ next_sync_committee=pre.next_sync_committee,
+ # [Modified in Heze:EIP7805]
+ latest_execution_payload_bid=latest_execution_payload_bid,
+ next_withdrawal_index=pre.next_withdrawal_index,
+ next_withdrawal_validator_index=pre.next_withdrawal_validator_index,
+ historical_summaries=pre.historical_summaries,
+ deposit_requests_start_index=pre.deposit_requests_start_index,
+ deposit_balance_to_consume=pre.deposit_balance_to_consume,
+ exit_balance_to_consume=pre.exit_balance_to_consume,
+ earliest_exit_epoch=pre.earliest_exit_epoch,
+ consolidation_balance_to_consume=pre.consolidation_balance_to_consume,
+ earliest_consolidation_epoch=pre.earliest_consolidation_epoch,
+ pending_deposits=pre.pending_deposits,
+ pending_partial_withdrawals=pre.pending_partial_withdrawals,
+ pending_consolidations=pre.pending_consolidations,
+ proposer_lookahead=pre.proposer_lookahead,
+ builders=pre.builders,
+ next_withdrawal_builder_index=pre.next_withdrawal_builder_index,
+ execution_payload_availability=pre.execution_payload_availability,
+ builder_pending_payments=pre.builder_pending_payments,
+ builder_pending_withdrawals=pre.builder_pending_withdrawals,
+ latest_block_hash=pre.latest_block_hash,
+ payload_expected_withdrawals=pre.payload_expected_withdrawals,
+ ptc_window=pre.ptc_window,
+ )
+
+ return post
+
+
+- name: validate_attester_slashing_gossip#phase0
+ sources: []
+ spec: |
+
+ def validate_attester_slashing_gossip(
+ seen: Seen,
+ state: BeaconState,
+ attester_slashing: AttesterSlashing,
+ ) -> None:
+ """
+ Validate an AttesterSlashing for gossip propagation.
+ Raises GossipIgnore or GossipReject on validation failure.
+ """
+ attestation_1 = attester_slashing.attestation_1
+ attestation_2 = attester_slashing.attestation_2
+
+ attesting_indices_1 = set(attestation_1.attesting_indices)
+ attesting_indices_2 = set(attestation_2.attesting_indices)
+ slashable_indices = attesting_indices_1.intersection(attesting_indices_2)
+
+ # [IGNORE] At least one index in the intersection has not yet been seen
+ new_indices = slashable_indices.difference(seen.attester_slashing_indices)
+ if len(new_indices) == 0:
+ raise GossipIgnore("all attester slashing indices already seen")
+
+ # [REJECT] The attestation data is slashable (double vote or surround vote)
+ if not is_slashable_attestation_data(attestation_1.data, attestation_2.data):
+ raise GossipReject("attestation data is not slashable")
+
+ # [REJECT] All validator indices in the first indexed attestation are valid
+ if any(index >= len(state.validators) for index in attestation_1.attesting_indices):
+ raise GossipReject("validator index out of range in indexed attestation 1")
+
+ # [REJECT] The first indexed attestation has valid properties
+ if not is_valid_indexed_attestation(state, attestation_1):
+ raise GossipReject("invalid indexed attestation 1")
+
+ # [REJECT] All validator indices in the second indexed attestation are valid
+ if any(index >= len(state.validators) for index in attestation_2.attesting_indices):
+ raise GossipReject("validator index out of range in indexed attestation 2")
+
+ # [REJECT] The second indexed attestation has valid properties
+ if not is_valid_indexed_attestation(state, attestation_2):
+ raise GossipReject("invalid indexed attestation 2")
+
+ # [REJECT] At least one validator in the intersection is slashable
+ slashable_any = False
+ current_epoch = get_current_epoch(state)
+ for index in slashable_indices:
+ if is_slashable_validator(state.validators[index], current_epoch):
+ slashable_any = True
+ break
+ if not slashable_any:
+ raise GossipReject("no slashable validators in intersection")
+
+ # Mark these indices as seen
+ seen.attester_slashing_indices.update(slashable_indices)
+
+
+- name: validate_beacon_aggregate_and_proof_gossip#phase0
+ sources: []
+ spec: |
+
+ def validate_beacon_aggregate_and_proof_gossip(
+ seen: Seen,
+ store: Store,
+ state: BeaconState,
+ signed_aggregate_and_proof: SignedAggregateAndProof,
+ current_time_ms: uint64,
+ ) -> None:
+ """
+ Validate a SignedAggregateAndProof for gossip propagation.
+ Raises GossipIgnore or GossipReject on validation failure.
+ """
+ aggregate_and_proof = signed_aggregate_and_proof.message
+ aggregate = aggregate_and_proof.aggregate
+ index = aggregate.data.index
+ aggregation_bits = aggregate.aggregation_bits
+
+ # [REJECT] The committee index is within the expected range
+ committee_count = get_committee_count_per_slot(state, aggregate.data.target.epoch)
+ if index >= committee_count:
+ raise GossipReject("committee index out of range")
+
+ # [IGNORE] The aggregate attestation's slot is within the propagation range
+ # (MAY be queued for processing at the appropriate slot)
+ if not is_within_slot_range(
+ state, aggregate.data.slot, ATTESTATION_PROPAGATION_SLOT_RANGE, current_time_ms
+ ):
+ raise GossipIgnore("attestation slot not within propagation range")
+
+ # [REJECT] The aggregate attestation's epoch matches its target
+ if aggregate.data.target.epoch != compute_epoch_at_slot(aggregate.data.slot):
+ raise GossipReject("attestation epoch does not match target epoch")
+
+ # [REJECT] The number of aggregation bits matches the committee size
+ committee = get_beacon_committee(state, aggregate.data.slot, index)
+ if len(aggregation_bits) != len(committee):
+ raise GossipReject("aggregation bits length does not match committee size")
+
+ # [REJECT] The aggregate attestation has participants
+ attesting_indices = get_attesting_indices(state, aggregate)
+ if len(attesting_indices) < 1:
+ raise GossipReject("aggregate has no participants")
+
+ # [IGNORE] A valid aggregate with a superset of aggregation bits has not already been seen
+ aggregate_data_root = hash_tree_root(aggregate.data)
+ aggregate_bits = tuple(bool(bit) for bit in aggregation_bits)
+ seen_aggregation_bits = seen.aggregate_data_roots.get(aggregate_data_root, set())
+ for prior_aggregation_bits in seen_aggregation_bits:
+ is_non_strict_superset = True
+ for prior_bit, aggregate_bit in zip(prior_aggregation_bits, aggregate_bits):
+ if aggregate_bit and not prior_bit:
+ is_non_strict_superset = False
+ break
+ if is_non_strict_superset:
+ raise GossipIgnore("already seen aggregate for this data")
+
+ # [IGNORE] This is the first valid aggregate for this aggregator in this epoch
+ aggregator_index = aggregate_and_proof.aggregator_index
+ target_epoch = aggregate.data.target.epoch
+ if (aggregator_index, target_epoch) in seen.aggregator_epochs:
+ raise GossipIgnore("already seen aggregate from this aggregator for this epoch")
+
+ # [REJECT] The selection proof selects the validator as an aggregator
+ if not is_aggregator(state, aggregate.data.slot, index, aggregate_and_proof.selection_proof):
+ raise GossipReject("validator is not selected as aggregator")
+
+ # [REJECT] The aggregator's validator index is within the committee
+ if aggregator_index not in committee:
+ raise GossipReject("aggregator index not in committee")
+
+ # [REJECT] The selection proof signature is valid
+ aggregator = state.validators[aggregator_index]
+ domain = get_domain(state, DOMAIN_SELECTION_PROOF, target_epoch)
+ signing_root = compute_signing_root(aggregate.data.slot, domain)
+ if not bls.Verify(aggregator.pubkey, signing_root, aggregate_and_proof.selection_proof):
+ raise GossipReject("invalid selection proof signature")
+
+ # [REJECT] The aggregator signature is valid
+ domain = get_domain(state, DOMAIN_AGGREGATE_AND_PROOF, target_epoch)
+ signing_root = compute_signing_root(aggregate_and_proof, domain)
+ if not bls.Verify(aggregator.pubkey, signing_root, signed_aggregate_and_proof.signature):
+ raise GossipReject("invalid aggregator signature")
+
+ # [REJECT] The aggregate signature is valid
+ if not is_valid_indexed_attestation(state, get_indexed_attestation(state, aggregate)):
+ raise GossipReject("invalid aggregate signature")
+
+ # [IGNORE] The block being voted for has been seen (via gossip or non-gossip sources)
+ # (MAY be queued until block is retrieved)
+ if aggregate.data.beacon_block_root not in store.blocks:
+ raise GossipIgnore("block being voted for has not been seen")
+
+ # [REJECT] The block being voted for passes validation
+ if aggregate.data.beacon_block_root not in store.block_states:
+ raise GossipReject("block being voted for failed validation")
+
+ # [REJECT] The target block is an ancestor of the LMD vote block
+ checkpoint_block = get_checkpoint_block(
+ store, aggregate.data.beacon_block_root, aggregate.data.target.epoch
+ )
+ if checkpoint_block != aggregate.data.target.root:
+ raise GossipReject("target block is not an ancestor of LMD vote block")
+
+ # [IGNORE] The finalized checkpoint is an ancestor of the block
+ finalized_checkpoint_block = get_checkpoint_block(
+ store, aggregate.data.beacon_block_root, store.finalized_checkpoint.epoch
+ )
+ if finalized_checkpoint_block != store.finalized_checkpoint.root:
+ raise GossipIgnore("finalized checkpoint is not an ancestor of block")
+
+ # Mark this aggregate as seen
+ seen.aggregator_epochs.add((aggregator_index, target_epoch))
+ if aggregate_data_root not in seen.aggregate_data_roots:
+ seen.aggregate_data_roots[aggregate_data_root] = set()
+ seen.aggregate_data_roots[aggregate_data_root].add(aggregate_bits)
+
+
+- name: validate_beacon_attestation_gossip#phase0
+ sources: []
+ spec: |
+
+ def validate_beacon_attestation_gossip(
+ seen: Seen,
+ store: Store,
+ state: BeaconState,
+ attestation: Attestation,
+ subnet_id: uint64,
+ current_time_ms: uint64,
+ ) -> None:
+ """
+ Validate an Attestation for gossip propagation on a subnet.
+ Raises GossipIgnore or GossipReject on validation failure.
+ """
+ data = attestation.data
+ committee_index = data.index
+ target_epoch = data.target.epoch
+ aggregation_bits = attestation.aggregation_bits
+
+ # [REJECT] The committee index is within the expected range
+ committees_per_slot = get_committee_count_per_slot(state, target_epoch)
+ if committee_index >= committees_per_slot:
+ raise GossipReject("committee index out of range")
+
+ # [REJECT] The attestation is for the correct subnet
+ expected_subnet = compute_subnet_for_attestation(
+ committees_per_slot, data.slot, committee_index
+ )
+ if expected_subnet != subnet_id:
+ raise GossipReject("attestation is for wrong subnet")
+
+ # [IGNORE] The attestation slot is within the propagation range
+ # (MAY be queued for processing at the appropriate slot)
+ if not is_within_slot_range(
+ state, data.slot, ATTESTATION_PROPAGATION_SLOT_RANGE, current_time_ms
+ ):
+ raise GossipIgnore("attestation slot not within propagation range")
+
+ # [REJECT] The attestation's epoch matches its target
+ if target_epoch != compute_epoch_at_slot(data.slot):
+ raise GossipReject("attestation epoch does not match target epoch")
+
+ # [REJECT] The attestation is unaggregated (exactly one bit set)
+ num_bits_set = sum(1 for bit in aggregation_bits if bit)
+ if num_bits_set != 1:
+ raise GossipReject("attestation is not unaggregated")
+
+ # [REJECT] The number of aggregation bits matches the committee size
+ committee = get_beacon_committee(state, data.slot, committee_index)
+ if len(aggregation_bits) != len(committee):
+ raise GossipReject("aggregation bits length does not match committee size")
+
+ # [IGNORE] No other valid attestation seen for this validator and target epoch
+ participant_index = committee[aggregation_bits.index(True)]
+ if (participant_index, target_epoch) in seen.attestation_validator_epochs:
+ raise GossipIgnore("already seen attestation from this validator for this epoch")
+
+ # [REJECT] The attestation signature is valid
+ indexed_attestation = get_indexed_attestation(state, attestation)
+ if not is_valid_indexed_attestation(state, indexed_attestation):
+ raise GossipReject("invalid attestation signature")
+
+ # [IGNORE] The block being voted for has been seen (via gossip or non-gossip sources)
+ # (MAY be queued until block is retrieved)
+ beacon_block_root = data.beacon_block_root
+ if beacon_block_root not in store.blocks:
+ raise GossipIgnore("block being voted for has not been seen")
+
+ # [REJECT] The block being voted for passes validation
+ if beacon_block_root not in store.block_states:
+ raise GossipReject("block being voted for failed validation")
+
+ # [REJECT] The attestation's target block is an ancestor of the LMD vote block
+ target_checkpoint_block = get_checkpoint_block(store, beacon_block_root, target_epoch)
+ if target_checkpoint_block != data.target.root:
+ raise GossipReject("target block is not an ancestor of LMD vote block")
+
+ # [IGNORE] The current finalized_checkpoint is an ancestor of the block
+ finalized_checkpoint_block = get_checkpoint_block(
+ store, beacon_block_root, store.finalized_checkpoint.epoch
+ )
+ if finalized_checkpoint_block != store.finalized_checkpoint.root:
+ raise GossipIgnore("finalized checkpoint is not an ancestor of block")
+
+ # Mark this attestation as seen
+ seen.attestation_validator_epochs.add((participant_index, target_epoch))
+
+
+- name: validate_beacon_block_gossip#phase0
+ sources: []
+ spec: |
+
+ def validate_beacon_block_gossip(
+ seen: Seen,
+ store: Store,
+ state: BeaconState,
+ signed_beacon_block: SignedBeaconBlock,
+ current_time_ms: uint64,
+ ) -> None:
+ """
+ Validate a SignedBeaconBlock for gossip propagation.
+ Raises GossipIgnore or GossipReject on validation failure.
+ """
+ block = signed_beacon_block.message
+
+ # [IGNORE] The block is not from a future slot
+ # (MAY be queued for processing at the appropriate slot)
+ if not is_not_from_future_slot(state, block.slot, current_time_ms):
+ raise GossipIgnore("block is from a future slot")
+
+ # [IGNORE] The block is from a slot greater than the latest finalized slot
+ # (MAY choose to validate and store such blocks for additional purposes
+ # -- e.g. slashing detection, archive nodes, etc).
+ finalized_slot = compute_start_slot_at_epoch(store.finalized_checkpoint.epoch)
+ if block.slot <= finalized_slot:
+ raise GossipIgnore("block is not from a slot greater than the latest finalized slot")
+
+ # [IGNORE] The block is the first block with valid signature received for the proposer for the slot
+ if (block.proposer_index, block.slot) in seen.proposer_slots:
+ raise GossipIgnore("block is not the first valid block for this proposer and slot")
+
+ # [REJECT] The proposer index is a valid validator index
+ if block.proposer_index >= len(state.validators):
+ raise GossipReject("proposer index out of range")
+
+ # [REJECT] The proposer signature is valid
+ proposer = state.validators[block.proposer_index]
+ domain = get_domain(state, DOMAIN_BEACON_PROPOSER, compute_epoch_at_slot(block.slot))
+ signing_root = compute_signing_root(block, domain)
+ if not bls.Verify(proposer.pubkey, signing_root, signed_beacon_block.signature):
+ raise GossipReject("invalid proposer signature")
+
+ # [IGNORE] The block's parent has been seen (via gossip or non-gossip sources)
+ # (MAY be queued until parent is retrieved)
+ if block.parent_root not in store.blocks:
+ raise GossipIgnore("block's parent has not been seen")
+
+ # [REJECT] The block's parent passes validation
+ if block.parent_root not in store.block_states:
+ raise GossipReject("block's parent failed validation")
+
+ # [REJECT] The block is from a higher slot than its parent
+ if block.slot <= store.blocks[block.parent_root].slot:
+ raise GossipReject("block is not from a higher slot than its parent")
+
+ # [REJECT] The current finalized checkpoint is an ancestor of the block
+ checkpoint_block = get_checkpoint_block(
+ store, block.parent_root, store.finalized_checkpoint.epoch
+ )
+ if checkpoint_block != store.finalized_checkpoint.root:
+ raise GossipReject("finalized checkpoint is not an ancestor of block")
+
+ # [REJECT] The block is proposed by the expected proposer for the slot
+ # (if shuffling is not available, IGNORE instead and MAY be queued for later)
+ parent_state = store.block_states[block.parent_root].copy()
+ process_slots(parent_state, block.slot)
+ expected_proposer = get_beacon_proposer_index(parent_state)
+ if block.proposer_index != expected_proposer:
+ raise GossipReject("block proposer_index does not match expected proposer")
+
+ # Mark this block as seen for this proposer/slot combination
+ seen.proposer_slots.add((block.proposer_index, block.slot))
+
+
- name: validate_light_client_update#altair
sources: []
spec: |
@@ -10881,7 +11975,7 @@
- name: validate_on_attestation#gloas
sources: []
spec: |
-
+
def validate_on_attestation(store: Store, attestation: Attestation, is_from_block: bool) -> None:
target = attestation.data.target
@@ -10909,6 +12003,10 @@
assert attestation.data.index in [0, 1]
if block_slot == attestation.data.slot:
assert attestation.data.index == 0
+ # [New in Gloas:EIP7732]
+ # If attesting for a full node, the payload must be known
+ if attestation.data.index == 1:
+ assert attestation.data.beacon_block_root in store.payload_states
# LMD vote must be consistent with FFG vote target
assert target.root == get_checkpoint_block(
@@ -10920,6 +12018,61 @@
assert get_current_slot(store) >= attestation.data.slot + 1
+- name: validate_proposer_slashing_gossip#phase0
+ sources: []
+ spec: |
+
+ def validate_proposer_slashing_gossip(
+ seen: Seen,
+ state: BeaconState,
+ proposer_slashing: ProposerSlashing,
+ ) -> None:
+ """
+ Validate a ProposerSlashing for gossip propagation.
+ Raises GossipIgnore or GossipReject on validation failure.
+ """
+ header_1 = proposer_slashing.signed_header_1.message
+ header_2 = proposer_slashing.signed_header_2.message
+ proposer_index = header_1.proposer_index
+
+ # [IGNORE] The proposer slashing is the first valid proposer slashing received for this proposer
+ if proposer_index in seen.proposer_slashing_indices:
+ raise GossipIgnore("already seen proposer slashing for this proposer")
+
+ # [REJECT] The header slots match
+ if header_1.slot != header_2.slot:
+ raise GossipReject("header slots do not match")
+
+ # [REJECT] The header proposer indices match
+ if header_1.proposer_index != header_2.proposer_index:
+ raise GossipReject("header proposer indices do not match")
+
+ # [REJECT] The headers are different
+ if header_1 == header_2:
+ raise GossipReject("headers are not different")
+
+ # [REJECT] The proposer index is valid
+ if proposer_index >= len(state.validators):
+ raise GossipReject("proposer index out of range")
+
+ # [REJECT] The proposer is slashable
+ proposer = state.validators[proposer_index]
+ if not is_slashable_validator(proposer, get_current_epoch(state)):
+ raise GossipReject("proposer is not slashable")
+
+ # [REJECT] The signatures are valid
+ for signed_header in (proposer_slashing.signed_header_1, proposer_slashing.signed_header_2):
+ domain = get_domain(
+ state, DOMAIN_BEACON_PROPOSER, compute_epoch_at_slot(signed_header.message.slot)
+ )
+ signing_root = compute_signing_root(signed_header.message, domain)
+ if not bls.Verify(proposer.pubkey, signing_root, signed_header.signature):
+ raise GossipReject("invalid proposer slashing signature")
+
+ # Mark this proposer slashing as seen
+ seen.proposer_slashing_indices.add(proposer_index)
+
+
- name: validate_target_epoch_against_current_time#phase0
sources: []
spec: |
@@ -10935,6 +12088,59 @@
assert target.epoch in [current_epoch, previous_epoch]
+- name: validate_voluntary_exit_gossip#phase0
+ sources: []
+ spec: |
+
+ def validate_voluntary_exit_gossip(
+ seen: Seen,
+ state: BeaconState,
+ signed_voluntary_exit: SignedVoluntaryExit,
+ ) -> None:
+ """
+ Validate a SignedVoluntaryExit for gossip propagation.
+ Raises GossipIgnore or GossipReject on validation failure.
+ """
+ voluntary_exit = signed_voluntary_exit.message
+ validator_index = voluntary_exit.validator_index
+
+ # [IGNORE] The voluntary exit is the first valid voluntary exit received for the validator
+ if validator_index in seen.voluntary_exit_indices:
+ raise GossipIgnore("already seen voluntary exit for this validator")
+
+ # [REJECT] The validator index is valid
+ if validator_index >= len(state.validators):
+ raise GossipReject("validator index out of range")
+
+ validator = state.validators[validator_index]
+ current_epoch = get_current_epoch(state)
+
+ # [REJECT] The validator is active
+ if not is_active_validator(validator, current_epoch):
+ raise GossipReject("validator is not active")
+
+ # [REJECT] The validator has not already initiated exit
+ if validator.exit_epoch != FAR_FUTURE_EPOCH:
+ raise GossipReject("validator has already initiated exit")
+
+ # [REJECT] The voluntary exit epoch is not in the future
+ if current_epoch < voluntary_exit.epoch:
+ raise GossipReject("voluntary exit epoch is in the future")
+
+ # [REJECT] The validator has been active long enough
+ if current_epoch < validator.activation_epoch + SHARD_COMMITTEE_PERIOD:
+ raise GossipReject("validator has not been active long enough")
+
+ # [REJECT] The signature is valid
+ domain = get_domain(state, DOMAIN_VOLUNTARY_EXIT, voluntary_exit.epoch)
+ signing_root = compute_signing_root(voluntary_exit, domain)
+ if not bls.Verify(validator.pubkey, signing_root, signed_voluntary_exit.signature):
+ raise GossipReject("invalid voluntary exit signature")
+
+ # Mark this voluntary exit as seen
+ seen.voluntary_exit_indices.add(validator_index)
+
+
- name: verify_blob_sidecar_inclusion_proof#deneb
sources:
- file: consensus-types/blocks/kzg.go
@@ -11106,6 +12312,50 @@
return bls.Verify(pubkey, signing_root, signed_envelope.signature)
+- name: verify_partial_data_column_header_inclusion_proof#fulu
+ sources: []
+ spec: |
+
+ def verify_partial_data_column_header_inclusion_proof(header: PartialDataColumnHeader) -> bool:
+ """
+ Verify if the given KZG commitments are included in the given beacon block.
+ """
+ return is_valid_merkle_branch(
+ leaf=hash_tree_root(header.kzg_commitments),
+ branch=header.kzg_commitments_inclusion_proof,
+ depth=KZG_COMMITMENTS_INCLUSION_PROOF_DEPTH,
+ index=get_subtree_index(get_generalized_index(BeaconBlockBody, "blob_kzg_commitments")),
+ root=header.signed_block_header.message.body_root,
+ )
+
+
+- name: verify_partial_data_column_sidecar_kzg_proofs#fulu
+ sources: []
+ spec: |
+
+ def verify_partial_data_column_sidecar_kzg_proofs(
+ sidecar: PartialDataColumnSidecar,
+ all_commitments: List[KZGCommitment, MAX_BLOB_COMMITMENTS_PER_BLOCK],
+ column_index: ColumnIndex,
+ ) -> bool:
+ """
+ Verify the KZG proofs.
+ """
+ # Get the blob indices from the bitmap
+ blob_indices = [i for i, b in enumerate(sidecar.cells_present_bitmap) if b]
+
+ # The cell index is the column index for all cells in this column
+ cell_indices = [CellIndex(column_index)] * len(blob_indices)
+
+ # Batch verify that the cells match the corresponding commitments and proofs
+ return verify_cell_kzg_proof_batch(
+ commitments_bytes=[all_commitments[i] for i in blob_indices],
+ cell_indices=cell_indices,
+ cells=sidecar.partial_column,
+ proofs_bytes=sidecar.kzg_proofs,
+ )
+
+
- name: voting_period_start_time#phase0
sources:
- file: time/slots/slottime.go
diff --git a/specrefs/presets.yml b/specrefs/presets.yml
index 9e7938edfd5b..896f79deee6b 100644
--- a/specrefs/presets.yml
+++ b/specrefs/presets.yml
@@ -192,6 +192,13 @@
INACTIVITY_PENALTY_QUOTIENT_BELLATRIX: uint64 = 16777216
+- name: INCLUSION_LIST_COMMITTEE_SIZE#heze
+ sources: []
+ spec: |
+
+ INCLUSION_LIST_COMMITTEE_SIZE: uint64 = 16
+
+
- name: KZG_COMMITMENTS_INCLUSION_PROOF_DEPTH#fulu
sources:
- file: proto/ssz_proto_library.bzl
diff --git a/testing/spectest/shared/fulu/ssz_static/ssz_static.go b/testing/spectest/shared/fulu/ssz_static/ssz_static.go
index 1175b6174e73..8d3529ce2380 100644
--- a/testing/spectest/shared/fulu/ssz_static/ssz_static.go
+++ b/testing/spectest/shared/fulu/ssz_static/ssz_static.go
@@ -155,6 +155,8 @@ func UnmarshalledSSZ(t *testing.T, serializedBytes []byte, folderName string) (a
obj = ðpb.DataColumnsByRootIdentifier{}
case "MatrixEntry":
t.Skip("Unused type")
+ case "PartialDataColumnHeader", "PartialDataColumnPartsMetadata", "PartialDataColumnSidecar":
+ t.Skip("Not yet implemented")
default:
return nil, errors.New("type not found")
}
diff --git a/testing/spectest/shared/gloas/ssz_static/ssz_static.go b/testing/spectest/shared/gloas/ssz_static/ssz_static.go
index 35fbbe7725fb..5fe3b0ea581d 100644
--- a/testing/spectest/shared/gloas/ssz_static/ssz_static.go
+++ b/testing/spectest/shared/gloas/ssz_static/ssz_static.go
@@ -187,6 +187,8 @@ func unmarshalledSSZ(t *testing.T, serializedBytes []byte, folderName string) (a
obj = ðpb.DataColumnsByRootIdentifier{}
case "MatrixEntry":
t.Skip("Unused type")
+ case "PartialDataColumnHeader", "PartialDataColumnPartsMetadata", "PartialDataColumnSidecar":
+ t.Skip("Not yet implemented")
default:
return nil, errors.New("type not found")
}
diff --git a/testing/util/BUILD.bazel b/testing/util/BUILD.bazel
index 01f7756ba267..2d9af46877ca 100644
--- a/testing/util/BUILD.bazel
+++ b/testing/util/BUILD.bazel
@@ -23,6 +23,7 @@ go_library(
"fulu.go",
"fulu_block.go",
"fulu_state.go",
+ "gloas_state.go",
"helpers.go",
"lightclient.go",
"logging.go",
@@ -39,6 +40,7 @@ go_library(
"//beacon-chain/blockchain/kzg:go_default_library",
"//beacon-chain/core/altair:go_default_library",
"//beacon-chain/core/blocks:go_default_library",
+ "//beacon-chain/core/gloas:go_default_library",
"//beacon-chain/core/helpers:go_default_library",
"//beacon-chain/core/peerdas:go_default_library",
"//beacon-chain/core/signing:go_default_library",
diff --git a/testing/util/gloas_state.go b/testing/util/gloas_state.go
new file mode 100644
index 000000000000..c431235ba3ff
--- /dev/null
+++ b/testing/util/gloas_state.go
@@ -0,0 +1,24 @@
+package util
+
+import (
+ "testing"
+
+ "github.com/OffchainLabs/prysm/v7/beacon-chain/core/gloas"
+ "github.com/OffchainLabs/prysm/v7/beacon-chain/state"
+ "github.com/OffchainLabs/prysm/v7/crypto/bls"
+ "github.com/pkg/errors"
+)
+
+// DeterministicGenesisStateGloas returns a genesis state in Gloas format made
+// using the deterministic deposits.
+func DeterministicGenesisStateGloas(t testing.TB, numValidators uint64) (state.BeaconState, []bls.SecretKey) {
+ t.Helper()
+
+ fuluState, privKeys := DeterministicGenesisStateFulu(t, numValidators)
+ beaconState, err := gloas.UpgradeToGloas(fuluState)
+ if err != nil {
+ t.Fatal(errors.Wrapf(err, "failed to upgrade genesis beacon state of %d validators to gloas", numValidators))
+ }
+ resetCache()
+ return beaconState, privKeys
+}
diff --git a/testing/util/state.go b/testing/util/state.go
index 69daf54e5124..6f4a58c64d2b 100644
--- a/testing/util/state.go
+++ b/testing/util/state.go
@@ -12,6 +12,7 @@ import (
state_native "github.com/OffchainLabs/prysm/v7/beacon-chain/state/state-native"
fieldparams "github.com/OffchainLabs/prysm/v7/config/fieldparams"
"github.com/OffchainLabs/prysm/v7/config/params"
+ "github.com/OffchainLabs/prysm/v7/consensus-types/primitives"
"github.com/OffchainLabs/prysm/v7/crypto/bls"
enginev1 "github.com/OffchainLabs/prysm/v7/proto/engine/v1"
ethpb "github.com/OffchainLabs/prysm/v7/proto/prysm/v1alpha1"
@@ -526,6 +527,13 @@ func NewBeaconStateGloas(options ...func(state *ethpb.BeaconStateGloas) error) (
}
}
+ ptcWindow := make([]*ethpb.PTCs, 3*params.BeaconConfig().SlotsPerEpoch)
+ for i := range ptcWindow {
+ ptcWindow[i] = ðpb.PTCs{
+ ValidatorIndices: make([]primitives.ValidatorIndex, fieldparams.PTCSize),
+ }
+ }
+
seed := ðpb.BeaconStateGloas{
BlockRoots: filledByteSlice2D(uint64(params.BeaconConfig().SlotsPerHistoricalRoot), 32),
StateRoots: filledByteSlice2D(uint64(params.BeaconConfig().SlotsPerHistoricalRoot), 32),
@@ -572,6 +580,7 @@ func NewBeaconStateGloas(options ...func(state *ethpb.BeaconStateGloas) error) (
BuilderPendingWithdrawals: make([]*ethpb.BuilderPendingWithdrawal, 0),
LatestBlockHash: make([]byte, 32),
PayloadExpectedWithdrawals: make([]*enginev1.Withdrawal, 0),
+ PtcWindow: ptcWindow,
}
for _, opt := range options {