Files
prysm/runtime/interop/premine-state.go
james-prysm f97622b054 e2e support electra forkstart (#16048)
<!-- Thanks for sending a PR! Before submitting:

1. If this is your first PR, check out our contribution guide here
https://docs.prylabs.network/docs/contribute/contribution-guidelines
You will then need to sign our Contributor License Agreement (CLA),
which will show up as a comment from a bot in this pull request after
you open it. We cannot review code without a signed CLA.
2. Please file an associated tracking issue if this pull request is
non-trivial and requires context for our team to understand. All
features and most bug fixes should have
an associated issue with a design discussed and decided upon. Small bug
   fixes and documentation improvements don't need issues.
3. New features and bug fixes must have tests. Documentation may need to
be updated. If you're unsure what to update, send the PR, and we'll
discuss
   in review.
4. Note that PRs updating dependencies and new Go versions are not
accepted.
   Please file an issue instead.
5. A changelog entry is required for user facing issues.
-->

**What type of PR is this?**

Bug fix


**What does this PR do? Why is it needed?**

Allows for starting e2e tests from electra or a specific fork of
interest again. doesn't fix missing execution requests tests, nishant
reverted it.

**Which issues(s) does this PR fix?**

Fixes #

**Other notes for review**

**Acknowledgements**

- [x] I have read
[CONTRIBUTING.md](https://github.com/prysmaticlabs/prysm/blob/develop/CONTRIBUTING.md).
- [x] I have included a uniquely named [changelog fragment
file](https://github.com/prysmaticlabs/prysm/blob/develop/CONTRIBUTING.md#maintaining-changelogmd).
- [x] I have added a description to this PR with sufficient context for
reviewers to understand this PR.

---------

Co-authored-by: Radosław Kapka <rkapka@wp.pl>
2025-11-26 16:33:24 +00:00

777 lines
22 KiB
Go

package interop
import (
"context"
"time"
"github.com/OffchainLabs/prysm/v7/beacon-chain/core/altair"
"github.com/OffchainLabs/prysm/v7/beacon-chain/core/helpers"
"github.com/OffchainLabs/prysm/v7/beacon-chain/state"
state_native "github.com/OffchainLabs/prysm/v7/beacon-chain/state/state-native"
"github.com/OffchainLabs/prysm/v7/beacon-chain/state/stateutil"
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/container/trie"
"github.com/OffchainLabs/prysm/v7/crypto/bls"
"github.com/OffchainLabs/prysm/v7/encoding/bytesutil"
enginev1 "github.com/OffchainLabs/prysm/v7/proto/engine/v1"
ethpb "github.com/OffchainLabs/prysm/v7/proto/prysm/v1alpha1"
"github.com/OffchainLabs/prysm/v7/runtime/version"
"github.com/ethereum/go-ethereum/core/types"
"github.com/pkg/errors"
)
var errUnsupportedVersion = errors.New("schema version not supported by PremineGenesisConfig")
type PremineGenesisConfig struct {
GenesisTime time.Time
NVals uint64
PregenesisCreds uint64
Version int // as in "github.com/OffchainLabs/prysm/v7/runtime/version"
GB *types.Block // geth genesis block
depositEntries *depositEntries
}
type depositEntries struct {
dds []*ethpb.Deposit_Data
roots [][]byte
}
type PremineGenesisOpt func(*PremineGenesisConfig)
func WithDepositData(dds []*ethpb.Deposit_Data, roots [][]byte) PremineGenesisOpt {
return func(cfg *PremineGenesisConfig) {
cfg.depositEntries = &depositEntries{
dds: dds,
roots: roots,
}
}
}
// NewPreminedGenesis creates a genesis BeaconState at the given fork version, suitable for using as an e2e genesis.
func NewPreminedGenesis(ctx context.Context, genesis time.Time, nvals, pCreds uint64, version int, gb *types.Block, opts ...PremineGenesisOpt) (state.BeaconState, error) {
cfg := &PremineGenesisConfig{
GenesisTime: genesis,
NVals: nvals,
PregenesisCreds: pCreds,
Version: version,
GB: gb,
}
for _, o := range opts {
o(cfg)
}
return cfg.prepare(ctx)
}
func (s *PremineGenesisConfig) prepare(ctx context.Context) (state.BeaconState, error) {
switch s.Version {
case version.Phase0, version.Altair, version.Bellatrix, version.Capella, version.Deneb, version.Electra, version.Fulu:
default:
return nil, errors.Wrapf(errUnsupportedVersion, "version=%s", version.String(s.Version))
}
st, err := s.empty()
if err != nil {
return nil, err
}
if err = s.processDeposits(ctx, st); err != nil {
return nil, err
}
if err = s.populate(st); err != nil {
return nil, err
}
return st, nil
}
func (s *PremineGenesisConfig) empty() (state.BeaconState, error) {
var e state.BeaconState
var err error
bRoots := make([][]byte, fieldparams.BlockRootsLength)
for i := range bRoots {
bRoots[i] = bytesutil.PadTo([]byte{}, 32)
}
sRoots := make([][]byte, fieldparams.StateRootsLength)
for i := range sRoots {
sRoots[i] = bytesutil.PadTo([]byte{}, 32)
}
mixes := make([][]byte, fieldparams.RandaoMixesLength)
for i := range mixes {
mixes[i] = bytesutil.PadTo([]byte{}, 32)
}
switch s.Version {
case version.Phase0:
e, err = state_native.InitializeFromProtoPhase0(&ethpb.BeaconState{
BlockRoots: bRoots,
StateRoots: sRoots,
RandaoMixes: mixes,
Balances: []uint64{},
Validators: []*ethpb.Validator{},
})
if err != nil {
return nil, err
}
case version.Altair:
e, err = state_native.InitializeFromProtoAltair(&ethpb.BeaconStateAltair{
BlockRoots: bRoots,
StateRoots: sRoots,
RandaoMixes: mixes,
Balances: []uint64{},
InactivityScores: []uint64{},
Validators: []*ethpb.Validator{},
})
if err != nil {
return nil, err
}
case version.Bellatrix:
e, err = state_native.InitializeFromProtoBellatrix(&ethpb.BeaconStateBellatrix{
BlockRoots: bRoots,
StateRoots: sRoots,
RandaoMixes: mixes,
Balances: []uint64{},
InactivityScores: []uint64{},
Validators: []*ethpb.Validator{},
})
if err != nil {
return nil, err
}
case version.Capella:
e, err = state_native.InitializeFromProtoCapella(&ethpb.BeaconStateCapella{
BlockRoots: bRoots,
StateRoots: sRoots,
RandaoMixes: mixes,
Balances: []uint64{},
InactivityScores: []uint64{},
Validators: []*ethpb.Validator{},
})
if err != nil {
return nil, err
}
case version.Deneb:
e, err = state_native.InitializeFromProtoDeneb(&ethpb.BeaconStateDeneb{})
if err != nil {
return nil, err
}
case version.Electra:
e, err = state_native.InitializeFromProtoElectra(&ethpb.BeaconStateElectra{
DepositRequestsStartIndex: params.BeaconConfig().UnsetDepositRequestsStartIndex,
})
if err != nil {
return nil, err
}
case version.Fulu:
e, err = state_native.InitializeFromProtoFulu(&ethpb.BeaconStateFulu{
DepositRequestsStartIndex: params.BeaconConfig().UnsetDepositRequestsStartIndex,
})
if err != nil {
return nil, err
}
default:
return nil, errUnsupportedVersion
}
if err = e.SetSlot(0); err != nil {
return nil, err
}
if err = e.SetJustificationBits([]byte{0}); err != nil {
return nil, err
}
if err = e.SetHistoricalRoots([][]byte{}); err != nil {
return nil, err
}
zcp := &ethpb.Checkpoint{
Epoch: 0,
Root: params.BeaconConfig().ZeroHash[:],
}
if err = e.SetPreviousJustifiedCheckpoint(zcp); err != nil {
return nil, err
}
if err = e.SetCurrentJustifiedCheckpoint(zcp); err != nil {
return nil, err
}
if err = e.SetFinalizedCheckpoint(zcp); err != nil {
return nil, err
}
if err = e.SetEth1DataVotes([]*ethpb.Eth1Data{}); err != nil {
return nil, err
}
if s.Version == version.Phase0 {
if err = e.SetCurrentEpochAttestations([]*ethpb.PendingAttestation{}); err != nil {
return nil, err
}
if err = e.SetPreviousEpochAttestations([]*ethpb.PendingAttestation{}); err != nil {
return nil, err
}
}
return e.Copy(), nil
}
func (s *PremineGenesisConfig) processDeposits(ctx context.Context, g state.BeaconState) error {
deposits, err := s.deposits()
if err != nil {
return err
}
if err = s.setEth1Data(g); err != nil {
return err
}
if _, err = helpers.UpdateGenesisEth1Data(g, deposits, g.Eth1Data()); err != nil {
return err
}
// TODO: should be updated when electra E2E is updated
_, err = altair.ProcessPreGenesisDeposits(ctx, g, deposits)
if err != nil {
return errors.Wrap(err, "could not process validator deposits")
}
return nil
}
func (s *PremineGenesisConfig) deposits() ([]*ethpb.Deposit, error) {
if s.depositEntries == nil {
prv, pub, err := s.keys()
if err != nil {
return nil, err
}
dds, roots, err := DepositDataFromKeysWithExecCreds(prv, pub, s.PregenesisCreds)
if err != nil {
return nil, errors.Wrap(err, "could not generate deposit data from keys")
}
s.depositEntries = &depositEntries{
dds: dds,
roots: roots,
}
}
t, err := trie.GenerateTrieFromItems(s.depositEntries.roots, params.BeaconConfig().DepositContractTreeDepth)
if err != nil {
return nil, errors.Wrap(err, "could not generate Merkle trie for deposit proofs")
}
deposits, err := GenerateDepositsFromData(s.depositEntries.dds, t)
if err != nil {
return nil, errors.Wrap(err, "could not generate deposits from the deposit data provided")
}
return deposits, nil
}
func (s *PremineGenesisConfig) keys() ([]bls.SecretKey, []bls.PublicKey, error) {
prv, pub, err := DeterministicallyGenerateKeys(0, s.NVals)
if err != nil {
return nil, nil, errors.Wrapf(err, "could not deterministically generate keys for %d validators", s.NVals)
}
return prv, pub, nil
}
func (s *PremineGenesisConfig) setEth1Data(g state.BeaconState) error {
if err := g.SetEth1DepositIndex(0); err != nil {
return err
}
dr, err := emptyDepositRoot()
if err != nil {
return err
}
return g.SetEth1Data(&ethpb.Eth1Data{DepositRoot: dr[:], BlockHash: s.GB.Hash().Bytes()})
}
func emptyDepositRoot() ([32]byte, error) {
t, err := trie.NewTrie(params.BeaconConfig().DepositContractTreeDepth)
if err != nil {
return [32]byte{}, err
}
return t.HashTreeRoot()
}
func (s *PremineGenesisConfig) populate(g state.BeaconState) error {
if err := g.SetGenesisTime(s.GenesisTime); err != nil {
return err
}
if err := s.setGenesisValidatorsRoot(g); err != nil {
return err
}
if err := s.setFork(g); err != nil {
return err
}
rao := nSetRoots(uint64(params.BeaconConfig().EpochsPerHistoricalVector), s.GB.Hash().Bytes())
if err := g.SetRandaoMixes(rao); err != nil {
return err
}
if err := g.SetBlockRoots(nZeroRoots(uint64(params.BeaconConfig().SlotsPerHistoricalRoot))); err != nil {
return err
}
if err := g.SetStateRoots(nZeroRoots(uint64(params.BeaconConfig().SlotsPerHistoricalRoot))); err != nil {
return err
}
if err := g.SetSlashings(make([]uint64, params.BeaconConfig().EpochsPerSlashingsVector)); err != nil {
return err
}
if err := s.setLatestBlockHeader(g); err != nil {
return err
}
if err := s.setInactivityScores(g); err != nil {
return err
}
if err := s.setCurrentEpochParticipation(g); err != nil {
return err
}
if err := s.setPrevEpochParticipation(g); err != nil {
return err
}
if err := s.setSyncCommittees(g); err != nil {
return err
}
if err := s.setExecutionPayload(g); err != nil {
return err
}
// For pre-mined genesis, we want to keep the deposit root set to the root of an empty trie.
// This needs to be set again because the methods used by processDeposits mutate the state's eth1data.
return s.setEth1Data(g)
}
func (s *PremineGenesisConfig) setGenesisValidatorsRoot(g state.BeaconState) error {
vroot, err := stateutil.ValidatorRegistryRoot(g.Validators())
if err != nil {
return err
}
return g.SetGenesisValidatorsRoot(vroot[:])
}
func (s *PremineGenesisConfig) setFork(g state.BeaconState) error {
var pv, cv []byte
switch s.Version {
case version.Phase0:
pv, cv = params.BeaconConfig().GenesisForkVersion, params.BeaconConfig().GenesisForkVersion
case version.Altair:
pv, cv = params.BeaconConfig().GenesisForkVersion, params.BeaconConfig().AltairForkVersion
case version.Bellatrix:
pv, cv = params.BeaconConfig().AltairForkVersion, params.BeaconConfig().BellatrixForkVersion
case version.Capella:
pv, cv = params.BeaconConfig().BellatrixForkVersion, params.BeaconConfig().CapellaForkVersion
case version.Deneb:
pv, cv = params.BeaconConfig().CapellaForkVersion, params.BeaconConfig().DenebForkVersion
case version.Electra:
pv, cv = params.BeaconConfig().DenebForkVersion, params.BeaconConfig().ElectraForkVersion
case version.Fulu:
pv, cv = params.BeaconConfig().ElectraForkVersion, params.BeaconConfig().FuluForkVersion
default:
return errUnsupportedVersion
}
fork := &ethpb.Fork{
PreviousVersion: pv,
CurrentVersion: cv,
Epoch: 0,
}
return g.SetFork(fork)
}
func (s *PremineGenesisConfig) setInactivityScores(g state.BeaconState) error {
if s.Version < version.Altair {
return nil
}
scores, err := g.InactivityScores()
if err != nil {
return err
}
scoresMissing := len(g.Validators()) - len(scores)
if scoresMissing > 0 {
for range scoresMissing {
scores = append(scores, 0)
}
}
return g.SetInactivityScores(scores)
}
func (s *PremineGenesisConfig) setCurrentEpochParticipation(g state.BeaconState) error {
if s.Version < version.Altair {
return nil
}
p, err := g.CurrentEpochParticipation()
if err != nil {
return err
}
missing := len(g.Validators()) - len(p)
if missing > 0 {
for range missing {
p = append(p, 0)
}
}
return g.SetCurrentParticipationBits(p)
}
func (s *PremineGenesisConfig) setPrevEpochParticipation(g state.BeaconState) error {
if s.Version < version.Altair {
return nil
}
p, err := g.PreviousEpochParticipation()
if err != nil {
return err
}
missing := len(g.Validators()) - len(p)
if missing > 0 {
for range missing {
p = append(p, 0)
}
}
return g.SetPreviousParticipationBits(p)
}
func (s *PremineGenesisConfig) setSyncCommittees(g state.BeaconState) error {
if s.Version < version.Altair {
return nil
}
sc, err := altair.NextSyncCommittee(context.Background(), g)
if err != nil {
return err
}
if err = g.SetNextSyncCommittee(sc); err != nil {
return err
}
return g.SetCurrentSyncCommittee(sc)
}
type rooter interface {
HashTreeRoot() ([32]byte, error)
}
func (s *PremineGenesisConfig) setLatestBlockHeader(g state.BeaconState) error {
var body rooter
switch s.Version {
case version.Phase0:
body = &ethpb.BeaconBlockBody{
RandaoReveal: make([]byte, 96),
Eth1Data: &ethpb.Eth1Data{
DepositRoot: make([]byte, 32),
BlockHash: make([]byte, 32),
},
Graffiti: make([]byte, 32),
}
case version.Altair:
body = &ethpb.BeaconBlockBodyAltair{
RandaoReveal: make([]byte, 96),
Eth1Data: &ethpb.Eth1Data{
DepositRoot: make([]byte, 32),
BlockHash: make([]byte, 32),
},
Graffiti: make([]byte, 32),
SyncAggregate: &ethpb.SyncAggregate{
SyncCommitteeBits: make([]byte, fieldparams.SyncCommitteeLength/8),
SyncCommitteeSignature: make([]byte, fieldparams.BLSSignatureLength),
},
}
case version.Bellatrix:
body = &ethpb.BeaconBlockBodyBellatrix{
RandaoReveal: make([]byte, 96),
Eth1Data: &ethpb.Eth1Data{
DepositRoot: make([]byte, 32),
BlockHash: make([]byte, 32),
},
Graffiti: make([]byte, 32),
SyncAggregate: &ethpb.SyncAggregate{
SyncCommitteeBits: make([]byte, fieldparams.SyncCommitteeLength/8),
SyncCommitteeSignature: make([]byte, fieldparams.BLSSignatureLength),
},
ExecutionPayload: &enginev1.ExecutionPayload{
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),
Transactions: make([][]byte, 0),
},
}
case version.Capella:
body = &ethpb.BeaconBlockBodyCapella{
RandaoReveal: make([]byte, 96),
Eth1Data: &ethpb.Eth1Data{
DepositRoot: make([]byte, 32),
BlockHash: make([]byte, 32),
},
Graffiti: make([]byte, 32),
SyncAggregate: &ethpb.SyncAggregate{
SyncCommitteeBits: make([]byte, fieldparams.SyncCommitteeLength/8),
SyncCommitteeSignature: make([]byte, fieldparams.BLSSignatureLength),
},
ExecutionPayload: &enginev1.ExecutionPayloadCapella{
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),
Transactions: make([][]byte, 0),
Withdrawals: make([]*enginev1.Withdrawal, 0),
},
BlsToExecutionChanges: make([]*ethpb.SignedBLSToExecutionChange, 0),
}
case version.Deneb:
body = &ethpb.BeaconBlockBodyDeneb{
RandaoReveal: make([]byte, 96),
Eth1Data: &ethpb.Eth1Data{
DepositRoot: make([]byte, 32),
BlockHash: make([]byte, 32),
},
Graffiti: make([]byte, 32),
SyncAggregate: &ethpb.SyncAggregate{
SyncCommitteeBits: make([]byte, fieldparams.SyncCommitteeLength/8),
SyncCommitteeSignature: make([]byte, fieldparams.BLSSignatureLength),
},
ExecutionPayload: &enginev1.ExecutionPayloadDeneb{
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),
Transactions: make([][]byte, 0),
Withdrawals: make([]*enginev1.Withdrawal, 0),
},
BlsToExecutionChanges: make([]*ethpb.SignedBLSToExecutionChange, 0),
BlobKzgCommitments: make([][]byte, 0),
}
case version.Electra:
body = &ethpb.BeaconBlockBodyElectra{
RandaoReveal: make([]byte, 96),
Eth1Data: &ethpb.Eth1Data{
DepositRoot: make([]byte, 32),
BlockHash: make([]byte, 32),
},
Graffiti: make([]byte, 32),
SyncAggregate: &ethpb.SyncAggregate{
SyncCommitteeBits: make([]byte, fieldparams.SyncCommitteeLength/8),
SyncCommitteeSignature: make([]byte, fieldparams.BLSSignatureLength),
},
ExecutionPayload: &enginev1.ExecutionPayloadDeneb{
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),
Transactions: make([][]byte, 0),
Withdrawals: make([]*enginev1.Withdrawal, 0),
},
BlsToExecutionChanges: make([]*ethpb.SignedBLSToExecutionChange, 0),
BlobKzgCommitments: make([][]byte, 0),
ExecutionRequests: &enginev1.ExecutionRequests{
Deposits: make([]*enginev1.DepositRequest, 0),
Withdrawals: make([]*enginev1.WithdrawalRequest, 0),
Consolidations: make([]*enginev1.ConsolidationRequest, 0),
},
}
case version.Fulu:
body = &ethpb.BeaconBlockBodyElectra{
RandaoReveal: make([]byte, 96),
Eth1Data: &ethpb.Eth1Data{
DepositRoot: make([]byte, 32),
BlockHash: make([]byte, 32),
},
Graffiti: make([]byte, 32),
SyncAggregate: &ethpb.SyncAggregate{
SyncCommitteeBits: make([]byte, fieldparams.SyncCommitteeLength/8),
SyncCommitteeSignature: make([]byte, fieldparams.BLSSignatureLength),
},
ExecutionPayload: &enginev1.ExecutionPayloadDeneb{
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),
Transactions: make([][]byte, 0),
Withdrawals: make([]*enginev1.Withdrawal, 0),
},
BlsToExecutionChanges: make([]*ethpb.SignedBLSToExecutionChange, 0),
BlobKzgCommitments: make([][]byte, 0),
ExecutionRequests: &enginev1.ExecutionRequests{
Deposits: make([]*enginev1.DepositRequest, 0),
Withdrawals: make([]*enginev1.WithdrawalRequest, 0),
Consolidations: make([]*enginev1.ConsolidationRequest, 0),
},
}
default:
return errUnsupportedVersion
}
root, err := body.HashTreeRoot()
if err != nil {
return errors.Wrap(err, "could not hash tree root empty block body")
}
lbh := &ethpb.BeaconBlockHeader{
ParentRoot: params.BeaconConfig().ZeroHash[:],
StateRoot: params.BeaconConfig().ZeroHash[:],
BodyRoot: root[:],
}
return g.SetLatestBlockHeader(lbh)
}
func (s *PremineGenesisConfig) setExecutionPayload(g state.BeaconState) error {
gb := s.GB
extraData := gb.Extra()
if len(extraData) > 32 {
extraData = extraData[:32]
}
if s.Version >= version.Deneb {
payload := &enginev1.ExecutionPayloadDeneb{
ParentHash: gb.ParentHash().Bytes(),
FeeRecipient: gb.Coinbase().Bytes(),
StateRoot: gb.Root().Bytes(),
ReceiptsRoot: gb.ReceiptHash().Bytes(),
LogsBloom: gb.Bloom().Bytes(),
PrevRandao: params.BeaconConfig().ZeroHash[:],
BlockNumber: gb.NumberU64(),
GasLimit: gb.GasLimit(),
GasUsed: gb.GasUsed(),
Timestamp: gb.Time(),
ExtraData: extraData,
BaseFeePerGas: bytesutil.PadTo(bytesutil.ReverseByteOrder(gb.BaseFee().Bytes()), fieldparams.RootLength),
BlockHash: gb.Hash().Bytes(),
Transactions: make([][]byte, 0),
Withdrawals: make([]*enginev1.Withdrawal, 0),
ExcessBlobGas: unwrapUint64Ptr(gb.ExcessBlobGas()),
BlobGasUsed: unwrapUint64Ptr(gb.BlobGasUsed()),
}
wep, err := blocks.WrappedExecutionPayloadDeneb(payload)
if err != nil {
return err
}
eph, err := blocks.PayloadToHeaderDeneb(wep)
if err != nil {
return err
}
ed, err := blocks.WrappedExecutionPayloadHeaderDeneb(eph)
if err != nil {
return err
}
return g.SetLatestExecutionPayloadHeader(ed)
}
if s.Version >= version.Capella {
payload := &enginev1.ExecutionPayloadCapella{
ParentHash: gb.ParentHash().Bytes(),
FeeRecipient: gb.Coinbase().Bytes(),
StateRoot: gb.Root().Bytes(),
ReceiptsRoot: gb.ReceiptHash().Bytes(),
LogsBloom: gb.Bloom().Bytes(),
PrevRandao: params.BeaconConfig().ZeroHash[:],
BlockNumber: gb.NumberU64(),
GasLimit: gb.GasLimit(),
GasUsed: gb.GasUsed(),
Timestamp: gb.Time(),
ExtraData: extraData,
BaseFeePerGas: bytesutil.PadTo(bytesutil.ReverseByteOrder(gb.BaseFee().Bytes()), fieldparams.RootLength),
BlockHash: gb.Hash().Bytes(),
Transactions: make([][]byte, 0),
Withdrawals: make([]*enginev1.Withdrawal, 0),
}
wep, err := blocks.WrappedExecutionPayloadCapella(payload)
if err != nil {
return err
}
eph, err := blocks.PayloadToHeaderCapella(wep)
if err != nil {
return err
}
ed, err := blocks.WrappedExecutionPayloadHeaderCapella(eph)
if err != nil {
return err
}
return g.SetLatestExecutionPayloadHeader(ed)
}
if s.Version >= version.Bellatrix {
payload := &enginev1.ExecutionPayload{
ParentHash: gb.ParentHash().Bytes(),
FeeRecipient: gb.Coinbase().Bytes(),
StateRoot: gb.Root().Bytes(),
ReceiptsRoot: gb.ReceiptHash().Bytes(),
LogsBloom: gb.Bloom().Bytes(),
PrevRandao: params.BeaconConfig().ZeroHash[:],
BlockNumber: gb.NumberU64(),
GasLimit: gb.GasLimit(),
GasUsed: gb.GasUsed(),
Timestamp: gb.Time(),
ExtraData: extraData,
BaseFeePerGas: bytesutil.PadTo(bytesutil.ReverseByteOrder(gb.BaseFee().Bytes()), fieldparams.RootLength),
BlockHash: gb.Hash().Bytes(),
Transactions: make([][]byte, 0),
}
wep, err := blocks.WrappedExecutionPayload(payload)
if err != nil {
return err
}
eph, err := blocks.PayloadToHeader(wep)
if err != nil {
return err
}
ed, err := blocks.WrappedExecutionPayloadHeader(eph)
if err != nil {
return err
}
return g.SetLatestExecutionPayloadHeader(ed)
}
if s.Version >= version.Phase0 {
return nil
}
return errUnsupportedVersion
}
func unwrapUint64Ptr(u *uint64) uint64 {
if u == nil {
return 0
}
return *u
}
func nZeroRoots(n uint64) [][]byte {
roots := make([][]byte, n)
zh := params.BeaconConfig().ZeroHash[:]
for i := range n {
roots[i] = zh
}
return roots
}
func nSetRoots(n uint64, r []byte) [][]byte {
roots := make([][]byte, n)
for i := range n {
h := make([]byte, 32)
copy(h, r)
roots[i] = h
}
return roots
}