mirror of
https://github.com/OffchainLabs/prysm.git
synced 2026-01-06 20:13:59 -05:00
<!-- 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>
777 lines
22 KiB
Go
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(ðpb.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(ðpb.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(ðpb.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(ðpb.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(ðpb.BeaconStateDeneb{})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
case version.Electra:
|
|
e, err = state_native.InitializeFromProtoElectra(ðpb.BeaconStateElectra{
|
|
DepositRequestsStartIndex: params.BeaconConfig().UnsetDepositRequestsStartIndex,
|
|
})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
case version.Fulu:
|
|
e, err = state_native.InitializeFromProtoFulu(ðpb.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 := ðpb.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(ðpb.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 := ðpb.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 = ðpb.BeaconBlockBody{
|
|
RandaoReveal: make([]byte, 96),
|
|
Eth1Data: ðpb.Eth1Data{
|
|
DepositRoot: make([]byte, 32),
|
|
BlockHash: make([]byte, 32),
|
|
},
|
|
Graffiti: make([]byte, 32),
|
|
}
|
|
case version.Altair:
|
|
body = ðpb.BeaconBlockBodyAltair{
|
|
RandaoReveal: make([]byte, 96),
|
|
Eth1Data: ðpb.Eth1Data{
|
|
DepositRoot: make([]byte, 32),
|
|
BlockHash: make([]byte, 32),
|
|
},
|
|
Graffiti: make([]byte, 32),
|
|
SyncAggregate: ðpb.SyncAggregate{
|
|
SyncCommitteeBits: make([]byte, fieldparams.SyncCommitteeLength/8),
|
|
SyncCommitteeSignature: make([]byte, fieldparams.BLSSignatureLength),
|
|
},
|
|
}
|
|
case version.Bellatrix:
|
|
body = ðpb.BeaconBlockBodyBellatrix{
|
|
RandaoReveal: make([]byte, 96),
|
|
Eth1Data: ðpb.Eth1Data{
|
|
DepositRoot: make([]byte, 32),
|
|
BlockHash: make([]byte, 32),
|
|
},
|
|
Graffiti: make([]byte, 32),
|
|
SyncAggregate: ðpb.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 = ðpb.BeaconBlockBodyCapella{
|
|
RandaoReveal: make([]byte, 96),
|
|
Eth1Data: ðpb.Eth1Data{
|
|
DepositRoot: make([]byte, 32),
|
|
BlockHash: make([]byte, 32),
|
|
},
|
|
Graffiti: make([]byte, 32),
|
|
SyncAggregate: ðpb.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 = ðpb.BeaconBlockBodyDeneb{
|
|
RandaoReveal: make([]byte, 96),
|
|
Eth1Data: ðpb.Eth1Data{
|
|
DepositRoot: make([]byte, 32),
|
|
BlockHash: make([]byte, 32),
|
|
},
|
|
Graffiti: make([]byte, 32),
|
|
SyncAggregate: ðpb.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 = ðpb.BeaconBlockBodyElectra{
|
|
RandaoReveal: make([]byte, 96),
|
|
Eth1Data: ðpb.Eth1Data{
|
|
DepositRoot: make([]byte, 32),
|
|
BlockHash: make([]byte, 32),
|
|
},
|
|
Graffiti: make([]byte, 32),
|
|
SyncAggregate: ðpb.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 = ðpb.BeaconBlockBodyElectra{
|
|
RandaoReveal: make([]byte, 96),
|
|
Eth1Data: ðpb.Eth1Data{
|
|
DepositRoot: make([]byte, 32),
|
|
BlockHash: make([]byte, 32),
|
|
},
|
|
Graffiti: make([]byte, 32),
|
|
SyncAggregate: ðpb.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 := ðpb.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
|
|
}
|