|
|
- package node
-
- import (
- "context"
- "errors"
- "fmt"
- "net/http"
- "strings"
- "time"
-
- "github.com/tendermint/tendermint/config"
- "github.com/tendermint/tendermint/internal/p2p"
- "github.com/tendermint/tendermint/internal/p2p/pex"
- sm "github.com/tendermint/tendermint/internal/state"
- "github.com/tendermint/tendermint/libs/log"
- "github.com/tendermint/tendermint/libs/service"
- tmtime "github.com/tendermint/tendermint/libs/time"
- "github.com/tendermint/tendermint/types"
- )
-
- type seedNodeImpl struct {
- service.BaseService
- logger log.Logger
-
- // config
- config *config.Config
- genesisDoc *types.GenesisDoc // initial validator set
-
- // network
- peerManager *p2p.PeerManager
- router *p2p.Router
- nodeInfo types.NodeInfo
- nodeKey types.NodeKey // our node privkey
- isListening bool
-
- // services
- pexReactor service.Service // for exchanging peer addresses
- shutdownOps closer
- }
-
- // makeSeedNode returns a new seed node, containing only p2p, pex reactor
- func makeSeedNode(
- ctx context.Context,
- cfg *config.Config,
- dbProvider config.DBProvider,
- nodeKey types.NodeKey,
- genesisDocProvider genesisDocProvider,
- logger log.Logger,
- ) (service.Service, error) {
- if !cfg.P2P.PexReactor {
- return nil, errors.New("cannot run seed nodes with PEX disabled")
- }
-
- genDoc, err := genesisDocProvider()
- if err != nil {
- return nil, err
- }
-
- state, err := sm.MakeGenesisState(genDoc)
- if err != nil {
- return nil, err
- }
-
- nodeInfo, err := makeSeedNodeInfo(cfg, nodeKey, genDoc, state)
- if err != nil {
- return nil, err
- }
-
- // Setup Transport and Switch.
- p2pMetrics := p2p.PrometheusMetrics(cfg.Instrumentation.Namespace, "chain_id", genDoc.ChainID)
-
- peerManager, closer, err := createPeerManager(cfg, dbProvider, nodeKey.ID)
- if err != nil {
- return nil, combineCloseError(
- fmt.Errorf("failed to create peer manager: %w", err),
- closer)
- }
-
- router, err := createRouter(ctx, logger, p2pMetrics, nodeInfo, nodeKey,
- peerManager, cfg, nil)
- if err != nil {
- return nil, combineCloseError(
- fmt.Errorf("failed to create router: %w", err),
- closer)
- }
-
- pexReactor, err := pex.NewReactor(ctx, logger, peerManager, router.OpenChannel, peerManager.Subscribe(ctx))
- if err != nil {
- return nil, combineCloseError(err, closer)
- }
-
- node := &seedNodeImpl{
- config: cfg,
- logger: logger,
- genesisDoc: genDoc,
-
- nodeInfo: nodeInfo,
- nodeKey: nodeKey,
- peerManager: peerManager,
- router: router,
-
- shutdownOps: closer,
-
- pexReactor: pexReactor,
- }
- node.BaseService = *service.NewBaseService(logger, "SeedNode", node)
-
- return node, nil
- }
-
- // OnStart starts the Seed Node. It implements service.Service.
- func (n *seedNodeImpl) OnStart(ctx context.Context) error {
- if n.config.RPC.PprofListenAddress != "" {
- rpcCtx, rpcCancel := context.WithCancel(ctx)
- srv := &http.Server{Addr: n.config.RPC.PprofListenAddress, Handler: nil}
- go func() {
- select {
- case <-ctx.Done():
- sctx, scancel := context.WithTimeout(context.Background(), time.Second)
- defer scancel()
- _ = srv.Shutdown(sctx)
- case <-rpcCtx.Done():
- }
- }()
-
- go func() {
- n.logger.Info("Starting pprof server", "laddr", n.config.RPC.PprofListenAddress)
-
- if err := srv.ListenAndServe(); err != nil {
- n.logger.Error("pprof server error", "err", err)
- rpcCancel()
- }
- }()
- }
-
- now := tmtime.Now()
- genTime := n.genesisDoc.GenesisTime
- if genTime.After(now) {
- n.logger.Info("Genesis time is in the future. Sleeping until then...", "genTime", genTime)
- time.Sleep(genTime.Sub(now))
- }
-
- // Start the transport.
- if err := n.router.Start(ctx); err != nil {
- return err
- }
- n.isListening = true
-
- if n.config.P2P.PexReactor {
- if err := n.pexReactor.Start(ctx); err != nil {
- return err
- }
- }
-
- return nil
- }
-
- // OnStop stops the Seed Node. It implements service.Service.
- func (n *seedNodeImpl) OnStop() {
- n.logger.Info("Stopping Node")
-
- n.pexReactor.Wait()
- n.router.Wait()
- n.isListening = false
-
- if err := n.shutdownOps(); err != nil {
- if strings.TrimSpace(err.Error()) != "" {
- n.logger.Error("problem shutting down additional services", "err", err)
- }
- }
- }
|