OSDN Git Service

Merge pull request #1829 from Bytom/dashboard
[bytom/bytom.git] / config / config.go
index 62b6e53..666b14f 100644 (file)
@@ -1,21 +1,33 @@
 package config
 
 import (
+       "io"
+       "io/ioutil"
        "os"
        "os/user"
        "path/filepath"
        "runtime"
-       "time"
+
+       log "github.com/sirupsen/logrus"
+
+       "github.com/bytom/bytom/crypto/ed25519"
+)
+
+var (
+       // CommonConfig means config object
+       CommonConfig *Config
 )
 
 type Config struct {
        // Top level options use an anonymous struct
        BaseConfig `mapstructure:",squash"`
        // Options for services
-       P2P    *P2PConfig     `mapstructure:"p2p"`
-       Wallet *WalletConfig  `mapstructure:"wallet"`
-       Auth   *RPCAuthConfig `mapstructure:"auth"`
-       Web    *WebConfig     `mapstructure:"web"`
+       P2P       *P2PConfig       `mapstructure:"p2p"`
+       Wallet    *WalletConfig    `mapstructure:"wallet"`
+       Auth      *RPCAuthConfig   `mapstructure:"auth"`
+       Web       *WebConfig       `mapstructure:"web"`
+       Simd      *SimdConfig      `mapstructure:"simd"`
+       Websocket *WebsocketConfig `mapstructure:"ws"`
 }
 
 // Default configurable parameters.
@@ -26,16 +38,48 @@ func DefaultConfig() *Config {
                Wallet:     DefaultWalletConfig(),
                Auth:       DefaultRPCAuthConfig(),
                Web:        DefaultWebConfig(),
+               Simd:       DefaultSimdConfig(),
+               Websocket:  DefaultWebsocketConfig(),
        }
 }
 
 // Set the RootDir for all Config structs
 func (cfg *Config) SetRoot(root string) *Config {
        cfg.BaseConfig.RootDir = root
-       cfg.P2P.RootDir = root
        return cfg
 }
 
+// NodeKey retrieves the currently configured private key of the node, checking
+// first any manually set key, falling back to the one found in the configured
+// data folder. If no key can be found, a new one is generated.
+func (cfg *Config) NodeKey() (string, error) {
+       // Use any specifically configured key.
+       if cfg.P2P.PrivateKey != "" {
+               return cfg.P2P.PrivateKey, nil
+       }
+
+       keyFile := rootify(cfg.P2P.NodeKeyFile, cfg.BaseConfig.RootDir)
+       buf := make([]byte, ed25519.PrivateKeySize*2)
+       fd, err := os.Open(keyFile)
+       defer fd.Close()
+       if err == nil {
+               if _, err = io.ReadFull(fd, buf); err == nil {
+                       return string(buf), nil
+               }
+       }
+
+       log.WithField("err", err).Warning("key file access failed")
+       _, privKey, err := ed25519.GenerateKey(nil)
+       if err != nil {
+               return "", err
+       }
+
+       if err = ioutil.WriteFile(keyFile, []byte(privKey.String()), 0600); err != nil {
+               return "", err
+       }
+       return privKey.String(), nil
+}
+
 //-----------------------------------------------------------------------------
 // BaseConfig
 type BaseConfig struct {
@@ -43,11 +87,14 @@ type BaseConfig struct {
        // This should be set in viper so it can unmarshal into this struct
        RootDir string `mapstructure:"home"`
 
+       //The alias of the node
+       NodeAlias string `mapstructure:"node_alias"`
+
        //The ID of the network to json
        ChainID string `mapstructure:"chain_id"`
 
-       // A JSON file containing the private key to use as a validator in the consensus protocol
-       PrivateKey string `mapstructure:"private_key"`
+       //log level to set
+       LogLevel string `mapstructure:"log_level"`
 
        // A custom human readable name for this node
        Moniker string `mapstructure:"moniker"`
@@ -55,18 +102,8 @@ type BaseConfig struct {
        // TCP or UNIX socket address for the profiling server to listen on
        ProfListenAddress string `mapstructure:"prof_laddr"`
 
-       // If this node is many blocks behind the tip of the chain, FastSync
-       // allows them to catchup quickly by downloading blocks in parallel
-       // and verifying their commits
-       FastSync bool `mapstructure:"fast_sync"`
-
        Mining bool `mapstructure:"mining"`
 
-       FilterPeers bool `mapstructure:"filter_peers"` // false
-
-       // What indexer to use for transactions
-       TxIndex string `mapstructure:"tx_index"`
-
        // Database backend: leveldb | memdb
        DBBackend string `mapstructure:"db_backend"`
 
@@ -76,15 +113,10 @@ type BaseConfig struct {
        // Keystore directory
        KeysPath string `mapstructure:"keys_dir"`
 
-       // remote HSM url
-       HsmUrl string `mapstructure:"hsm_url"`
-
        ApiAddress string `mapstructure:"api_addr"`
 
        VaultMode bool `mapstructure:"vault_mode"`
 
-       Time time.Time
-
        // log file name
        LogFile string `mapstructure:"log_file"`
 }
@@ -94,14 +126,12 @@ func DefaultBaseConfig() BaseConfig {
        return BaseConfig{
                Moniker:           "anonymous",
                ProfListenAddress: "",
-               FastSync:          true,
-               FilterPeers:       false,
                Mining:            false,
-               TxIndex:           "kv",
                DBBackend:         "leveldb",
                DBPath:            "data",
                KeysPath:          "keystore",
-               HsmUrl:            "",
+               NodeAlias:         "",
+               LogFile:           "log",
        }
 }
 
@@ -109,46 +139,53 @@ func (b BaseConfig) DBDir() string {
        return rootify(b.DBPath, b.RootDir)
 }
 
+func (b BaseConfig) LogDir() string {
+       return rootify(b.LogFile, b.RootDir)
+}
+
 func (b BaseConfig) KeysDir() string {
        return rootify(b.KeysPath, b.RootDir)
 }
 
 // P2PConfig
 type P2PConfig struct {
-       RootDir          string `mapstructure:"home"`
        ListenAddress    string `mapstructure:"laddr"`
        Seeds            string `mapstructure:"seeds"`
+       PrivateKey       string `mapstructure:"node_key"`
+       NodeKeyFile      string `mapstructure:"node_key_file"`
        SkipUPNP         bool   `mapstructure:"skip_upnp"`
-       AddrBook         string `mapstructure:"addr_book_file"`
-       AddrBookStrict   bool   `mapstructure:"addr_book_strict"`
-       PexReactor       bool   `mapstructure:"pex"`
+       LANDiscover      bool   `mapstructure:"lan_discoverable"`
        MaxNumPeers      int    `mapstructure:"max_num_peers"`
        HandshakeTimeout int    `mapstructure:"handshake_timeout"`
        DialTimeout      int    `mapstructure:"dial_timeout"`
+       ProxyAddress     string `mapstructure:"proxy_address"`
+       ProxyUsername    string `mapstructure:"proxy_username"`
+       ProxyPassword    string `mapstructure:"proxy_password"`
+       KeepDial         string `mapstructure:"keep_dial"`
 }
 
 // Default configurable p2p parameters.
 func DefaultP2PConfig() *P2PConfig {
        return &P2PConfig{
                ListenAddress:    "tcp://0.0.0.0:46656",
-               AddrBook:         "addrbook.json",
-               AddrBookStrict:   true,
+               NodeKeyFile:      "nodekey",
                SkipUPNP:         false,
+               LANDiscover:      true,
                MaxNumPeers:      50,
                HandshakeTimeout: 30,
                DialTimeout:      3,
-               PexReactor:       true,
+               ProxyAddress:     "",
+               ProxyUsername:    "",
+               ProxyPassword:    "",
        }
 }
 
-func (p *P2PConfig) AddrBookFile() string {
-       return rootify(p.AddrBook, p.RootDir)
-}
-
 //-----------------------------------------------------------------------------
 type WalletConfig struct {
-       Disable bool `mapstructure:"disable"`
-       Rescan  bool `mapstructure:"rescan"`
+       Disable  bool   `mapstructure:"disable"`
+       Rescan   bool   `mapstructure:"rescan"`
+       TxIndex  bool   `mapstructure:"txindex"`
+       MaxTxFee uint64 `mapstructure:"max_tx_fee"`
 }
 
 type RPCAuthConfig struct {
@@ -159,6 +196,15 @@ type WebConfig struct {
        Closed bool `mapstructure:"closed"`
 }
 
+type SimdConfig struct {
+       Enable bool `mapstructure:"enable"`
+}
+
+type WebsocketConfig struct {
+       MaxNumWebsockets     int `mapstructure:"max_num_websockets"`
+       MaxNumConcurrentReqs int `mapstructure:"max_num_concurrent_reqs"`
+}
+
 // Default configurable rpc's auth parameters.
 func DefaultRPCAuthConfig() *RPCAuthConfig {
        return &RPCAuthConfig{
@@ -176,8 +222,24 @@ func DefaultWebConfig() *WebConfig {
 // Default configurable wallet parameters.
 func DefaultWalletConfig() *WalletConfig {
        return &WalletConfig{
-               Disable: false,
-               Rescan:  false,
+               Disable:  false,
+               Rescan:   false,
+               TxIndex:  false,
+               MaxTxFee: uint64(1000000000),
+       }
+}
+
+// Default configurable web parameters.
+func DefaultSimdConfig() *SimdConfig {
+       return &SimdConfig{
+               Enable: false,
+       }
+}
+
+func DefaultWebsocketConfig() *WebsocketConfig {
+       return &WebsocketConfig{
+               MaxNumWebsockets:     25,
+               MaxNumConcurrentReqs: 20,
        }
 }
 
@@ -202,7 +264,17 @@ func DefaultDataDir() string {
        }
        switch runtime.GOOS {
        case "darwin":
-               return filepath.Join(home, "Library", "Bytom")
+               // In order to be compatible with old data path,
+               // copy the data from the old path to the new path
+               oldPath := filepath.Join(home, "Library", "Bytom")
+               newPath := filepath.Join(home, "Library", "Application Support", "Bytom")
+               if !isFolderNotExists(oldPath) && isFolderNotExists(newPath) {
+                       if err := os.Rename(oldPath, newPath); err != nil {
+                               log.Errorf("DefaultDataDir: %v", err)
+                               return oldPath
+                       }
+               }
+               return newPath
        case "windows":
                return filepath.Join(home, "AppData", "Roaming", "Bytom")
        default:
@@ -210,6 +282,11 @@ func DefaultDataDir() string {
        }
 }
 
+func isFolderNotExists(path string) bool {
+       _, err := os.Stat(path)
+       return os.IsNotExist(err)
+}
+
 func homeDir() string {
        if home := os.Getenv("HOME"); home != "" {
                return home