github.com/decred/dcrlnd@v0.7.6/lntest/itest/lnd_switch_test.go (about) 1 package itest 2 3 import ( 4 "context" 5 "time" 6 7 "github.com/decred/dcrd/dcrutil/v4" 8 "github.com/decred/dcrd/wire" 9 "github.com/decred/dcrlnd/lnrpc" 10 "github.com/decred/dcrlnd/lntest" 11 "github.com/decred/dcrlnd/lntest/wait" 12 "github.com/stretchr/testify/require" 13 ) 14 15 // testSwitchCircuitPersistence creates a multihop network to ensure the sender 16 // and intermediaries are persisting their open payment circuits. After 17 // forwarding a packet via an outgoing link, all are restarted, and expected to 18 // forward a response back from the receiver once back online. 19 // 20 // The general flow of this test: 21 // 1. Carol --> Dave --> Alice --> Bob forward payment 22 // 2. X X X Bob restart sender and intermediaries 23 // 3. Carol <-- Dave <-- Alice <-- Bob expect settle to propagate 24 func testSwitchCircuitPersistence(net *lntest.NetworkHarness, t *harnessTest) { 25 ctxb := context.Background() 26 27 const chanAmt = dcrutil.Amount(1000000) 28 const pushAmt = dcrutil.Amount(900000) 29 var networkChans []*lnrpc.ChannelPoint 30 31 // Open a channel with 100k atoms between Alice and Bob with Alice 32 // being the sole funder of the channel. 33 chanPointAlice := openChannelAndAssert( 34 t, net, net.Alice, net.Bob, 35 lntest.OpenChannelParams{ 36 Amt: chanAmt, 37 PushAmt: pushAmt, 38 }, 39 ) 40 networkChans = append(networkChans, chanPointAlice) 41 42 aliceChanTXID, err := lnrpc.GetChanPointFundingTxid(chanPointAlice) 43 if err != nil { 44 t.Fatalf("unable to get txid: %v", err) 45 } 46 aliceFundPoint := wire.OutPoint{ 47 Hash: *aliceChanTXID, 48 Index: chanPointAlice.OutputIndex, 49 } 50 51 // As preliminary setup, we'll create two new nodes: Carol and Dave, 52 // such that we now have a 4 ndoe, 3 channel topology. Dave will make 53 // a channel with Alice, and Carol with Dave. After this setup, the 54 // network topology should now look like: 55 // Carol -> Dave -> Alice -> Bob 56 // 57 // First, we'll create Dave and establish a channel to Alice. 58 dave := net.NewNode(t.t, "Dave", nil) 59 defer shutdownAndAssert(net, t, dave) 60 61 net.ConnectNodes(t.t, dave, net.Alice) 62 net.SendCoins(t.t, dcrutil.AtomsPerCoin, dave) 63 64 chanPointDave := openChannelAndAssert( 65 t, net, dave, net.Alice, 66 lntest.OpenChannelParams{ 67 Amt: chanAmt, 68 PushAmt: pushAmt, 69 }, 70 ) 71 networkChans = append(networkChans, chanPointDave) 72 daveChanTXID, err := lnrpc.GetChanPointFundingTxid(chanPointDave) 73 if err != nil { 74 t.Fatalf("unable to get txid: %v", err) 75 } 76 daveFundPoint := wire.OutPoint{ 77 Hash: *daveChanTXID, 78 Index: chanPointDave.OutputIndex, 79 } 80 81 // Next, we'll create Carol and establish a channel to from her to 82 // Dave. Carol is started in htlchodl mode so that we can disconnect the 83 // intermediary hops before starting the settle. 84 carol := net.NewNode(t.t, "Carol", []string{"--hodl.exit-settle"}) 85 defer shutdownAndAssert(net, t, carol) 86 87 net.ConnectNodes(t.t, carol, dave) 88 net.SendCoins(t.t, dcrutil.AtomsPerCoin, carol) 89 90 chanPointCarol := openChannelAndAssert( 91 t, net, carol, dave, 92 lntest.OpenChannelParams{ 93 Amt: chanAmt, 94 PushAmt: pushAmt, 95 }, 96 ) 97 networkChans = append(networkChans, chanPointCarol) 98 99 carolChanTXID, err := lnrpc.GetChanPointFundingTxid(chanPointCarol) 100 if err != nil { 101 t.Fatalf("unable to get txid: %v", err) 102 } 103 carolFundPoint := wire.OutPoint{ 104 Hash: *carolChanTXID, 105 Index: chanPointCarol.OutputIndex, 106 } 107 108 // Wait for all nodes to have seen all channels. 109 nodes := []*lntest.HarnessNode{net.Alice, net.Bob, carol, dave} 110 nodeNames := []string{"Alice", "Bob", "Carol", "Dave"} 111 for _, chanPoint := range networkChans { 112 for i, node := range nodes { 113 txid, err := lnrpc.GetChanPointFundingTxid(chanPoint) 114 if err != nil { 115 t.Fatalf("unable to get txid: %v", err) 116 } 117 point := wire.OutPoint{ 118 Hash: *txid, 119 Index: chanPoint.OutputIndex, 120 } 121 122 err = node.WaitForNetworkChannelOpen(chanPoint) 123 if err != nil { 124 t.Fatalf("%s(%d): timeout waiting for "+ 125 "channel(%s) open: %v", nodeNames[i], 126 node.NodeID, point, err) 127 } 128 } 129 } 130 131 // Create 5 invoices for Carol, which expect a payment from Bob for 1k 132 // atoms with a different preimage each time. 133 const numPayments = 5 134 const paymentAmt = 1000 135 payReqs, _, _, err := createPayReqs( 136 carol, paymentAmt, numPayments, 137 ) 138 if err != nil { 139 t.Fatalf("unable to create pay reqs: %v", err) 140 } 141 142 // We'll wait for all parties to recognize the new channels within the 143 // network. 144 err = dave.WaitForNetworkChannelOpen(chanPointDave) 145 if err != nil { 146 t.Fatalf("dave didn't advertise his channel: %v", err) 147 } 148 err = carol.WaitForNetworkChannelOpen(chanPointCarol) 149 if err != nil { 150 t.Fatalf("carol didn't advertise her channel in time: %v", 151 err) 152 } 153 154 time.Sleep(time.Millisecond * 50) 155 156 // Using Carol as the source, pay to the 5 invoices from Bob created 157 // above. 158 err = completePaymentRequests( 159 net.Bob, net.Bob.RouterClient, payReqs, false, 160 ) 161 if err != nil { 162 t.Fatalf("unable to send payments: %v", err) 163 } 164 165 // Wait until all nodes in the network have 5 outstanding htlcs. 166 var predErr error 167 err = wait.Predicate(func() bool { 168 predErr = assertNumActiveHtlcs(nodes, numPayments) 169 return predErr == nil 170 }, defaultTimeout) 171 if err != nil { 172 t.Fatalf("htlc mismatch: %v", predErr) 173 } 174 175 // Restart the intermediaries and the sender. 176 if err := net.RestartNode(dave, nil); err != nil { 177 t.Fatalf("Node restart failed: %v", err) 178 } 179 180 if err := net.RestartNode(net.Alice, nil); err != nil { 181 t.Fatalf("Node restart failed: %v", err) 182 } 183 184 if err := net.RestartNode(net.Bob, nil); err != nil { 185 t.Fatalf("Node restart failed: %v", err) 186 } 187 188 // Ensure all of the intermediate links are reconnected. 189 net.EnsureConnected(t.t, net.Alice, dave) 190 net.EnsureConnected(t.t, net.Bob, net.Alice) 191 192 // Ensure all nodes in the network still have 5 outstanding htlcs. 193 err = wait.Predicate(func() bool { 194 predErr = assertNumActiveHtlcs(nodes, numPayments) 195 return predErr == nil 196 }, defaultTimeout) 197 if err != nil { 198 t.Fatalf("htlc mismatch: %v", predErr) 199 } 200 201 // Now restart carol without hodl mode, to settle back the outstanding 202 // payments. 203 carol.SetExtraArgs(nil) 204 if err := net.RestartNode(carol, nil); err != nil { 205 t.Fatalf("Node restart failed: %v", err) 206 } 207 208 net.EnsureConnected(t.t, dave, carol) 209 210 // After the payments settle, there should be no active htlcs on any of 211 // the nodes in the network. 212 err = wait.Predicate(func() bool { 213 predErr = assertNumActiveHtlcs(nodes, 0) 214 return predErr == nil 215 }, defaultTimeout) 216 if err != nil { 217 t.Fatalf("htlc mismatch: %v", predErr) 218 } 219 220 // When asserting the amount of atoms moved, we'll factor in the 221 // default base fee, as we didn't modify the fee structure when 222 // creating the seed nodes in the network. 223 const baseFee = 1 224 225 // At this point all the channels within our proto network should be 226 // shifted by 5k atoms in the direction of Carol, the sink within the 227 // payment flow generated above. The order of asserts corresponds to 228 // increasing of time is needed to embed the HTLC in commitment 229 // transaction, in channel Bob->Alice->David->Carol, order is Carol, 230 // David, Alice, Bob. 231 var amountPaid = int64(5000) 232 assertAmountPaid(t, "Dave(local) => Carol(remote)", carol, 233 carolFundPoint, int64(0), amountPaid) 234 assertAmountPaid(t, "Dave(local) => Carol(remote)", dave, 235 carolFundPoint, amountPaid, int64(0)) 236 assertAmountPaid(t, "Alice(local) => Dave(remote)", dave, 237 daveFundPoint, int64(0), amountPaid+(baseFee*numPayments)) 238 assertAmountPaid(t, "Alice(local) => Dave(remote)", net.Alice, 239 daveFundPoint, amountPaid+(baseFee*numPayments), int64(0)) 240 assertAmountPaid(t, "Bob(local) => Alice(remote)", net.Alice, 241 aliceFundPoint, int64(0), amountPaid+((baseFee*numPayments)*2)) 242 assertAmountPaid(t, "Bob(local) => Alice(remote)", net.Bob, 243 aliceFundPoint, amountPaid+(baseFee*numPayments)*2, int64(0)) 244 245 // Lastly, we will send one more payment to ensure all channels are 246 // still functioning properly. 247 finalInvoice := &lnrpc.Invoice{ 248 Memo: "testing", 249 Value: paymentAmt, 250 } 251 ctxt, _ := context.WithTimeout(ctxb, defaultTimeout) 252 resp, err := carol.AddInvoice(ctxt, finalInvoice) 253 if err != nil { 254 t.Fatalf("unable to add invoice: %v", err) 255 } 256 257 payReqs = []string{resp.PaymentRequest} 258 259 // Using Carol as the source, pay to the 5 invoices from Bob created 260 // above. 261 err = completePaymentRequests( 262 net.Bob, net.Bob.RouterClient, payReqs, true, 263 ) 264 if err != nil { 265 t.Fatalf("unable to send payments: %v", err) 266 } 267 268 amountPaid = int64(6000) 269 assertAmountPaid(t, "Dave(local) => Carol(remote)", carol, 270 carolFundPoint, int64(0), amountPaid) 271 assertAmountPaid(t, "Dave(local) => Carol(remote)", dave, 272 carolFundPoint, amountPaid, int64(0)) 273 assertAmountPaid(t, "Alice(local) => Dave(remote)", dave, 274 daveFundPoint, int64(0), amountPaid+(baseFee*(numPayments+1))) 275 assertAmountPaid(t, "Alice(local) => Dave(remote)", net.Alice, 276 daveFundPoint, amountPaid+(baseFee*(numPayments+1)), int64(0)) 277 assertAmountPaid(t, "Bob(local) => Alice(remote)", net.Alice, 278 aliceFundPoint, int64(0), amountPaid+((baseFee*(numPayments+1))*2)) 279 assertAmountPaid(t, "Bob(local) => Alice(remote)", net.Bob, 280 aliceFundPoint, amountPaid+(baseFee*(numPayments+1))*2, int64(0)) 281 282 closeChannelAndAssert(t, net, net.Alice, chanPointAlice, false) 283 closeChannelAndAssert(t, net, dave, chanPointDave, false) 284 closeChannelAndAssert(t, net, carol, chanPointCarol, false) 285 } 286 287 // testSwitchOfflineDelivery constructs a set of multihop payments, and tests 288 // that the returning payments are not lost if a peer on the backwards path is 289 // offline when the settle/fails are received. We expect the payments to be 290 // buffered in memory, and transmitted as soon as the disconnect link comes back 291 // online. 292 // 293 // The general flow of this test: 294 // 1. Carol --> Dave --> Alice --> Bob forward payment 295 // 2. Carol --- Dave X Alice --- Bob disconnect intermediaries 296 // 3. Carol --- Dave X Alice <-- Bob settle last hop 297 // 4. Carol <-- Dave <-- Alice --- Bob reconnect, expect settle to propagate 298 func testSwitchOfflineDelivery(net *lntest.NetworkHarness, t *harnessTest) { 299 ctxb := context.Background() 300 301 const chanAmt = dcrutil.Amount(1000000) 302 const pushAmt = dcrutil.Amount(900000) 303 var networkChans []*lnrpc.ChannelPoint 304 305 // Open a channel with 100k atoms between Alice and Bob with Alice 306 // being the sole funder of the channel. 307 chanPointAlice := openChannelAndAssert( 308 t, net, net.Alice, net.Bob, 309 lntest.OpenChannelParams{ 310 Amt: chanAmt, 311 PushAmt: pushAmt, 312 }, 313 ) 314 networkChans = append(networkChans, chanPointAlice) 315 316 aliceChanTXID, err := lnrpc.GetChanPointFundingTxid(chanPointAlice) 317 if err != nil { 318 t.Fatalf("unable to get txid: %v", err) 319 } 320 aliceFundPoint := wire.OutPoint{ 321 Hash: *aliceChanTXID, 322 Index: chanPointAlice.OutputIndex, 323 } 324 325 // As preliminary setup, we'll create two new nodes: Carol and Dave, 326 // such that we now have a 4 ndoe, 3 channel topology. Dave will make 327 // a channel with Alice, and Carol with Dave. After this setup, the 328 // network topology should now look like: 329 // Carol -> Dave -> Alice -> Bob 330 // 331 // First, we'll create Dave and establish a channel to Alice. 332 dave := net.NewNode(t.t, "Dave", nil) 333 defer shutdownAndAssert(net, t, dave) 334 335 net.ConnectNodes(t.t, dave, net.Alice) 336 net.SendCoins(t.t, dcrutil.AtomsPerCoin, dave) 337 338 chanPointDave := openChannelAndAssert( 339 t, net, dave, net.Alice, 340 lntest.OpenChannelParams{ 341 Amt: chanAmt, 342 PushAmt: pushAmt, 343 }, 344 ) 345 networkChans = append(networkChans, chanPointDave) 346 daveChanTXID, err := lnrpc.GetChanPointFundingTxid(chanPointDave) 347 if err != nil { 348 t.Fatalf("unable to get txid: %v", err) 349 } 350 daveFundPoint := wire.OutPoint{ 351 Hash: *daveChanTXID, 352 Index: chanPointDave.OutputIndex, 353 } 354 355 // Next, we'll create Carol and establish a channel to from her to 356 // Dave. Carol is started in htlchodl mode so that we can disconnect the 357 // intermediary hops before starting the settle. 358 carol := net.NewNode(t.t, "Carol", []string{"--hodl.exit-settle", 359 "--nolisten"}) 360 defer shutdownAndAssert(net, t, carol) 361 362 net.ConnectNodes(t.t, carol, dave) 363 net.SendCoins(t.t, dcrutil.AtomsPerCoin, carol) 364 365 chanPointCarol := openChannelAndAssert( 366 t, net, carol, dave, 367 lntest.OpenChannelParams{ 368 Amt: chanAmt, 369 PushAmt: pushAmt, 370 }, 371 ) 372 networkChans = append(networkChans, chanPointCarol) 373 374 carolChanTXID, err := lnrpc.GetChanPointFundingTxid(chanPointCarol) 375 if err != nil { 376 t.Fatalf("unable to get txid: %v", err) 377 } 378 carolFundPoint := wire.OutPoint{ 379 Hash: *carolChanTXID, 380 Index: chanPointCarol.OutputIndex, 381 } 382 383 // Wait for all nodes to have seen all channels. 384 nodes := []*lntest.HarnessNode{net.Alice, net.Bob, carol, dave} 385 nodeNames := []string{"Alice", "Bob", "Carol", "Dave"} 386 for _, chanPoint := range networkChans { 387 for i, node := range nodes { 388 txid, err := lnrpc.GetChanPointFundingTxid(chanPoint) 389 if err != nil { 390 t.Fatalf("unable to get txid: %v", err) 391 } 392 point := wire.OutPoint{ 393 Hash: *txid, 394 Index: chanPoint.OutputIndex, 395 } 396 397 err = node.WaitForNetworkChannelOpen(chanPoint) 398 if err != nil { 399 t.Fatalf("%s(%d): timeout waiting for "+ 400 "channel(%s) open: %v", nodeNames[i], 401 node.NodeID, point, err) 402 } 403 } 404 } 405 406 // Create 5 invoices for Carol, which expect a payment from Bob for 1k 407 // atoms with a different preimage each time. 408 const numPayments = 5 409 const paymentAmt = 1000 410 payReqs, _, _, err := createPayReqs( 411 carol, paymentAmt, numPayments, 412 ) 413 if err != nil { 414 t.Fatalf("unable to create pay reqs: %v", err) 415 } 416 417 // We'll wait for all parties to recognize the new channels within the 418 // network. 419 err = dave.WaitForNetworkChannelOpen(chanPointDave) 420 if err != nil { 421 t.Fatalf("dave didn't advertise his channel: %v", err) 422 } 423 err = carol.WaitForNetworkChannelOpen(chanPointCarol) 424 if err != nil { 425 t.Fatalf("carol didn't advertise her channel in time: %v", 426 err) 427 } 428 429 // Make sure all nodes are fully synced before we continue. 430 for _, node := range nodes { 431 err := node.WaitForBlockchainSync() 432 if err != nil { 433 t.Fatalf("unable to wait for sync: %v", err) 434 } 435 } 436 437 // Using Carol as the source, pay to the 5 invoices from Bob created 438 // above. 439 err = completePaymentRequests( 440 net.Bob, net.Bob.RouterClient, payReqs, false, 441 ) 442 if err != nil { 443 t.Fatalf("unable to send payments: %v", err) 444 } 445 446 // Wait for all of the payments to reach Carol. 447 var predErr error 448 err = wait.Predicate(func() bool { 449 predErr = assertNumActiveHtlcs(nodes, numPayments) 450 return predErr == nil 451 }, defaultTimeout) 452 if err != nil { 453 t.Fatalf("htlc mismatch: %v", predErr) 454 } 455 456 peerReq := &lnrpc.PeerEventSubscription{} 457 peerClient, err := dave.SubscribePeerEvents(ctxb, peerReq) 458 require.NoError(t.t, err) 459 460 // First, disconnect Dave and Alice so that their link is broken. 461 if err := net.DisconnectNodes(dave, net.Alice); err != nil { 462 t.Fatalf("unable to disconnect alice from dave: %v", err) 463 } 464 465 // Wait to receive the PEER_OFFLINE event before reconnecting them. 466 peerEvent, err := peerClient.Recv() 467 require.NoError(t.t, err) 468 require.Equal(t.t, lnrpc.PeerEvent_PEER_OFFLINE, peerEvent.GetType()) 469 470 // Then, reconnect them to ensure Dave doesn't just fail back the htlc. 471 net.ConnectNodes(t.t, dave, net.Alice) 472 473 // Wait to ensure that the payment remain are not failed back after 474 // reconnecting. All node should report the number payments initiated 475 // for the duration of the interval. 476 err = wait.Invariant(func() bool { 477 predErr = assertNumActiveHtlcs(nodes, numPayments) 478 return predErr == nil 479 }, defaultTimeout) 480 if err != nil { 481 t.Fatalf("htlc change: %v", predErr) 482 } 483 484 // Now, disconnect Dave from Alice again before settling back the 485 // payment. 486 if err := net.DisconnectNodes(dave, net.Alice); err != nil { 487 t.Fatalf("unable to disconnect alice from dave: %v", err) 488 } 489 490 // Wait to receive the PEER_ONLINE and then the PEER_OFFLINE event 491 // before advancing. 492 peerEvent2, err := peerClient.Recv() 493 require.NoError(t.t, err) 494 require.Equal(t.t, lnrpc.PeerEvent_PEER_ONLINE, peerEvent2.GetType()) 495 496 peerEvent3, err := peerClient.Recv() 497 require.NoError(t.t, err) 498 require.Equal(t.t, lnrpc.PeerEvent_PEER_OFFLINE, peerEvent3.GetType()) 499 500 // Now restart carol without hodl mode, to settle back the outstanding 501 // payments. 502 carol.SetExtraArgs(nil) 503 if err := net.RestartNode(carol, nil); err != nil { 504 t.Fatalf("Node restart failed: %v", err) 505 } 506 507 // Wait for Carol to report no outstanding htlcs. 508 carolNode := []*lntest.HarnessNode{carol} 509 err = wait.Predicate(func() bool { 510 predErr = assertNumActiveHtlcs(carolNode, 0) 511 return predErr == nil 512 }, defaultTimeout) 513 if err != nil { 514 t.Fatalf("htlc mismatch: %v", predErr) 515 } 516 517 // Make sure all nodes are fully synced again. 518 for _, node := range nodes { 519 err := node.WaitForBlockchainSync() 520 if err != nil { 521 t.Fatalf("unable to wait for sync: %v", err) 522 } 523 } 524 525 // Now that the settles have reached Dave, reconnect him with Alice, 526 // allowing the settles to return to the sender. 527 net.EnsureConnected(t.t, dave, net.Alice) 528 529 // Wait until all outstanding htlcs in the network have been settled. 530 err = wait.Predicate(func() bool { 531 return assertNumActiveHtlcs(nodes, 0) == nil 532 }, defaultTimeout) 533 if err != nil { 534 t.Fatalf("htlc mismatch: %v", predErr) 535 } 536 537 // When asserting the amount of atoms moved, we'll factor in the 538 // default base fee, as we didn't modify the fee structure when 539 // creating the seed nodes in the network. 540 const baseFee = 1 541 542 // At this point all the channels within our proto network should be 543 // shifted by 5k atoms in the direction of Carol, the sink within the 544 // payment flow generated above. The order of asserts corresponds to 545 // increasing of time is needed to embed the HTLC in commitment 546 // transaction, in channel Bob->Alice->David->Carol, order is Carol, 547 // David, Alice, Bob. 548 var amountPaid = int64(5000) 549 assertAmountPaid(t, "Dave(local) => Carol(remote)", carol, 550 carolFundPoint, int64(0), amountPaid) 551 assertAmountPaid(t, "Dave(local) => Carol(remote)", dave, 552 carolFundPoint, amountPaid, int64(0)) 553 assertAmountPaid(t, "Alice(local) => Dave(remote)", dave, 554 daveFundPoint, int64(0), amountPaid+(baseFee*numPayments)) 555 assertAmountPaid(t, "Alice(local) => Dave(remote)", net.Alice, 556 daveFundPoint, amountPaid+(baseFee*numPayments), int64(0)) 557 assertAmountPaid(t, "Bob(local) => Alice(remote)", net.Alice, 558 aliceFundPoint, int64(0), amountPaid+((baseFee*numPayments)*2)) 559 assertAmountPaid(t, "Bob(local) => Alice(remote)", net.Bob, 560 aliceFundPoint, amountPaid+(baseFee*numPayments)*2, int64(0)) 561 562 // Ensure Carol and Dave are connected so the final payment will 563 // complete. 564 net.EnsureConnected(t.t, carol, dave) 565 566 // Lastly, we will send one more payment to ensure all channels are 567 // still functioning properly. 568 finalInvoice := &lnrpc.Invoice{ 569 Memo: "testing", 570 Value: paymentAmt, 571 } 572 ctxt, _ := context.WithTimeout(ctxb, defaultTimeout) 573 resp, err := carol.AddInvoice(ctxt, finalInvoice) 574 if err != nil { 575 t.Fatalf("unable to add invoice: %v", err) 576 } 577 578 payReqs = []string{resp.PaymentRequest} 579 580 // Using Carol as the source, pay to the 5 invoices from Bob created 581 // above. 582 err = completePaymentRequests( 583 net.Bob, net.Bob.RouterClient, payReqs, true, 584 ) 585 if err != nil { 586 t.Fatalf("unable to send payments: %v", err) 587 } 588 589 amountPaid = int64(6000) 590 assertAmountPaid(t, "Dave(local) => Carol(remote)", carol, 591 carolFundPoint, int64(0), amountPaid) 592 assertAmountPaid(t, "Dave(local) => Carol(remote)", dave, 593 carolFundPoint, amountPaid, int64(0)) 594 assertAmountPaid(t, "Alice(local) => Dave(remote)", dave, 595 daveFundPoint, int64(0), amountPaid+(baseFee*(numPayments+1))) 596 assertAmountPaid(t, "Alice(local) => Dave(remote)", net.Alice, 597 daveFundPoint, amountPaid+(baseFee*(numPayments+1)), int64(0)) 598 assertAmountPaid(t, "Bob(local) => Alice(remote)", net.Alice, 599 aliceFundPoint, int64(0), amountPaid+((baseFee*(numPayments+1))*2)) 600 assertAmountPaid(t, "Bob(local) => Alice(remote)", net.Bob, 601 aliceFundPoint, amountPaid+(baseFee*(numPayments+1))*2, int64(0)) 602 603 closeChannelAndAssert(t, net, net.Alice, chanPointAlice, false) 604 closeChannelAndAssert(t, net, dave, chanPointDave, false) 605 closeChannelAndAssert(t, net, carol, chanPointCarol, false) 606 } 607 608 // testSwitchOfflineDeliveryPersistence constructs a set of multihop payments, 609 // and tests that the returning payments are not lost if a peer on the backwards 610 // path is offline when the settle/fails are received AND the peer buffering the 611 // responses is completely restarts. We expect the payments to be reloaded from 612 // disk, and transmitted as soon as the intermediaries are reconnected. 613 // 614 // The general flow of this test: 615 // 1. Carol --> Dave --> Alice --> Bob forward payment 616 // 2. Carol --- Dave X Alice --- Bob disconnect intermediaries 617 // 3. Carol --- Dave X Alice <-- Bob settle last hop 618 // 4. Carol --- Dave X X Bob restart Alice 619 // 5. Carol <-- Dave <-- Alice --- Bob expect settle to propagate 620 func testSwitchOfflineDeliveryPersistence(net *lntest.NetworkHarness, t *harnessTest) { 621 ctxb := context.Background() 622 623 const chanAmt = dcrutil.Amount(1000000) 624 const pushAmt = dcrutil.Amount(900000) 625 var networkChans []*lnrpc.ChannelPoint 626 627 // Open a channel with 100k atoms between Alice and Bob with Alice 628 // being the sole funder of the channel. 629 chanPointAlice := openChannelAndAssert( 630 t, net, net.Alice, net.Bob, 631 lntest.OpenChannelParams{ 632 Amt: chanAmt, 633 PushAmt: pushAmt, 634 }, 635 ) 636 networkChans = append(networkChans, chanPointAlice) 637 638 aliceChanTXID, err := lnrpc.GetChanPointFundingTxid(chanPointAlice) 639 if err != nil { 640 t.Fatalf("unable to get txid: %v", err) 641 } 642 aliceFundPoint := wire.OutPoint{ 643 Hash: *aliceChanTXID, 644 Index: chanPointAlice.OutputIndex, 645 } 646 647 // As preliminary setup, we'll create two new nodes: Carol and Dave, 648 // such that we now have a 4 ndoe, 3 channel topology. Dave will make 649 // a channel with Alice, and Carol with Dave. After this setup, the 650 // network topology should now look like: 651 // Carol -> Dave -> Alice -> Bob 652 // 653 // First, we'll create Dave and establish a channel to Alice. 654 dave := net.NewNode(t.t, "Dave", nil) 655 defer shutdownAndAssert(net, t, dave) 656 657 net.ConnectNodes(t.t, dave, net.Alice) 658 net.SendCoins(t.t, dcrutil.AtomsPerCoin, dave) 659 660 chanPointDave := openChannelAndAssert( 661 t, net, dave, net.Alice, 662 lntest.OpenChannelParams{ 663 Amt: chanAmt, 664 PushAmt: pushAmt, 665 }, 666 ) 667 668 networkChans = append(networkChans, chanPointDave) 669 daveChanTXID, err := lnrpc.GetChanPointFundingTxid(chanPointDave) 670 if err != nil { 671 t.Fatalf("unable to get txid: %v", err) 672 } 673 daveFundPoint := wire.OutPoint{ 674 Hash: *daveChanTXID, 675 Index: chanPointDave.OutputIndex, 676 } 677 678 // Next, we'll create Carol and establish a channel to from her to 679 // Dave. Carol is started in htlchodl mode so that we can disconnect the 680 // intermediary hops before starting the settle. 681 carol := net.NewNode(t.t, "Carol", []string{"--hodl.exit-settle"}) 682 defer shutdownAndAssert(net, t, carol) 683 684 net.ConnectNodes(t.t, carol, dave) 685 net.SendCoins(t.t, dcrutil.AtomsPerCoin, carol) 686 687 chanPointCarol := openChannelAndAssert( 688 t, net, carol, dave, 689 lntest.OpenChannelParams{ 690 Amt: chanAmt, 691 PushAmt: pushAmt, 692 }, 693 ) 694 networkChans = append(networkChans, chanPointCarol) 695 696 carolChanTXID, err := lnrpc.GetChanPointFundingTxid(chanPointCarol) 697 if err != nil { 698 t.Fatalf("unable to get txid: %v", err) 699 } 700 carolFundPoint := wire.OutPoint{ 701 Hash: *carolChanTXID, 702 Index: chanPointCarol.OutputIndex, 703 } 704 705 // Wait for all nodes to have seen all channels. 706 nodes := []*lntest.HarnessNode{net.Alice, net.Bob, carol, dave} 707 nodeNames := []string{"Alice", "Bob", "Carol", "Dave"} 708 for _, chanPoint := range networkChans { 709 for i, node := range nodes { 710 txid, err := lnrpc.GetChanPointFundingTxid(chanPoint) 711 if err != nil { 712 t.Fatalf("unable to get txid: %v", err) 713 } 714 point := wire.OutPoint{ 715 Hash: *txid, 716 Index: chanPoint.OutputIndex, 717 } 718 719 err = node.WaitForNetworkChannelOpen(chanPoint) 720 if err != nil { 721 t.Fatalf("%s(%d): timeout waiting for "+ 722 "channel(%s) open: %v", nodeNames[i], 723 node.NodeID, point, err) 724 } 725 } 726 } 727 728 // Create 5 invoices for Carol, which expect a payment from Bob for 1k 729 // atoms with a different preimage each time. 730 const numPayments = 5 731 const paymentAmt = 1000 732 payReqs, _, _, err := createPayReqs( 733 carol, paymentAmt, numPayments, 734 ) 735 if err != nil { 736 t.Fatalf("unable to create pay reqs: %v", err) 737 } 738 739 // We'll wait for all parties to recognize the new channels within the 740 // network. 741 err = dave.WaitForNetworkChannelOpen(chanPointDave) 742 if err != nil { 743 t.Fatalf("dave didn't advertise his channel: %v", err) 744 } 745 err = carol.WaitForNetworkChannelOpen(chanPointCarol) 746 if err != nil { 747 t.Fatalf("carol didn't advertise her channel in time: %v", 748 err) 749 } 750 751 // Using Carol as the source, pay to the 5 invoices from Bob created 752 // above. 753 err = completePaymentRequests( 754 net.Bob, net.Bob.RouterClient, payReqs, false, 755 ) 756 if err != nil { 757 t.Fatalf("unable to send payments: %v", err) 758 } 759 760 var predErr error 761 err = wait.Predicate(func() bool { 762 predErr = assertNumActiveHtlcs(nodes, numPayments) 763 return predErr == nil 764 }, defaultTimeout) 765 if err != nil { 766 t.Fatalf("htlc mismatch: %v", predErr) 767 } 768 769 // Disconnect the two intermediaries, Alice and Dave, by shutting down 770 // Alice. 771 if err := net.StopNode(net.Alice); err != nil { 772 t.Fatalf("unable to shutdown alice: %v", err) 773 } 774 775 // Now restart carol without hodl mode, to settle back the outstanding 776 // payments. 777 carol.SetExtraArgs(nil) 778 if err := net.RestartNode(carol, nil); err != nil { 779 t.Fatalf("Node restart failed: %v", err) 780 } 781 782 // Make Carol and Dave are reconnected before waiting for the htlcs to 783 // clear. 784 net.EnsureConnected(t.t, dave, carol) 785 786 // Wait for Carol to report no outstanding htlcs, and also for Dav to 787 // receive all the settles from Carol. 788 carolNode := []*lntest.HarnessNode{carol} 789 err = wait.Predicate(func() bool { 790 predErr = assertNumActiveHtlcs(carolNode, 0) 791 if predErr != nil { 792 return false 793 } 794 795 predErr = assertNumActiveHtlcsChanPoint(dave, carolFundPoint, 0) 796 return predErr == nil 797 }, defaultTimeout) 798 if err != nil { 799 t.Fatalf("htlc mismatch: %v", predErr) 800 } 801 802 // Finally, restart dave who received the settles, but was unable to 803 // deliver them to Alice since they were disconnected. 804 if err := net.RestartNode(dave, nil); err != nil { 805 t.Fatalf("unable to restart dave: %v", err) 806 } 807 if err = net.RestartNode(net.Alice, nil); err != nil { 808 t.Fatalf("unable to restart alice: %v", err) 809 } 810 811 // Force Dave and Alice to reconnect before waiting for the htlcs to 812 // clear. 813 net.EnsureConnected(t.t, dave, net.Alice) 814 815 // Also ensure Alice and Bob have reconnected. 816 net.EnsureConnected(t.t, net.Alice, net.Bob) 817 818 // After reconnection succeeds, the settles should be propagated all 819 // the way back to the sender. All nodes should report no active htlcs. 820 err = wait.Predicate(func() bool { 821 return assertNumActiveHtlcs(nodes, 0) == nil 822 }, defaultTimeout) 823 if err != nil { 824 t.Fatalf("htlc mismatch: %v", predErr) 825 } 826 827 // When asserting the amount of atoms moved, we'll factor in the 828 // default base fee, as we didn't modify the fee structure when 829 // creating the seed nodes in the network. 830 const baseFee = 1 831 832 // At this point all the channels within our proto network should be 833 // shifted by 5k atoms in the direction of Carol, the sink within the 834 // payment flow generated above. The order of asserts corresponds to 835 // increasing of time is needed to embed the HTLC in commitment 836 // transaction, in channel Bob->Alice->David->Carol, order is Carol, 837 // David, Alice, Bob. 838 var amountPaid = int64(5000) 839 assertAmountPaid(t, "Dave(local) => Carol(remote)", carol, 840 carolFundPoint, int64(0), amountPaid) 841 assertAmountPaid(t, "Dave(local) => Carol(remote)", dave, 842 carolFundPoint, amountPaid, int64(0)) 843 assertAmountPaid(t, "Alice(local) => Dave(remote)", dave, 844 daveFundPoint, int64(0), amountPaid+(baseFee*numPayments)) 845 assertAmountPaid(t, "Alice(local) => Dave(remote)", net.Alice, 846 daveFundPoint, amountPaid+(baseFee*numPayments), int64(0)) 847 assertAmountPaid(t, "Bob(local) => Alice(remote)", net.Alice, 848 aliceFundPoint, int64(0), amountPaid+((baseFee*numPayments)*2)) 849 assertAmountPaid(t, "Bob(local) => Alice(remote)", net.Bob, 850 aliceFundPoint, amountPaid+(baseFee*numPayments)*2, int64(0)) 851 852 // Before completing the final payment request, ensure that the 853 // connection between Dave and Carol has been healed. 854 net.EnsureConnected(t.t, dave, carol) 855 856 // Lastly, we will send one more payment to ensure all channels are 857 // still functioning properly. 858 finalInvoice := &lnrpc.Invoice{ 859 Memo: "testing", 860 Value: paymentAmt, 861 } 862 ctxt, _ := context.WithTimeout(ctxb, defaultTimeout) 863 resp, err := carol.AddInvoice(ctxt, finalInvoice) 864 if err != nil { 865 t.Fatalf("unable to add invoice: %v", err) 866 } 867 868 payReqs = []string{resp.PaymentRequest} 869 870 // Before completing the final payment request, ensure that the 871 // connection between Dave and Carol has been healed. 872 net.EnsureConnected(t.t, dave, carol) 873 874 // Using Carol as the source, pay to the 5 invoices from Bob created 875 // above. 876 err = completePaymentRequests( 877 net.Bob, net.Bob.RouterClient, payReqs, true, 878 ) 879 if err != nil { 880 t.Fatalf("unable to send payments: %v", err) 881 } 882 883 amountPaid = int64(6000) 884 assertAmountPaid(t, "Dave(local) => Carol(remote)", carol, 885 carolFundPoint, int64(0), amountPaid) 886 assertAmountPaid(t, "Dave(local) => Carol(remote)", dave, 887 carolFundPoint, amountPaid, int64(0)) 888 assertAmountPaid(t, "Alice(local) => Dave(remote)", dave, 889 daveFundPoint, int64(0), amountPaid+(baseFee*(numPayments+1))) 890 assertAmountPaid(t, "Alice(local) => Dave(remote)", net.Alice, 891 daveFundPoint, amountPaid+(baseFee*(numPayments+1)), int64(0)) 892 assertAmountPaid(t, "Bob(local) => Alice(remote)", net.Alice, 893 aliceFundPoint, int64(0), amountPaid+((baseFee*(numPayments+1))*2)) 894 assertAmountPaid(t, "Bob(local) => Alice(remote)", net.Bob, 895 aliceFundPoint, amountPaid+(baseFee*(numPayments+1))*2, int64(0)) 896 897 closeChannelAndAssert(t, net, net.Alice, chanPointAlice, false) 898 closeChannelAndAssert(t, net, dave, chanPointDave, false) 899 closeChannelAndAssert(t, net, carol, chanPointCarol, false) 900 } 901 902 // testSwitchOfflineDeliveryOutgoingOffline constructs a set of multihop payments, 903 // and tests that the returning payments are not lost if a peer on the backwards 904 // path is offline when the settle/fails are received AND the peer buffering the 905 // responses is completely restarts. We expect the payments to be reloaded from 906 // disk, and transmitted as soon as the intermediaries are reconnected. 907 // 908 // The general flow of this test: 909 // 1. Carol --> Dave --> Alice --> Bob forward payment 910 // 2. Carol --- Dave X Alice --- Bob disconnect intermediaries 911 // 3. Carol --- Dave X Alice <-- Bob settle last hop 912 // 4. Carol --- Dave X X shutdown Bob, restart Alice 913 // 5. Carol <-- Dave <-- Alice X expect settle to propagate 914 func testSwitchOfflineDeliveryOutgoingOffline( 915 net *lntest.NetworkHarness, t *harnessTest) { 916 917 const chanAmt = dcrutil.Amount(1000000) 918 const pushAmt = dcrutil.Amount(900000) 919 var networkChans []*lnrpc.ChannelPoint 920 921 // Open a channel with 100k atoms between Alice and Bob with Alice 922 // being the sole funder of the channel. 923 chanPointAlice := openChannelAndAssert( 924 t, net, net.Alice, net.Bob, 925 lntest.OpenChannelParams{ 926 Amt: chanAmt, 927 PushAmt: pushAmt, 928 }, 929 ) 930 networkChans = append(networkChans, chanPointAlice) 931 932 aliceChanTXID, err := lnrpc.GetChanPointFundingTxid(chanPointAlice) 933 if err != nil { 934 t.Fatalf("unable to get txid: %v", err) 935 } 936 aliceFundPoint := wire.OutPoint{ 937 Hash: *aliceChanTXID, 938 Index: chanPointAlice.OutputIndex, 939 } 940 941 // As preliminary setup, we'll create two new nodes: Carol and Dave, 942 // such that we now have a 4 ndoe, 3 channel topology. Dave will make 943 // a channel with Alice, and Carol with Dave. After this setup, the 944 // network topology should now look like: 945 // Carol -> Dave -> Alice -> Bob 946 // 947 // First, we'll create Dave and establish a channel to Alice. 948 dave := net.NewNode(t.t, "Dave", nil) 949 defer shutdownAndAssert(net, t, dave) 950 951 net.ConnectNodes(t.t, dave, net.Alice) 952 net.SendCoins(t.t, dcrutil.AtomsPerCoin, dave) 953 954 chanPointDave := openChannelAndAssert( 955 t, net, dave, net.Alice, 956 lntest.OpenChannelParams{ 957 Amt: chanAmt, 958 PushAmt: pushAmt, 959 }, 960 ) 961 networkChans = append(networkChans, chanPointDave) 962 daveChanTXID, err := lnrpc.GetChanPointFundingTxid(chanPointDave) 963 if err != nil { 964 t.Fatalf("unable to get txid: %v", err) 965 } 966 daveFundPoint := wire.OutPoint{ 967 Hash: *daveChanTXID, 968 Index: chanPointDave.OutputIndex, 969 } 970 971 // Next, we'll create Carol and establish a channel to from her to 972 // Dave. Carol is started in htlchodl mode so that we can disconnect the 973 // intermediary hops before starting the settle. 974 carol := net.NewNode(t.t, "Carol", []string{"--hodl.exit-settle"}) 975 net.ConnectNodes(t.t, carol, dave) 976 net.SendCoins(t.t, dcrutil.AtomsPerCoin, carol) 977 978 chanPointCarol := openChannelAndAssert( 979 t, net, carol, dave, 980 lntest.OpenChannelParams{ 981 Amt: chanAmt, 982 PushAmt: pushAmt, 983 }, 984 ) 985 networkChans = append(networkChans, chanPointCarol) 986 987 carolChanTXID, err := lnrpc.GetChanPointFundingTxid(chanPointCarol) 988 if err != nil { 989 t.Fatalf("unable to get txid: %v", err) 990 } 991 carolFundPoint := wire.OutPoint{ 992 Hash: *carolChanTXID, 993 Index: chanPointCarol.OutputIndex, 994 } 995 996 // Wait for all nodes to have seen all channels. 997 nodes := []*lntest.HarnessNode{net.Alice, net.Bob, carol, dave} 998 nodeNames := []string{"Alice", "Bob", "Carol", "Dave"} 999 for _, chanPoint := range networkChans { 1000 for i, node := range nodes { 1001 txid, err := lnrpc.GetChanPointFundingTxid(chanPoint) 1002 if err != nil { 1003 t.Fatalf("unable to get txid: %v", err) 1004 } 1005 point := wire.OutPoint{ 1006 Hash: *txid, 1007 Index: chanPoint.OutputIndex, 1008 } 1009 1010 err = node.WaitForNetworkChannelOpen(chanPoint) 1011 if err != nil { 1012 t.Fatalf("%s(%d): timeout waiting for "+ 1013 "channel(%s) open: %v", nodeNames[i], 1014 node.NodeID, point, err) 1015 } 1016 } 1017 } 1018 1019 // Create 5 invoices for Carol, which expect a payment from Bob for 1k 1020 // atoms with a different preimage each time. 1021 const numPayments = 5 1022 const paymentAmt = 1000 1023 payReqs, _, _, err := createPayReqs( 1024 carol, paymentAmt, numPayments, 1025 ) 1026 if err != nil { 1027 t.Fatalf("unable to create pay reqs: %v", err) 1028 } 1029 1030 // We'll wait for all parties to recognize the new channels within the 1031 // network. 1032 err = dave.WaitForNetworkChannelOpen(chanPointDave) 1033 if err != nil { 1034 t.Fatalf("dave didn't advertise his channel: %v", err) 1035 } 1036 err = carol.WaitForNetworkChannelOpen(chanPointCarol) 1037 if err != nil { 1038 t.Fatalf("carol didn't advertise her channel in time: %v", 1039 err) 1040 } 1041 1042 // Using Carol as the source, pay to the 5 invoices from Bob created 1043 // above. 1044 err = completePaymentRequests( 1045 net.Bob, net.Bob.RouterClient, payReqs, false, 1046 ) 1047 if err != nil { 1048 t.Fatalf("unable to send payments: %v", err) 1049 } 1050 1051 // Wait for all payments to reach Carol. 1052 var predErr error 1053 err = wait.Predicate(func() bool { 1054 return assertNumActiveHtlcs(nodes, numPayments) == nil 1055 }, defaultTimeout) 1056 if err != nil { 1057 t.Fatalf("htlc mismatch: %v", predErr) 1058 } 1059 1060 // Disconnect the two intermediaries, Alice and Dave, so that when carol 1061 // restarts, the response will be held by Dave. 1062 if err := net.StopNode(net.Alice); err != nil { 1063 t.Fatalf("unable to shutdown alice: %v", err) 1064 } 1065 1066 // Now restart carol without hodl mode, to settle back the outstanding 1067 // payments. 1068 carol.SetExtraArgs(nil) 1069 if err := net.RestartNode(carol, nil); err != nil { 1070 t.Fatalf("Node restart failed: %v", err) 1071 } 1072 1073 // Wait for Carol to report no outstanding htlcs. 1074 carolNode := []*lntest.HarnessNode{carol} 1075 err = wait.Predicate(func() bool { 1076 predErr = assertNumActiveHtlcs(carolNode, 0) 1077 if predErr != nil { 1078 return false 1079 } 1080 1081 predErr = assertNumActiveHtlcsChanPoint(dave, carolFundPoint, 0) 1082 return predErr == nil 1083 }, defaultTimeout) 1084 if err != nil { 1085 t.Fatalf("htlc mismatch: %v", predErr) 1086 } 1087 1088 // Now check that the total amount was transferred from Dave to Carol. 1089 // The amount transferred should be exactly equal to the invoice total 1090 // payment amount, 5k atomssohis. 1091 const amountPaid = int64(5000) 1092 assertAmountPaid(t, "Dave(local) => Carol(remote)", carol, 1093 carolFundPoint, int64(0), amountPaid) 1094 assertAmountPaid(t, "Dave(local) => Carol(remote)", dave, 1095 carolFundPoint, amountPaid, int64(0)) 1096 1097 // Shutdown carol and leave her offline for the rest of the test. This 1098 // is critical, as we wish to see if Dave can propragate settles even if 1099 // the outgoing link is never revived. 1100 shutdownAndAssert(net, t, carol) 1101 1102 // Now restart Dave, ensuring he is both persisting the settles, and is 1103 // able to reforward them to Alice after recovering from a restart. 1104 if err := net.RestartNode(dave, nil); err != nil { 1105 t.Fatalf("unable to restart dave: %v", err) 1106 } 1107 if err = net.RestartNode(net.Alice, nil); err != nil { 1108 t.Fatalf("unable to restart alice: %v", err) 1109 } 1110 1111 // Ensure that Dave is reconnected to Alice before waiting for the 1112 // htlcs to clear. 1113 net.EnsureConnected(t.t, dave, net.Alice) 1114 1115 // Since Carol has been shutdown permanently, we will wait until all 1116 // other nodes in the network report no active htlcs. 1117 nodesMinusCarol := []*lntest.HarnessNode{net.Bob, net.Alice, dave} 1118 err = wait.Predicate(func() bool { 1119 predErr = assertNumActiveHtlcs(nodesMinusCarol, 0) 1120 return predErr == nil 1121 }, defaultTimeout) 1122 if err != nil { 1123 t.Fatalf("htlc mismatch: %v", predErr) 1124 } 1125 1126 // When asserting the amount of atoms moved, we'll factor in the 1127 // default base fee, as we didn't modify the fee structure when 1128 // creating the seed nodes in the network. 1129 const baseFee = 1 1130 1131 // At this point, all channels (minus Carol, who is shutdown) should 1132 // show a shift of 5k atoms towards Carol. The order of asserts 1133 // corresponds to increasing of time is needed to embed the HTLC in 1134 // commitment transaction, in channel Bob->Alice->David, order is 1135 // David, Alice, Bob. 1136 assertAmountPaid(t, "Alice(local) => Dave(remote)", dave, 1137 daveFundPoint, int64(0), amountPaid+(baseFee*numPayments)) 1138 assertAmountPaid(t, "Alice(local) => Dave(remote)", net.Alice, 1139 daveFundPoint, amountPaid+(baseFee*numPayments), int64(0)) 1140 assertAmountPaid(t, "Bob(local) => Alice(remote)", net.Alice, 1141 aliceFundPoint, int64(0), amountPaid+((baseFee*numPayments)*2)) 1142 assertAmountPaid(t, "Bob(local) => Alice(remote)", net.Bob, 1143 aliceFundPoint, amountPaid+(baseFee*numPayments)*2, int64(0)) 1144 1145 closeChannelAndAssert(t, net, net.Alice, chanPointAlice, false) 1146 closeChannelAndAssert(t, net, dave, chanPointDave, false) 1147 }