OSDN Git Service

Peer add announces new block message num limit
[bytom/vapor.git] / config / config.go
1 package config
2
3 import (
4         "encoding/hex"
5         "io"
6         "os"
7         "os/user"
8         "path/filepath"
9         "runtime"
10
11         log "github.com/sirupsen/logrus"
12
13         "github.com/vapor/crypto/ed25519/chainkd"
14 )
15
16 var (
17         // CommonConfig means config object
18         CommonConfig *Config
19 )
20
21 type Config struct {
22         // Top level options use an anonymous struct
23         BaseConfig `mapstructure:",squash"`
24         // Options for services
25         P2P        *P2PConfig        `mapstructure:"p2p"`
26         Wallet     *WalletConfig     `mapstructure:"wallet"`
27         Auth       *RPCAuthConfig    `mapstructure:"auth"`
28         Web        *WebConfig        `mapstructure:"web"`
29         Websocket  *WebsocketConfig  `mapstructure:"ws"`
30         Federation *FederationConfig `mapstructure:"federation"`
31 }
32
33 // Default configurable parameters.
34 func DefaultConfig() *Config {
35         return &Config{
36                 BaseConfig: DefaultBaseConfig(),
37                 P2P:        DefaultP2PConfig(),
38                 Wallet:     DefaultWalletConfig(),
39                 Auth:       DefaultRPCAuthConfig(),
40                 Web:        DefaultWebConfig(),
41                 Websocket:  DefaultWebsocketConfig(),
42                 Federation: DefaultFederationConfig(),
43         }
44 }
45
46 // Set the RootDir for all Config structs
47 func (cfg *Config) SetRoot(root string) *Config {
48         cfg.BaseConfig.RootDir = root
49         return cfg
50 }
51
52 // NodeKey retrieves the currently configured private key of the node, checking
53 // first any manually set key, falling back to the one found in the configured
54 // data folder. If no key can be found, a new one is generated.
55 func (cfg *Config) PrivateKey() *chainkd.XPrv {
56         if cfg.XPrv != nil {
57                 return cfg.XPrv
58         }
59
60         filePath := rootify(cfg.PrivateKeyFile, cfg.BaseConfig.RootDir)
61         fildReader, err := os.Open(filePath)
62         if err != nil {
63                 log.WithField("err", err).Panic("fail on open private key file")
64         }
65
66         defer fildReader.Close()
67         buf := make([]byte, 128)
68         if _, err = io.ReadFull(fildReader, buf); err != nil {
69                 log.WithField("err", err).Panic("fail on read private key file")
70         }
71
72         var xprv chainkd.XPrv
73         if _, err := hex.Decode(xprv[:], buf); err != nil {
74                 log.WithField("err", err).Panic("fail on decode private key")
75         }
76
77         cfg.XPrv = &xprv
78         xpub := cfg.XPrv.XPub()
79         cfg.XPub = &xpub
80         return cfg.XPrv
81 }
82
83 //-----------------------------------------------------------------------------
84 // BaseConfig
85 type BaseConfig struct {
86         // The root directory for all data.
87         // This should be set in viper so it can unmarshal into this struct
88         RootDir string `mapstructure:"home"`
89
90         //The ID of the network to json
91         ChainID string `mapstructure:"chain_id"`
92
93         //log level to set
94         LogLevel string `mapstructure:"log_level"`
95
96         // A custom human readable name for this node
97         Moniker string `mapstructure:"moniker"`
98
99         // TCP or UNIX socket address for the profiling server to listen on
100         ProfListenAddress string `mapstructure:"prof_laddr"`
101
102         Mining bool `mapstructure:"mining"`
103
104         // Database backend: leveldb | memdb
105         DBBackend string `mapstructure:"db_backend"`
106
107         // Database directory
108         DBPath string `mapstructure:"db_dir"`
109
110         // Keystore directory
111         KeysPath string `mapstructure:"keys_dir"`
112
113         ApiAddress string `mapstructure:"api_addr"`
114
115         VaultMode bool `mapstructure:"vault_mode"`
116
117         // log file name
118         LogFile string `mapstructure:"log_file"`
119
120         PrivateKeyFile string `mapstructure:"private_key_file"`
121         XPrv           *chainkd.XPrv
122         XPub           *chainkd.XPub
123
124         // Federation file name
125         FederationFileName string `mapstructure:"federation_file"`
126 }
127
128 // Default configurable base parameters.
129 func DefaultBaseConfig() BaseConfig {
130         return BaseConfig{
131                 Moniker:            "anonymous",
132                 ProfListenAddress:  "",
133                 Mining:             false,
134                 DBBackend:          "leveldb",
135                 DBPath:             "data",
136                 KeysPath:           "keystore",
137                 LogFile:            "log",
138                 PrivateKeyFile:     "node_key.txt",
139                 FederationFileName: "federation.json",
140         }
141 }
142
143 func (b BaseConfig) DBDir() string {
144         return rootify(b.DBPath, b.RootDir)
145 }
146
147 func (b BaseConfig) LogDir() string {
148         return rootify(b.LogFile, b.RootDir)
149 }
150
151 func (b BaseConfig) KeysDir() string {
152         return rootify(b.KeysPath, b.RootDir)
153 }
154
155 func (b BaseConfig) FederationFile() string {
156         return rootify(b.FederationFileName, b.RootDir)
157 }
158
159 // P2PConfig
160 type P2PConfig struct {
161         ListenAddress    string `mapstructure:"laddr"`
162         Seeds            string `mapstructure:"seeds"`
163         SkipUPNP         bool   `mapstructure:"skip_upnp"`
164         LANDiscover      bool   `mapstructure:"lan_discoverable"`
165         MaxNumPeers      int    `mapstructure:"max_num_peers"`
166         HandshakeTimeout int    `mapstructure:"handshake_timeout"`
167         DialTimeout      int    `mapstructure:"dial_timeout"`
168         ProxyAddress     string `mapstructure:"proxy_address"`
169         ProxyUsername    string `mapstructure:"proxy_username"`
170         ProxyPassword    string `mapstructure:"proxy_password"`
171         KeepDial         string `mapstructure:"keep_dial"`
172         Compression      string `mapstructure:"compression_backend"`
173 }
174
175 // Default configurable p2p parameters.
176 func DefaultP2PConfig() *P2PConfig {
177         return &P2PConfig{
178                 ListenAddress:    "tcp://0.0.0.0:56656",
179                 SkipUPNP:         false,
180                 LANDiscover:      true,
181                 MaxNumPeers:      20,
182                 HandshakeTimeout: 30,
183                 DialTimeout:      3,
184                 ProxyAddress:     "",
185                 ProxyUsername:    "",
186                 ProxyPassword:    "",
187                 Compression:      "snappy",
188         }
189 }
190
191 //-----------------------------------------------------------------------------
192 type WalletConfig struct {
193         Disable  bool   `mapstructure:"disable"`
194         Rescan   bool   `mapstructure:"rescan"`
195         TxIndex  bool   `mapstructure:"txindex"`
196         MaxTxFee uint64 `mapstructure:"max_tx_fee"`
197 }
198
199 type RPCAuthConfig struct {
200         Disable bool `mapstructure:"disable"`
201 }
202
203 type WebConfig struct {
204         Closed bool `mapstructure:"closed"`
205 }
206
207 type WebsocketConfig struct {
208         MaxNumWebsockets     int `mapstructure:"max_num_websockets"`
209         MaxNumConcurrentReqs int `mapstructure:"max_num_concurrent_reqs"`
210 }
211
212 type FederationConfig struct {
213         Xpubs  []chainkd.XPub `json:"xpubs"`
214         Quorum int            `json:"quorum"`
215 }
216
217 // Default configurable rpc's auth parameters.
218 func DefaultRPCAuthConfig() *RPCAuthConfig {
219         return &RPCAuthConfig{
220                 Disable: false,
221         }
222 }
223
224 // Default configurable web parameters.
225 func DefaultWebConfig() *WebConfig {
226         return &WebConfig{
227                 Closed: false,
228         }
229 }
230
231 // Default configurable wallet parameters.
232 func DefaultWalletConfig() *WalletConfig {
233         return &WalletConfig{
234                 Disable:  false,
235                 Rescan:   false,
236                 TxIndex:  false,
237                 MaxTxFee: uint64(1000000000),
238         }
239 }
240
241 func DefaultWebsocketConfig() *WebsocketConfig {
242         return &WebsocketConfig{
243                 MaxNumWebsockets:     25,
244                 MaxNumConcurrentReqs: 20,
245         }
246 }
247
248 func DefaultFederationConfig() *FederationConfig {
249         return &FederationConfig{
250                 Xpubs: []chainkd.XPub{
251                         xpub("580daf48fa8962100047cb1391da890bb7f2c849fdbc9b368cb4394a4c7cbb0977e2e7ebbf055dc0ef90af6a0d2af01ce7ec56b735d016aab597815ec48552e5"),
252                         xpub("f3f6bcf61b65fa9d1566455a5688ca8b395efdc22e654963134b5e5cb0a45d8be522d21abc384a73177a7b9d64eba915fcfe2862d86a508a3c46dc410bdd72ad"),
253                         xpub("53559612f2b7bcada18948b7de39d63947a0e2bd7336d07db1350c54ba5743996b84bf9d18ff7a2457e1a5c70ce5013e4a3b62666ddb03294c53051d5f5c70c0"),
254                         xpub("7c88cc58adfc71818b08308d43c29de22460b0ea6895449cbec6e458d7dc09e0aea243fa5075ee6621da0d805bd047f6bb207329c5bd2ca3253b172fb323b512"),
255                 },
256                 Quorum: 2,
257         }
258 }
259
260 func xpub(str string) (xpub chainkd.XPub) {
261         if err := xpub.UnmarshalText([]byte(str)); err != nil {
262                 log.Panicf("Fail converts a string to xpub")
263         }
264         return xpub
265 }
266
267 //-----------------------------------------------------------------------------
268 // Utils
269
270 // helper function to make config creation independent of root dir
271 func rootify(path, root string) string {
272         if filepath.IsAbs(path) {
273                 return path
274         }
275         return filepath.Join(root, path)
276 }
277
278 // DefaultDataDir is the default data directory to use for the databases and other
279 // persistence requirements.
280 func DefaultDataDir() string {
281         // Try to place the data folder in the user's home dir
282         home := homeDir()
283         if home == "" {
284                 return "./.vapor"
285         }
286         switch runtime.GOOS {
287         case "darwin":
288                 return filepath.Join(home, "Library", "Application Support", "Vapor")
289         case "windows":
290                 return filepath.Join(home, "AppData", "Roaming", "Vapor")
291         default:
292                 return filepath.Join(home, ".vapor")
293         }
294 }
295
296 func isFolderNotExists(path string) bool {
297         _, err := os.Stat(path)
298         return os.IsNotExist(err)
299 }
300
301 func homeDir() string {
302         if home := os.Getenv("HOME"); home != "" {
303                 return home
304         }
305         if usr, err := user.Current(); err == nil {
306                 return usr.HomeDir
307         }
308         return ""
309 }