OSDN Git Service

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