From 07cd61e0da7492d489d9c27f1b1c7988db02382a Mon Sep 17 00:00:00 2001 From: Preston Van Loon Date: Wed, 4 Sep 2024 10:20:48 -0500 Subject: [PATCH 01/12] Remove interop dependencies from production binary for beacon-chain. Specifically, remove the interop genesis service. Finding links to pebble: bazel query 'somepath(//cmd/beacon-chain, @com_github_cockroachdb_pebble//...)' --notool_deps --- CHANGELOG.md | 3 + .../deterministic-genesis/BUILD.bazel | 24 -- beacon-chain/deterministic-genesis/log.go | 7 - beacon-chain/deterministic-genesis/service.go | 206 ------------------ beacon-chain/node/BUILD.bazel | 4 - beacon-chain/node/config.go | 17 -- beacon-chain/node/config_test.go | 60 ----- beacon-chain/node/node.go | 52 +---- beacon-chain/node/node_test.go | 55 ----- cmd/beacon-chain/flags/interop.go | 12 - cmd/beacon-chain/main.go | 2 - cmd/beacon-chain/usage.go | 8 - config/features/deprecated_flags.go | 12 + 13 files changed, 17 insertions(+), 445 deletions(-) delete mode 100644 beacon-chain/deterministic-genesis/BUILD.bazel delete mode 100644 beacon-chain/deterministic-genesis/log.go delete mode 100644 beacon-chain/deterministic-genesis/service.go diff --git a/CHANGELOG.md b/CHANGELOG.md index 2882c93d1cb1..9b9f6bc6e3cf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -46,12 +46,15 @@ The format is based on Keep a Changelog, and this project adheres to Semantic Ve ### Deprecated - `--disable-grpc-gateway` flag is deprecated due to grpc gateway removal. - `--enable-experimental-state` flag is deprecated. This feature is now on by default. Opt-out with `--disable-experimental-state`. +- `--interop-genesis-time` and `--interop-num-validators` have been deprecated in the beacon node as the functionality has been removed. These flags have no effect. ### Removed - removed gRPC Gateway - Removed unused blobs bundle cache - Removed consolidation signing domain from params. The Electra design changed such that EL handles consolidation signature verification. +- Removed support for starting a beacon node with a determinisitic interop genesis state via interop flags. Alteratively, create a genesis state with prysmctl and use `--genesis-state`. + ### Fixed diff --git a/beacon-chain/deterministic-genesis/BUILD.bazel b/beacon-chain/deterministic-genesis/BUILD.bazel deleted file mode 100644 index 32267dc50f34..000000000000 --- a/beacon-chain/deterministic-genesis/BUILD.bazel +++ /dev/null @@ -1,24 +0,0 @@ -load("@prysm//tools/go:def.bzl", "go_library") - -go_library( - name = "go_default_library", - srcs = [ - "log.go", - "service.go", - ], - importpath = "github.com/prysmaticlabs/prysm/v5/beacon-chain/deterministic-genesis", - visibility = ["//beacon-chain:__subpackages__"], - deps = [ - "//beacon-chain/cache:go_default_library", - "//beacon-chain/db:go_default_library", - "//beacon-chain/execution:go_default_library", - "//beacon-chain/state:go_default_library", - "//beacon-chain/state/state-native:go_default_library", - "//consensus-types/primitives:go_default_library", - "//proto/prysm/v1alpha1:go_default_library", - "//runtime:go_default_library", - "//runtime/interop:go_default_library", - "//time/slots:go_default_library", - "@com_github_sirupsen_logrus//:go_default_library", - ], -) diff --git a/beacon-chain/deterministic-genesis/log.go b/beacon-chain/deterministic-genesis/log.go deleted file mode 100644 index a9a259fe87bc..000000000000 --- a/beacon-chain/deterministic-genesis/log.go +++ /dev/null @@ -1,7 +0,0 @@ -package interopcoldstart - -import ( - "github.com/sirupsen/logrus" -) - -var log = logrus.WithField("prefix", "deterministic-genesis") diff --git a/beacon-chain/deterministic-genesis/service.go b/beacon-chain/deterministic-genesis/service.go deleted file mode 100644 index 163acfcd4488..000000000000 --- a/beacon-chain/deterministic-genesis/service.go +++ /dev/null @@ -1,206 +0,0 @@ -// Package interopcoldstart allows for spinning up a deterministic-genesis -// local chain without the need for eth1 deposits useful for -// local client development and interoperability testing. -package interopcoldstart - -import ( - "context" - "math/big" - "os" - "time" - - "github.com/prysmaticlabs/prysm/v5/beacon-chain/cache" - "github.com/prysmaticlabs/prysm/v5/beacon-chain/db" - "github.com/prysmaticlabs/prysm/v5/beacon-chain/execution" - "github.com/prysmaticlabs/prysm/v5/beacon-chain/state" - state_native "github.com/prysmaticlabs/prysm/v5/beacon-chain/state/state-native" - "github.com/prysmaticlabs/prysm/v5/consensus-types/primitives" - ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1" - "github.com/prysmaticlabs/prysm/v5/runtime" - "github.com/prysmaticlabs/prysm/v5/runtime/interop" - "github.com/prysmaticlabs/prysm/v5/time/slots" -) - -var _ runtime.Service = (*Service)(nil) -var _ cache.FinalizedFetcher = (*Service)(nil) -var _ execution.ChainStartFetcher = (*Service)(nil) - -// Service spins up an client interoperability service that handles responsibilities such -// as kickstarting a genesis state for the beacon node from cli flags or a genesis.ssz file. -type Service struct { - cfg *Config - ctx context.Context - cancel context.CancelFunc - chainStartDeposits []*ethpb.Deposit -} - -// All of these methods are stubs as they are not used by a node running with deterministic-genesis. - -func (s *Service) AllDepositContainers(ctx context.Context) []*ethpb.DepositContainer { - log.Errorf("AllDepositContainers should not be called") - return nil -} - -func (s *Service) InsertPendingDeposit(ctx context.Context, d *ethpb.Deposit, blockNum uint64, index int64, depositRoot [32]byte) { - log.Errorf("InsertPendingDeposit should not be called") -} - -func (s *Service) PendingDeposits(ctx context.Context, untilBlk *big.Int) []*ethpb.Deposit { - log.Errorf("PendingDeposits should not be called") - return nil -} - -func (s *Service) PendingContainers(ctx context.Context, untilBlk *big.Int) []*ethpb.DepositContainer { - log.Errorf("PendingContainers should not be called") - return nil -} - -func (s *Service) PrunePendingDeposits(ctx context.Context, merkleTreeIndex int64) { - log.Errorf("PrunePendingDeposits should not be called") -} - -func (s *Service) PruneProofs(ctx context.Context, untilDepositIndex int64) error { - log.Errorf("PruneProofs should not be called") - return nil -} - -// Config options for the interop service. -type Config struct { - GenesisTime uint64 - NumValidators uint64 - BeaconDB db.HeadAccessDatabase - DepositCache cache.DepositCache - GenesisPath string -} - -// NewService is an interoperability testing service to inject a deterministically generated genesis state -// into the beacon chain database and running services at start up. This service should not be used in production -// as it does not have any value other than ease of use for testing purposes. -func NewService(ctx context.Context, cfg *Config) *Service { - ctx, cancel := context.WithCancel(ctx) - - return &Service{ - cfg: cfg, - ctx: ctx, - cancel: cancel, - } -} - -// Start initializes the genesis state from configured flags. -func (s *Service) Start() { - log.Warn("Saving generated genesis state in database for interop testing") - - if s.cfg.GenesisPath != "" { - data, err := os.ReadFile(s.cfg.GenesisPath) - if err != nil { - log.WithError(err).Fatal("Could not read pre-loaded state") - } - genesisState := ðpb.BeaconState{} - if err := genesisState.UnmarshalSSZ(data); err != nil { - log.WithError(err).Fatal("Could not unmarshal pre-loaded state") - } - genesisTrie, err := state_native.InitializeFromProtoPhase0(genesisState) - if err != nil { - log.WithError(err).Fatal("Could not get state trie") - } - if err := s.saveGenesisState(s.ctx, genesisTrie); err != nil { - log.WithError(err).Fatal("Could not save interop genesis state") - } - return - } - - // Save genesis state in db - genesisState, _, err := interop.GenerateGenesisState(s.ctx, s.cfg.GenesisTime, s.cfg.NumValidators) - if err != nil { - log.WithError(err).Fatal("Could not generate interop genesis state") - } - genesisTrie, err := state_native.InitializeFromProtoPhase0(genesisState) - if err != nil { - log.WithError(err).Fatal("Could not get state trie") - } - if s.cfg.GenesisTime == 0 { - // Generated genesis time; fetch it - s.cfg.GenesisTime = genesisTrie.GenesisTime() - } - gRoot, err := genesisTrie.HashTreeRoot(s.ctx) - if err != nil { - log.WithError(err).Fatal("Could not hash tree root genesis state") - } - go slots.CountdownToGenesis(s.ctx, time.Unix(int64(s.cfg.GenesisTime), 0), s.cfg.NumValidators, gRoot) - - if err := s.saveGenesisState(s.ctx, genesisTrie); err != nil { - log.WithError(err).Fatal("Could not save interop genesis state") - } -} - -// Stop does nothing. -func (_ *Service) Stop() error { - return nil -} - -// Status always returns nil. -func (_ *Service) Status() error { - return nil -} - -// AllDeposits mocks out the deposit cache functionality for interop. -func (_ *Service) AllDeposits(_ context.Context, _ *big.Int) []*ethpb.Deposit { - return []*ethpb.Deposit{} -} - -// ChainStartEth1Data mocks out the powchain functionality for interop. -func (_ *Service) ChainStartEth1Data() *ethpb.Eth1Data { - return ðpb.Eth1Data{} -} - -// PreGenesisState returns an empty beacon state. -func (_ *Service) PreGenesisState() state.BeaconState { - s, err := state_native.InitializeFromProtoPhase0(ðpb.BeaconState{}) - if err != nil { - panic("could not initialize state") - } - return s -} - -// ClearPreGenesisData -- -func (_ *Service) ClearPreGenesisData() { - // no-op -} - -// DepositByPubkey mocks out the deposit cache functionality for interop. -func (_ *Service) DepositByPubkey(_ context.Context, _ []byte) (*ethpb.Deposit, *big.Int) { - return ðpb.Deposit{}, nil -} - -// DepositsNumberAndRootAtHeight mocks out the deposit cache functionality for interop. -func (_ *Service) DepositsNumberAndRootAtHeight(_ context.Context, _ *big.Int) (uint64, [32]byte) { - return 0, [32]byte{} -} - -// FinalizedDeposits mocks out the deposit cache functionality for interop. -func (_ *Service) FinalizedDeposits(ctx context.Context) (cache.FinalizedDeposits, error) { - return nil, nil -} - -// NonFinalizedDeposits mocks out the deposit cache functionality for interop. -func (_ *Service) NonFinalizedDeposits(_ context.Context, _ int64, _ *big.Int) []*ethpb.Deposit { - return []*ethpb.Deposit{} -} - -func (s *Service) saveGenesisState(ctx context.Context, genesisState state.BeaconState) error { - if err := s.cfg.BeaconDB.SaveGenesisData(ctx, genesisState); err != nil { - return err - } - - s.chainStartDeposits = make([]*ethpb.Deposit, genesisState.NumValidators()) - - for i := primitives.ValidatorIndex(0); uint64(i) < uint64(genesisState.NumValidators()); i++ { - pk := genesisState.PubkeyAtIndex(i) - s.chainStartDeposits[i] = ðpb.Deposit{ - Data: ðpb.Deposit_Data{ - PublicKey: pk[:], - }, - } - } - return nil -} diff --git a/beacon-chain/node/BUILD.bazel b/beacon-chain/node/BUILD.bazel index a310daf40b26..ab3eb9cd5654 100644 --- a/beacon-chain/node/BUILD.bazel +++ b/beacon-chain/node/BUILD.bazel @@ -26,7 +26,6 @@ go_library( "//beacon-chain/db/filesystem:go_default_library", "//beacon-chain/db/kv:go_default_library", "//beacon-chain/db/slasherkv:go_default_library", - "//beacon-chain/deterministic-genesis:go_default_library", "//beacon-chain/execution:go_default_library", "//beacon-chain/forkchoice:go_default_library", "//beacon-chain/forkchoice/doubly-linked-tree:go_default_library", @@ -92,12 +91,9 @@ go_test( "//cmd:go_default_library", "//cmd/beacon-chain/flags:go_default_library", "//config/features:go_default_library", - "//config/fieldparams:go_default_library", "//config/params:go_default_library", "//consensus-types/primitives:go_default_library", - "//proto/prysm/v1alpha1:go_default_library", "//runtime:go_default_library", - "//runtime/interop:go_default_library", "//testing/assert:go_default_library", "//testing/require:go_default_library", "@com_github_ethereum_go_ethereum//common:go_default_library", diff --git a/beacon-chain/node/config.go b/beacon-chain/node/config.go index eac5b90479f9..56e4f0f77ff0 100644 --- a/beacon-chain/node/config.go +++ b/beacon-chain/node/config.go @@ -144,23 +144,6 @@ func configureNetwork(cliCtx *cli.Context) { } } -func configureInteropConfig(cliCtx *cli.Context) error { - // an explicit chain config was specified, don't mess with it - if cliCtx.IsSet(cmd.ChainConfigFileFlag.Name) { - return nil - } - genTimeIsSet := cliCtx.IsSet(flags.InteropGenesisTimeFlag.Name) - numValsIsSet := cliCtx.IsSet(flags.InteropNumValidatorsFlag.Name) - votesIsSet := cliCtx.IsSet(flags.InteropMockEth1DataVotesFlag.Name) - - if genTimeIsSet || numValsIsSet || votesIsSet { - if err := params.SetActive(params.InteropConfig().Copy()); err != nil { - return err - } - } - return nil -} - func configureExecutionSetting(cliCtx *cli.Context) error { if cliCtx.IsSet(flags.TerminalTotalDifficultyOverride.Name) { c := params.BeaconConfig() diff --git a/beacon-chain/node/config_test.go b/beacon-chain/node/config_test.go index 4c045f4dcd1b..f545f156d01b 100644 --- a/beacon-chain/node/config_test.go +++ b/beacon-chain/node/config_test.go @@ -169,66 +169,6 @@ func TestConfigureNetwork_ConfigFile(t *testing.T) { require.NoError(t, os.Remove("flags_test.yaml")) } -func TestConfigureInterop(t *testing.T) { - params.SetupTestConfigCleanup(t) - - tests := []struct { - name string - flagSetter func() *cli.Context - configName string - }{ - { - "nothing set", - func() *cli.Context { - app := cli.App{} - set := flag.NewFlagSet("test", 0) - return cli.NewContext(&app, set, nil) - }, - "mainnet", - }, - { - "mock votes set", - func() *cli.Context { - app := cli.App{} - set := flag.NewFlagSet("test", 0) - set.Bool(flags.InteropMockEth1DataVotesFlag.Name, false, "") - assert.NoError(t, set.Set(flags.InteropMockEth1DataVotesFlag.Name, "true")) - return cli.NewContext(&app, set, nil) - }, - "interop", - }, - { - "validators set", - func() *cli.Context { - app := cli.App{} - set := flag.NewFlagSet("test", 0) - set.Uint64(flags.InteropNumValidatorsFlag.Name, 0, "") - assert.NoError(t, set.Set(flags.InteropNumValidatorsFlag.Name, "20")) - return cli.NewContext(&app, set, nil) - }, - "interop", - }, - { - "genesis time set", - func() *cli.Context { - app := cli.App{} - set := flag.NewFlagSet("test", 0) - set.Uint64(flags.InteropGenesisTimeFlag.Name, 0, "") - assert.NoError(t, set.Set(flags.InteropGenesisTimeFlag.Name, "200")) - return cli.NewContext(&app, set, nil) - }, - "interop", - }, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - require.NoError(t, configureInteropConfig(tt.flagSetter())) - assert.DeepEqual(t, tt.configName, params.BeaconConfig().ConfigName) - }) - } -} - func TestAliasFlag(t *testing.T) { // Create a new app with the flag app := &cli.App{ diff --git a/beacon-chain/node/node.go b/beacon-chain/node/node.go index c6e6f510cea9..70c477eb6d9d 100644 --- a/beacon-chain/node/node.go +++ b/beacon-chain/node/node.go @@ -30,7 +30,6 @@ import ( "github.com/prysmaticlabs/prysm/v5/beacon-chain/db/filesystem" "github.com/prysmaticlabs/prysm/v5/beacon-chain/db/kv" "github.com/prysmaticlabs/prysm/v5/beacon-chain/db/slasherkv" - interopcoldstart "github.com/prysmaticlabs/prysm/v5/beacon-chain/deterministic-genesis" "github.com/prysmaticlabs/prysm/v5/beacon-chain/execution" "github.com/prysmaticlabs/prysm/v5/beacon-chain/forkchoice" doublylinkedtree "github.com/prysmaticlabs/prysm/v5/beacon-chain/forkchoice/doubly-linked-tree" @@ -268,10 +267,6 @@ func configureBeacon(cliCtx *cli.Context) error { configureNetwork(cliCtx) - if err := configureInteropConfig(cliCtx); err != nil { - return errors.Wrap(err, "could not configure interop config") - } - if err := configureExecutionSetting(cliCtx); err != nil { return errors.Wrap(err, "could not configure execution setting") } @@ -330,11 +325,6 @@ func registerServices(cliCtx *cli.Context, beacon *BeaconNode, synchronizer *sta return errors.Wrap(err, "could not register attestation pool service") } - log.Debugln("Registering Deterministic Genesis Service") - if err := beacon.registerDeterministicGenesisService(); err != nil { - return errors.Wrap(err, "could not register deterministic genesis service") - } - log.Debugln("Registering Blockchain Service") if err := beacon.registerBlockchainService(beacon.forkChoicer, synchronizer, beacon.initialSyncComplete); err != nil { return errors.Wrap(err, "could not register blockchain service") @@ -926,20 +916,8 @@ func (b *BeaconNode) registerRPCService(router *http.ServeMux) error { } } - genesisValidators := b.cliCtx.Uint64(flags.InteropNumValidatorsFlag.Name) - var depositFetcher cache.DepositFetcher - var chainStartFetcher execution.ChainStartFetcher - if genesisValidators > 0 { - var interopService *interopcoldstart.Service - if err := b.services.FetchService(&interopService); err != nil { - return err - } - depositFetcher = interopService - chainStartFetcher = interopService - } else { - depositFetcher = b.depositCache - chainStartFetcher = web3Service - } + depositFetcher := b.depositCache + chainStartFetcher := web3Service host := b.cliCtx.String(flags.RPCHost.Name) port := b.cliCtx.String(flags.RPCPort.Name) @@ -1061,32 +1039,6 @@ func (b *BeaconNode) registerHTTPService(router *http.ServeMux) error { return b.services.RegisterService(g) } -func (b *BeaconNode) registerDeterministicGenesisService() error { - genesisTime := b.cliCtx.Uint64(flags.InteropGenesisTimeFlag.Name) - genesisValidators := b.cliCtx.Uint64(flags.InteropNumValidatorsFlag.Name) - - if genesisValidators > 0 { - svc := interopcoldstart.NewService(b.ctx, &interopcoldstart.Config{ - GenesisTime: genesisTime, - NumValidators: genesisValidators, - BeaconDB: b.db, - DepositCache: b.depositCache, - }) - svc.Start() - - // Register genesis state as start-up state when interop mode. - // The start-up state gets reused across services. - st, err := b.db.GenesisState(b.ctx) - if err != nil { - return err - } - b.finalizedStateAtStartUp = st - - return b.services.RegisterService(svc) - } - return nil -} - func (b *BeaconNode) registerValidatorMonitorService(initialSyncComplete chan struct{}) error { cliSlice := b.cliCtx.IntSlice(cmd.ValidatorMonitorIndicesFlag.Name) if cliSlice == nil { diff --git a/beacon-chain/node/node_test.go b/beacon-chain/node/node_test.go index e8f72562b3d2..09e06dd53ff4 100644 --- a/beacon-chain/node/node_test.go +++ b/beacon-chain/node/node_test.go @@ -6,9 +6,7 @@ import ( "fmt" "net/http" "net/http/httptest" - "os" "path/filepath" - "strconv" "testing" "time" @@ -23,11 +21,7 @@ import ( "github.com/prysmaticlabs/prysm/v5/cmd" "github.com/prysmaticlabs/prysm/v5/cmd/beacon-chain/flags" "github.com/prysmaticlabs/prysm/v5/config/features" - fieldparams "github.com/prysmaticlabs/prysm/v5/config/fieldparams" - "github.com/prysmaticlabs/prysm/v5/config/params" - ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1" "github.com/prysmaticlabs/prysm/v5/runtime" - "github.com/prysmaticlabs/prysm/v5/runtime/interop" "github.com/prysmaticlabs/prysm/v5/testing/assert" "github.com/prysmaticlabs/prysm/v5/testing/require" logTest "github.com/sirupsen/logrus/hooks/test" @@ -117,55 +111,6 @@ func TestNodeStart_SyncChecker(t *testing.T) { require.LogsContain(t, hook, "Starting beacon node") } -func TestNodeStart_Ok_registerDeterministicGenesisService(t *testing.T) { - numValidators := uint64(1) - hook := logTest.NewGlobal() - app := cli.App{} - tmp := fmt.Sprintf("%s/datadirtest2", t.TempDir()) - set := flag.NewFlagSet("test", 0) - set.String("datadir", tmp, "node data directory") - set.Uint64(flags.InteropNumValidatorsFlag.Name, numValidators, "") - set.String("suggested-fee-recipient", "0x6e35733c5af9B61374A128e6F85f553aF09ff89A", "fee recipient") - require.NoError(t, set.Set("suggested-fee-recipient", "0x6e35733c5af9B61374A128e6F85f553aF09ff89A")) - genesisState, _, err := interop.GenerateGenesisState(context.Background(), 0, numValidators) - require.NoError(t, err, "Could not generate genesis beacon state") - for i := uint64(1); i < 2; i++ { - var someRoot [32]byte - var someKey [fieldparams.BLSPubkeyLength]byte - copy(someRoot[:], strconv.Itoa(int(i))) - copy(someKey[:], strconv.Itoa(int(i))) - genesisState.Validators = append(genesisState.Validators, ðpb.Validator{ - PublicKey: someKey[:], - WithdrawalCredentials: someRoot[:], - EffectiveBalance: params.BeaconConfig().MaxEffectiveBalance, - Slashed: false, - ActivationEligibilityEpoch: 1, - ActivationEpoch: 1, - ExitEpoch: 1, - WithdrawableEpoch: 1, - }) - genesisState.Balances = append(genesisState.Balances, params.BeaconConfig().MaxEffectiveBalance) - } - genesisBytes, err := genesisState.MarshalSSZ() - require.NoError(t, err) - require.NoError(t, os.WriteFile("genesis_ssz.json", genesisBytes, 0666)) - set.String("genesis-state", "genesis_ssz.json", "") - ctx, cancel := newCliContextWithCancel(&app, set) - node, err := New(ctx, cancel, WithBlockchainFlagOptions([]blockchain.Option{}), - WithBuilderFlagOptions([]builder.Option{}), - WithExecutionChainOptions([]execution.Option{}), - WithBlobStorage(filesystem.NewEphemeralBlobStorage(t))) - require.NoError(t, err) - node.services = &runtime.ServiceRegistry{} - go func() { - node.Start() - }() - time.Sleep(3 * time.Second) - node.Close() - require.LogsContain(t, hook, "Starting beacon node") - require.NoError(t, os.Remove("genesis_ssz.json")) -} - // TestClearDB tests clearing the database func TestClearDB(t *testing.T) { hook := logTest.NewGlobal() diff --git a/cmd/beacon-chain/flags/interop.go b/cmd/beacon-chain/flags/interop.go index 6aac9e666480..2552d9d0960e 100644 --- a/cmd/beacon-chain/flags/interop.go +++ b/cmd/beacon-chain/flags/interop.go @@ -10,16 +10,4 @@ var ( Name: "interop-eth1data-votes", Usage: "Enable mocking of eth1 data votes for proposers to package into blocks", } - - // InteropGenesisTimeFlag specifies genesis time for state generation. - InteropGenesisTimeFlag = &cli.Uint64Flag{ - Name: "interop-genesis-time", - Usage: "Specify the genesis time for interop genesis state generation. Must be used with " + - "--interop-num-validators", - } - // InteropNumValidatorsFlag specifies number of genesis validators for state generation. - InteropNumValidatorsFlag = &cli.Uint64Flag{ - Name: "interop-num-validators", - Usage: "Specify number of genesis validators to generate for interop. Must be used with --interop-genesis-time", - } ) diff --git a/cmd/beacon-chain/main.go b/cmd/beacon-chain/main.go index 57eb8928ac41..3bbae9755171 100644 --- a/cmd/beacon-chain/main.go +++ b/cmd/beacon-chain/main.go @@ -60,8 +60,6 @@ var appFlags = []cli.Flag{ flags.BlobBatchLimit, flags.BlobBatchLimitBurstFactor, flags.InteropMockEth1DataVotesFlag, - flags.InteropNumValidatorsFlag, - flags.InteropGenesisTimeFlag, flags.SlotsPerArchivedPoint, flags.DisableDebugRPCEndpoints, flags.SubscribeToAllSubnets, diff --git a/cmd/beacon-chain/usage.go b/cmd/beacon-chain/usage.go index 5ac63e8f4baf..4ea3fe95dd97 100644 --- a/cmd/beacon-chain/usage.go +++ b/cmd/beacon-chain/usage.go @@ -184,14 +184,6 @@ var appHelpFlagGroups = []flagGroup{ Name: "features", Flags: features.ActiveFlags(features.BeaconChainFlags), }, - { - Name: "interop", - Flags: []cli.Flag{ - genesis.StatePath, - flags.InteropGenesisTimeFlag, - flags.InteropNumValidatorsFlag, - }, - }, { Name: "deprecated", Flags: []cli.Flag{ diff --git a/config/features/deprecated_flags.go b/config/features/deprecated_flags.go index d5754bcff61c..99030ad1bdc0 100644 --- a/config/features/deprecated_flags.go +++ b/config/features/deprecated_flags.go @@ -77,6 +77,16 @@ var ( Usage: deprecatedUsage, Hidden: true, } + deprecatedInteropGenesisTimeFlag = &cli.Uint64Flag{ + Name: "interop-genesis-time", + Usage: deprecatedUsage, + Hidden: true, + } + deprecatedInteropNumValidatorsFlag = &cli.Uint64Flag{ + Name: "interop-num-validators", + Usage: deprecatedUsage, + Hidden: true, + } ) // Deprecated flags for both the beacon node and validator client. @@ -94,6 +104,8 @@ var deprecatedFlags = []cli.Flag{ deprecatedBeaconRPCGatewayProviderFlag, deprecatedDisableGRPCGateway, deprecatedEnableExperimentalState, + deprecatedInteropGenesisTimeFlag, + deprecatedInteropNumValidatorsFlag, } // deprecatedBeaconFlags contains flags that are still used by other components From dbe72d065e091a48ecc3b3ff67bb69c7d9ea695d Mon Sep 17 00:00:00 2001 From: Preston Van Loon Date: Wed, 4 Sep 2024 15:00:21 -0500 Subject: [PATCH 02/12] Update INTEROP.md --- INTEROP.md | 38 ++++++-------------------------------- 1 file changed, 6 insertions(+), 32 deletions(-) diff --git a/INTEROP.md b/INTEROP.md index 59cc5ef1c25f..c5a10e779238 100644 --- a/INTEROP.md +++ b/INTEROP.md @@ -10,10 +10,8 @@ This README details how to setup Prysm for interop testing for usage with other ## Starting from Genesis -Prysm supports a few ways to quickly launch a beacon node from basic configurations: - -- `NumValidators + GenesisTime`: Launches a beacon node by deterministically generating a state from a num-validators flag along with a genesis time **(Recommended)** -- `SSZ Genesis`: Launches a beacon node from a .ssz file containing a SSZ-encoded, genesis beacon state +Prysm can be started from a built-in mainnet genesis state, or started with a provided genesis state by +using the `--genesis-state` flag and providing a path to the genesis.ssz file. ## Generating a Genesis State @@ -21,7 +19,7 @@ To setup the necessary files for these quick starts, Prysm provides a tool to ge a deterministically generated set of validator private keys following the official interop YAML format [here](https://github.com/ethereum/eth2.0-pm/blob/master/interop/mocked_start). -You can use `bazel run //tools/genesis-state-gen` to create a deterministic genesis state for interop. +You can use `bazel run //cmd/prysmctl -- testnet generate-genesis` to create a deterministic genesis state for interop. ### Usage @@ -31,10 +29,10 @@ You can use `bazel run //tools/genesis-state-gen` to create a deterministic gene - **--config-name=interop** string: name of the beacon chain config to use when generating the state. ex mainnet|minimal|interop The example below creates 64 validator keys, instantiates a genesis state with those 64 validators and with genesis unix timestamp 1567542540, -and finally writes a ssz encoded output to ~/Desktop/genesis.ssz. This file can be used to kickstart the beacon chain in the next section. When using the `--interop-*` flags, the beacon node will assume the `interop` config should be used, unless a different config is specified on the command line. +and finally writes a ssz encoded output to ~/Desktop/genesis.ssz. ``` -bazel run //tools/genesis-state-gen -- --config-name interop --output-ssz ~/Desktop/genesis.ssz --num-validators 64 --genesis-time 1567542540 +bazel run //cmd/prysmctl -- testnet generate-genesis --config-name interop --output-ssz ~/Desktop/genesis.ssz --num-validators 64 --genesis-time 1567542540 ``` ## Launching a Beacon Node + Validator Client @@ -50,8 +48,7 @@ bazel run //beacon-chain -- \ --datadir=/tmp/beacon-chain-interop \ --force-clear-db \ --min-sync-peers=0 \ ---interop-num-validators 64 \ ---interop-eth1data-votes +--genesis-ssz=~/Desktop/genesis.ssz ``` This will deterministically generate a beacon genesis state and start @@ -63,26 +60,3 @@ bazel run //validator -- --keymanager=interop --keymanageropts='{"keys":64}' ``` This will launch and kickstart the system with your 64 validators performing their duties accordingly. - -### Launching from `genesis.ssz` - -Assuming you generated a `genesis.ssz` file with 64 validators, open up two terminal windows, run: - -``` - bazel run //beacon-chain -- \ ---bootstrap-node= \ ---deposit-contract 0x8A04d14125D0FDCDc742F4A05C051De07232EDa4 \ ---datadir=/tmp/beacon-chain-interop \ ---force-clear-db \ ---min-sync-peers=0 \ ---interop-genesis-state /path/to/genesis.ssz \ ---interop-eth1data-votes -``` - -Wait a bit until your beacon chain starts, and in the other window: - -``` -bazel run //validator -- --keymanager=interop --keymanageropts='{"keys":64}' -``` - -This will launch and kickstart the system with your 64 validators performing their duties accordingly. From 3de7fce3c938a550682a420d7b1c7e12cf0f915b Mon Sep 17 00:00:00 2001 From: Preston Van Loon Date: Wed, 4 Sep 2024 16:08:40 -0500 Subject: [PATCH 03/12] Remove interop config --- INTEROP.md | 7 ++++--- cmd/prysmctl/testnet/generate_genesis.go | 13 +------------ 2 files changed, 5 insertions(+), 15 deletions(-) diff --git a/INTEROP.md b/INTEROP.md index c5a10e779238..f76944073c25 100644 --- a/INTEROP.md +++ b/INTEROP.md @@ -26,13 +26,13 @@ You can use `bazel run //cmd/prysmctl -- testnet generate-genesis` to create a d - **--genesis-time** uint: Unix timestamp used as the genesis time in the generated genesis state (defaults to now) - **--num-validators** int: Number of validators to deterministically include in the generated genesis state - **--output-ssz** string: Output filename of the SSZ marshaling of the generated genesis state -- **--config-name=interop** string: name of the beacon chain config to use when generating the state. ex mainnet|minimal|interop +- **--chain-config-file** string: Filepath to a chain config yaml file. The example below creates 64 validator keys, instantiates a genesis state with those 64 validators and with genesis unix timestamp 1567542540, and finally writes a ssz encoded output to ~/Desktop/genesis.ssz. ``` -bazel run //cmd/prysmctl -- testnet generate-genesis --config-name interop --output-ssz ~/Desktop/genesis.ssz --num-validators 64 --genesis-time 1567542540 +bazel run //cmd/prysmctl -- testnet generate-genesis --chain-config-file ~/Desktop/interop.yaml --output-ssz ~/Desktop/genesis.ssz --num-validators 64 --genesis-time 1567542540 ``` ## Launching a Beacon Node + Validator Client @@ -48,7 +48,8 @@ bazel run //beacon-chain -- \ --datadir=/tmp/beacon-chain-interop \ --force-clear-db \ --min-sync-peers=0 \ ---genesis-ssz=~/Desktop/genesis.ssz +--genesis-ssz=~/Desktop/genesis.ssz \ +--chain-config-file=~/Desktop/interop.yaml ``` This will deterministically generate a beacon genesis state and start diff --git a/cmd/prysmctl/testnet/generate_genesis.go b/cmd/prysmctl/testnet/generate_genesis.go index 00357e075e6e..4c79bf3d588f 100644 --- a/cmd/prysmctl/testnet/generate_genesis.go +++ b/cmd/prysmctl/testnet/generate_genesis.go @@ -31,7 +31,6 @@ var ( generateGenesisStateFlags = struct { DepositJsonFile string ChainConfigFile string - ConfigName string NumValidators uint64 GenesisTime uint64 GenesisTimeDelay uint64 @@ -83,12 +82,6 @@ var ( Destination: &generateGenesisStateFlags.DepositJsonFile, Usage: "Path to deposit_data.json file generated by the staking-deposit-cli tool for optionally specifying validators in genesis state", }, - &cli.StringFlag{ - Name: "config-name", - Usage: "Config kind to be used for generating the genesis state. Default: mainnet. Options include mainnet, interop, minimal, sepolia, holesky. --chain-config-file will override this flag.", - Destination: &generateGenesisStateFlags.ConfigName, - Value: params.MainnetName, - }, &cli.Uint64Flag{ Name: "num-validators", Usage: "Number of validators to deterministically generate in the genesis state", @@ -216,11 +209,7 @@ func setGlobalParams() error { log.Infof("Specified a chain config file: %s", chainConfigFile) return params.LoadChainConfigFile(chainConfigFile, nil) } - cfg, err := params.ByName(generateGenesisStateFlags.ConfigName) - if err != nil { - return fmt.Errorf("unable to find config using name %s: %w", generateGenesisStateFlags.ConfigName, err) - } - return params.SetActive(cfg.Copy()) + return errors.New("No chain config file was provided. Use `--chain-config-file` to provide a chain config.") } func generateGenesis(ctx context.Context) (state.BeaconState, error) { From 5a2a5a9ee9aec99c84b36431b6d973da4c2deab2 Mon Sep 17 00:00:00 2001 From: Preston Van Loon Date: Wed, 4 Sep 2024 15:30:08 -0500 Subject: [PATCH 04/12] Remove ancient interop script --- hack/interop_start.sh | 104 ------------------------------------------ 1 file changed, 104 deletions(-) delete mode 100755 hack/interop_start.sh diff --git a/hack/interop_start.sh b/hack/interop_start.sh deleted file mode 100755 index dd2d4a08c985..000000000000 --- a/hack/interop_start.sh +++ /dev/null @@ -1,104 +0,0 @@ -#!/bin/bash - -""" -2019/09/08 -- Interop start script. -This script is intended for dockerfile deployment for interop testing. -This script is fragile and subject to break as flags change. -Use at your own risk! - - -Use with interop.Dockerfile from the workspace root: - -docker build -f interop.Dockerfile . -""" - -# Flags -IDENTITY="" # P2P private key -PEERS="" # Comma separated list of peers -GEN_STATE="" # filepath to ssz encoded state. -PORT="8000" # port to serve p2p traffic -RPCPORT="8001" # port to serve rpc traffic -YAML_KEY_FILE="" # Path to yaml keyfile as defined here: https://github.com/ethereum/eth2.0-pm/tree/master/interop/mocked_start - -# Constants -BEACON_LOG_FILE="/tmp/beacon.log" -VALIDATOR_LOG_FILE="/tmp/validator.log" - -usage() { - echo "--identity=" - echo "--peer=" - echo "--num-validators=" - echo "--gen-state=" - echo "--port=" - echo "--rpcport=" -} - -while [ "$1" != "" ]; -do - PARAM=`echo $1 | awk -F= '{print $1}'` - VALUE=`echo $1 | sed 's/^[^=]*=//g'` - - case $PARAM in - --identity) - IDENTITY=$VALUE - ;; - --peers) - [ -z "$PEERS" ] && PEERS+="," - PEERS+="$VALUE" - ;; - --validator-keys) - YAML_KEY_FILE=$VALUE - ;; - --gen-state) - GEN_STATE=$VALUE - ;; - --port) - PORT=$VALUE - ;; - --rpcport) - RPCPORT=$VALUE - ;; - --help) - usage - exit - ;; - *) - echo "ERROR: unknown parameter \"$PARAM\"" - usage - exit 1 - ;; - esac - shift -done - - -echo "Converting hex yaml keys to a format that Prysm understands" - -# Expect YAML keys in hex encoded format. Convert this into the format the validator already understands. -./convert-keys $YAML_KEY_FILE /tmp/keys.json - -echo "Starting beacon chain and logging to $BEACON_LOG_FILE" - -echo -n "$IDENTITY" > /tmp/id.key - - - -BEACON_FLAGS="--bootstrap-node= \ - --deposit-contract=0xD775140349E6A5D12524C6ccc3d6A1d4519D4029 \ - --p2p-port=$PORT \ - --http-port=$RPCPORT \ - --peer=$PEERS \ - --interop-genesis-state=$GEN_STATE \ - --p2p-priv-key=/tmp/id.key \ - --log-file=$BEACON_LOG_FILE" - -./beacon-chain $BEACON_FLAGS & - -echo "Starting validator client and logging to $VALIDATOR_LOG_FILE" - -VALIDATOR_FLAGS="--monitoring-port=9091 \ - --unencrypted-keys /tmp/keys.json \ - --log-file=$VALIDATOR_LOG_FILE - -./validator- $VALIDATOR_FLAGS & - From b74f2b77f998f0141f1f9fbe0758c6fe72ca6fbf Mon Sep 17 00:00:00 2001 From: Preston Van Loon Date: Wed, 4 Sep 2024 16:17:59 -0500 Subject: [PATCH 05/12] Add electra support for premine genesis --- runtime/interop/premine-state.go | 76 ++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) diff --git a/runtime/interop/premine-state.go b/runtime/interop/premine-state.go index 235f8a1968e3..1c3ad64e1524 100644 --- a/runtime/interop/premine-state.go +++ b/runtime/interop/premine-state.go @@ -155,6 +155,11 @@ func (s *PremineGenesisConfig) empty() (state.BeaconState, error) { if err != nil { return nil, err } + case version.Electra: + e, err = state_native.InitializeFromProtoElectra(ðpb.BeaconStateElectra{}) + if err != nil { + return nil, err + } default: return nil, errUnsupportedVersion } @@ -336,6 +341,8 @@ func (s *PremineGenesisConfig) setFork(g state.BeaconState) error { 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 default: return errUnsupportedVersion } @@ -524,6 +531,38 @@ func (s *PremineGenesisConfig) setLatestBlockHeader(g state.BeaconState) error { 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.ExecutionPayloadElectra{ + 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), + DepositRequests: make([]*enginev1.DepositRequest, 0), +WithdrawalRequests: make([]*enginev1.WithdrawalRequest, 0), + ConsolidationRequests: make([]*enginev1.ConsolidationRequest, 0), + }, + BlsToExecutionChanges: make([]*ethpb.SignedBLSToExecutionChange, 0), + BlobKzgCommitments: make([][]byte, 0), + } + default: return errUnsupportedVersion } @@ -640,6 +679,43 @@ func (s *PremineGenesisConfig) setExecutionPayload(g state.BeaconState) error { if err != nil { return err } + case version.Electra: + payload := &enginev1.ExecutionPayloadElectra{ + 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: gb.Extra()[:32], + BaseFeePerGas: bytesutil.PadTo(bytesutil.ReverseByteOrder(gb.BaseFee().Bytes()), fieldparams.RootLength), + BlockHash: gb.Hash().Bytes(), + Transactions: make([][]byte, 0), + Withdrawals: make([]*enginev1.Withdrawal, 0), + ExcessBlobGas: *gb.ExcessBlobGas(), + BlobGasUsed: *gb.BlobGasUsed(), + } + wep, err := blocks.WrappedExecutionPayloadElectra(payload) + if err != nil { + return err + } + wep1, ok := wep.(interfaces.ExecutionDataElectra) + if !ok { + return errors.New("payload is not an ExecutionDataElectra") + } + eph, err := blocks.PayloadToHeaderElectra(wep1) + if err != nil { + return err + } + ed, err = blocks.WrappedExecutionPayloadHeaderElectra(eph) + if err != nil { + return err + } + default: return errUnsupportedVersion } From 10cee291a9dd188ed5cab10117333761bf8ed631 Mon Sep 17 00:00:00 2001 From: Preston Van Loon Date: Wed, 4 Sep 2024 16:17:59 -0500 Subject: [PATCH 06/12] Add example of --chain-config-file, test interop instructions --- INTEROP.md | 48 ++++++++++++++++++++++++++++++++---------------- 1 file changed, 32 insertions(+), 16 deletions(-) diff --git a/INTEROP.md b/INTEROP.md index f76944073c25..28a822a188c3 100644 --- a/INTEROP.md +++ b/INTEROP.md @@ -6,7 +6,7 @@ This README details how to setup Prysm for interop testing for usage with other 1. Install [Bazel](https://docs.bazel.build/versions/master/install.html) **(Recommended)** 2. `git clone https://github.com/prysmaticlabs/prysm && cd prysm` -3. `bazel build //...` +3. `bazel build //cmd/...` ## Starting from Genesis @@ -23,16 +23,23 @@ You can use `bazel run //cmd/prysmctl -- testnet generate-genesis` to create a d ### Usage -- **--genesis-time** uint: Unix timestamp used as the genesis time in the generated genesis state (defaults to now) +- **--genesis-time-delay** uint: The number of seconds in the future to define genesis. Example: a value of 60 will set the genesis time to 1 minute in the future. This should be sufficiently large enough to allow for you to start the beacon node before the genesis time. - **--num-validators** int: Number of validators to deterministically include in the generated genesis state - **--output-ssz** string: Output filename of the SSZ marshaling of the generated genesis state - **--chain-config-file** string: Filepath to a chain config yaml file. The example below creates 64 validator keys, instantiates a genesis state with those 64 validators and with genesis unix timestamp 1567542540, -and finally writes a ssz encoded output to ~/Desktop/genesis.ssz. +and finally writes a ssz encoded output to ~/Desktop/genesis.ssz. A chain config file could be any valid config yaml such as the [minimal.yaml](https://github.com/ethereum/consensus-specs/blob/dev/configs/minimal.yaml) file. + +Note: Use the bazel flag `--config=minimal` to run Prysm software with minimal state build constraints. This is required to run Prysm in the "minimal" configuration. ``` -bazel run //cmd/prysmctl -- testnet generate-genesis --chain-config-file ~/Desktop/interop.yaml --output-ssz ~/Desktop/genesis.ssz --num-validators 64 --genesis-time 1567542540 +bazel run //cmd/prysmctl --config=minimal -- \ + testnet generate-genesis \ + --chain-config-file=~/Downloads/minimal.yaml \ + --output-ssz=~/Desktop/genesis.ssz \ + --num-validators=64 \ + --genesis-time-delay=60 ``` ## Launching a Beacon Node + Validator Client @@ -42,22 +49,31 @@ bazel run //cmd/prysmctl -- testnet generate-genesis --chain-config-file ~/Deskt Open up two terminal windows, run: ``` -bazel run //beacon-chain -- \ ---bootstrap-node= \ ---deposit-contract 0x8A04d14125D0FDCDc742F4A05C051De07232EDa4 \ ---datadir=/tmp/beacon-chain-interop \ ---force-clear-db \ ---min-sync-peers=0 \ ---genesis-ssz=~/Desktop/genesis.ssz \ ---chain-config-file=~/Desktop/interop.yaml +bazel run //beacon-chain --config=minimal -- \ + --bootstrap-node= \ + --deposit-contract 0x8A04d14125D0FDCDc742F4A05C051De07232EDa4 \ + --datadir=/tmp/beacon-chain-minimal-devnet \ + --force-clear-db \ + --min-sync-peers=0 \ + --genesis-ssz=~/Desktop/genesis.ssz \ + --chain-config-file=~/Downloads/minimal.yaml ``` -This will deterministically generate a beacon genesis state and start -the system with 64 validators and the genesis time set to the current unix timestamp. -Wait a bit until your beacon chain starts, and in the other window: +This will start the system with 64 validators. The flags used can be explained as such: + +- `bazel run //cmd/beacon-chain --config=minimal` builds and runs the beacon node in minimal build configuration. +- `--` is a flag divider to distingish between bazel flags and flags that should be passed to the application. All flags and arguments after this divider are passed to the beacon chain. +- `--bootstrap-node=` disables the default bootstrap nodes. This prevents the client from attempting to peer with mainnet nodes. +- `--datadir=/tmp/beacon-chain-minimal-devnet` sets the data directory in a temporary location. Change this to your preferred destination. +- `--force-clear-db` will delete the beaconchain.db file without confirming with the user. This is helpful for iteratively running local devnets without changing the datadir, but less helpful for one off runs where there was no database in the data directory. +- `--min-sync-peers=0` allows the beacon node to skip initial sync without peers. This is essential because Prysm expects at least a few peers to start start the blockchain. +- `--genesis-ssz=~/Desktop/genesis.ssz` defines the path to the generated genesis ssz file. The beacon node will use this as the initial genesis state. +- `--chain-config-file=~/Downloads/minimal.yaml` defines the path to the yaml file with the chain configuration. + +As soon as the beacon node has started, start the validator in the other terminal window. ``` -bazel run //validator -- --keymanager=interop --keymanageropts='{"keys":64}' +bazel run //validator --config=minimal -- --keymanager=interop --keymanageropts='{"keys":64}' ``` This will launch and kickstart the system with your 64 validators performing their duties accordingly. From e9e380bbc01473dd0c4c6d9bc4b7edf67b664cbd Mon Sep 17 00:00:00 2001 From: Preston Van Loon Date: Sat, 7 Sep 2024 11:06:47 -0500 Subject: [PATCH 07/12] Fixes --- INTEROP.md | 63 +++++++++++++++++------------ beacon-chain/node/node_test.go | 1 - cmd/prysmctl/BUILD.bazel | 1 - config/features/deprecated_flags.go | 5 ++- runtime/interop/premine-state.go | 49 +++++++++++----------- 5 files changed, 66 insertions(+), 53 deletions(-) diff --git a/INTEROP.md b/INTEROP.md index 28a822a188c3..3c222a9b9c97 100644 --- a/INTEROP.md +++ b/INTEROP.md @@ -2,6 +2,11 @@ This README details how to setup Prysm for interop testing for usage with other Ethereum consensus clients. +> [!IMPORTANT] +> This guide is likely to be outdated. The Prysm team does not have capacity to troubleshoot +> outdated interop guides or instructions. If you experience issues with this guide, please file and +> issue for visibility and propose fixes, if possible. + ## Installation & Setup 1. Install [Bazel](https://docs.bazel.build/versions/master/install.html) **(Recommended)** @@ -19,29 +24,35 @@ To setup the necessary files for these quick starts, Prysm provides a tool to ge a deterministically generated set of validator private keys following the official interop YAML format [here](https://github.com/ethereum/eth2.0-pm/blob/master/interop/mocked_start). -You can use `bazel run //cmd/prysmctl -- testnet generate-genesis` to create a deterministic genesis state for interop. - -### Usage - -- **--genesis-time-delay** uint: The number of seconds in the future to define genesis. Example: a value of 60 will set the genesis time to 1 minute in the future. This should be sufficiently large enough to allow for you to start the beacon node before the genesis time. -- **--num-validators** int: Number of validators to deterministically include in the generated genesis state -- **--output-ssz** string: Output filename of the SSZ marshaling of the generated genesis state -- **--chain-config-file** string: Filepath to a chain config yaml file. - -The example below creates 64 validator keys, instantiates a genesis state with those 64 validators and with genesis unix timestamp 1567542540, -and finally writes a ssz encoded output to ~/Desktop/genesis.ssz. A chain config file could be any valid config yaml such as the [minimal.yaml](https://github.com/ethereum/consensus-specs/blob/dev/configs/minimal.yaml) file. +You can use `prysmctl` to create a deterministic genesis state for interop. -Note: Use the bazel flag `--config=minimal` to run Prysm software with minimal state build constraints. This is required to run Prysm in the "minimal" configuration. +```sh +# Download (or create) a chain config file. +curl https://raw.githubusercontent.com/ethereum/consensus-specs/refs/heads/dev/configs/minimal.yaml -o /tmp/minimal.yaml -``` +# Run prysmctl to generate genesis with a 2 minute genesis delay and 256 validators. bazel run //cmd/prysmctl --config=minimal -- \ testnet generate-genesis \ - --chain-config-file=~/Downloads/minimal.yaml \ - --output-ssz=~/Desktop/genesis.ssz \ - --num-validators=64 \ - --genesis-time-delay=60 + --genesis-time-delay=120 \ + --num-validators=256 \ + --output-ssz=/tmp/genesis.ssz \ + --chain-config-file=/tmp/minimal.yaml ``` +The flags are explained below: +- `bazel run //cmd/prysmctl` is the bazel command to compile and run prysmctl. +- `--config=minimal` is a bazel build time configuration flag to compile Prysm with minimal state constants. +- `--` is an argument divider to tell bazel that everything after this divider should be passed as arguments to prysmctl. Without this divider, it isn't clear to bazel if the arguments are meant to be build time arguments or runtime arguments so the operation complains and fails to build without this divider. +- `testnet` is the primary command argument for prysmctl. +- `generate-genesis` is the subcommand to `testnet` in prysmctl. +- `--genesis-time-delay` uint: The number of seconds in the future to define genesis. Example: a value of 60 will set the genesis time to 1 minute in the future. This should be sufficiently large enough to allow for you to start the beacon node before the genesis time. +- `--num-validators` int: Number of validators to deterministically include in the generated genesis state +- `--output-ssz` string: Output filename of the SSZ marshaling of the generated genesis state +- `--chain-config-file` string: Filepath to a chain config yaml file. + +Note: This guide saves items to the `/tmp/` directory which will not persist if your machine is +restarted. Consider tweaking the arguments if persistence is needed. + ## Launching a Beacon Node + Validator Client ### Launching from Pure CLI Flags @@ -49,31 +60,33 @@ bazel run //cmd/prysmctl --config=minimal -- \ Open up two terminal windows, run: ``` -bazel run //beacon-chain --config=minimal -- \ +bazel run //cmd/beacon-chain --config=minimal -- \ + --minimal-config \ --bootstrap-node= \ --deposit-contract 0x8A04d14125D0FDCDc742F4A05C051De07232EDa4 \ --datadir=/tmp/beacon-chain-minimal-devnet \ --force-clear-db \ --min-sync-peers=0 \ - --genesis-ssz=~/Desktop/genesis.ssz \ - --chain-config-file=~/Downloads/minimal.yaml + --genesis-state=/tmp/genesis.ssz \ + --chain-config-file=/tmp/minimal.yaml ``` -This will start the system with 64 validators. The flags used can be explained as such: +This will start the system with 256 validators. The flags used can be explained as such: - `bazel run //cmd/beacon-chain --config=minimal` builds and runs the beacon node in minimal build configuration. - `--` is a flag divider to distingish between bazel flags and flags that should be passed to the application. All flags and arguments after this divider are passed to the beacon chain. +- `--minimal-config` tells the beacon node to use minimal network configuration. This is different from the compile time state configuration flag `--config=minimal` and both are required. - `--bootstrap-node=` disables the default bootstrap nodes. This prevents the client from attempting to peer with mainnet nodes. - `--datadir=/tmp/beacon-chain-minimal-devnet` sets the data directory in a temporary location. Change this to your preferred destination. - `--force-clear-db` will delete the beaconchain.db file without confirming with the user. This is helpful for iteratively running local devnets without changing the datadir, but less helpful for one off runs where there was no database in the data directory. - `--min-sync-peers=0` allows the beacon node to skip initial sync without peers. This is essential because Prysm expects at least a few peers to start start the blockchain. -- `--genesis-ssz=~/Desktop/genesis.ssz` defines the path to the generated genesis ssz file. The beacon node will use this as the initial genesis state. -- `--chain-config-file=~/Downloads/minimal.yaml` defines the path to the yaml file with the chain configuration. +- `--genesis-state=/tmp/genesis.ssz` defines the path to the generated genesis ssz file. The beacon node will use this as the initial genesis state. +- `--chain-config-file=/tmp/minimal.yaml` defines the path to the yaml file with the chain configuration. As soon as the beacon node has started, start the validator in the other terminal window. ``` -bazel run //validator --config=minimal -- --keymanager=interop --keymanageropts='{"keys":64}' +bazel run //cmd/validator --config=minimal -- --datadir=/tmp/validator --interopt-num-validators=256 --minimal-config --suggested-fee-recipient=0x8A04d14125D0FDCDc742F4A05C051De07232EDa4 ``` -This will launch and kickstart the system with your 64 validators performing their duties accordingly. +This will launch and kickstart the system with your 256 validators performing their duties accordingly. diff --git a/beacon-chain/node/node_test.go b/beacon-chain/node/node_test.go index 09e06dd53ff4..d988be8f862b 100644 --- a/beacon-chain/node/node_test.go +++ b/beacon-chain/node/node_test.go @@ -19,7 +19,6 @@ import ( mockExecution "github.com/prysmaticlabs/prysm/v5/beacon-chain/execution/testing" "github.com/prysmaticlabs/prysm/v5/beacon-chain/monitor" "github.com/prysmaticlabs/prysm/v5/cmd" - "github.com/prysmaticlabs/prysm/v5/cmd/beacon-chain/flags" "github.com/prysmaticlabs/prysm/v5/config/features" "github.com/prysmaticlabs/prysm/v5/runtime" "github.com/prysmaticlabs/prysm/v5/testing/assert" diff --git a/cmd/prysmctl/BUILD.bazel b/cmd/prysmctl/BUILD.bazel index fdcb9f00809d..44e339e856e2 100644 --- a/cmd/prysmctl/BUILD.bazel +++ b/cmd/prysmctl/BUILD.bazel @@ -22,7 +22,6 @@ go_library( go_binary( name = "prysmctl", embed = [":go_default_library"], - gotags = ["noMainnetGenesis"], visibility = ["//visibility:public"], ) diff --git a/config/features/deprecated_flags.go b/config/features/deprecated_flags.go index 99030ad1bdc0..78f06befd247 100644 --- a/config/features/deprecated_flags.go +++ b/config/features/deprecated_flags.go @@ -105,9 +105,10 @@ var deprecatedFlags = []cli.Flag{ deprecatedDisableGRPCGateway, deprecatedEnableExperimentalState, deprecatedInteropGenesisTimeFlag, - deprecatedInteropNumValidatorsFlag, } // deprecatedBeaconFlags contains flags that are still used by other components // and therefore cannot be added to deprecatedFlags -var deprecatedBeaconFlags []cli.Flag +var deprecatedBeaconFlags = []cli.Flag{ + deprecatedInteropNumValidatorsFlag, +} diff --git a/runtime/interop/premine-state.go b/runtime/interop/premine-state.go index 1c3ad64e1524..75cf4d9135ec 100644 --- a/runtime/interop/premine-state.go +++ b/runtime/interop/premine-state.go @@ -342,7 +342,7 @@ func (s *PremineGenesisConfig) setFork(g state.BeaconState) error { case version.Deneb: pv, cv = params.BeaconConfig().CapellaForkVersion, params.BeaconConfig().DenebForkVersion case version.Electra: - pv, cv = params.BeaconConfig().DenebForkVersion, params.BeaconConfig().ElectraForkVersion + pv, cv = params.BeaconConfig().DenebForkVersion, params.BeaconConfig().ElectraForkVersion default: return errUnsupportedVersion } @@ -544,23 +544,21 @@ func (s *PremineGenesisConfig) setLatestBlockHeader(g state.BeaconState) error { SyncCommitteeSignature: make([]byte, fieldparams.BLSSignatureLength), }, ExecutionPayload: &enginev1.ExecutionPayloadElectra{ - 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), - DepositRequests: make([]*enginev1.DepositRequest, 0), -WithdrawalRequests: make([]*enginev1.WithdrawalRequest, 0), - ConsolidationRequests: make([]*enginev1.ConsolidationRequest, 0), + 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{}, } default: @@ -664,8 +662,8 @@ func (s *PremineGenesisConfig) setExecutionPayload(g state.BeaconState) error { BlockHash: gb.Hash().Bytes(), Transactions: make([][]byte, 0), Withdrawals: make([]*enginev1.Withdrawal, 0), - ExcessBlobGas: *gb.ExcessBlobGas(), - BlobGasUsed: *gb.BlobGasUsed(), + ExcessBlobGas: unwrapUint64Ptr(gb.ExcessBlobGas()), + BlobGasUsed: unwrapUint64Ptr(gb.BlobGasUsed()), } wep, err := blocks.WrappedExecutionPayloadDeneb(payload) if err != nil { @@ -696,18 +694,14 @@ func (s *PremineGenesisConfig) setExecutionPayload(g state.BeaconState) error { BlockHash: gb.Hash().Bytes(), Transactions: make([][]byte, 0), Withdrawals: make([]*enginev1.Withdrawal, 0), - ExcessBlobGas: *gb.ExcessBlobGas(), - BlobGasUsed: *gb.BlobGasUsed(), + ExcessBlobGas: unwrapUint64Ptr(gb.ExcessBlobGas()), + BlobGasUsed: unwrapUint64Ptr(gb.BlobGasUsed()), } wep, err := blocks.WrappedExecutionPayloadElectra(payload) if err != nil { return err } - wep1, ok := wep.(interfaces.ExecutionDataElectra) - if !ok { - return errors.New("payload is not an ExecutionDataElectra") - } - eph, err := blocks.PayloadToHeaderElectra(wep1) + eph, err := blocks.PayloadToHeaderElectra(wep) if err != nil { return err } @@ -722,6 +716,13 @@ func (s *PremineGenesisConfig) setExecutionPayload(g state.BeaconState) error { return g.SetLatestExecutionPayloadHeader(ed) } +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[:] From f9a98232a44f69be37d3859e7dc747e197e7c4e9 Mon Sep 17 00:00:00 2001 From: Preston Van Loon Date: Thu, 5 Sep 2024 15:24:15 -0500 Subject: [PATCH 08/12] Add binary size reduction --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9b9f6bc6e3cf..d26f8c42ab63 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -53,7 +53,7 @@ The format is based on Keep a Changelog, and this project adheres to Semantic Ve - removed gRPC Gateway - Removed unused blobs bundle cache - Removed consolidation signing domain from params. The Electra design changed such that EL handles consolidation signature verification. -- Removed support for starting a beacon node with a determinisitic interop genesis state via interop flags. Alteratively, create a genesis state with prysmctl and use `--genesis-state`. +- Removed support for starting a beacon node with a determinisitic interop genesis state via interop flags. Alteratively, create a genesis state with prysmctl and use `--genesis-state`. This removes about 8Mb of unnecessary code and dependencies from the final production binary. ### Fixed From 516cc42303aefd078e04d9347644ce356c8ca7ff Mon Sep 17 00:00:00 2001 From: Preston Van Loon Date: Thu, 17 Oct 2024 09:52:12 -0500 Subject: [PATCH 09/12] Update binary size reduction --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8a60b92efc37..83b2f3bcc90e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -114,7 +114,7 @@ Updating to this release is recommended at your convenience. - Removed unused blobs bundle cache. - Removed consolidation signing domain from params. The Electra design changed such that EL handles consolidation signature verification. - Remove engine_getPayloadBodiesBy{Hash|Range}V2 -- Removed support for starting a beacon node with a deterministic interop genesis state via interop flags. Alteratively, create a genesis state with prysmctl and use `--genesis-state`. This removes about 8Mb of unnecessary code and dependencies from the final production binary. +- Removed support for starting a beacon node with a deterministic interop genesis state via interop flags. Alteratively, create a genesis state with prysmctl and use `--genesis-state`. This removes about 9Mb (~11%) of unnecessary code and dependencies from the final production binary. ### Fixed From 4186f6384390a9c2f1bb666e76694b0283f6a5ff Mon Sep 17 00:00:00 2001 From: Preston Van Loon Date: Thu, 17 Oct 2024 09:57:24 -0500 Subject: [PATCH 10/12] Fix duplicate switch case --- runtime/interop/premine-state.go | 33 -------------------------------- 1 file changed, 33 deletions(-) diff --git a/runtime/interop/premine-state.go b/runtime/interop/premine-state.go index 81df74e5cb39..ce2381a7191d 100644 --- a/runtime/interop/premine-state.go +++ b/runtime/interop/premine-state.go @@ -712,39 +712,6 @@ func (s *PremineGenesisConfig) setExecutionPayload(g state.BeaconState) error { if err != nil { return err } - case version.Electra: - payload := &enginev1.ExecutionPayloadElectra{ - 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: gb.Extra()[:32], - 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.WrappedExecutionPayloadElectra(payload) - if err != nil { - return err - } - eph, err := blocks.PayloadToHeaderElectra(wep) - if err != nil { - return err - } - ed, err = blocks.WrappedExecutionPayloadHeaderElectra(eph) - if err != nil { - return err - } - default: return errUnsupportedVersion } From 0ceb69c279254d5e7e3466b5764d3692f34ab224 Mon Sep 17 00:00:00 2001 From: Preston Van Loon Date: Wed, 20 Nov 2024 07:29:21 -0600 Subject: [PATCH 11/12] Move CHANGELOG entries to unreleased section --- CHANGELOG.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f341eed87d1d..50234be06f8b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -60,12 +60,14 @@ The format is based on Keep a Changelog, and this project adheres to Semantic Ve ### Deprecated - `/eth/v1alpha1/validator/activation/stream` grpc wait for activation stream is deprecated. [pr](https://github.com/prysmaticlabs/prysm/pull/14514) +- `--interop-genesis-time` and `--interop-num-validators` have been deprecated in the beacon node as the functionality has been removed. These flags have no effect. ### Removed - Removed finalized validator index cache, no longer needed. - Removed validator queue position log on key reload and wait for activation. - Removed outdated spectest exclusions for EIP-6110. +- Removed support for starting a beacon node with a deterministic interop genesis state via interop flags. Alteratively, create a genesis state with prysmctl and use `--genesis-state`. This removes about 9Mb (~11%) of unnecessary code and dependencies from the final production binary. ### Fixed @@ -173,7 +175,6 @@ Updating to this release is recommended at your convenience. ### Deprecated - `--disable-grpc-gateway` flag is deprecated due to grpc gateway removal. - `--enable-experimental-state` flag is deprecated. This feature is now on by default. Opt-out with `--disable-experimental-state`. -- `--interop-genesis-time` and `--interop-num-validators` have been deprecated in the beacon node as the functionality has been removed. These flags have no effect. ### Removed @@ -181,8 +182,6 @@ Updating to this release is recommended at your convenience. - Removed unused blobs bundle cache. - Removed consolidation signing domain from params. The Electra design changed such that EL handles consolidation signature verification. - Remove engine_getPayloadBodiesBy{Hash|Range}V2 -- Removed support for starting a beacon node with a deterministic interop genesis state via interop flags. Alteratively, create a genesis state with prysmctl and use `--genesis-state`. This removes about 9Mb (~11%) of unnecessary code and dependencies from the final production binary. - ### Fixed From 63d4d39061191dc58917e528943aa02df90d5172 Mon Sep 17 00:00:00 2001 From: Preston Van Loon Date: Wed, 20 Nov 2024 07:36:57 -0600 Subject: [PATCH 12/12] gofmt --- config/features/deprecated_flags.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/features/deprecated_flags.go b/config/features/deprecated_flags.go index 5681d995087a..e0c555d502b7 100644 --- a/config/features/deprecated_flags.go +++ b/config/features/deprecated_flags.go @@ -110,7 +110,7 @@ var deprecatedFlags = []cli.Flag{ deprecatedBeaconRPCGatewayProviderFlag, deprecatedDisableGRPCGateway, deprecatedEnableExperimentalState, - deprecatedEnableCommitteeAwarePacking, + deprecatedEnableCommitteeAwarePacking, deprecatedInteropGenesisTimeFlag, }