github.com/adoriasoft/tendermint@v0.34.0-dev1.0.20200722151356-96d84601a75a/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/tendermint/tendermint/config" 13 tmos "github.com/tendermint/tendermint/libs/os" 14 nm "github.com/tendermint/tendermint/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 41 // abci flags 42 cmd.Flags().String( 43 "proxy_app", 44 config.ProxyApp, 45 "Proxy app address, or one of: 'kvstore',"+ 46 " 'persistent_kvstore',"+ 47 " 'counter',"+ 48 " 'counter_serial' or 'noop' for local testing.") 49 cmd.Flags().String("abci", config.ABCI, "Specify abci transport (socket | grpc)") 50 51 // rpc flags 52 cmd.Flags().String("rpc.laddr", config.RPC.ListenAddress, "RPC listen address. Port required") 53 cmd.Flags().String( 54 "rpc.grpc_laddr", 55 config.RPC.GRPCListenAddress, 56 "GRPC listen address (BroadcastTx only). Port required") 57 cmd.Flags().Bool("rpc.unsafe", config.RPC.Unsafe, "Enabled unsafe rpc methods") 58 59 // p2p flags 60 cmd.Flags().String( 61 "p2p.laddr", 62 config.P2P.ListenAddress, 63 "Node listen address. (0.0.0.0:0 means any interface, any port)") 64 cmd.Flags().String("p2p.seeds", config.P2P.Seeds, "Comma-delimited ID@host:port seed nodes") 65 cmd.Flags().String("p2p.persistent_peers", config.P2P.PersistentPeers, "Comma-delimited ID@host:port persistent peers") 66 cmd.Flags().String("p2p.unconditional_peer_ids", 67 config.P2P.UnconditionalPeerIDs, "Comma-delimited IDs of unconditional peers") 68 cmd.Flags().Bool("p2p.upnp", config.P2P.UPNP, "Enable/disable UPNP port forwarding") 69 cmd.Flags().Bool("p2p.pex", config.P2P.PexReactor, "Enable/disable Peer-Exchange") 70 cmd.Flags().Bool("p2p.seed_mode", config.P2P.SeedMode, "Enable/disable seed mode") 71 cmd.Flags().String("p2p.private_peer_ids", config.P2P.PrivatePeerIDs, "Comma-delimited private peer IDs") 72 73 // consensus flags 74 cmd.Flags().Bool( 75 "consensus.create_empty_blocks", 76 config.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 config.Consensus.CreateEmptyBlocksInterval.String(), 81 "The possible interval between empty blocks") 82 83 // db flags 84 cmd.Flags().String( 85 "db_backend", 86 config.DBBackend, 87 "Database backend: goleveldb | cleveldb | boltdb | rocksdb") 88 cmd.Flags().String( 89 "db_dir", 90 config.DBPath, 91 "Database directory") 92 } 93 94 // NewRunNodeCmd returns the command that allows the CLI to start a node. 95 // It can be used with a custom PrivValidator and in-process ABCI application. 96 func NewRunNodeCmd(nodeProvider nm.Provider) *cobra.Command { 97 cmd := &cobra.Command{ 98 Use: "node", 99 Short: "Run the tendermint node", 100 RunE: func(cmd *cobra.Command, args []string) error { 101 if err := checkGenesisHash(config); err != nil { 102 return err 103 } 104 105 n, err := nodeProvider(config, logger) 106 if err != nil { 107 return fmt.Errorf("failed to create node: %w", err) 108 } 109 110 if err := n.Start(); err != nil { 111 return fmt.Errorf("failed to start node: %w", err) 112 } 113 114 logger.Info("Started node", "nodeInfo", n.Switch().NodeInfo()) 115 116 // Stop upon receiving SIGTERM or CTRL-C. 117 tmos.TrapSignal(logger, func() { 118 if n.IsRunning() { 119 n.Stop() 120 } 121 }) 122 123 // Run forever. 124 select {} 125 }, 126 } 127 128 AddNodeFlags(cmd) 129 return cmd 130 } 131 132 func checkGenesisHash(config *cfg.Config) error { 133 if len(genesisHash) == 0 || config.Genesis == "" { 134 return nil 135 } 136 137 // Calculate SHA-256 hash of the genesis file. 138 f, err := os.Open(config.GenesisFile()) 139 if err != nil { 140 return fmt.Errorf("can't open genesis file: %w", err) 141 } 142 defer f.Close() 143 h := sha256.New() 144 if _, err := io.Copy(h, f); err != nil { 145 return fmt.Errorf("error when hashing genesis file: %w", err) 146 } 147 actualHash := h.Sum(nil) 148 149 // Compare with the flag. 150 if !bytes.Equal(genesisHash, actualHash) { 151 return fmt.Errorf( 152 "--genesis_hash=%X does not match %s hash: %X", 153 genesisHash, config.GenesisFile(), actualHash) 154 } 155 156 return nil 157 }