github.com/ari-anchor/sei-tendermint@v0.0.0-20230519144642-dc826b7b56bb/cmd/tendermint/commands/run_node.go (about)

     1  package commands
     2  
     3  import (
     4  	"bytes"
     5  	"crypto/sha256"
     6  	"fmt"
     7  	"io"
     8  	"os"
     9  	"os/signal"
    10  	"syscall"
    11  
    12  	"github.com/spf13/cobra"
    13  
    14  	cfg "github.com/ari-anchor/sei-tendermint/config"
    15  	"github.com/ari-anchor/sei-tendermint/libs/log"
    16  )
    17  
    18  var (
    19  	genesisHash []byte
    20  )
    21  
    22  // AddNodeFlags exposes some common configuration options from conf in the flag
    23  // set for cmd. This is a convenience for commands embedding a Tendermint node.
    24  func AddNodeFlags(cmd *cobra.Command, conf *cfg.Config) {
    25  	// bind flags
    26  	cmd.Flags().String("moniker", conf.Moniker, "node name")
    27  
    28  	// mode flags
    29  	cmd.Flags().String("mode", conf.Mode, "node mode (full | validator | seed)")
    30  
    31  	// priv val flags
    32  	cmd.Flags().String(
    33  		"priv-validator-laddr",
    34  		conf.PrivValidator.ListenAddr,
    35  		"socket address to listen on for connections from external priv-validator process")
    36  
    37  	// node flags
    38  
    39  	cmd.Flags().BytesHexVar(
    40  		&genesisHash,
    41  		"genesis-hash",
    42  		[]byte{},
    43  		"optional SHA-256 hash of the genesis file")
    44  	cmd.Flags().Int64("consensus.double-sign-check-height", conf.Consensus.DoubleSignCheckHeight,
    45  		"how many blocks to look back to check existence of the node's "+
    46  			"consensus votes before joining consensus")
    47  
    48  	// abci flags
    49  	cmd.Flags().String(
    50  		"proxy-app",
    51  		conf.ProxyApp,
    52  		"proxy app address, or one of: 'kvstore',"+
    53  			" 'persistent_kvstore', 'e2e' or 'noop' for local testing.")
    54  	cmd.Flags().String("abci", conf.ABCI, "specify abci transport (socket | grpc)")
    55  
    56  	// rpc flags
    57  	cmd.Flags().String("rpc.laddr", conf.RPC.ListenAddress, "RPC listen address. Port required")
    58  	cmd.Flags().Bool("rpc.unsafe", conf.RPC.Unsafe, "enabled unsafe rpc methods")
    59  	cmd.Flags().String("rpc.pprof-laddr", conf.RPC.PprofListenAddress, "pprof listen address (https://golang.org/pkg/net/http/pprof)")
    60  
    61  	// p2p flags
    62  	cmd.Flags().String(
    63  		"p2p.laddr",
    64  		conf.P2P.ListenAddress,
    65  		"node listen address. (0.0.0.0:0 means any interface, any port)")
    66  	cmd.Flags().String("p2p.persistent-peers", conf.P2P.PersistentPeers, "comma-delimited ID@host:port persistent peers")
    67  	cmd.Flags().Bool("p2p.upnp", conf.P2P.UPNP, "enable/disable UPNP port forwarding")
    68  	cmd.Flags().Bool("p2p.pex", conf.P2P.PexReactor, "enable/disable Peer-Exchange")
    69  	cmd.Flags().String("p2p.private-peer-ids", conf.P2P.PrivatePeerIDs, "comma-delimited private peer IDs")
    70  	cmd.Flags().String("p2p.unconditional_peer_ids",
    71  		conf.P2P.UnconditionalPeerIDs, "comma-delimited IDs of unconditional peers")
    72  
    73  	// consensus flags
    74  	cmd.Flags().Bool(
    75  		"consensus.create-empty-blocks",
    76  		conf.Consensus.CreateEmptyBlocks,
    77  		"set this to false to only produce blocks when there are txs or when the AppHash changes")
    78  	cmd.Flags().String(
    79  		"consensus.create-empty-blocks-interval",
    80  		conf.Consensus.CreateEmptyBlocksInterval.String(),
    81  		"the possible interval between empty blocks")
    82  	cmd.Flags().Bool(
    83  		"consensus.gossip-tx-key-only",
    84  		conf.Consensus.GossipTransactionKeyOnly,
    85  		"set this to false to gossip entire data rather than just the key")
    86  
    87  	addDBFlags(cmd, conf)
    88  }
    89  
    90  func addDBFlags(cmd *cobra.Command, conf *cfg.Config) {
    91  	cmd.Flags().String(
    92  		"db-backend",
    93  		conf.DBBackend,
    94  		"database backend: goleveldb | cleveldb | boltdb | rocksdb | badgerdb")
    95  	cmd.Flags().String(
    96  		"db-dir",
    97  		conf.DBPath,
    98  		"database directory")
    99  }
   100  
   101  // NewRunNodeCmd returns the command that allows the CLI to start a node.
   102  // It can be used with a custom PrivValidator and in-process ABCI application.
   103  func NewRunNodeCmd(nodeProvider cfg.ServiceProvider, conf *cfg.Config, logger log.Logger, restartCh chan struct{}) *cobra.Command {
   104  	cmd := &cobra.Command{
   105  		Use:     "start",
   106  		Aliases: []string{"node", "run"},
   107  		Short:   "Run the tendermint node",
   108  		RunE: func(cmd *cobra.Command, args []string) error {
   109  			if err := checkGenesisHash(conf); err != nil {
   110  				return err
   111  			}
   112  
   113  			ctx, cancel := signal.NotifyContext(cmd.Context(), os.Interrupt, syscall.SIGTERM)
   114  			defer cancel()
   115  
   116  			n, err := nodeProvider(ctx, conf, logger, restartCh)
   117  			if err != nil {
   118  				return fmt.Errorf("failed to create node: %w", err)
   119  			}
   120  
   121  			if err := n.Start(ctx); err != nil {
   122  				return fmt.Errorf("failed to start node: %w", err)
   123  			}
   124  
   125  			logger.Info("started node", "chain", conf.ChainID())
   126  
   127  			for {
   128  				select {
   129  				case <-ctx.Done():
   130  					return nil
   131  				case <-restartCh:
   132  					logger.Info("Received signal to restart node.")
   133  					n.Stop()
   134  					os.Exit(1)
   135  				}
   136  			}
   137  		},
   138  	}
   139  
   140  	AddNodeFlags(cmd, conf)
   141  	return cmd
   142  }
   143  
   144  func checkGenesisHash(config *cfg.Config) error {
   145  	if len(genesisHash) == 0 || config.Genesis == "" {
   146  		return nil
   147  	}
   148  
   149  	// Calculate SHA-256 hash of the genesis file.
   150  	f, err := os.Open(config.GenesisFile())
   151  	if err != nil {
   152  		return fmt.Errorf("can't open genesis file: %w", err)
   153  	}
   154  	defer f.Close()
   155  	h := sha256.New()
   156  	if _, err := io.Copy(h, f); err != nil {
   157  		return fmt.Errorf("error when hashing genesis file: %w", err)
   158  	}
   159  	actualHash := h.Sum(nil)
   160  
   161  	// Compare with the flag.
   162  	if !bytes.Equal(genesisHash, actualHash) {
   163  		return fmt.Errorf(
   164  			"--genesis-hash=%X does not match %s hash: %X",
   165  			genesisHash, config.GenesisFile(), actualHash)
   166  	}
   167  
   168  	return nil
   169  }