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

     1  package itest
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  	"strings"
     7  	"time"
     8  
     9  	"golang.org/x/net/context"
    10  	"matheusd.com/testctx"
    11  
    12  	"github.com/decred/dcrd/chaincfg/chainhash"
    13  	"github.com/decred/dcrd/dcrutil/v4"
    14  	"github.com/decred/dcrd/txscript/v4/stdscript"
    15  	"github.com/decred/dcrd/wire"
    16  	"github.com/decred/dcrlnd/input"
    17  	"github.com/decred/dcrlnd/lnrpc"
    18  	"github.com/decred/dcrlnd/lnrpc/walletrpc"
    19  	"github.com/decred/dcrlnd/lntest"
    20  	"github.com/decred/dcrlnd/lntest/wait"
    21  	"github.com/decred/dcrlnd/lnwallet"
    22  	"github.com/decred/dcrlnd/sweep"
    23  	"github.com/stretchr/testify/require"
    24  )
    25  
    26  // testCPFP ensures that the daemon can bump an unconfirmed  transaction's fee
    27  // rate by broadcasting a Child-Pays-For-Parent (CPFP) transaction.
    28  //
    29  // TODO(wilmer): Add RBF case once btcd supports it.
    30  func testCPFP(net *lntest.NetworkHarness, t *harnessTest) {
    31  	runCPFP(net, t, net.Alice, net.Bob)
    32  }
    33  
    34  // runCPFP ensures that the daemon can bump an unconfirmed  transaction's fee
    35  // rate by broadcasting a Child-Pays-For-Parent (CPFP) transaction.
    36  func runCPFP(net *lntest.NetworkHarness, t *harnessTest,
    37  	alice, bob *lntest.HarnessNode) {
    38  
    39  	// Skip this test for neutrino, as it's not aware of mempool
    40  	// transactions.
    41  	if net.BackendCfg.Name() == "spv" {
    42  		t.Skipf("skipping CPFP test for spv backend")
    43  	}
    44  
    45  	// We'll start the test by sending Alice some coins, which she'll use to
    46  	// send to Bob.
    47  	ctxb := context.Background()
    48  	net.SendCoins(t.t, dcrutil.AtomsPerCoin, alice)
    49  
    50  	// Create an address for Bob to send the coins to.
    51  	addrReq := &lnrpc.NewAddressRequest{
    52  		Type: lnrpc.AddressType_PUBKEY_HASH,
    53  	}
    54  	ctxt, _ := context.WithTimeout(ctxb, defaultTimeout)
    55  	resp, err := bob.NewAddress(ctxt, addrReq)
    56  	if err != nil {
    57  		t.Fatalf("unable to get new address for bob: %v", err)
    58  	}
    59  
    60  	// Send the coins from Alice to Bob. We should expect a transaction to
    61  	// be broadcast and seen in the mempool.
    62  	sendReq := &lnrpc.SendCoinsRequest{
    63  		Addr:   resp.Address,
    64  		Amount: dcrutil.AtomsPerCoin,
    65  	}
    66  	ctxt, _ = context.WithTimeout(ctxb, defaultTimeout)
    67  	if _, err = alice.SendCoins(ctxt, sendReq); err != nil {
    68  		t.Fatalf("unable to send coins to bob: %v", err)
    69  	}
    70  
    71  	txid, err := waitForTxInMempool(net.Miner.Node, minerMempoolTimeout)
    72  	if err != nil {
    73  		t.Fatalf("expected one mempool transaction: %v", err)
    74  	}
    75  
    76  	// We'll then extract the raw transaction from the mempool in order to
    77  	// determine the index of Bob's output.
    78  	tx, err := net.Miner.Node.GetRawTransaction(ctxt, txid)
    79  	if err != nil {
    80  		t.Fatalf("unable to extract raw transaction from mempool: %v",
    81  			err)
    82  	}
    83  	bobOutputIdx := -1
    84  	for i, txOut := range tx.MsgTx().TxOut {
    85  		_, addrs := stdscript.ExtractAddrs(
    86  			txOut.Version, txOut.PkScript, net.Miner.ActiveNet,
    87  		)
    88  		if len(addrs) != 1 {
    89  			t.Fatalf("wrong nb of addresses from pkScript=%x: "+
    90  				"%v", txOut.PkScript, err)
    91  		}
    92  		if addrs[0].String() == resp.Address {
    93  			bobOutputIdx = i
    94  		}
    95  	}
    96  	if bobOutputIdx == -1 {
    97  		t.Fatalf("bob's output was not found within the transaction")
    98  	}
    99  
   100  	// Wait until bob has seen the tx and considers it as owned.
   101  	op := &lnrpc.OutPoint{
   102  		TxidBytes:   txid[:],
   103  		OutputIndex: uint32(bobOutputIdx),
   104  	}
   105  	assertWalletUnspent(t, bob, op)
   106  
   107  	// We'll attempt to bump the fee of this transaction by performing a
   108  	// CPFP from Alice's point of view.
   109  	bumpFeeReq := &walletrpc.BumpFeeRequest{
   110  		Outpoint:     op,
   111  		AtomsPerByte: uint32(sweep.DefaultMaxFeeRate / 1000),
   112  	}
   113  	ctxt, _ = context.WithTimeout(ctxb, defaultTimeout)
   114  	_, err = bob.WalletKitClient.BumpFee(ctxt, bumpFeeReq)
   115  	if err != nil {
   116  		t.Fatalf("unable to bump fee: %v", err)
   117  	}
   118  
   119  	// We should now expect to see two transactions within the mempool, a
   120  	// parent and its child.
   121  	_, err = waitForNTxsInMempool(net.Miner.Node, 2, minerMempoolTimeout)
   122  	if err != nil {
   123  		t.Fatalf("expected two mempool transactions: %v", err)
   124  	}
   125  
   126  	// We should also expect to see the output being swept by the
   127  	// UtxoSweeper. We'll ensure it's using the fee rate specified.
   128  	pendingSweepsReq := &walletrpc.PendingSweepsRequest{}
   129  	ctxt, _ = context.WithTimeout(ctxb, defaultTimeout)
   130  	pendingSweepsResp, err := bob.WalletKitClient.PendingSweeps(
   131  		ctxt, pendingSweepsReq,
   132  	)
   133  	if err != nil {
   134  		t.Fatalf("unable to retrieve pending sweeps: %v", err)
   135  	}
   136  	if len(pendingSweepsResp.PendingSweeps) != 1 {
   137  		t.Fatalf("expected to find %v pending sweep(s), found %v", 1,
   138  			len(pendingSweepsResp.PendingSweeps))
   139  	}
   140  	pendingSweep := pendingSweepsResp.PendingSweeps[0]
   141  	if !bytes.Equal(pendingSweep.Outpoint.TxidBytes, op.TxidBytes) {
   142  		t.Fatalf("expected output txid %x, got %x", op.TxidBytes,
   143  			pendingSweep.Outpoint.TxidBytes)
   144  	}
   145  	if pendingSweep.Outpoint.OutputIndex != op.OutputIndex {
   146  		t.Fatalf("expected output index %v, got %v", op.OutputIndex,
   147  			pendingSweep.Outpoint.OutputIndex)
   148  	}
   149  	if pendingSweep.AtomsPerByte != bumpFeeReq.AtomsPerByte {
   150  		t.Fatalf("expected sweep atoms per byte %v, got %v",
   151  			bumpFeeReq.AtomsPerByte, pendingSweep.AtomsPerByte)
   152  	}
   153  
   154  	// Mine a block to clean up the unconfirmed transactions.
   155  	mineBlocks(t, net, 1, 2)
   156  
   157  	// The input used to CPFP should no longer be pending.
   158  	err = wait.NoError(func() error {
   159  		req := &walletrpc.PendingSweepsRequest{}
   160  		ctxt, _ = context.WithTimeout(ctxb, defaultTimeout)
   161  		resp, err := bob.WalletKitClient.PendingSweeps(ctxt, req)
   162  		if err != nil {
   163  			return fmt.Errorf("unable to retrieve bob's pending "+
   164  				"sweeps: %v", err)
   165  		}
   166  		if len(resp.PendingSweeps) != 0 {
   167  			return fmt.Errorf("expected 0 pending sweeps, found %d",
   168  				len(resp.PendingSweeps))
   169  		}
   170  		return nil
   171  	}, defaultTimeout)
   172  	if err != nil {
   173  		t.Fatalf(err.Error())
   174  	}
   175  }
   176  
   177  // testAnchorReservedValue tests that we won't allow sending transactions when
   178  // that would take the value we reserve for anchor fee bumping out of our
   179  // wallet.
   180  func testAnchorReservedValue(net *lntest.NetworkHarness, t *harnessTest) {
   181  	// Start two nodes supporting anchor channels.
   182  	args := nodeArgsForCommitType(lnrpc.CommitmentType_ANCHORS)
   183  	alice := net.NewNode(t.t, "Alice", args)
   184  	defer shutdownAndAssert(net, t, alice)
   185  
   186  	bob := net.NewNode(t.t, "Bob", args)
   187  	defer shutdownAndAssert(net, t, bob)
   188  
   189  	ctxb := context.Background()
   190  	net.ConnectNodes(t.t, alice, bob)
   191  
   192  	// Send just enough coins for Alice to open a channel without a change
   193  	// output.
   194  	const (
   195  		chanAmt = 1000000
   196  		feeEst  = 8000
   197  	)
   198  
   199  	net.SendCoins(t.t, chanAmt+feeEst, alice)
   200  
   201  	// wallet, without a change output. This should not be allowed.
   202  	resErr := lnwallet.ErrReservedValueInvalidated.Error()
   203  
   204  	_, err := net.OpenChannel(
   205  		alice, bob, lntest.OpenChannelParams{
   206  			Amt: chanAmt,
   207  		},
   208  	)
   209  	if err == nil || !strings.Contains(err.Error(), resErr) {
   210  		t.Fatalf("expected failure, got: %v", err)
   211  	}
   212  
   213  	// Alice opens a smaller channel. This works since it will have a
   214  	// change output.
   215  	aliceChanPoint1 := openChannelAndAssert(
   216  		t, net, alice, bob, lntest.OpenChannelParams{
   217  			Amt: chanAmt / 4,
   218  		},
   219  	)
   220  
   221  	// If Alice tries to open another anchor channel to Bob, Bob should not
   222  	// reject it as he is not contributing any funds.
   223  	aliceChanPoint2 := openChannelAndAssert(
   224  		t, net, alice, bob, lntest.OpenChannelParams{
   225  			Amt: chanAmt / 4,
   226  		},
   227  	)
   228  
   229  	// Similarly, if Alice tries to open a legacy channel to Bob, Bob should
   230  	// not reject it as he is not contributing any funds. We'll restart Bob
   231  	// to remove his support for anchors.
   232  	err = net.RestartNode(bob, nil)
   233  	require.NoError(t.t, err)
   234  	aliceChanPoint3 := openChannelAndAssert(
   235  		t, net, alice, bob, lntest.OpenChannelParams{
   236  			Amt: chanAmt / 4,
   237  		},
   238  	)
   239  
   240  	chanPoints := []*lnrpc.ChannelPoint{
   241  		aliceChanPoint1, aliceChanPoint2, aliceChanPoint3,
   242  	}
   243  	for _, chanPoint := range chanPoints {
   244  		err = alice.WaitForNetworkChannelOpen(chanPoint)
   245  		require.NoError(t.t, err)
   246  
   247  		err = bob.WaitForNetworkChannelOpen(chanPoint)
   248  		require.NoError(t.t, err)
   249  	}
   250  
   251  	// Alice tries to send all coins to an internal address. This is
   252  	// allowed, since the final wallet balance will still be above the
   253  	// reserved value.
   254  	addrReq := &lnrpc.NewAddressRequest{
   255  		Type: lnrpc.AddressType_PUBKEY_HASH,
   256  	}
   257  	ctxt, _ := context.WithTimeout(ctxb, defaultTimeout)
   258  	resp, err := alice.NewAddress(ctxt, addrReq)
   259  	require.NoError(t.t, err)
   260  
   261  	sweepReq := &lnrpc.SendCoinsRequest{
   262  		Addr:    resp.Address,
   263  		SendAll: true,
   264  	}
   265  	ctxt, _ = context.WithTimeout(ctxb, defaultTimeout)
   266  	_, err = alice.SendCoins(ctxt, sweepReq)
   267  	require.NoError(t.t, err)
   268  
   269  	block := mineBlocks(t, net, 1, 1)[0]
   270  
   271  	// The sweep transaction should have exactly one input, the change from
   272  	// the previous SendCoins call.
   273  	sweepTx := block.Transactions[1]
   274  	if len(sweepTx.TxIn) != 1 {
   275  		t.Fatalf("expected 1 inputs instead have %v", len(sweepTx.TxIn))
   276  	}
   277  
   278  	// It should have a single output.
   279  	if len(sweepTx.TxOut) != 1 {
   280  		t.Fatalf("expected 1 output instead have %v", len(sweepTx.TxOut))
   281  	}
   282  
   283  	// Wait for Alice to see her balance as confirmed.
   284  	waitForConfirmedBalance := func() int64 {
   285  		var balance int64
   286  		err := wait.NoError(func() error {
   287  			req := &lnrpc.WalletBalanceRequest{}
   288  			ctxt, _ = context.WithTimeout(ctxb, defaultTimeout)
   289  			resp, err := alice.WalletBalance(ctxt, req)
   290  			if err != nil {
   291  				return err
   292  			}
   293  
   294  			if resp.TotalBalance == 0 {
   295  				return fmt.Errorf("no balance")
   296  			}
   297  
   298  			if resp.UnconfirmedBalance > 0 {
   299  				return fmt.Errorf("unconfirmed balance")
   300  			}
   301  
   302  			balance = resp.TotalBalance
   303  			return nil
   304  		}, defaultTimeout)
   305  		require.NoError(t.t, err)
   306  
   307  		return balance
   308  	}
   309  
   310  	_ = waitForConfirmedBalance()
   311  
   312  	// Alice tries to send all funds to an external address, the reserved
   313  	// value must stay in her wallet.
   314  	minerAddr, err := net.Miner.NewAddress(testctx.New(t))
   315  	require.NoError(t.t, err)
   316  
   317  	sweepReq = &lnrpc.SendCoinsRequest{
   318  		Addr:    minerAddr.String(),
   319  		SendAll: true,
   320  	}
   321  	ctxt, _ = context.WithTimeout(ctxb, defaultTimeout)
   322  	_, err = alice.SendCoins(ctxt, sweepReq)
   323  	require.NoError(t.t, err)
   324  
   325  	// We'll mine a block which should include the sweep transaction we
   326  	// generated above.
   327  	block = mineBlocks(t, net, 1, 1)[0]
   328  
   329  	// The sweep transaction should have exactly one inputs as we only had
   330  	// the single output from above in the wallet.
   331  	sweepTx = block.Transactions[1]
   332  	if len(sweepTx.TxIn) != 1 {
   333  		t.Fatalf("expected 1 inputs instead have %v", len(sweepTx.TxIn))
   334  	}
   335  
   336  	// It should have two outputs, one being the miner address, the other
   337  	// one being the reserve going back to our wallet.
   338  	if len(sweepTx.TxOut) != 2 {
   339  		t.Fatalf("expected 2 outputs instead have %v", len(sweepTx.TxOut))
   340  	}
   341  
   342  	// The reserved value is now back in Alice's wallet.
   343  	aliceBalance := waitForConfirmedBalance()
   344  
   345  	// Alice closes channel, should now be allowed to send everything to an
   346  	// external address.
   347  	for _, chanPoint := range chanPoints {
   348  		closeChannelAndAssert(t, net, alice, chanPoint, false)
   349  	}
   350  
   351  	newBalance := waitForConfirmedBalance()
   352  	if newBalance <= aliceBalance {
   353  		t.Fatalf("Alice's balance did not increase after channel close")
   354  	}
   355  
   356  	// Assert there are no open or pending channels anymore.
   357  	assertNumPendingChannels(t, alice, 0, 0, 0, 0)
   358  	assertNodeNumChannels(t, alice, 0)
   359  
   360  	// We'll wait for the balance to reflect that the channel has been
   361  	// closed and the funds are in the wallet.
   362  	sweepReq = &lnrpc.SendCoinsRequest{
   363  		Addr:    minerAddr.String(),
   364  		SendAll: true,
   365  	}
   366  	ctxt, _ = context.WithTimeout(ctxb, defaultTimeout)
   367  	_, err = alice.SendCoins(ctxt, sweepReq)
   368  	require.NoError(t.t, err)
   369  
   370  	// We'll mine a block which should include the sweep transaction we
   371  	// generated above.
   372  	block = mineBlocks(t, net, 1, 1)[0]
   373  
   374  	// The sweep transaction should have four inputs, the change output from
   375  	// the previous sweep, and the outputs from the coop closed channels.
   376  	sweepTx = block.Transactions[1]
   377  	if len(sweepTx.TxIn) != 4 {
   378  		t.Fatalf("expected 4 inputs instead have %v", len(sweepTx.TxIn))
   379  	}
   380  
   381  	// It should have a single output.
   382  	if len(sweepTx.TxOut) != 1 {
   383  		t.Fatalf("expected 1 output instead have %v", len(sweepTx.TxOut))
   384  	}
   385  }
   386  
   387  // genAnchorSweep generates a "3rd party" anchor sweeping from an existing one.
   388  // In practice, we just re-use the existing witness, and track on our own
   389  // output producing a 1-in-1-out transaction.
   390  func genAnchorSweep(t *harnessTest, net *lntest.NetworkHarness,
   391  	aliceAnchor *sweptOutput, anchorCsv uint32) *dcrutil.Tx {
   392  
   393  	// At this point, we have the transaction that Alice used to try to
   394  	// sweep her anchor. As this is actually just something anyone can
   395  	// spend, just need to find the input spending the anchor output, then
   396  	// we can swap the output address.
   397  	aliceAnchorTxIn := func() wire.TxIn {
   398  		for _, txIn := range aliceAnchor.SweepTx.TxIn {
   399  			if txIn.PreviousOutPoint == aliceAnchor.OutPoint {
   400  				return *txIn
   401  			}
   402  		}
   403  
   404  		t.Fatalf("anchor op not found")
   405  		return wire.TxIn{}
   406  	}()
   407  
   408  	// We'll set the signature on the input to nil, and then set the
   409  	// sequence to 16 (the anchor CSV period).
   410  	aliceAnchorTxIn.SignatureScript = nil
   411  	aliceAnchorTxIn.Sequence = anchorCsv
   412  
   413  	minerAddr, err := net.Miner.NewAddress(testctx.New(t))
   414  	if err != nil {
   415  		t.Fatalf("unable to get miner addr: %v", err)
   416  	}
   417  	scriptVersion, addrScript := minerAddr.PaymentScript()
   418  
   419  	// Now that we have the txIn, we can just make a new transaction that
   420  	// uses a different script for the output.
   421  	tx := wire.NewMsgTx()
   422  	tx.Version = input.LNTxVersion
   423  	tx.AddTxIn(&aliceAnchorTxIn)
   424  	tx.AddTxOut(&wire.TxOut{
   425  		Version:  scriptVersion,
   426  		PkScript: addrScript,
   427  		Value:    anchorSize - 1,
   428  	})
   429  
   430  	return dcrutil.NewTx(tx)
   431  }
   432  
   433  // testAnchorThirdPartySpend tests that if we force close a channel, but then
   434  // don't sweep the anchor in time and a 3rd party spends it, that we remove any
   435  // transactions that are a descendent of that sweep.
   436  func testAnchorThirdPartySpend(net *lntest.NetworkHarness, t *harnessTest) {
   437  	// This test requires an rpctest func (GenerateAndSubmitBlock) to
   438  	// perform something that is not currently available in decred: namely,
   439  	// to mine a block with _only_ a specific set of transactions. This is
   440  	// hard to do in decred, due to the requirements of the staking
   441  	// subsystem.
   442  	//
   443  	// This function is used so that the test can enforce that the
   444  	// transaction that redeems the anchor output from the force-closed
   445  	// channel is NOT mined (along with the force-close) and instead is
   446  	// double spent by someone else.
   447  	//
   448  	// Given that anchor outputs are currently disabled in mainnet, this
   449  	// test is skipped.
   450  	t.Skipf("Test disabled in dcrlnd")
   451  
   452  	// First, we'll create two new nodes that both default to anchor
   453  	// channels.
   454  	//
   455  	// NOTE: The itests differ here as anchors is default off vs the normal
   456  	// lnd binary.
   457  	args := nodeArgsForCommitType(lnrpc.CommitmentType_ANCHORS)
   458  	alice := net.NewNode(t.t, "Alice", args)
   459  	defer shutdownAndAssert(net, t, alice)
   460  
   461  	bob := net.NewNode(t.t, "Bob", args)
   462  	defer shutdownAndAssert(net, t, bob)
   463  
   464  	ctxb := context.Background()
   465  	net.ConnectNodes(t.t, alice, bob)
   466  
   467  	// We'll fund our Alice with coins, as she'll be opening the channel.
   468  	// We'll fund her with *just* enough coins to open the channel.
   469  	const (
   470  		firstChanSize   = 1_000_000
   471  		anchorFeeBuffer = 500_000
   472  	)
   473  	net.SendCoins(t.t, firstChanSize, alice)
   474  
   475  	// We'll give Alice another spare UTXO as well so she can use it to
   476  	// help sweep all coins.
   477  	net.SendCoins(t.t, anchorFeeBuffer, alice)
   478  
   479  	// Open the channel between the two nodes and wait for it to confirm
   480  	// fully.
   481  	aliceChanPoint1 := openChannelAndAssert(
   482  		t, net, alice, bob, lntest.OpenChannelParams{
   483  			Amt: firstChanSize,
   484  		},
   485  	)
   486  
   487  	// With the channel open, we'll actually immediately force close it. We
   488  	// don't care about network announcements here since there's no routing
   489  	// in this test.
   490  	_, _, err := net.CloseChannel(alice, aliceChanPoint1, true)
   491  	if err != nil {
   492  		t.Fatalf("unable to execute force channel closure: %v", err)
   493  	}
   494  
   495  	// Now that the channel has been force closed, it should show up in the
   496  	// PendingChannels RPC under the waiting close section.
   497  	pendingChansRequest := &lnrpc.PendingChannelsRequest{}
   498  	ctxt, _ := context.WithTimeout(ctxb, defaultTimeout)
   499  	pendingChanResp, err := alice.PendingChannels(ctxt, pendingChansRequest)
   500  	if err != nil {
   501  		t.Fatalf("unable to query for pending channels: %v", err)
   502  	}
   503  	err = checkNumWaitingCloseChannels(pendingChanResp, 1)
   504  	if err != nil {
   505  		t.Fatalf(err.Error())
   506  	}
   507  
   508  	// Get the normal channel outpoint so we can track it in the set of
   509  	// channels that are waiting to be closed.
   510  	fundingTxID, err := lnrpc.GetChanPointFundingTxid(aliceChanPoint1)
   511  	if err != nil {
   512  		t.Fatalf("unable to get txid: %v", err)
   513  	}
   514  	chanPoint := wire.OutPoint{
   515  		Hash:  *fundingTxID,
   516  		Index: aliceChanPoint1.OutputIndex,
   517  	}
   518  	waitingClose, err := findWaitingCloseChannel(pendingChanResp, &chanPoint)
   519  	if err != nil {
   520  		t.Fatalf(err.Error())
   521  	}
   522  
   523  	// At this point, the channel is waiting close, and we have both the
   524  	// commitment transaction and anchor sweep in the mempool.
   525  	const expectedTxns = 2
   526  	sweepTxns, err := getNTxsFromMempool(
   527  		net.Miner.Node, expectedTxns, minerMempoolTimeout,
   528  	)
   529  	require.NoError(t.t, err, "no sweep txns in miner mempool")
   530  	aliceCloseTx := waitingClose.Commitments.LocalTxid
   531  	_, aliceAnchor := findCommitAndAnchor(t, net, sweepTxns, aliceCloseTx)
   532  
   533  	// We'll now mine _only_ the commitment force close transaction, as we
   534  	// want the anchor sweep to stay unconfirmed.
   535  	var emptyTime time.Time
   536  	forceCloseTxID, _ := chainhash.NewHashFromStr(aliceCloseTx)
   537  	commitTxn, err := net.Miner.Node.GetRawTransaction(
   538  		testctx.New(t), forceCloseTxID,
   539  	)
   540  	if err != nil {
   541  		t.Fatalf("unable to get transaction: %v", err)
   542  	}
   543  
   544  	_, err = net.Miner.GenerateAndSubmitBlock(
   545  		[]*dcrutil.Tx{commitTxn}, -1, emptyTime,
   546  	)
   547  	if err != nil {
   548  		t.Fatalf("unable to generate block: %v", err)
   549  	}
   550  
   551  	// With the anchor output located, and the main commitment mined we'll
   552  	// instruct the wallet to send all coins in the wallet to a new address
   553  	// (to the miner), including unconfirmed change.
   554  	minerAddr, err := net.Miner.NewAddress(testctx.New(t))
   555  	if err != nil {
   556  		t.Fatalf("unable to create new miner addr: %v", err)
   557  	}
   558  	sweepReq := &lnrpc.SendCoinsRequest{
   559  		Addr:             minerAddr.String(),
   560  		SendAll:          true,
   561  		MinConfs:         0,
   562  		SpendUnconfirmed: true,
   563  	}
   564  	ctxt, _ = context.WithTimeout(ctxb, defaultTimeout)
   565  	sweepAllResp, err := alice.SendCoins(ctxt, sweepReq)
   566  	if err != nil {
   567  		t.Fatalf("unable to sweep coins: %v", err)
   568  	}
   569  
   570  	// Both the original anchor sweep transaction, as well as the
   571  	// transaction we created to sweep all the coins from Alice's wallet
   572  	// should be found in her transaction store.
   573  	sweepAllTxID, _ := chainhash.NewHashFromStr(sweepAllResp.Txid)
   574  	assertTransactionInWallet(t.t, alice, aliceAnchor.SweepTx.TxHash())
   575  	assertTransactionInWallet(t.t, alice, *sweepAllTxID)
   576  
   577  	// Next, we'll shutdown Alice, and allow 16 blocks to pass so that the
   578  	// anchor output can be swept by anyone. Rather than use the normal API
   579  	// call, we'll generate a series of _empty_ blocks here.
   580  	aliceRestart, err := net.SuspendNode(alice)
   581  	if err != nil {
   582  		t.Fatalf("unable to shutdown alice: %v", err)
   583  	}
   584  	const anchorCsv = 16
   585  	for i := 0; i < anchorCsv; i++ {
   586  		_, err := net.Miner.GenerateAndSubmitBlock(nil, -1, emptyTime)
   587  		if err != nil {
   588  			t.Fatalf("unable to generate block: %v", err)
   589  		}
   590  	}
   591  
   592  	// Before we sweep the anchor, we'll restart Alice.
   593  	if err := aliceRestart(); err != nil {
   594  		t.Fatalf("unable to restart alice: %v", err)
   595  	}
   596  
   597  	// Now that the channel has been closed, and Alice has an unconfirmed
   598  	// transaction spending the output produced by her anchor sweep, we'll
   599  	// mine a transaction that double spends the output.
   600  	thirdPartyAnchorSweep := genAnchorSweep(t, net, aliceAnchor, anchorCsv)
   601  	_, err = net.Miner.GenerateAndSubmitBlock(
   602  		[]*dcrutil.Tx{thirdPartyAnchorSweep}, -1, emptyTime,
   603  	)
   604  	if err != nil {
   605  		t.Fatalf("unable to generate block: %v", err)
   606  	}
   607  
   608  	// At this point, we should no longer find Alice's transaction that
   609  	// tried to sweep the anchor in her wallet.
   610  	assertTransactionNotInWallet(t.t, alice, aliceAnchor.SweepTx.TxHash())
   611  
   612  	// In addition, the transaction she sent to sweep all her coins to the
   613  	// miner also should no longer be found.
   614  	assertTransactionNotInWallet(t.t, alice, *sweepAllTxID)
   615  
   616  	// The anchor should now show as being "lost", while the force close
   617  	// response is still present.
   618  	assertAnchorOutputLost(t, alice, chanPoint)
   619  
   620  	// At this point Alice's CSV output should already be fully spent and
   621  	// the channel marked as being resolved. We mine a block first, as so
   622  	// far we've been generating custom blocks this whole time..
   623  	commitSweepOp := wire.OutPoint{
   624  		Hash:  *forceCloseTxID,
   625  		Index: 1,
   626  	}
   627  	assertSpendingTxInMempool(
   628  		t, net.Miner.Node, minerMempoolTimeout, commitSweepOp,
   629  	)
   630  	_, err = net.Generate(1)
   631  	if err != nil {
   632  		t.Fatalf("unable to generate block: %v", err)
   633  	}
   634  	assertNumPendingChannels(t, alice, 0, 0, 0, 0)
   635  }