github.com/decred/dcrlnd@v0.7.6/lntest/itest/lnd_payment_test.go (about) 1 package itest 2 3 import ( 4 "bytes" 5 "context" 6 "crypto/sha256" 7 "encoding/hex" 8 "fmt" 9 "reflect" 10 "time" 11 12 "github.com/decred/dcrd/dcrutil/v4" 13 "github.com/decred/dcrlnd/input" 14 "github.com/decred/dcrlnd/lnrpc" 15 "github.com/decred/dcrlnd/lnrpc/routerrpc" 16 "github.com/decred/dcrlnd/lntest" 17 "github.com/decred/dcrlnd/lntest/wait" 18 "github.com/stretchr/testify/require" 19 ) 20 21 func testListPayments(net *lntest.NetworkHarness, t *harnessTest) { 22 ctxb := context.Background() 23 24 // First start by deleting all payments that Alice knows of. This will 25 // allow us to execute the test with a clean state for Alice. 26 delPaymentsReq := &lnrpc.DeleteAllPaymentsRequest{} 27 ctxt, _ := context.WithTimeout(ctxb, defaultTimeout) 28 if _, err := net.Alice.DeleteAllPayments(ctxt, delPaymentsReq); err != nil { 29 t.Fatalf("unable to delete payments: %v", err) 30 } 31 32 // Check that there are no payments before test. 33 reqInit := &lnrpc.ListPaymentsRequest{} 34 ctxt, _ = context.WithTimeout(ctxb, defaultTimeout) 35 paymentsRespInit, err := net.Alice.ListPayments(ctxt, reqInit) 36 if err != nil { 37 t.Fatalf("error when obtaining Alice payments: %v", err) 38 } 39 if len(paymentsRespInit.Payments) != 0 { 40 t.Fatalf("incorrect number of payments, got %v, want %v", 41 len(paymentsRespInit.Payments), 0) 42 } 43 44 // Open a channel with 100k atoms between Alice and Bob with Alice 45 // being the sole funder of the channel. 46 chanAmt := dcrutil.Amount(100000) 47 chanPoint := openChannelAndAssert( 48 t, net, net.Alice, net.Bob, 49 lntest.OpenChannelParams{ 50 Amt: chanAmt, 51 }, 52 ) 53 54 // Now that the channel is open, create an invoice for Bob which 55 // expects a payment of 20000 atoms from Alice paid via a particular 56 // preimage. 57 const paymentAmt = 20000 58 preimage := bytes.Repeat([]byte("B"), 32) 59 invoice := &lnrpc.Invoice{ 60 Memo: "testing", 61 RPreimage: preimage, 62 Value: paymentAmt, 63 } 64 addInvoiceCtxt, _ := context.WithTimeout(ctxb, defaultTimeout) 65 invoiceResp, err := net.Bob.AddInvoice(addInvoiceCtxt, invoice) 66 if err != nil { 67 t.Fatalf("unable to add invoice: %v", err) 68 } 69 70 // Wait for Alice to recognize and advertise the new channel generated 71 // above. 72 if err = net.Alice.WaitForNetworkChannelOpen(chanPoint); err != nil { 73 t.Fatalf("alice didn't advertise channel before "+ 74 "timeout: %v", err) 75 } 76 if err = net.Bob.WaitForNetworkChannelOpen(chanPoint); err != nil { 77 t.Fatalf("bob didn't advertise channel before "+ 78 "timeout: %v", err) 79 } 80 81 // With the invoice for Bob added, send a payment towards Alice paying 82 // to the above generated invoice. 83 sendAndAssertSuccess( 84 t, net.Alice, &routerrpc.SendPaymentRequest{ 85 PaymentRequest: invoiceResp.PaymentRequest, 86 TimeoutSeconds: 60, 87 FeeLimitAtoms: 1000000, 88 }, 89 ) 90 91 // Grab Alice's list of payments, she should show the existence of 92 // exactly one payment. 93 req := &lnrpc.ListPaymentsRequest{} 94 ctxt, _ = context.WithTimeout(ctxb, defaultTimeout) 95 paymentsResp, err := net.Alice.ListPayments(ctxt, req) 96 if err != nil { 97 t.Fatalf("error when obtaining Alice payments: %v", err) 98 } 99 if len(paymentsResp.Payments) != 1 { 100 t.Fatalf("incorrect number of payments, got %v, want %v", 101 len(paymentsResp.Payments), 1) 102 } 103 p := paymentsResp.Payments[0] // nolint:staticcheck 104 path := p.Htlcs[len(p.Htlcs)-1].Route.Hops 105 106 // Ensure that the stored path shows a direct payment to Bob with no 107 // other nodes in-between. 108 if len(path) != 1 || path[0].PubKey != net.Bob.PubKeyStr { 109 t.Fatalf("incorrect path") 110 } 111 112 // The payment amount should also match our previous payment directly. 113 if p.Value != paymentAmt { // nolint:staticcheck 114 t.Fatalf("incorrect amount, got %v, want %v", 115 p.Value, paymentAmt) // nolint:staticcheck 116 } 117 118 // The payment hash (or r-hash) should have been stored correctly. 119 correctRHash := hex.EncodeToString(invoiceResp.RHash) 120 if !reflect.DeepEqual(p.PaymentHash, correctRHash) { 121 t.Fatalf("incorrect RHash, got %v, want %v", 122 p.PaymentHash, correctRHash) 123 } 124 125 // As we made a single-hop direct payment, there should have been no fee 126 // applied. 127 if p.Fee != 0 { // nolint:staticcheck 128 t.Fatalf("incorrect Fee, got %v, want %v", p.Fee, 0) // nolint:staticcheck 129 } 130 131 // Finally, verify that the payment request returned by the rpc matches 132 // the invoice that we paid. 133 if p.PaymentRequest != invoiceResp.PaymentRequest { 134 t.Fatalf("incorrect payreq, got: %v, want: %v", 135 p.PaymentRequest, invoiceResp.PaymentRequest) 136 } 137 138 // Delete all payments from Alice. DB should have no payments. 139 delReq := &lnrpc.DeleteAllPaymentsRequest{} 140 ctxt, _ = context.WithTimeout(ctxb, defaultTimeout) 141 _, err = net.Alice.DeleteAllPayments(ctxt, delReq) 142 if err != nil { 143 t.Fatalf("Can't delete payments at the end: %v", err) 144 } 145 146 // Check that there are no payments after test. 147 listReq := &lnrpc.ListPaymentsRequest{} 148 ctxt, _ = context.WithTimeout(ctxb, defaultTimeout) 149 paymentsResp, err = net.Alice.ListPayments(ctxt, listReq) 150 if err != nil { 151 t.Fatalf("error when obtaining Alice payments: %v", err) 152 } 153 if len(paymentsResp.Payments) != 0 { 154 t.Fatalf("incorrect number of payments, got %v, want %v", 155 len(paymentsResp.Payments), 0) 156 } 157 158 closeChannelAndAssert(t, net, net.Alice, chanPoint, false) 159 } 160 161 // testPaymentFollowingChannelOpen tests that the channel transition from 162 // 'pending' to 'open' state does not cause any inconsistencies within other 163 // subsystems trying to update the channel state in the db. We follow this 164 // transition with a payment that updates the commitment state and verify that 165 // the pending state is up to date. 166 func testPaymentFollowingChannelOpen(net *lntest.NetworkHarness, t *harnessTest) { 167 ctxb := context.Background() 168 169 // We first establish a channel between Alice and Bob. 170 const paymentAmt = dcrutil.Amount(100) 171 channelCapacity := paymentAmt * 1000 172 173 // We first establish a channel between Alice and Bob. 174 pendingUpdate, err := net.OpenPendingChannel( 175 net.Alice, net.Bob, channelCapacity, 0, 176 ) 177 if err != nil { 178 t.Fatalf("unable to open channel: %v", err) 179 } 180 181 // At this point, the channel's funding transaction will have been 182 // broadcast, but not confirmed. Alice and Bob's nodes 183 // should reflect this when queried via RPC. 184 assertNumOpenChannelsPending(t, net.Alice, net.Bob, 1) 185 186 // We are restarting Bob's node to let the link be created for the 187 // pending channel. 188 if err := net.RestartNode(net.Bob, nil); err != nil { 189 t.Fatalf("Bob restart failed: %v", err) 190 } 191 192 // We ensure that Bob reconnects to Alice. 193 net.EnsureConnected(t.t, net.Bob, net.Alice) 194 195 // We mine one block for the channel to be confirmed. 196 _ = mineBlocks(t, net, 6, 1)[0] 197 198 // We verify that the channel is open from both nodes point of view. 199 assertNumOpenChannelsPending(t, net.Alice, net.Bob, 0) 200 201 // With the channel open, we'll create invoices for Bob that Alice will 202 // pay to in order to advance the state of the channel. 203 bobPayReqs, _, _, err := createPayReqs( 204 net.Bob, paymentAmt, 1, 205 ) 206 if err != nil { 207 t.Fatalf("unable to create pay reqs: %v", err) 208 } 209 210 // Send payment to Bob so that a channel update to disk will be 211 // executed. 212 sendAndAssertSuccess( 213 t, net.Alice, &routerrpc.SendPaymentRequest{ 214 PaymentRequest: bobPayReqs[0], 215 TimeoutSeconds: 60, 216 FeeLimitAtoms: 1000000, 217 }, 218 ) 219 220 // At this point we want to make sure the channel is opened and not 221 // pending. 222 ctxt, cancel := context.WithTimeout(ctxb, defaultTimeout) 223 defer cancel() 224 res, err := net.Bob.ListChannels(ctxt, &lnrpc.ListChannelsRequest{}) 225 if err != nil { 226 t.Fatalf("unable to list bob channels: %v", err) 227 } 228 if len(res.Channels) == 0 { 229 t.Fatalf("bob list of channels is empty") 230 } 231 232 // Finally, immediately close the channel. This function will also 233 // block until the channel is closed and will additionally assert the 234 // relevant channel closing post conditions. 235 chanPoint := &lnrpc.ChannelPoint{ 236 FundingTxid: &lnrpc.ChannelPoint_FundingTxidBytes{ 237 FundingTxidBytes: pendingUpdate.Txid, 238 }, 239 OutputIndex: pendingUpdate.OutputIndex, 240 } 241 closeChannelAndAssert(t, net, net.Alice, chanPoint, false) 242 } 243 244 // testAsyncPayments tests the performance of the async payments. 245 func testAsyncPayments(net *lntest.NetworkHarness, t *harnessTest) { 246 runAsyncPayments(net, t, net.Alice, net.Bob) 247 } 248 249 // runAsyncPayments tests the performance of the async payments. 250 func runAsyncPayments(net *lntest.NetworkHarness, t *harnessTest, alice, 251 bob *lntest.HarnessNode) { 252 253 ctxb := context.Background() 254 255 const ( 256 paymentAmt = 100 257 ) 258 259 // First establish a channel with a capacity equals to the overall 260 // amount of payments, between Alice and Bob, at the end of the test 261 // Alice should send all money from her side to Bob. 262 channelCapacity := dcrutil.Amount(paymentAmt * 2000) 263 chanPoint := openChannelAndAssert( 264 t, net, alice, bob, 265 lntest.OpenChannelParams{ 266 Amt: channelCapacity, 267 }, 268 ) 269 270 info, err := getChanInfo(alice) 271 if err != nil { 272 t.Fatalf("unable to get alice channel info: %v", err) 273 } 274 275 // We'll create a number of invoices equal the max number of HTLCs that 276 // can be carried in one direction. The number on the commitment will 277 // likely be lower, but we can't guarantee that any more HTLCs will 278 // succeed due to the limited path diversity and inability of the 279 // router to retry via another path. 280 numInvoices := int(input.MaxHTLCNumber / 2) 281 282 bobAmt := int64(numInvoices * paymentAmt) 283 aliceAmt := info.LocalBalance - bobAmt 284 285 // With the channel open, we'll create invoices for Bob that Alice 286 // will pay to in order to advance the state of the channel. 287 bobPayReqs, _, _, err := createPayReqs( 288 bob, paymentAmt, numInvoices, 289 ) 290 if err != nil { 291 t.Fatalf("unable to create pay reqs: %v", err) 292 } 293 294 // Wait for Alice to receive the channel edge from the funding manager. 295 err = alice.WaitForNetworkChannelOpen(chanPoint) 296 if err != nil { 297 t.Fatalf("alice didn't see the alice->bob channel before "+ 298 "timeout: %v", err) 299 } 300 301 // Simultaneously send payments from Alice to Bob using of Bob's payment 302 // hashes generated above. 303 now := time.Now() 304 errChan := make(chan error) 305 statusChan := make(chan *lnrpc.Payment) 306 for i := 0; i < numInvoices; i++ { 307 payReq := bobPayReqs[i] 308 go func() { 309 ctxt, _ := context.WithTimeout(ctxb, lntest.AsyncBenchmarkTimeout) 310 stream, err := alice.RouterClient.SendPaymentV2( 311 ctxt, 312 &routerrpc.SendPaymentRequest{ 313 PaymentRequest: payReq, 314 TimeoutSeconds: 60, 315 FeeLimitMAtoms: noFeeLimitMAtoms, 316 }, 317 ) 318 if err != nil { 319 errChan <- err 320 } 321 result, err := getPaymentResult(stream) 322 if err != nil { 323 errChan <- err 324 } 325 326 statusChan <- result 327 }() 328 } 329 330 // Wait until all the payments have settled. 331 for i := 0; i < numInvoices; i++ { 332 select { 333 case result := <-statusChan: 334 if result.Status == lnrpc.Payment_SUCCEEDED { 335 continue 336 } 337 338 case err := <-errChan: 339 t.Fatalf("payment error: %v", err) 340 } 341 } 342 343 // All payments have been sent, mark the finish time. 344 timeTaken := time.Since(now) 345 346 // Next query for Bob's and Alice's channel states, in order to confirm 347 // that all payment have been successful transmitted. 348 349 // Wait for the revocation to be received so alice no longer has pending 350 // htlcs listed and has correct balances. This is needed due to the fact 351 // that we now pipeline the settles. 352 err = wait.Predicate(func() bool { 353 aliceChan, err := getChanInfo(alice) 354 if err != nil { 355 return false 356 } 357 if len(aliceChan.PendingHtlcs) != 0 { 358 return false 359 } 360 if aliceChan.RemoteBalance != bobAmt { 361 return false 362 } 363 if aliceChan.LocalBalance != aliceAmt { 364 return false 365 } 366 367 return true 368 }, defaultTimeout) 369 if err != nil { 370 t.Fatalf("failed to assert alice's pending htlcs and/or remote/local balance") 371 } 372 373 // Wait for Bob to receive revocation from Alice. 374 err = wait.NoError(func() error { 375 bobChan, err := getChanInfo(bob) 376 if err != nil { 377 t.Fatalf("unable to get bob's channel info: %v", err) 378 } 379 380 if len(bobChan.PendingHtlcs) != 0 { 381 return fmt.Errorf("bob's pending htlcs is incorrect, "+ 382 "got %v, expected %v", 383 len(bobChan.PendingHtlcs), 0) 384 } 385 386 if bobChan.LocalBalance != bobAmt { 387 return fmt.Errorf("bob's local balance is incorrect, "+ 388 "got %v, expected %v", bobChan.LocalBalance, 389 bobAmt) 390 } 391 392 if bobChan.RemoteBalance != aliceAmt { 393 return fmt.Errorf("bob's remote balance is incorrect, "+ 394 "got %v, expected %v", bobChan.RemoteBalance, 395 aliceAmt) 396 } 397 398 return nil 399 }, defaultTimeout) 400 require.NoError(t.t, err) 401 402 t.Log("\tBenchmark info: Elapsed time: ", timeTaken) 403 t.Log("\tBenchmark info: TPS: ", float64(numInvoices)/timeTaken.Seconds()) 404 405 // Finally, immediately close the channel. This function will also 406 // block until the channel is closed and will additionally assert the 407 // relevant channel closing post conditions. 408 closeChannelAndAssert(t, net, alice, chanPoint, false) 409 } 410 411 // testBidirectionalAsyncPayments tests that nodes are able to send the 412 // payments to each other in async manner without blocking. 413 func testBidirectionalAsyncPayments(net *lntest.NetworkHarness, t *harnessTest) { 414 ctxb := context.Background() 415 416 const ( 417 paymentAmt = 1000 418 ) 419 420 // First establish a channel with a capacity equals to the overall 421 // amount of payments, between Alice and Bob, at the end of the test 422 // Alice should send all money from her side to Bob. 423 chanPoint := openChannelAndAssert( 424 t, net, net.Alice, net.Bob, 425 lntest.OpenChannelParams{ 426 Amt: paymentAmt * 500, 427 PushAmt: paymentAmt * 250, 428 }, 429 ) 430 431 info, err := getChanInfo(net.Alice) 432 if err != nil { 433 t.Fatalf("unable to get alice channel info: %v", err) 434 } 435 436 // We'll create a number of invoices equal the max number of HTLCs that 437 // can be carried in one direction. The number on the commitment will 438 // likely be lower, but we can't guarantee that any more HTLCs will 439 // succeed due to the limited path diversity and inability of the router 440 // to retry via another path. 441 numInvoices := int(input.MaxHTLCNumber / 2) 442 443 // Nodes should exchange the same amount of money and because of this 444 // at the end balances should remain the same. 445 aliceAmt := info.LocalBalance 446 bobAmt := info.RemoteBalance 447 448 // With the channel open, we'll create invoices for Bob that Alice 449 // will pay to in order to advance the state of the channel. 450 bobPayReqs, _, _, err := createPayReqs( 451 net.Bob, paymentAmt, numInvoices, 452 ) 453 if err != nil { 454 t.Fatalf("unable to create pay reqs: %v", err) 455 } 456 457 // With the channel open, we'll create invoices for Alice that Bob 458 // will pay to in order to advance the state of the channel. 459 alicePayReqs, _, _, err := createPayReqs( 460 net.Alice, paymentAmt, numInvoices, 461 ) 462 if err != nil { 463 t.Fatalf("unable to create pay reqs: %v", err) 464 } 465 466 // Wait for Alice to receive the channel edge from the funding manager. 467 if err = net.Alice.WaitForNetworkChannelOpen(chanPoint); err != nil { 468 t.Fatalf("alice didn't see the alice->bob channel before "+ 469 "timeout: %v", err) 470 } 471 if err = net.Bob.WaitForNetworkChannelOpen(chanPoint); err != nil { 472 t.Fatalf("bob didn't see the bob->alice channel before "+ 473 "timeout: %v", err) 474 } 475 476 // Reset mission control to prevent previous payment results from 477 // interfering with this test. A new channel has been opened, but 478 // mission control operates on node pairs. 479 ctxt, _ := context.WithTimeout(ctxb, defaultTimeout) 480 _, err = net.Alice.RouterClient.ResetMissionControl( 481 ctxt, &routerrpc.ResetMissionControlRequest{}, 482 ) 483 if err != nil { 484 t.Fatalf("unable to reset mc for alice: %v", err) 485 } 486 487 // Send payments from Alice to Bob and from Bob to Alice in async 488 // manner. 489 errChan := make(chan error) 490 statusChan := make(chan *lnrpc.Payment) 491 492 send := func(node *lntest.HarnessNode, payReq string) { 493 go func() { 494 ctxt, _ = context.WithTimeout( 495 ctxb, lntest.AsyncBenchmarkTimeout, 496 ) 497 stream, err := node.RouterClient.SendPaymentV2( 498 ctxt, 499 &routerrpc.SendPaymentRequest{ 500 PaymentRequest: payReq, 501 TimeoutSeconds: 60, 502 FeeLimitMAtoms: noFeeLimitMAtoms, 503 }, 504 ) 505 if err != nil { 506 errChan <- err 507 } 508 result, err := getPaymentResult(stream) 509 if err != nil { 510 errChan <- err 511 } 512 513 statusChan <- result 514 }() 515 } 516 517 for i := 0; i < numInvoices; i++ { 518 send(net.Bob, alicePayReqs[i]) 519 send(net.Alice, bobPayReqs[i]) 520 } 521 522 // Expect all payments to succeed. 523 for i := 0; i < 2*numInvoices; i++ { 524 select { 525 case result := <-statusChan: 526 if result.Status != lnrpc.Payment_SUCCEEDED { 527 t.Fatalf("payment error: %v", result.Status) 528 } 529 530 case err := <-errChan: 531 t.Fatalf("payment error: %v", err) 532 } 533 } 534 535 // Wait for Alice and Bob to receive revocations messages, and update 536 // states, i.e. balance info. 537 err = wait.NoError(func() error { 538 aliceInfo, err := getChanInfo(net.Alice) 539 if err != nil { 540 t.Fatalf("unable to get alice's channel info: %v", err) 541 } 542 543 if aliceInfo.RemoteBalance != bobAmt { 544 return fmt.Errorf("alice's remote balance is incorrect, "+ 545 "got %v, expected %v", aliceInfo.RemoteBalance, 546 bobAmt) 547 } 548 549 if aliceInfo.LocalBalance != aliceAmt { 550 return fmt.Errorf("alice's local balance is incorrect, "+ 551 "got %v, expected %v", aliceInfo.LocalBalance, 552 aliceAmt) 553 } 554 555 if len(aliceInfo.PendingHtlcs) != 0 { 556 return fmt.Errorf("alice's pending htlcs is incorrect, "+ 557 "got %v expected %v", 558 len(aliceInfo.PendingHtlcs), 0) 559 } 560 561 return nil 562 }, defaultTimeout) 563 require.NoError(t.t, err) 564 565 // Next query for Bob's and Alice's channel states, in order to confirm 566 // that all payment have been successful transmitted. 567 err = wait.NoError(func() error { 568 bobInfo, err := getChanInfo(net.Bob) 569 if err != nil { 570 t.Fatalf("unable to get bob's channel info: %v", err) 571 } 572 573 if bobInfo.LocalBalance != bobAmt { 574 return fmt.Errorf("bob's local balance is incorrect, "+ 575 "got %v, expected %v", bobInfo.LocalBalance, 576 bobAmt) 577 } 578 579 if bobInfo.RemoteBalance != aliceAmt { 580 return fmt.Errorf("bob's remote balance is incorrect, "+ 581 "got %v, expected %v", bobInfo.RemoteBalance, 582 aliceAmt) 583 } 584 585 if len(bobInfo.PendingHtlcs) != 0 { 586 return fmt.Errorf("bob's pending htlcs is incorrect, "+ 587 "got %v, expected %v", 588 len(bobInfo.PendingHtlcs), 0) 589 } 590 591 return nil 592 }, defaultTimeout) 593 require.NoError(t.t, err) 594 595 // Finally, immediately close the channel. This function will also 596 // block until the channel is closed and will additionally assert the 597 // relevant channel closing post conditions. 598 closeChannelAndAssert(t, net, net.Alice, chanPoint, false) 599 } 600 601 func testInvoiceSubscriptions(net *lntest.NetworkHarness, t *harnessTest) { 602 ctxb := context.Background() 603 604 const chanAmt = dcrutil.Amount(500000) 605 606 // Open a channel with 500k atoms between Alice and Bob with Alice 607 // being the sole funder of the channel. 608 chanPoint := openChannelAndAssert( 609 t, net, net.Alice, net.Bob, 610 lntest.OpenChannelParams{ 611 Amt: chanAmt, 612 }, 613 ) 614 615 // Next create a new invoice for Bob requesting 1k atoms. 616 // TODO(roasbeef): make global list of invoices for each node to re-use 617 // and avoid collisions 618 const paymentAmt = 1000 619 invoice := &lnrpc.Invoice{ 620 Memo: "testing", 621 RPreimage: makeFakePayHash(t), 622 Value: paymentAmt, 623 } 624 ctxt, _ := context.WithTimeout(ctxb, defaultTimeout) 625 invoiceResp, err := net.Bob.AddInvoice(ctxt, invoice) 626 if err != nil { 627 t.Fatalf("unable to add invoice: %v", err) 628 } 629 lastAddIndex := invoiceResp.AddIndex 630 631 // Create a new invoice subscription client for Bob, the notification 632 // should be dispatched shortly below. 633 req := &lnrpc.InvoiceSubscription{} 634 ctx, cancelInvoiceSubscription := context.WithCancel(ctxb) 635 bobInvoiceSubscription, err := net.Bob.SubscribeInvoices(ctx, req) 636 if err != nil { 637 t.Fatalf("unable to subscribe to bob's invoice updates: %v", err) 638 } 639 640 var settleIndex uint64 641 quit := make(chan struct{}) 642 updateSent := make(chan struct{}) 643 go func() { 644 invoiceUpdate, err := bobInvoiceSubscription.Recv() 645 select { 646 case <-quit: 647 // Received cancellation 648 return 649 default: 650 } 651 652 if err != nil { 653 t.Fatalf("unable to recv invoice update: %v", err) 654 } 655 656 // The invoice update should exactly match the invoice created 657 // above, but should now be settled and have SettleDate 658 if !invoiceUpdate.Settled { 659 t.Fatalf("invoice not settled but should be") 660 } 661 if invoiceUpdate.SettleDate == 0 { 662 t.Fatalf("invoice should have non zero settle date, but doesn't") 663 } 664 665 if !bytes.Equal(invoiceUpdate.RPreimage, invoice.RPreimage) { 666 t.Fatalf("payment preimages don't match: expected %v, got %v", 667 invoice.RPreimage, invoiceUpdate.RPreimage) 668 } 669 670 if invoiceUpdate.SettleIndex == 0 { 671 t.Fatalf("invoice should have settle index") 672 } 673 674 settleIndex = invoiceUpdate.SettleIndex 675 676 close(updateSent) 677 }() 678 679 // Wait for the channel to be recognized by both Alice and Bob before 680 // continuing the rest of the test. 681 err = net.Alice.WaitForNetworkChannelOpen(chanPoint) 682 if err != nil { 683 // TODO(roasbeef): will need to make num blocks to advertise a 684 // node param 685 close(quit) 686 t.Fatalf("channel not seen by alice before timeout: %v", err) 687 } 688 689 // With the assertion above set up, send a payment from Alice to Bob 690 // which should finalize and settle the invoice. 691 sendReq := &routerrpc.SendPaymentRequest{ 692 PaymentRequest: invoiceResp.PaymentRequest, 693 TimeoutSeconds: 60, 694 FeeLimitMAtoms: noFeeLimitMAtoms, 695 } 696 ctxt, _ = context.WithTimeout(ctxb, defaultTimeout) 697 stream, err := net.Alice.RouterClient.SendPaymentV2(ctxt, sendReq) 698 if err != nil { 699 close(quit) 700 t.Fatalf("unable to send payment: %v", err) 701 } 702 result, err := getPaymentResult(stream) 703 if err != nil { 704 close(quit) 705 t.Fatalf("cannot get payment result: %v", err) 706 } 707 if result.Status != lnrpc.Payment_SUCCEEDED { 708 close(quit) 709 t.Fatalf("error when attempting recv: %v", result.Status) 710 } 711 712 select { 713 case <-time.After(time.Second * 10): 714 close(quit) 715 t.Fatalf("update not sent after 10 seconds") 716 case <-updateSent: // Fall through on success 717 } 718 719 // With the base case working, we'll now cancel Bob's current 720 // subscription in order to exercise the backlog fill behavior. 721 cancelInvoiceSubscription() 722 723 // We'll now add 3 more invoices to Bob's invoice registry. 724 const numInvoices = 3 725 payReqs, _, newInvoices, err := createPayReqs( 726 net.Bob, paymentAmt, numInvoices, 727 ) 728 if err != nil { 729 t.Fatalf("unable to create pay reqs: %v", err) 730 } 731 732 // Now that the set of invoices has been added, we'll re-register for 733 // streaming invoice notifications for Bob, this time specifying the 734 // add invoice of the last prior invoice. 735 req = &lnrpc.InvoiceSubscription{ 736 AddIndex: lastAddIndex, 737 } 738 ctx, cancelInvoiceSubscription = context.WithCancel(ctxb) 739 bobInvoiceSubscription, err = net.Bob.SubscribeInvoices(ctx, req) 740 if err != nil { 741 t.Fatalf("unable to subscribe to bob's invoice updates: %v", err) 742 } 743 744 // Since we specified a value of the prior add index above, we should 745 // now immediately get the invoices we just added as we should get the 746 // backlog of notifications. 747 for i := 0; i < numInvoices; i++ { 748 invoiceUpdate, err := bobInvoiceSubscription.Recv() 749 if err != nil { 750 t.Fatalf("unable to receive subscription") 751 } 752 753 // We should now get the ith invoice we added, as they should 754 // be returned in order. 755 if invoiceUpdate.Settled { 756 t.Fatalf("should have only received add events") 757 } 758 originalInvoice := newInvoices[i] 759 rHash := sha256.Sum256(originalInvoice.RPreimage) 760 if !bytes.Equal(invoiceUpdate.RHash, rHash[:]) { 761 t.Fatalf("invoices have mismatched payment hashes: "+ 762 "expected %x, got %x", rHash, 763 invoiceUpdate.RHash) 764 } 765 } 766 767 cancelInvoiceSubscription() 768 769 // We'll now have Bob settle out the remainder of these invoices so we 770 // can test that all settled invoices are properly notified. 771 err = completePaymentRequests( 772 net.Alice, net.Alice.RouterClient, payReqs, true, 773 ) 774 if err != nil { 775 t.Fatalf("unable to send payment: %v", err) 776 } 777 778 // With the set of invoices paid, we'll now cancel the old 779 // subscription, and create a new one for Bob, this time using the 780 // settle index to obtain the backlog of settled invoices. 781 req = &lnrpc.InvoiceSubscription{ 782 SettleIndex: settleIndex, 783 } 784 ctx, cancelInvoiceSubscription = context.WithCancel(ctxb) 785 bobInvoiceSubscription, err = net.Bob.SubscribeInvoices(ctx, req) 786 if err != nil { 787 t.Fatalf("unable to subscribe to bob's invoice updates: %v", err) 788 } 789 790 defer cancelInvoiceSubscription() 791 792 // As we specified the index of the past settle index, we should now 793 // receive notifications for the three HTLCs that we just settled. As 794 // the order that the HTLCs will be settled in is partially randomized, 795 // we'll use a map to assert that the proper set has been settled. 796 settledInvoices := make(map[[32]byte]struct{}) 797 for _, invoice := range newInvoices { 798 rHash := sha256.Sum256(invoice.RPreimage) 799 settledInvoices[rHash] = struct{}{} 800 } 801 for i := 0; i < numInvoices; i++ { 802 invoiceUpdate, err := bobInvoiceSubscription.Recv() 803 if err != nil { 804 t.Fatalf("unable to receive subscription") 805 } 806 807 // We should now get the ith invoice we added, as they should 808 // be returned in order. 809 if !invoiceUpdate.Settled { 810 t.Fatalf("should have only received settle events") 811 } 812 813 var rHash [32]byte 814 copy(rHash[:], invoiceUpdate.RHash) 815 if _, ok := settledInvoices[rHash]; !ok { 816 t.Fatalf("unknown invoice settled: %x", rHash) 817 } 818 819 delete(settledInvoices, rHash) 820 } 821 822 // At this point, all the invoices should be fully settled. 823 if len(settledInvoices) != 0 { 824 t.Fatalf("not all invoices settled") 825 } 826 827 closeChannelAndAssert(t, net, net.Alice, chanPoint, false) 828 }