Skip to content

Commit

Permalink
Strip down to basic P2P client
Browse files Browse the repository at this point in the history
  • Loading branch information
wizeguyy committed Nov 14, 2023
1 parent a51a475 commit d47515c
Show file tree
Hide file tree
Showing 35 changed files with 411 additions and 1,382 deletions.
70 changes: 0 additions & 70 deletions cmd/chat.go

This file was deleted.

15 changes: 15 additions & 0 deletions cmd/options/options.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package options

// String names of every CLI option supported by go-quai
const (
CONFIG_DIR = "config-dir"
DATA_DIR = "data-dir"
LOG_LEVEL = "log-level"
SAVE_CONFIG_FILE = "save-config"
IP_ADDR = "ipaddr"
PORT = "port"
BOOTNODE = "bootnode"
PORTMAP = "portmap"
BOOTPEERS = "bootpeers"
KEYFILE = "private.key"
)
92 changes: 26 additions & 66 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,21 @@ package cmd

import (
"fmt"
"os"
"strings"

"github.com/adrg/xdg"
"github.com/dominant-strategies/go-quai/config"
"github.com/dominant-strategies/go-quai/log"
"github.com/spf13/cobra"
"github.com/spf13/viper"

"github.com/dominant-strategies/go-quai/cmd/options"
"github.com/dominant-strategies/go-quai/common"
"github.com/dominant-strategies/go-quai/common/constants"
"github.com/dominant-strategies/go-quai/log"
)

var rootCmd = &cobra.Command{
PersistentPreRunE: runPersistenPreRunE,
PersistentPreRunE: rootCmdPreRun,
}

func Execute() error {
Expand All @@ -24,92 +28,48 @@ func Execute() error {
}

func init() {

// Location for default config directory
defaultConfigDir := xdg.ConfigHome + "/" + config.APP_NAME + "/"
rootCmd.PersistentFlags().StringP(config.CONFIG_DIR, "c", defaultConfigDir, "config directory"+generateEnvDoc(config.CONFIG_DIR))
defaultConfigDir := xdg.ConfigHome + "/" + constants.APP_NAME + "/"
rootCmd.PersistentFlags().StringP(options.CONFIG_DIR, "c", defaultConfigDir, "config directory"+generateEnvDoc(options.CONFIG_DIR))

// Location for default runtime data directory
defaultDataDir := xdg.DataHome + "/" + config.APP_NAME + "/"
rootCmd.PersistentFlags().StringP(config.DATA_DIR, "d", defaultDataDir, "data directory"+generateEnvDoc(config.DATA_DIR))
defaultDataDir := xdg.DataHome + "/" + constants.APP_NAME + "/"
rootCmd.PersistentFlags().StringP(options.DATA_DIR, "d", defaultDataDir, "data directory"+generateEnvDoc(options.DATA_DIR))

// Log level to use (trace, debug, info, warn, error, fatal, panic)
rootCmd.PersistentFlags().StringP(config.LOG_LEVEL, "l", "info", "log level (trace, debug, info, warn, error, fatal, panic)"+generateEnvDoc(config.LOG_LEVEL))
rootCmd.PersistentFlags().StringP(options.LOG_LEVEL, "l", "info", "log level (trace, debug, info, warn, error, fatal, panic)"+generateEnvDoc(options.LOG_LEVEL))

// When set to true saves or updates the config file with the current config parameters
rootCmd.PersistentFlags().BoolP(config.SAVE_CONFIG_FILE, "S", false, "save/update config file with current config parameters"+generateEnvDoc(config.SAVE_CONFIG_FILE))

// IP address for p2p networking
rootCmd.PersistentFlags().StringP(config.IP_ADDR, "i", "0.0.0.0", "ip address to listen on"+generateEnvDoc(config.IP_ADDR))

// p2p port for networking
rootCmd.PersistentFlags().StringP(config.PORT, "p", "4001", "p2p port to listen on"+generateEnvDoc(config.PORT))

// isBootNode when set to true starts p2p node as a DHT boostrap server (no static peers required).
rootCmd.PersistentFlags().BoolP(config.BOOTNODE, "s", false, "start the node as a boot node (no static peers required)"+generateEnvDoc(config.BOOTNODE))

// bootstrapPeers is a list of multiaddresses to bootstrap the DHT.
rootCmd.PersistentFlags().StringSlice(config.BOOTSTRAP_PEERS, []string{}, "list of multiaddresses to bootstrap the DHT, i.e. /ip4/181.111.5.24/tcp/4001/p2p/QmbLHAnMoJPWSCR5Zhtx6BHJX9KiKNN6tpvbUcqanj75Nb"+generateEnvDoc(config.BOOTSTRAP_PEERS))

// p2p options

// enableNATService configures libp2p to provide a service to peers for determining
// their reachability status. When enabled, the host will attempt to dial back to peers,
// and then tell them if it was successful in making such connections.
// See https://pkg.go.dev/github.com/libp2p/[email protected]#EnableNATService
rootCmd.PersistentFlags().Bool(config.NAT_SERVICE, true, "enable NAT service"+generateEnvDoc(config.NAT_SERVICE))

// enableNATPortMap configures libp2p to open a port in network's firewall using UPnP.
// See https://pkg.go.dev/github.com/libp2p/[email protected]#NATPortMap
rootCmd.PersistentFlags().Bool(config.NAT_PORTMAP, true, "enable NAT portmap"+generateEnvDoc(config.NAT_PORTMAP))

// enableAutoRelayWithStaticRelays configures libp2p to enable the AutoRelay subsystem using the
// provided relays as relay candidates. This subsystem performs automatic address rewriting to
// advertise relay addresses when it detects that the node is publicly unreachable (e.g. behind a NAT).
// See https://pkg.go.dev/github.com/libp2p/[email protected]#EnableAutoRelayWithStaticRelays
rootCmd.PersistentFlags().Bool(config.AUTO_RELAY_STATIC, false, "enable AutoRelay with Static Relays"+generateEnvDoc(config.AUTO_RELAY_STATIC))

// enableHolePunching configures libp2p to enable NAT traversal by enabling NATT'd peers
// to both initiate and respond to hole punching attempts to create direct/NAT-traversed
// connections with other peers. NOTE: 'enableRelay' must be enabled for this option to work.
// See https://pkg.go.dev/github.com/libp2p/[email protected]#EnableHolePunching
rootCmd.PersistentFlags().Bool(config.HOLE_PUNCHING, true, "enable Hole Punching"+generateEnvDoc(config.HOLE_PUNCHING))

// ** Note: "EnableRelay" is enabled by default in libp2p.
// enableRelay configures libp2p to enable the relay transport.
// This option only configures libp2p to accept inbound connections from relays
// and make outbound connections_through_ relays when requested by the remote peer.
// See https://pkg.go.dev/github.com/libp2p/[email protected]#EnableRelay
rootCmd.PersistentFlags().Bool(config.RELAY, true, "enable relay transport"+generateEnvDoc(config.RELAY))
rootCmd.PersistentFlags().BoolP(options.SAVE_CONFIG_FILE, "S", false, "save/update config file with current config parameters"+generateEnvDoc(options.SAVE_CONFIG_FILE))
}

func runPersistenPreRunE(cmd *cobra.Command, args []string) error {
func rootCmdPreRun(cmd *cobra.Command, args []string) error {
// set logger inmediately after parsing cobra flags
logLevel := cmd.Flag(config.LOG_LEVEL).Value.String()
logLevel := cmd.Flag(options.LOG_LEVEL).Value.String()
log.ConfigureLogger(log.WithLevel(logLevel))
// set config path to read config file
configPath := cmd.Flag(config.CONFIG_DIR).Value.String()
viper.SetConfigFile(configPath + config.CONFIG_FILE_NAME)
configDir := cmd.Flag(options.CONFIG_DIR).Value.String()
viper.SetConfigFile(configDir + constants.CONFIG_FILE_NAME)
viper.SetConfigType("yaml")
// load config from file and environment variables
config.InitConfig()
common.InitConfig()
// bind cobra flags to viper instance
err := viper.BindPFlags(cmd.Flags())
if err != nil {
return fmt.Errorf("error binding flags: %s", err)
}

// if no bootstrap peers are provided, use the default ones defined in config/bootnodes.go
bootstrapPeers := viper.GetStringSlice(config.BOOTSTRAP_PEERS)
if len(bootstrapPeers) == 0 {
log.Debugf("no bootstrap peers provided. Using default ones: %v", config.BootstrapPeers)
viper.Set(config.BOOTSTRAP_PEERS, config.BootstrapPeers)
// Make sure data dir and config dir exist
if _, err := os.Stat(configDir); os.IsNotExist(err) {
if err := os.MkdirAll(configDir, 0755); err != nil {
return err
}
}

// save config file if SAVE_CONFIG_FILE flag is set to true
saveConfigFile := viper.GetBool(config.SAVE_CONFIG_FILE)
saveConfigFile := viper.GetBool(options.SAVE_CONFIG_FILE)
if saveConfigFile {
err := config.SaveConfig()
err := common.SaveConfig()
if err != nil {
log.Errorf("error saving config file: %s . Skipping...", err)
} else {
Expand All @@ -124,6 +84,6 @@ func runPersistenPreRunE(cmd *cobra.Command, args []string) error {
// helper function that given a cobra flag name, returns the corresponding
// help legend for the equivalent environment variable
func generateEnvDoc(flag string) string {
envVar := config.ENV_PREFIX + "_" + strings.ReplaceAll(strings.ToUpper(flag), "-", "_")
envVar := constants.ENV_PREFIX + "_" + strings.ReplaceAll(strings.ToUpper(flag), "-", "_")
return fmt.Sprintf(" [%s]", envVar)
}
56 changes: 50 additions & 6 deletions cmd/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,14 @@ import (
"os/signal"
"syscall"

"github.com/dominant-strategies/go-quai/consensus/quai"
"github.com/dominant-strategies/go-quai/log"
"github.com/spf13/cobra"
"github.com/spf13/viper"

p2pnode "github.com/dominant-strategies/go-quai/p2p/node"
"github.com/dominant-strategies/go-quai/cmd/options"
"github.com/dominant-strategies/go-quai/common"
"github.com/dominant-strategies/go-quai/consensus/quai"
"github.com/dominant-strategies/go-quai/log"
"github.com/dominant-strategies/go-quai/p2p/node"
)

var startCmd = &cobra.Command{
Expand All @@ -23,10 +26,51 @@ To bootstrap to a private node, use the --bootstrap flag.`,
SilenceUsage: true,
SuggestionsMinimumDistance: 2,
Example: `go-quai start -loglevel=debug`,
PreRunE: startCmdPreRun,
}

func init() {
rootCmd.AddCommand(startCmd)

// IP address for p2p networking
startCmd.PersistentFlags().StringP(options.IP_ADDR, "i", "0.0.0.0", "ip address to listen on"+generateEnvDoc(options.IP_ADDR))
viper.BindPFlag(options.IP_ADDR, startCmd.PersistentFlags().Lookup(options.IP_ADDR))

// p2p port for networking
startCmd.PersistentFlags().StringP(options.PORT, "p", "4001", "p2p port to listen on"+generateEnvDoc(options.PORT))
viper.BindPFlag(options.PORT, startCmd.PersistentFlags().Lookup(options.PORT))

// isBootNode when set to true starts p2p node as a DHT boostrap server (no static peers required).
startCmd.PersistentFlags().BoolP(options.BOOTNODE, "b", false, "start the node as a boot node (no static peers required)"+generateEnvDoc(options.BOOTNODE))
viper.BindPFlag(options.BOOTNODE, startCmd.PersistentFlags().Lookup(options.BOOTNODE))

// initial peers to connect to and use for bootstrapping purposes
startCmd.PersistentFlags().StringSliceP(options.BOOTPEERS, "", []string{}, "list of bootstrap peers. Syntax: <multiaddress1>,<multiaddress2>,...")
viper.BindPFlag(options.BOOTPEERS, startCmd.PersistentFlags().Lookup(options.BOOTPEERS))

// enableNATPortMap configures libp2p to attempt to open a port in network's firewall using UPnP.
// See https://pkg.go.dev/github.com/libp2p/[email protected]#NATPortMap
startCmd.PersistentFlags().Bool(options.PORTMAP, true, "enable NAT portmap"+generateEnvDoc(options.PORTMAP))
viper.BindPFlag(options.PORTMAP, startCmd.PersistentFlags().Lookup(options.PORTMAP))

// path to file containing node private key
startCmd.PersistentFlags().StringP(options.KEYFILE, "k", "", "file containing node private key"+generateEnvDoc(options.KEYFILE))
viper.BindPFlag(options.KEYFILE, startCmd.PersistentFlags().Lookup(options.KEYFILE))
}

func startCmdPreRun(cmd *cobra.Command, args []string) error {
// set keyfile path
if "" == viper.GetString(options.KEYFILE) {
configDir := cmd.Flag(options.CONFIG_DIR).Value.String()
viper.Set(options.KEYFILE, configDir+"private.key")
}

// if no bootstrap peers are provided, use the default ones defined in config/bootnodes.go
if bootstrapPeers := viper.GetStringSlice(options.BOOTPEERS); len(bootstrapPeers) == 0 {
log.Debugf("no bootstrap peers provided. Using default ones: %v", common.BootstrapPeers)
viper.Set(options.BOOTPEERS, common.BootstrapPeers)
}
return nil
}

func runStart(cmd *cobra.Command, args []string) error {
Expand All @@ -35,7 +79,7 @@ func runStart(cmd *cobra.Command, args []string) error {
defer cancel()

// create a new p2p node
node, err := p2pnode.NewNode(ctx)
node, err := node.NewNode(ctx)
if err != nil {
log.Fatalf("error creating node: %s", err)
}
Expand All @@ -47,7 +91,7 @@ func runStart(cmd *cobra.Command, args []string) error {
}

// start the consensus backend
consensus.SetP2PClient(node)
consensus.SetP2PNode(node)
if err := consensus.Start(); err != nil {
log.Fatalf("error starting consensus backend: %s", err)
}
Expand All @@ -64,7 +108,7 @@ func runStart(cmd *cobra.Command, args []string) error {
<-ch
log.Warnf("Received 'stop' signal, shutting down gracefully...")
cancel()
if err := node.Shutdown(); err != nil {
if err := node.Stop(); err != nil {
panic(err)
}
log.Warnf("Node is offline")
Expand Down
2 changes: 1 addition & 1 deletion config/bootnodes.go → common/bootnodes.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package config
package common

var (

Expand Down
15 changes: 15 additions & 0 deletions common/constants/constants.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package constants

const (
APP_NAME = "go-quai"
// prefix used to read config parameters from environment variables
ENV_PREFIX = "GO_QUAI"
// default private key file name
PRIVATE_KEY_FILENAME = "private.key"
// default config file name
CONFIG_FILE_NAME = "config.yaml"
// file to dynamically store node's ID and listening addresses
NODEINFO_FILE_NAME = "node.info"
// file to read the host's IP address (used to replace Docker's internal IP)
HOST_IP_FILE_NAME = "host.ip"
)
2 changes: 1 addition & 1 deletion config/main_test.go → common/main_test.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package config
package common

import (
"os"
Expand Down
14 changes: 7 additions & 7 deletions config/utils.go → common/utils.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
package config
package common

import (
"errors"
"io/fs"
"os"

"github.com/dominant-strategies/go-quai/cmd/options"
"github.com/dominant-strategies/go-quai/common/constants"
"github.com/dominant-strategies/go-quai/log"
"github.com/spf13/viper"
)
Expand All @@ -29,8 +31,8 @@ func InitConfig() {
}
}

log.Infof("Loading config from environment variables with prefix: '%s_'", ENV_PREFIX)
viper.SetEnvPrefix(ENV_PREFIX)
log.Infof("Loading config from environment variables with prefix: '%s_'", constants.ENV_PREFIX)
viper.SetEnvPrefix(constants.ENV_PREFIX)
viper.AutomaticEnv()
}

Expand All @@ -54,13 +56,11 @@ func SaveConfig() error {
} else if os.IsNotExist(err) {
// config file does not exist, create directory if it does not exist
if _, err := os.Stat(configFile); os.IsNotExist(err) {
configDir := viper.GetString(CONFIG_DIR)
err := os.MkdirAll(configDir, 0755)
if err != nil {
configDir := viper.GetString(options.CONFIG_DIR)
if err := os.MkdirAll(configDir, 0755); err != nil {
return err
}
}
// create config file
_, err := os.Create(configFile)
if err != nil {
return err
Expand Down
Loading

0 comments on commit d47515c

Please sign in to comment.