github.com/decred/dcrlnd@v0.7.6/lntest/itest/lnd_misc_test.go (about) 1 package itest 2 3 import ( 4 "bytes" 5 "context" 6 "crypto/rand" 7 "fmt" 8 "io/ioutil" 9 "strings" 10 "time" 11 12 "github.com/davecgh/go-spew/spew" 13 "github.com/decred/dcrd/chaincfg/chainhash" 14 "github.com/decred/dcrd/dcrutil/v4" 15 "github.com/decred/dcrd/wire" 16 "github.com/decred/dcrlnd/chainreg" 17 "github.com/decred/dcrlnd/input" 18 "github.com/decred/dcrlnd/lncfg" 19 "github.com/decred/dcrlnd/lnrpc" 20 "github.com/decred/dcrlnd/lnrpc/routerrpc" 21 "github.com/decred/dcrlnd/lnrpc/walletrpc" 22 "github.com/decred/dcrlnd/lntest" 23 "github.com/decred/dcrlnd/lntest/wait" 24 "github.com/decred/dcrlnd/lnwallet" 25 "github.com/decred/dcrlnd/lnwire" 26 "github.com/stretchr/testify/require" 27 "matheusd.com/testctx" 28 ) 29 30 // testDisconnectingTargetPeer performs a test which disconnects Alice-peer from 31 // Bob-peer and then re-connects them again. We expect Alice to be able to 32 // disconnect at any point. 33 func testDisconnectingTargetPeer(net *lntest.NetworkHarness, t *harnessTest) { 34 // We'll start both nodes with a high backoff so that they don't 35 // reconnect automatically during our test. 36 args := []string{ 37 "--minbackoff=1m", 38 "--maxbackoff=1m", 39 } 40 41 alice := net.NewNode(t.t, "Alice", args) 42 defer shutdownAndAssert(net, t, alice) 43 44 bob := net.NewNode(t.t, "Bob", args) 45 defer shutdownAndAssert(net, t, bob) 46 47 // Start by connecting Alice and Bob with no channels. 48 net.ConnectNodes(t.t, alice, bob) 49 50 // Check existing connection. 51 assertConnected(t, alice, bob) 52 53 // Give Alice some coins so she can fund a channel. 54 net.SendCoins(t.t, dcrutil.AtomsPerCoin, alice) 55 56 chanAmt := defaultChanAmt 57 pushAmt := dcrutil.Amount(0) 58 59 // Create a new channel that requires 1 confs before it's considered 60 // open, then broadcast the funding transaction 61 const numConfs = 1 62 pendingUpdate, err := net.OpenPendingChannel( 63 alice, bob, chanAmt, pushAmt, 64 ) 65 if err != nil { 66 t.Fatalf("unable to open channel: %v", err) 67 } 68 69 // At this point, the channel's funding transaction will have been 70 // broadcast, but not confirmed. Alice and Bob's nodes should reflect 71 // this when queried via RPC. 72 assertNumOpenChannelsPending(t, alice, bob, 1) 73 74 // Disconnect Alice-peer from Bob-peer and get error causes by one 75 // pending channel with detach node is existing. 76 if err := net.DisconnectNodes(alice, bob); err != nil { 77 t.Fatalf("Bob's peer was disconnected from Alice's"+ 78 " while one pending channel is existing: err %v", err) 79 } 80 81 time.Sleep(time.Millisecond * 300) 82 83 // Assert that the connection was torn down. 84 assertNotConnected(t, alice, bob) 85 86 fundingTxID, err := chainhash.NewHash(pendingUpdate.Txid) 87 if err != nil { 88 t.Fatalf("unable to convert funding txid into chainhash.Hash:"+ 89 " %v", err) 90 } 91 92 // Mine a block, then wait for Alice's node to notify us that the 93 // channel has been opened. The funding transaction should be found 94 // within the newly mined block. 95 block := mineBlocks(t, net, numConfs, 1)[0] 96 assertTxInBlock(t, block, fundingTxID) 97 98 // At this point, the channel should be fully opened and there should be 99 // no pending channels remaining for either node. 100 time.Sleep(time.Millisecond * 300) 101 102 assertNumOpenChannelsPending(t, alice, bob, 0) 103 104 // Reconnect the nodes so that the channel can become active. 105 net.ConnectNodes(t.t, alice, bob) 106 107 // The channel should be listed in the peer information returned by both 108 // peers. 109 outPoint := wire.OutPoint{ 110 Hash: *fundingTxID, 111 Index: pendingUpdate.OutputIndex, 112 } 113 114 // Check both nodes to ensure that the channel is ready for operation. 115 if err := net.AssertChannelExists(alice, &outPoint); err != nil { 116 t.Fatalf("unable to assert channel existence: %v", err) 117 } 118 if err := net.AssertChannelExists(bob, &outPoint); err != nil { 119 t.Fatalf("unable to assert channel existence: %v", err) 120 } 121 122 // Disconnect Alice-peer from Bob-peer and get error causes by one 123 // active channel with detach node is existing. 124 if err := net.DisconnectNodes(alice, bob); err != nil { 125 t.Fatalf("Bob's peer was disconnected from Alice's"+ 126 " while one active channel is existing: err %v", err) 127 } 128 129 // Check existing connection. 130 assertNotConnected(t, alice, bob) 131 132 // Reconnect both nodes before force closing the channel. 133 net.ConnectNodes(t.t, alice, bob) 134 135 // Finally, immediately close the channel. This function will also block 136 // until the channel is closed and will additionally assert the relevant 137 // channel closing post conditions. 138 chanPoint := &lnrpc.ChannelPoint{ 139 FundingTxid: &lnrpc.ChannelPoint_FundingTxidBytes{ 140 FundingTxidBytes: pendingUpdate.Txid, 141 }, 142 OutputIndex: pendingUpdate.OutputIndex, 143 } 144 145 closeChannelAndAssert(t, net, alice, chanPoint, true) 146 147 // Disconnect Alice-peer from Bob-peer without getting error about 148 // existing channels. 149 if err := net.DisconnectNodes(alice, bob); err != nil { 150 t.Fatalf("unable to disconnect Bob's peer from Alice's: err %v", 151 err) 152 } 153 154 // Check that the nodes not connected. 155 assertNotConnected(t, alice, bob) 156 157 // Finally, re-connect both nodes. 158 net.ConnectNodes(t.t, alice, bob) 159 160 // Check existing connection. 161 assertConnected(t, alice, bob) 162 163 // Cleanup by mining the force close and sweep transaction. 164 cleanupForceClose(t, net, alice, chanPoint) 165 } 166 167 // testSphinxReplayPersistence verifies that replayed onion packets are rejected 168 // by a remote peer after a restart. We use a combination of unsafe 169 // configuration arguments to force Carol to replay the same sphinx packet after 170 // reconnecting to Dave, and compare the returned failure message with what we 171 // expect for replayed onion packets. 172 func testSphinxReplayPersistence(net *lntest.NetworkHarness, t *harnessTest) { 173 ctxb := context.Background() 174 175 // Open a channel with 100k atoms between Carol and Dave with Carol being 176 // the sole funder of the channel. 177 chanAmt := dcrutil.Amount(100000) 178 179 // First, we'll create Dave, the receiver, and start him in hodl mode. 180 dave := net.NewNode(t.t, "Dave", []string{"--hodl.exit-settle"}) 181 182 // We must remember to shutdown the nodes we created for the duration 183 // of the tests, only leaving the two seed nodes (Alice and Bob) within 184 // our test network. 185 defer shutdownAndAssert(net, t, dave) 186 187 // Next, we'll create Carol and establish a channel to from her to 188 // Dave. Carol is started in both unsafe-replay which will cause her to 189 // replay any pending Adds held in memory upon reconnection. 190 carol := net.NewNode(t.t, "Carol", []string{"--unsafe-replay"}) 191 defer shutdownAndAssert(net, t, carol) 192 193 net.ConnectNodes(t.t, carol, dave) 194 net.SendCoins(t.t, dcrutil.AtomsPerCoin, carol) 195 196 chanPoint := openChannelAndAssert( 197 t, net, carol, dave, 198 lntest.OpenChannelParams{ 199 Amt: chanAmt, 200 }, 201 ) 202 203 // Next, we'll create Fred who is going to initiate the payment and 204 // establish a channel to from him to Carol. We can't perform this test 205 // by paying from Carol directly to Dave, because the '--unsafe-replay' 206 // setup doesn't apply to locally added htlcs. In that case, the 207 // mailbox, that is responsible for generating the replay, is bypassed. 208 fred := net.NewNode(t.t, "Fred", nil) 209 defer shutdownAndAssert(net, t, fred) 210 211 net.ConnectNodes(t.t, fred, carol) 212 net.SendCoins(t.t, dcrutil.AtomsPerCoin, fred) 213 214 chanPointFC := openChannelAndAssert( 215 t, net, fred, carol, 216 lntest.OpenChannelParams{ 217 Amt: chanAmt, 218 }, 219 ) 220 221 // Now that the channel is open, create an invoice for Dave which 222 // expects a payment of 1000 atoms from Carol paid via a particular 223 // preimage. 224 const paymentAmt = 1000 225 preimage := bytes.Repeat([]byte("A"), 32) 226 invoice := &lnrpc.Invoice{ 227 Memo: "testing", 228 RPreimage: preimage, 229 Value: paymentAmt, 230 } 231 ctxt, _ := context.WithTimeout(ctxb, defaultTimeout) 232 invoiceResp, err := dave.AddInvoice(ctxt, invoice) 233 if err != nil { 234 t.Fatalf("unable to add invoice: %v", err) 235 } 236 237 // Wait for all channels to be recognized and advertized. 238 err = carol.WaitForNetworkChannelOpen(chanPoint) 239 if err != nil { 240 t.Fatalf("alice didn't advertise channel before "+ 241 "timeout: %v", err) 242 } 243 err = dave.WaitForNetworkChannelOpen(chanPoint) 244 if err != nil { 245 t.Fatalf("bob didn't advertise channel before "+ 246 "timeout: %v", err) 247 } 248 err = carol.WaitForNetworkChannelOpen(chanPointFC) 249 if err != nil { 250 t.Fatalf("alice didn't advertise channel before "+ 251 "timeout: %v", err) 252 } 253 err = fred.WaitForNetworkChannelOpen(chanPointFC) 254 if err != nil { 255 t.Fatalf("bob didn't advertise channel before "+ 256 "timeout: %v", err) 257 } 258 259 // With the invoice for Dave added, send a payment from Fred paying 260 // to the above generated invoice. 261 ctx, cancel := context.WithCancel(ctxb) 262 defer cancel() 263 264 payStream, err := fred.RouterClient.SendPaymentV2( 265 ctx, 266 &routerrpc.SendPaymentRequest{ 267 PaymentRequest: invoiceResp.PaymentRequest, 268 TimeoutSeconds: 60, 269 FeeLimitMAtoms: noFeeLimitMAtoms, 270 }, 271 ) 272 if err != nil { 273 t.Fatalf("unable to open payment stream: %v", err) 274 } 275 276 time.Sleep(200 * time.Millisecond) 277 278 // Dave's invoice should not be marked as settled. 279 payHash := &lnrpc.PaymentHash{ 280 RHash: invoiceResp.RHash, 281 } 282 ctxt, _ = context.WithTimeout(ctxb, defaultTimeout) 283 dbInvoice, err := dave.LookupInvoice(ctxt, payHash) 284 if err != nil { 285 t.Fatalf("unable to lookup invoice: %v", err) 286 } 287 if dbInvoice.Settled { // nolint:staticcheck 288 t.Fatalf("dave's invoice should not be marked as settled: %v", 289 spew.Sdump(dbInvoice)) 290 } 291 292 // With the payment sent but hedl, all balance related stats should not 293 // have changed. 294 err = wait.InvariantNoError( 295 assertAmountSent(0, carol, dave), 3*time.Second, 296 ) 297 if err != nil { 298 t.Fatalf(err.Error()) 299 } 300 301 // With the first payment sent, restart dave to make sure he is 302 // persisting the information required to detect replayed sphinx 303 // packets. 304 if err := net.RestartNode(dave, nil); err != nil { 305 t.Fatalf("unable to restart dave: %v", err) 306 } 307 308 // Carol should retransmit the Add hedl in her mailbox on startup. Dave 309 // should not accept the replayed Add, and actually fail back the 310 // pending payment. Even though he still holds the original settle, if 311 // he does fail, it is almost certainly caused by the sphinx replay 312 // protection, as it is the only validation we do in hodl mode. 313 result, err := getPaymentResult(payStream) 314 if err != nil { 315 t.Fatalf("unable to receive payment response: %v", err) 316 } 317 318 // Assert that Fred receives the expected failure after Carol sent a 319 // duplicate packet that fails due to sphinx replay detection. 320 if result.Status == lnrpc.Payment_SUCCEEDED { 321 t.Fatalf("expected payment error") 322 } 323 assertLastHTLCError(t, fred, lnrpc.Failure_INVALID_ONION_KEY) 324 325 // Since the payment failed, the balance should still be left 326 // unaltered. 327 err = wait.InvariantNoError( 328 assertAmountSent(0, carol, dave), 3*time.Second, 329 ) 330 if err != nil { 331 t.Fatalf(err.Error()) 332 } 333 334 closeChannelAndAssert(t, net, carol, chanPoint, true) 335 336 // Cleanup by mining the force close and sweep transaction. 337 cleanupForceClose(t, net, carol, chanPoint) 338 } 339 340 // testListChannels checks that the response from ListChannels is correct. It 341 // tests the values in all ChannelConstraints are returned as expected. Once 342 // ListChannels becomes mature, a test against all fields in ListChannels should 343 // be performed. 344 func testListChannels(net *lntest.NetworkHarness, t *harnessTest) { 345 ctxb := context.Background() 346 347 const aliceRemoteMaxHtlcs = 50 348 const bobRemoteMaxHtlcs = 100 349 350 // Create two fresh nodes and open a channel between them. 351 alice := net.NewNode(t.t, "Alice", nil) 352 defer shutdownAndAssert(net, t, alice) 353 354 bob := net.NewNode( 355 t.t, "Bob", []string{ 356 fmt.Sprintf( 357 "--default-remote-max-htlcs=%v", 358 bobRemoteMaxHtlcs, 359 ), 360 }, 361 ) 362 defer shutdownAndAssert(net, t, bob) 363 364 // Connect Alice to Bob. 365 net.ConnectNodes(t.t, alice, bob) 366 367 // Give Alice some coins so she can fund a channel. 368 net.SendCoins(t.t, dcrutil.AtomsPerCoin, alice) 369 370 // Open a channel with 100k satoshis between Alice and Bob with Alice 371 // being the sole funder of the channel. The minial HTLC amount is set to 372 // 4200 msats. 373 const customizedMinHtlc = 4200 374 375 chanAmt := dcrutil.Amount(100000) 376 chanPoint := openChannelAndAssert( 377 t, net, alice, bob, 378 lntest.OpenChannelParams{ 379 Amt: chanAmt, 380 MinHtlc: customizedMinHtlc, 381 RemoteMaxHtlcs: aliceRemoteMaxHtlcs, 382 }, 383 ) 384 385 // Wait for Alice and Bob to receive the channel edge from the 386 // funding manager. 387 err := alice.WaitForNetworkChannelOpen(chanPoint) 388 if err != nil { 389 t.Fatalf("alice didn't see the alice->bob channel before "+ 390 "timeout: %v", err) 391 } 392 393 err = bob.WaitForNetworkChannelOpen(chanPoint) 394 if err != nil { 395 t.Fatalf("bob didn't see the bob->alice channel before "+ 396 "timeout: %v", err) 397 } 398 399 // Alice should have one channel opened with Bob. 400 assertNodeNumChannels(t, alice, 1) 401 // Bob should have one channel opened with Alice. 402 assertNodeNumChannels(t, bob, 1) 403 404 // Get the ListChannel response from Alice. 405 listReq := &lnrpc.ListChannelsRequest{} 406 ctxt, _ := context.WithTimeout(ctxb, defaultTimeout) 407 resp, err := alice.ListChannels(ctxt, listReq) 408 if err != nil { 409 t.Fatalf("unable to query for %s's channel list: %v", 410 alice.Name(), err) 411 } 412 413 // Check the returned response is correct. 414 aliceChannel := resp.Channels[0] 415 416 // Calculate the dust limit we'll use for the test. 417 dustLimit := lnwallet.DustLimitForSize(input.P2PKHPkScriptSize) 418 419 // defaultConstraints is a ChannelConstraints with default values. It is 420 // used to test against Alice's local channel constraints. 421 defaultConstraints := &lnrpc.ChannelConstraints{ 422 CsvDelay: 4, 423 ChanReserveAtoms: 6030, 424 DustLimitAtoms: uint64(dustLimit), 425 MaxPendingAmtMAtoms: 99000000, 426 MinHtlcMAtoms: 1000, 427 MaxAcceptedHtlcs: bobRemoteMaxHtlcs, 428 } 429 assertChannelConstraintsEqual( 430 t, defaultConstraints, aliceChannel.LocalConstraints, 431 ) 432 433 // customizedConstraints is a ChannelConstraints with customized values. 434 // Ideally, all these values can be passed in when creating the channel. 435 // Currently, only the MinHtlcMAtoms is customized. It is used to check 436 // against Alice's remote channel constratins. 437 customizedConstraints := &lnrpc.ChannelConstraints{ 438 CsvDelay: 4, 439 ChanReserveAtoms: 6030, 440 DustLimitAtoms: uint64(dustLimit), 441 MaxPendingAmtMAtoms: 99000000, 442 MinHtlcMAtoms: customizedMinHtlc, 443 MaxAcceptedHtlcs: aliceRemoteMaxHtlcs, 444 } 445 assertChannelConstraintsEqual( 446 t, customizedConstraints, aliceChannel.RemoteConstraints, 447 ) 448 449 // Get the ListChannel response for Bob. 450 listReq = &lnrpc.ListChannelsRequest{} 451 ctxb = context.Background() 452 ctxt, _ = context.WithTimeout(ctxb, defaultTimeout) 453 resp, err = bob.ListChannels(ctxt, listReq) 454 if err != nil { 455 t.Fatalf("unable to query for %s's channel "+ 456 "list: %v", bob.Name(), err) 457 } 458 459 bobChannel := resp.Channels[0] 460 if bobChannel.ChannelPoint != aliceChannel.ChannelPoint { 461 t.Fatalf("Bob's channel point mismatched, want: %s, got: %s", 462 chanPoint.String(), bobChannel.ChannelPoint, 463 ) 464 } 465 466 // Check channel constraints match. Alice's local channel constraint should 467 // be equal to Bob's remote channel constraint, and her remote one should 468 // be equal to Bob's local one. 469 assertChannelConstraintsEqual( 470 t, aliceChannel.LocalConstraints, bobChannel.RemoteConstraints, 471 ) 472 assertChannelConstraintsEqual( 473 t, aliceChannel.RemoteConstraints, bobChannel.LocalConstraints, 474 ) 475 476 } 477 478 // testMaxPendingChannels checks that error is returned from remote peer if 479 // max pending channel number was exceeded and that '--maxpendingchannels' flag 480 // exists and works properly. 481 func testMaxPendingChannels(net *lntest.NetworkHarness, t *harnessTest) { 482 maxPendingChannels := lncfg.DefaultMaxPendingChannels + 1 483 amount := defaultChanAmt 484 485 // Create a new node (Carol) with greater number of max pending 486 // channels. 487 args := []string{ 488 fmt.Sprintf("--maxpendingchannels=%v", maxPendingChannels), 489 } 490 carol := net.NewNode(t.t, "Carol", args) 491 defer shutdownAndAssert(net, t, carol) 492 493 net.ConnectNodes(t.t, net.Alice, carol) 494 495 carolBalance := dcrutil.Amount(maxPendingChannels) * amount 496 net.SendCoins(t.t, carolBalance, carol) 497 498 // Send open channel requests without generating new blocks thereby 499 // increasing pool of pending channels. Then check that we can't open 500 // the channel if the number of pending channels exceed max value. 501 openStreams := make([]lnrpc.Lightning_OpenChannelClient, maxPendingChannels) 502 for i := 0; i < maxPendingChannels; i++ { 503 stream := openChannelStream( 504 t, net, net.Alice, carol, 505 lntest.OpenChannelParams{ 506 Amt: amount, 507 }, 508 ) 509 openStreams[i] = stream 510 } 511 512 // Carol exhausted available amount of pending channels, next open 513 // channel request should cause ErrorGeneric to be sent back to Alice. 514 _, err := net.OpenChannel( 515 net.Alice, carol, lntest.OpenChannelParams{ 516 Amt: amount, 517 }, 518 ) 519 520 if err == nil { 521 t.Fatalf("error wasn't received") 522 } else if !strings.Contains( 523 err.Error(), lnwire.ErrMaxPendingChannels.Error(), 524 ) { 525 t.Fatalf("not expected error was received: %v", err) 526 } 527 528 // For now our channels are in pending state, in order to not interfere 529 // with other tests we should clean up - complete opening of the 530 // channel and then close it. 531 532 // Mine 6 blocks, then wait for node's to notify us that the channel has 533 // been opened. The funding transactions should be found within the 534 // first newly mined block. 6 blocks make sure the funding transaction 535 // has enough confirmations to be announced publicly. 536 block := mineBlocks(t, net, 6, maxPendingChannels)[0] 537 538 chanPoints := make([]*lnrpc.ChannelPoint, maxPendingChannels) 539 for i, stream := range openStreams { 540 fundingChanPoint, err := net.WaitForChannelOpen(stream) 541 if err != nil { 542 t.Fatalf("error while waiting for channel open: %v", err) 543 } 544 545 fundingTxID, err := lnrpc.GetChanPointFundingTxid(fundingChanPoint) 546 if err != nil { 547 t.Fatalf("unable to get txid: %v", err) 548 } 549 550 // Ensure that the funding transaction enters a block, and is 551 // properly advertised by Alice. 552 assertTxInBlock(t, block, fundingTxID) 553 err = net.Alice.WaitForNetworkChannelOpen(fundingChanPoint) 554 if err != nil { 555 t.Fatalf("channel not seen on network before "+ 556 "timeout: %v", err) 557 } 558 559 // The channel should be listed in the peer information 560 // returned by both peers. 561 chanPoint := wire.OutPoint{ 562 Hash: *fundingTxID, 563 Index: fundingChanPoint.OutputIndex, 564 } 565 err = net.AssertChannelExists(net.Alice, &chanPoint) 566 require.NoError(t.t, err, "unable to assert channel existence") 567 568 chanPoints[i] = fundingChanPoint 569 } 570 571 // Next, close the channel between Alice and Carol, asserting that the 572 // channel has been properly closed on-chain. 573 for _, chanPoint := range chanPoints { 574 closeChannelAndAssert(t, net, net.Alice, chanPoint, false) 575 } 576 } 577 578 // testGarbageCollectLinkNodes tests that we properly garbage collect link nodes 579 // from the database and the set of persistent connections within the server. 580 func testGarbageCollectLinkNodes(net *lntest.NetworkHarness, t *harnessTest) { 581 ctxb := context.Background() 582 583 const ( 584 chanAmt = 1000000 585 ) 586 587 // Open a channel between Alice and Bob which will later be 588 // cooperatively closed. 589 coopChanPoint := openChannelAndAssert( 590 t, net, net.Alice, net.Bob, lntest.OpenChannelParams{ 591 Amt: chanAmt, 592 }, 593 ) 594 595 // Create Carol's node and connect Alice to her. 596 carol := net.NewNode(t.t, "Carol", nil) 597 defer shutdownAndAssert(net, t, carol) 598 net.ConnectNodes(t.t, net.Alice, carol) 599 600 // Open a channel between Alice and Carol which will later be force 601 // closed. 602 forceCloseChanPoint := openChannelAndAssert( 603 t, net, net.Alice, carol, lntest.OpenChannelParams{ 604 Amt: chanAmt, 605 }, 606 ) 607 608 // Now, create Dave's a node and also open a channel between Alice and 609 // him. This link will serve as the only persistent link throughout 610 // restarts in this test. 611 dave := net.NewNode(t.t, "Dave", nil) 612 defer shutdownAndAssert(net, t, dave) 613 614 net.ConnectNodes(t.t, net.Alice, dave) 615 persistentChanPoint := openChannelAndAssert( 616 t, net, net.Alice, dave, lntest.OpenChannelParams{ 617 Amt: chanAmt, 618 }, 619 ) 620 621 // isConnected is a helper closure that checks if a peer is connected to 622 // Alice. 623 isConnected := func(pubKey string) bool { 624 req := &lnrpc.ListPeersRequest{} 625 ctxt, _ := context.WithTimeout(ctxb, defaultTimeout) 626 resp, err := net.Alice.ListPeers(ctxt, req) 627 if err != nil { 628 t.Fatalf("unable to retrieve alice's peers: %v", err) 629 } 630 631 for _, peer := range resp.Peers { 632 if peer.PubKey == pubKey { 633 return true 634 } 635 } 636 637 return false 638 } 639 640 // Ensure there's enough time after opening the channel for all nodes 641 // to process it before shutting them down, otherwise we might deadlock 642 // waiting for the chain to shut down. 643 // 644 // See https://github.com/decred/dcrlnd/issues/97 645 time.Sleep(time.Second) 646 647 // Restart both Bob and Carol to ensure Alice is able to reconnect to 648 // them. 649 if err := net.RestartNode(net.Bob, nil); err != nil { 650 t.Fatalf("unable to restart bob's node: %v", err) 651 } 652 if err := net.RestartNode(carol, nil); err != nil { 653 t.Fatalf("unable to restart carol's node: %v", err) 654 } 655 656 require.Eventually(t.t, func() bool { 657 return isConnected(net.Bob.PubKeyStr) 658 }, defaultTimeout, 20*time.Millisecond) 659 require.Eventually(t.t, func() bool { 660 return isConnected(carol.PubKeyStr) 661 }, defaultTimeout, 20*time.Millisecond) 662 663 // We'll also restart Alice to ensure she can reconnect to her peers 664 // with open channels. 665 if err := net.RestartNode(net.Alice, nil); err != nil { 666 t.Fatalf("unable to restart alice's node: %v", err) 667 } 668 669 require.Eventually(t.t, func() bool { 670 return isConnected(net.Bob.PubKeyStr) 671 }, defaultTimeout, 20*time.Millisecond) 672 require.Eventually(t.t, func() bool { 673 return isConnected(carol.PubKeyStr) 674 }, defaultTimeout, 20*time.Millisecond) 675 require.Eventually(t.t, func() bool { 676 return isConnected(dave.PubKeyStr) 677 }, defaultTimeout, 20*time.Millisecond) 678 err := wait.Predicate(func() bool { 679 return isConnected(dave.PubKeyStr) 680 }, defaultTimeout) 681 682 // testReconnection is a helper closure that restarts the nodes at both 683 // ends of a channel to ensure they do not reconnect after restarting. 684 // When restarting Alice, we'll first need to ensure she has 685 // reestablished her connection with Dave, as they still have an open 686 // channel together. 687 testReconnection := func(node *lntest.HarnessNode) { 688 // Restart both nodes, to trigger the pruning logic. 689 if err := net.RestartNode(node, nil); err != nil { 690 t.Fatalf("unable to restart %v's node: %v", 691 node.Name(), err) 692 } 693 694 if err := net.RestartNode(net.Alice, nil); err != nil { 695 t.Fatalf("unable to restart alice's node: %v", err) 696 } 697 698 // Now restart both nodes and make sure they don't reconnect. 699 if err := net.RestartNode(node, nil); err != nil { 700 t.Fatalf("unable to restart %v's node: %v", node.Name(), 701 err) 702 } 703 err = wait.Invariant(func() bool { 704 return !isConnected(node.PubKeyStr) 705 }, 5*time.Second) 706 if err != nil { 707 t.Fatalf("alice reconnected to %v", node.Name()) 708 } 709 710 if err := net.RestartNode(net.Alice, nil); err != nil { 711 t.Fatalf("unable to restart alice's node: %v", err) 712 } 713 err = wait.Predicate(func() bool { 714 return isConnected(dave.PubKeyStr) 715 }, defaultTimeout) 716 if err != nil { 717 t.Fatalf("alice didn't reconnect to Dave") 718 } 719 720 err = wait.Invariant(func() bool { 721 return !isConnected(node.PubKeyStr) 722 }, 5*time.Second) 723 if err != nil { 724 t.Fatalf("alice reconnected to %v", node.Name()) 725 } 726 } 727 728 // Now, we'll close the channel between Alice and Bob and ensure there 729 // is no reconnection logic between the both once the channel is fully 730 // closed. 731 closeChannelAndAssert(t, net, net.Alice, coopChanPoint, false) 732 733 testReconnection(net.Bob) 734 735 // We'll do the same with Alice and Carol, but this time we'll force 736 // close the channel instead. 737 closeChannelAndAssert(t, net, net.Alice, forceCloseChanPoint, true) 738 739 // Cleanup by mining the force close and sweep transaction. 740 cleanupForceClose(t, net, net.Alice, forceCloseChanPoint) 741 742 // We'll need to mine some blocks in order to mark the channel fully 743 // closed. 744 _, err = net.Generate(chainreg.DefaultDecredTimeLockDelta - defaultCSV) 745 if err != nil { 746 t.Fatalf("unable to generate blocks: %v", err) 747 } 748 749 // Before we test reconnection, we'll ensure that the channel has been 750 // fully cleaned up for both Carol and Alice. 751 var predErr error 752 pendingChansRequest := &lnrpc.PendingChannelsRequest{} 753 err = wait.Predicate(func() bool { 754 ctxt, _ := context.WithTimeout(ctxb, defaultTimeout) 755 pendingChanResp, err := net.Alice.PendingChannels( 756 ctxt, pendingChansRequest, 757 ) 758 if err != nil { 759 predErr = fmt.Errorf("unable to query for pending "+ 760 "channels: %v", err) 761 return false 762 } 763 764 predErr = checkNumForceClosedChannels(pendingChanResp, 0) 765 if predErr != nil { 766 return false 767 } 768 769 ctxt, _ = context.WithTimeout(ctxb, defaultTimeout) 770 pendingChanResp, err = carol.PendingChannels( 771 ctxt, pendingChansRequest, 772 ) 773 if err != nil { 774 predErr = fmt.Errorf("unable to query for pending "+ 775 "channels: %v", err) 776 return false 777 } 778 779 predErr = checkNumForceClosedChannels(pendingChanResp, 0) 780 return predErr == nil 781 }, defaultTimeout) 782 if err != nil { 783 t.Fatalf("channels not marked as fully resolved: %v", predErr) 784 } 785 786 testReconnection(carol) 787 788 // Finally, we'll ensure that Bob and Carol no longer show in Alice's 789 // channel graph. 790 describeGraphReq := &lnrpc.ChannelGraphRequest{ 791 IncludeUnannounced: true, 792 } 793 ctxt, _ := context.WithTimeout(ctxb, defaultTimeout) 794 channelGraph, err := net.Alice.DescribeGraph(ctxt, describeGraphReq) 795 if err != nil { 796 t.Fatalf("unable to query for alice's channel graph: %v", err) 797 } 798 for _, node := range channelGraph.Nodes { 799 if node.PubKey == net.Bob.PubKeyStr { 800 t.Logf("Full channel graph: %s", spew.Sdump(channelGraph)) 801 t.Fatalf("did not expect to find bob in the channel " + 802 "graph, but did") 803 } 804 if node.PubKey == carol.PubKeyStr { 805 t.Logf("Full channel graph: %s", spew.Sdump(channelGraph)) 806 t.Fatalf("did not expect to find carol in the channel " + 807 "graph, but did") 808 } 809 } 810 811 // Now that the test is done, we can also close the persistent link. 812 closeChannelAndAssert(t, net, net.Alice, persistentChanPoint, false) 813 } 814 815 // testDataLossProtection tests that if one of the nodes in a channel 816 // relationship lost state, they will detect this during channel sync, and the 817 // up-to-date party will force close the channel, giving the outdated party the 818 // opportunity to sweep its output. 819 func testDataLossProtection(net *lntest.NetworkHarness, t *harnessTest) { 820 ctxb := context.Background() 821 const ( 822 chanAmt = defaultChanAmt 823 paymentAmt = 10000 824 numInvoices = 6 825 ) 826 827 // Carol will be the up-to-date party. We set --nolisten to ensure Dave 828 // won't be able to connect to her and trigger the channel data 829 // protection logic automatically. We also can't have Carol 830 // automatically re-connect too early, otherwise DLP would be initiated 831 // at the wrong moment. 832 carol := net.NewNode( 833 t.t, "Carol", []string{"--nolisten", "--minbackoff=1h"}, 834 ) 835 defer shutdownAndAssert(net, t, carol) 836 837 // Dave will be the party losing his state. 838 dave := net.NewNode(t.t, "Dave", nil) 839 defer shutdownAndAssert(net, t, dave) 840 841 // Before we make a channel, we'll load up Carol with some coins sent 842 // directly from the miner. 843 net.SendCoins(t.t, dcrutil.AtomsPerCoin, carol) 844 845 // timeTravel is a method that will make Carol open a channel to the 846 // passed node, settle a series of payments, then reset the node back 847 // to the state before the payments happened. When this method returns 848 // the node will be unaware of the new state updates. The returned 849 // function can be used to restart the node in this state. 850 timeTravel := func(node *lntest.HarnessNode) (func() error, 851 *lnrpc.ChannelPoint, int64, error) { 852 853 // We must let the node communicate with Carol before they are 854 // able to open channel, so we connect them. 855 net.EnsureConnected(t.t, carol, node) 856 857 // We'll first open up a channel between them with a 0.5 DCR 858 // value. 859 chanPoint := openChannelAndAssert( 860 t, net, carol, node, 861 lntest.OpenChannelParams{ 862 Amt: chanAmt, 863 }, 864 ) 865 866 // With the channel open, we'll create a few invoices for the 867 // node that Carol will pay to in order to advance the state of 868 // the channel. 869 // TODO(halseth): have dangling HTLCs on the commitment, able to 870 // retrieve funds? 871 payReqs, _, _, err := createPayReqs( 872 node, paymentAmt, numInvoices, 873 ) 874 if err != nil { 875 t.Fatalf("unable to create pay reqs: %v", err) 876 } 877 878 // Wait for Carol to receive the channel edge from the funding 879 // manager. 880 err = carol.WaitForNetworkChannelOpen(chanPoint) 881 if err != nil { 882 t.Fatalf("carol didn't see the carol->%s channel "+ 883 "before timeout: %v", node.Name(), err) 884 } 885 886 // Send payments from Carol using 3 of the payment hashes 887 // generated above. 888 err = completePaymentRequests( 889 carol, carol.RouterClient, 890 payReqs[:numInvoices/2], true, 891 ) 892 if err != nil { 893 t.Fatalf("unable to send payments: %v", err) 894 } 895 896 // Next query for the node's channel state, as we sent 3 897 // payments of 10k atoms each, it should now see his balance 898 // as being 30k atoms. 899 var nodeChan *lnrpc.Channel 900 var predErr error 901 err = wait.Predicate(func() bool { 902 bChan, err := getChanInfo(node) 903 if err != nil { 904 t.Fatalf("unable to get channel info: %v", err) 905 } 906 if bChan.LocalBalance != 30000 { 907 predErr = fmt.Errorf("balance is incorrect, "+ 908 "got %v, expected %v", 909 bChan.LocalBalance, 30000) 910 return false 911 } 912 913 nodeChan = bChan 914 return true 915 }, defaultTimeout) 916 if err != nil { 917 t.Fatalf("%v", predErr) 918 } 919 920 // Grab the current commitment height (update number), we'll 921 // later revert him to this state after additional updates to 922 // revoke this state. 923 stateNumPreCopy := nodeChan.NumUpdates 924 925 // With the temporary file created, copy the current state into 926 // the temporary file we created above. Later after more 927 // updates, we'll restore this state. 928 if err := net.BackupDb(node); err != nil { 929 t.Fatalf("unable to copy database files: %v", err) 930 } 931 932 // Reconnect the peers after the restart that was needed for the db 933 // backup. 934 net.EnsureConnected(t.t, carol, node) 935 936 // Finally, send more payments from , using the remaining 937 // payment hashes. 938 err = completePaymentRequests( 939 carol, carol.RouterClient, payReqs[numInvoices/2:], true, 940 ) 941 if err != nil { 942 t.Fatalf("unable to send payments: %v", err) 943 } 944 945 // Ensure all HTLCs have been finalized so that the most recent 946 // commitment doesn't have any. 947 err = wait.NoError(func() error { 948 return assertNumActiveHtlcs([]*lntest.HarnessNode{node, carol}, 0) 949 }, defaultTimeout) 950 if err != nil { 951 t.Fatalf("nodes still show active htcls: %v", err) 952 } 953 954 nodeChan, err = getChanInfo(node) 955 if err != nil { 956 t.Fatalf("unable to get dave chan info: %v", err) 957 } 958 959 // Disconnect the nodes, to prevent Carol attempting to reconnect 960 // and restore the node state. 961 err = net.DisconnectNodes(carol, node) 962 if err != nil { 963 t.Fatalf("unable to disconnect carol and dave: %v", err) 964 } 965 966 // Now we shutdown the node, copying over the its temporary 967 // database state which has the *prior* channel state over his 968 // current most up to date state. With this, we essentially 969 // force the node to travel back in time within the channel's 970 // history. 971 if err = net.RestartNode(node, func() error { 972 return net.RestoreDb(node) 973 }); err != nil { 974 t.Fatalf("unable to restart node: %v", err) 975 } 976 977 // Make sure the channel is still there from the PoV of the 978 // node. 979 assertNodeNumChannels(t, node, 1) 980 981 // Now query for the channel state, it should show that it's at 982 // a state number in the past, not the *latest* state. 983 nodeChan, err = getChanInfo(node) 984 if err != nil { 985 t.Fatalf("unable to get dave chan info: %v", err) 986 } 987 if nodeChan.NumUpdates != stateNumPreCopy { 988 t.Fatalf("db copy failed: %v", nodeChan.NumUpdates) 989 } 990 991 balReq := &lnrpc.WalletBalanceRequest{} 992 ctxt, _ := context.WithTimeout(ctxb, defaultTimeout) 993 balResp, err := node.WalletBalance(ctxt, balReq) 994 if err != nil { 995 t.Fatalf("unable to get dave's balance: %v", err) 996 } 997 998 restartNode, err := net.SuspendNode(node) 999 if err != nil { 1000 t.Fatalf("unable to suspend node: %v", err) 1001 } 1002 1003 restart := func() error { 1004 err := restartNode() 1005 if err != nil { 1006 return err 1007 } 1008 1009 // Reconnect carol to the node. 1010 net.ConnectNodes(t.t, carol, node) 1011 1012 return nil 1013 } 1014 1015 return restart, chanPoint, balResp.ConfirmedBalance, nil 1016 } 1017 1018 // Reset Dave to a state where he has an outdated channel state. 1019 restartDave, _, daveStartingBalance, err := timeTravel(dave) 1020 if err != nil { 1021 t.Fatalf("unable to time travel dave: %v", err) 1022 } 1023 1024 // We make a note of the nodes' current on-chain balances, to make sure 1025 // they are able to retrieve the channel funds eventually, 1026 balReq := &lnrpc.WalletBalanceRequest{} 1027 ctxt, _ := context.WithTimeout(ctxb, defaultTimeout) 1028 carolBalResp, err := carol.WalletBalance(ctxt, balReq) 1029 if err != nil { 1030 t.Fatalf("unable to get carol's balance: %v", err) 1031 } 1032 carolStartingBalance := carolBalResp.ConfirmedBalance 1033 1034 // Restart Dave to trigger a channel resync. 1035 if err := restartDave(); err != nil { 1036 t.Fatalf("unable to restart dave: %v", err) 1037 } 1038 1039 // Assert that once Dave comes up, they reconnect, Carol force closes 1040 // on chain, and both of them properly carry out the DLP protocol. 1041 assertDLPExecuted( 1042 net, t, carol, carolStartingBalance, dave, daveStartingBalance, 1043 lnrpc.CommitmentType_STATIC_REMOTE_KEY, 1044 ) 1045 1046 // As a second part of this test, we will test the scenario where a 1047 // channel is closed while Dave is offline, loses his state and comes 1048 // back online. In this case the node should attempt to resync the 1049 // channel, and the peer should resend a channel sync message for the 1050 // closed channel, such that Dave can retrieve his funds. 1051 // 1052 // We start by letting Dave time travel back to an outdated state. 1053 restartDave, chanPoint2, daveStartingBalance, err := timeTravel(dave) 1054 if err != nil { 1055 t.Fatalf("unable to time travel eve: %v", err) 1056 } 1057 1058 ctxt, _ = context.WithTimeout(ctxb, defaultTimeout) 1059 carolBalResp, err = carol.WalletBalance(ctxt, balReq) 1060 if err != nil { 1061 t.Fatalf("unable to get carol's balance: %v", err) 1062 } 1063 carolStartingBalance = carolBalResp.ConfirmedBalance 1064 1065 // Now let Carol force close the channel while Dave is offline. 1066 closeChannelAndAssert(t, net, carol, chanPoint2, true) 1067 1068 // Wait for the channel to be marked pending force close. 1069 err = waitForChannelPendingForceClose(carol, chanPoint2) 1070 if err != nil { 1071 t.Fatalf("channel not pending force close: %v", err) 1072 } 1073 1074 // Mine enough blocks for Carol to sweep her funds. 1075 mineBlocks(t, net, defaultCSV-1, 0) 1076 1077 carolSweep, err := waitForTxInMempool(net.Miner.Node, minerMempoolTimeout) 1078 if err != nil { 1079 t.Fatalf("unable to find Carol's sweep tx in mempool: %v", err) 1080 } 1081 block := mineBlocks(t, net, 1, 1)[0] 1082 assertTxInBlock(t, block, carolSweep) 1083 1084 // Now the channel should be fully closed also from Carol's POV. 1085 assertNumPendingChannels(t, carol, 0, 0, 0, 0) 1086 1087 // Make sure Carol got her balance back. 1088 ctxt, _ = context.WithTimeout(ctxb, defaultTimeout) 1089 carolBalResp, err = carol.WalletBalance(ctxt, balReq) 1090 if err != nil { 1091 t.Fatalf("unable to get carol's balance: %v", err) 1092 } 1093 carolBalance := carolBalResp.ConfirmedBalance 1094 if carolBalance <= carolStartingBalance { 1095 t.Fatalf("expected carol to have balance above %d, "+ 1096 "instead had %v", carolStartingBalance, 1097 carolBalance) 1098 } 1099 1100 assertNodeNumChannels(t, carol, 0) 1101 1102 // When Dave comes online, he will reconnect to Carol, try to resync 1103 // the channel, but it will already be closed. Carol should resend the 1104 // information Dave needs to sweep his funds. 1105 if err := restartDave(); err != nil { 1106 t.Fatalf("unable to restart Eve: %v", err) 1107 } 1108 1109 // Dave should sweep his funds. 1110 _, err = waitForTxInMempool(net.Miner.Node, minerMempoolTimeout) 1111 if err != nil { 1112 t.Fatalf("unable to find Dave's sweep tx in mempool: %v", err) 1113 } 1114 1115 // Mine a block to confirm the sweep, and make sure Dave got his 1116 // balance back. 1117 mineBlocks(t, net, 1, 1) 1118 assertNodeNumChannels(t, dave, 0) 1119 1120 err = wait.NoError(func() error { 1121 ctxt, _ = context.WithTimeout(ctxb, defaultTimeout) 1122 daveBalResp, err := dave.WalletBalance(ctxt, balReq) 1123 if err != nil { 1124 return fmt.Errorf("unable to get dave's balance: %v", 1125 err) 1126 } 1127 1128 daveBalance := daveBalResp.ConfirmedBalance 1129 if daveBalance <= daveStartingBalance { 1130 return fmt.Errorf("expected dave to have balance "+ 1131 "above %d, intead had %v", daveStartingBalance, 1132 daveBalance) 1133 } 1134 1135 return nil 1136 }, defaultTimeout) 1137 if err != nil { 1138 t.Fatalf("%v", err) 1139 } 1140 } 1141 1142 // testRejectHTLC tests that a node can be created with the flag --rejecthtlc. 1143 // This means that the node will reject all forwarded HTLCs but can still 1144 // accept direct HTLCs as well as send HTLCs. 1145 func testRejectHTLC(net *lntest.NetworkHarness, t *harnessTest) { 1146 // RejectHTLC 1147 // Alice ------> Carol ------> Bob 1148 // 1149 const chanAmt = dcrutil.Amount(1000000) 1150 ctxb := context.Background() 1151 1152 // Create Carol with reject htlc flag. 1153 carol := net.NewNode(t.t, "Carol", []string{"--rejecthtlc"}) 1154 defer shutdownAndAssert(net, t, carol) 1155 1156 // Connect Alice to Carol. 1157 net.ConnectNodes(t.t, net.Alice, carol) 1158 1159 // Connect Carol to Bob. 1160 net.ConnectNodes(t.t, carol, net.Bob) 1161 1162 // Send coins to Carol. 1163 net.SendCoins(t.t, dcrutil.AtomsPerCoin, carol) 1164 1165 // Send coins to Alice. 1166 net.SendCoins(t.t, dcrutil.AtomsPerCoin, net.Alice) 1167 1168 // Open a channel between Alice and Carol. 1169 chanPointAlice := openChannelAndAssert( 1170 t, net, net.Alice, carol, 1171 lntest.OpenChannelParams{ 1172 Amt: chanAmt, 1173 }, 1174 ) 1175 1176 // Open a channel between Carol and Bob. 1177 chanPointCarol := openChannelAndAssert( 1178 t, net, carol, net.Bob, 1179 lntest.OpenChannelParams{ 1180 Amt: chanAmt, 1181 }, 1182 ) 1183 1184 // Channel should be ready for payments. 1185 const payAmt = 100 1186 1187 // Helper closure to generate a random pre image. 1188 genPreImage := func() []byte { 1189 preimage := make([]byte, 32) 1190 1191 _, err := rand.Read(preimage) 1192 if err != nil { 1193 t.Fatalf("unable to generate preimage: %v", err) 1194 } 1195 1196 return preimage 1197 } 1198 1199 // Create an invoice from Carol of 100 satoshis. 1200 // We expect Alice to be able to pay this invoice. 1201 preimage := genPreImage() 1202 1203 carolInvoice := &lnrpc.Invoice{ 1204 Memo: "testing - alice should pay carol", 1205 RPreimage: preimage, 1206 Value: payAmt, 1207 } 1208 1209 // Carol adds the invoice to her database. 1210 resp, err := carol.AddInvoice(ctxb, carolInvoice) 1211 if err != nil { 1212 t.Fatalf("unable to add invoice: %v", err) 1213 } 1214 1215 // Alice pays Carols invoice. 1216 err = completePaymentRequests( 1217 net.Alice, net.Alice.RouterClient, 1218 []string{resp.PaymentRequest}, true, 1219 ) 1220 if err != nil { 1221 t.Fatalf("unable to send payments from alice to carol: %v", err) 1222 } 1223 1224 // Create an invoice from Bob of 100 satoshis. 1225 // We expect Carol to be able to pay this invoice. 1226 preimage = genPreImage() 1227 1228 bobInvoice := &lnrpc.Invoice{ 1229 Memo: "testing - carol should pay bob", 1230 RPreimage: preimage, 1231 Value: payAmt, 1232 } 1233 1234 // Bob adds the invoice to his database. 1235 resp, err = net.Bob.AddInvoice(ctxb, bobInvoice) 1236 if err != nil { 1237 t.Fatalf("unable to add invoice: %v", err) 1238 } 1239 1240 // Carol pays Bobs invoice. 1241 err = completePaymentRequests( 1242 carol, carol.RouterClient, 1243 []string{resp.PaymentRequest}, true, 1244 ) 1245 if err != nil { 1246 t.Fatalf("unable to send payments from carol to bob: %v", err) 1247 } 1248 1249 // Create an invoice from Bob of 100 satoshis. 1250 // Alice attempts to pay Bob but this should fail, since we are 1251 // using Carol as a hop and her node will reject onward HTLCs. 1252 preimage = genPreImage() 1253 1254 bobInvoice = &lnrpc.Invoice{ 1255 Memo: "testing - alice tries to pay bob", 1256 RPreimage: preimage, 1257 Value: payAmt, 1258 } 1259 1260 // Bob adds the invoice to his database. 1261 resp, err = net.Bob.AddInvoice(ctxb, bobInvoice) 1262 if err != nil { 1263 t.Fatalf("unable to add invoice: %v", err) 1264 } 1265 1266 // Alice attempts to pay Bobs invoice. This payment should be rejected since 1267 // we are using Carol as an intermediary hop, Carol is running lnd with 1268 // --rejecthtlc. 1269 err = completePaymentRequests( 1270 net.Alice, net.Alice.RouterClient, 1271 []string{resp.PaymentRequest}, true, 1272 ) 1273 if err == nil { 1274 t.Fatalf( 1275 "should have been rejected, carol will not accept forwarded htlcs", 1276 ) 1277 } 1278 1279 assertLastHTLCError(t, net.Alice, lnrpc.Failure_CHANNEL_DISABLED) 1280 1281 // Close all channels. 1282 closeChannelAndAssert(t, net, net.Alice, chanPointAlice, false) 1283 closeChannelAndAssert(t, net, carol, chanPointCarol, false) 1284 } 1285 1286 func testNodeSignVerify(net *lntest.NetworkHarness, t *harnessTest) { 1287 ctxb := context.Background() 1288 1289 chanAmt := defaultChanAmt 1290 pushAmt := dcrutil.Amount(100000) 1291 1292 // Create a channel between alice and bob. 1293 aliceBobCh := openChannelAndAssert( 1294 t, net, net.Alice, net.Bob, 1295 lntest.OpenChannelParams{ 1296 Amt: chanAmt, 1297 PushAmt: pushAmt, 1298 }, 1299 ) 1300 1301 aliceMsg := []byte("alice msg") 1302 1303 // alice signs "alice msg" and sends her signature to bob. 1304 sigReq := &lnrpc.SignMessageRequest{Msg: aliceMsg, SingleHash: true} 1305 ctxt, _ := context.WithTimeout(ctxb, defaultTimeout) 1306 sigResp, err := net.Alice.SignMessage(ctxt, sigReq) 1307 if err != nil { 1308 t.Fatalf("SignMessage rpc call failed: %v", err) 1309 } 1310 aliceSig := sigResp.Signature 1311 1312 // bob verifying alice's signature should succeed since alice and bob are 1313 // connected. 1314 verifyReq := &lnrpc.VerifyMessageRequest{Msg: aliceMsg, Signature: aliceSig} 1315 ctxt, _ = context.WithTimeout(ctxb, defaultTimeout) 1316 verifyResp, err := net.Bob.VerifyMessage(ctxt, verifyReq) 1317 if err != nil { 1318 t.Fatalf("VerifyMessage failed: %v", err) 1319 } 1320 if !verifyResp.Valid { 1321 t.Fatalf("alice's signature didn't validate") 1322 } 1323 if verifyResp.Pubkey != net.Alice.PubKeyStr { 1324 t.Fatalf("alice's signature doesn't contain alice's pubkey.") 1325 } 1326 1327 // carol is a new node that is unconnected to alice or bob. 1328 carol := net.NewNode(t.t, "Carol", nil) 1329 defer shutdownAndAssert(net, t, carol) 1330 1331 carolMsg := []byte("carol msg") 1332 1333 // carol signs "carol msg" and sends her signature to bob. 1334 sigReq = &lnrpc.SignMessageRequest{Msg: carolMsg, SingleHash: true} 1335 ctxt, _ = context.WithTimeout(ctxb, defaultTimeout) 1336 sigResp, err = carol.SignMessage(ctxt, sigReq) 1337 if err != nil { 1338 t.Fatalf("SignMessage rpc call failed: %v", err) 1339 } 1340 carolSig := sigResp.Signature 1341 1342 // bob verifying carol's signature should fail since they are not connected. 1343 verifyReq = &lnrpc.VerifyMessageRequest{Msg: carolMsg, Signature: carolSig} 1344 ctxt, _ = context.WithTimeout(ctxb, defaultTimeout) 1345 verifyResp, err = net.Bob.VerifyMessage(ctxt, verifyReq) 1346 if err != nil { 1347 t.Fatalf("VerifyMessage failed: %v", err) 1348 } 1349 if verifyResp.Valid { 1350 t.Fatalf("carol's signature should not be valid") 1351 } 1352 if verifyResp.Pubkey != carol.PubKeyStr { 1353 t.Fatalf("carol's signature doesn't contain her pubkey") 1354 } 1355 1356 // Close the channel between alice and bob. 1357 closeChannelAndAssert(t, net, net.Alice, aliceBobCh, false) 1358 } 1359 1360 // testAbandonChannel abandones a channel and asserts that it is no 1361 // longer open and not in one of the pending closure states. It also 1362 // verifies that the abandoned channel is reported as closed with close 1363 // type 'abandoned'. 1364 func testAbandonChannel(net *lntest.NetworkHarness, t *harnessTest) { 1365 ctxb := context.Background() 1366 1367 // First establish a channel between Alice and Bob. 1368 channelParam := lntest.OpenChannelParams{ 1369 Amt: defaultChanAmt, 1370 PushAmt: dcrutil.Amount(100000), 1371 } 1372 1373 chanPoint := openChannelAndAssert( 1374 t, net, net.Alice, net.Bob, channelParam, 1375 ) 1376 txid, err := lnrpc.GetChanPointFundingTxid(chanPoint) 1377 require.NoError(t.t, err, "alice bob get channel funding txid") 1378 chanPointStr := fmt.Sprintf("%v:%v", txid, chanPoint.OutputIndex) 1379 1380 // Wait for channel to be confirmed open. 1381 err = net.Alice.WaitForNetworkChannelOpen(chanPoint) 1382 require.NoError(t.t, err, "alice wait for network channel open") 1383 err = net.Bob.WaitForNetworkChannelOpen(chanPoint) 1384 require.NoError(t.t, err, "bob wait for network channel open") 1385 1386 // Now that the channel is open, we'll obtain its channel ID real quick 1387 // so we can use it to query the graph below. 1388 listReq := &lnrpc.ListChannelsRequest{} 1389 ctxt, _ := context.WithTimeout(ctxb, defaultTimeout) 1390 aliceChannelList, err := net.Alice.ListChannels(ctxt, listReq) 1391 require.NoError(t.t, err) 1392 var chanID uint64 1393 for _, channel := range aliceChannelList.Channels { 1394 if channel.ChannelPoint == chanPointStr { 1395 chanID = channel.ChanId 1396 } 1397 } 1398 1399 require.NotZero(t.t, chanID, "unable to find channel") 1400 1401 // To make sure the channel is removed from the backup file as well 1402 // when being abandoned, grab a backup snapshot so we can compare it 1403 // with the later state. 1404 bkupBefore, err := ioutil.ReadFile(net.Alice.ChanBackupPath()) 1405 require.NoError(t.t, err, "channel backup before abandoning channel") 1406 1407 // Send request to abandon channel. 1408 abandonChannelRequest := &lnrpc.AbandonChannelRequest{ 1409 ChannelPoint: chanPoint, 1410 } 1411 1412 ctxt, _ = context.WithTimeout(ctxb, defaultTimeout) 1413 _, err = net.Alice.AbandonChannel(ctxt, abandonChannelRequest) 1414 require.NoError(t.t, err, "abandon channel") 1415 1416 // Assert that channel in no longer open. 1417 ctxt, _ = context.WithTimeout(ctxb, defaultTimeout) 1418 aliceChannelList, err = net.Alice.ListChannels(ctxt, listReq) 1419 require.NoError(t.t, err, "list channels") 1420 require.Zero(t.t, len(aliceChannelList.Channels), "alice open channels") 1421 1422 // Assert that channel is not pending closure. 1423 pendingReq := &lnrpc.PendingChannelsRequest{} 1424 ctxt, _ = context.WithTimeout(ctxb, defaultTimeout) 1425 alicePendingList, err := net.Alice.PendingChannels(ctxt, pendingReq) 1426 require.NoError(t.t, err, "alice list pending channels") 1427 require.Zero( 1428 t.t, len(alicePendingList.PendingClosingChannels), //nolint:staticcheck 1429 "alice pending channels", 1430 ) 1431 require.Zero( 1432 t.t, len(alicePendingList.PendingForceClosingChannels), 1433 "alice pending force close channels", 1434 ) 1435 require.Zero( 1436 t.t, len(alicePendingList.WaitingCloseChannels), 1437 "alice waiting close channels", 1438 ) 1439 1440 // Assert that channel is listed as abandoned. 1441 closedReq := &lnrpc.ClosedChannelsRequest{ 1442 Abandoned: true, 1443 } 1444 ctxt, _ = context.WithTimeout(ctxb, defaultTimeout) 1445 aliceClosedList, err := net.Alice.ClosedChannels(ctxt, closedReq) 1446 require.NoError(t.t, err, "alice list closed channels") 1447 require.Len(t.t, aliceClosedList.Channels, 1, "alice closed channels") 1448 1449 // Ensure that the channel can no longer be found in the channel graph. 1450 err = wait.NoError(func() error { 1451 _, err := net.Alice.GetChanInfo(ctxb, &lnrpc.ChanInfoRequest{ 1452 ChanId: chanID, 1453 }) 1454 if err == nil { 1455 return fmt.Errorf("expected error but got nil") 1456 } 1457 1458 if !strings.Contains(err.Error(), "marked as zombie") { 1459 return fmt.Errorf("expected error to contain '%s' but "+ 1460 "was '%v'", "marked as zombie", err) 1461 } 1462 1463 return nil 1464 }, defaultTimeout) 1465 require.NoError(t.t, err, "marked as zombie") 1466 1467 // Make sure the channel is no longer in the channel backup list. 1468 err = wait.NoError(func() error { 1469 bkupAfter, err := ioutil.ReadFile(net.Alice.ChanBackupPath()) 1470 if err != nil { 1471 return fmt.Errorf("could not get channel backup "+ 1472 "before abandoning channel: %v", err) 1473 } 1474 1475 if len(bkupAfter) >= len(bkupBefore) { 1476 return fmt.Errorf("expected backups after to be less "+ 1477 "than %d but was %d", bkupBefore, bkupAfter) 1478 } 1479 1480 return nil 1481 }, defaultTimeout) 1482 require.NoError(t.t, err, "channel removed from backup file") 1483 1484 // Calling AbandonChannel again, should result in no new errors, as the 1485 // channel has already been removed. 1486 ctxt, _ = context.WithTimeout(ctxb, defaultTimeout) 1487 _, err = net.Alice.AbandonChannel(ctxt, abandonChannelRequest) 1488 require.NoError(t.t, err, "abandon channel second time") 1489 1490 // Now that we're done with the test, the channel can be closed. This 1491 // is necessary to avoid unexpected outcomes of other tests that use 1492 // Bob's lnd instance. 1493 closeChannelAndAssert(t, net, net.Bob, chanPoint, true) 1494 1495 // Cleanup by mining the force close and sweep transaction. 1496 cleanupForceClose(t, net, net.Bob, chanPoint) 1497 } 1498 1499 // testSweepAllCoins tests that we're able to properly sweep all coins from the 1500 // wallet into a single target address at the specified fee rate. 1501 func testSweepAllCoins(net *lntest.NetworkHarness, t *harnessTest) { 1502 ctxb := context.Background() 1503 1504 // First, we'll make a new node, Carol who'll we'll use to test wallet 1505 // sweeping. 1506 carol := net.NewNode(t.t, "Carol", nil) 1507 defer shutdownAndAssert(net, t, carol) 1508 1509 ctxt := testctx.New(t) 1510 1511 // Next, we'll give Carol exactly 2 utxos of 1 DCR each, both using 1512 // p2pkh addresses. 1513 net.SendCoins(t.t, dcrutil.AtomsPerCoin, carol) 1514 1515 net.SendCoins(t.t, dcrutil.AtomsPerCoin, carol) 1516 1517 // Ensure that we can't send coins to our own Pubkey. 1518 info, err := carol.GetInfo(ctxt, &lnrpc.GetInfoRequest{}) 1519 if err != nil { 1520 t.Fatalf("unable to get node info: %v", err) 1521 } 1522 1523 // Create a label that we will used to label the transaction with. 1524 sendCoinsLabel := "send all coins" 1525 1526 sweepReq := &lnrpc.SendCoinsRequest{ 1527 Addr: info.IdentityPubkey, 1528 SendAll: true, 1529 Label: sendCoinsLabel, 1530 } 1531 _, err = carol.SendCoins(ctxt, sweepReq) 1532 if err == nil { 1533 t.Fatalf("expected SendCoins to users own pubkey to fail") 1534 } 1535 1536 // Ensure that we can't send coins to another users Pubkey. 1537 info, err = net.Alice.GetInfo(ctxt, &lnrpc.GetInfoRequest{}) 1538 if err != nil { 1539 t.Fatalf("unable to get node info: %v", err) 1540 } 1541 1542 sweepReq = &lnrpc.SendCoinsRequest{ 1543 Addr: info.IdentityPubkey, 1544 SendAll: true, 1545 Label: sendCoinsLabel, 1546 } 1547 _, err = carol.SendCoins(ctxt, sweepReq) 1548 if err == nil { 1549 t.Fatalf("expected SendCoins to Alices pubkey to fail") 1550 } 1551 1552 // With the two coins above mined, we'll now instruct ainz to sweep all 1553 // the coins to an external address not under its control. 1554 // We will first attempt to send the coins to addresses that are not 1555 // compatible with the current network. This is to test that the wallet 1556 // will prevent any onchain transactions to addresses that are not on 1557 // the same network as the user. 1558 1559 // Send coins to a testnet3 address. 1560 ctxt, _ = context.WithTimeout(ctxb, defaultTimeout) 1561 sweepReq = &lnrpc.SendCoinsRequest{ 1562 Addr: "Tsi6gGYNSMmFwi7JoL5Li39SrERZTTMu6vY", 1563 SendAll: true, 1564 Label: sendCoinsLabel, 1565 } 1566 _, err = carol.SendCoins(ctxt, sweepReq) 1567 if err == nil { 1568 t.Fatalf("expected SendCoins to different network to fail") 1569 } 1570 1571 // Send coins to a mainnet address. 1572 ctxt, _ = context.WithTimeout(ctxb, defaultTimeout) 1573 sweepReq = &lnrpc.SendCoinsRequest{ 1574 Addr: "DsaAKsMvZ6HrqhmbhLjV9qVbPkkzF5daowT", 1575 SendAll: true, 1576 Label: sendCoinsLabel, 1577 } 1578 _, err = carol.SendCoins(ctxt, sweepReq) 1579 if err == nil { 1580 t.Fatalf("expected SendCoins to different network to fail") 1581 } 1582 1583 // Send coins to a compatible address. 1584 minerAddr, err := net.Miner.NewAddress(ctxb) 1585 if err != nil { 1586 t.Fatalf("unable to create new miner addr: %v", err) 1587 } 1588 1589 sweepReq = &lnrpc.SendCoinsRequest{ 1590 Addr: minerAddr.String(), 1591 SendAll: true, 1592 Label: sendCoinsLabel, 1593 } 1594 ctxt, _ = context.WithTimeout(ctxb, defaultTimeout) 1595 _, err = carol.SendCoins(ctxt, sweepReq) 1596 if err != nil { 1597 t.Fatalf("unable to sweep coins: %v", err) 1598 } 1599 1600 // We'll mine a block which should include the sweep transaction we 1601 // generated above. 1602 block := mineBlocks(t, net, 1, 1)[0] 1603 1604 // The sweep transaction should have exactly two inputs as we only had 1605 // two UTXOs in the wallet. 1606 sweepTx := block.Transactions[1] 1607 if len(sweepTx.TxIn) != 2 { 1608 t.Fatalf("expected 2 inputs instead have %v", len(sweepTx.TxIn)) 1609 } 1610 1611 sweepTxStr := sweepTx.TxHash().String() 1612 assertTxLabel(t, carol, sweepTxStr, sendCoinsLabel) 1613 1614 // While we are looking at labels, we test our label transaction command 1615 // to make sure it is behaving as expected. First, we try to label our 1616 // transaction with an empty label, and check that we fail as expected. 1617 sweepHash := sweepTx.TxHash() 1618 _, err = carol.WalletKitClient.LabelTransaction( 1619 ctxt, &walletrpc.LabelTransactionRequest{ 1620 Txid: sweepHash[:], 1621 Label: "", 1622 Overwrite: false, 1623 }, 1624 ) 1625 if err == nil { 1626 t.Fatalf("expected error for zero transaction label") 1627 } 1628 1629 // Our error will be wrapped in a rpc error, so we check that it 1630 // contains the error we expect. 1631 errZeroLabel := "cannot label transaction with empty label" 1632 if !strings.Contains(err.Error(), errZeroLabel) { 1633 t.Fatalf("expected: zero label error, got: %v", err) 1634 } 1635 1636 // Next, we try to relabel our transaction without setting the overwrite 1637 // boolean. We expect this to fail, because the wallet requires setting 1638 // of this param to prevent accidental overwrite of labels. 1639 ctxt, _ = context.WithTimeout(ctxb, defaultTimeout) 1640 _, err = carol.WalletKitClient.LabelTransaction( 1641 ctxt, &walletrpc.LabelTransactionRequest{ 1642 Txid: sweepHash[:], 1643 Label: "label that will not work", 1644 Overwrite: false, 1645 }, 1646 ) 1647 if err == nil { 1648 t.Fatalf("expected error for tx already labelled") 1649 } 1650 1651 // Our error will be wrapped in a rpc error, so we check that it 1652 // contains the error we expect. 1653 if !strings.Contains(err.Error(), "unimplemented") { 1654 t.Fatalf("expected: label exists, got: %v", err) 1655 } 1656 1657 // Finally, we overwrite our label with a new label, which should not 1658 // fail. 1659 newLabel := "new sweep tx label" 1660 _, err = carol.WalletKitClient.LabelTransaction( 1661 ctxt, &walletrpc.LabelTransactionRequest{ 1662 Txid: sweepHash[:], 1663 Label: newLabel, 1664 Overwrite: true, 1665 }, 1666 ) 1667 if err == nil || !strings.Contains(err.Error(), "unimplemented") { 1668 t.Fatalf("could not label tx: %v", err) 1669 } 1670 1671 assertTxLabel(t, carol, sweepTxStr, newLabel) 1672 1673 // Finally, Ainz should now have no coins at all within his wallet. 1674 balReq := &lnrpc.WalletBalanceRequest{} 1675 resp, err := carol.WalletBalance(ctxt, balReq) 1676 if err != nil { 1677 t.Fatalf("unable to get ainz's balance: %v", err) 1678 } 1679 switch { 1680 case resp.ConfirmedBalance != 0: 1681 t.Fatalf("expected no confirmed balance, instead have %v", 1682 resp.ConfirmedBalance) 1683 1684 case resp.UnconfirmedBalance != 0: 1685 t.Fatalf("expected no unconfirmed balance, instead have %v", 1686 resp.UnconfirmedBalance) 1687 } 1688 1689 // If we try again, but this time specifying an amount, then the call 1690 // should fail. 1691 sweepReq.Amount = 10000 1692 _, err = carol.SendCoins(ctxt, sweepReq) 1693 if err == nil { 1694 t.Fatalf("sweep attempt should fail") 1695 } 1696 }