github.com/decred/dcrlnd@v0.7.6/htlcswitch/switch_test.go (about) 1 package htlcswitch 2 3 import ( 4 "crypto/rand" 5 "crypto/sha256" 6 "fmt" 7 "io" 8 "io/ioutil" 9 "reflect" 10 "testing" 11 "time" 12 13 "github.com/davecgh/go-spew/spew" 14 "github.com/decred/dcrd/chaincfg/chainhash" 15 "github.com/decred/dcrd/dcrutil/v4" 16 "github.com/decred/dcrlnd/channeldb" 17 "github.com/decred/dcrlnd/htlcswitch/hodl" 18 "github.com/decred/dcrlnd/htlcswitch/hop" 19 "github.com/decred/dcrlnd/lntypes" 20 "github.com/decred/dcrlnd/lnwire" 21 "github.com/decred/dcrlnd/ticker" 22 "github.com/stretchr/testify/require" 23 ) 24 25 var zeroCircuit = channeldb.CircuitKey{} 26 27 func genPreimage() ([32]byte, error) { 28 var preimage [32]byte 29 if _, err := io.ReadFull(rand.Reader, preimage[:]); err != nil { 30 return preimage, err 31 } 32 return preimage, nil 33 } 34 35 // TestSwitchAddDuplicateLink tests that the switch will reject duplicate links 36 // for both pending and live links. It also tests that we can successfully 37 // add a link after having removed it. 38 func TestSwitchAddDuplicateLink(t *testing.T) { 39 t.Parallel() 40 41 alicePeer, err := newMockServer( 42 t, "alice", testStartingHeight, nil, testDefaultDelta, 43 ) 44 if err != nil { 45 t.Fatalf("unable to create alice server: %v", err) 46 } 47 48 s, err := initSwitchWithDB(testStartingHeight, nil) 49 if err != nil { 50 t.Fatalf("unable to init switch: %v", err) 51 } 52 if err := s.Start(); err != nil { 53 t.Fatalf("unable to start switch: %v", err) 54 } 55 defer s.Stop() 56 57 chanID1, _, aliceChanID, _ := genIDs() 58 59 pendingChanID := lnwire.ShortChannelID{} 60 61 aliceChannelLink := newMockChannelLink( 62 s, chanID1, pendingChanID, alicePeer, false, 63 ) 64 if err := s.AddLink(aliceChannelLink); err != nil { 65 t.Fatalf("unable to add alice link: %v", err) 66 } 67 68 // Alice should have a pending link, adding again should fail. 69 if err := s.AddLink(aliceChannelLink); err == nil { 70 t.Fatalf("adding duplicate link should have failed") 71 } 72 73 // Update the short chan id of the channel, so that the link goes live. 74 aliceChannelLink.setLiveShortChanID(aliceChanID) 75 err = s.UpdateShortChanID(chanID1) 76 if err != nil { 77 t.Fatalf("unable to update alice short_chan_id: %v", err) 78 } 79 80 // Alice should have a live link, adding again should fail. 81 if err := s.AddLink(aliceChannelLink); err == nil { 82 t.Fatalf("adding duplicate link should have failed") 83 } 84 85 // Remove the live link to ensure the indexes are cleared. 86 s.RemoveLink(chanID1) 87 88 // Alice has no links, adding should succeed. 89 if err := s.AddLink(aliceChannelLink); err != nil { 90 t.Fatalf("unable to add alice link: %v", err) 91 } 92 } 93 94 // TestSwitchHasActiveLink tests the behavior of HasActiveLink, and asserts that 95 // it only returns true if a link's short channel id has confirmed (meaning the 96 // channel is no longer pending) and it's EligibleToForward method returns true, 97 // i.e. it has received FundingLocked from the remote peer. 98 func TestSwitchHasActiveLink(t *testing.T) { 99 t.Parallel() 100 101 alicePeer, err := newMockServer( 102 t, "alice", testStartingHeight, nil, testDefaultDelta, 103 ) 104 if err != nil { 105 t.Fatalf("unable to create alice server: %v", err) 106 } 107 108 s, err := initSwitchWithDB(testStartingHeight, nil) 109 if err != nil { 110 t.Fatalf("unable to init switch: %v", err) 111 } 112 if err := s.Start(); err != nil { 113 t.Fatalf("unable to start switch: %v", err) 114 } 115 defer s.Stop() 116 117 chanID1, _, aliceChanID, _ := genIDs() 118 119 pendingChanID := lnwire.ShortChannelID{} 120 121 aliceChannelLink := newMockChannelLink( 122 s, chanID1, pendingChanID, alicePeer, false, 123 ) 124 if err := s.AddLink(aliceChannelLink); err != nil { 125 t.Fatalf("unable to add alice link: %v", err) 126 } 127 128 // The link has been added, but it's still pending. HasActiveLink should 129 // return false since the link has not been added to the linkIndex 130 // containing live links. 131 if s.HasActiveLink(chanID1) { 132 t.Fatalf("link should not be active yet, still pending") 133 } 134 135 // Update the short chan id of the channel, so that the link goes live. 136 aliceChannelLink.setLiveShortChanID(aliceChanID) 137 err = s.UpdateShortChanID(chanID1) 138 if err != nil { 139 t.Fatalf("unable to update alice short_chan_id: %v", err) 140 } 141 142 // UpdateShortChanID will cause the mock link to become eligible to 143 // forward. However, we can simulate the event where the short chan id 144 // is confirmed, but funding locked has yet to be received by resetting 145 // the mock link's eligibility to false. 146 aliceChannelLink.eligible = false 147 148 // Now, even though the link has been added to the linkIndex because the 149 // short channel id has confirmed, we should still see HasActiveLink 150 // fail because EligibleToForward should return false. 151 if s.HasActiveLink(chanID1) { 152 t.Fatalf("link should not be active yet, still ineligible") 153 } 154 155 // Finally, simulate the link receiving funding locked by setting its 156 // eligibility to true. 157 aliceChannelLink.eligible = true 158 159 // The link should now be reported as active, since EligibleToForward 160 // returns true and the link is in the linkIndex. 161 if !s.HasActiveLink(chanID1) { 162 t.Fatalf("link should not be active now") 163 } 164 } 165 166 // TestSwitchSendPending checks the inability of htlc switch to forward adds 167 // over pending links, and the UpdateShortChanID makes a pending link live. 168 func TestSwitchSendPending(t *testing.T) { 169 t.Parallel() 170 171 alicePeer, err := newMockServer( 172 t, "alice", testStartingHeight, nil, testDefaultDelta, 173 ) 174 if err != nil { 175 t.Fatalf("unable to create alice server: %v", err) 176 } 177 178 bobPeer, err := newMockServer( 179 t, "bob", testStartingHeight, nil, testDefaultDelta, 180 ) 181 if err != nil { 182 t.Fatalf("unable to create bob server: %v", err) 183 } 184 185 s, err := initSwitchWithDB(testStartingHeight, nil) 186 if err != nil { 187 t.Fatalf("unable to init switch: %v", err) 188 } 189 if err := s.Start(); err != nil { 190 t.Fatalf("unable to start switch: %v", err) 191 } 192 defer s.Stop() 193 194 chanID1, chanID2, aliceChanID, bobChanID := genIDs() 195 196 pendingChanID := lnwire.ShortChannelID{} 197 198 aliceChannelLink := newMockChannelLink( 199 s, chanID1, pendingChanID, alicePeer, false, 200 ) 201 if err := s.AddLink(aliceChannelLink); err != nil { 202 t.Fatalf("unable to add alice link: %v", err) 203 } 204 205 bobChannelLink := newMockChannelLink( 206 s, chanID2, bobChanID, bobPeer, true, 207 ) 208 if err := s.AddLink(bobChannelLink); err != nil { 209 t.Fatalf("unable to add bob link: %v", err) 210 } 211 212 // Create request which should is being forwarded from Bob channel 213 // link to Alice channel link. 214 preimage, err := genPreimage() 215 if err != nil { 216 t.Fatalf("unable to generate preimage: %v", err) 217 } 218 rhash := sha256.Sum256(preimage[:]) 219 packet := &htlcPacket{ 220 incomingChanID: bobChanID, 221 incomingHTLCID: 0, 222 outgoingChanID: aliceChanID, 223 obfuscator: NewMockObfuscator(), 224 htlc: &lnwire.UpdateAddHTLC{ 225 PaymentHash: rhash, 226 Amount: 1, 227 }, 228 } 229 230 // Send the ADD packet, this should not be forwarded out to the link 231 // since there are no eligible links. 232 if err = s.ForwardPackets(nil, packet); err != nil { 233 t.Fatal(err) 234 } 235 select { 236 case p := <-bobChannelLink.packets: 237 if p.linkFailure != nil { 238 err = p.linkFailure 239 } 240 case <-time.After(time.Second): 241 t.Fatal("no timely reply from switch") 242 } 243 linkErr, ok := err.(*LinkError) 244 if !ok { 245 t.Fatalf("expected link error, got: %T", err) 246 } 247 if linkErr.WireMessage().Code() != lnwire.CodeUnknownNextPeer { 248 t.Fatalf("expected fail unknown next peer, got: %T", 249 linkErr.WireMessage().Code()) 250 } 251 252 // No message should be sent, since the packet was failed. 253 select { 254 case <-aliceChannelLink.packets: 255 t.Fatal("expected not to receive message") 256 case <-time.After(time.Second): 257 } 258 259 // Since the packet should have been failed, there should be no active 260 // circuits. 261 if s.circuits.NumOpen() != 0 { 262 t.Fatal("wrong amount of circuits") 263 } 264 265 // Now, update Alice's link with her final short channel id. This should 266 // move the link to the live state. 267 aliceChannelLink.setLiveShortChanID(aliceChanID) 268 err = s.UpdateShortChanID(chanID1) 269 if err != nil { 270 t.Fatalf("unable to update alice short_chan_id: %v", err) 271 } 272 273 // Increment the packet's HTLC index, so that it does not collide with 274 // the prior attempt. 275 packet.incomingHTLCID++ 276 277 // Handle the request and checks that bob channel link received it. 278 if err := s.ForwardPackets(nil, packet); err != nil { 279 t.Fatalf("unexpected forward failure: %v", err) 280 } 281 282 // Since Alice's link is now active, this packet should succeed. 283 select { 284 case <-aliceChannelLink.packets: 285 case <-time.After(time.Second): 286 t.Fatal("request was not propagated to alice") 287 } 288 } 289 290 // TestSwitchForward checks the ability of htlc switch to forward add/settle 291 // requests. 292 func TestSwitchForward(t *testing.T) { 293 t.Parallel() 294 295 alicePeer, err := newMockServer( 296 t, "alice", testStartingHeight, nil, testDefaultDelta, 297 ) 298 if err != nil { 299 t.Fatalf("unable to create alice server: %v", err) 300 } 301 bobPeer, err := newMockServer( 302 t, "bob", testStartingHeight, nil, testDefaultDelta, 303 ) 304 if err != nil { 305 t.Fatalf("unable to create bob server: %v", err) 306 } 307 308 s, err := initSwitchWithDB(testStartingHeight, nil) 309 if err != nil { 310 t.Fatalf("unable to init switch: %v", err) 311 } 312 if err := s.Start(); err != nil { 313 t.Fatalf("unable to start switch: %v", err) 314 } 315 defer s.Stop() 316 317 chanID1, chanID2, aliceChanID, bobChanID := genIDs() 318 319 aliceChannelLink := newMockChannelLink( 320 s, chanID1, aliceChanID, alicePeer, true, 321 ) 322 bobChannelLink := newMockChannelLink( 323 s, chanID2, bobChanID, bobPeer, true, 324 ) 325 if err := s.AddLink(aliceChannelLink); err != nil { 326 t.Fatalf("unable to add alice link: %v", err) 327 } 328 if err := s.AddLink(bobChannelLink); err != nil { 329 t.Fatalf("unable to add bob link: %v", err) 330 } 331 332 // Create request which should be forwarded from Alice channel link to 333 // bob channel link. 334 preimage, err := genPreimage() 335 if err != nil { 336 t.Fatalf("unable to generate preimage: %v", err) 337 } 338 rhash := sha256.Sum256(preimage[:]) 339 packet := &htlcPacket{ 340 incomingChanID: aliceChannelLink.ShortChanID(), 341 incomingHTLCID: 0, 342 outgoingChanID: bobChannelLink.ShortChanID(), 343 obfuscator: NewMockObfuscator(), 344 htlc: &lnwire.UpdateAddHTLC{ 345 PaymentHash: rhash, 346 Amount: 1, 347 }, 348 } 349 350 // Handle the request and checks that bob channel link received it. 351 if err := s.ForwardPackets(nil, packet); err != nil { 352 t.Fatal(err) 353 } 354 355 select { 356 case <-bobChannelLink.packets: 357 if err := bobChannelLink.completeCircuit(packet); err != nil { 358 t.Fatalf("unable to complete payment circuit: %v", err) 359 } 360 case <-time.After(time.Second): 361 t.Fatal("request was not propagated to destination") 362 } 363 364 if s.circuits.NumOpen() != 1 { 365 t.Fatal("wrong amount of circuits") 366 } 367 368 if !s.IsForwardedHTLC(bobChannelLink.ShortChanID(), 0) { 369 t.Fatal("htlc should be identified as forwarded") 370 } 371 372 // Create settle request pretending that bob link handled the add htlc 373 // request and sent the htlc settle request back. This request should 374 // be forwarder back to Alice link. 375 packet = &htlcPacket{ 376 outgoingChanID: bobChannelLink.ShortChanID(), 377 outgoingHTLCID: 0, 378 amount: 1, 379 htlc: &lnwire.UpdateFulfillHTLC{ 380 PaymentPreimage: preimage, 381 }, 382 } 383 384 // Handle the request and checks that payment circuit works properly. 385 if err := s.ForwardPackets(nil, packet); err != nil { 386 t.Fatal(err) 387 } 388 389 select { 390 case pkt := <-aliceChannelLink.packets: 391 if err := aliceChannelLink.deleteCircuit(pkt); err != nil { 392 t.Fatalf("unable to remove circuit: %v", err) 393 } 394 case <-time.After(time.Second): 395 t.Fatal("request was not propagated to channelPoint") 396 } 397 398 if s.circuits.NumOpen() != 0 { 399 t.Fatal("wrong amount of circuits") 400 } 401 } 402 403 func TestSwitchForwardFailAfterFullAdd(t *testing.T) { 404 t.Parallel() 405 406 chanID1, chanID2, aliceChanID, bobChanID := genIDs() 407 408 alicePeer, err := newMockServer( 409 t, "alice", testStartingHeight, nil, testDefaultDelta, 410 ) 411 if err != nil { 412 t.Fatalf("unable to create alice server: %v", err) 413 } 414 bobPeer, err := newMockServer( 415 t, "bob", testStartingHeight, nil, testDefaultDelta, 416 ) 417 if err != nil { 418 t.Fatalf("unable to create bob server: %v", err) 419 } 420 421 tempPath, err := ioutil.TempDir("", "circuitdb") 422 if err != nil { 423 t.Fatalf("unable to temporary path: %v", err) 424 } 425 426 cdb, err := channeldb.Open(tempPath) 427 if err != nil { 428 t.Fatalf("unable to open channeldb: %v", err) 429 } 430 431 s, err := initSwitchWithDB(testStartingHeight, cdb) 432 if err != nil { 433 t.Fatalf("unable to init switch: %v", err) 434 } 435 if err := s.Start(); err != nil { 436 t.Fatalf("unable to start switch: %v", err) 437 } 438 439 // Even though we intend to Stop s later in the test, it is safe to 440 // defer this Stop since its execution it is protected by an atomic 441 // guard, guaranteeing it executes at most once. 442 defer s.Stop() 443 444 aliceChannelLink := newMockChannelLink( 445 s, chanID1, aliceChanID, alicePeer, true, 446 ) 447 bobChannelLink := newMockChannelLink( 448 s, chanID2, bobChanID, bobPeer, true, 449 ) 450 if err := s.AddLink(aliceChannelLink); err != nil { 451 t.Fatalf("unable to add alice link: %v", err) 452 } 453 if err := s.AddLink(bobChannelLink); err != nil { 454 t.Fatalf("unable to add bob link: %v", err) 455 } 456 457 // Create request which should be forwarded from Alice channel link to 458 // bob channel link. 459 preimage := [chainhash.HashSize]byte{1} 460 rhash := sha256.Sum256(preimage[:]) 461 ogPacket := &htlcPacket{ 462 incomingChanID: aliceChannelLink.ShortChanID(), 463 incomingHTLCID: 0, 464 outgoingChanID: bobChannelLink.ShortChanID(), 465 obfuscator: NewMockObfuscator(), 466 htlc: &lnwire.UpdateAddHTLC{ 467 PaymentHash: rhash, 468 Amount: 1, 469 }, 470 } 471 472 if s.circuits.NumPending() != 0 { 473 t.Fatalf("wrong amount of half circuits") 474 } 475 if s.circuits.NumOpen() != 0 { 476 t.Fatalf("wrong amount of circuits") 477 } 478 479 // Handle the request and checks that bob channel link received it. 480 if err := s.ForwardPackets(nil, ogPacket); err != nil { 481 t.Fatal(err) 482 } 483 484 if s.circuits.NumPending() != 1 { 485 t.Fatalf("wrong amount of half circuits") 486 } 487 if s.circuits.NumOpen() != 0 { 488 t.Fatalf("wrong amount of circuits") 489 } 490 491 // Pull packet from bob's link, but do not perform a full add. 492 select { 493 case packet := <-bobChannelLink.packets: 494 // Complete the payment circuit and assign the outgoing htlc id 495 // before restarting. 496 if err := bobChannelLink.completeCircuit(packet); err != nil { 497 t.Fatalf("unable to complete payment circuit: %v", err) 498 } 499 500 case <-time.After(time.Second): 501 t.Fatal("request was not propagated to destination") 502 } 503 504 if s.circuits.NumPending() != 1 { 505 t.Fatalf("wrong amount of half circuits") 506 } 507 if s.circuits.NumOpen() != 1 { 508 t.Fatalf("wrong amount of circuits") 509 } 510 511 // Now we will restart bob, leaving the forwarding decision for this 512 // htlc is in the half-added state. 513 if err := s.Stop(); err != nil { 514 t.Fatalf(err.Error()) 515 } 516 517 if err := cdb.Close(); err != nil { 518 t.Fatalf(err.Error()) 519 } 520 521 cdb2, err := channeldb.Open(tempPath) 522 if err != nil { 523 t.Fatalf("unable to reopen channeldb: %v", err) 524 } 525 526 s2, err := initSwitchWithDB(testStartingHeight, cdb2) 527 if err != nil { 528 t.Fatalf("unable reinit switch: %v", err) 529 } 530 if err := s2.Start(); err != nil { 531 t.Fatalf("unable to restart switch: %v", err) 532 } 533 534 // Even though we intend to Stop s2 later in the test, it is safe to 535 // defer this Stop since its execution it is protected by an atomic 536 // guard, guaranteeing it executes at most once. 537 defer s2.Stop() 538 539 aliceChannelLink = newMockChannelLink( 540 s2, chanID1, aliceChanID, alicePeer, true, 541 ) 542 bobChannelLink = newMockChannelLink( 543 s2, chanID2, bobChanID, bobPeer, true, 544 ) 545 if err := s2.AddLink(aliceChannelLink); err != nil { 546 t.Fatalf("unable to add alice link: %v", err) 547 } 548 if err := s2.AddLink(bobChannelLink); err != nil { 549 t.Fatalf("unable to add bob link: %v", err) 550 } 551 552 if s2.circuits.NumPending() != 1 { 553 t.Fatalf("wrong amount of half circuits") 554 } 555 if s2.circuits.NumOpen() != 1 { 556 t.Fatalf("wrong amount of circuits") 557 } 558 559 // Craft a failure message from the remote peer. 560 fail := &htlcPacket{ 561 outgoingChanID: bobChannelLink.ShortChanID(), 562 outgoingHTLCID: 0, 563 amount: 1, 564 htlc: &lnwire.UpdateFailHTLC{}, 565 } 566 567 // Send the fail packet from the remote peer through the switch. 568 if err := s2.ForwardPackets(nil, fail); err != nil { 569 t.Fatalf(err.Error()) 570 } 571 572 // Pull packet from alice's link, as it should have gone through 573 // successfully. 574 select { 575 case pkt := <-aliceChannelLink.packets: 576 if err := aliceChannelLink.completeCircuit(pkt); err != nil { 577 t.Fatalf("unable to remove circuit: %v", err) 578 } 579 case <-time.After(time.Second): 580 t.Fatal("request was not propagated to destination") 581 } 582 583 // Circuit map should be empty now. 584 if s2.circuits.NumPending() != 0 { 585 t.Fatalf("wrong amount of half circuits") 586 } 587 if s2.circuits.NumOpen() != 0 { 588 t.Fatalf("wrong amount of circuits") 589 } 590 591 // Send the fail packet from the remote peer through the switch. 592 if err := s.ForwardPackets(nil, fail); err != nil { 593 t.Fatal(err) 594 } 595 select { 596 case <-aliceChannelLink.packets: 597 t.Fatalf("expected duplicate fail to not arrive at the destination") 598 case <-time.After(time.Second): 599 } 600 } 601 602 func TestSwitchForwardSettleAfterFullAdd(t *testing.T) { 603 t.Parallel() 604 605 chanID1, chanID2, aliceChanID, bobChanID := genIDs() 606 607 alicePeer, err := newMockServer( 608 t, "alice", testStartingHeight, nil, testDefaultDelta, 609 ) 610 if err != nil { 611 t.Fatalf("unable to create alice server: %v", err) 612 } 613 bobPeer, err := newMockServer( 614 t, "bob", testStartingHeight, nil, testDefaultDelta, 615 ) 616 if err != nil { 617 t.Fatalf("unable to create bob server: %v", err) 618 } 619 620 tempPath, err := ioutil.TempDir("", "circuitdb") 621 if err != nil { 622 t.Fatalf("unable to temporary path: %v", err) 623 } 624 625 cdb, err := channeldb.Open(tempPath) 626 if err != nil { 627 t.Fatalf("unable to open channeldb: %v", err) 628 } 629 630 s, err := initSwitchWithDB(testStartingHeight, cdb) 631 if err != nil { 632 t.Fatalf("unable to init switch: %v", err) 633 } 634 if err := s.Start(); err != nil { 635 t.Fatalf("unable to start switch: %v", err) 636 } 637 638 // Even though we intend to Stop s later in the test, it is safe to 639 // defer this Stop since its execution it is protected by an atomic 640 // guard, guaranteeing it executes at most once. 641 defer s.Stop() 642 643 aliceChannelLink := newMockChannelLink( 644 s, chanID1, aliceChanID, alicePeer, true, 645 ) 646 bobChannelLink := newMockChannelLink( 647 s, chanID2, bobChanID, bobPeer, true, 648 ) 649 if err := s.AddLink(aliceChannelLink); err != nil { 650 t.Fatalf("unable to add alice link: %v", err) 651 } 652 if err := s.AddLink(bobChannelLink); err != nil { 653 t.Fatalf("unable to add bob link: %v", err) 654 } 655 656 // Create request which should be forwarded from Alice channel link to 657 // bob channel link. 658 preimage := [chainhash.HashSize]byte{1} 659 rhash := sha256.Sum256(preimage[:]) 660 ogPacket := &htlcPacket{ 661 incomingChanID: aliceChannelLink.ShortChanID(), 662 incomingHTLCID: 0, 663 outgoingChanID: bobChannelLink.ShortChanID(), 664 obfuscator: NewMockObfuscator(), 665 htlc: &lnwire.UpdateAddHTLC{ 666 PaymentHash: rhash, 667 Amount: 1, 668 }, 669 } 670 671 if s.circuits.NumPending() != 0 { 672 t.Fatalf("wrong amount of half circuits") 673 } 674 if s.circuits.NumOpen() != 0 { 675 t.Fatalf("wrong amount of circuits") 676 } 677 678 // Handle the request and checks that bob channel link received it. 679 if err := s.ForwardPackets(nil, ogPacket); err != nil { 680 t.Fatal(err) 681 } 682 683 if s.circuits.NumPending() != 1 { 684 t.Fatalf("wrong amount of half circuits") 685 } 686 if s.circuits.NumOpen() != 0 { 687 t.Fatalf("wrong amount of circuits") 688 } 689 690 // Pull packet from bob's link, but do not perform a full add. 691 select { 692 case packet := <-bobChannelLink.packets: 693 // Complete the payment circuit and assign the outgoing htlc id 694 // before restarting. 695 if err := bobChannelLink.completeCircuit(packet); err != nil { 696 t.Fatalf("unable to complete payment circuit: %v", err) 697 } 698 699 case <-time.After(time.Second): 700 t.Fatal("request was not propagated to destination") 701 } 702 703 if s.circuits.NumPending() != 1 { 704 t.Fatalf("wrong amount of half circuits") 705 } 706 if s.circuits.NumOpen() != 1 { 707 t.Fatalf("wrong amount of circuits") 708 } 709 710 // Now we will restart bob, leaving the forwarding decision for this 711 // htlc is in the half-added state. 712 if err := s.Stop(); err != nil { 713 t.Fatalf(err.Error()) 714 } 715 716 if err := cdb.Close(); err != nil { 717 t.Fatalf(err.Error()) 718 } 719 720 cdb2, err := channeldb.Open(tempPath) 721 if err != nil { 722 t.Fatalf("unable to reopen channeldb: %v", err) 723 } 724 725 s2, err := initSwitchWithDB(testStartingHeight, cdb2) 726 if err != nil { 727 t.Fatalf("unable reinit switch: %v", err) 728 } 729 if err := s2.Start(); err != nil { 730 t.Fatalf("unable to restart switch: %v", err) 731 } 732 733 // Even though we intend to Stop s2 later in the test, it is safe to 734 // defer this Stop since its execution it is protected by an atomic 735 // guard, guaranteeing it executes at most once. 736 defer s2.Stop() 737 738 aliceChannelLink = newMockChannelLink( 739 s2, chanID1, aliceChanID, alicePeer, true, 740 ) 741 bobChannelLink = newMockChannelLink( 742 s2, chanID2, bobChanID, bobPeer, true, 743 ) 744 if err := s2.AddLink(aliceChannelLink); err != nil { 745 t.Fatalf("unable to add alice link: %v", err) 746 } 747 if err := s2.AddLink(bobChannelLink); err != nil { 748 t.Fatalf("unable to add bob link: %v", err) 749 } 750 751 if s2.circuits.NumPending() != 1 { 752 t.Fatalf("wrong amount of half circuits") 753 } 754 if s2.circuits.NumOpen() != 1 { 755 t.Fatalf("wrong amount of circuits") 756 } 757 758 // Craft a settle message from the remote peer. 759 settle := &htlcPacket{ 760 outgoingChanID: bobChannelLink.ShortChanID(), 761 outgoingHTLCID: 0, 762 amount: 1, 763 htlc: &lnwire.UpdateFulfillHTLC{ 764 PaymentPreimage: preimage, 765 }, 766 } 767 768 // Send the settle packet from the remote peer through the switch. 769 if err := s2.ForwardPackets(nil, settle); err != nil { 770 t.Fatalf(err.Error()) 771 } 772 773 // Pull packet from alice's link, as it should have gone through 774 // successfully. 775 select { 776 case packet := <-aliceChannelLink.packets: 777 if err := aliceChannelLink.completeCircuit(packet); err != nil { 778 t.Fatalf("unable to complete circuit with in key=%s: %v", 779 packet.inKey(), err) 780 } 781 case <-time.After(time.Second): 782 t.Fatal("request was not propagated to destination") 783 } 784 785 // Circuit map should be empty now. 786 if s2.circuits.NumPending() != 0 { 787 t.Fatalf("wrong amount of half circuits") 788 } 789 if s2.circuits.NumOpen() != 0 { 790 t.Fatalf("wrong amount of circuits") 791 } 792 793 // Send the settle packet again, which not arrive at destination. 794 if err := s2.ForwardPackets(nil, settle); err != nil { 795 t.Fatal(err) 796 } 797 select { 798 case <-bobChannelLink.packets: 799 t.Fatalf("expected duplicate fail to not arrive at the destination") 800 case <-time.After(time.Second): 801 } 802 } 803 804 func TestSwitchForwardDropAfterFullAdd(t *testing.T) { 805 t.Parallel() 806 807 chanID1, chanID2, aliceChanID, bobChanID := genIDs() 808 809 alicePeer, err := newMockServer( 810 t, "alice", testStartingHeight, nil, testDefaultDelta, 811 ) 812 if err != nil { 813 t.Fatalf("unable to create alice server: %v", err) 814 } 815 bobPeer, err := newMockServer( 816 t, "bob", testStartingHeight, nil, testDefaultDelta, 817 ) 818 if err != nil { 819 t.Fatalf("unable to create bob server: %v", err) 820 } 821 822 tempPath, err := ioutil.TempDir("", "circuitdb") 823 if err != nil { 824 t.Fatalf("unable to temporary path: %v", err) 825 } 826 827 cdb, err := channeldb.Open(tempPath) 828 if err != nil { 829 t.Fatalf("unable to open channeldb: %v", err) 830 } 831 832 s, err := initSwitchWithDB(testStartingHeight, cdb) 833 if err != nil { 834 t.Fatalf("unable to init switch: %v", err) 835 } 836 if err := s.Start(); err != nil { 837 t.Fatalf("unable to start switch: %v", err) 838 } 839 840 // Even though we intend to Stop s later in the test, it is safe to 841 // defer this Stop since its execution it is protected by an atomic 842 // guard, guaranteeing it executes at most once. 843 defer s.Stop() 844 845 aliceChannelLink := newMockChannelLink( 846 s, chanID1, aliceChanID, alicePeer, true, 847 ) 848 bobChannelLink := newMockChannelLink( 849 s, chanID2, bobChanID, bobPeer, true, 850 ) 851 if err := s.AddLink(aliceChannelLink); err != nil { 852 t.Fatalf("unable to add alice link: %v", err) 853 } 854 if err := s.AddLink(bobChannelLink); err != nil { 855 t.Fatalf("unable to add bob link: %v", err) 856 } 857 858 // Create request which should be forwarded from Alice channel link to 859 // bob channel link. 860 preimage := [chainhash.HashSize]byte{1} 861 rhash := sha256.Sum256(preimage[:]) 862 ogPacket := &htlcPacket{ 863 incomingChanID: aliceChannelLink.ShortChanID(), 864 incomingHTLCID: 0, 865 outgoingChanID: bobChannelLink.ShortChanID(), 866 obfuscator: NewMockObfuscator(), 867 htlc: &lnwire.UpdateAddHTLC{ 868 PaymentHash: rhash, 869 Amount: 1, 870 }, 871 } 872 873 if s.circuits.NumPending() != 0 { 874 t.Fatalf("wrong amount of half circuits") 875 } 876 if s.circuits.NumOpen() != 0 { 877 t.Fatalf("wrong amount of circuits") 878 } 879 880 // Handle the request and checks that bob channel link received it. 881 if err := s.ForwardPackets(nil, ogPacket); err != nil { 882 t.Fatal(err) 883 } 884 885 if s.circuits.NumPending() != 1 { 886 t.Fatalf("wrong amount of half circuits") 887 } 888 if s.circuits.NumOpen() != 0 { 889 t.Fatalf("wrong amount of half circuits") 890 } 891 892 // Pull packet from bob's link, but do not perform a full add. 893 select { 894 case packet := <-bobChannelLink.packets: 895 // Complete the payment circuit and assign the outgoing htlc id 896 // before restarting. 897 if err := bobChannelLink.completeCircuit(packet); err != nil { 898 t.Fatalf("unable to complete payment circuit: %v", err) 899 } 900 case <-time.After(time.Second): 901 t.Fatal("request was not propagated to destination") 902 } 903 904 // Now we will restart bob, leaving the forwarding decision for this 905 // htlc is in the half-added state. 906 if err := s.Stop(); err != nil { 907 t.Fatalf(err.Error()) 908 } 909 910 if err := cdb.Close(); err != nil { 911 t.Fatalf(err.Error()) 912 } 913 914 cdb2, err := channeldb.Open(tempPath) 915 if err != nil { 916 t.Fatalf("unable to reopen channeldb: %v", err) 917 } 918 919 s2, err := initSwitchWithDB(testStartingHeight, cdb2) 920 if err != nil { 921 t.Fatalf("unable reinit switch: %v", err) 922 } 923 if err := s2.Start(); err != nil { 924 t.Fatalf("unable to restart switch: %v", err) 925 } 926 927 // Even though we intend to Stop s2 later in the test, it is safe to 928 // defer this Stop since its execution it is protected by an atomic 929 // guard, guaranteeing it executes at most once. 930 defer s2.Stop() 931 932 aliceChannelLink = newMockChannelLink( 933 s2, chanID1, aliceChanID, alicePeer, true, 934 ) 935 bobChannelLink = newMockChannelLink( 936 s2, chanID2, bobChanID, bobPeer, true, 937 ) 938 if err := s2.AddLink(aliceChannelLink); err != nil { 939 t.Fatalf("unable to add alice link: %v", err) 940 } 941 if err := s2.AddLink(bobChannelLink); err != nil { 942 t.Fatalf("unable to add bob link: %v", err) 943 } 944 945 if s2.circuits.NumPending() != 1 { 946 t.Fatalf("wrong amount of half circuits") 947 } 948 if s2.circuits.NumOpen() != 1 { 949 t.Fatalf("wrong amount of half circuits") 950 } 951 952 // Resend the failed htlc. The packet will be dropped silently since the 953 // switch will detect that it has been half added previously. 954 if err := s2.ForwardPackets(nil, ogPacket); err != nil { 955 t.Fatal(err) 956 } 957 958 // After detecting an incomplete forward, the fail packet should have 959 // been returned to the sender. 960 select { 961 case <-aliceChannelLink.packets: 962 t.Fatal("request should not have returned to source") 963 case <-bobChannelLink.packets: 964 t.Fatal("request should not have forwarded to destination") 965 case <-time.After(time.Second): 966 } 967 } 968 969 func TestSwitchForwardFailAfterHalfAdd(t *testing.T) { 970 t.Parallel() 971 972 chanID1, chanID2, aliceChanID, bobChanID := genIDs() 973 974 alicePeer, err := newMockServer( 975 t, "alice", testStartingHeight, nil, testDefaultDelta, 976 ) 977 if err != nil { 978 t.Fatalf("unable to create alice server: %v", err) 979 } 980 bobPeer, err := newMockServer( 981 t, "bob", testStartingHeight, nil, testDefaultDelta, 982 ) 983 if err != nil { 984 t.Fatalf("unable to create bob server: %v", err) 985 } 986 987 tempPath, err := ioutil.TempDir("", "circuitdb") 988 if err != nil { 989 t.Fatalf("unable to temporary path: %v", err) 990 } 991 992 cdb, err := channeldb.Open(tempPath) 993 if err != nil { 994 t.Fatalf("unable to open channeldb: %v", err) 995 } 996 997 s, err := initSwitchWithDB(testStartingHeight, cdb) 998 if err != nil { 999 t.Fatalf("unable to init switch: %v", err) 1000 } 1001 if err := s.Start(); err != nil { 1002 t.Fatalf("unable to start switch: %v", err) 1003 } 1004 1005 // Even though we intend to Stop s later in the test, it is safe to 1006 // defer this Stop since its execution it is protected by an atomic 1007 // guard, guaranteeing it executes at most once. 1008 defer s.Stop() 1009 1010 aliceChannelLink := newMockChannelLink( 1011 s, chanID1, aliceChanID, alicePeer, true, 1012 ) 1013 bobChannelLink := newMockChannelLink( 1014 s, chanID2, bobChanID, bobPeer, true, 1015 ) 1016 if err := s.AddLink(aliceChannelLink); err != nil { 1017 t.Fatalf("unable to add alice link: %v", err) 1018 } 1019 if err := s.AddLink(bobChannelLink); err != nil { 1020 t.Fatalf("unable to add bob link: %v", err) 1021 } 1022 1023 // Create request which should be forwarded from Alice channel link to 1024 // bob channel link. 1025 preimage := [chainhash.HashSize]byte{1} 1026 rhash := sha256.Sum256(preimage[:]) 1027 ogPacket := &htlcPacket{ 1028 incomingChanID: aliceChannelLink.ShortChanID(), 1029 incomingHTLCID: 0, 1030 outgoingChanID: bobChannelLink.ShortChanID(), 1031 obfuscator: NewMockObfuscator(), 1032 htlc: &lnwire.UpdateAddHTLC{ 1033 PaymentHash: rhash, 1034 Amount: 1, 1035 }, 1036 } 1037 1038 if s.circuits.NumPending() != 0 { 1039 t.Fatalf("wrong amount of half circuits") 1040 } 1041 if s.circuits.NumOpen() != 0 { 1042 t.Fatalf("wrong amount of circuits") 1043 } 1044 1045 // Handle the request and checks that bob channel link received it. 1046 if err := s.ForwardPackets(nil, ogPacket); err != nil { 1047 t.Fatal(err) 1048 } 1049 1050 if s.circuits.NumPending() != 1 { 1051 t.Fatalf("wrong amount of half circuits") 1052 } 1053 if s.circuits.NumOpen() != 0 { 1054 t.Fatalf("wrong amount of half circuits") 1055 } 1056 1057 // Pull packet from bob's link, but do not perform a full add. 1058 select { 1059 case <-bobChannelLink.packets: 1060 case <-time.After(time.Second): 1061 t.Fatal("request was not propagated to destination") 1062 } 1063 1064 // Now we will restart bob, leaving the forwarding decision for this 1065 // htlc is in the half-added state. 1066 if err := s.Stop(); err != nil { 1067 t.Fatalf(err.Error()) 1068 } 1069 1070 if err := cdb.Close(); err != nil { 1071 t.Fatalf(err.Error()) 1072 } 1073 1074 cdb2, err := channeldb.Open(tempPath) 1075 if err != nil { 1076 t.Fatalf("unable to reopen channeldb: %v", err) 1077 } 1078 1079 s2, err := initSwitchWithDB(testStartingHeight, cdb2) 1080 if err != nil { 1081 t.Fatalf("unable reinit switch: %v", err) 1082 } 1083 if err := s2.Start(); err != nil { 1084 t.Fatalf("unable to restart switch: %v", err) 1085 } 1086 1087 // Even though we intend to Stop s2 later in the test, it is safe to 1088 // defer this Stop since its execution it is protected by an atomic 1089 // guard, guaranteeing it executes at most once. 1090 defer s2.Stop() 1091 1092 aliceChannelLink = newMockChannelLink( 1093 s2, chanID1, aliceChanID, alicePeer, true, 1094 ) 1095 bobChannelLink = newMockChannelLink( 1096 s2, chanID2, bobChanID, bobPeer, true, 1097 ) 1098 if err := s2.AddLink(aliceChannelLink); err != nil { 1099 t.Fatalf("unable to add alice link: %v", err) 1100 } 1101 if err := s2.AddLink(bobChannelLink); err != nil { 1102 t.Fatalf("unable to add bob link: %v", err) 1103 } 1104 1105 if s2.circuits.NumPending() != 1 { 1106 t.Fatalf("wrong amount of half circuits") 1107 } 1108 if s2.circuits.NumOpen() != 0 { 1109 t.Fatalf("wrong amount of half circuits") 1110 } 1111 1112 // Resend the failed htlc, it should be returned to alice since the 1113 // switch will detect that it has been half added previously. 1114 err = s2.ForwardPackets(nil, ogPacket) 1115 if err != nil { 1116 t.Fatal(err) 1117 } 1118 1119 // After detecting an incomplete forward, the fail packet should have 1120 // been returned to the sender. 1121 select { 1122 case pkt := <-aliceChannelLink.packets: 1123 linkErr := pkt.linkFailure 1124 if linkErr.FailureDetail != OutgoingFailureIncompleteForward { 1125 t.Fatalf("expected incomplete forward, got: %v", 1126 linkErr.FailureDetail) 1127 } 1128 case <-time.After(time.Second): 1129 t.Fatal("request was not propagated to destination") 1130 } 1131 } 1132 1133 // TestSwitchForwardCircuitPersistence checks the ability of htlc switch to 1134 // maintain the proper entries in the circuit map in the face of restarts. 1135 func TestSwitchForwardCircuitPersistence(t *testing.T) { 1136 t.Parallel() 1137 1138 chanID1, chanID2, aliceChanID, bobChanID := genIDs() 1139 1140 alicePeer, err := newMockServer( 1141 t, "alice", testStartingHeight, nil, testDefaultDelta, 1142 ) 1143 if err != nil { 1144 t.Fatalf("unable to create alice server: %v", err) 1145 } 1146 bobPeer, err := newMockServer( 1147 t, "bob", testStartingHeight, nil, testDefaultDelta, 1148 ) 1149 if err != nil { 1150 t.Fatalf("unable to create bob server: %v", err) 1151 } 1152 1153 tempPath, err := ioutil.TempDir("", "circuitdb") 1154 if err != nil { 1155 t.Fatalf("unable to temporary path: %v", err) 1156 } 1157 1158 cdb, err := channeldb.Open(tempPath) 1159 if err != nil { 1160 t.Fatalf("unable to open channeldb: %v", err) 1161 } 1162 1163 s, err := initSwitchWithDB(testStartingHeight, cdb) 1164 if err != nil { 1165 t.Fatalf("unable to init switch: %v", err) 1166 } 1167 if err := s.Start(); err != nil { 1168 t.Fatalf("unable to start switch: %v", err) 1169 } 1170 1171 // Even though we intend to Stop s later in the test, it is safe to 1172 // defer this Stop since its execution it is protected by an atomic 1173 // guard, guaranteeing it executes at most once. 1174 defer s.Stop() 1175 1176 aliceChannelLink := newMockChannelLink( 1177 s, chanID1, aliceChanID, alicePeer, true, 1178 ) 1179 bobChannelLink := newMockChannelLink( 1180 s, chanID2, bobChanID, bobPeer, true, 1181 ) 1182 if err := s.AddLink(aliceChannelLink); err != nil { 1183 t.Fatalf("unable to add alice link: %v", err) 1184 } 1185 if err := s.AddLink(bobChannelLink); err != nil { 1186 t.Fatalf("unable to add bob link: %v", err) 1187 } 1188 1189 // Create request which should be forwarded from Alice channel link to 1190 // bob channel link. 1191 preimage := [chainhash.HashSize]byte{1} 1192 rhash := sha256.Sum256(preimage[:]) 1193 ogPacket := &htlcPacket{ 1194 incomingChanID: aliceChannelLink.ShortChanID(), 1195 incomingHTLCID: 0, 1196 outgoingChanID: bobChannelLink.ShortChanID(), 1197 obfuscator: NewMockObfuscator(), 1198 htlc: &lnwire.UpdateAddHTLC{ 1199 PaymentHash: rhash, 1200 Amount: 1, 1201 }, 1202 } 1203 1204 if s.circuits.NumPending() != 0 { 1205 t.Fatalf("wrong amount of half circuits") 1206 } 1207 if s.circuits.NumOpen() != 0 { 1208 t.Fatalf("wrong amount of circuits") 1209 } 1210 1211 // Handle the request and checks that bob channel link received it. 1212 if err := s.ForwardPackets(nil, ogPacket); err != nil { 1213 t.Fatal(err) 1214 } 1215 1216 if s.circuits.NumPending() != 1 { 1217 t.Fatalf("wrong amount of half circuits") 1218 } 1219 if s.circuits.NumOpen() != 0 { 1220 t.Fatalf("wrong amount of circuits") 1221 } 1222 1223 // Retrieve packet from outgoing link and cache until after restart. 1224 var packet *htlcPacket 1225 select { 1226 case packet = <-bobChannelLink.packets: 1227 case <-time.After(time.Second): 1228 t.Fatal("request was not propagated to destination") 1229 } 1230 1231 if err := s.Stop(); err != nil { 1232 t.Fatalf(err.Error()) 1233 } 1234 1235 if err := cdb.Close(); err != nil { 1236 t.Fatalf(err.Error()) 1237 } 1238 1239 cdb2, err := channeldb.Open(tempPath) 1240 if err != nil { 1241 t.Fatalf("unable to reopen channeldb: %v", err) 1242 } 1243 1244 s2, err := initSwitchWithDB(testStartingHeight, cdb2) 1245 if err != nil { 1246 t.Fatalf("unable reinit switch: %v", err) 1247 } 1248 if err := s2.Start(); err != nil { 1249 t.Fatalf("unable to restart switch: %v", err) 1250 } 1251 1252 // Even though we intend to Stop s2 later in the test, it is safe to 1253 // defer this Stop since its execution it is protected by an atomic 1254 // guard, guaranteeing it executes at most once. 1255 defer s2.Stop() 1256 1257 aliceChannelLink = newMockChannelLink( 1258 s2, chanID1, aliceChanID, alicePeer, true, 1259 ) 1260 bobChannelLink = newMockChannelLink( 1261 s2, chanID2, bobChanID, bobPeer, true, 1262 ) 1263 if err := s2.AddLink(aliceChannelLink); err != nil { 1264 t.Fatalf("unable to add alice link: %v", err) 1265 } 1266 if err := s2.AddLink(bobChannelLink); err != nil { 1267 t.Fatalf("unable to add bob link: %v", err) 1268 } 1269 1270 if s2.circuits.NumPending() != 1 { 1271 t.Fatalf("wrong amount of half circuits") 1272 } 1273 if s2.circuits.NumOpen() != 0 { 1274 t.Fatalf("wrong amount of half circuits") 1275 } 1276 1277 // Now that the switch has restarted, complete the payment circuit. 1278 if err := bobChannelLink.completeCircuit(packet); err != nil { 1279 t.Fatalf("unable to complete payment circuit: %v", err) 1280 } 1281 1282 if s2.circuits.NumPending() != 1 { 1283 t.Fatalf("wrong amount of half circuits") 1284 } 1285 if s2.circuits.NumOpen() != 1 { 1286 t.Fatal("wrong amount of circuits") 1287 } 1288 1289 // Create settle request pretending that bob link handled the add htlc 1290 // request and sent the htlc settle request back. This request should 1291 // be forwarder back to Alice link. 1292 ogPacket = &htlcPacket{ 1293 outgoingChanID: bobChannelLink.ShortChanID(), 1294 outgoingHTLCID: 0, 1295 amount: 1, 1296 htlc: &lnwire.UpdateFulfillHTLC{ 1297 PaymentPreimage: preimage, 1298 }, 1299 } 1300 1301 // Handle the request and checks that payment circuit works properly. 1302 if err := s2.ForwardPackets(nil, ogPacket); err != nil { 1303 t.Fatal(err) 1304 } 1305 1306 select { 1307 case packet = <-aliceChannelLink.packets: 1308 if err := aliceChannelLink.completeCircuit(packet); err != nil { 1309 t.Fatalf("unable to complete circuit with in key=%s: %v", 1310 packet.inKey(), err) 1311 } 1312 case <-time.After(time.Second): 1313 t.Fatal("request was not propagated to channelPoint") 1314 } 1315 1316 if s2.circuits.NumPending() != 0 { 1317 t.Fatalf("wrong amount of half circuits, want 1, got %d", 1318 s2.circuits.NumPending()) 1319 } 1320 if s2.circuits.NumOpen() != 0 { 1321 t.Fatal("wrong amount of circuits") 1322 } 1323 1324 if err := s2.Stop(); err != nil { 1325 t.Fatal(err) 1326 } 1327 1328 if err := cdb2.Close(); err != nil { 1329 t.Fatalf(err.Error()) 1330 } 1331 1332 cdb3, err := channeldb.Open(tempPath) 1333 if err != nil { 1334 t.Fatalf("unable to reopen channeldb: %v", err) 1335 } 1336 1337 s3, err := initSwitchWithDB(testStartingHeight, cdb3) 1338 if err != nil { 1339 t.Fatalf("unable reinit switch: %v", err) 1340 } 1341 if err := s3.Start(); err != nil { 1342 t.Fatalf("unable to restart switch: %v", err) 1343 } 1344 defer s3.Stop() 1345 1346 aliceChannelLink = newMockChannelLink( 1347 s3, chanID1, aliceChanID, alicePeer, true, 1348 ) 1349 bobChannelLink = newMockChannelLink( 1350 s3, chanID2, bobChanID, bobPeer, true, 1351 ) 1352 if err := s3.AddLink(aliceChannelLink); err != nil { 1353 t.Fatalf("unable to add alice link: %v", err) 1354 } 1355 if err := s3.AddLink(bobChannelLink); err != nil { 1356 t.Fatalf("unable to add bob link: %v", err) 1357 } 1358 1359 if s3.circuits.NumPending() != 0 { 1360 t.Fatalf("wrong amount of half circuits") 1361 } 1362 if s3.circuits.NumOpen() != 0 { 1363 t.Fatalf("wrong amount of circuits") 1364 } 1365 } 1366 1367 type multiHopFwdTest struct { 1368 name string 1369 eligible1, eligible2 bool 1370 failure1, failure2 *LinkError 1371 expectedReply lnwire.FailCode 1372 } 1373 1374 // TestCircularForwards tests the allowing/disallowing of circular payments 1375 // through the same channel in the case where the switch is configured to allow 1376 // and disallow same channel circular forwards. 1377 func TestCircularForwards(t *testing.T) { 1378 chanID1, aliceChanID := genID() 1379 preimage := [sha256.Size]byte{1} 1380 hash := sha256.Sum256(preimage[:]) 1381 1382 tests := []struct { 1383 name string 1384 allowCircularPayment bool 1385 expectedErr error 1386 }{ 1387 { 1388 name: "circular payment allowed", 1389 allowCircularPayment: true, 1390 expectedErr: nil, 1391 }, 1392 { 1393 name: "circular payment disallowed", 1394 allowCircularPayment: false, 1395 expectedErr: NewDetailedLinkError( 1396 lnwire.NewTemporaryChannelFailure(nil), 1397 OutgoingFailureCircularRoute, 1398 ), 1399 }, 1400 } 1401 1402 for _, test := range tests { 1403 test := test 1404 t.Run(test.name, func(t *testing.T) { 1405 t.Parallel() 1406 1407 alicePeer, err := newMockServer( 1408 t, "alice", testStartingHeight, nil, 1409 testDefaultDelta, 1410 ) 1411 if err != nil { 1412 t.Fatalf("unable to create alice server: %v", 1413 err) 1414 } 1415 1416 s, err := initSwitchWithDB(testStartingHeight, nil) 1417 if err != nil { 1418 t.Fatalf("unable to init switch: %v", err) 1419 } 1420 if err := s.Start(); err != nil { 1421 t.Fatalf("unable to start switch: %v", err) 1422 } 1423 defer func() { _ = s.Stop() }() 1424 1425 // Set the switch to allow or disallow circular routes 1426 // according to the test's requirements. 1427 s.cfg.AllowCircularRoute = test.allowCircularPayment 1428 1429 aliceChannelLink := newMockChannelLink( 1430 s, chanID1, aliceChanID, alicePeer, true, 1431 ) 1432 1433 if err := s.AddLink(aliceChannelLink); err != nil { 1434 t.Fatalf("unable to add alice link: %v", err) 1435 } 1436 1437 // Create a new packet that loops through alice's link 1438 // in a circle. 1439 obfuscator := NewMockObfuscator() 1440 packet := &htlcPacket{ 1441 incomingChanID: aliceChannelLink.ShortChanID(), 1442 outgoingChanID: aliceChannelLink.ShortChanID(), 1443 htlc: &lnwire.UpdateAddHTLC{ 1444 PaymentHash: hash, 1445 Amount: 1, 1446 }, 1447 obfuscator: obfuscator, 1448 } 1449 1450 // Attempt to forward the packet and check for the expected 1451 // error. 1452 if err = s.ForwardPackets(nil, packet); err != nil { 1453 t.Fatal(err) 1454 } 1455 select { 1456 case p := <-aliceChannelLink.packets: 1457 if p.linkFailure != nil { 1458 err = p.linkFailure 1459 } 1460 case <-time.After(time.Second): 1461 t.Fatal("no timely reply from switch") 1462 } 1463 if !reflect.DeepEqual(err, test.expectedErr) { 1464 t.Fatalf("expected: %v, got: %v", 1465 test.expectedErr, err) 1466 } 1467 1468 // Ensure that no circuits were opened. 1469 if s.circuits.NumOpen() > 0 { 1470 t.Fatal("do not expect any open circuits") 1471 } 1472 }) 1473 } 1474 } 1475 1476 // TestCheckCircularForward tests the error returned by checkCircularForward 1477 // in cases where we allow and disallow same channel circular forwards. 1478 func TestCheckCircularForward(t *testing.T) { 1479 tests := []struct { 1480 name string 1481 1482 // allowCircular determines whether we should allow circular 1483 // forwards. 1484 allowCircular bool 1485 1486 // incomingLink is the link that the htlc arrived on. 1487 incomingLink lnwire.ShortChannelID 1488 1489 // outgoingLink is the link that the htlc forward 1490 // is destined to leave on. 1491 outgoingLink lnwire.ShortChannelID 1492 1493 // expectedErr is the error we expect to be returned. 1494 expectedErr *LinkError 1495 }{ 1496 { 1497 name: "not circular, allowed in config", 1498 allowCircular: true, 1499 incomingLink: lnwire.NewShortChanIDFromInt(123), 1500 outgoingLink: lnwire.NewShortChanIDFromInt(321), 1501 expectedErr: nil, 1502 }, 1503 { 1504 name: "not circular, not allowed in config", 1505 allowCircular: false, 1506 incomingLink: lnwire.NewShortChanIDFromInt(123), 1507 outgoingLink: lnwire.NewShortChanIDFromInt(321), 1508 expectedErr: nil, 1509 }, 1510 { 1511 name: "circular, allowed in config", 1512 allowCircular: true, 1513 incomingLink: lnwire.NewShortChanIDFromInt(123), 1514 outgoingLink: lnwire.NewShortChanIDFromInt(123), 1515 expectedErr: nil, 1516 }, 1517 { 1518 name: "circular, not allowed in config", 1519 allowCircular: false, 1520 incomingLink: lnwire.NewShortChanIDFromInt(123), 1521 outgoingLink: lnwire.NewShortChanIDFromInt(123), 1522 expectedErr: NewDetailedLinkError( 1523 lnwire.NewTemporaryChannelFailure(nil), 1524 OutgoingFailureCircularRoute, 1525 ), 1526 }, 1527 } 1528 1529 for _, test := range tests { 1530 test := test 1531 1532 t.Run(test.name, func(t *testing.T) { 1533 t.Parallel() 1534 1535 // Check for a circular forward, the hash passed can 1536 // be nil because it is only used for logging. 1537 err := checkCircularForward( 1538 test.incomingLink, test.outgoingLink, 1539 test.allowCircular, lntypes.Hash{}, 1540 ) 1541 if !reflect.DeepEqual(err, test.expectedErr) { 1542 t.Fatalf("expected: %v, got: %v", 1543 test.expectedErr, err) 1544 } 1545 }) 1546 } 1547 } 1548 1549 // TestSkipIneligibleLinksMultiHopForward tests that if a multi-hop HTLC comes 1550 // along, then we won't attempt to froward it down al ink that isn't yet able 1551 // to forward any HTLC's. 1552 func TestSkipIneligibleLinksMultiHopForward(t *testing.T) { 1553 tests := []multiHopFwdTest{ 1554 // None of the channels is eligible. 1555 { 1556 name: "not eligible", 1557 expectedReply: lnwire.CodeUnknownNextPeer, 1558 }, 1559 1560 // Channel one has a policy failure and the other channel isn't 1561 // available. 1562 { 1563 name: "policy fail", 1564 eligible1: true, 1565 failure1: NewLinkError( 1566 lnwire.NewFinalIncorrectCltvExpiry(0), 1567 ), 1568 expectedReply: lnwire.CodeFinalIncorrectCltvExpiry, 1569 }, 1570 1571 // The requested channel is not eligible, but the packet is 1572 // forwarded through the other channel. 1573 { 1574 name: "non-strict success", 1575 eligible2: true, 1576 expectedReply: lnwire.CodeNone, 1577 }, 1578 1579 // The requested channel has insufficient bandwidth and the 1580 // other channel's policy isn't satisfied. 1581 { 1582 name: "non-strict policy fail", 1583 eligible1: true, 1584 failure1: NewDetailedLinkError( 1585 lnwire.NewTemporaryChannelFailure(nil), 1586 OutgoingFailureInsufficientBalance, 1587 ), 1588 eligible2: true, 1589 failure2: NewLinkError( 1590 lnwire.NewFinalIncorrectCltvExpiry(0), 1591 ), 1592 expectedReply: lnwire.CodeTemporaryChannelFailure, 1593 }, 1594 } 1595 1596 for _, test := range tests { 1597 test := test 1598 t.Run(test.name, func(t *testing.T) { 1599 testSkipIneligibleLinksMultiHopForward(t, &test) 1600 }) 1601 } 1602 } 1603 1604 // testSkipIneligibleLinksMultiHopForward tests that if a multi-hop HTLC comes 1605 // along, then we won't attempt to froward it down al ink that isn't yet able 1606 // to forward any HTLC's. 1607 func testSkipIneligibleLinksMultiHopForward(t *testing.T, 1608 testCase *multiHopFwdTest) { 1609 1610 t.Parallel() 1611 1612 var packet *htlcPacket 1613 1614 alicePeer, err := newMockServer( 1615 t, "alice", testStartingHeight, nil, testDefaultDelta, 1616 ) 1617 if err != nil { 1618 t.Fatalf("unable to create alice server: %v", err) 1619 } 1620 bobPeer, err := newMockServer( 1621 t, "bob", testStartingHeight, nil, testDefaultDelta, 1622 ) 1623 if err != nil { 1624 t.Fatalf("unable to create bob server: %v", err) 1625 } 1626 1627 s, err := initSwitchWithDB(testStartingHeight, nil) 1628 if err != nil { 1629 t.Fatalf("unable to init switch: %v", err) 1630 } 1631 if err := s.Start(); err != nil { 1632 t.Fatalf("unable to start switch: %v", err) 1633 } 1634 defer s.Stop() 1635 1636 chanID1, aliceChanID := genID() 1637 aliceChannelLink := newMockChannelLink( 1638 s, chanID1, aliceChanID, alicePeer, true, 1639 ) 1640 1641 // We'll create a link for Bob, but mark the link as unable to forward 1642 // any new outgoing HTLC's. 1643 chanID2, bobChanID2 := genID() 1644 bobChannelLink1 := newMockChannelLink( 1645 s, chanID2, bobChanID2, bobPeer, testCase.eligible1, 1646 ) 1647 bobChannelLink1.checkHtlcForwardResult = testCase.failure1 1648 1649 chanID3, bobChanID3 := genID() 1650 bobChannelLink2 := newMockChannelLink( 1651 s, chanID3, bobChanID3, bobPeer, testCase.eligible2, 1652 ) 1653 bobChannelLink2.checkHtlcForwardResult = testCase.failure2 1654 1655 if err := s.AddLink(aliceChannelLink); err != nil { 1656 t.Fatalf("unable to add alice link: %v", err) 1657 } 1658 if err := s.AddLink(bobChannelLink1); err != nil { 1659 t.Fatalf("unable to add bob link: %v", err) 1660 } 1661 if err := s.AddLink(bobChannelLink2); err != nil { 1662 t.Fatalf("unable to add bob link: %v", err) 1663 } 1664 1665 // Create a new packet that's destined for Bob as an incoming HTLC from 1666 // Alice. 1667 preimage := [chainhash.HashSize]byte{1} 1668 rhash := sha256.Sum256(preimage[:]) 1669 obfuscator := NewMockObfuscator() 1670 packet = &htlcPacket{ 1671 incomingChanID: aliceChannelLink.ShortChanID(), 1672 incomingHTLCID: 0, 1673 outgoingChanID: bobChannelLink1.ShortChanID(), 1674 htlc: &lnwire.UpdateAddHTLC{ 1675 PaymentHash: rhash, 1676 Amount: 1, 1677 }, 1678 obfuscator: obfuscator, 1679 } 1680 1681 // The request to forward should fail as 1682 if err := s.ForwardPackets(nil, packet); err != nil { 1683 t.Fatal(err) 1684 } 1685 1686 // We select from all links and extract the error if exists. 1687 // The packet must be selected but we don't always expect a link error. 1688 var linkError *LinkError 1689 select { 1690 case p := <-aliceChannelLink.packets: 1691 linkError = p.linkFailure 1692 case p := <-bobChannelLink1.packets: 1693 linkError = p.linkFailure 1694 case p := <-bobChannelLink2.packets: 1695 linkError = p.linkFailure 1696 case <-time.After(time.Second): 1697 t.Fatal("no timely reply from switch") 1698 } 1699 failure := obfuscator.(*mockObfuscator).failure 1700 if testCase.expectedReply == lnwire.CodeNone { 1701 if linkError != nil { 1702 t.Fatalf("forwarding should have succeeded") 1703 } 1704 if failure != nil { 1705 t.Fatalf("unexpected failure %T", failure) 1706 } 1707 } else { 1708 if linkError == nil { 1709 t.Fatalf("forwarding should have failed due to " + 1710 "inactive link") 1711 } 1712 if failure.Code() != testCase.expectedReply { 1713 t.Fatalf("unexpected failure %T", failure) 1714 } 1715 } 1716 1717 if s.circuits.NumOpen() != 0 { 1718 t.Fatal("wrong amount of circuits") 1719 } 1720 } 1721 1722 // TestSkipIneligibleLinksLocalForward ensures that the switch will not attempt 1723 // to forward any HTLC's down a link that isn't yet eligible for forwarding. 1724 func TestSkipIneligibleLinksLocalForward(t *testing.T) { 1725 t.Parallel() 1726 1727 testSkipLinkLocalForward(t, false, nil) 1728 } 1729 1730 // TestSkipPolicyUnsatisfiedLinkLocalForward ensures that the switch will not 1731 // attempt to send locally initiated HTLCs that would violate the channel policy 1732 // down a link. 1733 func TestSkipPolicyUnsatisfiedLinkLocalForward(t *testing.T) { 1734 t.Parallel() 1735 1736 testSkipLinkLocalForward(t, true, lnwire.NewTemporaryChannelFailure(nil)) 1737 } 1738 1739 func testSkipLinkLocalForward(t *testing.T, eligible bool, 1740 policyResult lnwire.FailureMessage) { 1741 1742 // We'll create a single link for this test, marking it as being unable 1743 // to forward form the get go. 1744 alicePeer, err := newMockServer( 1745 t, "alice", testStartingHeight, nil, testDefaultDelta, 1746 ) 1747 if err != nil { 1748 t.Fatalf("unable to create alice server: %v", err) 1749 } 1750 1751 s, err := initSwitchWithDB(testStartingHeight, nil) 1752 if err != nil { 1753 t.Fatalf("unable to init switch: %v", err) 1754 } 1755 if err := s.Start(); err != nil { 1756 t.Fatalf("unable to start switch: %v", err) 1757 } 1758 defer s.Stop() 1759 1760 chanID1, _, aliceChanID, _ := genIDs() 1761 1762 aliceChannelLink := newMockChannelLink( 1763 s, chanID1, aliceChanID, alicePeer, eligible, 1764 ) 1765 aliceChannelLink.checkHtlcTransitResult = NewLinkError( 1766 policyResult, 1767 ) 1768 if err := s.AddLink(aliceChannelLink); err != nil { 1769 t.Fatalf("unable to add alice link: %v", err) 1770 } 1771 1772 preimage, err := genPreimage() 1773 if err != nil { 1774 t.Fatalf("unable to generate preimage: %v", err) 1775 } 1776 rhash := sha256.Sum256(preimage[:]) 1777 addMsg := &lnwire.UpdateAddHTLC{ 1778 PaymentHash: rhash, 1779 Amount: 1, 1780 } 1781 1782 // We'll attempt to send out a new HTLC that has Alice as the first 1783 // outgoing link. This should fail as Alice isn't yet able to forward 1784 // any active HTLC's. 1785 err = s.SendHTLC(aliceChannelLink.ShortChanID(), 0, addMsg) 1786 if err == nil { 1787 t.Fatalf("local forward should fail due to inactive link") 1788 } 1789 1790 if s.circuits.NumOpen() != 0 { 1791 t.Fatal("wrong amount of circuits") 1792 } 1793 } 1794 1795 // TestSwitchCancel checks that if htlc was rejected we remove unused 1796 // circuits. 1797 func TestSwitchCancel(t *testing.T) { 1798 t.Parallel() 1799 1800 alicePeer, err := newMockServer( 1801 t, "alice", testStartingHeight, nil, testDefaultDelta, 1802 ) 1803 if err != nil { 1804 t.Fatalf("unable to create alice server: %v", err) 1805 } 1806 bobPeer, err := newMockServer( 1807 t, "bob", testStartingHeight, nil, testDefaultDelta, 1808 ) 1809 if err != nil { 1810 t.Fatalf("unable to create bob server: %v", err) 1811 } 1812 1813 s, err := initSwitchWithDB(testStartingHeight, nil) 1814 if err != nil { 1815 t.Fatalf("unable to init switch: %v", err) 1816 } 1817 if err := s.Start(); err != nil { 1818 t.Fatalf("unable to start switch: %v", err) 1819 } 1820 defer s.Stop() 1821 1822 chanID1, chanID2, aliceChanID, bobChanID := genIDs() 1823 1824 aliceChannelLink := newMockChannelLink( 1825 s, chanID1, aliceChanID, alicePeer, true, 1826 ) 1827 bobChannelLink := newMockChannelLink( 1828 s, chanID2, bobChanID, bobPeer, true, 1829 ) 1830 if err := s.AddLink(aliceChannelLink); err != nil { 1831 t.Fatalf("unable to add alice link: %v", err) 1832 } 1833 if err := s.AddLink(bobChannelLink); err != nil { 1834 t.Fatalf("unable to add bob link: %v", err) 1835 } 1836 1837 // Create request which should be forwarder from alice channel link 1838 // to bob channel link. 1839 preimage, err := genPreimage() 1840 if err != nil { 1841 t.Fatalf("unable to generate preimage: %v", err) 1842 } 1843 rhash := sha256.Sum256(preimage[:]) 1844 request := &htlcPacket{ 1845 incomingChanID: aliceChannelLink.ShortChanID(), 1846 incomingHTLCID: 0, 1847 outgoingChanID: bobChannelLink.ShortChanID(), 1848 obfuscator: NewMockObfuscator(), 1849 htlc: &lnwire.UpdateAddHTLC{ 1850 PaymentHash: rhash, 1851 Amount: 1, 1852 }, 1853 } 1854 1855 // Handle the request and checks that bob channel link received it. 1856 if err := s.ForwardPackets(nil, request); err != nil { 1857 t.Fatal(err) 1858 } 1859 1860 select { 1861 case packet := <-bobChannelLink.packets: 1862 if err := bobChannelLink.completeCircuit(packet); err != nil { 1863 t.Fatalf("unable to complete payment circuit: %v", err) 1864 } 1865 1866 case <-time.After(time.Second): 1867 t.Fatal("request was not propagated to destination") 1868 } 1869 1870 if s.circuits.NumPending() != 1 { 1871 t.Fatalf("wrong amount of half circuits") 1872 } 1873 if s.circuits.NumOpen() != 1 { 1874 t.Fatal("wrong amount of circuits") 1875 } 1876 1877 // Create settle request pretending that bob channel link handled 1878 // the add htlc request and sent the htlc settle request back. This 1879 // request should be forwarder back to alice channel link. 1880 request = &htlcPacket{ 1881 outgoingChanID: bobChannelLink.ShortChanID(), 1882 outgoingHTLCID: 0, 1883 amount: 1, 1884 htlc: &lnwire.UpdateFailHTLC{}, 1885 } 1886 1887 // Handle the request and checks that payment circuit works properly. 1888 if err := s.ForwardPackets(nil, request); err != nil { 1889 t.Fatal(err) 1890 } 1891 1892 select { 1893 case pkt := <-aliceChannelLink.packets: 1894 if err := aliceChannelLink.completeCircuit(pkt); err != nil { 1895 t.Fatalf("unable to remove circuit: %v", err) 1896 } 1897 1898 case <-time.After(time.Second): 1899 t.Fatal("request was not propagated to channelPoint") 1900 } 1901 1902 if s.circuits.NumPending() != 0 { 1903 t.Fatal("wrong amount of circuits") 1904 } 1905 if s.circuits.NumOpen() != 0 { 1906 t.Fatal("wrong amount of circuits") 1907 } 1908 } 1909 1910 // TestSwitchAddSamePayment tests that we send the payment with the same 1911 // payment hash. 1912 func TestSwitchAddSamePayment(t *testing.T) { 1913 t.Parallel() 1914 1915 chanID1, chanID2, aliceChanID, bobChanID := genIDs() 1916 1917 alicePeer, err := newMockServer( 1918 t, "alice", testStartingHeight, nil, testDefaultDelta, 1919 ) 1920 if err != nil { 1921 t.Fatalf("unable to create alice server: %v", err) 1922 } 1923 bobPeer, err := newMockServer( 1924 t, "bob", testStartingHeight, nil, testDefaultDelta, 1925 ) 1926 if err != nil { 1927 t.Fatalf("unable to create bob server: %v", err) 1928 } 1929 1930 s, err := initSwitchWithDB(testStartingHeight, nil) 1931 if err != nil { 1932 t.Fatalf("unable to init switch: %v", err) 1933 } 1934 if err := s.Start(); err != nil { 1935 t.Fatalf("unable to start switch: %v", err) 1936 } 1937 defer s.Stop() 1938 1939 aliceChannelLink := newMockChannelLink( 1940 s, chanID1, aliceChanID, alicePeer, true, 1941 ) 1942 bobChannelLink := newMockChannelLink( 1943 s, chanID2, bobChanID, bobPeer, true, 1944 ) 1945 if err := s.AddLink(aliceChannelLink); err != nil { 1946 t.Fatalf("unable to add alice link: %v", err) 1947 } 1948 if err := s.AddLink(bobChannelLink); err != nil { 1949 t.Fatalf("unable to add bob link: %v", err) 1950 } 1951 1952 // Create request which should be forwarder from alice channel link 1953 // to bob channel link. 1954 preimage, err := genPreimage() 1955 if err != nil { 1956 t.Fatalf("unable to generate preimage: %v", err) 1957 } 1958 rhash := sha256.Sum256(preimage[:]) 1959 request := &htlcPacket{ 1960 incomingChanID: aliceChannelLink.ShortChanID(), 1961 incomingHTLCID: 0, 1962 outgoingChanID: bobChannelLink.ShortChanID(), 1963 obfuscator: NewMockObfuscator(), 1964 htlc: &lnwire.UpdateAddHTLC{ 1965 PaymentHash: rhash, 1966 Amount: 1, 1967 }, 1968 } 1969 1970 // Handle the request and checks that bob channel link received it. 1971 if err := s.ForwardPackets(nil, request); err != nil { 1972 t.Fatal(err) 1973 } 1974 1975 select { 1976 case packet := <-bobChannelLink.packets: 1977 if err := bobChannelLink.completeCircuit(packet); err != nil { 1978 t.Fatalf("unable to complete payment circuit: %v", err) 1979 } 1980 1981 case <-time.After(time.Second): 1982 t.Fatal("request was not propagated to destination") 1983 } 1984 1985 if s.circuits.NumOpen() != 1 { 1986 t.Fatal("wrong amount of circuits") 1987 } 1988 1989 request = &htlcPacket{ 1990 incomingChanID: aliceChannelLink.ShortChanID(), 1991 incomingHTLCID: 1, 1992 outgoingChanID: bobChannelLink.ShortChanID(), 1993 obfuscator: NewMockObfuscator(), 1994 htlc: &lnwire.UpdateAddHTLC{ 1995 PaymentHash: rhash, 1996 Amount: 1, 1997 }, 1998 } 1999 2000 // Handle the request and checks that bob channel link received it. 2001 if err := s.ForwardPackets(nil, request); err != nil { 2002 t.Fatal(err) 2003 } 2004 2005 select { 2006 case packet := <-bobChannelLink.packets: 2007 if err := bobChannelLink.completeCircuit(packet); err != nil { 2008 t.Fatalf("unable to complete payment circuit: %v", err) 2009 } 2010 2011 case <-time.After(time.Second): 2012 t.Fatal("request was not propagated to destination") 2013 } 2014 2015 if s.circuits.NumOpen() != 2 { 2016 t.Fatal("wrong amount of circuits") 2017 } 2018 2019 // Create settle request pretending that bob channel link handled 2020 // the add htlc request and sent the htlc settle request back. This 2021 // request should be forwarder back to alice channel link. 2022 request = &htlcPacket{ 2023 outgoingChanID: bobChannelLink.ShortChanID(), 2024 outgoingHTLCID: 0, 2025 amount: 1, 2026 htlc: &lnwire.UpdateFailHTLC{}, 2027 } 2028 2029 // Handle the request and checks that payment circuit works properly. 2030 if err := s.ForwardPackets(nil, request); err != nil { 2031 t.Fatal(err) 2032 } 2033 2034 select { 2035 case pkt := <-aliceChannelLink.packets: 2036 if err := aliceChannelLink.completeCircuit(pkt); err != nil { 2037 t.Fatalf("unable to remove circuit: %v", err) 2038 } 2039 2040 case <-time.After(time.Second): 2041 t.Fatal("request was not propagated to channelPoint") 2042 } 2043 2044 if s.circuits.NumOpen() != 1 { 2045 t.Fatal("wrong amount of circuits") 2046 } 2047 2048 request = &htlcPacket{ 2049 outgoingChanID: bobChannelLink.ShortChanID(), 2050 outgoingHTLCID: 1, 2051 amount: 1, 2052 htlc: &lnwire.UpdateFailHTLC{}, 2053 } 2054 2055 // Handle the request and checks that payment circuit works properly. 2056 if err := s.ForwardPackets(nil, request); err != nil { 2057 t.Fatal(err) 2058 } 2059 2060 select { 2061 case pkt := <-aliceChannelLink.packets: 2062 if err := aliceChannelLink.completeCircuit(pkt); err != nil { 2063 t.Fatalf("unable to remove circuit: %v", err) 2064 } 2065 2066 case <-time.After(time.Second): 2067 t.Fatal("request was not propagated to channelPoint") 2068 } 2069 2070 if s.circuits.NumOpen() != 0 { 2071 t.Fatal("wrong amount of circuits") 2072 } 2073 } 2074 2075 // TestSwitchSendPayment tests ability of htlc switch to respond to the 2076 // users when response is came back from channel link. 2077 func TestSwitchSendPayment(t *testing.T) { 2078 t.Parallel() 2079 2080 alicePeer, err := newMockServer( 2081 t, "alice", testStartingHeight, nil, testDefaultDelta, 2082 ) 2083 if err != nil { 2084 t.Fatalf("unable to create alice server: %v", err) 2085 } 2086 2087 s, err := initSwitchWithDB(testStartingHeight, nil) 2088 if err != nil { 2089 t.Fatalf("unable to init switch: %v", err) 2090 } 2091 if err := s.Start(); err != nil { 2092 t.Fatalf("unable to start switch: %v", err) 2093 } 2094 defer s.Stop() 2095 2096 chanID1, _, aliceChanID, _ := genIDs() 2097 2098 aliceChannelLink := newMockChannelLink( 2099 s, chanID1, aliceChanID, alicePeer, true, 2100 ) 2101 if err := s.AddLink(aliceChannelLink); err != nil { 2102 t.Fatalf("unable to add link: %v", err) 2103 } 2104 2105 // Create request which should be forwarder from alice channel link 2106 // to bob channel link. 2107 preimage, err := genPreimage() 2108 if err != nil { 2109 t.Fatalf("unable to generate preimage: %v", err) 2110 } 2111 rhash := sha256.Sum256(preimage[:]) 2112 update := &lnwire.UpdateAddHTLC{ 2113 PaymentHash: rhash, 2114 Amount: 1, 2115 } 2116 paymentID := uint64(123) 2117 2118 // First check that the switch will correctly respond that this payment 2119 // ID is unknown. 2120 _, err = s.GetPaymentResult( 2121 paymentID, lntypes.Hash(rhash), newMockDeobfuscator(), 2122 ) 2123 if err != ErrPaymentIDNotFound { 2124 t.Fatalf("expected ErrPaymentIDNotFound, got %v", err) 2125 } 2126 2127 // Handle the request and checks that bob channel link received it. 2128 errChan := make(chan error) 2129 go func() { 2130 err := s.SendHTLC( 2131 aliceChannelLink.ShortChanID(), paymentID, update, 2132 ) 2133 if err != nil { 2134 errChan <- err 2135 return 2136 } 2137 2138 resultChan, err := s.GetPaymentResult( 2139 paymentID, lntypes.Hash(rhash), newMockDeobfuscator(), 2140 ) 2141 if err != nil { 2142 errChan <- err 2143 return 2144 } 2145 2146 result, ok := <-resultChan 2147 if !ok { 2148 errChan <- fmt.Errorf("shutting down") 2149 } 2150 2151 if result.Error != nil { 2152 errChan <- result.Error 2153 return 2154 } 2155 2156 errChan <- nil 2157 }() 2158 2159 select { 2160 case packet := <-aliceChannelLink.packets: 2161 if err := aliceChannelLink.completeCircuit(packet); err != nil { 2162 t.Fatalf("unable to complete payment circuit: %v", err) 2163 } 2164 2165 case err := <-errChan: 2166 if err != nil { 2167 t.Fatalf("unable to send payment: %v", err) 2168 } 2169 case <-time.After(time.Second): 2170 t.Fatal("request was not propagated to destination") 2171 } 2172 2173 if s.circuits.NumOpen() != 1 { 2174 t.Fatal("wrong amount of circuits") 2175 } 2176 2177 // Create fail request pretending that bob channel link handled 2178 // the add htlc request with error and sent the htlc fail request 2179 // back. This request should be forwarded back to alice channel link. 2180 obfuscator := NewMockObfuscator() 2181 failure := lnwire.NewFailIncorrectDetails(update.Amount, 100) 2182 reason, err := obfuscator.EncryptFirstHop(failure) 2183 if err != nil { 2184 t.Fatalf("unable obfuscate failure: %v", err) 2185 } 2186 2187 if s.IsForwardedHTLC(aliceChannelLink.ShortChanID(), update.ID) { 2188 t.Fatal("htlc should be identified as not forwarded") 2189 } 2190 packet := &htlcPacket{ 2191 outgoingChanID: aliceChannelLink.ShortChanID(), 2192 outgoingHTLCID: 0, 2193 amount: 1, 2194 htlc: &lnwire.UpdateFailHTLC{ 2195 Reason: reason, 2196 }, 2197 } 2198 2199 if err := s.ForwardPackets(nil, packet); err != nil { 2200 t.Fatalf("can't forward htlc packet: %v", err) 2201 } 2202 2203 select { 2204 case err := <-errChan: 2205 assertFailureCode( 2206 t, err, lnwire.CodeIncorrectOrUnknownPaymentDetails, 2207 ) 2208 case <-time.After(time.Second): 2209 t.Fatal("err wasn't received") 2210 } 2211 } 2212 2213 // TestLocalPaymentNoForwardingEvents tests that if we send a series of locally 2214 // initiated payments, then they aren't reflected in the forwarding log. 2215 func TestLocalPaymentNoForwardingEvents(t *testing.T) { 2216 t.Parallel() 2217 2218 // First, we'll create our traditional three hop network. We'll only be 2219 // interacting with and asserting the state of the first end point for 2220 // this test. 2221 channels, cleanUp, _, err := createClusterChannels( 2222 dcrutil.AtomsPerCoin*3, 2223 dcrutil.AtomsPerCoin*5) 2224 if err != nil { 2225 t.Fatalf("unable to create channel: %v", err) 2226 } 2227 defer cleanUp() 2228 2229 n := newThreeHopNetwork(t, channels.aliceToBob, channels.bobToAlice, 2230 channels.bobToCarol, channels.carolToBob, testStartingHeight) 2231 if err := n.start(); err != nil { 2232 t.Fatalf("unable to start three hop network: %v", err) 2233 } 2234 2235 // We'll now craft and send a payment from Alice to Bob. 2236 amount := lnwire.NewMAtomsFromAtoms(dcrutil.AtomsPerCoin) 2237 htlcAmt, totalTimelock, hops := generateHops( 2238 amount, testStartingHeight, n.firstBobChannelLink, 2239 ) 2240 2241 // With the payment crafted, we'll send it from Alice to Bob. We'll 2242 // wait for Alice to receive the preimage for the payment before 2243 // proceeding. 2244 receiver := n.bobServer 2245 firstHop := n.firstBobChannelLink.ShortChanID() 2246 _, err = makePayment( 2247 n.aliceServer, receiver, firstHop, hops, amount, htlcAmt, 2248 totalTimelock, 2249 ).Wait(30 * time.Second) 2250 if err != nil { 2251 t.Fatalf("unable to make the payment: %v", err) 2252 } 2253 2254 // At this point, we'll forcibly stop the three hop network. Doing 2255 // this will cause any pending forwarding events to be flushed by the 2256 // various switches in the network. 2257 n.stop() 2258 2259 // With all the switches stopped, we'll fetch Alice's mock forwarding 2260 // event log. 2261 log, ok := n.aliceServer.htlcSwitch.cfg.FwdingLog.(*mockForwardingLog) 2262 if !ok { 2263 t.Fatalf("mockForwardingLog assertion failed") 2264 } 2265 log.Lock() 2266 defer log.Unlock() 2267 2268 // If we examine the memory of the forwarding log, then it should be 2269 // blank. 2270 if len(log.events) != 0 { 2271 t.Fatalf("log should have no events, instead has: %v", 2272 spew.Sdump(log.events)) 2273 } 2274 } 2275 2276 // TestMultiHopPaymentForwardingEvents tests that if we send a series of 2277 // multi-hop payments via Alice->Bob->Carol. Then Bob properly logs forwarding 2278 // events, while Alice and Carol don't. 2279 func TestMultiHopPaymentForwardingEvents(t *testing.T) { 2280 t.Parallel() 2281 2282 // First, we'll create our traditional three hop network. 2283 channels, cleanUp, _, err := createClusterChannels( 2284 dcrutil.AtomsPerCoin*3, 2285 dcrutil.AtomsPerCoin*5) 2286 if err != nil { 2287 t.Fatalf("unable to create channel: %v", err) 2288 } 2289 defer cleanUp() 2290 2291 n := newThreeHopNetwork(t, channels.aliceToBob, channels.bobToAlice, 2292 channels.bobToCarol, channels.carolToBob, testStartingHeight) 2293 if err := n.start(); err != nil { 2294 t.Fatalf("unable to start three hop network: %v", err) 2295 } 2296 2297 // We'll make now 10 payments, of 100k atoms each from Alice to 2298 // Carol via Bob. 2299 const numPayments = 10 2300 finalAmt := lnwire.NewMAtomsFromAtoms(100000) 2301 htlcAmt, totalTimelock, hops := generateHops( 2302 finalAmt, testStartingHeight, n.firstBobChannelLink, 2303 n.carolChannelLink, 2304 ) 2305 firstHop := n.firstBobChannelLink.ShortChanID() 2306 for i := 0; i < numPayments/2; i++ { 2307 _, err := makePayment( 2308 n.aliceServer, n.carolServer, firstHop, hops, finalAmt, 2309 htlcAmt, totalTimelock, 2310 ).Wait(30 * time.Second) 2311 if err != nil { 2312 t.Fatalf("unable to send payment: %v", err) 2313 } 2314 } 2315 2316 bobLog, ok := n.bobServer.htlcSwitch.cfg.FwdingLog.(*mockForwardingLog) 2317 if !ok { 2318 t.Fatalf("mockForwardingLog assertion failed") 2319 } 2320 2321 // After sending 5 of the payments, trigger the forwarding ticker, to 2322 // make sure the events are properly flushed. 2323 bobTicker, ok := n.bobServer.htlcSwitch.cfg.FwdEventTicker.(*ticker.Force) 2324 if !ok { 2325 t.Fatalf("mockTicker assertion failed") 2326 } 2327 2328 // We'll trigger the ticker, and wait for the events to appear in Bob's 2329 // forwarding log. 2330 timeout := time.After(15 * time.Second) 2331 for { 2332 select { 2333 case bobTicker.Force <- time.Now(): 2334 case <-time.After(1 * time.Second): 2335 t.Fatalf("unable to force tick") 2336 } 2337 2338 // If all 5 events is found in Bob's log, we can break out and 2339 // continue the test. 2340 bobLog.Lock() 2341 if len(bobLog.events) == 5 { 2342 bobLog.Unlock() 2343 break 2344 } 2345 bobLog.Unlock() 2346 2347 // Otherwise wait a little bit before checking again. 2348 select { 2349 case <-time.After(50 * time.Millisecond): 2350 case <-timeout: 2351 bobLog.Lock() 2352 defer bobLog.Unlock() 2353 t.Fatalf("expected 5 events in event log, instead "+ 2354 "found: %v", spew.Sdump(bobLog.events)) 2355 } 2356 } 2357 2358 // Send the remaining payments. 2359 for i := numPayments / 2; i < numPayments; i++ { 2360 _, err := makePayment( 2361 n.aliceServer, n.carolServer, firstHop, hops, finalAmt, 2362 htlcAmt, totalTimelock, 2363 ).Wait(30 * time.Second) 2364 if err != nil { 2365 t.Fatalf("unable to send payment: %v", err) 2366 } 2367 } 2368 2369 // With all 10 payments sent. We'll now manually stop each of the 2370 // switches so we can examine their end state. 2371 n.stop() 2372 2373 // Alice and Carol shouldn't have any recorded forwarding events, as 2374 // they were the source and the sink for these payment flows. 2375 aliceLog, ok := n.aliceServer.htlcSwitch.cfg.FwdingLog.(*mockForwardingLog) 2376 if !ok { 2377 t.Fatalf("mockForwardingLog assertion failed") 2378 } 2379 aliceLog.Lock() 2380 defer aliceLog.Unlock() 2381 if len(aliceLog.events) != 0 { 2382 t.Fatalf("log should have no events, instead has: %v", 2383 spew.Sdump(aliceLog.events)) 2384 } 2385 2386 carolLog, ok := n.carolServer.htlcSwitch.cfg.FwdingLog.(*mockForwardingLog) 2387 if !ok { 2388 t.Fatalf("mockForwardingLog assertion failed") 2389 } 2390 carolLog.Lock() 2391 defer carolLog.Unlock() 2392 if len(carolLog.events) != 0 { 2393 t.Fatalf("log should have no events, instead has: %v", 2394 spew.Sdump(carolLog.events)) 2395 } 2396 2397 // Bob on the other hand, should have 10 events. 2398 bobLog.Lock() 2399 defer bobLog.Unlock() 2400 if len(bobLog.events) != 10 { 2401 t.Fatalf("log should have 10 events, instead has: %v", 2402 spew.Sdump(bobLog.events)) 2403 } 2404 2405 // Each of the 10 events should have had all fields set properly. 2406 for _, event := range bobLog.events { 2407 // The incoming and outgoing channels should properly be set for 2408 // the event. 2409 if event.IncomingChanID != n.aliceChannelLink.ShortChanID() { 2410 t.Fatalf("chan id mismatch: expected %v, got %v", 2411 event.IncomingChanID, 2412 n.aliceChannelLink.ShortChanID()) 2413 } 2414 if event.OutgoingChanID != n.carolChannelLink.ShortChanID() { 2415 t.Fatalf("chan id mismatch: expected %v, got %v", 2416 event.OutgoingChanID, 2417 n.carolChannelLink.ShortChanID()) 2418 } 2419 2420 // Additionally, the incoming and outgoing amounts should also 2421 // be properly set. 2422 if event.AmtIn != htlcAmt { 2423 t.Fatalf("incoming amt mismatch: expected %v, got %v", 2424 event.AmtIn, htlcAmt) 2425 } 2426 if event.AmtOut != finalAmt { 2427 t.Fatalf("outgoing amt mismatch: expected %v, got %v", 2428 event.AmtOut, finalAmt) 2429 } 2430 } 2431 } 2432 2433 // TestUpdateFailMalformedHTLCErrorConversion tests that we're able to properly 2434 // convert malformed HTLC errors that originate at the direct link, as well as 2435 // during multi-hop HTLC forwarding. 2436 func TestUpdateFailMalformedHTLCErrorConversion(t *testing.T) { 2437 t.Parallel() 2438 2439 // First, we'll create our traditional three hop network. 2440 channels, cleanUp, _, err := createClusterChannels( 2441 dcrutil.AtomsPerCoin*3, dcrutil.AtomsPerCoin*5, 2442 ) 2443 if err != nil { 2444 t.Fatalf("unable to create channel: %v", err) 2445 } 2446 defer cleanUp() 2447 2448 n := newThreeHopNetwork( 2449 t, channels.aliceToBob, channels.bobToAlice, 2450 channels.bobToCarol, channels.carolToBob, testStartingHeight, 2451 ) 2452 if err := n.start(); err != nil { 2453 t.Fatalf("unable to start three hop network: %v", err) 2454 } 2455 2456 assertPaymentFailure := func(t *testing.T) { 2457 // With the decoder modified, we'll now attempt to send a 2458 // payment from Alice to carol. 2459 finalAmt := lnwire.NewMAtomsFromAtoms(100000) 2460 htlcAmt, totalTimelock, hops := generateHops( 2461 finalAmt, testStartingHeight, n.firstBobChannelLink, 2462 n.carolChannelLink, 2463 ) 2464 firstHop := n.firstBobChannelLink.ShortChanID() 2465 _, err = makePayment( 2466 n.aliceServer, n.carolServer, firstHop, hops, finalAmt, 2467 htlcAmt, totalTimelock, 2468 ).Wait(30 * time.Second) 2469 2470 // The payment should fail as Carol is unable to decode the 2471 // onion blob sent to her. 2472 if err == nil { 2473 t.Fatalf("unable to send payment: %v", err) 2474 } 2475 2476 routingErr := err.(ClearTextError) 2477 failureMsg := routingErr.WireMessage() 2478 if _, ok := failureMsg.(*lnwire.FailInvalidOnionKey); !ok { 2479 t.Fatalf("expected onion failure instead got: %v", 2480 routingErr.WireMessage()) 2481 } 2482 } 2483 2484 t.Run("multi-hop error conversion", func(t *testing.T) { 2485 // Now that we have our network up, we'll modify the hop 2486 // iterator for the Bob <-> Carol channel to fail to decode in 2487 // order to simulate either a replay attack or an issue 2488 // decoding the onion. 2489 n.carolOnionDecoder.decodeFail = true 2490 2491 assertPaymentFailure(t) 2492 }) 2493 2494 t.Run("direct channel error conversion", func(t *testing.T) { 2495 // Similar to the above test case, we'll now make the Alice <-> 2496 // Bob link always fail to decode an onion. This differs from 2497 // the above test case in that there's no encryption on the 2498 // error at all since Alice will directly receive a 2499 // UpdateFailMalformedHTLC message. 2500 n.bobOnionDecoder.decodeFail = true 2501 2502 assertPaymentFailure(t) 2503 }) 2504 } 2505 2506 // TestSwitchGetPaymentResult tests that the switch interacts as expected with 2507 // the circuit map and network result store when looking up the result of a 2508 // payment ID. This is important for not to lose results under concurrent 2509 // lookup and receiving results. 2510 func TestSwitchGetPaymentResult(t *testing.T) { 2511 t.Parallel() 2512 2513 const paymentID = 123 2514 var preimg lntypes.Preimage 2515 preimg[0] = 3 2516 2517 s, err := initSwitchWithDB(testStartingHeight, nil) 2518 if err != nil { 2519 t.Fatalf("unable to init switch: %v", err) 2520 } 2521 if err := s.Start(); err != nil { 2522 t.Fatalf("unable to start switch: %v", err) 2523 } 2524 defer s.Stop() 2525 2526 lookup := make(chan *PaymentCircuit, 1) 2527 s.circuits = &mockCircuitMap{ 2528 lookup: lookup, 2529 } 2530 2531 // If the payment circuit is not found in the circuit map, the payment 2532 // result must be found in the store if available. Since we haven't 2533 // added anything to the store yet, ErrPaymentIDNotFound should be 2534 // returned. 2535 lookup <- nil 2536 _, err = s.GetPaymentResult( 2537 paymentID, lntypes.Hash{}, newMockDeobfuscator(), 2538 ) 2539 if err != ErrPaymentIDNotFound { 2540 t.Fatalf("expected ErrPaymentIDNotFound, got %v", err) 2541 } 2542 2543 // Next let the lookup find the circuit in the circuit map. It should 2544 // subscribe to payment results, and return the result when available. 2545 lookup <- &PaymentCircuit{} 2546 resultChan, err := s.GetPaymentResult( 2547 paymentID, lntypes.Hash{}, newMockDeobfuscator(), 2548 ) 2549 if err != nil { 2550 t.Fatalf("unable to get payment result: %v", err) 2551 } 2552 2553 // Add the result to the store. 2554 n := &networkResult{ 2555 msg: &lnwire.UpdateFulfillHTLC{ 2556 PaymentPreimage: preimg, 2557 }, 2558 unencrypted: true, 2559 isResolution: true, 2560 } 2561 2562 err = s.networkResults.storeResult(paymentID, n) 2563 if err != nil { 2564 t.Fatalf("unable to store result: %v", err) 2565 } 2566 2567 // The result should be availble. 2568 select { 2569 case res, ok := <-resultChan: 2570 if !ok { 2571 t.Fatalf("channel was closed") 2572 } 2573 2574 if res.Error != nil { 2575 t.Fatalf("got unexpected error result") 2576 } 2577 2578 if res.Preimage != preimg { 2579 t.Fatalf("expected preimg %v, got %v", 2580 preimg, res.Preimage) 2581 } 2582 2583 case <-time.After(1 * time.Second): 2584 t.Fatalf("result not received") 2585 } 2586 2587 // As a final test, try to get the result again. Now that is no longer 2588 // in the circuit map, it should be immediately available from the 2589 // store. 2590 lookup <- nil 2591 resultChan, err = s.GetPaymentResult( 2592 paymentID, lntypes.Hash{}, newMockDeobfuscator(), 2593 ) 2594 if err != nil { 2595 t.Fatalf("unable to get payment result: %v", err) 2596 } 2597 2598 select { 2599 case res, ok := <-resultChan: 2600 if !ok { 2601 t.Fatalf("channel was closed") 2602 } 2603 2604 if res.Error != nil { 2605 t.Fatalf("got unexpected error result") 2606 } 2607 2608 if res.Preimage != preimg { 2609 t.Fatalf("expected preimg %v, got %v", 2610 preimg, res.Preimage) 2611 } 2612 2613 case <-time.After(1 * time.Second): 2614 t.Fatalf("result not received") 2615 } 2616 } 2617 2618 // TestInvalidFailure tests that the switch returns an unreadable failure error 2619 // if the failure cannot be decrypted. 2620 func TestInvalidFailure(t *testing.T) { 2621 t.Parallel() 2622 2623 alicePeer, err := newMockServer( 2624 t, "alice", testStartingHeight, nil, testDefaultDelta, 2625 ) 2626 if err != nil { 2627 t.Fatalf("unable to create alice server: %v", err) 2628 } 2629 2630 s, err := initSwitchWithDB(testStartingHeight, nil) 2631 if err != nil { 2632 t.Fatalf("unable to init switch: %v", err) 2633 } 2634 if err := s.Start(); err != nil { 2635 t.Fatalf("unable to start switch: %v", err) 2636 } 2637 defer s.Stop() 2638 2639 chanID1, _, aliceChanID, _ := genIDs() 2640 2641 // Set up a mock channel link. 2642 aliceChannelLink := newMockChannelLink( 2643 s, chanID1, aliceChanID, alicePeer, true, 2644 ) 2645 if err := s.AddLink(aliceChannelLink); err != nil { 2646 t.Fatalf("unable to add link: %v", err) 2647 } 2648 2649 // Create a request which should be forwarded to the mock channel link. 2650 preimage, err := genPreimage() 2651 if err != nil { 2652 t.Fatalf("unable to generate preimage: %v", err) 2653 } 2654 rhash := lntypes.Hash(sha256.Sum256(preimage[:])) 2655 update := &lnwire.UpdateAddHTLC{ 2656 PaymentHash: rhash, 2657 Amount: 1, 2658 } 2659 2660 paymentID := uint64(123) 2661 2662 // Send the request. 2663 err = s.SendHTLC( 2664 aliceChannelLink.ShortChanID(), paymentID, update, 2665 ) 2666 if err != nil { 2667 t.Fatalf("unable to send payment: %v", err) 2668 } 2669 2670 // Catch the packet and complete the circuit so that the switch is ready 2671 // for a response. 2672 select { 2673 case packet := <-aliceChannelLink.packets: 2674 if err := aliceChannelLink.completeCircuit(packet); err != nil { 2675 t.Fatalf("unable to complete payment circuit: %v", err) 2676 } 2677 2678 case <-time.After(time.Second): 2679 t.Fatal("request was not propagated to destination") 2680 } 2681 2682 // Send response packet with an unreadable failure message to the 2683 // switch. The reason failed is not relevant, because we mock the 2684 // decryption. 2685 packet := &htlcPacket{ 2686 outgoingChanID: aliceChannelLink.ShortChanID(), 2687 outgoingHTLCID: 0, 2688 amount: 1, 2689 htlc: &lnwire.UpdateFailHTLC{ 2690 Reason: []byte{1, 2, 3}, 2691 }, 2692 } 2693 2694 if err := s.ForwardPackets(nil, packet); err != nil { 2695 t.Fatalf("can't forward htlc packet: %v", err) 2696 } 2697 2698 // Get payment result from switch. We expect an unreadable failure 2699 // message error. 2700 deobfuscator := SphinxErrorDecrypter{ 2701 OnionErrorDecrypter: &mockOnionErrorDecryptor{ 2702 err: ErrUnreadableFailureMessage, 2703 }, 2704 } 2705 2706 resultChan, err := s.GetPaymentResult( 2707 paymentID, rhash, &deobfuscator, 2708 ) 2709 if err != nil { 2710 t.Fatal(err) 2711 } 2712 2713 select { 2714 case result := <-resultChan: 2715 if result.Error != ErrUnreadableFailureMessage { 2716 t.Fatal("expected unreadable failure message") 2717 } 2718 2719 case <-time.After(time.Second): 2720 t.Fatal("err wasn't received") 2721 } 2722 2723 // Modify the decryption to simulate that decryption went alright, but 2724 // the failure cannot be decoded. 2725 deobfuscator = SphinxErrorDecrypter{ 2726 OnionErrorDecrypter: &mockOnionErrorDecryptor{ 2727 sourceIdx: 2, 2728 message: []byte{200}, 2729 }, 2730 } 2731 2732 resultChan, err = s.GetPaymentResult( 2733 paymentID, rhash, &deobfuscator, 2734 ) 2735 if err != nil { 2736 t.Fatal(err) 2737 } 2738 2739 select { 2740 case result := <-resultChan: 2741 rtErr, ok := result.Error.(ClearTextError) 2742 if !ok { 2743 t.Fatal("expected ClearTextError") 2744 } 2745 source, ok := rtErr.(*ForwardingError) 2746 if !ok { 2747 t.Fatalf("expected forwarding error, got: %T", rtErr) 2748 } 2749 if source.FailureSourceIdx != 2 { 2750 t.Fatal("unexpected error source index") 2751 } 2752 if rtErr.WireMessage() != nil { 2753 t.Fatal("expected empty failure message") 2754 } 2755 2756 case <-time.After(time.Second): 2757 t.Fatal("err wasn't received") 2758 } 2759 } 2760 2761 // htlcNotifierEvents is a function that generates a set of expected htlc 2762 // notifier evetns for each node in a three hop network with the dynamic 2763 // values provided. These functions take dynamic values so that changes to 2764 // external systems (such as our default timelock delta) do not break 2765 // these tests. 2766 type htlcNotifierEvents func(channels *clusterChannels, htlcID uint64, 2767 ts time.Time, htlc *lnwire.UpdateAddHTLC, 2768 hops []*hop.Payload, 2769 preimage *lntypes.Preimage) ([]interface{}, []interface{}, []interface{}) 2770 2771 // TestHtlcNotifier tests the notifying of htlc events that are routed over a 2772 // three hop network. It sets up an Alice -> Bob -> Carol network and routes 2773 // payments from Alice -> Carol to test events from the perspective of a 2774 // sending (Alice), forwarding (Bob) and receiving (Carol) node. Test cases 2775 // are present for saduccessful and failed payments. 2776 func TestHtlcNotifier(t *testing.T) { 2777 tests := []struct { 2778 name string 2779 2780 // Options is a set of options to apply to the three hop 2781 // network's servers. 2782 options []serverOption 2783 2784 // expectedEvents is a function which returns an expected set 2785 // of events for the test. 2786 expectedEvents htlcNotifierEvents 2787 2788 // iterations is the number of times we will send a payment, 2789 // this is used to send more than one payment to force non- 2790 // zero htlc indexes to make sure we aren't just checking 2791 // default values. 2792 iterations int 2793 }{ 2794 { 2795 name: "successful three hop payment", 2796 options: nil, 2797 expectedEvents: func(channels *clusterChannels, 2798 htlcID uint64, ts time.Time, 2799 htlc *lnwire.UpdateAddHTLC, 2800 hops []*hop.Payload, 2801 preimage *lntypes.Preimage) ([]interface{}, 2802 []interface{}, []interface{}) { 2803 2804 return getThreeHopEvents( 2805 channels, htlcID, ts, htlc, hops, nil, preimage, 2806 ) 2807 }, 2808 iterations: 2, 2809 }, 2810 { 2811 name: "failed at forwarding link", 2812 // Set a functional option which disables bob as a 2813 // forwarding node to force a payment error. 2814 options: []serverOption{ 2815 serverOptionRejectHtlc(false, true, false), 2816 }, 2817 expectedEvents: func(channels *clusterChannels, 2818 htlcID uint64, ts time.Time, 2819 htlc *lnwire.UpdateAddHTLC, 2820 hops []*hop.Payload, 2821 preimage *lntypes.Preimage) ([]interface{}, 2822 []interface{}, []interface{}) { 2823 2824 return getThreeHopEvents( 2825 channels, htlcID, ts, htlc, hops, 2826 &LinkError{ 2827 msg: &lnwire.FailChannelDisabled{}, 2828 FailureDetail: OutgoingFailureForwardsDisabled, 2829 }, 2830 preimage, 2831 ) 2832 }, 2833 iterations: 1, 2834 }, 2835 } 2836 2837 for _, test := range tests { 2838 test := test 2839 2840 t.Run(test.name, func(t *testing.T) { 2841 testHtcNotifier( 2842 t, test.options, test.iterations, 2843 test.expectedEvents, 2844 ) 2845 }) 2846 } 2847 } 2848 2849 // testHtcNotifier runs a htlc notifier test. 2850 func testHtcNotifier(t *testing.T, testOpts []serverOption, iterations int, 2851 getEvents htlcNotifierEvents) { 2852 2853 t.Parallel() 2854 2855 // First, we'll create our traditional three hop 2856 // network. 2857 channels, cleanUp, _, err := createClusterChannels( 2858 dcrutil.AtomsPerCoin*3, 2859 dcrutil.AtomsPerCoin*5) 2860 if err != nil { 2861 t.Fatalf("unable to create channel: %v", err) 2862 } 2863 defer cleanUp() 2864 2865 // Mock time so that all events are reported with a static timestamp. 2866 now := time.Now() 2867 mockTime := func() time.Time { 2868 return now 2869 } 2870 2871 // Create htlc notifiers for each server in the three hop network and 2872 // start them. 2873 aliceNotifier := NewHtlcNotifier(mockTime) 2874 if err := aliceNotifier.Start(); err != nil { 2875 t.Fatalf("could not start alice notifier") 2876 } 2877 defer func() { 2878 if err := aliceNotifier.Stop(); err != nil { 2879 t.Fatalf("failed to stop alice notifier: %v", err) 2880 } 2881 }() 2882 2883 bobNotifier := NewHtlcNotifier(mockTime) 2884 if err := bobNotifier.Start(); err != nil { 2885 t.Fatalf("could not start bob notifier") 2886 } 2887 defer func() { 2888 if err := bobNotifier.Stop(); err != nil { 2889 t.Fatalf("failed to stop bob notifier: %v", err) 2890 } 2891 }() 2892 2893 carolNotifier := NewHtlcNotifier(mockTime) 2894 if err := carolNotifier.Start(); err != nil { 2895 t.Fatalf("could not start carol notifier") 2896 } 2897 defer func() { 2898 if err := carolNotifier.Stop(); err != nil { 2899 t.Fatalf("failed to stop carol notifier: %v", err) 2900 } 2901 }() 2902 2903 // Create a notifier server option which will set our htlc notifiers 2904 // for the three hop network. 2905 notifierOption := serverOptionWithHtlcNotifier( 2906 aliceNotifier, bobNotifier, carolNotifier, 2907 ) 2908 2909 // Add the htlcNotifier option to any other options 2910 // set in the test. 2911 options := append(testOpts, notifierOption) 2912 2913 n := newThreeHopNetwork( 2914 t, channels.aliceToBob, 2915 channels.bobToAlice, channels.bobToCarol, 2916 channels.carolToBob, testStartingHeight, 2917 options..., 2918 ) 2919 if err := n.start(); err != nil { 2920 t.Fatalf("unable to start three hop "+ 2921 "network: %v", err) 2922 } 2923 defer n.stop() 2924 2925 // Before we forward anything, subscribe to htlc events 2926 // from each notifier. 2927 aliceEvents, err := aliceNotifier.SubscribeHtlcEvents() 2928 if err != nil { 2929 t.Fatalf("could not subscribe to alice's"+ 2930 " events: %v", err) 2931 } 2932 defer aliceEvents.Cancel() 2933 2934 bobEvents, err := bobNotifier.SubscribeHtlcEvents() 2935 if err != nil { 2936 t.Fatalf("could not subscribe to bob's"+ 2937 " events: %v", err) 2938 } 2939 defer bobEvents.Cancel() 2940 2941 carolEvents, err := carolNotifier.SubscribeHtlcEvents() 2942 if err != nil { 2943 t.Fatalf("could not subscribe to carol's"+ 2944 " events: %v", err) 2945 } 2946 defer carolEvents.Cancel() 2947 2948 // Send multiple payments, as specified by the test to test incrementing 2949 // of htlc ids. 2950 for i := 0; i < iterations; i++ { 2951 // We'll start off by making a payment from 2952 // Alice -> Bob -> Carol. The preimage, generated 2953 // by Carol's Invoice is expected in the Settle events 2954 htlc, hops, preimage := n.sendThreeHopPayment(t) 2955 2956 alice, bob, carol := getEvents( 2957 channels, uint64(i), now, htlc, hops, preimage, 2958 ) 2959 2960 checkHtlcEvents(t, aliceEvents.Updates(), alice) 2961 checkHtlcEvents(t, bobEvents.Updates(), bob) 2962 checkHtlcEvents(t, carolEvents.Updates(), carol) 2963 2964 } 2965 } 2966 2967 // checkHtlcEvents checks that a subscription has the set of htlc events 2968 // we expect it to have. 2969 func checkHtlcEvents(t *testing.T, events <-chan interface{}, 2970 expectedEvents []interface{}) { 2971 2972 t.Helper() 2973 2974 for _, expected := range expectedEvents { 2975 select { 2976 case event := <-events: 2977 if !reflect.DeepEqual(event, expected) { 2978 t.Fatalf("expected %v, got: %v", expected, 2979 event) 2980 } 2981 2982 case <-time.After(5 * time.Second): 2983 t.Fatalf("expected event: %v", expected) 2984 } 2985 } 2986 } 2987 2988 // sendThreeHopPayment is a helper function which sends a payment over 2989 // Alice -> Bob -> Carol in a three hop network and returns Alice's first htlc 2990 // and the remainder of the hops. 2991 func (n *threeHopNetwork) sendThreeHopPayment(t *testing.T) (*lnwire.UpdateAddHTLC, 2992 []*hop.Payload, *lntypes.Preimage) { 2993 2994 amount := lnwire.NewMAtomsFromAtoms(dcrutil.AtomsPerCoin) 2995 2996 htlcAmt, totalTimelock, hops := generateHops(amount, testStartingHeight, 2997 n.firstBobChannelLink, n.carolChannelLink) 2998 blob, err := generateRoute(hops...) 2999 if err != nil { 3000 t.Fatal(err) 3001 } 3002 invoice, htlc, pid, err := generatePayment( 3003 amount, htlcAmt, totalTimelock, blob, 3004 ) 3005 if err != nil { 3006 t.Fatal(err) 3007 } 3008 3009 err = n.carolServer.registry.AddInvoice(*invoice, htlc.PaymentHash) 3010 if err != nil { 3011 t.Fatalf("unable to add invoice in carol registry: %v", err) 3012 } 3013 3014 if err := n.aliceServer.htlcSwitch.SendHTLC( 3015 n.firstBobChannelLink.ShortChanID(), pid, htlc, 3016 ); err != nil { 3017 t.Fatalf("could not send htlc") 3018 } 3019 3020 return htlc, hops, invoice.Terms.PaymentPreimage 3021 } 3022 3023 // getThreeHopEvents gets the set of htlc events that we expect for a payment 3024 // from Alice -> Bob -> Carol. If a non-nil link error is provided, the set 3025 // of events will fail on Bob's outgoing link. 3026 func getThreeHopEvents(channels *clusterChannels, htlcID uint64, 3027 ts time.Time, htlc *lnwire.UpdateAddHTLC, hops []*hop.Payload, 3028 linkError *LinkError, 3029 preimage *lntypes.Preimage) ([]interface{}, []interface{}, []interface{}) { 3030 3031 aliceKey := HtlcKey{ 3032 IncomingCircuit: zeroCircuit, 3033 OutgoingCircuit: channeldb.CircuitKey{ 3034 ChanID: channels.aliceToBob.ShortChanID(), 3035 HtlcID: htlcID, 3036 }, 3037 } 3038 3039 // Alice always needs a forwarding event because she initiates the 3040 // send. 3041 aliceEvents := []interface{}{ 3042 &ForwardingEvent{ 3043 HtlcKey: aliceKey, 3044 HtlcInfo: HtlcInfo{ 3045 OutgoingTimeLock: htlc.Expiry, 3046 OutgoingAmt: htlc.Amount, 3047 }, 3048 HtlcEventType: HtlcEventTypeSend, 3049 Timestamp: ts, 3050 }, 3051 } 3052 3053 bobKey := HtlcKey{ 3054 IncomingCircuit: channeldb.CircuitKey{ 3055 ChanID: channels.bobToAlice.ShortChanID(), 3056 HtlcID: htlcID, 3057 }, 3058 OutgoingCircuit: channeldb.CircuitKey{ 3059 ChanID: channels.bobToCarol.ShortChanID(), 3060 HtlcID: htlcID, 3061 }, 3062 } 3063 3064 bobInfo := HtlcInfo{ 3065 IncomingTimeLock: htlc.Expiry, 3066 IncomingAmt: htlc.Amount, 3067 OutgoingTimeLock: hops[1].FwdInfo.OutgoingCTLV, 3068 OutgoingAmt: hops[1].FwdInfo.AmountToForward, 3069 } 3070 3071 // If we expect the payment to fail, we add failures for alice and 3072 // bob, and no events for carol because the payment never reaches her. 3073 if linkError != nil { 3074 aliceEvents = append(aliceEvents, 3075 &ForwardingFailEvent{ 3076 HtlcKey: aliceKey, 3077 HtlcEventType: HtlcEventTypeSend, 3078 Timestamp: ts, 3079 }, 3080 ) 3081 3082 bobEvents := []interface{}{ 3083 &LinkFailEvent{ 3084 HtlcKey: bobKey, 3085 HtlcInfo: bobInfo, 3086 HtlcEventType: HtlcEventTypeForward, 3087 LinkError: linkError, 3088 Incoming: false, 3089 Timestamp: ts, 3090 }, 3091 } 3092 3093 return aliceEvents, bobEvents, nil 3094 } 3095 3096 // If we want to get events for a successful payment, we add a settle 3097 // for alice, a forward and settle for bob and a receive settle for 3098 // carol. 3099 aliceEvents = append( 3100 aliceEvents, 3101 &SettleEvent{ 3102 HtlcKey: aliceKey, 3103 Preimage: *preimage, 3104 HtlcEventType: HtlcEventTypeSend, 3105 Timestamp: ts, 3106 }, 3107 ) 3108 3109 bobEvents := []interface{}{ 3110 &ForwardingEvent{ 3111 HtlcKey: bobKey, 3112 HtlcInfo: bobInfo, 3113 HtlcEventType: HtlcEventTypeForward, 3114 Timestamp: ts, 3115 }, 3116 &SettleEvent{ 3117 HtlcKey: bobKey, 3118 Preimage: *preimage, 3119 HtlcEventType: HtlcEventTypeForward, 3120 Timestamp: ts, 3121 }, 3122 } 3123 3124 carolEvents := []interface{}{ 3125 &SettleEvent{ 3126 HtlcKey: HtlcKey{ 3127 IncomingCircuit: channeldb.CircuitKey{ 3128 ChanID: channels.carolToBob.ShortChanID(), 3129 HtlcID: htlcID, 3130 }, 3131 OutgoingCircuit: zeroCircuit, 3132 }, 3133 Preimage: *preimage, 3134 HtlcEventType: HtlcEventTypeReceive, 3135 Timestamp: ts, 3136 }, 3137 } 3138 3139 return aliceEvents, bobEvents, carolEvents 3140 } 3141 3142 type mockForwardInterceptor struct { 3143 intercepted InterceptedForward 3144 } 3145 3146 func (m *mockForwardInterceptor) InterceptForwardHtlc(intercepted InterceptedForward) bool { 3147 3148 m.intercepted = intercepted 3149 return true 3150 } 3151 3152 func (m *mockForwardInterceptor) settle(preimage lntypes.Preimage) error { 3153 return m.intercepted.Settle(preimage) 3154 } 3155 3156 func (m *mockForwardInterceptor) fail() error { 3157 return m.intercepted.Fail() 3158 } 3159 3160 func (m *mockForwardInterceptor) resume() error { 3161 return m.intercepted.Resume() 3162 } 3163 3164 func assertNumCircuits(t *testing.T, s *Switch, pending, opened int) { 3165 if s.circuits.NumPending() != pending { 3166 t.Fatal("wrong amount of half circuits") 3167 } 3168 if s.circuits.NumOpen() != opened { 3169 t.Fatal("wrong amount of circuits") 3170 } 3171 } 3172 3173 func assertOutgoingLinkReceive(t *testing.T, targetLink *mockChannelLink, 3174 expectReceive bool) { 3175 3176 // Pull packet from targetLink link. 3177 select { 3178 case packet := <-targetLink.packets: 3179 if !expectReceive { 3180 t.Fatal("forward was intercepted, shouldn't land at bob link") 3181 } else if err := targetLink.completeCircuit(packet); err != nil { 3182 t.Fatalf("unable to complete payment circuit: %v", err) 3183 } 3184 3185 case <-time.After(time.Second): 3186 if expectReceive { 3187 t.Fatal("request was not propagated to destination") 3188 } 3189 } 3190 } 3191 3192 func TestSwitchHoldForward(t *testing.T) { 3193 t.Parallel() 3194 3195 chanID1, chanID2, aliceChanID, bobChanID := genIDs() 3196 3197 alicePeer, err := newMockServer( 3198 t, "alice", testStartingHeight, nil, testDefaultDelta, 3199 ) 3200 if err != nil { 3201 t.Fatalf("unable to create alice server: %v", err) 3202 } 3203 bobPeer, err := newMockServer( 3204 t, "bob", testStartingHeight, nil, testDefaultDelta, 3205 ) 3206 if err != nil { 3207 t.Fatalf("unable to create bob server: %v", err) 3208 } 3209 3210 tempPath, err := ioutil.TempDir("", "circuitdb") 3211 if err != nil { 3212 t.Fatalf("unable to temporary path: %v", err) 3213 } 3214 3215 cdb, err := channeldb.Open(tempPath) 3216 if err != nil { 3217 t.Fatalf("unable to open channeldb: %v", err) 3218 } 3219 3220 s, err := initSwitchWithDB(testStartingHeight, cdb) 3221 if err != nil { 3222 t.Fatalf("unable to init switch: %v", err) 3223 } 3224 if err := s.Start(); err != nil { 3225 t.Fatalf("unable to start switch: %v", err) 3226 } 3227 3228 defer func() { 3229 if err := s.Stop(); err != nil { 3230 t.Fatalf(err.Error()) 3231 } 3232 }() 3233 3234 aliceChannelLink := newMockChannelLink( 3235 s, chanID1, aliceChanID, alicePeer, true, 3236 ) 3237 bobChannelLink := newMockChannelLink( 3238 s, chanID2, bobChanID, bobPeer, true, 3239 ) 3240 if err := s.AddLink(aliceChannelLink); err != nil { 3241 t.Fatalf("unable to add alice link: %v", err) 3242 } 3243 if err := s.AddLink(bobChannelLink); err != nil { 3244 t.Fatalf("unable to add bob link: %v", err) 3245 } 3246 3247 // Create request which should be forwarded from Alice channel link to 3248 // bob channel link. 3249 preimage := [sha256.Size]byte{1} 3250 rhash := sha256.Sum256(preimage[:]) 3251 ogPacket := &htlcPacket{ 3252 incomingChanID: aliceChannelLink.ShortChanID(), 3253 incomingHTLCID: 0, 3254 outgoingChanID: bobChannelLink.ShortChanID(), 3255 obfuscator: NewMockObfuscator(), 3256 htlc: &lnwire.UpdateAddHTLC{ 3257 PaymentHash: rhash, 3258 Amount: 1, 3259 }, 3260 } 3261 3262 forwardInterceptor := &mockForwardInterceptor{} 3263 switchForwardInterceptor := NewInterceptableSwitch(s) 3264 switchForwardInterceptor.SetInterceptor(forwardInterceptor.InterceptForwardHtlc) 3265 linkQuit := make(chan struct{}) 3266 3267 // Test resume a hold forward 3268 assertNumCircuits(t, s, 0, 0) 3269 if err := switchForwardInterceptor.ForwardPackets(linkQuit, ogPacket); err != nil { 3270 t.Fatalf("can't forward htlc packet: %v", err) 3271 } 3272 assertNumCircuits(t, s, 0, 0) 3273 assertOutgoingLinkReceive(t, bobChannelLink, false) 3274 3275 if err := forwardInterceptor.resume(); err != nil { 3276 t.Fatalf("failed to resume forward") 3277 } 3278 assertOutgoingLinkReceive(t, bobChannelLink, true) 3279 assertNumCircuits(t, s, 1, 1) 3280 3281 // settling the htlc to close the circuit. 3282 settle := &htlcPacket{ 3283 outgoingChanID: bobChannelLink.ShortChanID(), 3284 outgoingHTLCID: 0, 3285 amount: 1, 3286 htlc: &lnwire.UpdateFulfillHTLC{ 3287 PaymentPreimage: preimage, 3288 }, 3289 } 3290 if err := switchForwardInterceptor.ForwardPackets(linkQuit, settle); err != nil { 3291 t.Fatalf("can't forward htlc packet: %v", err) 3292 } 3293 assertOutgoingLinkReceive(t, aliceChannelLink, true) 3294 assertNumCircuits(t, s, 0, 0) 3295 3296 // Test failing a hold forward 3297 if err := switchForwardInterceptor.ForwardPackets(linkQuit, ogPacket); err != nil { 3298 t.Fatalf("can't forward htlc packet: %v", err) 3299 } 3300 assertNumCircuits(t, s, 0, 0) 3301 assertOutgoingLinkReceive(t, bobChannelLink, false) 3302 3303 if err := forwardInterceptor.fail(); err != nil { 3304 t.Fatalf("failed to cancel forward %v", err) 3305 } 3306 assertOutgoingLinkReceive(t, bobChannelLink, false) 3307 assertOutgoingLinkReceive(t, aliceChannelLink, true) 3308 assertNumCircuits(t, s, 0, 0) 3309 3310 // Test settling a hold forward 3311 if err := switchForwardInterceptor.ForwardPackets(linkQuit, ogPacket); err != nil { 3312 t.Fatalf("can't forward htlc packet: %v", err) 3313 } 3314 assertNumCircuits(t, s, 0, 0) 3315 assertOutgoingLinkReceive(t, bobChannelLink, false) 3316 3317 if err := forwardInterceptor.settle(preimage); err != nil { 3318 t.Fatal("failed to cancel forward") 3319 } 3320 assertOutgoingLinkReceive(t, bobChannelLink, false) 3321 assertOutgoingLinkReceive(t, aliceChannelLink, true) 3322 assertNumCircuits(t, s, 0, 0) 3323 } 3324 3325 // TestSwitchDustForwarding tests that the switch properly fails HTLC's which 3326 // have incoming or outgoing links that breach their dust thresholds. 3327 func TestSwitchDustForwarding(t *testing.T) { 3328 t.Parallel() 3329 3330 // We'll create a three-hop network: 3331 // - Alice has a dust limit of 6030 atoms with Bob 3332 // - Bob has a dust limit of 12060 atoms with Alice 3333 // - Bob has a dust limit of 6030 atoms with Carol 3334 // - Carol has a dust limit of 12060 atoms with Bob 3335 channels, cleanUp, _, err := createClusterChannels( 3336 dcrutil.AtomsPerCoin, dcrutil.AtomsPerCoin, 3337 ) 3338 require.NoError(t, err) 3339 defer cleanUp() 3340 3341 n := newThreeHopNetwork( 3342 t, channels.aliceToBob, channels.bobToAlice, 3343 channels.bobToCarol, channels.carolToBob, testStartingHeight, 3344 ) 3345 err = n.start() 3346 require.NoError(t, err) 3347 3348 // We'll also put Alice and Bob into hodl.ExitSettle mode, such that 3349 // they won't settle incoming exit-hop HTLC's automatically. 3350 n.aliceChannelLink.cfg.HodlMask = hodl.ExitSettle.Mask() 3351 n.firstBobChannelLink.cfg.HodlMask = hodl.ExitSettle.Mask() 3352 3353 // We'll test that once the default threshold is exceeded on the 3354 // Alice -> Bob channel, either side's calls to SendHTLC will fail. 3355 // This does not rely on the mailbox sum since there's no intermediate 3356 // hop. 3357 // 3358 // Alice will send 357 HTLC's of 700sats. Bob will also send 357 HTLC's 3359 // of 700sats. If either side attempts to send a dust HTLC, it will 3360 // fail so amounts below 800sats will breach the dust threshold. 3361 amt := lnwire.NewMAtomsFromAtoms(1677) 3362 aliceBobFirstHop := n.aliceChannelLink.ShortChanID() 3363 3364 sendDustHtlcs(t, n, true, amt, aliceBobFirstHop) 3365 sendDustHtlcs(t, n, false, amt, aliceBobFirstHop) 3366 3367 // Generate the parameters needed for Bob to send another dust HTLC. 3368 _, timelock, hops := generateHops( 3369 amt, testStartingHeight, n.aliceChannelLink, 3370 ) 3371 3372 blob, err := generateRoute(hops...) 3373 require.NoError(t, err) 3374 3375 // Assert that if Bob sends a dust HTLC it will fail. 3376 failingPreimage := lntypes.Preimage{0, 0, 3} 3377 failingHash := failingPreimage.Hash() 3378 failingHtlc := &lnwire.UpdateAddHTLC{ 3379 PaymentHash: failingHash, 3380 Amount: amt, 3381 Expiry: timelock, 3382 OnionBlob: blob, 3383 } 3384 3385 // Assert that the HTLC is failed due to the dust threshold. 3386 err = n.bobServer.htlcSwitch.SendHTLC( 3387 aliceBobFirstHop, uint64(150), failingHtlc, 3388 ) 3389 require.ErrorIs(t, err, errDustThresholdExceeded) 3390 3391 // Generate the parameters needed for bob to send a non-dust HTLC. 3392 nondustAmt := lnwire.NewMAtomsFromAtoms(30_000) 3393 _, _, hops = generateHops( 3394 nondustAmt, testStartingHeight, n.aliceChannelLink, 3395 ) 3396 3397 blob, err = generateRoute(hops...) 3398 require.NoError(t, err) 3399 3400 // Now attempt to send an HTLC above Bob's dust limit. It should 3401 // succeed. 3402 nondustPreimage := lntypes.Preimage{0, 0, 4} 3403 nondustHash := nondustPreimage.Hash() 3404 nondustHtlc := &lnwire.UpdateAddHTLC{ 3405 PaymentHash: nondustHash, 3406 Amount: nondustAmt, 3407 Expiry: timelock, 3408 OnionBlob: blob, 3409 } 3410 3411 // Assert that SendHTLC succeeds and evaluateDustThreshold returns 3412 // false. 3413 err = n.bobServer.htlcSwitch.SendHTLC( 3414 aliceBobFirstHop, uint64(150), nondustHtlc, 3415 ) 3416 require.NoError(t, err) 3417 3418 // Introduce Carol into the mix and assert that sending a multi-hop 3419 // dust HTLC to Alice will fail. Bob should fail back the HTLC with a 3420 // temporary channel failure. 3421 carolAmt, carolTimelock, carolHops := generateHops( 3422 amt, testStartingHeight, n.secondBobChannelLink, 3423 n.aliceChannelLink, 3424 ) 3425 3426 carolBlob, err := generateRoute(carolHops...) 3427 require.NoError(t, err) 3428 3429 carolPreimage := lntypes.Preimage{0, 0, 5} 3430 carolHash := carolPreimage.Hash() 3431 carolHtlc := &lnwire.UpdateAddHTLC{ 3432 PaymentHash: carolHash, 3433 Amount: carolAmt, 3434 Expiry: carolTimelock, 3435 OnionBlob: carolBlob, 3436 } 3437 3438 // Initialize Carol's attempt ID. 3439 carolAttemptID := 0 3440 3441 err = n.carolServer.htlcSwitch.SendHTLC( 3442 n.carolChannelLink.ShortChanID(), uint64(carolAttemptID), 3443 carolHtlc, 3444 ) 3445 require.NoError(t, err) 3446 carolAttemptID++ 3447 3448 carolResultChan, err := n.carolServer.htlcSwitch.GetPaymentResult( 3449 uint64(carolAttemptID-1), carolHash, newMockDeobfuscator(), 3450 ) 3451 require.NoError(t, err) 3452 3453 result, ok := <-carolResultChan 3454 require.True(t, ok) 3455 assertFailureCode( 3456 t, result.Error, lnwire.CodeTemporaryChannelFailure, 3457 ) 3458 3459 // Send an HTLC from Alice to Carol and assert that it is failed at the 3460 // call to SendHTLC. 3461 htlcAmt, totalTimelock, aliceHops := generateHops( 3462 amt, testStartingHeight, n.firstBobChannelLink, 3463 n.carolChannelLink, 3464 ) 3465 3466 blob, err = generateRoute(aliceHops...) 3467 require.NoError(t, err) 3468 3469 aliceMultihopPreimage := lntypes.Preimage{0, 0, 6} 3470 aliceMultihopHash := aliceMultihopPreimage.Hash() 3471 aliceMultihopHtlc := &lnwire.UpdateAddHTLC{ 3472 PaymentHash: aliceMultihopHash, 3473 Amount: htlcAmt, 3474 Expiry: totalTimelock, 3475 OnionBlob: blob, 3476 } 3477 3478 err = n.aliceServer.htlcSwitch.SendHTLC( 3479 n.aliceChannelLink.ShortChanID(), uint64(357), 3480 aliceMultihopHtlc, 3481 ) 3482 require.ErrorIs(t, err, errDustThresholdExceeded) 3483 } 3484 3485 // sendDustHtlcs is a helper function used to send many dust HTLC's to test the 3486 // Switch's dust-threshold logic. It takes a boolean denoting whether or not 3487 // Alice is the sender. 3488 func sendDustHtlcs(t *testing.T, n *threeHopNetwork, alice bool, 3489 amt lnwire.MilliAtom, sid lnwire.ShortChannelID) { 3490 3491 t.Helper() 3492 3493 // The number of dust HTLC's we'll send for both Alice and Bob. 3494 numHTLCs := 149 // 357 3495 3496 // Extract the destination into a variable. If alice is the sender, the 3497 // destination is Bob. 3498 destLink := n.aliceChannelLink 3499 if alice { 3500 destLink = n.firstBobChannelLink 3501 } 3502 3503 // Create hops that will be used in the onion payload. 3504 htlcAmt, totalTimelock, hops := generateHops( 3505 amt, testStartingHeight, destLink, 3506 ) 3507 3508 // Convert the hops to a blob that will be put in the Add message. 3509 blob, err := generateRoute(hops...) 3510 require.NoError(t, err) 3511 3512 // Create a slice to store the preimages. 3513 preimages := make([]lntypes.Preimage, numHTLCs) 3514 3515 // Initialize the attempt ID used in SendHTLC calls. 3516 attemptID := uint64(0) 3517 3518 // Deterministically generate preimages. Avoid the all-zeroes preimage 3519 // because that will be rejected by the database. We'll use a different 3520 // third byte for Alice and Bob. 3521 endByte := byte(2) 3522 if alice { 3523 endByte = byte(3) 3524 } 3525 3526 for i := 0; i < numHTLCs; i++ { 3527 preimages[i] = lntypes.Preimage{byte(i >> 8), byte(i), endByte} 3528 } 3529 3530 sendingSwitch := n.bobServer.htlcSwitch 3531 if alice { 3532 sendingSwitch = n.aliceServer.htlcSwitch 3533 } 3534 3535 // Call SendHTLC in a loop for numHTLCs. 3536 for i := 0; i < numHTLCs; i++ { 3537 // Construct the htlc packet. 3538 hash := preimages[i].Hash() 3539 3540 htlc := &lnwire.UpdateAddHTLC{ 3541 PaymentHash: hash, 3542 Amount: htlcAmt, 3543 Expiry: totalTimelock, 3544 OnionBlob: blob, 3545 } 3546 3547 err = sendingSwitch.SendHTLC(sid, attemptID, htlc) 3548 require.NoError(t, err, "at i %d", i) 3549 attemptID++ 3550 } 3551 } 3552 3553 // TestSwitchMailboxDust tests that the switch takes into account the mailbox 3554 // dust when evaluating the dust threshold. The mockChannelLink does not have 3555 // channel state, so this only tests the switch-mailbox interaction. 3556 func TestSwitchMailboxDust(t *testing.T) { 3557 t.Parallel() 3558 3559 alicePeer, err := newMockServer( 3560 t, "alice", testStartingHeight, nil, testDefaultDelta, 3561 ) 3562 require.NoError(t, err) 3563 3564 bobPeer, err := newMockServer( 3565 t, "bob", testStartingHeight, nil, testDefaultDelta, 3566 ) 3567 require.NoError(t, err) 3568 3569 carolPeer, err := newMockServer( 3570 t, "carol", testStartingHeight, nil, testDefaultDelta, 3571 ) 3572 require.NoError(t, err) 3573 3574 s, err := initSwitchWithDB(testStartingHeight, nil) 3575 require.NoError(t, err) 3576 err = s.Start() 3577 require.NoError(t, err) 3578 defer func() { 3579 _ = s.Stop() 3580 }() 3581 3582 chanID1, chanID2, aliceChanID, bobChanID := genIDs() 3583 3584 chanID3, carolChanID := genID() 3585 3586 aliceLink := newMockChannelLink( 3587 s, chanID1, aliceChanID, alicePeer, true, 3588 ) 3589 err = s.AddLink(aliceLink) 3590 require.NoError(t, err) 3591 3592 bobLink := newMockChannelLink( 3593 s, chanID2, bobChanID, bobPeer, true, 3594 ) 3595 err = s.AddLink(bobLink) 3596 require.NoError(t, err) 3597 3598 carolLink := newMockChannelLink( 3599 s, chanID3, carolChanID, carolPeer, true, 3600 ) 3601 err = s.AddLink(carolLink) 3602 require.NoError(t, err) 3603 3604 // mockChannelLink sets the local and remote dust limits of the mailbox 3605 // to 400 satoshis and the feerate to 0. We'll fill the mailbox up with 3606 // dust packets and assert that calls to SendHTLC will fail. 3607 preimage, err := genPreimage() 3608 require.NoError(t, err) 3609 rhash := sha256.Sum256(preimage[:]) 3610 amt := lnwire.NewMAtomsFromAtoms(350) 3611 addMsg := &lnwire.UpdateAddHTLC{ 3612 PaymentHash: rhash, 3613 Amount: amt, 3614 ChanID: chanID1, 3615 } 3616 3617 // Initialize the carolHTLCID. 3618 var carolHTLCID uint64 3619 3620 // It will take aliceCount HTLC's of 350sats to fill up Alice's mailbox 3621 // to the point where another would put Alice over the dust threshold. 3622 aliceCount := 1428 3623 3624 mailbox := s.mailOrchestrator.GetOrCreateMailBox(chanID1, aliceChanID) 3625 3626 for i := 0; i < aliceCount; i++ { 3627 alicePkt := &htlcPacket{ 3628 incomingChanID: carolChanID, 3629 incomingHTLCID: carolHTLCID, 3630 outgoingChanID: aliceChanID, 3631 obfuscator: NewMockObfuscator(), 3632 incomingAmount: amt, 3633 amount: amt, 3634 htlc: addMsg, 3635 } 3636 3637 err = mailbox.AddPacket(alicePkt) 3638 require.NoError(t, err) 3639 3640 carolHTLCID++ 3641 } 3642 3643 // Sending one more HTLC to Alice should result in the dust threshold 3644 // being breached. 3645 err = s.SendHTLC(aliceChanID, 0, addMsg) 3646 require.ErrorIs(t, err, errDustThresholdExceeded) 3647 3648 // We'll now call ForwardPackets from Bob to ensure that the mailbox 3649 // sum is also accounted for in the forwarding case. 3650 packet := &htlcPacket{ 3651 incomingChanID: bobChanID, 3652 incomingHTLCID: 0, 3653 outgoingChanID: aliceChanID, 3654 obfuscator: NewMockObfuscator(), 3655 incomingAmount: amt, 3656 amount: amt, 3657 htlc: &lnwire.UpdateAddHTLC{ 3658 PaymentHash: rhash, 3659 Amount: amt, 3660 ChanID: chanID1, 3661 }, 3662 } 3663 3664 err = s.ForwardPackets(nil, packet) 3665 require.NoError(t, err) 3666 3667 // Bob should receive a failure from the switch. 3668 select { 3669 case p := <-bobLink.packets: 3670 require.NotEmpty(t, p.linkFailure) 3671 assertFailureCode( 3672 t, p.linkFailure, lnwire.CodeTemporaryChannelFailure, 3673 ) 3674 3675 case <-time.After(5 * time.Second): 3676 t.Fatal("no timely reply from switch") 3677 } 3678 }