Merge pull request #3846 from guggero/lntest-node-config
itest: make harnesses usable in external projects
This commit is contained in:
commit
aab956471d
@ -35,6 +35,10 @@ const DefaultCSV = 4
|
|||||||
type NetworkHarness struct {
|
type NetworkHarness struct {
|
||||||
netParams *chaincfg.Params
|
netParams *chaincfg.Params
|
||||||
|
|
||||||
|
// lndBinary is the full path to the lnd binary that was specifically
|
||||||
|
// compiled with all required itest flags.
|
||||||
|
lndBinary string
|
||||||
|
|
||||||
// Miner is a reference to a running full node that can be used to create
|
// Miner is a reference to a running full node that can be used to create
|
||||||
// new blocks on the network.
|
// new blocks on the network.
|
||||||
Miner *rpctest.Harness
|
Miner *rpctest.Harness
|
||||||
@ -68,7 +72,9 @@ type NetworkHarness struct {
|
|||||||
// TODO(roasbeef): add option to use golang's build library to a binary of the
|
// TODO(roasbeef): add option to use golang's build library to a binary of the
|
||||||
// current repo. This will save developers from having to manually `go install`
|
// current repo. This will save developers from having to manually `go install`
|
||||||
// within the repo each time before changes
|
// within the repo each time before changes
|
||||||
func NewNetworkHarness(r *rpctest.Harness, b BackendConfig) (*NetworkHarness, error) {
|
func NewNetworkHarness(r *rpctest.Harness, b BackendConfig, lndBinary string) (
|
||||||
|
*NetworkHarness, error) {
|
||||||
|
|
||||||
n := NetworkHarness{
|
n := NetworkHarness{
|
||||||
activeNodes: make(map[int]*HarnessNode),
|
activeNodes: make(map[int]*HarnessNode),
|
||||||
nodesByPub: make(map[string]*HarnessNode),
|
nodesByPub: make(map[string]*HarnessNode),
|
||||||
@ -79,6 +85,7 @@ func NewNetworkHarness(r *rpctest.Harness, b BackendConfig) (*NetworkHarness, er
|
|||||||
Miner: r,
|
Miner: r,
|
||||||
BackendCfg: b,
|
BackendCfg: b,
|
||||||
quit: make(chan struct{}),
|
quit: make(chan struct{}),
|
||||||
|
lndBinary: lndBinary,
|
||||||
}
|
}
|
||||||
go n.networkWatcher()
|
go n.networkWatcher()
|
||||||
return &n, nil
|
return &n, nil
|
||||||
@ -343,7 +350,7 @@ func (n *NetworkHarness) RestoreNodeWithSeed(name string, extraArgs []string,
|
|||||||
func (n *NetworkHarness) newNode(name string, extraArgs []string,
|
func (n *NetworkHarness) newNode(name string, extraArgs []string,
|
||||||
hasSeed bool, password []byte) (*HarnessNode, error) {
|
hasSeed bool, password []byte) (*HarnessNode, error) {
|
||||||
|
|
||||||
node, err := newNode(nodeConfig{
|
node, err := newNode(NodeConfig{
|
||||||
Name: name,
|
Name: name,
|
||||||
HasSeed: hasSeed,
|
HasSeed: hasSeed,
|
||||||
Password: password,
|
Password: password,
|
||||||
@ -361,14 +368,14 @@ func (n *NetworkHarness) newNode(name string, extraArgs []string,
|
|||||||
n.activeNodes[node.NodeID] = node
|
n.activeNodes[node.NodeID] = node
|
||||||
n.mtx.Unlock()
|
n.mtx.Unlock()
|
||||||
|
|
||||||
if err := node.start(n.lndErrorChan); err != nil {
|
if err := node.start(n.lndBinary, n.lndErrorChan); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// If this node is to have a seed, it will need to be unlocked or
|
// If this node is to have a seed, it will need to be unlocked or
|
||||||
// initialized via rpc. Delay registering it with the network until it
|
// initialized via rpc. Delay registering it with the network until it
|
||||||
// can be driven via an unlocked rpc connection.
|
// can be driven via an unlocked rpc connection.
|
||||||
if node.cfg.HasSeed {
|
if node.Cfg.HasSeed {
|
||||||
return node, nil
|
return node, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -431,7 +438,7 @@ func (n *NetworkHarness) EnsureConnected(ctx context.Context, a, b *HarnessNode)
|
|||||||
req := &lnrpc.ConnectPeerRequest{
|
req := &lnrpc.ConnectPeerRequest{
|
||||||
Addr: &lnrpc.LightningAddress{
|
Addr: &lnrpc.LightningAddress{
|
||||||
Pubkey: bInfo.IdentityPubkey,
|
Pubkey: bInfo.IdentityPubkey,
|
||||||
Host: b.cfg.P2PAddr(),
|
Host: b.Cfg.P2PAddr(),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -536,7 +543,7 @@ func (n *NetworkHarness) ConnectNodes(ctx context.Context, a, b *HarnessNode) er
|
|||||||
req := &lnrpc.ConnectPeerRequest{
|
req := &lnrpc.ConnectPeerRequest{
|
||||||
Addr: &lnrpc.LightningAddress{
|
Addr: &lnrpc.LightningAddress{
|
||||||
Pubkey: bobInfo.IdentityPubkey,
|
Pubkey: bobInfo.IdentityPubkey,
|
||||||
Host: b.cfg.P2PAddr(),
|
Host: b.Cfg.P2PAddr(),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -612,20 +619,20 @@ func (n *NetworkHarness) RestartNode(node *HarnessNode, callback func() error,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := node.start(n.lndErrorChan); err != nil {
|
if err := node.start(n.lndBinary, n.lndErrorChan); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the node doesn't have a password set, then we can exit here as we
|
// If the node doesn't have a password set, then we can exit here as we
|
||||||
// don't need to unlock it.
|
// don't need to unlock it.
|
||||||
if len(node.cfg.Password) == 0 {
|
if len(node.Cfg.Password) == 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Otherwise, we'll unlock the wallet, then complete the final steps
|
// Otherwise, we'll unlock the wallet, then complete the final steps
|
||||||
// for the node initialization process.
|
// for the node initialization process.
|
||||||
unlockReq := &lnrpc.UnlockWalletRequest{
|
unlockReq := &lnrpc.UnlockWalletRequest{
|
||||||
WalletPassword: node.cfg.Password,
|
WalletPassword: node.Cfg.Password,
|
||||||
}
|
}
|
||||||
if len(chanBackups) != 0 {
|
if len(chanBackups) != 0 {
|
||||||
unlockReq.ChannelBackups = chanBackups[0]
|
unlockReq.ChannelBackups = chanBackups[0]
|
||||||
@ -643,7 +650,7 @@ func (n *NetworkHarness) SuspendNode(node *HarnessNode) (func() error, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
restart := func() error {
|
restart := func() error {
|
||||||
return node.start(n.lndErrorChan)
|
return node.start(n.lndBinary, n.lndErrorChan)
|
||||||
}
|
}
|
||||||
|
|
||||||
return restart, nil
|
return restart, nil
|
||||||
@ -687,13 +694,13 @@ func saveProfilesPage(node *HarnessNode) error {
|
|||||||
resp, err := http.Get(
|
resp, err := http.Get(
|
||||||
fmt.Sprintf(
|
fmt.Sprintf(
|
||||||
"http://localhost:%d/debug/pprof/goroutine?debug=1",
|
"http://localhost:%d/debug/pprof/goroutine?debug=1",
|
||||||
node.cfg.ProfilePort,
|
node.Cfg.ProfilePort,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Failed to get profile page "+
|
return fmt.Errorf("Failed to get profile page "+
|
||||||
"(node_id=%d, name=%s): %v\n",
|
"(node_id=%d, name=%s): %v\n",
|
||||||
node.NodeID, node.cfg.Name, err)
|
node.NodeID, node.Cfg.Name, err)
|
||||||
}
|
}
|
||||||
defer resp.Body.Close()
|
defer resp.Body.Close()
|
||||||
|
|
||||||
@ -701,11 +708,11 @@ func saveProfilesPage(node *HarnessNode) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Failed to read profile page "+
|
return fmt.Errorf("Failed to read profile page "+
|
||||||
"(node_id=%d, name=%s): %v\n",
|
"(node_id=%d, name=%s): %v\n",
|
||||||
node.NodeID, node.cfg.Name, err)
|
node.NodeID, node.Cfg.Name, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
fileName := fmt.Sprintf(
|
fileName := fmt.Sprintf(
|
||||||
"pprof-%d-%s-%s.log", node.NodeID, node.cfg.Name,
|
"pprof-%d-%s-%s.log", node.NodeID, node.Cfg.Name,
|
||||||
hex.EncodeToString(node.PubKey[:logPubKeyBytes]),
|
hex.EncodeToString(node.PubKey[:logPubKeyBytes]),
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -713,7 +720,7 @@ func saveProfilesPage(node *HarnessNode) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Failed to create file for profile page "+
|
return fmt.Errorf("Failed to create file for profile page "+
|
||||||
"(node_id=%d, name=%s): %v\n",
|
"(node_id=%d, name=%s): %v\n",
|
||||||
node.NodeID, node.cfg.Name, err)
|
node.NodeID, node.Cfg.Name, err)
|
||||||
}
|
}
|
||||||
defer logFile.Close()
|
defer logFile.Close()
|
||||||
|
|
||||||
@ -721,7 +728,7 @@ func saveProfilesPage(node *HarnessNode) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Failed to save profile page "+
|
return fmt.Errorf("Failed to save profile page "+
|
||||||
"(node_id=%d, name=%s): %v\n",
|
"(node_id=%d, name=%s): %v\n",
|
||||||
node.NodeID, node.cfg.Name, err)
|
node.NodeID, node.Cfg.Name, err)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -1227,7 +1234,7 @@ func (n *NetworkHarness) AssertChannelExists(ctx context.Context,
|
|||||||
// Logs from lightning node being generated with delay - you should
|
// Logs from lightning node being generated with delay - you should
|
||||||
// add time.Sleep() in order to get all logs.
|
// add time.Sleep() in order to get all logs.
|
||||||
func (n *NetworkHarness) DumpLogs(node *HarnessNode) (string, error) {
|
func (n *NetworkHarness) DumpLogs(node *HarnessNode) (string, error) {
|
||||||
logFile := fmt.Sprintf("%v/simnet/lnd.log", node.cfg.LogDir)
|
logFile := fmt.Sprintf("%v/simnet/lnd.log", node.Cfg.LogDir)
|
||||||
|
|
||||||
buf, err := ioutil.ReadFile(logFile)
|
buf, err := ioutil.ReadFile(logFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -1324,7 +1331,7 @@ func (n *NetworkHarness) sendCoins(ctx context.Context, amt btcutil.Amount,
|
|||||||
err = wait.NoError(func() error {
|
err = wait.NoError(func() error {
|
||||||
// Since neutrino doesn't support unconfirmed outputs, skip
|
// Since neutrino doesn't support unconfirmed outputs, skip
|
||||||
// this check.
|
// this check.
|
||||||
if target.cfg.BackendCfg.Name() == "neutrino" {
|
if target.Cfg.BackendCfg.Name() == "neutrino" {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,6 +58,7 @@ const (
|
|||||||
minerMempoolTimeout = lntest.MinerMempoolTimeout
|
minerMempoolTimeout = lntest.MinerMempoolTimeout
|
||||||
channelOpenTimeout = lntest.ChannelOpenTimeout
|
channelOpenTimeout = lntest.ChannelOpenTimeout
|
||||||
channelCloseTimeout = lntest.ChannelCloseTimeout
|
channelCloseTimeout = lntest.ChannelCloseTimeout
|
||||||
|
itestLndBinary = "../../lnd-itest"
|
||||||
)
|
)
|
||||||
|
|
||||||
// harnessTest wraps a regular testing.T providing enhanced error detection
|
// harnessTest wraps a regular testing.T providing enhanced error detection
|
||||||
@ -15298,7 +15299,9 @@ func TestLightningNetworkDaemon(t *testing.T) {
|
|||||||
|
|
||||||
// Now we can set up our test harness (LND instance), with the chain
|
// Now we can set up our test harness (LND instance), with the chain
|
||||||
// backend we just created.
|
// backend we just created.
|
||||||
lndHarness, err = lntest.NewNetworkHarness(miner, chainBackend)
|
lndHarness, err = lntest.NewNetworkHarness(
|
||||||
|
miner, chainBackend, itestLndBinary,
|
||||||
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ht.Fatalf("unable to create lightning network harness: %v", err)
|
ht.Fatalf("unable to create lightning network harness: %v", err)
|
||||||
}
|
}
|
||||||
|
@ -130,7 +130,7 @@ type BackendConfig interface {
|
|||||||
Name() string
|
Name() string
|
||||||
}
|
}
|
||||||
|
|
||||||
type nodeConfig struct {
|
type NodeConfig struct {
|
||||||
Name string
|
Name string
|
||||||
BackendCfg BackendConfig
|
BackendCfg BackendConfig
|
||||||
NetParams *chaincfg.Params
|
NetParams *chaincfg.Params
|
||||||
@ -156,24 +156,24 @@ type nodeConfig struct {
|
|||||||
AcceptKeySend bool
|
AcceptKeySend bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cfg nodeConfig) P2PAddr() string {
|
func (cfg NodeConfig) P2PAddr() string {
|
||||||
return net.JoinHostPort("127.0.0.1", strconv.Itoa(cfg.P2PPort))
|
return net.JoinHostPort("127.0.0.1", strconv.Itoa(cfg.P2PPort))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cfg nodeConfig) RPCAddr() string {
|
func (cfg NodeConfig) RPCAddr() string {
|
||||||
return net.JoinHostPort("127.0.0.1", strconv.Itoa(cfg.RPCPort))
|
return net.JoinHostPort("127.0.0.1", strconv.Itoa(cfg.RPCPort))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cfg nodeConfig) RESTAddr() string {
|
func (cfg NodeConfig) RESTAddr() string {
|
||||||
return net.JoinHostPort("127.0.0.1", strconv.Itoa(cfg.RESTPort))
|
return net.JoinHostPort("127.0.0.1", strconv.Itoa(cfg.RESTPort))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cfg nodeConfig) DBPath() string {
|
func (cfg NodeConfig) DBPath() string {
|
||||||
return filepath.Join(cfg.DataDir, "graph",
|
return filepath.Join(cfg.DataDir, "graph",
|
||||||
fmt.Sprintf("%v/channel.db", cfg.NetParams.Name))
|
fmt.Sprintf("%v/channel.db", cfg.NetParams.Name))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cfg nodeConfig) ChanBackupPath() string {
|
func (cfg NodeConfig) ChanBackupPath() string {
|
||||||
return filepath.Join(
|
return filepath.Join(
|
||||||
cfg.DataDir, "chain", "bitcoin",
|
cfg.DataDir, "chain", "bitcoin",
|
||||||
fmt.Sprintf(
|
fmt.Sprintf(
|
||||||
@ -185,7 +185,7 @@ func (cfg nodeConfig) ChanBackupPath() string {
|
|||||||
|
|
||||||
// genArgs generates a slice of command line arguments from the lightning node
|
// genArgs generates a slice of command line arguments from the lightning node
|
||||||
// config struct.
|
// config struct.
|
||||||
func (cfg nodeConfig) genArgs() []string {
|
func (cfg NodeConfig) genArgs() []string {
|
||||||
var args []string
|
var args []string
|
||||||
|
|
||||||
switch cfg.NetParams {
|
switch cfg.NetParams {
|
||||||
@ -238,7 +238,7 @@ func (cfg nodeConfig) genArgs() []string {
|
|||||||
// harness. Each HarnessNode instance also fully embeds an RPC client in
|
// harness. Each HarnessNode instance also fully embeds an RPC client in
|
||||||
// order to pragmatically drive the node.
|
// order to pragmatically drive the node.
|
||||||
type HarnessNode struct {
|
type HarnessNode struct {
|
||||||
cfg *nodeConfig
|
Cfg *NodeConfig
|
||||||
|
|
||||||
// NodeID is a unique identifier for the node within a NetworkHarness.
|
// NodeID is a unique identifier for the node within a NetworkHarness.
|
||||||
NodeID int
|
NodeID int
|
||||||
@ -292,7 +292,7 @@ var _ lnrpc.WalletUnlockerClient = (*HarnessNode)(nil)
|
|||||||
var _ invoicesrpc.InvoicesClient = (*HarnessNode)(nil)
|
var _ invoicesrpc.InvoicesClient = (*HarnessNode)(nil)
|
||||||
|
|
||||||
// newNode creates a new test lightning node instance from the passed config.
|
// newNode creates a new test lightning node instance from the passed config.
|
||||||
func newNode(cfg nodeConfig) (*HarnessNode, error) {
|
func newNode(cfg NodeConfig) (*HarnessNode, error) {
|
||||||
if cfg.BaseDir == "" {
|
if cfg.BaseDir == "" {
|
||||||
var err error
|
var err error
|
||||||
cfg.BaseDir, err = ioutil.TempDir("", "lndtest-node")
|
cfg.BaseDir, err = ioutil.TempDir("", "lndtest-node")
|
||||||
@ -304,9 +304,13 @@ func newNode(cfg nodeConfig) (*HarnessNode, error) {
|
|||||||
cfg.LogDir = filepath.Join(cfg.BaseDir, "log")
|
cfg.LogDir = filepath.Join(cfg.BaseDir, "log")
|
||||||
cfg.TLSCertPath = filepath.Join(cfg.DataDir, "tls.cert")
|
cfg.TLSCertPath = filepath.Join(cfg.DataDir, "tls.cert")
|
||||||
cfg.TLSKeyPath = filepath.Join(cfg.DataDir, "tls.key")
|
cfg.TLSKeyPath = filepath.Join(cfg.DataDir, "tls.key")
|
||||||
cfg.AdminMacPath = filepath.Join(cfg.DataDir, "admin.macaroon")
|
|
||||||
cfg.ReadMacPath = filepath.Join(cfg.DataDir, "readonly.macaroon")
|
networkDir := filepath.Join(
|
||||||
cfg.InvoiceMacPath = filepath.Join(cfg.DataDir, "invoice.macaroon")
|
cfg.DataDir, "chain", "bitcoin", cfg.NetParams.Name,
|
||||||
|
)
|
||||||
|
cfg.AdminMacPath = filepath.Join(networkDir, "admin.macaroon")
|
||||||
|
cfg.ReadMacPath = filepath.Join(networkDir, "readonly.macaroon")
|
||||||
|
cfg.InvoiceMacPath = filepath.Join(networkDir, "invoice.macaroon")
|
||||||
|
|
||||||
cfg.P2PPort, cfg.RPCPort, cfg.RESTPort, cfg.ProfilePort = generateListeningPorts()
|
cfg.P2PPort, cfg.RPCPort, cfg.RESTPort, cfg.ProfilePort = generateListeningPorts()
|
||||||
|
|
||||||
@ -321,7 +325,7 @@ func newNode(cfg nodeConfig) (*HarnessNode, error) {
|
|||||||
numActiveNodesMtx.Unlock()
|
numActiveNodesMtx.Unlock()
|
||||||
|
|
||||||
return &HarnessNode{
|
return &HarnessNode{
|
||||||
cfg: &cfg,
|
Cfg: &cfg,
|
||||||
NodeID: nodeNum,
|
NodeID: nodeNum,
|
||||||
chanWatchRequests: make(chan *chanWatchRequest),
|
chanWatchRequests: make(chan *chanWatchRequest),
|
||||||
openChans: make(map[wire.OutPoint]int),
|
openChans: make(map[wire.OutPoint]int),
|
||||||
@ -334,44 +338,44 @@ func newNode(cfg nodeConfig) (*HarnessNode, error) {
|
|||||||
|
|
||||||
// DBPath returns the filepath to the channeldb database file for this node.
|
// DBPath returns the filepath to the channeldb database file for this node.
|
||||||
func (hn *HarnessNode) DBPath() string {
|
func (hn *HarnessNode) DBPath() string {
|
||||||
return hn.cfg.DBPath()
|
return hn.Cfg.DBPath()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Name returns the name of this node set during initialization.
|
// Name returns the name of this node set during initialization.
|
||||||
func (hn *HarnessNode) Name() string {
|
func (hn *HarnessNode) Name() string {
|
||||||
return hn.cfg.Name
|
return hn.Cfg.Name
|
||||||
}
|
}
|
||||||
|
|
||||||
// TLSCertStr returns the path where the TLS certificate is stored.
|
// TLSCertStr returns the path where the TLS certificate is stored.
|
||||||
func (hn *HarnessNode) TLSCertStr() string {
|
func (hn *HarnessNode) TLSCertStr() string {
|
||||||
return hn.cfg.TLSCertPath
|
return hn.Cfg.TLSCertPath
|
||||||
}
|
}
|
||||||
|
|
||||||
// TLSKeyStr returns the path where the TLS key is stored.
|
// TLSKeyStr returns the path where the TLS key is stored.
|
||||||
func (hn *HarnessNode) TLSKeyStr() string {
|
func (hn *HarnessNode) TLSKeyStr() string {
|
||||||
return hn.cfg.TLSKeyPath
|
return hn.Cfg.TLSKeyPath
|
||||||
}
|
}
|
||||||
|
|
||||||
// ChanBackupPath returns the fielpath to the on-disk channels.backup file for
|
// ChanBackupPath returns the fielpath to the on-disk channels.backup file for
|
||||||
// this node.
|
// this node.
|
||||||
func (hn *HarnessNode) ChanBackupPath() string {
|
func (hn *HarnessNode) ChanBackupPath() string {
|
||||||
return hn.cfg.ChanBackupPath()
|
return hn.Cfg.ChanBackupPath()
|
||||||
}
|
}
|
||||||
|
|
||||||
// AdminMacPath returns the filepath to the admin.macaroon file for this node.
|
// AdminMacPath returns the filepath to the admin.macaroon file for this node.
|
||||||
func (hn *HarnessNode) AdminMacPath() string {
|
func (hn *HarnessNode) AdminMacPath() string {
|
||||||
return hn.cfg.AdminMacPath
|
return hn.Cfg.AdminMacPath
|
||||||
}
|
}
|
||||||
|
|
||||||
// ReadMacPath returns the filepath to the readonly.macaroon file for this node.
|
// ReadMacPath returns the filepath to the readonly.macaroon file for this node.
|
||||||
func (hn *HarnessNode) ReadMacPath() string {
|
func (hn *HarnessNode) ReadMacPath() string {
|
||||||
return hn.cfg.ReadMacPath
|
return hn.Cfg.ReadMacPath
|
||||||
}
|
}
|
||||||
|
|
||||||
// InvoiceMacPath returns the filepath to the invoice.macaroon file for this
|
// InvoiceMacPath returns the filepath to the invoice.macaroon file for this
|
||||||
// node.
|
// node.
|
||||||
func (hn *HarnessNode) InvoiceMacPath() string {
|
func (hn *HarnessNode) InvoiceMacPath() string {
|
||||||
return hn.cfg.InvoiceMacPath
|
return hn.Cfg.InvoiceMacPath
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start launches a new process running lnd. Additionally, the PID of the
|
// Start launches a new process running lnd. Additionally, the PID of the
|
||||||
@ -380,11 +384,11 @@ func (hn *HarnessNode) InvoiceMacPath() string {
|
|||||||
//
|
//
|
||||||
// This may not clean up properly if an error is returned, so the caller should
|
// This may not clean up properly if an error is returned, so the caller should
|
||||||
// call shutdown() regardless of the return value.
|
// call shutdown() regardless of the return value.
|
||||||
func (hn *HarnessNode) start(lndError chan<- error) error {
|
func (hn *HarnessNode) start(lndBinary string, lndError chan<- error) error {
|
||||||
hn.quit = make(chan struct{})
|
hn.quit = make(chan struct{})
|
||||||
|
|
||||||
args := hn.cfg.genArgs()
|
args := hn.Cfg.genArgs()
|
||||||
hn.cmd = exec.Command("../../lnd-itest", args...)
|
hn.cmd = exec.Command(lndBinary, args...)
|
||||||
|
|
||||||
// Redirect stderr output to buffer
|
// Redirect stderr output to buffer
|
||||||
var errb bytes.Buffer
|
var errb bytes.Buffer
|
||||||
@ -402,14 +406,14 @@ func (hn *HarnessNode) start(lndError chan<- error) error {
|
|||||||
// log files.
|
// log files.
|
||||||
if *logOutput {
|
if *logOutput {
|
||||||
fileName := fmt.Sprintf("output-%d-%s-%s.log", hn.NodeID,
|
fileName := fmt.Sprintf("output-%d-%s-%s.log", hn.NodeID,
|
||||||
hn.cfg.Name, hex.EncodeToString(hn.PubKey[:logPubKeyBytes]))
|
hn.Cfg.Name, hex.EncodeToString(hn.PubKey[:logPubKeyBytes]))
|
||||||
|
|
||||||
// If the node's PubKey is not yet initialized, create a temporary
|
// If the node's PubKey is not yet initialized, create a temporary
|
||||||
// file name. Later, after the PubKey has been initialized, the
|
// file name. Later, after the PubKey has been initialized, the
|
||||||
// file can be moved to its final name with the PubKey included.
|
// file can be moved to its final name with the PubKey included.
|
||||||
if bytes.Equal(hn.PubKey[:4], []byte{0, 0, 0, 0}) {
|
if bytes.Equal(hn.PubKey[:4], []byte{0, 0, 0, 0}) {
|
||||||
fileName = fmt.Sprintf("output-%d-%s-tmp__.log", hn.NodeID,
|
fileName = fmt.Sprintf("output-%d-%s-tmp__.log", hn.NodeID,
|
||||||
hn.cfg.Name)
|
hn.Cfg.Name)
|
||||||
|
|
||||||
// Once the node has done its work, the log file can be renamed.
|
// Once the node has done its work, the log file can be renamed.
|
||||||
finalizeLogfile = func() {
|
finalizeLogfile = func() {
|
||||||
@ -417,7 +421,7 @@ func (hn *HarnessNode) start(lndError chan<- error) error {
|
|||||||
hn.logFile.Close()
|
hn.logFile.Close()
|
||||||
|
|
||||||
newFileName := fmt.Sprintf("output-%d-%s-%s.log",
|
newFileName := fmt.Sprintf("output-%d-%s-%s.log",
|
||||||
hn.NodeID, hn.cfg.Name,
|
hn.NodeID, hn.Cfg.Name,
|
||||||
hex.EncodeToString(hn.PubKey[:logPubKeyBytes]))
|
hex.EncodeToString(hn.PubKey[:logPubKeyBytes]))
|
||||||
err := os.Rename(fileName, newFileName)
|
err := os.Rename(fileName, newFileName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -480,7 +484,7 @@ func (hn *HarnessNode) start(lndError chan<- error) error {
|
|||||||
|
|
||||||
// Since Stop uses the LightningClient to stop the node, if we fail to get a
|
// Since Stop uses the LightningClient to stop the node, if we fail to get a
|
||||||
// connected client, we have to kill the process.
|
// connected client, we have to kill the process.
|
||||||
useMacaroons := !hn.cfg.HasSeed
|
useMacaroons := !hn.Cfg.HasSeed
|
||||||
conn, err := hn.ConnectRPC(useMacaroons)
|
conn, err := hn.ConnectRPC(useMacaroons)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
hn.cmd.Process.Kill()
|
hn.cmd.Process.Kill()
|
||||||
@ -491,7 +495,7 @@ func (hn *HarnessNode) start(lndError chan<- error) error {
|
|||||||
// additional step to unlock the wallet. The connection returned will
|
// additional step to unlock the wallet. The connection returned will
|
||||||
// only use the TLS certs, and can only perform operations necessary to
|
// only use the TLS certs, and can only perform operations necessary to
|
||||||
// unlock the daemon.
|
// unlock the daemon.
|
||||||
if hn.cfg.HasSeed {
|
if hn.Cfg.HasSeed {
|
||||||
hn.WalletUnlockerClient = lnrpc.NewWalletUnlockerClient(conn)
|
hn.WalletUnlockerClient = lnrpc.NewWalletUnlockerClient(conn)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -656,7 +660,7 @@ func (hn *HarnessNode) AddToLog(line string) error {
|
|||||||
|
|
||||||
// writePidFile writes the process ID of the running lnd process to a .pid file.
|
// writePidFile writes the process ID of the running lnd process to a .pid file.
|
||||||
func (hn *HarnessNode) writePidFile() error {
|
func (hn *HarnessNode) writePidFile() error {
|
||||||
filePath := filepath.Join(hn.cfg.BaseDir, fmt.Sprintf("%v.pid", hn.NodeID))
|
filePath := filepath.Join(hn.Cfg.BaseDir, fmt.Sprintf("%v.pid", hn.NodeID))
|
||||||
|
|
||||||
pid, err := os.Create(filePath)
|
pid, err := os.Create(filePath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -710,7 +714,7 @@ func (hn *HarnessNode) ConnectRPCWithMacaroon(mac *macaroon.Macaroon) (
|
|||||||
|
|
||||||
// Wait until TLS certificate is created before using it, up to 30 sec.
|
// Wait until TLS certificate is created before using it, up to 30 sec.
|
||||||
tlsTimeout := time.After(DefaultTimeout)
|
tlsTimeout := time.After(DefaultTimeout)
|
||||||
for !fileExists(hn.cfg.TLSCertPath) {
|
for !fileExists(hn.Cfg.TLSCertPath) {
|
||||||
select {
|
select {
|
||||||
case <-tlsTimeout:
|
case <-tlsTimeout:
|
||||||
return nil, fmt.Errorf("timeout waiting for TLS cert " +
|
return nil, fmt.Errorf("timeout waiting for TLS cert " +
|
||||||
@ -721,7 +725,7 @@ func (hn *HarnessNode) ConnectRPCWithMacaroon(mac *macaroon.Macaroon) (
|
|||||||
|
|
||||||
opts := []grpc.DialOption{grpc.WithBlock()}
|
opts := []grpc.DialOption{grpc.WithBlock()}
|
||||||
tlsCreds, err := credentials.NewClientTLSFromFile(
|
tlsCreds, err := credentials.NewClientTLSFromFile(
|
||||||
hn.cfg.TLSCertPath, "",
|
hn.Cfg.TLSCertPath, "",
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -729,14 +733,14 @@ func (hn *HarnessNode) ConnectRPCWithMacaroon(mac *macaroon.Macaroon) (
|
|||||||
opts = append(opts, grpc.WithTransportCredentials(tlsCreds))
|
opts = append(opts, grpc.WithTransportCredentials(tlsCreds))
|
||||||
|
|
||||||
if mac == nil {
|
if mac == nil {
|
||||||
return grpc.Dial(hn.cfg.RPCAddr(), opts...)
|
return grpc.Dial(hn.Cfg.RPCAddr(), opts...)
|
||||||
}
|
}
|
||||||
macCred := macaroons.NewMacaroonCredential(mac)
|
macCred := macaroons.NewMacaroonCredential(mac)
|
||||||
opts = append(opts, grpc.WithPerRPCCredentials(macCred))
|
opts = append(opts, grpc.WithPerRPCCredentials(macCred))
|
||||||
|
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), DefaultTimeout)
|
ctx, cancel := context.WithTimeout(context.Background(), DefaultTimeout)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
return grpc.DialContext(ctx, hn.cfg.RPCAddr(), opts...)
|
return grpc.DialContext(ctx, hn.Cfg.RPCAddr(), opts...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ConnectRPC uses the TLS certificate and admin macaroon files written by the
|
// ConnectRPC uses the TLS certificate and admin macaroon files written by the
|
||||||
@ -750,7 +754,7 @@ func (hn *HarnessNode) ConnectRPC(useMacs bool) (*grpc.ClientConn, error) {
|
|||||||
|
|
||||||
// If we should use a macaroon, always take the admin macaroon as a
|
// If we should use a macaroon, always take the admin macaroon as a
|
||||||
// default.
|
// default.
|
||||||
mac, err := hn.ReadMacaroon(hn.cfg.AdminMacPath, DefaultTimeout)
|
mac, err := hn.ReadMacaroon(hn.Cfg.AdminMacPath, DefaultTimeout)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -760,12 +764,12 @@ func (hn *HarnessNode) ConnectRPC(useMacs bool) (*grpc.ClientConn, error) {
|
|||||||
// SetExtraArgs assigns the ExtraArgs field for the node's configuration. The
|
// SetExtraArgs assigns the ExtraArgs field for the node's configuration. The
|
||||||
// changes will take effect on restart.
|
// changes will take effect on restart.
|
||||||
func (hn *HarnessNode) SetExtraArgs(extraArgs []string) {
|
func (hn *HarnessNode) SetExtraArgs(extraArgs []string) {
|
||||||
hn.cfg.ExtraArgs = extraArgs
|
hn.Cfg.ExtraArgs = extraArgs
|
||||||
}
|
}
|
||||||
|
|
||||||
// cleanup cleans up all the temporary files created by the node's process.
|
// cleanup cleans up all the temporary files created by the node's process.
|
||||||
func (hn *HarnessNode) cleanup() error {
|
func (hn *HarnessNode) cleanup() error {
|
||||||
return os.RemoveAll(hn.cfg.BaseDir)
|
return os.RemoveAll(hn.Cfg.BaseDir)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stop attempts to stop the active lnd process.
|
// Stop attempts to stop the active lnd process.
|
||||||
|
Loading…
Reference in New Issue
Block a user