diff --git a/lnd_test.go b/lnd_test.go index dae99f56..d1f76b5b 100644 --- a/lnd_test.go +++ b/lnd_test.go @@ -5084,7 +5084,7 @@ func testGarbageCollectLinkNodes(net *lntest.NetworkHarness, t *harnessTest) { closeChannelAndAssert(ctxt, t, net, net.Alice, persistentChanPoint, false) } -// testRevokedCloseRetribution tests that Alice is able carry out +// testRevokedCloseRetribution tests that Carol is able carry out // retribution in the event that she fails immediately after detecting Bob's // breach txn in the mempool. func testRevokedCloseRetribution(net *lntest.NetworkHarness, t *harnessTest) { @@ -5096,16 +5096,41 @@ func testRevokedCloseRetribution(net *lntest.NetworkHarness, t *harnessTest) { numInvoices = 6 ) - // In order to test Alice's response to an uncooperative channel + // Carol will be the breached party. We set --nolisten to ensure Bob + // won't be able to connect to her and trigger the channel data + // protection logic automatically. + carol, err := net.NewNode( + "Carol", + []string{"--debughtlc", "--hodl.exit-settle", "--nolisten"}, + ) + if err != nil { + t.Fatalf("unable to create new carol node: %v", err) + } + defer shutdownAndAssert(net, t, carol) + + // We must let Bob communicate with Carol before they are able to open + // channel, so we connect Bob and Carol, + if err := net.ConnectNodes(ctxb, carol, net.Bob); err != nil { + t.Fatalf("unable to connect dave to carol: %v", err) + } + + // Before we make a channel, we'll load up Carol with some coins sent + // directly from the miner. + err = net.SendCoins(ctxb, btcutil.SatoshiPerBitcoin, carol) + if err != nil { + t.Fatalf("unable to send coins to carol: %v", err) + } + + // In order to test Carol's response to an uncooperative channel // closure by Bob, we'll first open up a channel between them with a // 0.5 BTC value. ctxt, _ := context.WithTimeout(ctxb, timeout) chanPoint := openChannelAndAssert( - ctxt, t, net, net.Alice, net.Bob, chanAmt, 0, false, + ctxt, t, net, carol, net.Bob, chanAmt, 0, false, ) // With the channel open, we'll create a few invoices for Bob that - // Alice will pay to in order to advance the state of the channel. + // Carol will pay to in order to advance the state of the channel. bobPayReqs := make([]string, numInvoices) for i := 0; i < numInvoices; i++ { preimage := bytes.Repeat([]byte{byte(255 - i)}, 32) @@ -5138,18 +5163,18 @@ func testRevokedCloseRetribution(net *lntest.NetworkHarness, t *harnessTest) { return bobChannelInfo.Channels[0], nil } - // Wait for Alice to receive the channel edge from the funding manager. + // Wait for Carol to receive the channel edge from the funding manager. ctxt, _ = context.WithTimeout(ctxb, timeout) - err := net.Alice.WaitForNetworkChannelOpen(ctxt, chanPoint) + err = carol.WaitForNetworkChannelOpen(ctxt, chanPoint) if err != nil { - t.Fatalf("alice didn't see the alice->bob channel before "+ + t.Fatalf("carol didn't see the carol->bob channel before "+ "timeout: %v", err) } - // Send payments from Alice to Bob using 3 of Bob's payment hashes + // Send payments from Carol to Bob using 3 of Bob's payment hashes // generated above. ctxt, _ = context.WithTimeout(ctxb, timeout) - err = completePaymentRequests(ctxt, net.Alice, bobPayReqs[:numInvoices/2], + err = completePaymentRequests(ctxt, carol, bobPayReqs[:numInvoices/2], true) if err != nil { t.Fatalf("unable to send payments: %v", err) @@ -5199,10 +5224,10 @@ func testRevokedCloseRetribution(net *lntest.NetworkHarness, t *harnessTest) { t.Fatalf("unable to copy database files: %v", err) } - // Finally, send payments from Alice to Bob, consuming Bob's remaining + // Finally, send payments from Carol to Bob, consuming Bob's remaining // payment hashes. ctxt, _ = context.WithTimeout(ctxb, timeout) - err = completePaymentRequests(ctxt, net.Alice, bobPayReqs[numInvoices/2:], + err = completePaymentRequests(ctxt, carol, bobPayReqs[numInvoices/2:], true) if err != nil { t.Fatalf("unable to send payments: %v", err) @@ -5236,7 +5261,7 @@ func testRevokedCloseRetribution(net *lntest.NetworkHarness, t *harnessTest) { // Now force Bob to execute a *force* channel closure by unilaterally // broadcasting his current channel state. This is actually the // commitment transaction of a prior *revoked* state, so he'll soon - // feel the wrath of Alice's retribution. + // feel the wrath of Carol's retribution. var closeUpdates lnrpc.Lightning_CloseChannelClient force := true err = lntest.WaitPredicate(func() bool { @@ -5253,19 +5278,19 @@ func testRevokedCloseRetribution(net *lntest.NetworkHarness, t *harnessTest) { } // Wait for Bob's breach transaction to show up in the mempool to ensure - // that Alice's node has started waiting for confirmations. + // that Carol's node has started waiting for confirmations. _, err = waitForTxInMempool(net.Miner.Node, 5*time.Second) if err != nil { t.Fatalf("unable to find Bob's breach tx in mempool: %v", err) } - // Here, Alice sees Bob's breach transaction in the mempool, but is waiting - // for it to confirm before continuing her retribution. We restart Alice to + // Here, Carol sees Bob's breach transaction in the mempool, but is waiting + // for it to confirm before continuing her retribution. We restart Carol to // ensure that she is persisting her retribution state and continues // watching for the breach transaction to confirm even after her node // restarts. - if err := net.RestartNode(net.Alice, nil); err != nil { - t.Fatalf("unable to restart Alice's node: %v", err) + if err := net.RestartNode(carol, nil); err != nil { + t.Fatalf("unable to restart Carol's node: %v", err) } // Finally, generate a single block, wait for the final close status @@ -5279,12 +5304,12 @@ func testRevokedCloseRetribution(net *lntest.NetworkHarness, t *harnessTest) { } assertTxInBlock(t, block, breachTXID) - // Query the mempool for Alice's justice transaction, this should be + // Query the mempool for Carol's justice transaction, this should be // broadcast as Bob's contract breaching transaction gets confirmed // above. justiceTXID, err := waitForTxInMempool(net.Miner.Node, 5*time.Second) if err != nil { - t.Fatalf("unable to find Alice's justice tx in mempool: %v", err) + t.Fatalf("unable to find Carol's justice tx in mempool: %v", err) } time.Sleep(100 * time.Millisecond) @@ -5302,16 +5327,16 @@ func testRevokedCloseRetribution(net *lntest.NetworkHarness, t *harnessTest) { } } - // We restart Alice here to ensure that she persists her retribution state + // We restart Carol here to ensure that she persists her retribution state // and successfully continues exacting retribution after restarting. At - // this point, Alice has broadcast the justice transaction, but it hasn't - // been confirmed yet; when Alice restarts, she should start waiting for + // this point, Carol has broadcast the justice transaction, but it hasn't + // been confirmed yet; when Carol restarts, she should start waiting for // the justice transaction to confirm again. - if err := net.RestartNode(net.Alice, nil); err != nil { - t.Fatalf("unable to restart Alice's node: %v", err) + if err := net.RestartNode(carol, nil); err != nil { + t.Fatalf("unable to restart Carol's node: %v", err) } - // Now mine a block, this transaction should include Alice's justice + // Now mine a block, this transaction should include Carol's justice // transaction which was just accepted into the mempool. block = mineBlocks(t, net, 1)[0] @@ -5325,10 +5350,10 @@ func testRevokedCloseRetribution(net *lntest.NetworkHarness, t *harnessTest) { t.Fatalf("justice tx wasn't mined") } - assertNodeNumChannels(t, ctxb, net.Alice, 0) + assertNodeNumChannels(t, ctxb, carol, 0) } -// testRevokedCloseRetributionZeroValueRemoteOutput tests that Alice is able +// testRevokedCloseRetributionZeroValueRemoteOutput tests that Dave is able // carry out retribution in the event that she fails in state where the remote // commitment output has zero-value. func testRevokedCloseRetributionZeroValueRemoteOutput(net *lntest.NetworkHarness, @@ -5350,22 +5375,41 @@ func testRevokedCloseRetributionZeroValueRemoteOutput(net *lntest.NetworkHarness } defer shutdownAndAssert(net, t, carol) - // We must let Alice have an open channel before she can send a node + // Dave will be the breached party. We set --nolisten to ensure Carol + // won't be able to connect to him and trigger the channel data + // protection logic automatically. + dave, err := net.NewNode( + "Dave", + []string{"--debughtlc", "--hodl.exit-settle", "--nolisten"}, + ) + if err != nil { + t.Fatalf("unable to create new node: %v", err) + } + defer shutdownAndAssert(net, t, dave) + + // We must let Dave have an open channel before she can send a node // announcement, so we open a channel with Carol, - if err := net.ConnectNodes(ctxb, net.Alice, carol); err != nil { - t.Fatalf("unable to connect alice to carol: %v", err) + if err := net.ConnectNodes(ctxb, dave, carol); err != nil { + t.Fatalf("unable to connect dave to carol: %v", err) } - // In order to test Alice's response to an uncooperative channel + // Before we make a channel, we'll load up Dave with some coins sent + // directly from the miner. + err = net.SendCoins(ctxb, btcutil.SatoshiPerBitcoin, dave) + if err != nil { + t.Fatalf("unable to send coins to dave: %v", err) + } + + // In order to test Dave's response to an uncooperative channel // closure by Carol, we'll first open up a channel between them with a // 0.5 BTC value. ctxt, _ := context.WithTimeout(ctxb, timeout) chanPoint := openChannelAndAssert( - ctxt, t, net, net.Alice, carol, chanAmt, 0, false, + ctxt, t, net, dave, carol, chanAmt, 0, false, ) // With the channel open, we'll create a few invoices for Carol that - // Alice will pay to in order to advance the state of the channel. + // Dave will pay to in order to advance the state of the channel. carolPayReqs := make([]string, numInvoices) for i := 0; i < numInvoices; i++ { preimage := bytes.Repeat([]byte{byte(192 - i)}, 32) @@ -5398,11 +5442,11 @@ func testRevokedCloseRetributionZeroValueRemoteOutput(net *lntest.NetworkHarness return carolChannelInfo.Channels[0], nil } - // Wait for Alice to receive the channel edge from the funding manager. + // Wait for Dave to receive the channel edge from the funding manager. ctxt, _ = context.WithTimeout(ctxb, timeout) - err = net.Alice.WaitForNetworkChannelOpen(ctxt, chanPoint) + err = dave.WaitForNetworkChannelOpen(ctxt, chanPoint) if err != nil { - t.Fatalf("alice didn't see the alice->carol channel before "+ + t.Fatalf("dave didn't see the dave->carol channel before "+ "timeout: %v", err) } @@ -5438,9 +5482,9 @@ func testRevokedCloseRetributionZeroValueRemoteOutput(net *lntest.NetworkHarness t.Fatalf("unable to copy database files: %v", err) } - // Finally, send payments from Alice to Carol, consuming Carol's remaining + // Finally, send payments from Dave to Carol, consuming Carol's remaining // payment hashes. - err = completePaymentRequests(ctxb, net.Alice, carolPayReqs, false) + err = completePaymentRequests(ctxb, dave, carolPayReqs, false) if err != nil { t.Fatalf("unable to send payments: %v", err) } @@ -5473,7 +5517,7 @@ func testRevokedCloseRetributionZeroValueRemoteOutput(net *lntest.NetworkHarness // Now force Carol to execute a *force* channel closure by unilaterally // broadcasting his current channel state. This is actually the // commitment transaction of a prior *revoked* state, so he'll soon - // feel the wrath of Alice's retribution. + // feel the wrath of Dave's retribution. var ( closeUpdates lnrpc.Lightning_CloseChannelClient closeTxId *chainhash.Hash @@ -5507,11 +5551,11 @@ func testRevokedCloseRetributionZeroValueRemoteOutput(net *lntest.NetworkHarness // block. block := mineBlocks(t, net, 1)[0] - // Here, Alice receives a confirmation of Carol's breach transaction. - // We restart Alice to ensure that she is persisting her retribution + // Here, Dave receives a confirmation of Carol's breach transaction. + // We restart Dave to ensure that she is persisting her retribution // state and continues exacting justice after her node restarts. - if err := net.RestartNode(net.Alice, nil); err != nil { - t.Fatalf("unable to stop Alice's node: %v", err) + if err := net.RestartNode(dave, nil); err != nil { + t.Fatalf("unable to stop Dave's node: %v", err) } breachTXID, err := net.WaitForChannelClose(ctxb, closeUpdates) @@ -5520,12 +5564,12 @@ func testRevokedCloseRetributionZeroValueRemoteOutput(net *lntest.NetworkHarness } assertTxInBlock(t, block, breachTXID) - // Query the mempool for Alice's justice transaction, this should be + // Query the mempool for Dave's justice transaction, this should be // broadcast as Carol's contract breaching transaction gets confirmed // above. justiceTXID, err := waitForTxInMempool(net.Miner.Node, 15*time.Second) if err != nil { - t.Fatalf("unable to find Alice's justice tx in mempool: %v", + t.Fatalf("unable to find Dave's justice tx in mempool: %v", err) } time.Sleep(100 * time.Millisecond) @@ -5544,16 +5588,16 @@ func testRevokedCloseRetributionZeroValueRemoteOutput(net *lntest.NetworkHarness } } - // We restart Alice here to ensure that she persists her retribution state + // We restart Dave here to ensure that he persists her retribution state // and successfully continues exacting retribution after restarting. At - // this point, Alice has broadcast the justice transaction, but it hasn't - // been confirmed yet; when Alice restarts, she should start waiting for + // this point, Dave has broadcast the justice transaction, but it hasn't + // been confirmed yet; when Dave restarts, she should start waiting for // the justice transaction to confirm again. - if err := net.RestartNode(net.Alice, nil); err != nil { - t.Fatalf("unable to restart Alice's node: %v", err) + if err := net.RestartNode(dave, nil); err != nil { + t.Fatalf("unable to restart Dave's node: %v", err) } - // Now mine a block, this transaction should include Alice's justice + // Now mine a block, this transaction should include Dave's justice // transaction which was just accepted into the mempool. block = mineBlocks(t, net, 1)[0] @@ -5567,7 +5611,7 @@ func testRevokedCloseRetributionZeroValueRemoteOutput(net *lntest.NetworkHarness t.Fatalf("justice tx wasn't mined") } - assertNodeNumChannels(t, ctxb, net.Alice, 0) + assertNodeNumChannels(t, ctxb, dave, 0) } // testRevokedCloseRetributionRemoteHodl tests that Dave properly responds to a @@ -5596,8 +5640,13 @@ func testRevokedCloseRetributionRemoteHodl(net *lntest.NetworkHarness, // We'll also create a new node Dave, who will have a channel with // Carol, and also use similar settings so we can broadcast a commit - // with active HTLCs. - dave, err := net.NewNode("Dave", []string{"--debughtlc", "--hodl.exit-settle"}) + // with active HTLCs. Dave will be the breached party. We set + // --nolisten to ensure Carol won't be able to connect to him and + // trigger the channel data protection logic automatically. + dave, err := net.NewNode( + "Dave", + []string{"--debughtlc", "--hodl.exit-settle", "--nolisten"}, + ) if err != nil { t.Fatalf("unable to create new dave node: %v", err) }