mirror of
https://github.com/AthanorLabs/atomic-swap.git
synced 2026-01-09 14:18:03 -05:00
180 lines
4.5 KiB
Go
180 lines
4.5 KiB
Go
// Copyright 2023 The AthanorLabs/atomic-swap Authors
|
|
// SPDX-License-Identifier: LGPL-3.0-only
|
|
|
|
// Package main provides the entrypoint of the bootnode executable,
|
|
// a node that is only used to bootstrap the p2p network and does not run
|
|
// any swap services.
|
|
package main
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"os"
|
|
"path"
|
|
|
|
"github.com/athanorlabs/atomic-swap/bootnode"
|
|
"github.com/athanorlabs/atomic-swap/cliutil"
|
|
"github.com/athanorlabs/atomic-swap/common"
|
|
|
|
logging "github.com/ipfs/go-log"
|
|
"github.com/urfave/cli/v2"
|
|
)
|
|
|
|
const (
|
|
defaultLibp2pPort = 9909
|
|
defaultRPCPort = common.DefaultSwapdPort
|
|
|
|
flagDataDir = "data-dir"
|
|
flagLibp2pKey = "libp2p-key"
|
|
flagLibp2pPort = "libp2p-port"
|
|
flagBootnodes = "bootnodes"
|
|
flagRPCPort = "rpc-port"
|
|
flagEnv = "env"
|
|
)
|
|
|
|
var log = logging.Logger("cmd")
|
|
|
|
func cliApp() *cli.App {
|
|
return &cli.App{
|
|
Name: "bootnode",
|
|
Usage: "A bootnode for the atomic swap p2p network.",
|
|
Version: cliutil.GetVersion(),
|
|
Action: runBootnode,
|
|
EnableBashCompletion: true,
|
|
Suggest: true,
|
|
Flags: []cli.Flag{
|
|
&cli.StringFlag{
|
|
Name: flagDataDir,
|
|
Usage: "Path to store swap artifacts",
|
|
Value: "{HOME}/.atomicswap/{ENV}/bootnode", // For --help only, actual default replaces variables
|
|
},
|
|
&cli.StringFlag{
|
|
Name: flagLibp2pKey,
|
|
Usage: "libp2p private key",
|
|
Value: fmt.Sprintf("{DATA_DIR}/%s", common.DefaultLibp2pKeyFileName),
|
|
},
|
|
&cli.UintFlag{
|
|
Name: flagLibp2pPort,
|
|
Usage: "libp2p port to listen on",
|
|
EnvVars: []string{"SWAPD_LIBP2P_PORT"},
|
|
Value: defaultLibp2pPort,
|
|
},
|
|
&cli.StringSliceFlag{
|
|
Name: flagBootnodes,
|
|
Aliases: []string{"bn"},
|
|
Usage: "libp2p bootnode, comma separated if passing multiple to a single flag",
|
|
EnvVars: []string{"SWAPD_BOOTNODES"},
|
|
},
|
|
&cli.UintFlag{
|
|
Name: flagRPCPort,
|
|
Usage: "Port for the bootnode RPC server to run on",
|
|
Value: defaultRPCPort,
|
|
EnvVars: []string{"SWAPD_RPC_PORT"},
|
|
},
|
|
&cli.StringFlag{
|
|
Name: flagEnv,
|
|
Usage: "Environment to use: one of mainnet, stagenet, or dev. Default: mainnet",
|
|
EnvVars: []string{"SWAPD_ENV"},
|
|
Value: "mainnet",
|
|
},
|
|
&cli.StringFlag{
|
|
Name: cliutil.FlagLogLevel,
|
|
Usage: "Set log level: one of [error|warn|info|debug]",
|
|
EnvVars: []string{"SWAPD_LOG_LEVEL"},
|
|
Value: "info",
|
|
},
|
|
},
|
|
}
|
|
}
|
|
|
|
func main() {
|
|
ctx, cancel := context.WithCancel(context.Background())
|
|
defer cancel()
|
|
|
|
go cliutil.SignalHandler(ctx, cancel, log)
|
|
|
|
err := cliApp().RunContext(ctx, os.Args)
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
}
|
|
|
|
func runBootnode(c *cli.Context) error {
|
|
// Fail if any non-flag arguments were passed
|
|
if c.Args().Present() {
|
|
return fmt.Errorf("unknown command %q", c.Args().First())
|
|
}
|
|
|
|
if err := cliutil.SetLogLevelsFromContext(c); err != nil {
|
|
return err
|
|
}
|
|
|
|
config, err := getEnvConfig(c)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
libp2pKeyFile := config.LibP2PKeyFile()
|
|
if c.IsSet(flagLibp2pKey) {
|
|
libp2pKeyFile = c.String(flagLibp2pKey)
|
|
if libp2pKeyFile == "" {
|
|
return errFlagValueEmpty(flagLibp2pKey)
|
|
}
|
|
}
|
|
|
|
if libp2pKeyFile == "" {
|
|
libp2pKeyFile = path.Join(config.DataDir, common.DefaultLibp2pKeyFileName)
|
|
}
|
|
|
|
libp2pPort := uint16(c.Uint(flagLibp2pPort))
|
|
|
|
hostListenIP := "0.0.0.0"
|
|
if config.Env == common.Development {
|
|
hostListenIP = "127.0.0.1"
|
|
}
|
|
|
|
rpcPort := uint16(c.Uint(flagRPCPort))
|
|
return bootnode.RunBootnode(c.Context, &bootnode.Config{
|
|
Env: config.Env,
|
|
DataDir: config.DataDir,
|
|
Bootnodes: config.Bootnodes,
|
|
HostListenIP: hostListenIP,
|
|
Libp2pPort: libp2pPort,
|
|
Libp2pKeyFile: libp2pKeyFile,
|
|
RPCPort: rpcPort,
|
|
})
|
|
}
|
|
|
|
func getEnvConfig(c *cli.Context) (*common.Config, error) {
|
|
env, err := common.NewEnv(c.String(flagEnv))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
log.Infof("starting bootnode, environment: %s", env)
|
|
|
|
conf := common.ConfigDefaultsForEnv(env)
|
|
|
|
// cfg.DataDir already has a default set, so only override if the user explicitly set the flag
|
|
if c.IsSet(flagDataDir) {
|
|
conf.DataDir = c.String(flagDataDir) // override the value derived from `flagEnv`
|
|
if conf.DataDir == "" {
|
|
return nil, errFlagValueEmpty(flagDataDir)
|
|
}
|
|
}
|
|
|
|
conf.DataDir = path.Join(conf.DataDir, "bootnode")
|
|
if err = common.MakeDir(conf.DataDir); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if c.IsSet(flagBootnodes) {
|
|
conf.Bootnodes = cliutil.ExpandBootnodes(c.StringSlice(flagBootnodes))
|
|
}
|
|
|
|
return conf, nil
|
|
}
|
|
|
|
func errFlagValueEmpty(flag string) error {
|
|
return fmt.Errorf("flag %q requires a non-empty value", flag)
|
|
}
|