OSDN Git Service

merge with master
[bytom/bytom.git] / config / config.go
1 package config
2
3 import (
4         "fmt"
5         "path/filepath"
6         "time"
7
8         "github.com/bytom/types"
9 )
10
11 type Config struct {
12         // Top level options use an anonymous struct
13         BaseConfig `mapstructure:",squash"`
14
15         // Options for services
16         RPC       *RPCConfig       `mapstructure:"rpc"`
17         P2P       *P2PConfig       `mapstructure:"p2p"`
18         Mempool   *MempoolConfig   `mapstructure:"mempool"`
19         Consensus *ConsensusConfig `mapstructure:"consensus"`
20 }
21
22 func DefaultConfig() *Config {
23         return &Config{
24                 BaseConfig: DefaultBaseConfig(),
25                 RPC:        DefaultRPCConfig(),
26                 P2P:        DefaultP2PConfig(),
27                 Mempool:    DefaultMempoolConfig(),
28                 Consensus:  DefaultConsensusConfig(),
29         }
30 }
31
32 func TestConfig() *Config {
33         return &Config{
34                 BaseConfig: TestBaseConfig(),
35                 RPC:        TestRPCConfig(),
36                 P2P:        TestP2PConfig(),
37                 Mempool:    DefaultMempoolConfig(),
38                 Consensus:  TestConsensusConfig(),
39         }
40 }
41
42 // Set the RootDir for all Config structs
43 func (cfg *Config) SetRoot(root string) *Config {
44         cfg.BaseConfig.RootDir = root
45         cfg.RPC.RootDir = root
46         cfg.P2P.RootDir = root
47         cfg.Mempool.RootDir = root
48         cfg.Consensus.RootDir = root
49         return cfg
50 }
51
52 //-----------------------------------------------------------------------------
53 // BaseConfig
54
55 // BaseConfig struct for a Tendermint node
56 type BaseConfig struct {
57         // The root directory for all data.
58         // This should be set in viper so it can unmarshal into this struct
59         RootDir string `mapstructure:"home"`
60
61         // The ID of the chain to join (should be signed with every transaction and vote)
62         ChainID string `mapstructure:"chain_id"`
63
64         // A JSON file containing the initial validator set and other meta data
65         Genesis string `mapstructure:"genesis_file"`
66
67         // A JSON file containing the private key to use as a validator in the consensus protocol
68         PrivValidator string `mapstructure:"priv_validator_file"`
69
70         // A custom human readable name for this node
71         Moniker string `mapstructure:"moniker"`
72
73         // TCP or UNIX socket address of the ABCI application,
74         // or the name of an ABCI application compiled in with the Tendermint binary
75         ProxyApp string `mapstructure:"proxy_app"`
76
77         // Mechanism to connect to the ABCI application: socket | grpc
78         ABCI string `mapstructure:"abci"`
79
80         // Output level for logging
81         LogLevel string `mapstructure:"log_level"`
82
83         // TCP or UNIX socket address for the profiling server to listen on
84         ProfListenAddress string `mapstructure:"prof_laddr"`
85
86         // If this node is many blocks behind the tip of the chain, FastSync
87         // allows them to catchup quickly by downloading blocks in parallel
88         // and verifying their commits
89         FastSync bool `mapstructure:"fast_sync"`
90
91         // If true, query the ABCI app on connecting to a new peer
92         // so the app can decide if we should keep the connection or not
93         FilterPeers bool `mapstructure:"filter_peers"` // false
94
95         // What indexer to use for transactions
96         TxIndex string `mapstructure:"tx_index"`
97
98         // Database backend: leveldb | memdb
99         DBBackend string `mapstructure:"db_backend"`
100
101         // Database directory
102         DBPath string `mapstructure:"db_dir"`
103 }
104
105 func DefaultBaseConfig() BaseConfig {
106         return BaseConfig{
107                 Genesis:           "genesis.json",
108                 PrivValidator:     "priv_validator.json",
109                 Moniker:           "anonymous",
110                 ProxyApp:          "tcp://127.0.0.1:46658",
111                 ABCI:              "socket",
112                 LogLevel:          DefaultPackageLogLevels(),
113                 ProfListenAddress: "",
114                 FastSync:          true,
115                 FilterPeers:       false,
116                 TxIndex:           "kv",
117                 DBBackend:         "leveldb",
118                 DBPath:            "data",
119         }
120 }
121
122 func TestBaseConfig() BaseConfig {
123         conf := DefaultBaseConfig()
124         conf.ChainID = "tendermint_test"
125         conf.ProxyApp = "dummy"
126         conf.FastSync = false
127         conf.DBBackend = "memdb"
128         return conf
129 }
130
131 func (b BaseConfig) GenesisFile() string {
132         return rootify(b.Genesis, b.RootDir)
133 }
134
135 func (b BaseConfig) PrivValidatorFile() string {
136         return rootify(b.PrivValidator, b.RootDir)
137 }
138
139 func (b BaseConfig) DBDir() string {
140         return rootify(b.DBPath, b.RootDir)
141 }
142
143 func DefaultLogLevel() string {
144         return "info"
145 }
146
147 func DefaultPackageLogLevels() string {
148         return fmt.Sprintf("state:info,*:%s", DefaultLogLevel())
149 }
150
151 //-----------------------------------------------------------------------------
152 // RPCConfig
153
154 type RPCConfig struct {
155         RootDir string `mapstructure:"home"`
156
157         // TCP or UNIX socket address for the RPC server to listen on
158         ListenAddress string `mapstructure:"laddr"`
159
160         // TCP or UNIX socket address for the gRPC server to listen on
161         // NOTE: This server only supports /broadcast_tx_commit
162         GRPCListenAddress string `mapstructure:"grpc_laddr"`
163
164         // Activate unsafe RPC commands like /dial_seeds and /unsafe_flush_mempool
165         Unsafe bool `mapstructure:"unsafe"`
166 }
167
168 func DefaultRPCConfig() *RPCConfig {
169         return &RPCConfig{
170                 ListenAddress:     "tcp://0.0.0.0:46657",
171                 GRPCListenAddress: "",
172                 Unsafe:            false,
173         }
174 }
175
176 func TestRPCConfig() *RPCConfig {
177         conf := DefaultRPCConfig()
178         conf.ListenAddress = "tcp://0.0.0.0:36657"
179         conf.GRPCListenAddress = "tcp://0.0.0.0:36658"
180         conf.Unsafe = true
181         return conf
182 }
183
184 //-----------------------------------------------------------------------------
185 // P2PConfig
186
187 type P2PConfig struct {
188         RootDir        string `mapstructure:"home"`
189         ListenAddress  string `mapstructure:"laddr"`
190         Seeds          string `mapstructure:"seeds"`
191         SkipUPNP       bool   `mapstructure:"skip_upnp"`
192         AddrBook       string `mapstructure:"addr_book_file"`
193         AddrBookStrict bool   `mapstructure:"addr_book_strict"`
194         PexReactor     bool   `mapstructure:"pex"`
195         MaxNumPeers    int    `mapstructure:"max_num_peers"`
196 }
197
198 func DefaultP2PConfig() *P2PConfig {
199         return &P2PConfig{
200                 ListenAddress:  "tcp://0.0.0.0:46656",
201                 AddrBook:       "addrbook.json",
202                 AddrBookStrict: true,
203                 MaxNumPeers:    50,
204         }
205 }
206
207 func TestP2PConfig() *P2PConfig {
208         conf := DefaultP2PConfig()
209         conf.ListenAddress = "tcp://0.0.0.0:36656"
210         conf.SkipUPNP = true
211         return conf
212 }
213
214 func (p *P2PConfig) AddrBookFile() string {
215         return rootify(p.AddrBook, p.RootDir)
216 }
217
218 //-----------------------------------------------------------------------------
219 // MempoolConfig
220
221 type MempoolConfig struct {
222         RootDir      string `mapstructure:"home"`
223         Recheck      bool   `mapstructure:"recheck"`
224         RecheckEmpty bool   `mapstructure:"recheck_empty"`
225         Broadcast    bool   `mapstructure:"broadcast"`
226         WalPath      string `mapstructure:"wal_dir"`
227 }
228
229 func DefaultMempoolConfig() *MempoolConfig {
230         return &MempoolConfig{
231                 Recheck:      true,
232                 RecheckEmpty: true,
233                 Broadcast:    true,
234                 WalPath:      "data/mempool.wal",
235         }
236 }
237
238 func (m *MempoolConfig) WalDir() string {
239         return rootify(m.WalPath, m.RootDir)
240 }
241
242 //-----------------------------------------------------------------------------
243 // ConsensusConfig
244
245 // ConsensusConfig holds timeouts and details about the WAL, the block structure,
246 // and timeouts in the consensus protocol.
247 type ConsensusConfig struct {
248         RootDir  string `mapstructure:"home"`
249         WalPath  string `mapstructure:"wal_file"`
250         WalLight bool   `mapstructure:"wal_light"`
251         walFile  string // overrides WalPath if set
252
253         // All timeouts are in ms
254         TimeoutPropose        int `mapstructure:"timeout_propose"`
255         TimeoutProposeDelta   int `mapstructure:"timeout_propose_delta"`
256         TimeoutPrevote        int `mapstructure:"timeout_prevote"`
257         TimeoutPrevoteDelta   int `mapstructure:"timeout_prevote_delta"`
258         TimeoutPrecommit      int `mapstructure:"timeout_precommit"`
259         TimeoutPrecommitDelta int `mapstructure:"timeout_precommit_delta"`
260         TimeoutCommit         int `mapstructure:"timeout_commit"`
261
262         // Make progress as soon as we have all the precommits (as if TimeoutCommit = 0)
263         SkipTimeoutCommit bool `mapstructure:"skip_timeout_commit"`
264
265         // BlockSize
266         MaxBlockSizeTxs   int `mapstructure:"max_block_size_txs"`
267         MaxBlockSizeBytes int `mapstructure:"max_block_size_bytes"`
268
269         // TODO: This probably shouldn't be exposed but it makes it
270         // easy to write tests for the wal/replay
271         BlockPartSize int `mapstructure:"block_part_size"`
272 }
273
274 // Wait this long for a proposal
275 func (cfg *ConsensusConfig) Propose(round int) time.Duration {
276         return time.Duration(cfg.TimeoutPropose+cfg.TimeoutProposeDelta*round) * time.Millisecond
277 }
278
279 // After receiving any +2/3 prevote, wait this long for stragglers
280 func (cfg *ConsensusConfig) Prevote(round int) time.Duration {
281         return time.Duration(cfg.TimeoutPrevote+cfg.TimeoutPrevoteDelta*round) * time.Millisecond
282 }
283
284 // After receiving any +2/3 precommits, wait this long for stragglers
285 func (cfg *ConsensusConfig) Precommit(round int) time.Duration {
286         return time.Duration(cfg.TimeoutPrecommit+cfg.TimeoutPrecommitDelta*round) * time.Millisecond
287 }
288
289 // After receiving +2/3 precommits for a single block (a commit), wait this long for stragglers in the next height's RoundStepNewHeight
290 func (cfg *ConsensusConfig) Commit(t time.Time) time.Time {
291         return t.Add(time.Duration(cfg.TimeoutCommit) * time.Millisecond)
292 }
293
294 func DefaultConsensusConfig() *ConsensusConfig {
295         return &ConsensusConfig{
296                 WalPath:               "data/cs.wal/wal",
297                 WalLight:              false,
298                 TimeoutPropose:        3000,
299                 TimeoutProposeDelta:   500,
300                 TimeoutPrevote:        1000,
301                 TimeoutPrevoteDelta:   500,
302                 TimeoutPrecommit:      1000,
303                 TimeoutPrecommitDelta: 500,
304                 TimeoutCommit:         1000,
305                 SkipTimeoutCommit:     false,
306                 MaxBlockSizeTxs:       10000,
307                 MaxBlockSizeBytes:     1,                          // TODO
308                 BlockPartSize:         types.DefaultBlockPartSize, // TODO: we shouldnt be importing types
309         }
310 }
311
312 func TestConsensusConfig() *ConsensusConfig {
313         config := DefaultConsensusConfig()
314         config.TimeoutPropose = 2000
315         config.TimeoutProposeDelta = 1
316         config.TimeoutPrevote = 10
317         config.TimeoutPrevoteDelta = 1
318         config.TimeoutPrecommit = 10
319         config.TimeoutPrecommitDelta = 1
320         config.TimeoutCommit = 10
321         config.SkipTimeoutCommit = true
322         return config
323 }
324
325 func (c *ConsensusConfig) WalFile() string {
326         if c.walFile != "" {
327                 return c.walFile
328         }
329         return rootify(c.WalPath, c.RootDir)
330 }
331
332 func (c *ConsensusConfig) SetWalFile(walFile string) {
333         c.walFile = walFile
334 }
335
336 //-----------------------------------------------------------------------------
337 // Utils
338
339 // helper function to make config creation independent of root dir
340 func rootify(path, root string) string {
341         if filepath.IsAbs(path) {
342                 return path
343         }
344         return filepath.Join(root, path)
345 }