package config
import (
+ "encoding/hex"
+ "io"
"os"
"os/user"
"path/filepath"
"runtime"
log "github.com/sirupsen/logrus"
+
+ "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"`
- Side *SideChainConfig `mapstructure:"side"`
- MainChain *MainChainRpcConfig `mapstructure:"mainchain"`
- 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(),
- Side: DefaultSideChainConfig(),
- MainChain: DefaultMainChainRpc(),
Websocket: DefaultWebsocketConfig(),
+ Federation: DefaultFederationConfig(),
}
}
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) PrivateKey() *chainkd.XPrv {
+ if cfg.XPrv != nil {
+ return cfg.XPrv
+ }
+
+ 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")
+ }
+
+ 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")
+ }
+
+ var xprv chainkd.XPrv
+ if _, err := hex.Decode(xprv[:], buf); err != nil {
+ log.WithField("err", err).Panic("fail on decode private key")
+ }
+
+ cfg.XPrv = &xprv
+ xpub := cfg.XPrv.XPub()
+ cfg.XPub = &xpub
+ return cfg.XPrv
+}
+
//-----------------------------------------------------------------------------
// BaseConfig
type BaseConfig struct {
// log file name
LogFile string `mapstructure:"log_file"`
- //Validate pegin proof by checking bytom transaction inclusion in mainchain.
- ValidatePegin bool `mapstructure:"validate_pegin"`
- Signer string `mapstructure:"signer"`
+ 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",
+ 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"`
SkipUPNP bool `mapstructure:"skip_upnp"`
+ 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"`
+ Compression string `mapstructure:"compression_backend"`
}
// Default configurable p2p parameters.
func DefaultP2PConfig() *P2PConfig {
return &P2PConfig{
- ListenAddress: "tcp://0.0.0.0:46656",
+ ListenAddress: "tcp://0.0.0.0:56656",
SkipUPNP: false,
- MaxNumPeers: 50,
+ LANDiscover: true,
+ MaxNumPeers: 20,
HandshakeTimeout: 30,
DialTimeout: 3,
ProxyAddress: "",
ProxyUsername: "",
ProxyPassword: "",
+ Compression: "snappy",
}
}
type WalletConfig struct {
Disable bool `mapstructure:"disable"`
Rescan bool `mapstructure:"rescan"`
+ TxIndex bool `mapstructure:"txindex"`
MaxTxFee uint64 `mapstructure:"max_tx_fee"`
}
Closed bool `mapstructure:"closed"`
}
-type SideChainConfig struct {
- FedpegXPubs string `mapstructure:"fedpeg_xpubs"`
- SignBlockXPubs string `mapstructure:"sign_block_xpubs"`
- PeginMinDepth uint64 `mapstructure:"pegin_confirmation_depth"`
- ParentGenesisBlockHash string `mapstructure:"parent_genesis_block_hash"`
-}
-
-type MainChainRpcConfig struct {
- MainchainRpcHost string `mapstructure:"mainchain_rpc_host"`
- MainchainRpcPort string `mapstructure:"mainchain_rpc_port"`
- MainchainToken string `mapstructure:"mainchain_rpc_token"`
-}
-
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{
return &WalletConfig{
Disable: false,
Rescan: false,
+ TxIndex: false,
MaxTxFee: uint64(1000000000),
}
}
-// DeafultSideChainConfig for sidechain
-func DefaultSideChainConfig() *SideChainConfig {
- return &SideChainConfig{
- PeginMinDepth: 6,
- ParentGenesisBlockHash: "a75483474799ea1aa6bb910a1a5025b4372bf20bef20f246a2c2dc5e12e8a053",
+func DefaultWebsocketConfig() *WebsocketConfig {
+ return &WebsocketConfig{
+ MaxNumWebsockets: 25,
+ MaxNumConcurrentReqs: 20,
}
}
-func DefaultMainChainRpc() *MainChainRpcConfig {
- return &MainChainRpcConfig{
- MainchainRpcHost: "127.0.0.1",
- MainchainRpcPort: "9888",
+func DefaultFederationConfig() *FederationConfig {
+ return &FederationConfig{
+ Xpubs: []chainkd.XPub{
+ xpub("580daf48fa8962100047cb1391da890bb7f2c849fdbc9b368cb4394a4c7cbb0977e2e7ebbf055dc0ef90af6a0d2af01ce7ec56b735d016aab597815ec48552e5"),
+ xpub("f3f6bcf61b65fa9d1566455a5688ca8b395efdc22e654963134b5e5cb0a45d8be522d21abc384a73177a7b9d64eba915fcfe2862d86a508a3c46dc410bdd72ad"),
+ xpub("53559612f2b7bcada18948b7de39d63947a0e2bd7336d07db1350c54ba5743996b84bf9d18ff7a2457e1a5c70ce5013e4a3b62666ddb03294c53051d5f5c70c0"),
+ xpub("7c88cc58adfc71818b08308d43c29de22460b0ea6895449cbec6e458d7dc09e0aea243fa5075ee6621da0d805bd047f6bb207329c5bd2ca3253b172fb323b512"),
+ },
+ Quorum: 2,
}
}
-func DefaultWebsocketConfig() *WebsocketConfig {
- return &WebsocketConfig{
- MaxNumWebsockets: 25,
- MaxNumConcurrentReqs: 20,
+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
}
//-----------------------------------------------------------------------------
// Try to place the data folder in the user's home dir
home := homeDir()
if home == "" {
- return "./.bytom_sidechain"
+ 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_sidechain")
- newPath := filepath.Join(home, "Library", "Application Support", "Bytom_sidechain")
- 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_sidechain")
+ return filepath.Join(home, "AppData", "Roaming", "Vapor")
default:
- return filepath.Join(home, ".bytom_sidechain")
+ return filepath.Join(home, ".vapor")
}
}