11 log "github.com/sirupsen/logrus"
13 "github.com/bytom/vapor/crypto/ed25519/chainkd"
17 // CommonConfig means config object
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"`
35 // Default configurable parameters.
36 func DefaultConfig() *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(),
50 // Set the RootDir for all Config structs
51 func (cfg *Config) SetRoot(root string) *Config {
52 cfg.BaseConfig.RootDir = root
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 {
64 filePath := rootify(cfg.PrivateKeyFile, cfg.BaseConfig.RootDir)
65 fildReader, err := os.Open(filePath)
67 log.WithField("err", err).Panic("fail on open private key file")
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")
77 if _, err := hex.Decode(xprv[:], buf); err != nil {
78 log.WithField("err", err).Panic("fail on decode private key")
82 xpub := cfg.XPrv.XPub()
87 //-----------------------------------------------------------------------------
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"`
94 //The ID of the network to json
95 ChainID string `mapstructure:"chain_id"`
98 LogLevel string `mapstructure:"log_level"`
100 // A custom human readable name for this node
101 Moniker string `mapstructure:"moniker"`
103 // TCP or UNIX socket address for the profiling server to listen on
104 ProfListenAddress string `mapstructure:"prof_laddr"`
106 Mining bool `mapstructure:"mining"`
108 // Database backend: leveldb | memdb
109 DBBackend string `mapstructure:"db_backend"`
111 // Database directory
112 DBPath string `mapstructure:"db_dir"`
114 // Keystore directory
115 KeysPath string `mapstructure:"keys_dir"`
117 ApiAddress string `mapstructure:"api_addr"`
119 VaultMode bool `mapstructure:"vault_mode"`
122 LogFile string `mapstructure:"log_file"`
124 PrivateKeyFile string `mapstructure:"private_key_file"`
128 // Federation file name
129 FederationFileName string `mapstructure:"federation_file"`
132 // Default configurable base parameters.
133 func DefaultBaseConfig() BaseConfig {
135 Moniker: "anonymous",
136 ProfListenAddress: "",
138 DBBackend: "leveldb",
140 KeysPath: "keystore",
142 PrivateKeyFile: "node_key.txt",
143 FederationFileName: "federation.json",
147 func (b BaseConfig) DBDir() string {
148 return rootify(b.DBPath, b.RootDir)
151 func (b BaseConfig) LogDir() string {
152 return rootify(b.LogFile, b.RootDir)
155 func (b BaseConfig) KeysDir() string {
156 return rootify(b.KeysPath, b.RootDir)
159 func (b BaseConfig) FederationFile() string {
160 return rootify(b.FederationFileName, b.RootDir)
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"`
179 // Default configurable p2p parameters.
180 func DefaultP2PConfig() *P2PConfig {
182 ListenAddress: "tcp://0.0.0.0:56656",
186 HandshakeTimeout: 30,
191 Compression: "snappy",
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"`
203 type RPCAuthConfig struct {
204 Disable bool `mapstructure:"disable"`
207 type WebConfig struct {
208 Closed bool `mapstructure:"closed"`
211 type WebsocketConfig struct {
212 MaxNumWebsockets int `mapstructure:"max_num_websockets"`
213 MaxNumConcurrentReqs int `mapstructure:"max_num_concurrent_reqs"`
216 type FederationConfig struct {
217 Xpubs []chainkd.XPub `json:"xpubs"`
218 Quorum int `json:"quorum"`
221 type CrossChainConfig struct {
222 AssetWhitelist string `mapstructure:"asset_whitelist"`
225 type OssConfig struct {
226 Url string `mapstructure:"url"`
229 // Default configurable rpc's auth parameters.
230 func DefaultRPCAuthConfig() *RPCAuthConfig {
231 return &RPCAuthConfig{
236 // Default configurable web parameters.
237 func DefaultWebConfig() *WebConfig {
243 // Default configurable wallet parameters.
244 func DefaultWalletConfig() *WalletConfig {
245 return &WalletConfig{
249 MaxTxFee: uint64(1000000000),
253 // Default configurable websocket parameters.
254 func DefaultWebsocketConfig() *WebsocketConfig {
255 return &WebsocketConfig{
256 MaxNumWebsockets: 25,
257 MaxNumConcurrentReqs: 20,
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"),
274 // Default configurable crosschain parameters.
275 func DefaultCrossChainConfig() *CrossChainConfig {
276 return &CrossChainConfig{}
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")
286 // Default configurable oss parameters.
287 func DefaultOssConfig() *OssConfig {
291 //-----------------------------------------------------------------------------
294 // helper function to make config creation independent of root dir
295 func rootify(path, root string) string {
296 if filepath.IsAbs(path) {
299 return filepath.Join(root, path)
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
310 switch runtime.GOOS {
312 return filepath.Join(home, "Library", "Application Support", "Vapor")
314 return filepath.Join(home, "AppData", "Roaming", "Vapor")
316 return filepath.Join(home, ".vapor")
320 func isFolderNotExists(path string) bool {
321 _, err := os.Stat(path)
322 return os.IsNotExist(err)
325 func homeDir() string {
326 if home := os.Getenv("HOME"); home != "" {
329 if usr, err := user.Current(); err == nil {