gecko/main/params.go

312 lines
10 KiB
Go
Raw Normal View History

2020-03-10 12:20:34 -07:00
// (c) 2019-2020, Ava Labs, Inc. All rights reserved.
// See the file LICENSE for licensing terms.
package main
import (
"errors"
"flag"
"fmt"
"net"
"os"
2020-03-10 12:20:34 -07:00
"path"
"path/filepath"
2020-03-10 12:20:34 -07:00
"strings"
"github.com/ava-labs/gecko/database/leveldb"
"github.com/ava-labs/gecko/database/memdb"
"github.com/ava-labs/gecko/genesis"
"github.com/ava-labs/gecko/ids"
"github.com/ava-labs/gecko/nat"
2020-03-10 12:20:34 -07:00
"github.com/ava-labs/gecko/node"
"github.com/ava-labs/gecko/snow/networking/router"
"github.com/ava-labs/gecko/staking"
2020-03-10 12:20:34 -07:00
"github.com/ava-labs/gecko/utils"
"github.com/ava-labs/gecko/utils/formatting"
"github.com/ava-labs/gecko/utils/hashing"
"github.com/ava-labs/gecko/utils/logging"
"github.com/ava-labs/gecko/utils/wrappers"
)
2020-04-24 11:44:04 -07:00
const (
2020-05-30 10:35:46 -07:00
dbVersion = "v0.4.0"
2020-04-24 11:44:04 -07:00
)
2020-03-10 12:20:34 -07:00
// Results of parsing the CLI
var (
Config = node.Config{}
Err error
defaultDbDir = os.ExpandEnv(filepath.Join("$HOME", ".gecko", "db"))
defaultStakingKeyPath = os.ExpandEnv(filepath.Join("$HOME", ".gecko", "staking", "staker.key"))
defaultStakingCertPath = os.ExpandEnv(filepath.Join("$HOME", ".gecko", "staking", "staker.crt"))
)
var (
errBootstrapMismatch = errors.New("more bootstrap IDs provided than bootstrap IPs")
2020-03-10 12:20:34 -07:00
)
2020-04-02 20:43:02 -07:00
// GetIPs returns the default IPs for each network
func GetIPs(networkID uint32) []string {
switch networkID {
2020-05-30 13:31:43 -07:00
case genesis.DenaliID:
return []string{
"3.133.117.223:21001",
"18.224.140.156:21001",
"3.133.83.66:21001",
"3.133.131.39:21001",
"18.188.121.35:21001",
}
2020-04-17 00:51:14 -07:00
case genesis.CascadeID:
return []string{
"3.227.207.132:21001",
"34.207.133.167:21001",
2020-05-25 14:57:22 -07:00
"54.162.71.9:21001",
2020-04-17 00:51:14 -07:00
"54.197.215.186:21001",
"18.234.153.22:21001",
}
2020-04-02 20:43:02 -07:00
default:
return nil
2020-03-31 15:32:10 -07:00
}
2020-04-02 20:43:02 -07:00
}
2020-03-31 15:32:10 -07:00
2020-03-10 12:20:34 -07:00
// Parse the CLI arguments
func init() {
errs := &wrappers.Errs{}
defer func() { Err = errs.Err }()
loggingConfig, err := logging.DefaultConfig()
if errs.Add(err); errs.Errored() {
return
}
2020-03-10 12:20:34 -07:00
fs := flag.NewFlagSet("gecko", flag.ContinueOnError)
2020-03-10 12:20:34 -07:00
// NetworkID:
2020-05-30 12:50:37 -07:00
networkName := fs.String("network-id", genesis.TestnetName, "Network ID this node will connect to")
2020-03-10 12:20:34 -07:00
// Ava fees:
fs.Uint64Var(&Config.AvaTxFee, "ava-tx-fee", 0, "Ava transaction fee, in $nAva")
2020-03-10 12:20:34 -07:00
// Assertions:
fs.BoolVar(&loggingConfig.Assertions, "assertions-enabled", true, "Turn on assertion execution")
2020-03-10 12:20:34 -07:00
// Crypto:
fs.BoolVar(&Config.EnableCrypto, "signature-verification-enabled", true, "Turn on signature verification")
2020-03-10 12:20:34 -07:00
// Database:
db := fs.Bool("db-enabled", true, "Turn on persistent storage")
2020-04-29 10:44:25 -07:00
dbDir := fs.String("db-dir", defaultDbDir, "Database directory for Ava state")
2020-03-10 12:20:34 -07:00
// IP:
consensusIP := fs.String("public-ip", "", "Public IP of this node")
2020-03-10 12:20:34 -07:00
// HTTP Server:
httpHost := fs.String("http-host", "", "Address of the HTTP server")
httpPort := fs.Uint("http-port", 9650, "Port of the HTTP server")
fs.BoolVar(&Config.EnableHTTPS, "http-tls-enabled", false, "Upgrade the HTTP server to HTTPs")
fs.StringVar(&Config.HTTPSKeyFile, "http-tls-key-file", "", "TLS private key file for the HTTPs server")
fs.StringVar(&Config.HTTPSCertFile, "http-tls-cert-file", "", "TLS certificate file for the HTTPs server")
2020-03-10 12:20:34 -07:00
// Bootstrapping:
bootstrapIPs := fs.String("bootstrap-ips", "default", "Comma separated list of bootstrap peer ips to connect to. Example: 127.0.0.1:9630,127.0.0.1:9631")
bootstrapIDs := fs.String("bootstrap-ids", "default", "Comma separated list of bootstrap peer ids to connect to. Example: JR4dVmy6ffUGAKCBDkyCbeZbyHQBeDsET,8CrVPQZ4VSqgL8zTdvL14G8HqAfrBr4z")
2020-03-10 12:20:34 -07:00
// Staking:
consensusPort := fs.Uint("staking-port", 9651, "Port of the consensus server")
fs.BoolVar(&Config.EnableStaking, "staking-tls-enabled", true, "Require TLS to authenticate staking connections")
fs.StringVar(&Config.StakingKeyFile, "staking-tls-key-file", defaultStakingKeyPath, "TLS private key for staking")
fs.StringVar(&Config.StakingCertFile, "staking-tls-cert-file", defaultStakingCertPath, "TLS certificate for staking")
2020-03-10 12:20:34 -07:00
// Plugins:
fs.StringVar(&Config.PluginDir, "plugin-dir", "./build/plugins", "Plugin directory for Ava VMs")
2020-03-10 12:20:34 -07:00
// Logging:
logsDir := fs.String("log-dir", "", "Logging directory for Ava")
logLevel := fs.String("log-level", "info", "The log level. Should be one of {verbo, debug, info, warn, error, fatal, off}")
logDisplayLevel := fs.String("log-display-level", "", "The log display level. If left blank, will inherit the value of log-level. Otherwise, should be one of {verbo, debug, info, warn, error, fatal, off}")
2020-03-10 12:20:34 -07:00
fs.IntVar(&Config.ConsensusParams.K, "snow-sample-size", 5, "Number of nodes to query for each network poll")
fs.IntVar(&Config.ConsensusParams.Alpha, "snow-quorum-size", 4, "Alpha value to use for required number positive results")
fs.IntVar(&Config.ConsensusParams.BetaVirtuous, "snow-virtuous-commit-threshold", 20, "Beta value to use for virtuous transactions")
fs.IntVar(&Config.ConsensusParams.BetaRogue, "snow-rogue-commit-threshold", 30, "Beta value to use for rogue transactions")
fs.IntVar(&Config.ConsensusParams.Parents, "snow-avalanche-num-parents", 5, "Number of vertexes for reference from each new vertex")
fs.IntVar(&Config.ConsensusParams.BatchSize, "snow-avalanche-batch-size", 30, "Number of operations to batch in each new vertex")
fs.IntVar(&Config.ConsensusParams.ConcurrentRepolls, "snow-concurrent-repolls", 1, "Minimum number of concurrent polls for finalizing consensus")
2020-03-10 12:20:34 -07:00
// Enable/Disable APIs:
fs.BoolVar(&Config.AdminAPIEnabled, "api-admin-enabled", true, "If true, this node exposes the Admin API")
fs.BoolVar(&Config.KeystoreAPIEnabled, "api-keystore-enabled", true, "If true, this node exposes the Keystore API")
fs.BoolVar(&Config.MetricsAPIEnabled, "api-metrics-enabled", true, "If true, this node exposes the Metrics API")
2020-05-05 22:44:45 -07:00
fs.BoolVar(&Config.HealthAPIEnabled, "api-health-enabled", true, "If true, this node exposes the Health API")
fs.BoolVar(&Config.IPCEnabled, "api-ipcs-enabled", false, "If true, IPCs can be opened")
2020-03-10 12:20:34 -07:00
// Throughput Server
throughputPort := fs.Uint("xput-server-port", 9652, "Port of the deprecated throughput test server")
fs.BoolVar(&Config.ThroughputServerEnabled, "xput-server-enabled", false, "If true, throughput test server is created")
ferr := fs.Parse(os.Args[1:])
2020-03-10 12:20:34 -07:00
if ferr == flag.ErrHelp {
// display usage/help text and exit successfully
os.Exit(0)
}
2020-03-10 12:20:34 -07:00
if ferr != nil {
// other type of error occurred when parsing args
os.Exit(2)
}
2020-03-10 12:20:34 -07:00
networkID, err := genesis.NetworkID(*networkName)
if errs.Add(err); err != nil {
return
}
2020-03-10 12:20:34 -07:00
Config.NetworkID = networkID
// DB:
if *db {
*dbDir = os.ExpandEnv(*dbDir) // parse any env variables
2020-04-24 11:44:04 -07:00
dbPath := path.Join(*dbDir, genesis.NetworkName(Config.NetworkID), dbVersion)
2020-03-10 12:20:34 -07:00
db, err := leveldb.New(dbPath, 0, 0, 0)
if err != nil {
errs.Add(fmt.Errorf("couldn't create db at %s: %w", dbPath, err))
return
}
2020-03-10 12:20:34 -07:00
Config.DB = db
} else {
Config.DB = memdb.New()
}
Config.Nat = nat.NewRouter()
2020-03-10 12:20:34 -07:00
var ip net.IP
// If public IP is not specified, get it using shell command dig
if *consensusIP == "" {
ip, err = Config.Nat.IP()
2020-04-18 19:47:53 -07:00
if err != nil {
ip = net.IPv4zero // Couldn't get my IP...set to 0.0.0.0
2020-04-18 19:47:53 -07:00
}
2020-03-10 12:20:34 -07:00
} else {
ip = net.ParseIP(*consensusIP)
}
if ip == nil {
errs.Add(fmt.Errorf("Invalid IP Address %s", *consensusIP))
return
2020-03-10 12:20:34 -07:00
}
2020-03-10 12:20:34 -07:00
Config.StakingIP = utils.IPDesc{
IP: ip,
Port: uint16(*consensusPort),
}
// Bootstrapping:
if *bootstrapIPs == "default" {
*bootstrapIPs = strings.Join(GetIPs(networkID), ",")
2020-04-02 20:43:02 -07:00
}
for _, ip := range strings.Split(*bootstrapIPs, ",") {
2020-03-10 12:20:34 -07:00
if ip != "" {
addr, err := utils.ToIPDesc(ip)
if err != nil {
errs.Add(fmt.Errorf("couldn't parse ip: %w", err))
return
}
2020-03-10 12:20:34 -07:00
Config.BootstrapPeers = append(Config.BootstrapPeers, &node.Peer{
IP: addr,
})
}
}
if *bootstrapIDs == "default" {
if *bootstrapIPs == "" {
*bootstrapIDs = ""
} else {
*bootstrapIDs = strings.Join(genesis.GetConfig(networkID).StakerIDs, ",")
}
2020-04-02 20:43:02 -07:00
}
2020-03-10 12:20:34 -07:00
if Config.EnableStaking {
i := 0
cb58 := formatting.CB58{}
for _, id := range strings.Split(*bootstrapIDs, ",") {
if id != "" {
err = cb58.FromString(id)
if err != nil {
2020-05-11 08:48:16 -07:00
errs.Add(fmt.Errorf("couldn't parse bootstrap peer id to bytes: %w", err))
return
}
peerID, err := ids.ToShortID(cb58.Bytes)
if err != nil {
errs.Add(fmt.Errorf("couldn't parse bootstrap peer id: %w", err))
return
}
2020-03-10 12:20:34 -07:00
if len(Config.BootstrapPeers) <= i {
errs.Add(errBootstrapMismatch)
return
2020-03-10 12:20:34 -07:00
}
Config.BootstrapPeers[i].ID = peerID
2020-03-10 12:20:34 -07:00
i++
}
}
if len(Config.BootstrapPeers) != i {
errs.Add(fmt.Errorf("More bootstrap IPs, %d, provided than bootstrap IDs, %d", len(Config.BootstrapPeers), i))
return
2020-03-10 12:20:34 -07:00
}
} else {
for _, peer := range Config.BootstrapPeers {
peer.ID = ids.NewShortID(hashing.ComputeHash160Array([]byte(peer.IP.String())))
}
}
// Staking
Config.StakingCertFile = os.ExpandEnv(Config.StakingCertFile) // parse any env variable
Config.StakingKeyFile = os.ExpandEnv(Config.StakingKeyFile)
switch {
// If staking key/cert locations are specified but not found, error
case Config.StakingKeyFile != defaultStakingKeyPath || Config.StakingCertFile != defaultStakingCertPath:
if _, err := os.Stat(Config.StakingKeyFile); os.IsNotExist(err) {
errs.Add(fmt.Errorf("couldn't find staking key at %s", Config.StakingKeyFile))
return
} else if _, err := os.Stat(Config.StakingCertFile); os.IsNotExist(err) {
errs.Add(fmt.Errorf("couldn't find staking certificate at %s", Config.StakingCertFile))
return
}
default:
// Only creates staking key/cert if [stakingKeyPath] doesn't exist
if err := staking.GenerateStakingKeyCert(Config.StakingKeyFile, Config.StakingCertFile); err != nil {
errs.Add(fmt.Errorf("couldn't generate staking key/cert: %w", err))
return
}
}
2020-03-10 12:20:34 -07:00
// HTTP:
Config.HTTPHost = *httpHost
2020-03-10 12:20:34 -07:00
Config.HTTPPort = uint16(*httpPort)
// Logging:
if *logsDir != "" {
loggingConfig.Directory = *logsDir
}
logFileLevel, err := logging.ToLevel(*logLevel)
if errs.Add(err); err != nil {
return
}
2020-03-10 12:20:34 -07:00
loggingConfig.LogLevel = logFileLevel
if *logDisplayLevel == "" {
*logDisplayLevel = *logLevel
}
displayLevel, err := logging.ToLevel(*logDisplayLevel)
if errs.Add(err); err != nil {
return
}
2020-03-10 12:20:34 -07:00
loggingConfig.DisplayLevel = displayLevel
Config.LoggingConfig = loggingConfig
// Throughput:
Config.ThroughputPort = uint16(*throughputPort)
// Router used for consensus
Config.ConsensusRouter = &router.ChainRouter{}
}