package config
import (
+ "encoding/hex"
"io"
- "io/ioutil"
"os"
"os/user"
"path/filepath"
log "github.com/sirupsen/logrus"
- "github.com/vapor/crypto/ed25519"
+ "github.com/vapor/crypto/ed25519/chainkd"
)
var (
// 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"`
- Simd *SimdConfig `mapstructure:"simd"`
- Websocket *WebsocketConfig `mapstructure:"ws"`
+ P2P *P2PConfig `mapstructure:"p2p"`
+ Wallet *WalletConfig `mapstructure:"wallet"`
+ Auth *RPCAuthConfig `mapstructure:"auth"`
+ Web *WebConfig `mapstructure:"web"`
+ Websocket *WebsocketConfig `mapstructure:"ws"`
+ Federation *FederationConfig `mapstructure:"federation"`
}
// Default configurable parameters.
Wallet: DefaultWalletConfig(),
Auth: DefaultRPCAuthConfig(),
Web: DefaultWebConfig(),
- Simd: DefaultSimdConfig(),
Websocket: DefaultWebsocketConfig(),
+ Federation: DefaultFederationConfig(),
}
}
// 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
+func (cfg *Config) PrivateKey() *chainkd.XPrv {
+ if cfg.XPrv != nil {
+ return cfg.XPrv
}
- 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
- }
+ filePath := rootify(cfg.PrivateKeyFile, cfg.BaseConfig.RootDir)
+ fildReader, err := os.Open(filePath)
+ if err != nil {
+ log.WithField("err", err).Panic("fail on open private key file")
}
- log.WithField("err", err).Warning("key file access failed")
- _, privKey, err := ed25519.GenerateKey(nil)
- if err != nil {
- return "", err
+ defer fildReader.Close()
+ buf := make([]byte, 128)
+ if _, err = io.ReadFull(fildReader, buf); err != nil {
+ log.WithField("err", err).Panic("fail on read private key file")
}
- if err = ioutil.WriteFile(keyFile, []byte(privKey.String()), 0600); err != nil {
- return "", err
+ var xprv chainkd.XPrv
+ if _, err := hex.Decode(xprv[:], buf); err != nil {
+ log.WithField("err", err).Panic("fail on decode private key")
}
- return privKey.String(), nil
+
+ cfg.XPrv = &xprv
+ xpub := cfg.XPrv.XPub()
+ cfg.XPub = &xpub
+ return cfg.XPrv
}
//-----------------------------------------------------------------------------
// 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"`
// log file name
LogFile string `mapstructure:"log_file"`
+
+ PrivateKeyFile string `mapstructure:"private_key_file"`
+ XPrv *chainkd.XPrv
+ XPub *chainkd.XPub
+
+ // Federation file name
+ FederationFileName string `mapstructure:"federation_file"`
}
// Default configurable base parameters.
func DefaultBaseConfig() BaseConfig {
return BaseConfig{
- Moniker: "anonymous",
- ProfListenAddress: "",
- Mining: false,
- DBBackend: "leveldb",
- DBPath: "data",
- KeysPath: "keystore",
- NodeAlias: "",
+ Moniker: "anonymous",
+ ProfListenAddress: "",
+ Mining: false,
+ DBBackend: "leveldb",
+ DBPath: "data",
+ KeysPath: "keystore",
+ PrivateKeyFile: "node_key.txt",
+ FederationFileName: "federation.json",
}
}
return rootify(b.KeysPath, b.RootDir)
}
+func (b BaseConfig) FederationFile() string {
+ return rootify(b.FederationFileName, b.RootDir)
+}
+
// P2PConfig
type P2PConfig struct {
ListenAddress string `mapstructure:"laddr"`
Seeds string `mapstructure:"seeds"`
- PrivateKey string `mapstructure:"node_key"`
- NodeKeyFile string `mapstructure:"node_key_file"`
SkipUPNP bool `mapstructure:"skip_upnp"`
LANDiscover bool `mapstructure:"lan_discoverable"`
MaxNumPeers int `mapstructure:"max_num_peers"`
ProxyUsername string `mapstructure:"proxy_username"`
ProxyPassword string `mapstructure:"proxy_password"`
KeepDial string `mapstructure:"keep_dial"`
+ Compression string `mapstructure:"compression_backend"`
}
// Default configurable p2p parameters.
func DefaultP2PConfig() *P2PConfig {
return &P2PConfig{
ListenAddress: "tcp://0.0.0.0:46656",
- NodeKeyFile: "nodekey",
SkipUPNP: false,
LANDiscover: true,
MaxNumPeers: 50,
ProxyAddress: "",
ProxyUsername: "",
ProxyPassword: "",
+ Compression: "snappy",
}
}
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"`
}
+type FederationConfig struct {
+ Xpubs []chainkd.XPub `json:"xpubs"`
+ Quorum int `json:"quorum"`
+}
+
// Default configurable rpc's auth parameters.
func DefaultRPCAuthConfig() *RPCAuthConfig {
return &RPCAuthConfig{
}
}
-// Default configurable web parameters.
-func DefaultSimdConfig() *SimdConfig {
- return &SimdConfig{
- Enable: false,
- }
-}
-
func DefaultWebsocketConfig() *WebsocketConfig {
return &WebsocketConfig{
MaxNumWebsockets: 25,
}
}
+func DefaultFederationConfig() *FederationConfig {
+ return &FederationConfig{
+ Xpubs: []chainkd.XPub{
+ xpub("50ef22b3a3fca7bc08916187cc9ec2f4005c9c6b1353aa1decbd4be3f3bb0fbe1967589f0d9dec13a388c0412002d2c267bdf3b920864e1ddc50581be5604ce1"),
+ },
+ Quorum: 1,
+ }
+}
+
+func xpub(str string) (xpub chainkd.XPub) {
+ if err := xpub.UnmarshalText([]byte(str)); err != nil {
+ log.Panicf("Fail converts a string to xpub")
+ }
+ return xpub
+}
+
//-----------------------------------------------------------------------------
// Utils
// Try to place the data folder in the user's home dir
home := homeDir()
if home == "" {
- return "./.bytom"
+ return "./.vapor"
}
switch runtime.GOOS {
case "darwin":
- // 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
+ return filepath.Join(home, "Library", "Application Support", "Vapor")
case "windows":
- return filepath.Join(home, "AppData", "Roaming", "Bytom")
+ return filepath.Join(home, "AppData", "Roaming", "Vapor")
default:
- return filepath.Join(home, ".bytom")
+ return filepath.Join(home, ".vapor")
}
}