github.com/number571/tendermint@v0.34.11-gost/cmd/tendermint/commands/run_node.go (about) 1 package commands 2 3 import ( 4 "bytes" 5 6 "fmt" 7 "io" 8 "os" 9 10 ghash "github.com/number571/go-cryptopro/gost_r_34_11_2012" 11 12 "github.com/spf13/cobra" 13 14 cfg "github.com/number571/tendermint/config" 15 tmos "github.com/number571/tendermint/libs/os" 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 // mode flags 29 cmd.Flags().String("mode", config.Mode, "node mode (full | validator | seed)") 30 31 // priv val flags 32 cmd.Flags().String( 33 "priv-validator-laddr", 34 config.PrivValidator.ListenAddr, 35 "socket address to listen on for connections from external priv-validator process") 36 37 // node flags 38 cmd.Flags().Bool("fast-sync", config.FastSyncMode, "fast blockchain syncing") 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", config.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 config.ProxyApp, 52 "proxy app address, or one of: 'kvstore',"+ 53 " 'persistent_kvstore' or 'noop' for local testing.") 54 cmd.Flags().String("abci", config.ABCI, "specify abci transport (socket | grpc)") 55 56 // rpc flags 57 cmd.Flags().String("rpc.laddr", config.RPC.ListenAddress, "RPC listen address. Port required") 58 cmd.Flags().String( 59 "rpc.grpc-laddr", 60 config.RPC.GRPCListenAddress, 61 "GRPC listen address (BroadcastTx only). Port required") 62 cmd.Flags().Bool("rpc.unsafe", config.RPC.Unsafe, "enabled unsafe rpc methods") 63 cmd.Flags().String("rpc.pprof-laddr", config.RPC.PprofListenAddress, "pprof listen address (https://golang.org/pkg/net/http/pprof)") 64 65 // p2p flags 66 cmd.Flags().String( 67 "p2p.laddr", 68 config.P2P.ListenAddress, 69 "node listen address. (0.0.0.0:0 means any interface, any port)") 70 cmd.Flags().String("p2p.seeds", config.P2P.Seeds, "comma-delimited ID@host:port seed nodes") 71 cmd.Flags().String("p2p.persistent-peers", config.P2P.PersistentPeers, "comma-delimited ID@host:port persistent peers") 72 cmd.Flags().String("p2p.unconditional-peer-ids", 73 config.P2P.UnconditionalPeerIDs, "comma-delimited IDs of unconditional peers") 74 cmd.Flags().Bool("p2p.upnp", config.P2P.UPNP, "enable/disable UPNP port forwarding") 75 cmd.Flags().Bool("p2p.pex", config.P2P.PexReactor, "enable/disable Peer-Exchange") 76 cmd.Flags().String("p2p.private-peer-ids", config.P2P.PrivatePeerIDs, "comma-delimited private peer IDs") 77 78 // consensus flags 79 cmd.Flags().Bool( 80 "consensus.create-empty-blocks", 81 config.Consensus.CreateEmptyBlocks, 82 "set this to false to only produce blocks when there are txs or when the AppHash changes") 83 cmd.Flags().String( 84 "consensus.create-empty-blocks-interval", 85 config.Consensus.CreateEmptyBlocksInterval.String(), 86 "the possible interval between empty blocks") 87 88 // db flags 89 cmd.Flags().String( 90 "db-backend", 91 config.DBBackend, 92 "database backend: goleveldb | cleveldb | boltdb | rocksdb | badgerdb") 93 cmd.Flags().String( 94 "db-dir", 95 config.DBPath, 96 "database directory") 97 } 98 99 // NewRunNodeCmd returns the command that allows the CLI to start a node. 100 // It can be used with a custom PrivValidator and in-process ABCI application. 101 func NewRunNodeCmd(nodeProvider cfg.ServiceProvider) *cobra.Command { 102 cmd := &cobra.Command{ 103 Use: "start", 104 Aliases: []string{"node", "run"}, 105 Short: "Run the tendermint node", 106 RunE: func(cmd *cobra.Command, args []string) error { 107 if err := checkGenesisHash(config); err != nil { 108 return err 109 } 110 111 n, err := nodeProvider(config, logger) 112 if err != nil { 113 return fmt.Errorf("failed to create node: %w", err) 114 } 115 116 if err := n.Start(); err != nil { 117 return fmt.Errorf("failed to start node: %w", err) 118 } 119 120 logger.Info("started node", "node", n.String()) 121 122 // Stop upon receiving SIGTERM or CTRL-C. 123 tmos.TrapSignal(logger, func() { 124 if n.IsRunning() { 125 if err := n.Stop(); err != nil { 126 logger.Error("unable to stop the node", "error", err) 127 } 128 } 129 }) 130 131 // Run forever. 132 select {} 133 }, 134 } 135 136 AddNodeFlags(cmd) 137 return cmd 138 } 139 140 func checkGenesisHash(config *cfg.Config) error { 141 if len(genesisHash) == 0 || config.Genesis == "" { 142 return nil 143 } 144 145 // Calculate SHA-256 hash of the genesis file. 146 f, err := os.Open(config.GenesisFile()) 147 if err != nil { 148 return fmt.Errorf("can't open genesis file: %w", err) 149 } 150 defer f.Close() 151 h := ghash.New(ghash.H256) 152 if _, err := io.Copy(h, f); err != nil { 153 return fmt.Errorf("error when hashing genesis file: %w", err) 154 } 155 actualHash := h.Sum(nil) 156 157 // Compare with the flag. 158 if !bytes.Equal(genesisHash, actualHash) { 159 return fmt.Errorf( 160 "--genesis_hash=%X does not match %s hash: %X", 161 genesisHash, config.GenesisFile(), actualHash) 162 } 163 164 return nil 165 }