github.com/decred/dcrlnd@v0.7.6/lntest/itest/lnd_funding_test.go (about)

     1  package itest
     2  
     3  import (
     4  	"context"
     5  	"crypto/rand"
     6  	"fmt"
     7  	"testing"
     8  	"time"
     9  
    10  	"github.com/decred/dcrd/chaincfg/chainhash"
    11  	"github.com/decred/dcrd/dcrutil/v4"
    12  	"github.com/decred/dcrd/wire"
    13  	"github.com/decred/dcrlnd/input"
    14  	"github.com/decred/dcrlnd/labels"
    15  	"github.com/decred/dcrlnd/lnrpc"
    16  	"github.com/decred/dcrlnd/lnrpc/walletrpc"
    17  	"github.com/decred/dcrlnd/lntest"
    18  	"github.com/decred/dcrlnd/lnwire"
    19  	"github.com/stretchr/testify/require"
    20  )
    21  
    22  // testBasicChannelFunding performs a test exercising expected behavior from a
    23  // basic funding workflow. The test creates a new channel between Alice and
    24  // Bob, then immediately closes the channel after asserting some expected post
    25  // conditions. Finally, the chain itself is checked to ensure the closing
    26  // transaction was mined.
    27  func testBasicChannelFunding(net *lntest.NetworkHarness, t *harnessTest) {
    28  	// Run through the test with combinations of all the different
    29  	// commitment types.
    30  	allTypes := []lnrpc.CommitmentType{
    31  		lnrpc.CommitmentType_LEGACY,
    32  		lnrpc.CommitmentType_STATIC_REMOTE_KEY,
    33  		lnrpc.CommitmentType_ANCHORS,
    34  	}
    35  
    36  	// testFunding is a function closure that takes Carol and Dave's
    37  	// commitment types and test the funding flow.
    38  	testFunding := func(carolCommitType, daveCommitType lnrpc.CommitmentType) {
    39  		// Based on the current tweak variable for Carol, we'll
    40  		// preferentially signal the legacy commitment format.  We do
    41  		// the same for Dave shortly below.
    42  		carolArgs := nodeArgsForCommitType(carolCommitType)
    43  		carol := net.NewNode(t.t, "Carol", carolArgs)
    44  		defer shutdownAndAssert(net, t, carol)
    45  
    46  		// Each time, we'll send Carol a new set of coins in order to
    47  		// fund the channel.
    48  		net.SendCoins(t.t, dcrutil.AtomsPerCoin, carol)
    49  
    50  		daveArgs := nodeArgsForCommitType(daveCommitType)
    51  		dave := net.NewNode(t.t, "Dave", daveArgs)
    52  		defer shutdownAndAssert(net, t, dave)
    53  
    54  		// Before we start the test, we'll ensure both sides are
    55  		// connected to the funding flow can properly be executed.
    56  		net.EnsureConnected(t.t, carol, dave)
    57  
    58  		carolChannel, daveChannel, closeChan, err := basicChannelFundingTest(
    59  			t, net, carol, dave, nil,
    60  		)
    61  		if err != nil {
    62  			t.Fatalf("failed funding flow: %v", err)
    63  		}
    64  
    65  		// Both nodes should report the same commitment
    66  		// type.
    67  		chansCommitType := carolChannel.CommitmentType
    68  		if daveChannel.CommitmentType != chansCommitType {
    69  			t.Fatalf("commit types don't match, "+
    70  				"carol got %v, dave got %v",
    71  				carolChannel.CommitmentType,
    72  				daveChannel.CommitmentType,
    73  			)
    74  		}
    75  
    76  		// Now check that the commitment type reported
    77  		// by both nodes is what we expect. It will be
    78  		// the minimum of the two nodes' preference, in
    79  		// the order Legacy, Tweakless, Anchors.
    80  		expType := carolCommitType
    81  
    82  		switch daveCommitType {
    83  
    84  		// Dave supports anchors, type will be what
    85  		// Carol supports.
    86  		case lnrpc.CommitmentType_ANCHORS:
    87  
    88  		// Dave only supports tweakless, channel will
    89  		// be downgraded to this type if Carol supports
    90  		// anchors.
    91  		case lnrpc.CommitmentType_STATIC_REMOTE_KEY:
    92  			if expType == lnrpc.CommitmentType_ANCHORS {
    93  				expType = lnrpc.CommitmentType_STATIC_REMOTE_KEY
    94  			}
    95  
    96  		// Dave only supoprts legacy type, channel will
    97  		// be downgraded to this type.
    98  		case lnrpc.CommitmentType_LEGACY:
    99  			expType = lnrpc.CommitmentType_LEGACY
   100  
   101  		default:
   102  			t.Fatalf("invalid commit type %v",
   103  				daveCommitType)
   104  		}
   105  
   106  		// Check that the signalled type matches what we
   107  		// expect.
   108  		switch {
   109  		case expType == lnrpc.CommitmentType_ANCHORS &&
   110  			chansCommitType == lnrpc.CommitmentType_ANCHORS:
   111  
   112  		case expType == lnrpc.CommitmentType_STATIC_REMOTE_KEY &&
   113  			chansCommitType == lnrpc.CommitmentType_STATIC_REMOTE_KEY:
   114  
   115  		case expType == lnrpc.CommitmentType_LEGACY &&
   116  			chansCommitType == lnrpc.CommitmentType_LEGACY:
   117  
   118  		default:
   119  			t.Fatalf("expected nodes to signal "+
   120  				"commit type %v, instead got "+
   121  				"%v", expType, chansCommitType)
   122  		}
   123  
   124  		// As we've concluded this sub-test case we'll
   125  		// now close out the channel for both sides.
   126  		closeChan()
   127  
   128  		shutdownAndAssert(net, t, carol)
   129  		shutdownAndAssert(net, t, dave)
   130  	}
   131  
   132  test:
   133  	// We'll test all possible combinations of the feature bit presence
   134  	// that both nodes can signal for this new channel type. We'll make a
   135  	// new Carol+Dave for each test instance as well.
   136  	for _, carolCommitType := range allTypes {
   137  		for _, daveCommitType := range allTypes {
   138  			cc := carolCommitType
   139  			dc := daveCommitType
   140  
   141  			testName := fmt.Sprintf(
   142  				"carol_commit=%v,dave_commit=%v", cc, dc,
   143  			)
   144  
   145  			logLine := fmt.Sprintf(
   146  				"---- basic channel funding subtest %s ----\n",
   147  				testName,
   148  			)
   149  			net.Alice.AddToLog(logLine)
   150  
   151  			success := t.t.Run(testName, func(t *testing.T) {
   152  				testFunding(cc, dc)
   153  			})
   154  
   155  			if !success {
   156  				break test
   157  			}
   158  		}
   159  	}
   160  }
   161  
   162  // basicChannelFundingTest is a sub-test of the main testBasicChannelFunding
   163  // test. Given two nodes: Alice and Bob, it'll assert proper channel creation,
   164  // then return a function closure that should be called to assert proper
   165  // channel closure.
   166  func basicChannelFundingTest(t *harnessTest, net *lntest.NetworkHarness,
   167  	alice *lntest.HarnessNode, bob *lntest.HarnessNode,
   168  	fundingShim *lnrpc.FundingShim) (*lnrpc.Channel, *lnrpc.Channel, func(), error) {
   169  
   170  	chanAmt := defaultChanAmt
   171  	pushAmt := dcrutil.Amount(100000)
   172  	atomsPerByte := dcrutil.Amount(1)
   173  
   174  	// Record nodes' channel balance before testing.
   175  	aliceChannelBalance := getChannelBalance(t, alice)
   176  	bobChannelBalance := getChannelBalance(t, bob)
   177  
   178  	// Creates a helper closure to be used below which asserts the proper
   179  	// response to a channel balance RPC.
   180  	checkChannelBalance := func(node *lntest.HarnessNode,
   181  		oldChannelBalance *lnrpc.ChannelBalanceResponse,
   182  		local, remote dcrutil.Amount) {
   183  
   184  		newResp := oldChannelBalance
   185  
   186  		newResp.LocalBalance.Atoms += uint64(local)
   187  		newResp.LocalBalance.Matoms += uint64(
   188  			lnwire.NewMAtomsFromAtoms(local),
   189  		)
   190  		newResp.RemoteBalance.Atoms += uint64(remote)
   191  		newResp.RemoteBalance.Matoms += uint64(
   192  			lnwire.NewMAtomsFromAtoms(remote),
   193  		)
   194  		// Deprecated fields.
   195  		newResp.Balance += int64(local)
   196  		assertChannelBalanceResp(t, node, newResp)
   197  	}
   198  
   199  	// First establish a channel with a capacity of 0.16 DCR between Alice
   200  	// and Bob with Alice pushing 100k atoms to Bob's side during
   201  	// funding. This function will block until the channel itself is fully
   202  	// open or an error occurs in the funding process. A series of
   203  	// assertions will be executed to ensure the funding process completed
   204  	// successfully.
   205  	chanPoint := openChannelAndAssert(
   206  		t, net, alice, bob,
   207  		lntest.OpenChannelParams{
   208  			Amt:          chanAmt,
   209  			PushAmt:      pushAmt,
   210  			FundingShim:  fundingShim,
   211  			AtomsPerByte: atomsPerByte,
   212  		},
   213  	)
   214  
   215  	err := alice.WaitForNetworkChannelOpen(chanPoint)
   216  	require.NoError(t.t, err, "alice didn't report channel")
   217  
   218  	err = bob.WaitForNetworkChannelOpen(chanPoint)
   219  	require.NoError(t.t, err, "bob didn't report channel")
   220  
   221  	cType, err := channelCommitType(alice, chanPoint)
   222  	if err != nil {
   223  		return nil, nil, nil, fmt.Errorf("unable to get channel "+
   224  			"type: %v", err)
   225  	}
   226  
   227  	// With the channel open, ensure that the amount specified above has
   228  	// properly been pushed to Bob.
   229  	aliceLocalBalance := chanAmt - pushAmt - calcStaticFee(cType, 0)
   230  	checkChannelBalance(
   231  		alice, aliceChannelBalance, aliceLocalBalance, pushAmt,
   232  	)
   233  	checkChannelBalance(
   234  		bob, bobChannelBalance, pushAmt, aliceLocalBalance,
   235  	)
   236  
   237  	req := &lnrpc.ListChannelsRequest{}
   238  	aliceChannel, err := alice.ListChannels(context.Background(), req)
   239  	if err != nil {
   240  		return nil, nil, nil, fmt.Errorf("unable to obtain chan: %v", err)
   241  	}
   242  
   243  	bobChannel, err := bob.ListChannels(context.Background(), req)
   244  	if err != nil {
   245  		return nil, nil, nil, fmt.Errorf("unable to obtain chan: %v", err)
   246  	}
   247  
   248  	closeChan := func() {
   249  		// Finally, immediately close the channel. This function will
   250  		// also block until the channel is closed and will additionally
   251  		// assert the relevant channel closing post conditions.
   252  		closeChannelAndAssert(t, net, alice, chanPoint, false)
   253  	}
   254  
   255  	return aliceChannel.Channels[0], bobChannel.Channels[0], closeChan, nil
   256  }
   257  
   258  // testUnconfirmedChannelFunding tests that our unconfirmed change outputs can
   259  // be used to fund channels.
   260  func testUnconfirmedChannelFunding(net *lntest.NetworkHarness, t *harnessTest) {
   261  	ctxb := context.Background()
   262  
   263  	const (
   264  		chanAmt = defaultChanAmt
   265  		pushAmt = dcrutil.Amount(100000)
   266  	)
   267  
   268  	// We'll start off by creating a node for Carol.
   269  	carol := net.NewNode(t.t, "Carol", nil)
   270  	defer shutdownAndAssert(net, t, carol)
   271  
   272  	// We'll send her some confirmed funds.
   273  	net.SendCoins(t.t, 2*chanAmt, carol)
   274  
   275  	// Now let Carol send some funds to herself, making a unconfirmed
   276  	// change output.
   277  	addrReq := &lnrpc.NewAddressRequest{
   278  		Type: lnrpc.AddressType_PUBKEY_HASH,
   279  	}
   280  	ctxt, _ := context.WithTimeout(ctxb, defaultTimeout)
   281  	resp, err := carol.NewAddress(ctxt, addrReq)
   282  	if err != nil {
   283  		t.Fatalf("unable to get new address: %v", err)
   284  	}
   285  
   286  	sendReq := &lnrpc.SendCoinsRequest{
   287  		Addr:   resp.Address,
   288  		Amount: int64(chanAmt) / 5,
   289  	}
   290  	ctxt, _ = context.WithTimeout(ctxb, defaultTimeout)
   291  	_, err = carol.SendCoins(ctxt, sendReq)
   292  	if err != nil {
   293  		t.Fatalf("unable to send coins: %v", err)
   294  	}
   295  
   296  	// Make sure the unconfirmed tx is seen in the mempool.
   297  	_, err = waitForTxInMempool(net.Miner.Node, minerMempoolTimeout)
   298  	if err != nil {
   299  		t.Fatalf("failed to find tx in miner mempool: %v", err)
   300  	}
   301  
   302  	// Now, we'll connect her to Alice so that they can open a channel
   303  	// together. The funding flow should select Carol's unconfirmed output
   304  	// as she doesn't have any other funds since it's a new node.
   305  	net.ConnectNodes(t.t, carol, net.Alice)
   306  
   307  	chanOpenUpdate := openChannelStream(
   308  		t, net, carol, net.Alice,
   309  		lntest.OpenChannelParams{
   310  			Amt:              chanAmt,
   311  			PushAmt:          pushAmt,
   312  			SpendUnconfirmed: true,
   313  		},
   314  	)
   315  
   316  	// Creates a helper closure to be used below which asserts the proper
   317  	// response to a channel balance RPC.
   318  	checkChannelBalance := func(node *lntest.HarnessNode,
   319  		local, remote, pendingLocal, pendingRemote dcrutil.Amount) {
   320  		expectedResponse := &lnrpc.ChannelBalanceResponse{
   321  			LocalBalance: &lnrpc.Amount{
   322  				Atoms: uint64(local),
   323  				Matoms: uint64(lnwire.NewMAtomsFromAtoms(
   324  					local,
   325  				)),
   326  			},
   327  			RemoteBalance: &lnrpc.Amount{
   328  				Atoms: uint64(remote),
   329  				Matoms: uint64(lnwire.NewMAtomsFromAtoms(
   330  					remote,
   331  				)),
   332  			},
   333  			PendingOpenLocalBalance: &lnrpc.Amount{
   334  				Atoms: uint64(pendingLocal),
   335  				Matoms: uint64(lnwire.NewMAtomsFromAtoms(
   336  					pendingLocal,
   337  				)),
   338  			},
   339  			PendingOpenRemoteBalance: &lnrpc.Amount{
   340  				Atoms: uint64(pendingRemote),
   341  				Matoms: uint64(lnwire.NewMAtomsFromAtoms(
   342  					pendingRemote,
   343  				)),
   344  			},
   345  			UnsettledLocalBalance:  &lnrpc.Amount{},
   346  			UnsettledRemoteBalance: &lnrpc.Amount{},
   347  			// Deprecated fields.
   348  			Balance:            int64(local),
   349  			PendingOpenBalance: int64(pendingLocal),
   350  		}
   351  		assertChannelBalanceResp(t, node, expectedResponse)
   352  	}
   353  
   354  	// As the channel is pending open, it's expected Carol has both zero
   355  	// local and remote balances, and pending local/remote should not be
   356  	// zero.
   357  	//
   358  	// Note that atm we haven't obtained the chanPoint yet, so we use the
   359  	// type directly.
   360  	cType := lnrpc.CommitmentType_STATIC_REMOTE_KEY
   361  	carolLocalBalance := chanAmt - pushAmt - calcStaticFee(cType, 0)
   362  	checkChannelBalance(carol, 0, 0, carolLocalBalance, pushAmt)
   363  
   364  	// For Alice, her local/remote balances should be zero, and the
   365  	// local/remote balances are the mirror of Carol's.
   366  	checkChannelBalance(net.Alice, 0, 0, pushAmt, carolLocalBalance)
   367  
   368  	// Confirm the channel and wait for it to be recognized by both
   369  	// parties. Two transactions should be mined, the unconfirmed spend and
   370  	// the funding tx.
   371  	mineBlocks(t, net, 6, 2)
   372  	chanPoint, err := net.WaitForChannelOpen(chanOpenUpdate)
   373  	require.NoError(t.t, err, "error while waitinng for channel open")
   374  
   375  	// With the channel open, we'll check the balances on each side of the
   376  	// channel as a sanity check to ensure things worked out as intended.
   377  
   378  	checkChannelBalance(carol, carolLocalBalance, pushAmt, 0, 0)
   379  	checkChannelBalance(net.Alice, pushAmt, carolLocalBalance, 0, 0)
   380  
   381  	// Now that we're done with the test, the channel can be closed.
   382  	closeChannelAndAssert(t, net, carol, chanPoint, false)
   383  }
   384  
   385  // testExternalFundingChanPoint tests that we're able to carry out a normal
   386  // channel funding workflow given a channel point that was constructed outside
   387  // the main daemon.
   388  func testExternalFundingChanPoint(net *lntest.NetworkHarness, t *harnessTest) {
   389  	ctxb := context.Background()
   390  
   391  	// First, we'll create two new nodes that we'll use to open channel
   392  	// between for this test.
   393  	carol := net.NewNode(t.t, "carol", nil)
   394  	defer shutdownAndAssert(net, t, carol)
   395  
   396  	dave := net.NewNode(t.t, "dave", nil)
   397  	defer shutdownAndAssert(net, t, dave)
   398  
   399  	// Carol will be funding the channel, so we'll send some coins over to
   400  	// her and ensure they have enough confirmations before we proceed.
   401  	net.SendCoins(t.t, dcrutil.AtomsPerCoin, carol)
   402  
   403  	// Before we start the test, we'll ensure both sides are connected to
   404  	// the funding flow can properly be executed.
   405  	net.EnsureConnected(t.t, carol, dave)
   406  
   407  	// At this point, we're ready to simulate our external channel funding
   408  	// flow. To start with, we'll create a pending channel with a shim for
   409  	// a transaction that will never be published.
   410  	const thawHeight uint32 = 10
   411  	const chanSize = defaultChanAmt
   412  	fundingShim1, chanPoint1, _ := deriveFundingShim(
   413  		net, t, carol, dave, chanSize, thawHeight, false,
   414  	)
   415  	_ = openChannelStream(
   416  		t, net, carol, dave, lntest.OpenChannelParams{
   417  			Amt:         chanSize,
   418  			FundingShim: fundingShim1,
   419  		},
   420  	)
   421  	assertNumOpenChannelsPending(t, carol, dave, 1)
   422  
   423  	// That channel is now pending forever and normally would saturate the
   424  	// max pending channel limit for both nodes. But because the channel is
   425  	// externally funded, we should still be able to open another one. Let's
   426  	// do exactly that now. For this one we publish the transaction so we
   427  	// can mine it later.
   428  	fundingShim2, chanPoint2, _ := deriveFundingShim(
   429  		net, t, carol, dave, chanSize, thawHeight, true,
   430  	)
   431  
   432  	// At this point, we'll now carry out the normal basic channel funding
   433  	// test as everything should now proceed as normal (a regular channel
   434  	// funding flow).
   435  	carolChan, daveChan, _, err := basicChannelFundingTest(
   436  		t, net, carol, dave, fundingShim2,
   437  	)
   438  	require.NoError(t.t, err)
   439  
   440  	// Both channels should be marked as frozen with the proper thaw
   441  	// height.
   442  	if carolChan.ThawHeight != thawHeight {
   443  		t.Fatalf("expected thaw height of %v, got %v",
   444  			carolChan.ThawHeight, thawHeight)
   445  	}
   446  	if daveChan.ThawHeight != thawHeight {
   447  		t.Fatalf("expected thaw height of %v, got %v",
   448  			daveChan.ThawHeight, thawHeight)
   449  	}
   450  
   451  	// Next, to make sure the channel functions as normal, we'll make some
   452  	// payments within the channel.
   453  	payAmt := dcrutil.Amount(100000)
   454  	invoice := &lnrpc.Invoice{
   455  		Memo:  "new chans",
   456  		Value: int64(payAmt),
   457  	}
   458  	ctxt, _ := context.WithTimeout(ctxb, defaultTimeout)
   459  	resp, err := dave.AddInvoice(ctxt, invoice)
   460  	require.NoError(t.t, err)
   461  	err = completePaymentRequests(
   462  		carol, carol.RouterClient, []string{resp.PaymentRequest}, true,
   463  	)
   464  	require.NoError(t.t, err)
   465  
   466  	// Now that the channels are open, and we've confirmed that they're
   467  	// operational, we'll now ensure that the channels are frozen as
   468  	// intended (if requested).
   469  	//
   470  	// First, we'll try to close the channel as Carol, the initiator. This
   471  	// should fail as a frozen channel only allows the responder to
   472  	// initiate a channel close.
   473  	_, _, err = net.CloseChannel(carol, chanPoint2, false)
   474  	require.Error(t.t, err,
   475  		"carol wasn't denied a co-op close attempt "+
   476  			"for a frozen channel",
   477  	)
   478  
   479  	// Next we'll try but this time with Dave (the responder) as the
   480  	// initiator. This time the channel should be closed as normal.
   481  	closeChannelAndAssert(t, net, dave, chanPoint2, false)
   482  
   483  	// As a last step, we check if we still have the pending channel hanging
   484  	// around because we never published the funding TX.
   485  	assertNumOpenChannelsPending(t, carol, dave, 1)
   486  
   487  	// Let's make sure we can abandon it.
   488  	ctxt, _ = context.WithTimeout(ctxb, defaultTimeout)
   489  	_, err = carol.AbandonChannel(ctxt, &lnrpc.AbandonChannelRequest{
   490  		ChannelPoint:           chanPoint1,
   491  		PendingFundingShimOnly: true,
   492  	})
   493  	require.NoError(t.t, err)
   494  	ctxt, _ = context.WithTimeout(ctxb, defaultTimeout)
   495  	_, err = dave.AbandonChannel(ctxt, &lnrpc.AbandonChannelRequest{
   496  		ChannelPoint:           chanPoint1,
   497  		PendingFundingShimOnly: true,
   498  	})
   499  	require.NoError(t.t, err)
   500  
   501  	// It should now not appear in the pending channels anymore.
   502  	assertNumOpenChannelsPending(t, carol, dave, 0)
   503  }
   504  
   505  // testFundingPersistence is intended to ensure that the Funding Manager
   506  // persists the state of new channels prior to broadcasting the channel's
   507  // funding transaction. This ensures that the daemon maintains an up-to-date
   508  // representation of channels if the system is restarted or disconnected.
   509  // testFundingPersistence mirrors testBasicChannelFunding, but adds restarts
   510  // and checks for the state of channels with unconfirmed funding transactions.
   511  func testChannelFundingPersistence(net *lntest.NetworkHarness, t *harnessTest) {
   512  	chanAmt := defaultChanAmt
   513  	pushAmt := dcrutil.Amount(0)
   514  
   515  	// As we need to create a channel that requires more than 1
   516  	// confirmation before it's open, with the current set of defaults,
   517  	// we'll need to create a new node instance.
   518  	const numConfs = 5
   519  	carolArgs := []string{fmt.Sprintf("--defaultchanconfs=%v", numConfs)}
   520  	carol := net.NewNode(t.t, "Carol", carolArgs)
   521  
   522  	// Clean up carol's node when the test finishes.
   523  	defer shutdownAndAssert(net, t, carol)
   524  
   525  	net.ConnectNodes(t.t, net.Alice, carol)
   526  
   527  	// Create a new channel that requires 5 confs before it's considered
   528  	// open, then broadcast the funding transaction
   529  	pendingUpdate, err := net.OpenPendingChannel(
   530  		net.Alice, carol, chanAmt, pushAmt,
   531  	)
   532  	if err != nil {
   533  		t.Fatalf("unable to open channel: %v", err)
   534  	}
   535  
   536  	// At this point, the channel's funding transaction will have been
   537  	// broadcast, but not confirmed. Alice and Bob's nodes should reflect
   538  	// this when queried via RPC.
   539  	assertNumOpenChannelsPending(t, net.Alice, carol, 1)
   540  
   541  	// Restart both nodes to test that the appropriate state has been
   542  	// persisted and that both nodes recover gracefully.
   543  	if err := net.RestartNode(net.Alice, nil); err != nil {
   544  		t.Fatalf("Node restart failed: %v", err)
   545  	}
   546  	if err := net.RestartNode(carol, nil); err != nil {
   547  		t.Fatalf("Node restart failed: %v", err)
   548  	}
   549  
   550  	fundingTxID, err := chainhash.NewHash(pendingUpdate.Txid)
   551  	if err != nil {
   552  		t.Fatalf("unable to convert funding txid into chainhash.Hash:"+
   553  			" %v", err)
   554  	}
   555  	fundingTxStr := fundingTxID.String()
   556  
   557  	// Mine a block, then wait for Alice's node to notify us that the
   558  	// channel has been opened. The funding transaction should be found
   559  	// within the newly mined block.
   560  	block := mineBlocks(t, net, 1, 1)[0]
   561  	assertTxInBlock(t, block, fundingTxID)
   562  
   563  	// Get the height that our transaction confirmed at.
   564  	_, height, err := net.Miner.Node.GetBestBlock(context.Background())
   565  	require.NoError(t.t, err, "could not get best block")
   566  
   567  	// Restart both nodes to test that the appropriate state has been
   568  	// persisted and that both nodes recover gracefully.
   569  	if err := net.RestartNode(net.Alice, nil); err != nil {
   570  		t.Fatalf("Node restart failed: %v", err)
   571  	}
   572  	if err := net.RestartNode(carol, nil); err != nil {
   573  		t.Fatalf("Node restart failed: %v", err)
   574  	}
   575  
   576  	// The following block ensures that after both nodes have restarted,
   577  	// they have reconnected before the execution of the next test.
   578  	net.EnsureConnected(t.t, net.Alice, carol)
   579  
   580  	// Next, mine enough blocks s.t the channel will open with a single
   581  	// additional block mined.
   582  	if _, err := net.Generate(3); err != nil {
   583  		t.Fatalf("unable to mine blocks: %v", err)
   584  	}
   585  
   586  	// Assert that our wallet has our opening transaction with a label
   587  	// that does not have a channel ID set yet, because we have not
   588  	// reached our required confirmations.
   589  	tx := findTxAtHeight(t, height, fundingTxStr, net.Alice)
   590  
   591  	// At this stage, we expect the transaction to be labelled, but not with
   592  	// our channel ID because our transaction has not yet confirmed.
   593  	_ = labels.MakeLabel(labels.LabelTypeChannelOpen, nil)
   594  	// require.Equal(t.t, label, tx.Label, "open channel label wrong")
   595  	_ = tx // This is not supported in dcrw
   596  
   597  	// Both nodes should still show a single channel as pending.
   598  	time.Sleep(time.Second * 1)
   599  	assertNumOpenChannelsPending(t, net.Alice, carol, 1)
   600  
   601  	// Finally, mine the last block which should mark the channel as open.
   602  	if _, err := net.Generate(1); err != nil {
   603  		t.Fatalf("unable to mine blocks: %v", err)
   604  	}
   605  
   606  	// At this point, the channel should be fully opened and there should
   607  	// be no pending channels remaining for either node.
   608  	time.Sleep(time.Second * 1)
   609  	assertNumOpenChannelsPending(t, net.Alice, carol, 0)
   610  
   611  	// The channel should be listed in the peer information returned by
   612  	// both peers.
   613  	outPoint := wire.OutPoint{
   614  		Hash:  *fundingTxID,
   615  		Index: pendingUpdate.OutputIndex,
   616  	}
   617  
   618  	// Re-lookup our transaction in the block that it confirmed in.
   619  	_ = findTxAtHeight(t, height, fundingTxStr, net.Alice)
   620  
   621  	// Create an additional check for our channel assertion that will
   622  	// check that our label is as expected.
   623  	check := func(channel *lnrpc.Channel) {
   624  		shortChanID := lnwire.NewShortChanIDFromInt(
   625  			channel.ChanId,
   626  		)
   627  
   628  		_ = labels.MakeLabel(
   629  			labels.LabelTypeChannelOpen, &shortChanID,
   630  		)
   631  		// require.Equal(t.t, label, tx.Label,
   632  		// "open channel label not updated")
   633  	}
   634  
   635  	// Check both nodes to ensure that the channel is ready for operation.
   636  	err = net.AssertChannelExists(net.Alice, &outPoint, check)
   637  	if err != nil {
   638  		t.Fatalf("unable to assert channel existence: %v", err)
   639  	}
   640  	if err := net.AssertChannelExists(carol, &outPoint); err != nil {
   641  		t.Fatalf("unable to assert channel existence: %v", err)
   642  	}
   643  
   644  	// Finally, immediately close the channel. This function will also
   645  	// block until the channel is closed and will additionally assert the
   646  	// relevant channel closing post conditions.
   647  	chanPoint := &lnrpc.ChannelPoint{
   648  		FundingTxid: &lnrpc.ChannelPoint_FundingTxidBytes{
   649  			FundingTxidBytes: pendingUpdate.Txid,
   650  		},
   651  		OutputIndex: pendingUpdate.OutputIndex,
   652  	}
   653  	closeChannelAndAssert(t, net, net.Alice, chanPoint, false)
   654  }
   655  
   656  // deriveFundingShim creates a channel funding shim by deriving the necessary
   657  // keys on both sides.
   658  func deriveFundingShim(net *lntest.NetworkHarness, t *harnessTest,
   659  	carol, dave *lntest.HarnessNode, chanSize dcrutil.Amount,
   660  	thawHeight uint32, publish bool) (*lnrpc.FundingShim,
   661  	*lnrpc.ChannelPoint, *chainhash.Hash) {
   662  
   663  	ctxb := context.Background()
   664  	keyLoc := &walletrpc.KeyReq{KeyFamily: 0}
   665  	carolFundingKey, err := carol.WalletKitClient.DeriveNextKey(ctxb, keyLoc)
   666  	require.NoError(t.t, err)
   667  	daveFundingKey, err := dave.WalletKitClient.DeriveNextKey(ctxb, keyLoc)
   668  	require.NoError(t.t, err)
   669  
   670  	// Now that we have the multi-sig keys for each party, we can manually
   671  	// construct the funding transaction. We'll instruct the backend to
   672  	// immediately create and broadcast a transaction paying out an exact
   673  	// amount. Normally this would reside in the mempool, but we just
   674  	// confirm it now for simplicity.
   675  	_, fundingOutput, err := input.GenFundingPkScript(
   676  		carolFundingKey.RawKeyBytes, daveFundingKey.RawKeyBytes,
   677  		int64(chanSize),
   678  	)
   679  	require.NoError(t.t, err)
   680  
   681  	var txid *chainhash.Hash
   682  	targetOutputs := []*wire.TxOut{fundingOutput}
   683  	if publish {
   684  		txid, err = net.Miner.SendOutputs(
   685  			ctxb, targetOutputs, 1e4,
   686  		)
   687  		require.NoError(t.t, err)
   688  	} else {
   689  		tx, err := net.Miner.CreateTransaction(ctxb, targetOutputs, 1e4)
   690  		require.NoError(t.t, err)
   691  
   692  		txHash := tx.TxHash()
   693  		txid = &txHash
   694  	}
   695  
   696  	// At this point, we can being our external channel funding workflow.
   697  	// We'll start by generating a pending channel ID externally that will
   698  	// be used to track this new funding type.
   699  	var pendingChanID [32]byte
   700  	_, err = rand.Read(pendingChanID[:])
   701  	require.NoError(t.t, err)
   702  
   703  	// Now that we have the pending channel ID, Dave (our responder) will
   704  	// register the intent to receive a new channel funding workflow using
   705  	// the pending channel ID.
   706  	chanPoint := &lnrpc.ChannelPoint{
   707  		FundingTxid: &lnrpc.ChannelPoint_FundingTxidBytes{
   708  			FundingTxidBytes: txid[:],
   709  		},
   710  	}
   711  	chanPointShim := &lnrpc.ChanPointShim{
   712  		Amt:       int64(chanSize),
   713  		ChanPoint: chanPoint,
   714  		LocalKey: &lnrpc.KeyDescriptor{
   715  			RawKeyBytes: daveFundingKey.RawKeyBytes,
   716  			KeyLoc: &lnrpc.KeyLocator{
   717  				KeyFamily: daveFundingKey.KeyLoc.KeyFamily,
   718  				KeyIndex:  daveFundingKey.KeyLoc.KeyIndex,
   719  			},
   720  		},
   721  		RemoteKey:     carolFundingKey.RawKeyBytes,
   722  		PendingChanId: pendingChanID[:],
   723  		ThawHeight:    thawHeight,
   724  	}
   725  	fundingShim := &lnrpc.FundingShim{
   726  		Shim: &lnrpc.FundingShim_ChanPointShim{
   727  			ChanPointShim: chanPointShim,
   728  		},
   729  	}
   730  	_, err = dave.FundingStateStep(ctxb, &lnrpc.FundingTransitionMsg{
   731  		Trigger: &lnrpc.FundingTransitionMsg_ShimRegister{
   732  			ShimRegister: fundingShim,
   733  		},
   734  	})
   735  	require.NoError(t.t, err)
   736  
   737  	// If we attempt to register the same shim (has the same pending chan
   738  	// ID), then we should get an error.
   739  	_, err = dave.FundingStateStep(ctxb, &lnrpc.FundingTransitionMsg{
   740  		Trigger: &lnrpc.FundingTransitionMsg_ShimRegister{
   741  			ShimRegister: fundingShim,
   742  		},
   743  	})
   744  	if err == nil {
   745  		t.Fatalf("duplicate pending channel ID funding shim " +
   746  			"registration should trigger an error")
   747  	}
   748  
   749  	// We'll take the chan point shim we just registered for Dave (the
   750  	// responder), and swap the local/remote keys before we feed it in as
   751  	// Carol's funding shim as the initiator.
   752  	fundingShim.GetChanPointShim().LocalKey = &lnrpc.KeyDescriptor{
   753  		RawKeyBytes: carolFundingKey.RawKeyBytes,
   754  		KeyLoc: &lnrpc.KeyLocator{
   755  			KeyFamily: carolFundingKey.KeyLoc.KeyFamily,
   756  			KeyIndex:  carolFundingKey.KeyLoc.KeyIndex,
   757  		},
   758  	}
   759  	fundingShim.GetChanPointShim().RemoteKey = daveFundingKey.RawKeyBytes
   760  
   761  	return fundingShim, chanPoint, txid
   762  }
   763  
   764  // testBatchChanFunding makes sure multiple channels can be opened in one batch
   765  // transaction in an atomic way.
   766  func testBatchChanFunding(net *lntest.NetworkHarness, t *harnessTest) {
   767  	t.t.Skip("PSBT funding is not supported")
   768  
   769  	ctxb := context.Background()
   770  
   771  	// First, we'll create two new nodes that we'll use to open channels
   772  	// to during this test. Carol has a high minimum funding amount that
   773  	// we'll use to trigger an error during the batch channel open.
   774  	carol := net.NewNode(t.t, "carol", []string{"--minchansize=200000"})
   775  	defer shutdownAndAssert(net, t, carol)
   776  
   777  	dave := net.NewNode(t.t, "dave", nil)
   778  	defer shutdownAndAssert(net, t, dave)
   779  
   780  	// Before we start the test, we'll ensure Alice is connected to Carol
   781  	// and Dave so she can open channels to both of them (and Bob).
   782  	net.EnsureConnected(t.t, net.Alice, net.Bob)
   783  	net.EnsureConnected(t.t, net.Alice, carol)
   784  	net.EnsureConnected(t.t, net.Alice, dave)
   785  
   786  	// Let's create our batch TX request. This first one should fail as we
   787  	// open a channel to Carol that is too small for her min chan size.
   788  	batchReq := &lnrpc.BatchOpenChannelRequest{
   789  		AtomsPerByte: 12,
   790  		MinConfs:     1,
   791  		Channels: []*lnrpc.BatchOpenChannel{{
   792  			NodePubkey:         net.Bob.PubKey[:],
   793  			LocalFundingAmount: 100_000,
   794  		}, {
   795  			NodePubkey:         carol.PubKey[:],
   796  			LocalFundingAmount: 100_000,
   797  		}, {
   798  			NodePubkey:         dave.PubKey[:],
   799  			LocalFundingAmount: 100_000,
   800  		}},
   801  	}
   802  
   803  	ctxt, cancel := context.WithTimeout(ctxb, defaultTimeout)
   804  	defer cancel()
   805  	_, err := net.Alice.BatchOpenChannel(ctxt, batchReq)
   806  	require.Error(t.t, err)
   807  	require.Contains(t.t, err.Error(), "initial negotiation failed")
   808  
   809  	// Let's fix the minimum amount for Carol now and try again.
   810  	batchReq.Channels[1].LocalFundingAmount = 200_000
   811  	ctxt, cancel = context.WithTimeout(ctxb, defaultTimeout)
   812  	defer cancel()
   813  	batchResp, err := net.Alice.BatchOpenChannel(ctxt, batchReq)
   814  	require.NoError(t.t, err)
   815  	require.Len(t.t, batchResp.PendingChannels, 3)
   816  
   817  	txHash, err := chainhash.NewHash(batchResp.PendingChannels[0].Txid)
   818  	require.NoError(t.t, err)
   819  
   820  	chanPoint1 := &lnrpc.ChannelPoint{
   821  		FundingTxid: &lnrpc.ChannelPoint_FundingTxidBytes{
   822  			FundingTxidBytes: batchResp.PendingChannels[0].Txid,
   823  		},
   824  		OutputIndex: batchResp.PendingChannels[0].OutputIndex,
   825  	}
   826  	chanPoint2 := &lnrpc.ChannelPoint{
   827  		FundingTxid: &lnrpc.ChannelPoint_FundingTxidBytes{
   828  			FundingTxidBytes: batchResp.PendingChannels[1].Txid,
   829  		},
   830  		OutputIndex: batchResp.PendingChannels[1].OutputIndex,
   831  	}
   832  	chanPoint3 := &lnrpc.ChannelPoint{
   833  		FundingTxid: &lnrpc.ChannelPoint_FundingTxidBytes{
   834  			FundingTxidBytes: batchResp.PendingChannels[2].Txid,
   835  		},
   836  		OutputIndex: batchResp.PendingChannels[2].OutputIndex,
   837  	}
   838  
   839  	block := mineBlocks(t, net, 6, 1)[0]
   840  	assertTxInBlock(t, block, txHash)
   841  	err = net.Alice.WaitForNetworkChannelOpen(chanPoint1)
   842  	require.NoError(t.t, err)
   843  	err = net.Alice.WaitForNetworkChannelOpen(chanPoint2)
   844  	require.NoError(t.t, err)
   845  	err = net.Alice.WaitForNetworkChannelOpen(chanPoint3)
   846  	require.NoError(t.t, err)
   847  
   848  	// With the channel open, ensure that it is counted towards Carol's
   849  	// total channel balance.
   850  	balReq := &lnrpc.ChannelBalanceRequest{}
   851  	ctxt, cancel = context.WithTimeout(ctxb, defaultTimeout)
   852  	defer cancel()
   853  	balRes, err := net.Alice.ChannelBalance(ctxt, balReq)
   854  	require.NoError(t.t, err)
   855  	require.NotEqual(t.t, int64(0), balRes.LocalBalance.Atoms)
   856  
   857  	// Next, to make sure the channel functions as normal, we'll make some
   858  	// payments within the channel.
   859  	payAmt := dcrutil.Amount(100000)
   860  	invoice := &lnrpc.Invoice{
   861  		Memo:  "new chans",
   862  		Value: int64(payAmt),
   863  	}
   864  	ctxt, cancel = context.WithTimeout(ctxb, defaultTimeout)
   865  	defer cancel()
   866  	resp, err := carol.AddInvoice(ctxt, invoice)
   867  	require.NoError(t.t, err)
   868  	err = completePaymentRequests(
   869  		net.Alice, net.Alice.RouterClient,
   870  		[]string{resp.PaymentRequest}, true,
   871  	)
   872  	require.NoError(t.t, err)
   873  
   874  	// To conclude, we'll close the newly created channel between Carol and
   875  	// Dave. This function will also block until the channel is closed and
   876  	// will additionally assert the relevant channel closing post
   877  	// conditions.
   878  	closeChannelAndAssert(t, net, net.Alice, chanPoint1, false)
   879  	closeChannelAndAssert(t, net, net.Alice, chanPoint2, false)
   880  	closeChannelAndAssert(t, net, net.Alice, chanPoint3, false)
   881  }