OSDN Git Service

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