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"`
}
// Default configurable p2p parameters.
return &P2PConfig{
ListenAddress: "tcp://0.0.0.0:46656",
SkipUPNP: false,
+ LANDiscover: true,
MaxNumPeers: 50,
HandshakeTimeout: 30,
DialTimeout: 3,
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("7f23aae65ee4307c38d342699e328f21834488e18191ebd66823d220b5a58303496c9d09731784372bade78d5e9a4a6249b2cfe2e3a85464e5a4017aa5611e47"),
+ xpub("585e20143db413e45fbc82f03cb61f177e9916ef1df0012daa8cbf6dbb1025ce8f98e51ae319327b63505b64fdbbf6d36ef916d79e6dd67d51b0bfe76fe544c5"),
+ xpub("b58170b51ca61604028ba1cb412377dfc2bc6567c0afc84c83aae1c0c297d0227ccf568561df70851f4144bbf069b525129f2434133c145e35949375b22a6c9d"),
+ },
+ 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")
}
}