github.com/prysmaticlabs/prysm@v1.4.4/beacon-chain/node/node.go (about)

     1  // Package node is the main service which launches a beacon node and manages
     2  // the lifecycle of all its associated services at runtime, such as p2p, RPC, sync,
     3  // gracefully closing them if the process ends.
     4  package node
     5  
     6  import (
     7  	"bytes"
     8  	"context"
     9  	"fmt"
    10  	"os"
    11  	"os/signal"
    12  	"path/filepath"
    13  	"strings"
    14  	"sync"
    15  	"syscall"
    16  
    17  	"github.com/ethereum/go-ethereum/common"
    18  	"github.com/pkg/errors"
    19  	"github.com/prysmaticlabs/prysm/beacon-chain/blockchain"
    20  	"github.com/prysmaticlabs/prysm/beacon-chain/cache/depositcache"
    21  	"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
    22  	"github.com/prysmaticlabs/prysm/beacon-chain/db"
    23  	"github.com/prysmaticlabs/prysm/beacon-chain/db/kv"
    24  	"github.com/prysmaticlabs/prysm/beacon-chain/forkchoice"
    25  	"github.com/prysmaticlabs/prysm/beacon-chain/forkchoice/protoarray"
    26  	gateway2 "github.com/prysmaticlabs/prysm/beacon-chain/gateway"
    27  	interopcoldstart "github.com/prysmaticlabs/prysm/beacon-chain/interop-cold-start"
    28  	"github.com/prysmaticlabs/prysm/beacon-chain/node/registration"
    29  	"github.com/prysmaticlabs/prysm/beacon-chain/operations/attestations"
    30  	"github.com/prysmaticlabs/prysm/beacon-chain/operations/slashings"
    31  	"github.com/prysmaticlabs/prysm/beacon-chain/operations/voluntaryexits"
    32  	"github.com/prysmaticlabs/prysm/beacon-chain/p2p"
    33  	"github.com/prysmaticlabs/prysm/beacon-chain/powchain"
    34  	"github.com/prysmaticlabs/prysm/beacon-chain/rpc"
    35  	"github.com/prysmaticlabs/prysm/beacon-chain/rpc/apimiddleware"
    36  	"github.com/prysmaticlabs/prysm/beacon-chain/state/stategen"
    37  	regularsync "github.com/prysmaticlabs/prysm/beacon-chain/sync"
    38  	initialsync "github.com/prysmaticlabs/prysm/beacon-chain/sync/initial-sync"
    39  	"github.com/prysmaticlabs/prysm/cmd/beacon-chain/flags"
    40  	"github.com/prysmaticlabs/prysm/shared"
    41  	"github.com/prysmaticlabs/prysm/shared/backuputil"
    42  	"github.com/prysmaticlabs/prysm/shared/cmd"
    43  	"github.com/prysmaticlabs/prysm/shared/debug"
    44  	"github.com/prysmaticlabs/prysm/shared/event"
    45  	"github.com/prysmaticlabs/prysm/shared/featureconfig"
    46  	"github.com/prysmaticlabs/prysm/shared/gateway"
    47  	"github.com/prysmaticlabs/prysm/shared/params"
    48  	"github.com/prysmaticlabs/prysm/shared/prereq"
    49  	"github.com/prysmaticlabs/prysm/shared/prometheus"
    50  	"github.com/prysmaticlabs/prysm/shared/sliceutil"
    51  	"github.com/prysmaticlabs/prysm/shared/version"
    52  	"github.com/sirupsen/logrus"
    53  	"github.com/urfave/cli/v2"
    54  )
    55  
    56  const testSkipPowFlag = "test-skip-pow"
    57  
    58  // BeaconNode defines a struct that handles the services running a random beacon chain
    59  // full PoS node. It handles the lifecycle of the entire system and registers
    60  // services to a service registry.
    61  type BeaconNode struct {
    62  	cliCtx          *cli.Context
    63  	ctx             context.Context
    64  	cancel          context.CancelFunc
    65  	services        *shared.ServiceRegistry
    66  	lock            sync.RWMutex
    67  	stop            chan struct{} // Channel to wait for termination notifications.
    68  	db              db.Database
    69  	attestationPool attestations.Pool
    70  	exitPool        voluntaryexits.PoolManager
    71  	slashingsPool   slashings.PoolManager
    72  	depositCache    *depositcache.DepositCache
    73  	stateFeed       *event.Feed
    74  	blockFeed       *event.Feed
    75  	opFeed          *event.Feed
    76  	forkChoiceStore forkchoice.ForkChoicer
    77  	stateGen        *stategen.State
    78  	collector       *bcnodeCollector
    79  }
    80  
    81  // New creates a new node instance, sets up configuration options, and registers
    82  // every required service to the node.
    83  func New(cliCtx *cli.Context) (*BeaconNode, error) {
    84  	if err := configureTracing(cliCtx); err != nil {
    85  		return nil, err
    86  	}
    87  	prereq.WarnIfPlatformNotSupported(cliCtx.Context)
    88  	featureconfig.ConfigureBeaconChain(cliCtx)
    89  	cmd.ConfigureBeaconChain(cliCtx)
    90  	flags.ConfigureGlobalFlags(cliCtx)
    91  	configureChainConfig(cliCtx)
    92  	configureHistoricalSlasher(cliCtx)
    93  	configureSlotsPerArchivedPoint(cliCtx)
    94  	configureEth1Config(cliCtx)
    95  	configureNetwork(cliCtx)
    96  	configureInteropConfig(cliCtx)
    97  
    98  	registry := shared.NewServiceRegistry()
    99  
   100  	ctx, cancel := context.WithCancel(cliCtx.Context)
   101  	beacon := &BeaconNode{
   102  		cliCtx:          cliCtx,
   103  		ctx:             ctx,
   104  		cancel:          cancel,
   105  		services:        registry,
   106  		stop:            make(chan struct{}),
   107  		stateFeed:       new(event.Feed),
   108  		blockFeed:       new(event.Feed),
   109  		opFeed:          new(event.Feed),
   110  		attestationPool: attestations.NewPool(),
   111  		exitPool:        voluntaryexits.NewPool(),
   112  		slashingsPool:   slashings.NewPool(),
   113  	}
   114  
   115  	depositAddress, err := registration.DepositContractAddress()
   116  	if err != nil {
   117  		return nil, err
   118  	}
   119  	if err := beacon.startDB(cliCtx, depositAddress); err != nil {
   120  		return nil, err
   121  	}
   122  
   123  	beacon.startStateGen()
   124  
   125  	if err := beacon.registerP2P(cliCtx); err != nil {
   126  		return nil, err
   127  	}
   128  
   129  	if err := beacon.registerPOWChainService(); err != nil {
   130  		return nil, err
   131  	}
   132  
   133  	if err := beacon.registerAttestationPool(); err != nil {
   134  		return nil, err
   135  	}
   136  
   137  	if err := beacon.registerInteropServices(); err != nil {
   138  		return nil, err
   139  	}
   140  
   141  	beacon.startForkChoice()
   142  
   143  	if err := beacon.registerBlockchainService(); err != nil {
   144  		return nil, err
   145  	}
   146  
   147  	if err := beacon.registerInitialSyncService(); err != nil {
   148  		return nil, err
   149  	}
   150  
   151  	if err := beacon.registerSyncService(); err != nil {
   152  		return nil, err
   153  	}
   154  
   155  	if err := beacon.registerRPCService(); err != nil {
   156  		return nil, err
   157  	}
   158  
   159  	if err := beacon.registerGRPCGateway(); err != nil {
   160  		return nil, err
   161  	}
   162  
   163  	if !cliCtx.Bool(cmd.DisableMonitoringFlag.Name) {
   164  		if err := beacon.registerPrometheusService(cliCtx); err != nil {
   165  			return nil, err
   166  		}
   167  	}
   168  
   169  	// db.DatabasePath is the path to the containing directory
   170  	// db.NewDBFilename expands that to the canonical full path using
   171  	// the same constuction as NewDB()
   172  	c, err := newBeaconNodePromCollector(db.NewDBFilename(beacon.db.DatabasePath()))
   173  	if err != nil {
   174  		return nil, err
   175  	}
   176  	beacon.collector = c
   177  
   178  	return beacon, nil
   179  }
   180  
   181  // StateFeed implements statefeed.Notifier.
   182  func (b *BeaconNode) StateFeed() *event.Feed {
   183  	return b.stateFeed
   184  }
   185  
   186  // BlockFeed implements blockfeed.Notifier.
   187  func (b *BeaconNode) BlockFeed() *event.Feed {
   188  	return b.blockFeed
   189  }
   190  
   191  // OperationFeed implements opfeed.Notifier.
   192  func (b *BeaconNode) OperationFeed() *event.Feed {
   193  	return b.opFeed
   194  }
   195  
   196  // Start the BeaconNode and kicks off every registered service.
   197  func (b *BeaconNode) Start() {
   198  	b.lock.Lock()
   199  
   200  	log.WithFields(logrus.Fields{
   201  		"version": version.Version(),
   202  	}).Info("Starting beacon node")
   203  
   204  	b.services.StartAll()
   205  
   206  	stop := b.stop
   207  	b.lock.Unlock()
   208  
   209  	go func() {
   210  		sigc := make(chan os.Signal, 1)
   211  		signal.Notify(sigc, syscall.SIGINT, syscall.SIGTERM)
   212  		defer signal.Stop(sigc)
   213  		<-sigc
   214  		log.Info("Got interrupt, shutting down...")
   215  		debug.Exit(b.cliCtx) // Ensure trace and CPU profile data are flushed.
   216  		go b.Close()
   217  		for i := 10; i > 0; i-- {
   218  			<-sigc
   219  			if i > 1 {
   220  				log.WithField("times", i-1).Info("Already shutting down, interrupt more to panic")
   221  			}
   222  		}
   223  		panic("Panic closing the beacon node")
   224  	}()
   225  
   226  	// Wait for stop channel to be closed.
   227  	<-stop
   228  }
   229  
   230  // Close handles graceful shutdown of the system.
   231  func (b *BeaconNode) Close() {
   232  	b.lock.Lock()
   233  	defer b.lock.Unlock()
   234  
   235  	log.Info("Stopping beacon node")
   236  	b.services.StopAll()
   237  	if err := b.db.Close(); err != nil {
   238  		log.Errorf("Failed to close database: %v", err)
   239  	}
   240  	b.collector.unregister()
   241  	b.cancel()
   242  	close(b.stop)
   243  }
   244  
   245  func (b *BeaconNode) startForkChoice() {
   246  	f := protoarray.New(0, 0, params.BeaconConfig().ZeroHash)
   247  	b.forkChoiceStore = f
   248  }
   249  
   250  func (b *BeaconNode) startDB(cliCtx *cli.Context, depositAddress string) error {
   251  	baseDir := cliCtx.String(cmd.DataDirFlag.Name)
   252  	dbPath := filepath.Join(baseDir, kv.BeaconNodeDbDirName)
   253  	clearDB := cliCtx.Bool(cmd.ClearDB.Name)
   254  	forceClearDB := cliCtx.Bool(cmd.ForceClearDB.Name)
   255  
   256  	log.WithField("database-path", dbPath).Info("Checking DB")
   257  
   258  	d, err := db.NewDB(b.ctx, dbPath, &kv.Config{
   259  		InitialMMapSize: cliCtx.Int(cmd.BoltMMapInitialSizeFlag.Name),
   260  	})
   261  	if err != nil {
   262  		return err
   263  	}
   264  	clearDBConfirmed := false
   265  	if clearDB && !forceClearDB {
   266  		actionText := "This will delete your beacon chain database stored in your data directory. " +
   267  			"Your database backups will not be removed - do you want to proceed? (Y/N)"
   268  		deniedText := "Database will not be deleted. No changes have been made."
   269  		clearDBConfirmed, err = cmd.ConfirmAction(actionText, deniedText)
   270  		if err != nil {
   271  			return err
   272  		}
   273  	}
   274  	if clearDBConfirmed || forceClearDB {
   275  		log.Warning("Removing database")
   276  		if err := d.Close(); err != nil {
   277  			return errors.Wrap(err, "could not close db prior to clearing")
   278  		}
   279  		if err := d.ClearDB(); err != nil {
   280  			return errors.Wrap(err, "could not clear database")
   281  		}
   282  		d, err = db.NewDB(b.ctx, dbPath, &kv.Config{
   283  			InitialMMapSize: cliCtx.Int(cmd.BoltMMapInitialSizeFlag.Name),
   284  		})
   285  		if err != nil {
   286  			return errors.Wrap(err, "could not create new database")
   287  		}
   288  	}
   289  
   290  	if err := d.RunMigrations(b.ctx); err != nil {
   291  		return err
   292  	}
   293  
   294  	b.db = d
   295  
   296  	depositCache, err := depositcache.New()
   297  	if err != nil {
   298  		return errors.Wrap(err, "could not create deposit cache")
   299  	}
   300  
   301  	b.depositCache = depositCache
   302  
   303  	if cliCtx.IsSet(flags.GenesisStatePath.Name) {
   304  		r, err := os.Open(cliCtx.String(flags.GenesisStatePath.Name))
   305  		if err != nil {
   306  			return err
   307  		}
   308  		defer func() {
   309  			if err := r.Close(); err != nil {
   310  				log.WithError(err).Error("Failed to close genesis file")
   311  			}
   312  		}()
   313  		if err := b.db.LoadGenesis(b.ctx, r); err != nil {
   314  			if err == db.ErrExistingGenesisState {
   315  				return errors.New("Genesis state flag specified but a genesis state " +
   316  					"exists already. Run again with --clear-db and/or ensure you are using the " +
   317  					"appropriate testnet flag to load the given genesis state.")
   318  			}
   319  			return errors.Wrap(err, "could not load genesis from file")
   320  		}
   321  	}
   322  
   323  	if err := b.db.EnsureEmbeddedGenesis(b.ctx); err != nil {
   324  		return err
   325  	}
   326  
   327  	knownContract, err := b.db.DepositContractAddress(b.ctx)
   328  	if err != nil {
   329  		return err
   330  	}
   331  	addr := common.HexToAddress(depositAddress)
   332  	if len(knownContract) == 0 {
   333  		if err := b.db.SaveDepositContractAddress(b.ctx, addr); err != nil {
   334  			return errors.Wrap(err, "could not save deposit contract")
   335  		}
   336  	}
   337  	if len(knownContract) > 0 && !bytes.Equal(addr.Bytes(), knownContract) {
   338  		return fmt.Errorf("database contract is %#x but tried to run with %#x. This likely means "+
   339  			"you are trying to run on a different network than what the database contains. You can run once with "+
   340  			"'--clear-db' to wipe the old database or use an alternative data directory with '--datadir'",
   341  			knownContract, addr.Bytes())
   342  	}
   343  	log.Infof("Deposit contract: %#x", addr.Bytes())
   344  
   345  	return nil
   346  }
   347  
   348  func (b *BeaconNode) startStateGen() {
   349  	b.stateGen = stategen.New(b.db)
   350  }
   351  
   352  func (b *BeaconNode) registerP2P(cliCtx *cli.Context) error {
   353  	bootstrapNodeAddrs, dataDir, err := registration.P2PPreregistration(cliCtx)
   354  	if err != nil {
   355  		return err
   356  	}
   357  
   358  	svc, err := p2p.NewService(b.ctx, &p2p.Config{
   359  		NoDiscovery:       cliCtx.Bool(cmd.NoDiscovery.Name),
   360  		StaticPeers:       sliceutil.SplitCommaSeparated(cliCtx.StringSlice(cmd.StaticPeers.Name)),
   361  		BootstrapNodeAddr: bootstrapNodeAddrs,
   362  		RelayNodeAddr:     cliCtx.String(cmd.RelayNode.Name),
   363  		DataDir:           dataDir,
   364  		LocalIP:           cliCtx.String(cmd.P2PIP.Name),
   365  		HostAddress:       cliCtx.String(cmd.P2PHost.Name),
   366  		HostDNS:           cliCtx.String(cmd.P2PHostDNS.Name),
   367  		PrivateKey:        cliCtx.String(cmd.P2PPrivKey.Name),
   368  		MetaDataDir:       cliCtx.String(cmd.P2PMetadata.Name),
   369  		TCPPort:           cliCtx.Uint(cmd.P2PTCPPort.Name),
   370  		UDPPort:           cliCtx.Uint(cmd.P2PUDPPort.Name),
   371  		MaxPeers:          cliCtx.Uint(cmd.P2PMaxPeers.Name),
   372  		AllowListCIDR:     cliCtx.String(cmd.P2PAllowList.Name),
   373  		DenyListCIDR:      sliceutil.SplitCommaSeparated(cliCtx.StringSlice(cmd.P2PDenyList.Name)),
   374  		EnableUPnP:        cliCtx.Bool(cmd.EnableUPnPFlag.Name),
   375  		DisableDiscv5:     cliCtx.Bool(flags.DisableDiscv5.Name),
   376  		StateNotifier:     b,
   377  		DB:                b.db,
   378  	})
   379  	if err != nil {
   380  		return err
   381  	}
   382  	return b.services.RegisterService(svc)
   383  }
   384  
   385  func (b *BeaconNode) fetchP2P() p2p.P2P {
   386  	var p *p2p.Service
   387  	if err := b.services.FetchService(&p); err != nil {
   388  		panic(err)
   389  	}
   390  	return p
   391  }
   392  
   393  func (b *BeaconNode) registerAttestationPool() error {
   394  	s, err := attestations.NewService(b.ctx, &attestations.Config{
   395  		Pool: b.attestationPool,
   396  	})
   397  	if err != nil {
   398  		return errors.Wrap(err, "could not register atts pool service")
   399  	}
   400  	return b.services.RegisterService(s)
   401  }
   402  
   403  func (b *BeaconNode) registerBlockchainService() error {
   404  	var web3Service *powchain.Service
   405  	if err := b.services.FetchService(&web3Service); err != nil {
   406  		return err
   407  	}
   408  
   409  	var attService *attestations.Service
   410  	if err := b.services.FetchService(&attService); err != nil {
   411  		return err
   412  	}
   413  
   414  	wsp := b.cliCtx.String(flags.WeakSubjectivityCheckpt.Name)
   415  	wsCheckpt, err := helpers.ParseWeakSubjectivityInputString(wsp)
   416  	if err != nil {
   417  		return err
   418  	}
   419  
   420  	maxRoutines := b.cliCtx.Int(cmd.MaxGoroutines.Name)
   421  	blockchainService, err := blockchain.NewService(b.ctx, &blockchain.Config{
   422  		BeaconDB:                b.db,
   423  		DepositCache:            b.depositCache,
   424  		ChainStartFetcher:       web3Service,
   425  		AttPool:                 b.attestationPool,
   426  		ExitPool:                b.exitPool,
   427  		SlashingPool:            b.slashingsPool,
   428  		P2p:                     b.fetchP2P(),
   429  		MaxRoutines:             maxRoutines,
   430  		StateNotifier:           b,
   431  		ForkChoiceStore:         b.forkChoiceStore,
   432  		AttService:              attService,
   433  		StateGen:                b.stateGen,
   434  		WeakSubjectivityCheckpt: wsCheckpt,
   435  	})
   436  	if err != nil {
   437  		return errors.Wrap(err, "could not register blockchain service")
   438  	}
   439  	return b.services.RegisterService(blockchainService)
   440  }
   441  
   442  func (b *BeaconNode) registerPOWChainService() error {
   443  	if b.cliCtx.Bool(testSkipPowFlag) {
   444  		return b.services.RegisterService(&powchain.Service{})
   445  	}
   446  
   447  	depAddress, endpoints, err := registration.PowchainPreregistration(b.cliCtx)
   448  	if err != nil {
   449  		return err
   450  	}
   451  
   452  	bs, err := powchain.NewPowchainCollector(b.ctx)
   453  	if err != nil {
   454  		return err
   455  	}
   456  
   457  	cfg := &powchain.Web3ServiceConfig{
   458  		HttpEndpoints:          endpoints,
   459  		DepositContract:        common.HexToAddress(depAddress),
   460  		BeaconDB:               b.db,
   461  		DepositCache:           b.depositCache,
   462  		StateNotifier:          b,
   463  		StateGen:               b.stateGen,
   464  		Eth1HeaderReqLimit:     b.cliCtx.Uint64(flags.Eth1HeaderReqLimit.Name),
   465  		BeaconNodeStatsUpdater: bs,
   466  	}
   467  
   468  	web3Service, err := powchain.NewService(b.ctx, cfg)
   469  	if err != nil {
   470  		return errors.Wrap(err, "could not register proof-of-work chain web3Service")
   471  	}
   472  
   473  	return b.services.RegisterService(web3Service)
   474  }
   475  
   476  func (b *BeaconNode) registerSyncService() error {
   477  	var web3Service *powchain.Service
   478  	if err := b.services.FetchService(&web3Service); err != nil {
   479  		return err
   480  	}
   481  
   482  	var chainService *blockchain.Service
   483  	if err := b.services.FetchService(&chainService); err != nil {
   484  		return err
   485  	}
   486  
   487  	var initSync *initialsync.Service
   488  	if err := b.services.FetchService(&initSync); err != nil {
   489  		return err
   490  	}
   491  
   492  	rs := regularsync.NewService(b.ctx, &regularsync.Config{
   493  		DB:                  b.db,
   494  		P2P:                 b.fetchP2P(),
   495  		Chain:               chainService,
   496  		InitialSync:         initSync,
   497  		StateNotifier:       b,
   498  		BlockNotifier:       b,
   499  		AttestationNotifier: b,
   500  		AttPool:             b.attestationPool,
   501  		ExitPool:            b.exitPool,
   502  		SlashingPool:        b.slashingsPool,
   503  		StateGen:            b.stateGen,
   504  	})
   505  
   506  	return b.services.RegisterService(rs)
   507  }
   508  
   509  func (b *BeaconNode) registerInitialSyncService() error {
   510  	var chainService *blockchain.Service
   511  	if err := b.services.FetchService(&chainService); err != nil {
   512  		return err
   513  	}
   514  
   515  	is := initialsync.NewService(b.ctx, &initialsync.Config{
   516  		DB:            b.db,
   517  		Chain:         chainService,
   518  		P2P:           b.fetchP2P(),
   519  		StateNotifier: b,
   520  		BlockNotifier: b,
   521  	})
   522  	return b.services.RegisterService(is)
   523  }
   524  
   525  func (b *BeaconNode) registerRPCService() error {
   526  	var chainService *blockchain.Service
   527  	if err := b.services.FetchService(&chainService); err != nil {
   528  		return err
   529  	}
   530  
   531  	var web3Service *powchain.Service
   532  	if err := b.services.FetchService(&web3Service); err != nil {
   533  		return err
   534  	}
   535  
   536  	var syncService *initialsync.Service
   537  	if err := b.services.FetchService(&syncService); err != nil {
   538  		return err
   539  	}
   540  
   541  	genesisValidators := b.cliCtx.Uint64(flags.InteropNumValidatorsFlag.Name)
   542  	genesisStatePath := b.cliCtx.String(flags.InteropGenesisStateFlag.Name)
   543  	var depositFetcher depositcache.DepositFetcher
   544  	var chainStartFetcher powchain.ChainStartFetcher
   545  	if genesisValidators > 0 || genesisStatePath != "" {
   546  		var interopService *interopcoldstart.Service
   547  		if err := b.services.FetchService(&interopService); err != nil {
   548  			return err
   549  		}
   550  		depositFetcher = interopService
   551  		chainStartFetcher = interopService
   552  	} else {
   553  		depositFetcher = b.depositCache
   554  		chainStartFetcher = web3Service
   555  	}
   556  
   557  	host := b.cliCtx.String(flags.RPCHost.Name)
   558  	port := b.cliCtx.String(flags.RPCPort.Name)
   559  	beaconMonitoringHost := b.cliCtx.String(cmd.MonitoringHostFlag.Name)
   560  	beaconMonitoringPort := b.cliCtx.Int(flags.MonitoringPortFlag.Name)
   561  	cert := b.cliCtx.String(flags.CertFlag.Name)
   562  	key := b.cliCtx.String(flags.KeyFlag.Name)
   563  	mockEth1DataVotes := b.cliCtx.Bool(flags.InteropMockEth1DataVotesFlag.Name)
   564  	enableDebugRPCEndpoints := b.cliCtx.Bool(flags.EnableDebugRPCEndpoints.Name)
   565  	maxMsgSize := b.cliCtx.Int(cmd.GrpcMaxCallRecvMsgSizeFlag.Name)
   566  	p2pService := b.fetchP2P()
   567  	rpcService := rpc.NewService(b.ctx, &rpc.Config{
   568  		Host:                    host,
   569  		Port:                    port,
   570  		BeaconMonitoringHost:    beaconMonitoringHost,
   571  		BeaconMonitoringPort:    beaconMonitoringPort,
   572  		CertFlag:                cert,
   573  		KeyFlag:                 key,
   574  		BeaconDB:                b.db,
   575  		Broadcaster:             p2pService,
   576  		PeersFetcher:            p2pService,
   577  		PeerManager:             p2pService,
   578  		MetadataProvider:        p2pService,
   579  		ChainInfoFetcher:        chainService,
   580  		HeadFetcher:             chainService,
   581  		CanonicalFetcher:        chainService,
   582  		ForkFetcher:             chainService,
   583  		FinalizationFetcher:     chainService,
   584  		BlockReceiver:           chainService,
   585  		AttestationReceiver:     chainService,
   586  		GenesisTimeFetcher:      chainService,
   587  		GenesisFetcher:          chainService,
   588  		AttestationsPool:        b.attestationPool,
   589  		ExitPool:                b.exitPool,
   590  		SlashingsPool:           b.slashingsPool,
   591  		POWChainService:         web3Service,
   592  		ChainStartFetcher:       chainStartFetcher,
   593  		MockEth1Votes:           mockEth1DataVotes,
   594  		SyncService:             syncService,
   595  		DepositFetcher:          depositFetcher,
   596  		PendingDepositFetcher:   b.depositCache,
   597  		BlockNotifier:           b,
   598  		StateNotifier:           b,
   599  		OperationNotifier:       b,
   600  		StateGen:                b.stateGen,
   601  		EnableDebugRPCEndpoints: enableDebugRPCEndpoints,
   602  		MaxMsgSize:              maxMsgSize,
   603  	})
   604  
   605  	return b.services.RegisterService(rpcService)
   606  }
   607  
   608  func (b *BeaconNode) registerPrometheusService(cliCtx *cli.Context) error {
   609  	var additionalHandlers []prometheus.Handler
   610  	var p *p2p.Service
   611  	if err := b.services.FetchService(&p); err != nil {
   612  		panic(err)
   613  	}
   614  	additionalHandlers = append(additionalHandlers, prometheus.Handler{Path: "/p2p", Handler: p.InfoHandler})
   615  
   616  	var c *blockchain.Service
   617  	if err := b.services.FetchService(&c); err != nil {
   618  		panic(err)
   619  	}
   620  
   621  	if cliCtx.IsSet(cmd.EnableBackupWebhookFlag.Name) {
   622  		additionalHandlers = append(
   623  			additionalHandlers,
   624  			prometheus.Handler{
   625  				Path:    "/db/backup",
   626  				Handler: backuputil.BackupHandler(b.db, cliCtx.String(cmd.BackupWebhookOutputDir.Name)),
   627  			},
   628  		)
   629  	}
   630  
   631  	additionalHandlers = append(additionalHandlers, prometheus.Handler{Path: "/tree", Handler: c.TreeHandler})
   632  
   633  	service := prometheus.NewService(
   634  		fmt.Sprintf("%s:%d", b.cliCtx.String(cmd.MonitoringHostFlag.Name), b.cliCtx.Int(flags.MonitoringPortFlag.Name)),
   635  		b.services,
   636  		additionalHandlers...,
   637  	)
   638  	hook := prometheus.NewLogrusCollector()
   639  	logrus.AddHook(hook)
   640  	return b.services.RegisterService(service)
   641  }
   642  
   643  func (b *BeaconNode) registerGRPCGateway() error {
   644  	if b.cliCtx.Bool(flags.DisableGRPCGateway.Name) {
   645  		return nil
   646  	}
   647  	gatewayPort := b.cliCtx.Int(flags.GRPCGatewayPort.Name)
   648  	ethApiPort := b.cliCtx.Int(flags.EthApiPort.Name)
   649  	gatewayHost := b.cliCtx.String(flags.GRPCGatewayHost.Name)
   650  	rpcHost := b.cliCtx.String(flags.RPCHost.Name)
   651  	selfAddress := fmt.Sprintf("%s:%d", rpcHost, b.cliCtx.Int(flags.RPCPort.Name))
   652  	gatewayAddress := fmt.Sprintf("%s:%d", gatewayHost, gatewayPort)
   653  	apiMiddlewareAddress := fmt.Sprintf("%s:%d", gatewayHost, ethApiPort)
   654  	allowedOrigins := strings.Split(b.cliCtx.String(flags.GPRCGatewayCorsDomain.Name), ",")
   655  	enableDebugRPCEndpoints := b.cliCtx.Bool(flags.EnableDebugRPCEndpoints.Name)
   656  	selfCert := b.cliCtx.String(flags.CertFlag.Name)
   657  	maxCallSize := b.cliCtx.Uint64(cmd.GrpcMaxCallRecvMsgSizeFlag.Name)
   658  
   659  	gatewayConfig := gateway2.DefaultConfig(enableDebugRPCEndpoints)
   660  
   661  	g := gateway.New(
   662  		b.ctx,
   663  		[]gateway.PbMux{gatewayConfig.V1Alpha1PbMux, gatewayConfig.V1PbMux},
   664  		gatewayConfig.Handler,
   665  		selfAddress,
   666  		gatewayAddress,
   667  	).WithAllowedOrigins(allowedOrigins).
   668  		WithRemoteCert(selfCert).
   669  		WithMaxCallRecvMsgSize(maxCallSize).
   670  		WithApiMiddleware(apiMiddlewareAddress, &apimiddleware.BeaconEndpointFactory{})
   671  
   672  	return b.services.RegisterService(g)
   673  }
   674  
   675  func (b *BeaconNode) registerInteropServices() error {
   676  	genesisTime := b.cliCtx.Uint64(flags.InteropGenesisTimeFlag.Name)
   677  	genesisValidators := b.cliCtx.Uint64(flags.InteropNumValidatorsFlag.Name)
   678  	genesisStatePath := b.cliCtx.String(flags.InteropGenesisStateFlag.Name)
   679  
   680  	if genesisValidators > 0 || genesisStatePath != "" {
   681  		svc := interopcoldstart.NewService(b.ctx, &interopcoldstart.Config{
   682  			GenesisTime:   genesisTime,
   683  			NumValidators: genesisValidators,
   684  			BeaconDB:      b.db,
   685  			DepositCache:  b.depositCache,
   686  			GenesisPath:   genesisStatePath,
   687  		})
   688  
   689  		return b.services.RegisterService(svc)
   690  	}
   691  	return nil
   692  }