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