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 (
    	// DefaultCSV is the CSV delay (remotedelay) we will start our test
    	// nodes with.
    	DefaultCSV = 4
    
    	// MinerMempoolTimeout is the max time we will wait for a transaction
    	// to propagate to the mining node's mempool.
    	MinerMempoolTimeout = time.Second * 30
    
    	// 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
    )

    Variables

    This section is empty.

    Functions

    func CopyFile

    func CopyFile(dest, src string) error

      CopyFile copies the file src to dest.

      func WaitInvariant

      func WaitInvariant(statement func() bool, timeout time.Duration) error

        WaitInvariant is a helper test function that will wait for a timeout period of time, verifying that a statement remains true for the entire duration. This function is helpful as timing doesn't always line up well when running integration tests with several running lnd nodes. This function gives callers a way to assert that some property is maintained over a particular time frame.

        func WaitNoError

        func WaitNoError(f func() error, timeout time.Duration) error

          WaitNoError is a wrapper around WaitPredicate that waits for the passed method f to execute without error, and returns the last error encountered if this doesn't happen within the timeout.

          func WaitPredicate

          func WaitPredicate(pred func() bool, timeout time.Duration) error

            WaitPredicate is a helper test function that will wait for a timeout period of time until the passed predicate returns true. This function is helpful as timing doesn't always line up well when running integration tests with several running lnd nodes. This function gives callers a way to assert that some property is upheld within a particular time frame.

            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
            
            	// P2PAddr returns the address of this node to be used when connection
            	// over the Bitcoin P2P network.
            	P2PAddr() 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 NewBtcdBackend

                func NewBtcdBackend() (*BtcdBackendConfig, func(), error)

                  NewBtcdBackend starts a new rpctest.Harness and returns a BtcdBackendConfig for that node.

                  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) P2PAddr

                    func (b BtcdBackendConfig) P2PAddr() string

                      P2PAddr returns the address of this node to be used when connection over the Bitcoin P2P network.

                      type HarnessNode

                      type HarnessNode struct {
                      
                      	// 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
                      	// 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) 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) 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

                                func (hn *HarnessNode) Init(ctx context.Context,
                                	initReq *lnrpc.InitWalletRequest) error

                                  Init initializes a harness node by passing the init request via rpc. After the request is submitted, this method will block until an 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) Name

                                  func (hn *HarnessNode) Name() string

                                    Name returns the name of this node set during initialization.

                                    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) WaitForBalance

                                      func (hn *HarnessNode) WaitForBalance(expectedBalance acmutil.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) (*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) error

                                                    AssertChannelExists asserts that an active channel identified by the specified channel point exists from the point-of-view of the node.

                                                    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) (*HarnessNode, []string, 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) OnTxAccepted

                                                                    func (n *NetworkHarness) OnTxAccepted(hash *chainhash.Hash)

                                                                      OnTxAccepted is a callback to be called each time a new transaction has been broadcast on the network.

                                                                      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 acmutil.Amount,
                                                                        	pushAmt acmutil.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) 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.

                                                                                func (*NetworkHarness) RestoreNodeWithSeed

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

                                                                                  RestoreNodeWithSeed fully initializes a HarnessNode using a chosen mnemonic, password, and recovery window. 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) SendCoins

                                                                                  func (n *NetworkHarness) SendCoins(ctx context.Context, amt acmutil.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 acmutil.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 acmutil.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) SetUp

                                                                                        func (n *NetworkHarness) SetUp(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 ACM 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) 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) TearDownAll

                                                                                                func (n *NetworkHarness) TearDownAll() error

                                                                                                  TearDownAll 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) WaitForTxBroadcast

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

                                                                                                        WaitForTxBroadcast blocks until the target txid is seen on the network. If the transaction isn't seen within the network before the passed timeout, then an error is returned. TODO(roasbeef): add another method which creates queue of all seen transactions

                                                                                                        type OpenChannelParams

                                                                                                        type OpenChannelParams struct {
                                                                                                        	// Amt is the local amount being put into the channel.
                                                                                                        	Amt acmutil.Amount
                                                                                                        
                                                                                                        	// PushAmt is the amount that should be pushed to the remote when the
                                                                                                        	// channel is opened.
                                                                                                        	PushAmt acmutil.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
                                                                                                        }

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