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 }