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