github.com/vipernet-xyz/tm@v0.34.24/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  
    10  	"github.com/spf13/cobra"
    11  
    12  	cfg "github.com/vipernet-xyz/tm/config"
    13  	tmos "github.com/vipernet-xyz/tm/libs/os"
    14  	nm "github.com/vipernet-xyz/tm/node"
    15  )
    16  
    17  var (
    18  	genesisHash []byte
    19  )
    20  
    21  // AddNodeFlags exposes some common configuration options on the command-line
    22  // These are exposed for convenience of commands embedding a tendermint node
    23  func AddNodeFlags(cmd *cobra.Command) {
    24  	// bind flags
    25  	cmd.Flags().String("moniker", config.Moniker, "node name")
    26  
    27  	// priv val flags
    28  	cmd.Flags().String(
    29  		"priv_validator_laddr",
    30  		config.PrivValidatorListenAddr,
    31  		"socket address to listen on for connections from external priv_validator process")
    32  
    33  	// node flags
    34  	cmd.Flags().Bool("fast_sync", config.FastSyncMode, "fast blockchain syncing")
    35  	cmd.Flags().BytesHexVar(
    36  		&genesisHash,
    37  		"genesis_hash",
    38  		[]byte{},
    39  		"optional SHA-256 hash of the genesis file")
    40  	cmd.Flags().Int64("consensus.double_sign_check_height", config.Consensus.DoubleSignCheckHeight,
    41  		"how many blocks to look back to check existence of the node's "+
    42  			"consensus votes before joining consensus")
    43  
    44  	// abci flags
    45  	cmd.Flags().String(
    46  		"proxy_app",
    47  		config.ProxyApp,
    48  		"proxy app address, or one of: 'kvstore',"+
    49  			" 'persistent_kvstore', 'counter', 'e2e' or 'noop' for local testing.")
    50  	cmd.Flags().String("abci", config.ABCI, "specify abci transport (socket | grpc)")
    51  
    52  	// rpc flags
    53  	cmd.Flags().String("rpc.laddr", config.RPC.ListenAddress, "RPC listen address. Port required")
    54  	cmd.Flags().String(
    55  		"rpc.grpc_laddr",
    56  		config.RPC.GRPCListenAddress,
    57  		"GRPC listen address (BroadcastTx only). Port required")
    58  	cmd.Flags().Bool("rpc.unsafe", config.RPC.Unsafe, "enabled unsafe rpc methods")
    59  	cmd.Flags().String("rpc.pprof_laddr", config.RPC.PprofListenAddress, "pprof listen address (https://golang.org/pkg/net/http/pprof)")
    60  
    61  	// p2p flags
    62  	cmd.Flags().String(
    63  		"p2p.laddr",
    64  		config.P2P.ListenAddress,
    65  		"node listen address. (0.0.0.0:0 means any interface, any port)")
    66  	cmd.Flags().String("p2p.external-address",
    67  		config.P2P.ExternalAddress, "ip:port address to advertise to peers for them to dial")
    68  	cmd.Flags().String("p2p.seeds", config.P2P.Seeds, "comma-delimited ID@host:port seed nodes")
    69  	cmd.Flags().String("p2p.persistent_peers", config.P2P.PersistentPeers, "comma-delimited ID@host:port persistent peers")
    70  	cmd.Flags().String("p2p.unconditional_peer_ids",
    71  		config.P2P.UnconditionalPeerIDs, "comma-delimited IDs of unconditional peers")
    72  	cmd.Flags().Bool("p2p.upnp", config.P2P.UPNP, "enable/disable UPNP port forwarding")
    73  	cmd.Flags().Bool("p2p.pex", config.P2P.PexReactor, "enable/disable Peer-Exchange")
    74  	cmd.Flags().Bool("p2p.seed_mode", config.P2P.SeedMode, "enable/disable seed mode")
    75  	cmd.Flags().String("p2p.private_peer_ids", config.P2P.PrivatePeerIDs, "comma-delimited private peer IDs")
    76  
    77  	// consensus flags
    78  	cmd.Flags().Bool(
    79  		"consensus.create_empty_blocks",
    80  		config.Consensus.CreateEmptyBlocks,
    81  		"set this to false to only produce blocks when there are txs or when the AppHash changes")
    82  	cmd.Flags().String(
    83  		"consensus.create_empty_blocks_interval",
    84  		config.Consensus.CreateEmptyBlocksInterval.String(),
    85  		"the possible interval between empty blocks")
    86  
    87  	// db flags
    88  	cmd.Flags().String(
    89  		"db_backend",
    90  		config.DBBackend,
    91  		"database backend: goleveldb | cleveldb | boltdb | rocksdb | badgerdb")
    92  	cmd.Flags().String(
    93  		"db_dir",
    94  		config.DBPath,
    95  		"database directory")
    96  }
    97  
    98  // NewRunNodeCmd returns the command that allows the CLI to start a node.
    99  // It can be used with a custom PrivValidator and in-process ABCI application.
   100  func NewRunNodeCmd(nodeProvider nm.Provider) *cobra.Command {
   101  	cmd := &cobra.Command{
   102  		Use:     "start",
   103  		Aliases: []string{"node", "run"},
   104  		Short:   "Run the tendermint node",
   105  		RunE: func(cmd *cobra.Command, args []string) error {
   106  			if err := checkGenesisHash(config); err != nil {
   107  				return err
   108  			}
   109  
   110  			n, err := nodeProvider(config, logger)
   111  			if err != nil {
   112  				return fmt.Errorf("failed to create node: %w", err)
   113  			}
   114  
   115  			if err := n.Start(); err != nil {
   116  				return fmt.Errorf("failed to start node: %w", err)
   117  			}
   118  
   119  			logger.Info("Started node", "nodeInfo", n.Switch().NodeInfo())
   120  
   121  			// Stop upon receiving SIGTERM or CTRL-C.
   122  			tmos.TrapSignal(logger, func() {
   123  				if n.IsRunning() {
   124  					if err := n.Stop(); err != nil {
   125  						logger.Error("unable to stop the node", "error", err)
   126  					}
   127  				}
   128  			})
   129  
   130  			// Run forever.
   131  			select {}
   132  		},
   133  	}
   134  
   135  	AddNodeFlags(cmd)
   136  	return cmd
   137  }
   138  
   139  func checkGenesisHash(config *cfg.Config) error {
   140  	if len(genesisHash) == 0 || config.Genesis == "" {
   141  		return nil
   142  	}
   143  
   144  	// Calculate SHA-256 hash of the genesis file.
   145  	f, err := os.Open(config.GenesisFile())
   146  	if err != nil {
   147  		return fmt.Errorf("can't open genesis file: %w", err)
   148  	}
   149  	defer f.Close()
   150  	h := sha256.New()
   151  	if _, err := io.Copy(h, f); err != nil {
   152  		return fmt.Errorf("error when hashing genesis file: %w", err)
   153  	}
   154  	actualHash := h.Sum(nil)
   155  
   156  	// Compare with the flag.
   157  	if !bytes.Equal(genesisHash, actualHash) {
   158  		return fmt.Errorf(
   159  			"--genesis_hash=%X does not match %s hash: %X",
   160  			genesisHash, config.GenesisFile(), actualHash)
   161  	}
   162  
   163  	return nil
   164  }