From 169ebad6c5369765e7d4bd96d8eeb2ea0018ae57 Mon Sep 17 00:00:00 2001 From: Wilmer Paulino Date: Thu, 9 Aug 2018 21:14:31 -0700 Subject: [PATCH] lnd_test: add test for funding channels with unconfirmed outputs --- lnd_test.go | 80 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) diff --git a/lnd_test.go b/lnd_test.go index ec55e3f0..207af566 100644 --- a/lnd_test.go +++ b/lnd_test.go @@ -677,6 +677,82 @@ func testBasicChannelFunding(net *lntest.NetworkHarness, t *harnessTest) { closeChannelAndAssert(ctxt, t, net, net.Alice, chanPoint, false) } +// testUnconfirmedChannelFunding tests that unconfirmed outputs that pay to us +// can be used to fund channels. +func testUnconfirmedChannelFunding(net *lntest.NetworkHarness, t *harnessTest) { + const ( + timeout = time.Duration(15 * time.Second) + chanAmt = maxBtcFundingAmount + pushAmt = btcutil.Amount(100000) + ) + + ctxb := context.Background() + + // We'll start off by creating a node for Carol. + carol, err := net.NewNode("Carol", nil) + if err != nil { + t.Fatalf("unable to create carol's node: %v", err) + } + defer shutdownAndAssert(net, t, carol) + + // We'll send her some funds that should not confirm. + ctxt, _ := context.WithTimeout(ctxb, timeout) + err = net.SendCoinsUnconfirmed(ctxt, 2*chanAmt, carol) + if err != nil { + t.Fatalf("unable to send coins to carol: %v", err) + } + + // Now, we'll connect her to Alice so that they can open a channel + // together. The funding flow should select Carol's unconfirmed output + // as she doesn't have any other funds since it's a new node. + ctxt, _ = context.WithTimeout(ctxb, timeout) + if err := net.ConnectNodes(ctxt, carol, net.Alice); err != nil { + t.Fatalf("unable to connect dave to alice: %v", err) + } + ctxt, _ = context.WithTimeout(ctxb, timeout) + chanOpenUpdate, err := net.OpenChannel( + ctxt, carol, net.Alice, chanAmt, pushAmt, false, false, + ) + if err != nil { + t.Fatalf("unable to open channel between carol and alice: %v", + err) + } + + // Confirm the channel and wait for it to be recognized by both parties. + mineBlocks(t, net, 6) + ctxt, _ = context.WithTimeout(ctxb, timeout) + chanPoint, err := net.WaitForChannelOpen(ctxt, chanOpenUpdate) + if err != nil { + t.Fatalf("error while waiting for channel open: %v", err) + } + + // With the channel open, we'll check the balances on each side of the + // channel as a sanity check to ensure things worked out as intended. + balReq := &lnrpc.ChannelBalanceRequest{} + ctxt, _ = context.WithTimeout(ctxb, timeout) + carolBal, err := carol.ChannelBalance(ctxt, balReq) + if err != nil { + t.Fatalf("unable to get carol's balance: %v", err) + } + ctxt, _ = context.WithTimeout(ctxb, timeout) + aliceBal, err := net.Alice.ChannelBalance(ctxt, balReq) + if err != nil { + t.Fatalf("unable to get alice's balance: %v", err) + } + if carolBal.Balance != int64(chanAmt-pushAmt-calcStaticFee(0)) { + t.Fatalf("carol's balance is incorrect: expected %v got %v", + chanAmt-pushAmt-calcStaticFee(0), carolBal) + } + if aliceBal.Balance != int64(pushAmt) { + t.Fatalf("alice's balance is incorrect: expected %v got %v", + pushAmt, aliceBal.Balance) + } + + // Now that we're done with the test, the channel can be closed. + ctxt, _ = context.WithTimeout(ctxb, timeout) + closeChannelAndAssert(ctxt, t, net, carol, chanPoint, false) +} + // txStr returns the string representation of the channel's funding transaction. func txStr(chanPoint *lnrpc.ChannelPoint) string { txidHash, err := getChanPointFundingTxid(chanPoint) @@ -10970,6 +11046,10 @@ var testsCases = []*testCase{ name: "basic funding flow", test: testBasicChannelFunding, }, + { + name: "unconfirmed channel funding", + test: testUnconfirmedChannelFunding, + }, { name: "update channel policy", test: testUpdateChannelPolicy,