Files
prysm/testing/util/state.go
terence 8b0cdc2db9 Implement defer payload processing (#16658)
**1 — proto + API structs**
New fields: `execution_requests_root` on the bid,
`parent_execution_requests`
on the body. `state_root` gone from the envelope. Nothing uses them yet.

  **2 — consensus-types accessors + state interfaces**
Wires up the Go side of (1). Also adds `QueueBuilderPaymentForSlot` and
  factors `queueBuilderPaymentAtIndex` out of `QueueBuilderPayment`.

  **3 — ProcessParentExecutionPayload + spec tests**
  New spec fn, not wired in yet. Read it side-by-side with the pyspec. 

  **4 — swap the mutation site**
Old `ProcessExecutionPayload` drops all its state mutations and becomes
  verify only. `ProcessParentExecutionPayload` gets wired into
`ProcessBlockForStateRoot` before `process_block_header` per spec order.

Also: renames `IsParentBlockFull` → `LatestBlockHashMatchesBidBlockHash`
(old name was misleading, it's just an equality check).
`ProcessSlotsForBlock`
and `head.full` are deleted. Envelope no longer computes a `state_root`.

  **5 — proposer**
Sets `parent_execution_requests` on the body, builds the bid with the
new
fields, computes withdrawals via `computePayloadWithdrawals`. That fn
has
  three branches (empty parent / pre-Gloas parent / full Gloas parent).

  **6 — gossip validation**
Adds `validateParentExecutionRequests`: body's
`parent_execution_requests`
  has to hash to what the parent bid said. 

  **7 — rip out dual-key state access**
  State's always keyed by beacon block root now, so all the "sometimes
execution block hash" code across forkchoice, stategen, and the
blockchain
  service can go. Almost pure deletions. One actual behavior change: FCU
notifications use `forkchoice.BlockHash()` instead of
`st.LatestBlockHash()`

**8 — rename ProcessExecutionPayload → VerifyExecutionPayloadEnvelope**
  Rename only, nothing else. Just approve.

  **9 — test utilities + assertions + changelog**
Mechanical. Test builders pick up the new fields, a few stray
`envelope.StateRoot` references get swept up, changelog added.
2026-04-24 19:47:38 +00:00

654 lines
24 KiB
Go

package util
import (
"context"
"fmt"
"testing"
"github.com/OffchainLabs/go-bitfield"
b "github.com/OffchainLabs/prysm/v7/beacon-chain/core/blocks"
"github.com/OffchainLabs/prysm/v7/beacon-chain/db/iface"
"github.com/OffchainLabs/prysm/v7/beacon-chain/state"
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"
"github.com/OffchainLabs/prysm/v7/testing/require"
"github.com/ethereum/go-ethereum/common/hexutil"
)
// FillRootsNaturalOpt is meant to be used as an option when calling NewBeaconState.
// It fills state and block roots with hex representations of natural numbers starting with 0.
// Example: 16 becomes 0x00...0f.
func FillRootsNaturalOpt(state *ethpb.BeaconState) error {
roots, err := PrepareRoots(int(params.BeaconConfig().SlotsPerHistoricalRoot))
if err != nil {
return err
}
state.StateRoots = roots
state.BlockRoots = roots
return nil
}
// FillRootsNaturalOptAltair is meant to be used as an option when calling NewBeaconStateAltair.
// It fills state and block roots with hex representations of natural numbers starting with 0.
// Example: 16 becomes 0x00...0f.
func FillRootsNaturalOptAltair(state *ethpb.BeaconStateAltair) error {
roots, err := PrepareRoots(int(params.BeaconConfig().SlotsPerHistoricalRoot))
if err != nil {
return err
}
state.StateRoots = roots
state.BlockRoots = roots
return nil
}
// FillRootsNaturalOptBellatrix is meant to be used as an option when calling NewBeaconStateBellatrix.
// It fills state and block roots with hex representations of natural numbers starting with 0.
// Example: 16 becomes 0x00...0f.
func FillRootsNaturalOptBellatrix(state *ethpb.BeaconStateBellatrix) error {
roots, err := PrepareRoots(int(params.BeaconConfig().SlotsPerHistoricalRoot))
if err != nil {
return err
}
state.StateRoots = roots
state.BlockRoots = roots
return nil
}
// FillRootsNaturalOptCapella is meant to be used as an option when calling NewBeaconStateCapella.
// It fills state and block roots with hex representations of natural numbers starting with 0.
// Example: 16 becomes 0x00...0f.
func FillRootsNaturalOptCapella(state *ethpb.BeaconStateCapella) error {
roots, err := PrepareRoots(int(params.BeaconConfig().SlotsPerHistoricalRoot))
if err != nil {
return err
}
state.StateRoots = roots
state.BlockRoots = roots
return nil
}
type NewBeaconStateOption func(state *ethpb.BeaconState) error
// NewBeaconState creates a beacon state with minimum marshalable fields.
func NewBeaconState(options ...NewBeaconStateOption) (state.BeaconState, error) {
seed := &ethpb.BeaconState{
BlockRoots: filledByteSlice2D(uint64(params.BeaconConfig().SlotsPerHistoricalRoot), 32),
StateRoots: filledByteSlice2D(uint64(params.BeaconConfig().SlotsPerHistoricalRoot), 32),
Slashings: make([]uint64, params.BeaconConfig().EpochsPerSlashingsVector),
RandaoMixes: filledByteSlice2D(uint64(params.BeaconConfig().EpochsPerHistoricalVector), 32),
Validators: make([]*ethpb.Validator, 0),
CurrentJustifiedCheckpoint: &ethpb.Checkpoint{Root: make([]byte, fieldparams.RootLength)},
Eth1Data: &ethpb.Eth1Data{
DepositRoot: make([]byte, fieldparams.RootLength),
BlockHash: make([]byte, 32),
},
Fork: &ethpb.Fork{
PreviousVersion: make([]byte, 4),
CurrentVersion: make([]byte, 4),
},
Eth1DataVotes: make([]*ethpb.Eth1Data, 0),
HistoricalRoots: make([][]byte, 0),
JustificationBits: bitfield.Bitvector4{0x0},
FinalizedCheckpoint: &ethpb.Checkpoint{Root: make([]byte, fieldparams.RootLength)},
LatestBlockHeader: HydrateBeaconHeader(&ethpb.BeaconBlockHeader{}),
PreviousEpochAttestations: make([]*ethpb.PendingAttestation, 0),
CurrentEpochAttestations: make([]*ethpb.PendingAttestation, 0),
PreviousJustifiedCheckpoint: &ethpb.Checkpoint{Root: make([]byte, fieldparams.RootLength)},
}
for _, opt := range options {
err := opt(seed)
if err != nil {
return nil, err
}
}
var st, err = state_native.InitializeFromProtoUnsafePhase0(seed)
if err != nil {
return nil, err
}
return st, nil
}
// NewBeaconStateAltair creates a beacon state with minimum marshalable fields.
func NewBeaconStateAltair(options ...func(state *ethpb.BeaconStateAltair) error) (state.BeaconState, error) {
pubkeys := make([][]byte, 512)
for i := range pubkeys {
pubkeys[i] = make([]byte, 48)
}
seed := &ethpb.BeaconStateAltair{
BlockRoots: filledByteSlice2D(uint64(params.BeaconConfig().SlotsPerHistoricalRoot), 32),
StateRoots: filledByteSlice2D(uint64(params.BeaconConfig().SlotsPerHistoricalRoot), 32),
Slashings: make([]uint64, params.BeaconConfig().EpochsPerSlashingsVector),
RandaoMixes: filledByteSlice2D(uint64(params.BeaconConfig().EpochsPerHistoricalVector), 32),
Validators: make([]*ethpb.Validator, 0),
CurrentJustifiedCheckpoint: &ethpb.Checkpoint{Root: make([]byte, fieldparams.RootLength)},
Eth1Data: &ethpb.Eth1Data{
DepositRoot: make([]byte, fieldparams.RootLength),
BlockHash: make([]byte, 32),
},
Fork: &ethpb.Fork{
PreviousVersion: make([]byte, 4),
CurrentVersion: make([]byte, 4),
},
Eth1DataVotes: make([]*ethpb.Eth1Data, 0),
HistoricalRoots: make([][]byte, 0),
JustificationBits: bitfield.Bitvector4{0x0},
FinalizedCheckpoint: &ethpb.Checkpoint{Root: make([]byte, fieldparams.RootLength)},
LatestBlockHeader: HydrateBeaconHeader(&ethpb.BeaconBlockHeader{}),
PreviousJustifiedCheckpoint: &ethpb.Checkpoint{Root: make([]byte, fieldparams.RootLength)},
PreviousEpochParticipation: make([]byte, 0),
CurrentEpochParticipation: make([]byte, 0),
CurrentSyncCommittee: &ethpb.SyncCommittee{
Pubkeys: pubkeys,
AggregatePubkey: make([]byte, 48),
},
NextSyncCommittee: &ethpb.SyncCommittee{
Pubkeys: pubkeys,
AggregatePubkey: make([]byte, 48),
},
}
for _, opt := range options {
err := opt(seed)
if err != nil {
return nil, err
}
}
var st, err = state_native.InitializeFromProtoUnsafeAltair(seed)
if err != nil {
return nil, err
}
return st, nil
}
// NewBeaconStateBellatrix creates a beacon state with minimum marshalable fields.
func NewBeaconStateBellatrix(options ...func(state *ethpb.BeaconStateBellatrix) error) (state.BeaconState, error) {
pubkeys := make([][]byte, 512)
for i := range pubkeys {
pubkeys[i] = make([]byte, 48)
}
seed := &ethpb.BeaconStateBellatrix{
BlockRoots: filledByteSlice2D(uint64(params.BeaconConfig().SlotsPerHistoricalRoot), 32),
StateRoots: filledByteSlice2D(uint64(params.BeaconConfig().SlotsPerHistoricalRoot), 32),
Slashings: make([]uint64, params.BeaconConfig().EpochsPerSlashingsVector),
RandaoMixes: filledByteSlice2D(uint64(params.BeaconConfig().EpochsPerHistoricalVector), 32),
Validators: make([]*ethpb.Validator, 0),
CurrentJustifiedCheckpoint: &ethpb.Checkpoint{Root: make([]byte, fieldparams.RootLength)},
Eth1Data: &ethpb.Eth1Data{
DepositRoot: make([]byte, fieldparams.RootLength),
BlockHash: make([]byte, 32),
},
Fork: &ethpb.Fork{
PreviousVersion: make([]byte, 4),
CurrentVersion: make([]byte, 4),
},
Eth1DataVotes: make([]*ethpb.Eth1Data, 0),
HistoricalRoots: make([][]byte, 0),
JustificationBits: bitfield.Bitvector4{0x0},
FinalizedCheckpoint: &ethpb.Checkpoint{Root: make([]byte, fieldparams.RootLength)},
LatestBlockHeader: HydrateBeaconHeader(&ethpb.BeaconBlockHeader{}),
PreviousJustifiedCheckpoint: &ethpb.Checkpoint{Root: make([]byte, fieldparams.RootLength)},
PreviousEpochParticipation: make([]byte, 0),
CurrentEpochParticipation: make([]byte, 0),
CurrentSyncCommittee: &ethpb.SyncCommittee{
Pubkeys: pubkeys,
AggregatePubkey: make([]byte, 48),
},
NextSyncCommittee: &ethpb.SyncCommittee{
Pubkeys: pubkeys,
AggregatePubkey: make([]byte, 48),
},
LatestExecutionPayloadHeader: &enginev1.ExecutionPayloadHeader{
ParentHash: make([]byte, 32),
FeeRecipient: make([]byte, 20),
StateRoot: make([]byte, 32),
ReceiptsRoot: make([]byte, 32),
LogsBloom: make([]byte, 256),
PrevRandao: make([]byte, 32),
ExtraData: make([]byte, 0),
BaseFeePerGas: make([]byte, 32),
BlockHash: make([]byte, 32),
TransactionsRoot: make([]byte, 32),
},
}
for _, opt := range options {
err := opt(seed)
if err != nil {
return nil, err
}
}
var st, err = state_native.InitializeFromProtoUnsafeBellatrix(seed)
if err != nil {
return nil, err
}
return st, nil
}
// NewBeaconStateCapella creates a beacon state with minimum marshalable fields.
func NewBeaconStateCapella(options ...func(state *ethpb.BeaconStateCapella) error) (state.BeaconState, error) {
pubkeys := make([][]byte, 512)
for i := range pubkeys {
pubkeys[i] = make([]byte, 48)
}
seed := &ethpb.BeaconStateCapella{
BlockRoots: filledByteSlice2D(uint64(params.BeaconConfig().SlotsPerHistoricalRoot), 32),
StateRoots: filledByteSlice2D(uint64(params.BeaconConfig().SlotsPerHistoricalRoot), 32),
Slashings: make([]uint64, params.BeaconConfig().EpochsPerSlashingsVector),
RandaoMixes: filledByteSlice2D(uint64(params.BeaconConfig().EpochsPerHistoricalVector), 32),
Validators: make([]*ethpb.Validator, 0),
CurrentJustifiedCheckpoint: &ethpb.Checkpoint{Root: make([]byte, fieldparams.RootLength)},
Eth1Data: &ethpb.Eth1Data{
DepositRoot: make([]byte, fieldparams.RootLength),
BlockHash: make([]byte, 32),
},
Fork: &ethpb.Fork{
PreviousVersion: make([]byte, 4),
CurrentVersion: make([]byte, 4),
},
Eth1DataVotes: make([]*ethpb.Eth1Data, 0),
HistoricalSummaries: make([]*ethpb.HistoricalSummary, 0),
JustificationBits: bitfield.Bitvector4{0x0},
FinalizedCheckpoint: &ethpb.Checkpoint{Root: make([]byte, fieldparams.RootLength)},
LatestBlockHeader: HydrateBeaconHeader(&ethpb.BeaconBlockHeader{}),
PreviousJustifiedCheckpoint: &ethpb.Checkpoint{Root: make([]byte, fieldparams.RootLength)},
PreviousEpochParticipation: make([]byte, 0),
CurrentEpochParticipation: make([]byte, 0),
CurrentSyncCommittee: &ethpb.SyncCommittee{
Pubkeys: pubkeys,
AggregatePubkey: make([]byte, 48),
},
NextSyncCommittee: &ethpb.SyncCommittee{
Pubkeys: pubkeys,
AggregatePubkey: make([]byte, 48),
},
LatestExecutionPayloadHeader: &enginev1.ExecutionPayloadHeaderCapella{
ParentHash: make([]byte, 32),
FeeRecipient: make([]byte, 20),
StateRoot: make([]byte, 32),
ReceiptsRoot: make([]byte, 32),
LogsBloom: make([]byte, 256),
PrevRandao: make([]byte, 32),
ExtraData: make([]byte, 0),
BaseFeePerGas: make([]byte, 32),
BlockHash: make([]byte, 32),
TransactionsRoot: make([]byte, 32),
WithdrawalsRoot: make([]byte, 32),
},
}
for _, opt := range options {
err := opt(seed)
if err != nil {
return nil, err
}
}
var st, err = state_native.InitializeFromProtoUnsafeCapella(seed)
if err != nil {
return nil, err
}
return st, nil
}
// NewBeaconStateDeneb creates a beacon state with minimum marshalable fields.
func NewBeaconStateDeneb(options ...func(state *ethpb.BeaconStateDeneb) error) (state.BeaconState, error) {
pubkeys := make([][]byte, 512)
for i := range pubkeys {
pubkeys[i] = make([]byte, 48)
}
seed := &ethpb.BeaconStateDeneb{
BlockRoots: filledByteSlice2D(uint64(params.BeaconConfig().SlotsPerHistoricalRoot), 32),
StateRoots: filledByteSlice2D(uint64(params.BeaconConfig().SlotsPerHistoricalRoot), 32),
Slashings: make([]uint64, params.BeaconConfig().EpochsPerSlashingsVector),
RandaoMixes: filledByteSlice2D(uint64(params.BeaconConfig().EpochsPerHistoricalVector), 32),
Validators: make([]*ethpb.Validator, 0),
CurrentJustifiedCheckpoint: &ethpb.Checkpoint{Root: make([]byte, fieldparams.RootLength)},
Eth1Data: &ethpb.Eth1Data{
DepositRoot: make([]byte, fieldparams.RootLength),
BlockHash: make([]byte, 32),
},
Fork: &ethpb.Fork{
PreviousVersion: make([]byte, 4),
CurrentVersion: make([]byte, 4),
},
Eth1DataVotes: make([]*ethpb.Eth1Data, 0),
HistoricalRoots: make([][]byte, 0),
JustificationBits: bitfield.Bitvector4{0x0},
FinalizedCheckpoint: &ethpb.Checkpoint{Root: make([]byte, fieldparams.RootLength)},
LatestBlockHeader: HydrateBeaconHeader(&ethpb.BeaconBlockHeader{}),
PreviousJustifiedCheckpoint: &ethpb.Checkpoint{Root: make([]byte, fieldparams.RootLength)},
PreviousEpochParticipation: make([]byte, 0),
CurrentEpochParticipation: make([]byte, 0),
CurrentSyncCommittee: &ethpb.SyncCommittee{
Pubkeys: pubkeys,
AggregatePubkey: make([]byte, 48),
},
NextSyncCommittee: &ethpb.SyncCommittee{
Pubkeys: pubkeys,
AggregatePubkey: make([]byte, 48),
},
LatestExecutionPayloadHeader: &enginev1.ExecutionPayloadHeaderDeneb{
ParentHash: make([]byte, 32),
FeeRecipient: make([]byte, 20),
StateRoot: make([]byte, 32),
ReceiptsRoot: make([]byte, 32),
LogsBloom: make([]byte, 256),
PrevRandao: make([]byte, 32),
ExtraData: make([]byte, 0),
BaseFeePerGas: make([]byte, 32),
BlockHash: make([]byte, 32),
TransactionsRoot: make([]byte, 32),
WithdrawalsRoot: make([]byte, 32),
},
}
for _, opt := range options {
err := opt(seed)
if err != nil {
return nil, err
}
}
var st, err = state_native.InitializeFromProtoUnsafeDeneb(seed)
if err != nil {
return nil, err
}
return st, nil
}
// NewBeaconStateElectra creates a beacon state with minimum marshalable fields.
func NewBeaconStateElectra(options ...func(state *ethpb.BeaconStateElectra) error) (state.BeaconState, error) {
pubkeys := make([][]byte, 512)
for i := range pubkeys {
pubkeys[i] = make([]byte, 48)
}
seed := &ethpb.BeaconStateElectra{
BlockRoots: filledByteSlice2D(uint64(params.BeaconConfig().SlotsPerHistoricalRoot), 32),
StateRoots: filledByteSlice2D(uint64(params.BeaconConfig().SlotsPerHistoricalRoot), 32),
Slashings: make([]uint64, params.BeaconConfig().EpochsPerSlashingsVector),
RandaoMixes: filledByteSlice2D(uint64(params.BeaconConfig().EpochsPerHistoricalVector), 32),
Validators: make([]*ethpb.Validator, 0),
CurrentJustifiedCheckpoint: &ethpb.Checkpoint{Root: make([]byte, fieldparams.RootLength)},
Eth1Data: &ethpb.Eth1Data{
DepositRoot: make([]byte, fieldparams.RootLength),
BlockHash: make([]byte, 32),
},
Fork: &ethpb.Fork{
PreviousVersion: make([]byte, 4),
CurrentVersion: make([]byte, 4),
},
Eth1DataVotes: make([]*ethpb.Eth1Data, 0),
HistoricalRoots: make([][]byte, 0),
JustificationBits: bitfield.Bitvector4{0x0},
FinalizedCheckpoint: &ethpb.Checkpoint{Root: make([]byte, fieldparams.RootLength)},
LatestBlockHeader: HydrateBeaconHeader(&ethpb.BeaconBlockHeader{}),
PreviousJustifiedCheckpoint: &ethpb.Checkpoint{Root: make([]byte, fieldparams.RootLength)},
PreviousEpochParticipation: make([]byte, 0),
CurrentEpochParticipation: make([]byte, 0),
CurrentSyncCommittee: &ethpb.SyncCommittee{
Pubkeys: pubkeys,
AggregatePubkey: make([]byte, 48),
},
NextSyncCommittee: &ethpb.SyncCommittee{
Pubkeys: pubkeys,
AggregatePubkey: make([]byte, 48),
},
LatestExecutionPayloadHeader: &enginev1.ExecutionPayloadHeaderDeneb{
ParentHash: make([]byte, 32),
FeeRecipient: make([]byte, 20),
StateRoot: make([]byte, 32),
ReceiptsRoot: make([]byte, 32),
LogsBloom: make([]byte, 256),
PrevRandao: make([]byte, 32),
ExtraData: make([]byte, 0),
BaseFeePerGas: make([]byte, 32),
BlockHash: make([]byte, 32),
TransactionsRoot: make([]byte, 32),
WithdrawalsRoot: make([]byte, 32),
},
}
for _, opt := range options {
err := opt(seed)
if err != nil {
return nil, err
}
}
var st, err = state_native.InitializeFromProtoUnsafeElectra(seed)
if err != nil {
return nil, err
}
return st, nil
}
// NewBeaconStateFulu creates a beacon state with minimum marshalable fields.
func NewBeaconStateFulu(options ...func(state *ethpb.BeaconStateFulu) error) (state.BeaconState, error) {
pubkeys := make([][]byte, 512)
for i := range pubkeys {
pubkeys[i] = make([]byte, 48)
}
seed := &ethpb.BeaconStateFulu{
BlockRoots: filledByteSlice2D(uint64(params.BeaconConfig().SlotsPerHistoricalRoot), 32),
StateRoots: filledByteSlice2D(uint64(params.BeaconConfig().SlotsPerHistoricalRoot), 32),
Slashings: make([]uint64, params.BeaconConfig().EpochsPerSlashingsVector),
RandaoMixes: filledByteSlice2D(uint64(params.BeaconConfig().EpochsPerHistoricalVector), 32),
Validators: make([]*ethpb.Validator, 0),
CurrentJustifiedCheckpoint: &ethpb.Checkpoint{Root: make([]byte, fieldparams.RootLength)},
Eth1Data: &ethpb.Eth1Data{
DepositRoot: make([]byte, fieldparams.RootLength),
BlockHash: make([]byte, 32),
},
Fork: &ethpb.Fork{
PreviousVersion: make([]byte, 4),
CurrentVersion: make([]byte, 4),
},
Eth1DataVotes: make([]*ethpb.Eth1Data, 0),
HistoricalRoots: make([][]byte, 0),
JustificationBits: bitfield.Bitvector4{0x0},
FinalizedCheckpoint: &ethpb.Checkpoint{Root: make([]byte, fieldparams.RootLength)},
LatestBlockHeader: HydrateBeaconHeader(&ethpb.BeaconBlockHeader{}),
PreviousJustifiedCheckpoint: &ethpb.Checkpoint{Root: make([]byte, fieldparams.RootLength)},
PreviousEpochParticipation: make([]byte, 0),
CurrentEpochParticipation: make([]byte, 0),
CurrentSyncCommittee: &ethpb.SyncCommittee{
Pubkeys: pubkeys,
AggregatePubkey: make([]byte, 48),
},
NextSyncCommittee: &ethpb.SyncCommittee{
Pubkeys: pubkeys,
AggregatePubkey: make([]byte, 48),
},
LatestExecutionPayloadHeader: &enginev1.ExecutionPayloadHeaderDeneb{
ParentHash: make([]byte, 32),
FeeRecipient: make([]byte, 20),
StateRoot: make([]byte, 32),
ReceiptsRoot: make([]byte, 32),
LogsBloom: make([]byte, 256),
PrevRandao: make([]byte, 32),
ExtraData: make([]byte, 0),
BaseFeePerGas: make([]byte, 32),
BlockHash: make([]byte, 32),
TransactionsRoot: make([]byte, 32),
WithdrawalsRoot: make([]byte, 32),
},
ProposerLookahead: make([]primitives.ValidatorIndex, 64),
}
for _, opt := range options {
err := opt(seed)
if err != nil {
return nil, err
}
}
var st, err = state_native.InitializeFromProtoUnsafeFulu(seed)
if err != nil {
return nil, err
}
return st, nil
}
// NewBeaconStateGloas creates a beacon state with minimum marshalable fields.
func NewBeaconStateGloas(options ...func(state *ethpb.BeaconStateGloas) error) (state.BeaconState, error) {
pubkeys := make([][]byte, 512)
for i := range pubkeys {
pubkeys[i] = make([]byte, 48)
}
builderPendingPayments := make([]*ethpb.BuilderPendingPayment, 64)
for i := range builderPendingPayments {
builderPendingPayments[i] = &ethpb.BuilderPendingPayment{
Withdrawal: &ethpb.BuilderPendingWithdrawal{
FeeRecipient: make([]byte, 20),
},
}
}
ptcWindow := make([]*ethpb.PTCs, 3*params.BeaconConfig().SlotsPerEpoch)
for i := range ptcWindow {
ptcWindow[i] = &ethpb.PTCs{
ValidatorIndices: make([]primitives.ValidatorIndex, fieldparams.PTCSize),
}
}
seed := &ethpb.BeaconStateGloas{
BlockRoots: filledByteSlice2D(uint64(params.BeaconConfig().SlotsPerHistoricalRoot), 32),
StateRoots: filledByteSlice2D(uint64(params.BeaconConfig().SlotsPerHistoricalRoot), 32),
Slashings: make([]uint64, params.BeaconConfig().EpochsPerSlashingsVector),
RandaoMixes: filledByteSlice2D(uint64(params.BeaconConfig().EpochsPerHistoricalVector), 32),
Validators: make([]*ethpb.Validator, 0),
CurrentJustifiedCheckpoint: &ethpb.Checkpoint{Root: make([]byte, fieldparams.RootLength)},
Eth1Data: &ethpb.Eth1Data{
DepositRoot: make([]byte, fieldparams.RootLength),
BlockHash: make([]byte, 32),
},
Fork: &ethpb.Fork{
PreviousVersion: make([]byte, 4),
CurrentVersion: make([]byte, 4),
},
Eth1DataVotes: make([]*ethpb.Eth1Data, 0),
HistoricalRoots: make([][]byte, 0),
JustificationBits: bitfield.Bitvector4{0x0},
FinalizedCheckpoint: &ethpb.Checkpoint{Root: make([]byte, fieldparams.RootLength)},
LatestBlockHeader: HydrateBeaconHeader(&ethpb.BeaconBlockHeader{}),
PreviousJustifiedCheckpoint: &ethpb.Checkpoint{Root: make([]byte, fieldparams.RootLength)},
PreviousEpochParticipation: make([]byte, 0),
CurrentEpochParticipation: make([]byte, 0),
CurrentSyncCommittee: &ethpb.SyncCommittee{
Pubkeys: pubkeys,
AggregatePubkey: make([]byte, 48),
},
NextSyncCommittee: &ethpb.SyncCommittee{
Pubkeys: pubkeys,
AggregatePubkey: make([]byte, 48),
},
ProposerLookahead: make([]primitives.ValidatorIndex, 64),
LatestExecutionPayloadBid: &ethpb.ExecutionPayloadBid{
ParentBlockHash: make([]byte, 32),
ParentBlockRoot: make([]byte, 32),
BlockHash: make([]byte, 32),
PrevRandao: make([]byte, 32),
FeeRecipient: make([]byte, 20),
BlobKzgCommitments: [][]byte{make([]byte, 48)},
ExecutionRequestsRoot: make([]byte, 32),
},
Builders: make([]*ethpb.Builder, 0),
ExecutionPayloadAvailability: make([]byte, 1024),
BuilderPendingPayments: builderPendingPayments,
BuilderPendingWithdrawals: make([]*ethpb.BuilderPendingWithdrawal, 0),
LatestBlockHash: make([]byte, 32),
PayloadExpectedWithdrawals: make([]*enginev1.Withdrawal, 0),
PtcWindow: ptcWindow,
}
for _, opt := range options {
err := opt(seed)
if err != nil {
return nil, err
}
}
var st, err = state_native.InitializeFromProtoUnsafeGloas(seed)
if err != nil {
return nil, err
}
return st, nil
}
// SSZ will fill 2D byte slices with their respective values, so we must fill these in too for round
// trip testing.
func filledByteSlice2D(length, innerLen uint64) [][]byte {
b := make([][]byte, length)
for i := range length {
b[i] = make([]byte, innerLen)
}
return b
}
// PrepareRoots returns a list of roots with hex representations of natural numbers starting with 0.
// Example: 16 becomes 0x00...0f.
func PrepareRoots(size int) ([][]byte, error) {
roots := make([][]byte, size)
for i := range size {
roots[i] = make([]byte, fieldparams.RootLength)
}
for j := range roots {
// Remove '0x' prefix and left-pad '0' to have 64 chars in total.
s := fmt.Sprintf("%064s", hexutil.EncodeUint64(uint64(j))[2:])
h, err := hexutil.Decode("0x" + s)
if err != nil {
return nil, err
}
roots[j] = h
}
return roots, nil
}
// DeterministicGenesisStateWithGenesisBlock creates a genesis state, saves the genesis block,
// genesis state and head block root. It returns the genesis state, genesis block's root and
// validator private keys.
func DeterministicGenesisStateWithGenesisBlock(
t *testing.T,
ctx context.Context,
db iface.HeadAccessDatabase,
numValidators uint64,
) (state.BeaconState, [32]byte, []bls.SecretKey) {
genesisState, privateKeys := DeterministicGenesisState(t, numValidators)
stateRoot, err := genesisState.HashTreeRoot(ctx)
require.NoError(t, err, "Could not hash genesis state")
genesis := b.NewGenesisBlock(stateRoot[:])
SaveBlock(t, ctx, db, genesis)
parentRoot, err := genesis.Block.HashTreeRoot()
require.NoError(t, err, "Could not get signing root")
require.NoError(t, db.SaveState(ctx, genesisState, parentRoot), "Could not save genesis state")
require.NoError(t, db.SaveHeadBlockRoot(ctx, parentRoot), "Could not save genesis state")
return genesisState, parentRoot, privateKeys
}