lntest

package
v0.12.1-beta.rc5-branch Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 17, 2021 License: MIT Imports: 44 Imported by: 0

Documentation

Overview

Package lntest provides testing utilities for the lnd repository.

This package contains infrastructure for integration tests that launch full lnd nodes in a controlled environment and interact with them via RPC. Using a NetworkHarness, a test can launch multiple lnd nodes, open channels between them, create defined network topologies, and anything else that is possible with RPC commands.

Index

Constants

View Source
const (
	// MinerMempoolTimeout is the max time we will wait for a transaction
	// to propagate to the mining node's mempool.
	MinerMempoolTimeout = time.Minute

	// ChannelOpenTimeout is the max time we will wait before a channel to
	// be considered opened.
	ChannelOpenTimeout = time.Second * 30

	// ChannelCloseTimeout is the max time we will wait before a channel is
	// considered closed.
	ChannelCloseTimeout = time.Second * 30

	// DefaultTimeout is a timeout that will be used for various wait
	// scenarios where no custom timeout value is defined.
	DefaultTimeout = time.Second * 30

	// AsyncBenchmarkTimeout is the timeout used when running the async
	// payments benchmark.
	AsyncBenchmarkTimeout = 2 * time.Minute
)
View Source
const DefaultCSV = 4

DefaultCSV is the CSV delay (remotedelay) we will start our test nodes with.

Variables

This section is empty.

Functions

func ApplyPortOffset

func ApplyPortOffset(offset uint32)

ApplyPortOffset adds the given offset to the lastPort variable, making it possible to run the tests in parallel without colliding on the same ports.

func CopyAll

func CopyAll(dstDir, srcDir string) error

CopyAll copies all files and directories from srcDir to dstDir recursively. Note that this function does not support links.

func CopyFile

func CopyFile(dest, src string) error

CopyFile copies the file src to dest.

func FileExists

func FileExists(path string) bool

FileExists returns true if the file at path exists.

func GenerateBtcdListenerAddresses

func GenerateBtcdListenerAddresses() (string, string)

GenerateBtcdListenerAddresses is a function that returns two listener addresses with unique ports and should be used to overwrite rpctest's default generator which is prone to use colliding ports.

func GetBtcdBinary

func GetBtcdBinary() string

GetBtcdBinary returns the full path to the binary of the custom built btcd executable or an empty string if none is set.

func GetLogDir

func GetLogDir() string

GetLogDir returns the passed --logdir flag or the default value if it wasn't set.

func NewMiner

func NewMiner(logDir, logFilename string, netParams *chaincfg.Params,
	handler *rpcclient.NotificationHandlers,
	btcdBinary string) (*rpctest.Harness, func() error, error)

NewMiner creates a new miner using btcd backend. The logDir specifies the miner node's log dir. When tests finished, during clean up, its logs are copied to a file specified as logFilename.

Types

type BackendConfig

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
}

BackendConfig is an interface that abstracts away the specific chain backend node implementation.

type BtcdBackendConfig

type BtcdBackendConfig struct {
	// contains filtered or unexported fields
}

BtcdBackendConfig is an implementation of the BackendConfig interface backed by a btcd node.

func NewBackend

func NewBackend(miner string, netParams *chaincfg.Params) (
	*BtcdBackendConfig, func() error, error)

NewBackend starts a new rpctest.Harness and returns a BtcdBackendConfig for that node. miner should be set to the P2P address of the miner to connect to.

func (BtcdBackendConfig) ConnectMiner

func (b BtcdBackendConfig) ConnectMiner() error

ConnectMiner is called to establish a connection to the test miner.

func (BtcdBackendConfig) DisconnectMiner

func (b BtcdBackendConfig) DisconnectMiner() error

DisconnectMiner is called to disconnect the miner.

func (BtcdBackendConfig) GenArgs

func (b BtcdBackendConfig) GenArgs() []string

GenArgs returns the arguments needed to be passed to LND at startup for using this node as a chain backend.

func (BtcdBackendConfig) Name

func (b BtcdBackendConfig) Name() string

Name returns the name of the backend type.

type HarnessNode

type HarnessNode struct {
	Cfg *NodeConfig

	// NodeID is a unique identifier for the node within a NetworkHarness.
	NodeID int

	// PubKey is the serialized compressed identity public key of the node.
	// This field will only be populated once the node itself has been
	// started via the start() method.
	PubKey    [33]byte
	PubKeyStr string

	lnrpc.LightningClient

	lnrpc.WalletUnlockerClient

	invoicesrpc.InvoicesClient

	// SignerClient cannot be embedded because the name collisions of the
	// methods SignMessage and VerifyMessage.
	SignerClient signrpc.SignerClient

	// RouterClient, WalletKitClient, WatchtowerClient cannot be embedded,
	// because a name collision would occur with LightningClient.
	RouterClient     routerrpc.RouterClient
	WalletKitClient  walletrpc.WalletKitClient
	Watchtower       watchtowerrpc.WatchtowerClient
	WatchtowerClient wtclientrpc.WatchtowerClientClient
	// contains filtered or unexported fields
}

HarnessNode represents an instance of lnd running within our test network harness. Each HarnessNode instance also fully embeds an RPC client in order to pragmatically drive the node.

func (*HarnessNode) AddToLog

func (hn *HarnessNode) AddToLog(line string) error

AddToLog adds a line of choice to the node's logfile. This is useful to interleave test output with output from the node.

func (*HarnessNode) AdminMacPath

func (hn *HarnessNode) AdminMacPath() string

AdminMacPath returns the filepath to the admin.macaroon file for this node.

func (*HarnessNode) ChanBackupPath

func (hn *HarnessNode) ChanBackupPath() string

ChanBackupPath returns the fielpath to the on-disk channels.backup file for this node.

func (*HarnessNode) ConnectRPC

func (hn *HarnessNode) ConnectRPC(useMacs bool) (*grpc.ClientConn, error)

ConnectRPC uses the TLS certificate and admin macaroon files written by the lnd node to create a gRPC client connection.

func (*HarnessNode) ConnectRPCWithMacaroon

func (hn *HarnessNode) ConnectRPCWithMacaroon(mac *macaroon.Macaroon) (
	*grpc.ClientConn, error)

ConnectRPCWithMacaroon uses the TLS certificate and given macaroon to create a gRPC client connection.

func (*HarnessNode) DBDir

func (hn *HarnessNode) DBDir() string

DBDir returns the path for the directory holding channeldb file(s).

func (*HarnessNode) DBPath

func (hn *HarnessNode) DBPath() string

DBPath returns the filepath to the channeldb database file for this node.

func (*HarnessNode) FetchNodeInfo

func (hn *HarnessNode) FetchNodeInfo() error

FetchNodeInfo queries an unlocked node to retrieve its public key.

func (*HarnessNode) Init

Init initializes a harness node by passing the init request via rpc. After the request is submitted, this method will block until a macaroon-authenticated RPC connection can be established to the harness node. Once established, the new connection is used to initialize the LightningClient and subscribes the HarnessNode to topology changes.

func (*HarnessNode) InitChangePassword

func (hn *HarnessNode) InitChangePassword(ctx context.Context,
	chngPwReq *lnrpc.ChangePasswordRequest) (*lnrpc.ChangePasswordResponse,
	error)

InitChangePassword initializes a harness node by passing the change password request via RPC. After the request is submitted, this method will block until a macaroon-authenticated RPC connection can be established to the harness node. Once established, the new connection is used to initialize the LightningClient and subscribes the HarnessNode to topology changes.

func (*HarnessNode) InvoiceMacPath

func (hn *HarnessNode) InvoiceMacPath() string

InvoiceMacPath returns the filepath to the invoice.macaroon file for this node.

func (*HarnessNode) Name

func (hn *HarnessNode) Name() string

Name returns the name of this node set during initialization.

func (*HarnessNode) ReadMacPath

func (hn *HarnessNode) ReadMacPath() string

ReadMacPath returns the filepath to the readonly.macaroon file for this node.

func (*HarnessNode) ReadMacaroon

func (hn *HarnessNode) ReadMacaroon(macPath string, timeout time.Duration) (
	*macaroon.Macaroon, error)

ReadMacaroon waits a given duration for the macaroon file to be created. If the file is readable within the timeout, its content is de-serialized as a macaroon and returned.

func (*HarnessNode) SetExtraArgs

func (hn *HarnessNode) SetExtraArgs(extraArgs []string)

SetExtraArgs assigns the ExtraArgs field for the node's configuration. The changes will take effect on restart.

func (*HarnessNode) TLSCertStr

func (hn *HarnessNode) TLSCertStr() string

TLSCertStr returns the path where the TLS certificate is stored.

func (*HarnessNode) TLSKeyStr

func (hn *HarnessNode) TLSKeyStr() string

TLSKeyStr returns the path where the TLS key is stored.

func (*HarnessNode) Unlock

func (hn *HarnessNode) Unlock(ctx context.Context,
	unlockReq *lnrpc.UnlockWalletRequest) error

Unlock attempts to unlock the wallet of the target HarnessNode. This method should be called after the restart of a HarnessNode that was created with a seed+password. Once this method returns, the HarnessNode will be ready to accept normal gRPC requests and harness command.

func (*HarnessNode) WaitForBalance

func (hn *HarnessNode) WaitForBalance(expectedBalance btcutil.Amount, confirmed bool) error

WaitForBalance waits until the node sees the expected confirmed/unconfirmed balance within their wallet.

func (*HarnessNode) WaitForBlockchainSync

func (hn *HarnessNode) WaitForBlockchainSync(ctx context.Context) error

WaitForBlockchainSync will block until the target nodes has fully synchronized with the blockchain. If the passed context object has a set timeout, then the goroutine will continually poll until the timeout has elapsed. In the case that the chain isn't synced before the timeout is up, then this function will return an error.

func (*HarnessNode) WaitForNetworkChannelClose

func (hn *HarnessNode) WaitForNetworkChannelClose(ctx context.Context,
	op *lnrpc.ChannelPoint) error

WaitForNetworkChannelClose will block until a channel with the target outpoint is seen as closed within the network. A channel is considered closed once a transaction spending the funding outpoint is seen within a confirmed block.

func (*HarnessNode) WaitForNetworkChannelOpen

func (hn *HarnessNode) WaitForNetworkChannelOpen(ctx context.Context,
	op *lnrpc.ChannelPoint) error

WaitForNetworkChannelOpen will block until a channel with the target outpoint is seen as being fully advertised within the network. A channel is considered "fully advertised" once both of its directional edges has been advertised within the test Lightning Network.

type NetworkHarness

type NetworkHarness struct {

	// Miner is a reference to a running full node that can be used to create
	// new blocks on the network.
	Miner *rpctest.Harness

	// BackendCfg houses the information necessary to use a node as LND
	// chain backend, such as rpc configuration, P2P information etc.
	BackendCfg BackendConfig

	// Alice and Bob are the initial seeder nodes that are automatically
	// created to be the initial participants of the test network.
	Alice *HarnessNode
	Bob   *HarnessNode
	// contains filtered or unexported fields
}

NetworkHarness is an integration testing harness for the lightning network. The harness by default is created with two active nodes on the network: Alice and Bob.

func NewNetworkHarness

func NewNetworkHarness(r *rpctest.Harness, b BackendConfig, lndBinary string,
	useEtcd bool) (*NetworkHarness, error)

NewNetworkHarness creates a new network test harness. 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` within the repo each time before changes

func (*NetworkHarness) AssertChannelExists

func (n *NetworkHarness) AssertChannelExists(ctx context.Context,
	node *HarnessNode, chanPoint *wire.OutPoint,
	checks ...func(*lnrpc.Channel)) error

AssertChannelExists asserts that an active channel identified by the specified channel point exists from the point-of-view of the node. It takes an optional set of check functions which can be used to make further assertions using channel's values. These functions are responsible for failing the test themselves if they do not pass. nolint: interfacer

func (*NetworkHarness) CloseChannel

CloseChannel attempts to close the channel indicated by the passed channel point, initiated by the passed lnNode. If the passed context has a timeout, an error is returned if that timeout is reached before the channel close is pending.

func (*NetworkHarness) ConnectNodes

func (n *NetworkHarness) ConnectNodes(ctx context.Context, a, b *HarnessNode) error

ConnectNodes establishes an encrypted+authenticated p2p connection from node a towards node b. The function will return a non-nil error if the connection was unable to be established.

NOTE: This function may block for up to 15-seconds as it will not return until the new connection is detected as being known to both nodes.

func (*NetworkHarness) DisconnectNodes

func (n *NetworkHarness) DisconnectNodes(ctx context.Context, a, b *HarnessNode) error

DisconnectNodes disconnects node a from node b by sending RPC message from a node to b node

func (*NetworkHarness) DumpLogs

func (n *NetworkHarness) DumpLogs(node *HarnessNode) (string, error)

DumpLogs reads the current logs generated by the passed node, and returns the logs as a single string. This function is useful for examining the logs of a particular node in the case of a test failure. Logs from lightning node being generated with delay - you should add time.Sleep() in order to get all logs.

func (*NetworkHarness) EnsureConnected

func (n *NetworkHarness) EnsureConnected(ctx context.Context, a, b *HarnessNode) error

EnsureConnected will try to connect to two nodes, returning no error if they are already connected. If the nodes were not connected previously, this will behave the same as ConnectNodes. If a pending connection request has already been made, the method will block until the two nodes appear in each other's peers list, or until the 15s timeout expires.

func (*NetworkHarness) LookUpNodeByPub

func (n *NetworkHarness) LookUpNodeByPub(pubStr string) (*HarnessNode, error)

LookUpNodeByPub queries the set of active nodes to locate a node according to its public key. The second value will be true if the node was found, and false otherwise.

func (*NetworkHarness) NewNode

func (n *NetworkHarness) NewNode(name string, extraArgs []string) (*HarnessNode, error)

NewNode fully initializes a returns a new HarnessNode bound to the current instance of the network harness. The created node is running, but not yet connected to other nodes within the network.

func (*NetworkHarness) NewNodeWithSeed

func (n *NetworkHarness) NewNodeWithSeed(name string, extraArgs []string,
	password []byte, statelessInit bool) (*HarnessNode, []string, []byte,
	error)

NewNodeWithSeed fully initializes a new HarnessNode after creating a fresh aezeed. The provided password is used as both the aezeed password and the wallet password. The generated mnemonic is returned along with the initialized harness node.

func (*NetworkHarness) OpenChannel

func (n *NetworkHarness) OpenChannel(ctx context.Context,
	srcNode, destNode *HarnessNode, p OpenChannelParams) (
	lnrpc.Lightning_OpenChannelClient, error)

OpenChannel attempts to open a channel between srcNode and destNode with the passed channel funding parameters. If the passed context has a timeout, then if the timeout is reached before the channel pending notification is received, an error is returned. The confirmed boolean determines whether we should fund the channel with confirmed outputs or not.

func (*NetworkHarness) OpenPendingChannel

func (n *NetworkHarness) OpenPendingChannel(ctx context.Context,
	srcNode, destNode *HarnessNode, amt btcutil.Amount,
	pushAmt btcutil.Amount) (*lnrpc.PendingUpdate, error)

OpenPendingChannel attempts to open a channel between srcNode and destNode with the passed channel funding parameters. If the passed context has a timeout, then if the timeout is reached before the channel pending notification is received, an error is returned.

func (*NetworkHarness) ProcessErrors

func (n *NetworkHarness) ProcessErrors() <-chan error

ProcessErrors returns a channel used for reporting any fatal process errors. If any of the active nodes within the harness' test network incur a fatal error, that error is sent over this channel.

func (*NetworkHarness) RegisterNode

func (n *NetworkHarness) RegisterNode(node *HarnessNode)

RegisterNode records a new HarnessNode in the NetworkHarnesses map of known nodes. This method should only be called with nodes that have successfully retrieved their public keys via FetchNodeInfo.

func (*NetworkHarness) RestartNode

func (n *NetworkHarness) RestartNode(node *HarnessNode, callback func() error,
	chanBackups ...*lnrpc.ChanBackupSnapshot) error

RestartNode attempts to restart a lightning node by shutting it down cleanly, then restarting the process. This function is fully blocking. Upon restart, the RPC connection to the node will be re-attempted, continuing iff the connection attempt is successful. If the callback parameter is non-nil, then the function will be executed after the node shuts down, but *before* the process has been started up again.

This method can be useful when testing edge cases such as a node broadcast and invalidated prior state, or persistent state recovery, simulating node crashes, etc. Additionally, each time the node is restarted, the caller can pass a set of SCBs to pass in via the Unlock method allowing them to restore channels during restart.

func (*NetworkHarness) RestartNodeNoUnlock

func (n *NetworkHarness) RestartNodeNoUnlock(node *HarnessNode,
	callback func() error) error

RestartNodeNoUnlock attempts to restart a lightning node by shutting it down cleanly, then restarting the process. In case the node was setup with a seed, it will be left in the unlocked state. This function is fully blocking. If the callback parameter is non-nil, then the function will be executed after the node shuts down, but *before* the process has been started up again.

func (*NetworkHarness) RestoreNodeWithSeed

func (n *NetworkHarness) RestoreNodeWithSeed(name string, extraArgs []string,
	password []byte, mnemonic []string, recoveryWindow int32,
	chanBackups *lnrpc.ChanBackupSnapshot) (*HarnessNode, error)

RestoreNodeWithSeed fully initializes a HarnessNode using a chosen mnemonic, password, recovery window, and optionally a set of static channel backups. After providing the initialization request to unlock the node, this method will finish initializing the LightningClient such that the HarnessNode can be used for regular rpc operations.

func (*NetworkHarness) SaveProfilesPages

func (n *NetworkHarness) SaveProfilesPages()

SaveProfilesPages hits profiles pages of all active nodes and writes it to disk using a similar naming scheme as to the regular set of logs.

func (*NetworkHarness) SendCoins

func (n *NetworkHarness) SendCoins(ctx context.Context, amt btcutil.Amount,
	target *HarnessNode) error

SendCoins attempts to send amt satoshis from the internal mining node to the targeted lightning node using a P2WKH address. 6 blocks are mined after in order to confirm the transaction.

func (*NetworkHarness) SendCoinsNP2WKH

func (n *NetworkHarness) SendCoinsNP2WKH(ctx context.Context,
	amt btcutil.Amount, target *HarnessNode) error

SendCoinsNP2WKH attempts to send amt satoshis from the internal mining node to the targeted lightning node using a NP2WKH address.

func (*NetworkHarness) SendCoinsUnconfirmed

func (n *NetworkHarness) SendCoinsUnconfirmed(ctx context.Context,
	amt btcutil.Amount, target *HarnessNode) error

SendCoinsUnconfirmed sends coins from the internal mining node to the target lightning node using a P2WPKH address. No blocks are mined after, so the transaction remains unconfirmed.

func (*NetworkHarness) SetFeeEstimate

func (n *NetworkHarness) SetFeeEstimate(fee chainfee.SatPerKWeight)

func (*NetworkHarness) SetUp

func (n *NetworkHarness) SetUp(testCase string, lndArgs []string) error

SetUp starts the initial seeder nodes within the test harness. The initial node's wallets will be funded wallets with ten 1 BTC outputs each. Finally rpc clients capable of communicating with the initial seeder nodes are created. Nodes are initialized with the given extra command line flags, which should be formatted properly - "--arg=value".

func (*NetworkHarness) ShutdownNode

func (n *NetworkHarness) ShutdownNode(node *HarnessNode) error

ShutdownNode stops an active lnd process and returns when the process has exited and any temporary directories have been cleaned up.

func (*NetworkHarness) Stop

func (n *NetworkHarness) Stop()

Stop stops the test harness.

func (*NetworkHarness) StopNode

func (n *NetworkHarness) StopNode(node *HarnessNode) error

StopNode stops the target node, but doesn't yet clean up its directories. This can be used to temporarily bring a node down during a test, to be later started up again.

func (*NetworkHarness) SuspendNode

func (n *NetworkHarness) SuspendNode(node *HarnessNode) (func() error, error)

SuspendNode stops the given node and returns a callback that can be used to start it again.

func (*NetworkHarness) TearDown

func (n *NetworkHarness) TearDown() error

TearDown tears down all active nodes within the test lightning network.

func (*NetworkHarness) WaitForChannelClose

func (n *NetworkHarness) WaitForChannelClose(ctx context.Context,
	closeChanStream lnrpc.Lightning_CloseChannelClient) (*chainhash.Hash, error)

WaitForChannelClose waits for a notification from the passed channel close stream that the node has deemed the channel has been fully closed. If the passed context has a timeout, then if the timeout is reached before the notification is received then an error is returned.

func (*NetworkHarness) WaitForChannelOpen

func (n *NetworkHarness) WaitForChannelOpen(ctx context.Context,
	openChanStream lnrpc.Lightning_OpenChannelClient) (*lnrpc.ChannelPoint, error)

WaitForChannelOpen waits for a notification that a channel is open by consuming a message from the past open channel stream. If the passed context has a timeout, then if the timeout is reached before the channel has been opened, then an error is returned.

func (*NetworkHarness) WaitForTxInMempool

func (n *NetworkHarness) WaitForTxInMempool(ctx context.Context,
	txid chainhash.Hash) error

WaitForTxInMempool blocks until the target txid is seen in the mempool. If the transaction isn't seen within the network before the passed timeout, then an error is returned.

type NodeConfig

type NodeConfig struct {
	Name string

	// LogFilenamePrefix is is used to prefix node log files. Can be used
	// to store the current test case for simpler postmortem debugging.
	LogFilenamePrefix string

	BackendCfg BackendConfig
	NetParams  *chaincfg.Params
	BaseDir    string
	ExtraArgs  []string

	DataDir        string
	LogDir         string
	TLSCertPath    string
	TLSKeyPath     string
	AdminMacPath   string
	ReadMacPath    string
	InvoiceMacPath string

	HasSeed  bool
	Password []byte

	P2PPort     int
	RPCPort     int
	RESTPort    int
	ProfilePort int

	AcceptKeySend bool

	FeeURL string

	Etcd bool
}

func (NodeConfig) ChanBackupPath

func (cfg NodeConfig) ChanBackupPath() string

func (NodeConfig) DBDir

func (cfg NodeConfig) DBDir() string

DBDir returns the holding directory path of the graph database.

func (NodeConfig) DBPath

func (cfg NodeConfig) DBPath() string

func (NodeConfig) P2PAddr

func (cfg NodeConfig) P2PAddr() string

func (NodeConfig) RESTAddr

func (cfg NodeConfig) RESTAddr() string

func (NodeConfig) RPCAddr

func (cfg NodeConfig) RPCAddr() string

type OpenChannelParams

type OpenChannelParams struct {
	// Amt is the local amount being put into the channel.
	Amt btcutil.Amount

	// PushAmt is the amount that should be pushed to the remote when the
	// channel is opened.
	PushAmt btcutil.Amount

	// Private is a boolan indicating whether the opened channel should be
	// private.
	Private bool

	// SpendUnconfirmed is a boolean indicating whether we can utilize
	// unconfirmed outputs to fund the channel.
	SpendUnconfirmed bool

	// MinHtlc is the htlc_minimum_msat value set when opening the channel.
	MinHtlc lnwire.MilliSatoshi

	// RemoteMaxHtlcs is the remote_max_htlcs value set when opening the
	// channel, restricting the number of concurrent HTLCs the remote party
	// can add to a commitment.
	RemoteMaxHtlcs uint16

	// FundingShim is an optional funding shim that the caller can specify
	// in order to modify the channel funding workflow.
	FundingShim *lnrpc.FundingShim
}

OpenChannelParams houses the params to specify when opening a new channel.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL