OSDN Git Service

Merge pull request #27 from Bytom/dev_modify_code
[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
97 // Default configurable base parameters.
98 func DefaultBaseConfig() BaseConfig {
99         return BaseConfig{
100                 Moniker:           "anonymous",
101                 ProfListenAddress: "",
102                 Mining:            false,
103                 DBBackend:         "leveldb",
104                 DBPath:            "data",
105                 KeysPath:          "keystore",
106         }
107 }
108
109 func (b BaseConfig) DBDir() string {
110         return rootify(b.DBPath, b.RootDir)
111 }
112
113 func (b BaseConfig) KeysDir() string {
114         return rootify(b.KeysPath, b.RootDir)
115 }
116
117 // P2PConfig
118 type P2PConfig struct {
119         ListenAddress    string `mapstructure:"laddr"`
120         Seeds            string `mapstructure:"seeds"`
121         SkipUPNP         bool   `mapstructure:"skip_upnp"`
122         MaxNumPeers      int    `mapstructure:"max_num_peers"`
123         HandshakeTimeout int    `mapstructure:"handshake_timeout"`
124         DialTimeout      int    `mapstructure:"dial_timeout"`
125         ProxyAddress     string `mapstructure:"proxy_address"`
126         ProxyUsername    string `mapstructure:"proxy_username"`
127         ProxyPassword    string `mapstructure:"proxy_password"`
128 }
129
130 // Default configurable p2p parameters.
131 func DefaultP2PConfig() *P2PConfig {
132         return &P2PConfig{
133                 ListenAddress:    "tcp://0.0.0.0:46656",
134                 SkipUPNP:         false,
135                 MaxNumPeers:      50,
136                 HandshakeTimeout: 30,
137                 DialTimeout:      3,
138                 ProxyAddress:     "",
139                 ProxyUsername:    "",
140                 ProxyPassword:    "",
141         }
142 }
143
144 //-----------------------------------------------------------------------------
145 type WalletConfig struct {
146         Disable  bool   `mapstructure:"disable"`
147         Rescan   bool   `mapstructure:"rescan"`
148         MaxTxFee uint64 `mapstructure:"max_tx_fee"`
149 }
150
151 type RPCAuthConfig struct {
152         Disable bool `mapstructure:"disable"`
153 }
154
155 type WebConfig struct {
156         Closed bool `mapstructure:"closed"`
157 }
158
159 type SideChainConfig struct {
160         FedpegXPubs            string `mapstructure:"fedpeg_xpubs"`
161         SignBlockXPubs         string `mapstructure:"sign_block_xpubs"`
162         PeginMinDepth          uint64 `mapstructure:"pegin_confirmation_depth"`
163         ParentGenesisBlockHash string `mapstructure:"parent_genesis_block_hash"`
164 }
165
166 type MainChainRpcConfig struct {
167         MainchainRpcHost string `mapstructure:"mainchain_rpc_host"`
168         MainchainRpcPort string `mapstructure:"mainchain_rpc_port"`
169         MainchainToken   string `mapstructure:"mainchain_rpc_token"`
170 }
171
172 type WebsocketConfig struct {
173         MaxNumWebsockets     int `mapstructure:"max_num_websockets"`
174         MaxNumConcurrentReqs int `mapstructure:"max_num_concurrent_reqs"`
175 }
176
177 type ConsensusConfig struct {
178         Dpos *DposConfig `mapstructure:"dpos"`
179 }
180
181 type DposConfig struct {
182         Period           uint64   `json:"period"`            // Number of seconds between blocks to enforce
183         Epoch            uint64   `json:"epoch"`             // Epoch length to reset votes and checkpoint
184         MaxSignerCount   uint64   `json:"max_signers_count"` // Max count of signers
185         MinVoterBalance  uint64   `json:"min_boter_balance"` // Min voter balance to valid this vote
186         GenesisTimestamp uint64   `json:"genesis_timestamp"` // The LoopStartTime of first Block
187         Coinbase         string   `json:"coinbase"`
188         XPrv             string   `json:"xprv"`
189         SelfVoteSigners  []string `json:"signers"` // Signers vote by themselves to seal the block, make sure the signer accounts are pre-funded
190         Signers          []common.Address
191 }
192
193 // Default configurable rpc's auth parameters.
194 func DefaultRPCAuthConfig() *RPCAuthConfig {
195         return &RPCAuthConfig{
196                 Disable: false,
197         }
198 }
199
200 // Default configurable web parameters.
201 func DefaultWebConfig() *WebConfig {
202         return &WebConfig{
203                 Closed: false,
204         }
205 }
206
207 // Default configurable wallet parameters.
208 func DefaultWalletConfig() *WalletConfig {
209         return &WalletConfig{
210                 Disable:  false,
211                 Rescan:   false,
212                 MaxTxFee: uint64(1000000000),
213         }
214 }
215
216 // DeafultSideChainConfig for sidechain
217 func DefaultSideChainConfig() *SideChainConfig {
218         return &SideChainConfig{
219                 PeginMinDepth:          6,
220                 ParentGenesisBlockHash: "a75483474799ea1aa6bb910a1a5025b4372bf20bef20f246a2c2dc5e12e8a053",
221         }
222 }
223
224 func DefaultMainChainRpc() *MainChainRpcConfig {
225         return &MainChainRpcConfig{
226                 MainchainRpcHost: "127.0.0.1",
227                 MainchainRpcPort: "9888",
228         }
229 }
230
231 func DefaultWebsocketConfig() *WebsocketConfig {
232         return &WebsocketConfig{
233                 MaxNumWebsockets:     25,
234                 MaxNumConcurrentReqs: 20,
235         }
236 }
237
238 func DefaultDposConfig() *DposConfig {
239         return &DposConfig{
240                 Period:           1,
241                 Epoch:            300,
242                 MaxSignerCount:   1,
243                 MinVoterBalance:  0,
244                 GenesisTimestamp: 1524549600,
245         }
246 }
247
248 func DefaultConsensusCOnfig() *ConsensusConfig {
249         return &ConsensusConfig{Dpos: DefaultDposConfig()}
250 }
251
252 //-----------------------------------------------------------------------------
253 // Utils
254
255 // helper function to make config creation independent of root dir
256 func rootify(path, root string) string {
257         if filepath.IsAbs(path) {
258                 return path
259         }
260         return filepath.Join(root, path)
261 }
262
263 // DefaultDataDir is the default data directory to use for the databases and other
264 // persistence requirements.
265 func DefaultDataDir() string {
266         // Try to place the data folder in the user's home dir
267         home := homeDir()
268         if home == "" {
269                 return "./.bytom_sidechain"
270         }
271         switch runtime.GOOS {
272         case "darwin":
273                 // In order to be compatible with old data path,
274                 // copy the data from the old path to the new path
275                 oldPath := filepath.Join(home, "Library", "Bytom_sidechain")
276                 newPath := filepath.Join(home, "Library", "Application Support", "Bytom_sidechain")
277                 if !isFolderNotExists(oldPath) && isFolderNotExists(newPath) {
278                         if err := os.Rename(oldPath, newPath); err != nil {
279                                 log.Errorf("DefaultDataDir: %v", err)
280                                 return oldPath
281                         }
282                 }
283                 return newPath
284         case "windows":
285                 return filepath.Join(home, "AppData", "Roaming", "Bytom_sidechain")
286         default:
287                 return filepath.Join(home, ".bytom_sidechain")
288         }
289 }
290
291 func isFolderNotExists(path string) bool {
292         _, err := os.Stat(path)
293         return os.IsNotExist(err)
294 }
295
296 func homeDir() string {
297         if home := os.Getenv("HOME"); home != "" {
298                 return home
299         }
300         if usr, err := user.Current(); err == nil {
301                 return usr.HomeDir
302         }
303         return ""
304 }