mirror of
https://github.com/OffchainLabs/prysm.git
synced 2026-02-15 07:25:14 -05:00
This PR moves kzg commitments to bid. The rationale behind is captured in this [issue](https://github.com/ethereum/consensus-specs/issues/4870) * Moves blob KZG commitments to the earlier point where builder intent is known * Removes duplicated commitments from data column sidecars which saves descent b/w per slot * Enables nodes to start fetching blobs via getBlobs as soon as the bid is received * Slightly increases bid size and may add minor bidding channel latency but the tradeoff favors lower network load and simpler DA handling
644 lines
24 KiB
Go
644 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/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 := ðpb.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: ðpb.Checkpoint{Root: make([]byte, fieldparams.RootLength)},
|
|
Eth1Data: ðpb.Eth1Data{
|
|
DepositRoot: make([]byte, fieldparams.RootLength),
|
|
BlockHash: make([]byte, 32),
|
|
},
|
|
Fork: ðpb.Fork{
|
|
PreviousVersion: make([]byte, 4),
|
|
CurrentVersion: make([]byte, 4),
|
|
},
|
|
Eth1DataVotes: make([]*ethpb.Eth1Data, 0),
|
|
HistoricalRoots: make([][]byte, 0),
|
|
JustificationBits: bitfield.Bitvector4{0x0},
|
|
FinalizedCheckpoint: ðpb.Checkpoint{Root: make([]byte, fieldparams.RootLength)},
|
|
LatestBlockHeader: HydrateBeaconHeader(ðpb.BeaconBlockHeader{}),
|
|
PreviousEpochAttestations: make([]*ethpb.PendingAttestation, 0),
|
|
CurrentEpochAttestations: make([]*ethpb.PendingAttestation, 0),
|
|
PreviousJustifiedCheckpoint: ðpb.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 := ðpb.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: ðpb.Checkpoint{Root: make([]byte, fieldparams.RootLength)},
|
|
Eth1Data: ðpb.Eth1Data{
|
|
DepositRoot: make([]byte, fieldparams.RootLength),
|
|
BlockHash: make([]byte, 32),
|
|
},
|
|
Fork: ðpb.Fork{
|
|
PreviousVersion: make([]byte, 4),
|
|
CurrentVersion: make([]byte, 4),
|
|
},
|
|
Eth1DataVotes: make([]*ethpb.Eth1Data, 0),
|
|
HistoricalRoots: make([][]byte, 0),
|
|
JustificationBits: bitfield.Bitvector4{0x0},
|
|
FinalizedCheckpoint: ðpb.Checkpoint{Root: make([]byte, fieldparams.RootLength)},
|
|
LatestBlockHeader: HydrateBeaconHeader(ðpb.BeaconBlockHeader{}),
|
|
PreviousJustifiedCheckpoint: ðpb.Checkpoint{Root: make([]byte, fieldparams.RootLength)},
|
|
PreviousEpochParticipation: make([]byte, 0),
|
|
CurrentEpochParticipation: make([]byte, 0),
|
|
CurrentSyncCommittee: ðpb.SyncCommittee{
|
|
Pubkeys: pubkeys,
|
|
AggregatePubkey: make([]byte, 48),
|
|
},
|
|
NextSyncCommittee: ðpb.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 := ðpb.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: ðpb.Checkpoint{Root: make([]byte, fieldparams.RootLength)},
|
|
Eth1Data: ðpb.Eth1Data{
|
|
DepositRoot: make([]byte, fieldparams.RootLength),
|
|
BlockHash: make([]byte, 32),
|
|
},
|
|
Fork: ðpb.Fork{
|
|
PreviousVersion: make([]byte, 4),
|
|
CurrentVersion: make([]byte, 4),
|
|
},
|
|
Eth1DataVotes: make([]*ethpb.Eth1Data, 0),
|
|
HistoricalRoots: make([][]byte, 0),
|
|
JustificationBits: bitfield.Bitvector4{0x0},
|
|
FinalizedCheckpoint: ðpb.Checkpoint{Root: make([]byte, fieldparams.RootLength)},
|
|
LatestBlockHeader: HydrateBeaconHeader(ðpb.BeaconBlockHeader{}),
|
|
PreviousJustifiedCheckpoint: ðpb.Checkpoint{Root: make([]byte, fieldparams.RootLength)},
|
|
PreviousEpochParticipation: make([]byte, 0),
|
|
CurrentEpochParticipation: make([]byte, 0),
|
|
CurrentSyncCommittee: ðpb.SyncCommittee{
|
|
Pubkeys: pubkeys,
|
|
AggregatePubkey: make([]byte, 48),
|
|
},
|
|
NextSyncCommittee: ðpb.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 := ðpb.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: ðpb.Checkpoint{Root: make([]byte, fieldparams.RootLength)},
|
|
Eth1Data: ðpb.Eth1Data{
|
|
DepositRoot: make([]byte, fieldparams.RootLength),
|
|
BlockHash: make([]byte, 32),
|
|
},
|
|
Fork: ðpb.Fork{
|
|
PreviousVersion: make([]byte, 4),
|
|
CurrentVersion: make([]byte, 4),
|
|
},
|
|
Eth1DataVotes: make([]*ethpb.Eth1Data, 0),
|
|
HistoricalSummaries: make([]*ethpb.HistoricalSummary, 0),
|
|
JustificationBits: bitfield.Bitvector4{0x0},
|
|
FinalizedCheckpoint: ðpb.Checkpoint{Root: make([]byte, fieldparams.RootLength)},
|
|
LatestBlockHeader: HydrateBeaconHeader(ðpb.BeaconBlockHeader{}),
|
|
PreviousJustifiedCheckpoint: ðpb.Checkpoint{Root: make([]byte, fieldparams.RootLength)},
|
|
PreviousEpochParticipation: make([]byte, 0),
|
|
CurrentEpochParticipation: make([]byte, 0),
|
|
CurrentSyncCommittee: ðpb.SyncCommittee{
|
|
Pubkeys: pubkeys,
|
|
AggregatePubkey: make([]byte, 48),
|
|
},
|
|
NextSyncCommittee: ðpb.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 := ðpb.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: ðpb.Checkpoint{Root: make([]byte, fieldparams.RootLength)},
|
|
Eth1Data: ðpb.Eth1Data{
|
|
DepositRoot: make([]byte, fieldparams.RootLength),
|
|
BlockHash: make([]byte, 32),
|
|
},
|
|
Fork: ðpb.Fork{
|
|
PreviousVersion: make([]byte, 4),
|
|
CurrentVersion: make([]byte, 4),
|
|
},
|
|
Eth1DataVotes: make([]*ethpb.Eth1Data, 0),
|
|
HistoricalRoots: make([][]byte, 0),
|
|
JustificationBits: bitfield.Bitvector4{0x0},
|
|
FinalizedCheckpoint: ðpb.Checkpoint{Root: make([]byte, fieldparams.RootLength)},
|
|
LatestBlockHeader: HydrateBeaconHeader(ðpb.BeaconBlockHeader{}),
|
|
PreviousJustifiedCheckpoint: ðpb.Checkpoint{Root: make([]byte, fieldparams.RootLength)},
|
|
PreviousEpochParticipation: make([]byte, 0),
|
|
CurrentEpochParticipation: make([]byte, 0),
|
|
CurrentSyncCommittee: ðpb.SyncCommittee{
|
|
Pubkeys: pubkeys,
|
|
AggregatePubkey: make([]byte, 48),
|
|
},
|
|
NextSyncCommittee: ðpb.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 := ðpb.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: ðpb.Checkpoint{Root: make([]byte, fieldparams.RootLength)},
|
|
Eth1Data: ðpb.Eth1Data{
|
|
DepositRoot: make([]byte, fieldparams.RootLength),
|
|
BlockHash: make([]byte, 32),
|
|
},
|
|
Fork: ðpb.Fork{
|
|
PreviousVersion: make([]byte, 4),
|
|
CurrentVersion: make([]byte, 4),
|
|
},
|
|
Eth1DataVotes: make([]*ethpb.Eth1Data, 0),
|
|
HistoricalRoots: make([][]byte, 0),
|
|
JustificationBits: bitfield.Bitvector4{0x0},
|
|
FinalizedCheckpoint: ðpb.Checkpoint{Root: make([]byte, fieldparams.RootLength)},
|
|
LatestBlockHeader: HydrateBeaconHeader(ðpb.BeaconBlockHeader{}),
|
|
PreviousJustifiedCheckpoint: ðpb.Checkpoint{Root: make([]byte, fieldparams.RootLength)},
|
|
PreviousEpochParticipation: make([]byte, 0),
|
|
CurrentEpochParticipation: make([]byte, 0),
|
|
CurrentSyncCommittee: ðpb.SyncCommittee{
|
|
Pubkeys: pubkeys,
|
|
AggregatePubkey: make([]byte, 48),
|
|
},
|
|
NextSyncCommittee: ðpb.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 := ðpb.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: ðpb.Checkpoint{Root: make([]byte, fieldparams.RootLength)},
|
|
Eth1Data: ðpb.Eth1Data{
|
|
DepositRoot: make([]byte, fieldparams.RootLength),
|
|
BlockHash: make([]byte, 32),
|
|
},
|
|
Fork: ðpb.Fork{
|
|
PreviousVersion: make([]byte, 4),
|
|
CurrentVersion: make([]byte, 4),
|
|
},
|
|
Eth1DataVotes: make([]*ethpb.Eth1Data, 0),
|
|
HistoricalRoots: make([][]byte, 0),
|
|
JustificationBits: bitfield.Bitvector4{0x0},
|
|
FinalizedCheckpoint: ðpb.Checkpoint{Root: make([]byte, fieldparams.RootLength)},
|
|
LatestBlockHeader: HydrateBeaconHeader(ðpb.BeaconBlockHeader{}),
|
|
PreviousJustifiedCheckpoint: ðpb.Checkpoint{Root: make([]byte, fieldparams.RootLength)},
|
|
PreviousEpochParticipation: make([]byte, 0),
|
|
CurrentEpochParticipation: make([]byte, 0),
|
|
CurrentSyncCommittee: ðpb.SyncCommittee{
|
|
Pubkeys: pubkeys,
|
|
AggregatePubkey: make([]byte, 48),
|
|
},
|
|
NextSyncCommittee: ðpb.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([]uint64, 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] = ðpb.BuilderPendingPayment{
|
|
Withdrawal: ðpb.BuilderPendingWithdrawal{
|
|
FeeRecipient: make([]byte, 20),
|
|
},
|
|
}
|
|
}
|
|
|
|
seed := ðpb.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: ðpb.Checkpoint{Root: make([]byte, fieldparams.RootLength)},
|
|
Eth1Data: ðpb.Eth1Data{
|
|
DepositRoot: make([]byte, fieldparams.RootLength),
|
|
BlockHash: make([]byte, 32),
|
|
},
|
|
Fork: ðpb.Fork{
|
|
PreviousVersion: make([]byte, 4),
|
|
CurrentVersion: make([]byte, 4),
|
|
},
|
|
Eth1DataVotes: make([]*ethpb.Eth1Data, 0),
|
|
HistoricalRoots: make([][]byte, 0),
|
|
JustificationBits: bitfield.Bitvector4{0x0},
|
|
FinalizedCheckpoint: ðpb.Checkpoint{Root: make([]byte, fieldparams.RootLength)},
|
|
LatestBlockHeader: HydrateBeaconHeader(ðpb.BeaconBlockHeader{}),
|
|
PreviousJustifiedCheckpoint: ðpb.Checkpoint{Root: make([]byte, fieldparams.RootLength)},
|
|
PreviousEpochParticipation: make([]byte, 0),
|
|
CurrentEpochParticipation: make([]byte, 0),
|
|
CurrentSyncCommittee: ðpb.SyncCommittee{
|
|
Pubkeys: pubkeys,
|
|
AggregatePubkey: make([]byte, 48),
|
|
},
|
|
NextSyncCommittee: ðpb.SyncCommittee{
|
|
Pubkeys: pubkeys,
|
|
AggregatePubkey: make([]byte, 48),
|
|
},
|
|
ProposerLookahead: make([]uint64, 64),
|
|
LatestExecutionPayloadBid: ðpb.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)},
|
|
},
|
|
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),
|
|
}
|
|
|
|
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
|
|
}
|