mirror of
https://github.com/lightningnetwork/lnd.git
synced 2024-11-19 18:10:34 +01:00
271 lines
7.0 KiB
Go
271 lines
7.0 KiB
Go
package node
|
|
|
|
import (
|
|
"fmt"
|
|
"path"
|
|
"path/filepath"
|
|
|
|
"github.com/btcsuite/btcd/chaincfg"
|
|
"github.com/lightningnetwork/lnd/chanbackup"
|
|
"github.com/lightningnetwork/lnd/kvdb/etcd"
|
|
"github.com/lightningnetwork/lnd/lntest"
|
|
)
|
|
|
|
const (
|
|
// ListenerFormat is the format string that is used to generate local
|
|
// listener addresses.
|
|
ListenerFormat = "127.0.0.1:%d"
|
|
)
|
|
|
|
// Option is a function for updating a node's configuration.
|
|
type Option func(*BaseNodeConfig)
|
|
|
|
// BackendConfig is an interface that abstracts away the specific chain backend
|
|
// node implementation.
|
|
type BackendConfig interface {
|
|
// GenArgs returns the arguments needed to be passed to LND at startup
|
|
// for using this node as a chain backend.
|
|
GenArgs() []string
|
|
|
|
// ConnectMiner is called to establish a connection to the test miner.
|
|
ConnectMiner() error
|
|
|
|
// DisconnectMiner is called to disconnect the miner.
|
|
DisconnectMiner() error
|
|
|
|
// Name returns the name of the backend type.
|
|
Name() string
|
|
|
|
// Credentials returns the rpc username, password and host for the
|
|
// backend.
|
|
Credentials() (string, string, string, error)
|
|
}
|
|
|
|
// BaseNodeConfig is the base node configuration.
|
|
type BaseNodeConfig struct {
|
|
Name string
|
|
|
|
// LogFilenamePrefix is used to prefix node log files. Can be used to
|
|
// store the current test case for simpler postmortem debugging.
|
|
LogFilenamePrefix string
|
|
|
|
NetParams *chaincfg.Params
|
|
BackendCfg BackendConfig
|
|
BaseDir string
|
|
ExtraArgs []string
|
|
OriginalExtraArgs []string
|
|
|
|
DataDir string
|
|
LogDir string
|
|
TLSCertPath string
|
|
TLSKeyPath string
|
|
AdminMacPath string
|
|
ReadMacPath string
|
|
InvoiceMacPath string
|
|
|
|
SkipUnlock bool
|
|
Password []byte
|
|
|
|
P2PPort int
|
|
RPCPort int
|
|
RESTPort int
|
|
ProfilePort int
|
|
|
|
FeeURL string
|
|
|
|
DbBackend lntest.DatabaseBackend
|
|
PostgresDsn string
|
|
|
|
// NodeID is a unique ID used to identify the node.
|
|
NodeID uint32
|
|
|
|
// LndBinary is the full path to the lnd binary that was specifically
|
|
// compiled with all required itest flags.
|
|
LndBinary string
|
|
|
|
// backupDbDir is the path where a database backup is stored, if any.
|
|
backupDbDir string
|
|
|
|
// postgresDbName is the name of the postgres database where lnd data
|
|
// is stored in.
|
|
postgresDbName string
|
|
}
|
|
|
|
func (cfg BaseNodeConfig) P2PAddr() string {
|
|
return fmt.Sprintf(ListenerFormat, cfg.P2PPort)
|
|
}
|
|
|
|
func (cfg BaseNodeConfig) RPCAddr() string {
|
|
return fmt.Sprintf(ListenerFormat, cfg.RPCPort)
|
|
}
|
|
|
|
func (cfg BaseNodeConfig) RESTAddr() string {
|
|
return fmt.Sprintf(ListenerFormat, cfg.RESTPort)
|
|
}
|
|
|
|
// DBDir returns the holding directory path of the graph database.
|
|
func (cfg BaseNodeConfig) DBDir() string {
|
|
return filepath.Join(cfg.DataDir, "graph", cfg.NetParams.Name)
|
|
}
|
|
|
|
func (cfg BaseNodeConfig) DBPath() string {
|
|
return filepath.Join(cfg.DBDir(), "channel.db")
|
|
}
|
|
|
|
func (cfg BaseNodeConfig) ChanBackupPath() string {
|
|
return filepath.Join(
|
|
cfg.DataDir, "chain", "bitcoin",
|
|
fmt.Sprintf(
|
|
"%v/%v", cfg.NetParams.Name,
|
|
chanbackup.DefaultBackupFileName,
|
|
),
|
|
)
|
|
}
|
|
|
|
// GenerateListeningPorts generates the ports to listen on designated for the
|
|
// current lightning network test.
|
|
func (cfg *BaseNodeConfig) GenerateListeningPorts() {
|
|
if cfg.P2PPort == 0 {
|
|
cfg.P2PPort = lntest.NextAvailablePort()
|
|
}
|
|
if cfg.RPCPort == 0 {
|
|
cfg.RPCPort = lntest.NextAvailablePort()
|
|
}
|
|
if cfg.RESTPort == 0 {
|
|
cfg.RESTPort = lntest.NextAvailablePort()
|
|
}
|
|
if cfg.ProfilePort == 0 {
|
|
cfg.ProfilePort = lntest.NextAvailablePort()
|
|
}
|
|
}
|
|
|
|
// BaseConfig returns the base node configuration struct.
|
|
func (cfg *BaseNodeConfig) BaseConfig() *BaseNodeConfig {
|
|
return cfg
|
|
}
|
|
|
|
// GenArgs generates a slice of command line arguments from the lightning node
|
|
// config struct.
|
|
func (cfg *BaseNodeConfig) GenArgs() []string {
|
|
var args []string
|
|
|
|
switch cfg.NetParams {
|
|
case &chaincfg.TestNet3Params:
|
|
args = append(args, "--bitcoin.testnet")
|
|
case &chaincfg.SimNetParams:
|
|
args = append(args, "--bitcoin.simnet")
|
|
case &chaincfg.RegressionNetParams:
|
|
args = append(args, "--bitcoin.regtest")
|
|
}
|
|
|
|
backendArgs := cfg.BackendCfg.GenArgs()
|
|
args = append(args, backendArgs...)
|
|
|
|
nodeArgs := []string{
|
|
"--bitcoin.active",
|
|
"--nobootstrap",
|
|
"--debuglevel=debug",
|
|
"--bitcoin.defaultchanconfs=1",
|
|
"--accept-keysend",
|
|
"--keep-failed-payment-attempts",
|
|
fmt.Sprintf("--db.batch-commit-interval=%v", commitInterval),
|
|
fmt.Sprintf("--bitcoin.defaultremotedelay=%v",
|
|
lntest.DefaultCSV),
|
|
fmt.Sprintf("--rpclisten=%v", cfg.RPCAddr()),
|
|
fmt.Sprintf("--restlisten=%v", cfg.RESTAddr()),
|
|
fmt.Sprintf("--restcors=https://%v", cfg.RESTAddr()),
|
|
fmt.Sprintf("--listen=%v", cfg.P2PAddr()),
|
|
fmt.Sprintf("--externalip=%v", cfg.P2PAddr()),
|
|
fmt.Sprintf("--lnddir=%v", cfg.BaseDir),
|
|
fmt.Sprintf("--adminmacaroonpath=%v", cfg.AdminMacPath),
|
|
fmt.Sprintf("--readonlymacaroonpath=%v", cfg.ReadMacPath),
|
|
fmt.Sprintf("--invoicemacaroonpath=%v", cfg.InvoiceMacPath),
|
|
fmt.Sprintf("--trickledelay=%v", trickleDelay),
|
|
fmt.Sprintf("--profile=%d", cfg.ProfilePort),
|
|
fmt.Sprintf("--caches.rpc-graph-cache-duration=%d", 0),
|
|
|
|
// Use a small batch window so we can broadcast our sweep
|
|
// transactions faster.
|
|
"--sweeper.batchwindowduration=5s",
|
|
}
|
|
args = append(args, nodeArgs...)
|
|
|
|
if cfg.Password == nil {
|
|
args = append(args, "--noseedbackup")
|
|
}
|
|
|
|
switch cfg.DbBackend {
|
|
case lntest.BackendEtcd:
|
|
args = append(args, "--db.backend=etcd")
|
|
args = append(args, "--db.etcd.embedded")
|
|
args = append(
|
|
args, fmt.Sprintf(
|
|
"--db.etcd.embedded_client_port=%v",
|
|
lntest.NextAvailablePort(),
|
|
),
|
|
)
|
|
args = append(
|
|
args, fmt.Sprintf(
|
|
"--db.etcd.embedded_peer_port=%v",
|
|
lntest.NextAvailablePort(),
|
|
),
|
|
)
|
|
args = append(
|
|
args, fmt.Sprintf(
|
|
"--db.etcd.embedded_log_file=%v",
|
|
path.Join(cfg.LogDir, "etcd.log"),
|
|
),
|
|
)
|
|
|
|
case lntest.BackendPostgres:
|
|
args = append(args, "--db.backend=postgres")
|
|
args = append(args, "--db.postgres.dsn="+cfg.PostgresDsn)
|
|
|
|
case lntest.BackendSqlite:
|
|
args = append(args, "--db.backend=sqlite")
|
|
args = append(args, fmt.Sprintf("--db.sqlite.busytimeout=%v",
|
|
lntest.SqliteBusyTimeout))
|
|
}
|
|
|
|
if cfg.FeeURL != "" {
|
|
args = append(args, "--feeurl="+cfg.FeeURL)
|
|
}
|
|
|
|
// Put extra args in the end so the args can be overwritten.
|
|
if cfg.ExtraArgs != nil {
|
|
args = append(args, cfg.ExtraArgs...)
|
|
}
|
|
|
|
return args
|
|
}
|
|
|
|
// ExtraArgsEtcd returns extra args for configuring LND to use an external etcd
|
|
// database (for remote channel DB and wallet DB).
|
|
func ExtraArgsEtcd(etcdCfg *etcd.Config, name string, cluster bool,
|
|
leaderSessionTTL int) []string {
|
|
|
|
extraArgs := []string{
|
|
"--db.backend=etcd",
|
|
fmt.Sprintf("--db.etcd.host=%v", etcdCfg.Host),
|
|
fmt.Sprintf("--db.etcd.user=%v", etcdCfg.User),
|
|
fmt.Sprintf("--db.etcd.pass=%v", etcdCfg.Pass),
|
|
fmt.Sprintf("--db.etcd.namespace=%v", etcdCfg.Namespace),
|
|
}
|
|
|
|
if etcdCfg.InsecureSkipVerify {
|
|
extraArgs = append(extraArgs, "--db.etcd.insecure_skip_verify")
|
|
}
|
|
|
|
if cluster {
|
|
clusterArgs := []string{
|
|
"--cluster.enable-leader-election",
|
|
fmt.Sprintf("--cluster.id=%v", name),
|
|
fmt.Sprintf("--cluster.leader-session-ttl=%v",
|
|
leaderSessionTTL),
|
|
}
|
|
extraArgs = append(extraArgs, clusterArgs...)
|
|
}
|
|
|
|
return extraArgs
|
|
}
|