OSDN Git Service

7e382170414698bd6d4fc91d8c8e6fdafeca9316
[bytom/vapor.git] / config / config.go
1 package config
2
3 import (
4         "os"
5         "os/user"
6         "path/filepath"
7         "runtime"
8
9         log "github.com/sirupsen/logrus"
10         "github.com/vapor/common"
11 )
12
13 var (
14         // CommonConfig means config object
15         CommonConfig *Config
16 )
17
18 type Config struct {
19         // Top level options use an anonymous struct
20         BaseConfig `mapstructure:",squash"`
21         // Options for services
22         P2P       *P2PConfig          `mapstructure:"p2p"`
23         Wallet    *WalletConfig       `mapstructure:"wallet"`
24         Auth      *RPCAuthConfig      `mapstructure:"auth"`
25         Web       *WebConfig          `mapstructure:"web"`
26         Side      *SideChainConfig    `mapstructure:"side"`
27         MainChain *MainChainRpcConfig `mapstructure:"mainchain"`
28         Websocket *WebsocketConfig    `mapstructure:"ws"`
29         Consensus *ConsensusConfig    `mapstructure:"consensus"`
30 }
31
32 // Default configurable parameters.
33 func DefaultConfig() *Config {
34         return &Config{
35                 BaseConfig: DefaultBaseConfig(),
36                 P2P:        DefaultP2PConfig(),
37                 Wallet:     DefaultWalletConfig(),
38                 Auth:       DefaultRPCAuthConfig(),
39                 Web:        DefaultWebConfig(),
40                 Side:       DefaultSideChainConfig(),
41                 MainChain:  DefaultMainChainRpc(),
42                 Websocket:  DefaultWebsocketConfig(),
43                 Consensus:  DefaultConsensusCOnfig(),
44         }
45 }
46
47 // Set the RootDir for all Config structs
48 func (cfg *Config) SetRoot(root string) *Config {
49         cfg.BaseConfig.RootDir = root
50         return cfg
51 }
52
53 //-----------------------------------------------------------------------------
54 // BaseConfig
55 type BaseConfig struct {
56         // The root directory for all data.
57         // This should be set in viper so it can unmarshal into this struct
58         RootDir string `mapstructure:"home"`
59
60         //The ID of the network to json
61         ChainID string `mapstructure:"chain_id"`
62
63         //log level to set
64         LogLevel string `mapstructure:"log_level"`
65
66         // A custom human readable name for this node
67         Moniker string `mapstructure:"moniker"`
68
69         // TCP or UNIX socket address for the profiling server to listen on
70         ProfListenAddress string `mapstructure:"prof_laddr"`
71
72         Mining bool `mapstructure:"mining"`
73
74         // Database backend: leveldb | memdb
75         DBBackend string `mapstructure:"db_backend"`
76
77         // Database directory
78         DBPath string `mapstructure:"db_dir"`
79
80         // Keystore directory
81         KeysPath string `mapstructure:"keys_dir"`
82
83         ApiAddress string `mapstructure:"api_addr"`
84
85         VaultMode bool `mapstructure:"vault_mode"`
86
87         // log file name
88         LogFile string `mapstructure:"log_file"`
89
90         // Validate pegin proof by checking bytom transaction inclusion in mainchain.
91         ValidatePegin bool   `mapstructure:"validate_pegin"`
92         Signer        string `mapstructure:"signer"`
93
94         ConsensusConfigFile string `mapstructure:"consensus_config_file"`
95
96         IpfsAddress string `mapstructure:"ipfs_addr"`
97 }
98
99 // Default configurable base parameters.
100 func DefaultBaseConfig() BaseConfig {
101         return BaseConfig{
102                 Moniker:           "anonymous",
103                 ProfListenAddress: "",
104                 Mining:            false,
105                 DBBackend:         "leveldb",
106                 DBPath:            "data",
107                 KeysPath:          "keystore",
108                 IpfsAddress:       "127.0.0.1:5001",
109         }
110 }
111
112 func (b BaseConfig) DBDir() string {
113         return rootify(b.DBPath, b.RootDir)
114 }
115
116 func (b BaseConfig) KeysDir() string {
117         return rootify(b.KeysPath, b.RootDir)
118 }
119
120 // P2PConfig
121 type P2PConfig struct {
122         ListenAddress    string `mapstructure:"laddr"`
123         Seeds            string `mapstructure:"seeds"`
124         SkipUPNP         bool   `mapstructure:"skip_upnp"`
125         MaxNumPeers      int    `mapstructure:"max_num_peers"`
126         HandshakeTimeout int    `mapstructure:"handshake_timeout"`
127         DialTimeout      int    `mapstructure:"dial_timeout"`
128         ProxyAddress     string `mapstructure:"proxy_address"`
129         ProxyUsername    string `mapstructure:"proxy_username"`
130         ProxyPassword    string `mapstructure:"proxy_password"`
131 }
132
133 // Default configurable p2p parameters.
134 func DefaultP2PConfig() *P2PConfig {
135         return &P2PConfig{
136                 ListenAddress:    "tcp://0.0.0.0:46656",
137                 SkipUPNP:         false,
138                 MaxNumPeers:      50,
139                 HandshakeTimeout: 30,
140                 DialTimeout:      3,
141                 ProxyAddress:     "",
142                 ProxyUsername:    "",
143                 ProxyPassword:    "",
144         }
145 }
146
147 //-----------------------------------------------------------------------------
148 type WalletConfig struct {
149         Disable  bool   `mapstructure:"disable"`
150         Rescan   bool   `mapstructure:"rescan"`
151         MaxTxFee uint64 `mapstructure:"max_tx_fee"`
152 }
153
154 type RPCAuthConfig struct {
155         Disable bool `mapstructure:"disable"`
156 }
157
158 type WebConfig struct {
159         Closed bool `mapstructure:"closed"`
160 }
161
162 type SideChainConfig struct {
163         FedpegXPubs            string `mapstructure:"fedpeg_xpubs"`
164         SignBlockXPubs         string `mapstructure:"sign_block_xpubs"`
165         PeginMinDepth          uint64 `mapstructure:"pegin_confirmation_depth"`
166         ParentGenesisBlockHash string `mapstructure:"parent_genesis_block_hash"`
167 }
168
169 type MainChainRpcConfig struct {
170         MainchainRpcHost string `mapstructure:"mainchain_rpc_host"`
171         MainchainRpcPort string `mapstructure:"mainchain_rpc_port"`
172         MainchainToken   string `mapstructure:"mainchain_rpc_token"`
173 }
174
175 type WebsocketConfig struct {
176         MaxNumWebsockets     int `mapstructure:"max_num_websockets"`
177         MaxNumConcurrentReqs int `mapstructure:"max_num_concurrent_reqs"`
178 }
179
180 type ConsensusConfig struct {
181         Dpos *DposConfig `mapstructure:"dpos"`
182 }
183
184 type DposConfig struct {
185         Period           uint64   `json:"period"`            // Number of seconds between blocks to enforce
186         Epoch            uint64   `json:"epoch"`             // Epoch length to reset votes and checkpoint
187         MaxSignerCount   uint64   `json:"max_signers_count"` // Max count of signers
188         MinVoterBalance  uint64   `json:"min_boter_balance"` // Min voter balance to valid this vote
189         GenesisTimestamp uint64   `json:"genesis_timestamp"` // The LoopStartTime of first Block
190         Coinbase         string   `json:"coinbase"`
191         XPrv             string   `json:"xprv"`
192         SelfVoteSigners  []string `json:"signers"` // Signers vote by themselves to seal the block, make sure the signer accounts are pre-funded
193         Signers          []common.Address
194 }
195
196 // Default configurable rpc's auth parameters.
197 func DefaultRPCAuthConfig() *RPCAuthConfig {
198         return &RPCAuthConfig{
199                 Disable: false,
200         }
201 }
202
203 // Default configurable web parameters.
204 func DefaultWebConfig() *WebConfig {
205         return &WebConfig{
206                 Closed: false,
207         }
208 }
209
210 // Default configurable wallet parameters.
211 func DefaultWalletConfig() *WalletConfig {
212         return &WalletConfig{
213                 Disable:  false,
214                 Rescan:   false,
215                 MaxTxFee: uint64(1000000000),
216         }
217 }
218
219 // DeafultSideChainConfig for sidechain
220 func DefaultSideChainConfig() *SideChainConfig {
221         return &SideChainConfig{
222                 PeginMinDepth:          6,
223                 ParentGenesisBlockHash: "a75483474799ea1aa6bb910a1a5025b4372bf20bef20f246a2c2dc5e12e8a053",
224         }
225 }
226
227 func DefaultMainChainRpc() *MainChainRpcConfig {
228         return &MainChainRpcConfig{
229                 MainchainRpcHost: "127.0.0.1",
230                 MainchainRpcPort: "9888",
231         }
232 }
233
234 func DefaultWebsocketConfig() *WebsocketConfig {
235         return &WebsocketConfig{
236                 MaxNumWebsockets:     25,
237                 MaxNumConcurrentReqs: 20,
238         }
239 }
240
241 func DefaultDposConfig() *DposConfig {
242         return &DposConfig{
243                 Period:           1,
244                 Epoch:            300,
245                 MaxSignerCount:   1,
246                 MinVoterBalance:  0,
247                 GenesisTimestamp: 1524549600,
248         }
249 }
250
251 func DefaultConsensusCOnfig() *ConsensusConfig {
252         return &ConsensusConfig{Dpos: DefaultDposConfig()}
253 }
254
255 //-----------------------------------------------------------------------------
256 // Utils
257
258 // helper function to make config creation independent of root dir
259 func rootify(path, root string) string {
260         if filepath.IsAbs(path) {
261                 return path
262         }
263         return filepath.Join(root, path)
264 }
265
266 // DefaultDataDir is the default data directory to use for the databases and other
267 // persistence requirements.
268 func DefaultDataDir() string {
269         // Try to place the data folder in the user's home dir
270         home := homeDir()
271         if home == "" {
272                 return "./.bytom_sidechain"
273         }
274         switch runtime.GOOS {
275         case "darwin":
276                 // In order to be compatible with old data path,
277                 // copy the data from the old path to the new path
278                 oldPath := filepath.Join(home, "Library", "Bytom_sidechain")
279                 newPath := filepath.Join(home, "Library", "Application Support", "Bytom_sidechain")
280                 if !isFolderNotExists(oldPath) && isFolderNotExists(newPath) {
281                         if err := os.Rename(oldPath, newPath); err != nil {
282                                 log.Errorf("DefaultDataDir: %v", err)
283                                 return oldPath
284                         }
285                 }
286                 return newPath
287         case "windows":
288                 return filepath.Join(home, "AppData", "Roaming", "Bytom_sidechain")
289         default:
290                 return filepath.Join(home, ".bytom_sidechain")
291         }
292 }
293
294 func isFolderNotExists(path string) bool {
295         _, err := os.Stat(path)
296         return os.IsNotExist(err)
297 }
298
299 func homeDir() string {
300         if home := os.Getenv("HOME"); home != "" {
301                 return home
302         }
303         if usr, err := user.Current(); err == nil {
304                 return usr.HomeDir
305         }
306         return ""
307 }