github.com/decred/dcrlnd@v0.7.6/htlcswitch/link_test.go (about) 1 package htlcswitch 2 3 import ( 4 "bytes" 5 "crypto/rand" 6 "encoding/binary" 7 "fmt" 8 "io" 9 "net" 10 "reflect" 11 "runtime" 12 "sync" 13 "testing" 14 "time" 15 16 "github.com/davecgh/go-spew/spew" 17 "github.com/go-errors/errors" 18 "github.com/stretchr/testify/require" 19 20 "github.com/decred/dcrd/chaincfg/chainhash" 21 "github.com/decred/dcrd/chaincfg/v3" 22 "github.com/decred/dcrd/dcrec/secp256k1/v4" 23 "github.com/decred/dcrd/dcrutil/v4" 24 "github.com/decred/dcrd/wire" 25 sphinx "github.com/decred/lightning-onion/v4" 26 27 "github.com/decred/dcrlnd/build" 28 "github.com/decred/dcrlnd/channeldb" 29 "github.com/decred/dcrlnd/contractcourt" 30 "github.com/decred/dcrlnd/htlcswitch/hodl" 31 "github.com/decred/dcrlnd/htlcswitch/hop" 32 "github.com/decred/dcrlnd/input" 33 "github.com/decred/dcrlnd/kvdb" 34 "github.com/decred/dcrlnd/lnpeer" 35 "github.com/decred/dcrlnd/lntest/wait" 36 "github.com/decred/dcrlnd/lntypes" 37 "github.com/decred/dcrlnd/lnwallet" 38 "github.com/decred/dcrlnd/lnwallet/chainfee" 39 "github.com/decred/dcrlnd/lnwire" 40 "github.com/decred/dcrlnd/ticker" 41 ) 42 43 const ( 44 testStartingHeight = 100 45 testDefaultDelta = 6 46 ) 47 48 // concurrentTester is a thread-safe wrapper around the Fatalf method of a 49 // *testing.T instance. With this wrapper multiple goroutines can safely 50 // attempt to fail a test concurrently. 51 type concurrentTester struct { 52 mtx sync.Mutex 53 *testing.T 54 } 55 56 func newConcurrentTester(t *testing.T) *concurrentTester { 57 return &concurrentTester{ 58 T: t, 59 } 60 } 61 62 func (c *concurrentTester) Fatalf(format string, args ...interface{}) { 63 c.T.Helper() 64 65 c.mtx.Lock() 66 defer c.mtx.Unlock() 67 68 c.T.Fatalf(format, args...) 69 } 70 71 // messageToString is used to produce less spammy log messages in trace mode by 72 // setting the 'Curve" parameter to nil. Doing this avoids printing out each of 73 // the field elements in the curve parameters for secp256k1. 74 func messageToString(msg lnwire.Message) string { 75 return spew.Sdump(msg) 76 } 77 78 // expectedMessage struct holds the message which travels from one peer to 79 // another, and additional information like, should this message we skipped for 80 // handling. 81 type expectedMessage struct { 82 from string 83 to string 84 message lnwire.Message 85 skip bool 86 } 87 88 // createLogFunc is a helper function which returns the function which will be 89 // used for logging message are received from another peer. 90 func createLogFunc(name string, channelID lnwire.ChannelID) messageInterceptor { 91 return func(m lnwire.Message) (bool, error) { 92 chanID, err := getChanID(m) 93 if err != nil { 94 return false, err 95 } 96 97 if chanID == channelID { 98 fmt.Printf("---------------------- \n %v received: "+ 99 "%v", name, messageToString(m)) 100 } 101 return false, nil 102 } 103 } 104 105 // createInterceptorFunc creates the function by the given set of messages 106 // which, checks the order of the messages and skip the ones which were 107 // indicated to be intercepted. 108 func createInterceptorFunc(prefix, receiver string, messages []expectedMessage, 109 chanID lnwire.ChannelID, debug bool) messageInterceptor { 110 111 // Filter message which should be received with given peer name. 112 var expectToReceive []expectedMessage 113 for _, message := range messages { 114 if message.to == receiver { 115 expectToReceive = append(expectToReceive, message) 116 } 117 } 118 119 // Return function which checks the message order and skip the 120 // messages. 121 return func(m lnwire.Message) (bool, error) { 122 messageChanID, err := getChanID(m) 123 if err != nil { 124 return false, err 125 } 126 127 if messageChanID == chanID { 128 if len(expectToReceive) == 0 { 129 return false, errors.Errorf("%v received "+ 130 "unexpected message out of range: %v", 131 receiver, m.MsgType()) 132 } 133 134 expectedMessage := expectToReceive[0] 135 expectToReceive = expectToReceive[1:] 136 137 if expectedMessage.message.MsgType() != m.MsgType() { 138 return false, errors.Errorf("%v received wrong message: \n"+ 139 "real: %v\nexpected: %v", receiver, m.MsgType(), 140 expectedMessage.message.MsgType()) 141 } 142 143 if debug { 144 var postfix string 145 if revocation, ok := m.(*lnwire.RevokeAndAck); ok { 146 var zeroHash chainhash.Hash 147 if bytes.Equal(zeroHash[:], revocation.Revocation[:]) { 148 postfix = "- empty revocation" 149 } 150 } 151 152 if expectedMessage.skip { 153 fmt.Printf("skipped: %v: %v %v \n", prefix, 154 m.MsgType(), postfix) 155 } else { 156 fmt.Printf("%v: %v %v \n", prefix, m.MsgType(), postfix) 157 } 158 } 159 160 return expectedMessage.skip, nil 161 } 162 return false, nil 163 } 164 } 165 166 // TestChannelLinkRevThenSig tests that if a link owes both a revocation and a 167 // signature to the counterparty (in this order), that they are sent as rev and 168 // then sig. 169 // 170 // Specifically, this tests the following scenario: 171 // 172 // A B 173 // 174 // <----add----- 175 // -----add----> 176 // <----sig----- 177 // -----rev----x 178 // -----sig----x 179 func TestChannelLinkRevThenSig(t *testing.T) { 180 t.Parallel() 181 182 const chanAmt = dcrutil.AtomsPerCoin * 5 183 const chanReserve = dcrutil.AtomsPerCoin * 1 184 aliceLink, bobChannel, batchTicker, start, cleanUp, restore, err := 185 newSingleLinkTestHarness(chanAmt, chanReserve) 186 require.NoError(t, err) 187 defer cleanUp() 188 189 err = start() 190 require.NoError(t, err) 191 defer aliceLink.Stop() 192 193 alice := newPersistentLinkHarness( 194 t, aliceLink, batchTicker, restore, 195 ) 196 197 var ( 198 coreLink = aliceLink.(*channelLink) 199 aliceMsgs = coreLink.cfg.Peer.(*mockPeer).sentMsgs 200 ) 201 202 ctx := linkTestContext{ 203 t: t, 204 aliceLink: aliceLink, 205 aliceMsgs: aliceMsgs, 206 bobChannel: bobChannel, 207 } 208 209 bobHtlc1 := generateHtlc(t, coreLink, 0) 210 211 // <-----add----- 212 // Send an htlc from Bob to Alice. 213 ctx.sendHtlcBobToAlice(bobHtlc1) 214 215 aliceHtlc1, _ := generateHtlcAndInvoice(t, 0) 216 217 // ------add----> 218 ctx.sendHtlcAliceToBob(0, aliceHtlc1) 219 ctx.receiveHtlcAliceToBob() 220 221 // <-----sig----- 222 ctx.sendCommitSigBobToAlice(1) 223 224 // ------rev----x 225 var msg lnwire.Message 226 select { 227 case msg = <-aliceMsgs: 228 case <-time.After(15 * time.Second): 229 t.Fatalf("did not receive message") 230 } 231 232 _, ok := msg.(*lnwire.RevokeAndAck) 233 require.True(t, ok) 234 235 // ------sig----x 236 // Trigger a commitsig from Alice->Bob. 237 select { 238 case batchTicker <- time.Now(): 239 case <-time.After(5 * time.Second): 240 t.Fatalf("could not force commit sig") 241 } 242 243 select { 244 case msg = <-aliceMsgs: 245 case <-time.After(15 * time.Second): 246 t.Fatalf("did not receive message") 247 } 248 249 comSig, ok := msg.(*lnwire.CommitSig) 250 require.True(t, ok) 251 252 if len(comSig.HtlcSigs) != 2 { 253 t.Fatalf("expected 2 htlc sigs, got %d", len(comSig.HtlcSigs)) 254 } 255 256 // Restart Alice so she sends and accepts ChannelReestablish. 257 cleanUp = alice.restart(false, true) 258 defer cleanUp() 259 260 ctx.aliceLink = alice.link 261 ctx.aliceMsgs = alice.msgs 262 263 // Restart Bob as well by calling NewLightningChannel. 264 bobSigner := bobChannel.Signer 265 bobPool := lnwallet.NewSigPool(runtime.NumCPU(), bobSigner) 266 bobChannel, err = lnwallet.NewLightningChannel( 267 bobSigner, bobChannel.State(), bobPool, 268 chaincfg.RegNetParams(), 269 ) 270 require.NoError(t, err) 271 err = bobPool.Start() 272 require.NoError(t, err) 273 274 ctx.bobChannel = bobChannel 275 276 // --reestablish-> 277 select { 278 case msg = <-ctx.aliceMsgs: 279 case <-time.After(15 * time.Second): 280 t.Fatalf("did not receive message") 281 } 282 283 _, ok = msg.(*lnwire.ChannelReestablish) 284 require.True(t, ok) 285 286 // <-reestablish-- 287 bobReest, err := bobChannel.State().ChanSyncMsg() 288 require.NoError(t, err) 289 ctx.aliceLink.HandleChannelUpdate(bobReest) 290 291 // ------rev----> 292 ctx.receiveRevAndAckAliceToBob() 293 294 // ------add----> 295 ctx.receiveHtlcAliceToBob() 296 297 // ------sig----> 298 ctx.receiveCommitSigAliceToBob(2) 299 } 300 301 // TestChannelLinkSigThenRev tests that if a link owes both a signature and a 302 // revocation to the counterparty (in this order), that they are sent as sig 303 // and then rev. 304 // 305 // Specifically, this tests the following scenario: 306 // 307 // A B 308 // 309 // <----add----- 310 // -----add----> 311 // -----sig----x 312 // <----sig----- 313 // -----rev----x 314 func TestChannelLinkSigThenRev(t *testing.T) { 315 t.Parallel() 316 317 const chanAmt = dcrutil.AtomsPerCoin * 5 318 const chanReserve = dcrutil.AtomsPerCoin * 1 319 aliceLink, bobChannel, batchTicker, start, cleanUp, restore, err := 320 newSingleLinkTestHarness(chanAmt, chanReserve) 321 require.NoError(t, err) 322 defer cleanUp() 323 324 err = start() 325 require.NoError(t, err) 326 defer aliceLink.Stop() 327 328 alice := newPersistentLinkHarness( 329 t, aliceLink, batchTicker, restore, 330 ) 331 332 var ( 333 coreLink = aliceLink.(*channelLink) 334 aliceMsgs = coreLink.cfg.Peer.(*mockPeer).sentMsgs 335 ) 336 337 ctx := linkTestContext{ 338 t: t, 339 aliceLink: aliceLink, 340 aliceMsgs: aliceMsgs, 341 bobChannel: bobChannel, 342 } 343 344 bobHtlc1 := generateHtlc(t, coreLink, 0) 345 346 // <-----add----- 347 // Send an htlc from Bob to Alice. 348 ctx.sendHtlcBobToAlice(bobHtlc1) 349 350 aliceHtlc1, _ := generateHtlcAndInvoice(t, 0) 351 352 // ------add----> 353 ctx.sendHtlcAliceToBob(0, aliceHtlc1) 354 ctx.receiveHtlcAliceToBob() 355 356 // ------sig----x 357 // Trigger a commitsig from Alice->Bob. 358 select { 359 case batchTicker <- time.Now(): 360 case <-time.After(5 * time.Second): 361 t.Fatalf("could not force commit sig") 362 } 363 364 var msg lnwire.Message 365 select { 366 case msg = <-aliceMsgs: 367 case <-time.After(15 * time.Second): 368 t.Fatalf("did not receive message") 369 } 370 371 comSig, ok := msg.(*lnwire.CommitSig) 372 require.True(t, ok) 373 374 if len(comSig.HtlcSigs) != 1 { 375 t.Fatalf("expected 1 htlc sig, got %d", len(comSig.HtlcSigs)) 376 } 377 378 // <-----sig----- 379 ctx.sendCommitSigBobToAlice(1) 380 381 // ------rev----x 382 select { 383 case msg = <-aliceMsgs: 384 case <-time.After(15 * time.Second): 385 t.Fatalf("did not receive message") 386 } 387 388 _, ok = msg.(*lnwire.RevokeAndAck) 389 require.True(t, ok) 390 391 // Restart Alice so she sends and accepts ChannelReestablish. 392 cleanUp = alice.restart(false, true) 393 defer cleanUp() 394 395 ctx.aliceLink = alice.link 396 ctx.aliceMsgs = alice.msgs 397 398 // Restart Bob as well by calling NewLightningChannel. 399 bobSigner := bobChannel.Signer 400 bobPool := lnwallet.NewSigPool(runtime.NumCPU(), bobSigner) 401 bobChannel, err = lnwallet.NewLightningChannel( 402 bobSigner, bobChannel.State(), bobPool, 403 chaincfg.RegNetParams(), 404 ) 405 require.NoError(t, err) 406 err = bobPool.Start() 407 require.NoError(t, err) 408 409 ctx.bobChannel = bobChannel 410 411 // --reestablish-> 412 select { 413 case msg = <-ctx.aliceMsgs: 414 case <-time.After(15 * time.Second): 415 t.Fatalf("did not receive message") 416 } 417 418 _, ok = msg.(*lnwire.ChannelReestablish) 419 require.True(t, ok) 420 421 // <-reestablish-- 422 bobReest, err := bobChannel.State().ChanSyncMsg() 423 require.NoError(t, err) 424 ctx.aliceLink.HandleChannelUpdate(bobReest) 425 426 // ------add----> 427 ctx.receiveHtlcAliceToBob() 428 429 // ------sig----> 430 ctx.receiveCommitSigAliceToBob(1) 431 432 // ------rev----> 433 ctx.receiveRevAndAckAliceToBob() 434 } 435 436 // TestChannelLinkSingleHopPayment in this test we checks the interaction 437 // between Alice and Bob within scope of one channel. 438 func TestChannelLinkSingleHopPayment(t *testing.T) { 439 t.Parallel() 440 441 // Setup a alice-bob network. 442 alice, bob, cleanUp, err := createTwoClusterChannels( 443 dcrutil.AtomsPerCoin*3, 444 dcrutil.AtomsPerCoin*5) 445 if err != nil { 446 t.Fatalf("unable to create channel: %v", err) 447 } 448 defer cleanUp() 449 450 n := newTwoHopNetwork( 451 t, alice.channel, bob.channel, testStartingHeight, 452 ) 453 if err := n.start(); err != nil { 454 t.Fatal(err) 455 } 456 defer n.stop() 457 458 aliceBandwidthBefore := n.aliceChannelLink.Bandwidth() 459 bobBandwidthBefore := n.bobChannelLink.Bandwidth() 460 461 debug := false 462 if debug { 463 // Log message that alice receives. 464 n.aliceServer.intersect(createLogFunc("alice", 465 n.aliceChannelLink.ChanID())) 466 467 // Log message that bob receives. 468 n.bobServer.intersect(createLogFunc("bob", 469 n.bobChannelLink.ChanID())) 470 } 471 472 amount := lnwire.NewMAtomsFromAtoms(dcrutil.AtomsPerCoin) 473 htlcAmt, totalTimelock, hops := generateHops(amount, testStartingHeight, 474 n.bobChannelLink) 475 476 // Wait for: 477 // * HTLC add request to be sent to bob. 478 // * alice<->bob commitment state to be updated. 479 // * settle request to be sent back from bob to alice. 480 // * alice<->bob commitment state to be updated. 481 // * user notification to be sent. 482 receiver := n.bobServer 483 firstHop := n.bobChannelLink.ShortChanID() 484 rhash, err := makePayment( 485 n.aliceServer, receiver, firstHop, hops, amount, htlcAmt, 486 totalTimelock, 487 ).Wait(30 * time.Second) 488 if err != nil { 489 t.Fatalf("unable to make the payment: %v", err) 490 } 491 492 // Wait for Alice to receive the revocation. 493 // 494 // TODO(roasbeef); replace with select over returned err chan 495 time.Sleep(2 * time.Second) 496 497 // Check that alice invoice was settled and bandwidth of HTLC 498 // links was changed. 499 invoice, err := receiver.registry.LookupInvoice(rhash) 500 if err != nil { 501 t.Fatalf("unable to get invoice: %v", err) 502 } 503 if invoice.State != channeldb.ContractSettled { 504 t.Fatal("alice invoice wasn't settled") 505 } 506 507 if aliceBandwidthBefore-amount != n.aliceChannelLink.Bandwidth() { 508 t.Fatal("alice bandwidth should have decrease on payment " + 509 "amount") 510 } 511 512 if bobBandwidthBefore+amount != n.bobChannelLink.Bandwidth() { 513 t.Fatalf("bob bandwidth isn't match: expected %v, got %v", 514 bobBandwidthBefore+amount, 515 n.bobChannelLink.Bandwidth()) 516 } 517 } 518 519 // TestChannelLinkMultiHopPayment checks the ability to send payment over two 520 // hops. In this test we send the payment from Carol to Alice over Bob peer. 521 // (Carol -> Bob -> Alice) and checking that HTLC was settled properly and 522 // balances were changed in two channels. 523 // 524 // The test is executed with two different OutgoingCltvRejectDelta values for 525 // bob. In addition to a normal positive value, we also test the zero case 526 // because this is currently the configured value in lnd 527 // (defaultOutgoingCltvRejectDelta). 528 func TestChannelLinkMultiHopPayment(t *testing.T) { 529 t.Run( 530 "bobOutgoingCltvRejectDelta 3", 531 func(t *testing.T) { 532 testChannelLinkMultiHopPayment(t, 3) 533 }, 534 ) 535 t.Run( 536 "bobOutgoingCltvRejectDelta 0", 537 func(t *testing.T) { 538 testChannelLinkMultiHopPayment(t, 0) 539 }, 540 ) 541 } 542 543 func testChannelLinkMultiHopPayment(t *testing.T, 544 bobOutgoingCltvRejectDelta uint32) { 545 546 t.Parallel() 547 548 channels, cleanUp, _, err := createClusterChannels( 549 dcrutil.AtomsPerCoin*3, 550 dcrutil.AtomsPerCoin*5) 551 if err != nil { 552 t.Fatalf("unable to create channel: %v", err) 553 } 554 defer cleanUp() 555 556 n := newThreeHopNetwork(t, channels.aliceToBob, channels.bobToAlice, 557 channels.bobToCarol, channels.carolToBob, testStartingHeight) 558 559 n.firstBobChannelLink.cfg.OutgoingCltvRejectDelta = 560 bobOutgoingCltvRejectDelta 561 562 n.secondBobChannelLink.cfg.OutgoingCltvRejectDelta = 563 bobOutgoingCltvRejectDelta 564 565 if err := n.start(); err != nil { 566 t.Fatal(err) 567 } 568 defer n.stop() 569 570 carolBandwidthBefore := n.carolChannelLink.Bandwidth() 571 firstBobBandwidthBefore := n.firstBobChannelLink.Bandwidth() 572 secondBobBandwidthBefore := n.secondBobChannelLink.Bandwidth() 573 aliceBandwidthBefore := n.aliceChannelLink.Bandwidth() 574 575 debug := false 576 if debug { 577 // Log messages that alice receives from bob. 578 n.aliceServer.intersect(createLogFunc("[alice]<-bob<-carol: ", 579 n.aliceChannelLink.ChanID())) 580 581 // Log messages that bob receives from alice. 582 n.bobServer.intersect(createLogFunc("alice->[bob]->carol: ", 583 n.firstBobChannelLink.ChanID())) 584 585 // Log messages that bob receives from carol. 586 n.bobServer.intersect(createLogFunc("alice<-[bob]<-carol: ", 587 n.secondBobChannelLink.ChanID())) 588 589 // Log messages that carol receives from bob. 590 n.carolServer.intersect(createLogFunc("alice->bob->[carol]", 591 n.carolChannelLink.ChanID())) 592 } 593 594 amount := lnwire.NewMAtomsFromAtoms(dcrutil.AtomsPerCoin) 595 htlcAmt, totalTimelock, hops := generateHops(amount, 596 testStartingHeight, 597 n.firstBobChannelLink, n.carolChannelLink) 598 599 // Wait for: 600 // * HTLC add request to be sent from Alice to Bob. 601 // * Alice<->Bob commitment states to be updated. 602 // * HTLC add request to be propagated to Carol. 603 // * Bob<->Carol commitment state to be updated. 604 // * settle request to be sent back from Carol to Bob. 605 // * Alice<->Bob commitment state to be updated. 606 // * settle request to be sent back from Bob to Alice. 607 // * Alice<->Bob commitment states to be updated. 608 // * user notification to be sent. 609 receiver := n.carolServer 610 firstHop := n.firstBobChannelLink.ShortChanID() 611 rhash, err := makePayment( 612 n.aliceServer, n.carolServer, firstHop, hops, amount, htlcAmt, 613 totalTimelock, 614 ).Wait(30 * time.Second) 615 if err != nil { 616 t.Fatalf("unable to send payment: %v", err) 617 } 618 619 // Wait for Alice and Bob's second link to receive the revocation. 620 time.Sleep(2 * time.Second) 621 622 // Check that Carol invoice was settled and bandwidth of HTLC 623 // links were changed. 624 invoice, err := receiver.registry.LookupInvoice(rhash) 625 if err != nil { 626 t.Fatalf("unable to get invoice: %v", err) 627 } 628 if invoice.State != channeldb.ContractSettled { 629 t.Fatal("carol invoice haven't been settled") 630 } 631 632 expectedAliceBandwidth := aliceBandwidthBefore - htlcAmt 633 if expectedAliceBandwidth != n.aliceChannelLink.Bandwidth() { 634 t.Fatalf("channel bandwidth incorrect: expected %v, got %v", 635 expectedAliceBandwidth, n.aliceChannelLink.Bandwidth()) 636 } 637 638 expectedBobBandwidth1 := firstBobBandwidthBefore + htlcAmt 639 if expectedBobBandwidth1 != n.firstBobChannelLink.Bandwidth() { 640 t.Fatalf("channel bandwidth incorrect: expected %v, got %v", 641 expectedBobBandwidth1, n.firstBobChannelLink.Bandwidth()) 642 } 643 644 expectedBobBandwidth2 := secondBobBandwidthBefore - amount 645 if expectedBobBandwidth2 != n.secondBobChannelLink.Bandwidth() { 646 t.Fatalf("channel bandwidth incorrect: expected %v, got %v", 647 expectedBobBandwidth2, n.secondBobChannelLink.Bandwidth()) 648 } 649 650 expectedCarolBandwidth := carolBandwidthBefore + amount 651 if expectedCarolBandwidth != n.carolChannelLink.Bandwidth() { 652 t.Fatalf("channel bandwidth incorrect: expected %v, got %v", 653 expectedCarolBandwidth, n.carolChannelLink.Bandwidth()) 654 } 655 } 656 657 // TestChannelLinkCancelFullCommitment tests the ability for links to cancel 658 // forwarded HTLCs once all of their commitment slots are full. 659 func TestChannelLinkCancelFullCommitment(t *testing.T) { 660 t.Parallel() 661 662 channels, cleanUp, _, err := createClusterChannels( 663 dcrutil.AtomsPerCoin*3, 664 dcrutil.AtomsPerCoin*5) 665 if err != nil { 666 t.Fatalf("unable to create channel: %v", err) 667 } 668 defer cleanUp() 669 670 n := newTwoHopNetwork( 671 t, channels.aliceToBob, channels.bobToAlice, testStartingHeight, 672 ) 673 if err := n.start(); err != nil { 674 t.Fatal(err) 675 } 676 defer n.stop() 677 678 // Fill up the commitment from Alice's side with 20 sat payments. 679 count := (input.MaxHTLCNumber / 2) 680 amt := lnwire.NewMAtomsFromAtoms(20000) 681 682 htlcAmt, totalTimelock, hopsForwards := generateHops(amt, 683 testStartingHeight, n.bobChannelLink) 684 685 firstHop := n.aliceChannelLink.ShortChanID() 686 687 // Create channels to buffer the preimage and error channels used in 688 // making the preliminary payments. 689 preimages := make([]lntypes.Preimage, count) 690 aliceErrChan := make(chan chan error, count) 691 692 var wg sync.WaitGroup 693 for i := 0; i < count; i++ { 694 // Deterministically generate preimages. Avoid the all-zeroes 695 // preimage because that will be rejected by the database. 696 preimages[i] = lntypes.Preimage{byte(i >> 8), byte(i), 1} 697 698 wg.Add(1) 699 go func(i int) { 700 defer wg.Done() 701 702 errChan := n.makeHoldPayment( 703 n.aliceServer, n.bobServer, firstHop, 704 hopsForwards, amt, htlcAmt, totalTimelock, 705 preimages[i], 706 ) 707 aliceErrChan <- errChan 708 }(i) 709 } 710 711 // Wait for Alice to finish filling her commitment. 712 wg.Wait() 713 close(aliceErrChan) 714 715 // Now make an additional payment from Alice to Bob, this should be 716 // canceled because the commitment in this direction is full. 717 err = <-makePayment( 718 n.aliceServer, n.bobServer, firstHop, hopsForwards, amt, 719 htlcAmt, totalTimelock, 720 ).err 721 if err == nil { 722 t.Fatalf("overflow payment should have failed") 723 } 724 lerr, ok := err.(*LinkError) 725 if !ok { 726 t.Fatalf("expected LinkError, got: %T", err) 727 } 728 729 msg := lerr.WireMessage() 730 if _, ok := msg.(*lnwire.FailTemporaryChannelFailure); !ok { 731 t.Fatalf("expected TemporaryChannelFailure, got: %T", msg) 732 } 733 734 // Now, settle all htlcs held by bob and clear the commitment of htlcs. 735 for _, preimage := range preimages { 736 preimage := preimage 737 738 // It's possible that the HTLCs have not been delivered to the 739 // invoice registry at this point, so we poll until we are able 740 // to settle. 741 err = wait.NoError(func() error { 742 return n.bobServer.registry.SettleHodlInvoice(preimage) 743 }, time.Minute) 744 if err != nil { 745 t.Fatal(err) 746 } 747 } 748 749 // Ensure that all of the payments sent by alice eventually succeed. 750 for errChan := range aliceErrChan { 751 err := <-errChan 752 if err != nil { 753 t.Fatalf("alice payment failed: %v", err) 754 } 755 } 756 } 757 758 // TestExitNodeTimelockPayloadMismatch tests that when an exit node receives an 759 // incoming HTLC, if the time lock encoded in the payload of the forwarded HTLC 760 // doesn't match the expected payment value, then the HTLC will be rejected 761 // with the appropriate error. 762 func TestExitNodeTimelockPayloadMismatch(t *testing.T) { 763 t.Parallel() 764 765 channels, cleanUp, _, err := createClusterChannels( 766 dcrutil.AtomsPerCoin*5, 767 dcrutil.AtomsPerCoin*5) 768 if err != nil { 769 t.Fatalf("unable to create channel: %v", err) 770 } 771 defer cleanUp() 772 773 n := newThreeHopNetwork(t, channels.aliceToBob, channels.bobToAlice, 774 channels.bobToCarol, channels.carolToBob, testStartingHeight) 775 if err := n.start(); err != nil { 776 t.Fatal(err) 777 } 778 defer n.stop() 779 780 const amount = dcrutil.AtomsPerCoin 781 htlcAmt, htlcExpiry, hops := generateHops(amount, 782 testStartingHeight, n.firstBobChannelLink) 783 784 // In order to exercise this case, we'll now _manually_ modify the 785 // per-hop payload for outgoing time lock to be the incorrect value. 786 // The proper value of the outgoing CLTV should be the policy set by 787 // the receiving node, instead we set it to be a random value. 788 hops[0].FwdInfo.OutgoingCTLV = 500 789 firstHop := n.firstBobChannelLink.ShortChanID() 790 _, err = makePayment( 791 n.aliceServer, n.bobServer, firstHop, hops, amount, htlcAmt, 792 htlcExpiry, 793 ).Wait(30 * time.Second) 794 if err == nil { 795 t.Fatalf("payment should have failed but didn't") 796 } 797 798 rtErr, ok := err.(ClearTextError) 799 if !ok { 800 t.Fatalf("expected a ClearTextError, instead got: %T", err) 801 } 802 803 switch rtErr.WireMessage().(type) { 804 case *lnwire.FailFinalIncorrectCltvExpiry: 805 default: 806 t.Fatalf("incorrect error, expected incorrect cltv expiry, "+ 807 "instead have: %v", err) 808 } 809 } 810 811 // TestExitNodeAmountPayloadMismatch tests that when an exit node receives an 812 // incoming HTLC, if the amount encoded in the onion payload of the forwarded 813 // HTLC doesn't match the expected payment value, then the HTLC will be 814 // rejected. 815 func TestExitNodeAmountPayloadMismatch(t *testing.T) { 816 t.Parallel() 817 818 channels, cleanUp, _, err := createClusterChannels( 819 dcrutil.AtomsPerCoin*5, 820 dcrutil.AtomsPerCoin*5) 821 if err != nil { 822 t.Fatalf("unable to create channel: %v", err) 823 } 824 defer cleanUp() 825 826 n := newThreeHopNetwork(t, channels.aliceToBob, channels.bobToAlice, 827 channels.bobToCarol, channels.carolToBob, testStartingHeight) 828 if err := n.start(); err != nil { 829 t.Fatal(err) 830 } 831 defer n.stop() 832 833 const amount = dcrutil.AtomsPerCoin 834 htlcAmt, htlcExpiry, hops := generateHops(amount, testStartingHeight, 835 n.firstBobChannelLink) 836 837 // In order to exercise this case, we'll now _manually_ modify the 838 // per-hop payload for amount to be the incorrect value. The proper 839 // value of the amount to forward should be the amount that the 840 // receiving node expects to receive. 841 hops[0].FwdInfo.AmountToForward = 1 842 firstHop := n.firstBobChannelLink.ShortChanID() 843 _, err = makePayment( 844 n.aliceServer, n.bobServer, firstHop, hops, amount, htlcAmt, 845 htlcExpiry, 846 ).Wait(30 * time.Second) 847 if err == nil { 848 t.Fatalf("payment should have failed but didn't") 849 } 850 assertFailureCode(t, err, lnwire.CodeFinalIncorrectHtlcAmount) 851 } 852 853 // TestLinkForwardTimelockPolicyMismatch tests that if a node is an 854 // intermediate node in a multi-hop payment, and receives an HTLC which 855 // violates its specified multi-hop policy, then the HTLC is rejected. 856 func TestLinkForwardTimelockPolicyMismatch(t *testing.T) { 857 t.Parallel() 858 859 channels, cleanUp, _, err := createClusterChannels( 860 dcrutil.AtomsPerCoin*5, 861 dcrutil.AtomsPerCoin*5) 862 if err != nil { 863 t.Fatalf("unable to create channel: %v", err) 864 } 865 defer cleanUp() 866 867 n := newThreeHopNetwork(t, channels.aliceToBob, channels.bobToAlice, 868 channels.bobToCarol, channels.carolToBob, testStartingHeight) 869 if err := n.start(); err != nil { 870 t.Fatal(err) 871 } 872 defer n.stop() 873 874 // We'll be sending 1 DCR over a 2-hop (3 vertex) route. 875 amount := lnwire.NewMAtomsFromAtoms(dcrutil.AtomsPerCoin) 876 877 // Generate the route over two hops, ignoring the total time lock that 878 // we'll need to use for the first HTLC in order to have a sufficient 879 // time-lock value to account for the decrements over the entire route. 880 htlcAmt, htlcExpiry, hops := generateHops(amount, testStartingHeight, 881 n.firstBobChannelLink, n.carolChannelLink) 882 htlcExpiry -= 2 883 884 // Next, we'll make the payment which'll send an HTLC with our 885 // specified parameters to the first hop in the route. 886 firstHop := n.firstBobChannelLink.ShortChanID() 887 _, err = makePayment( 888 n.aliceServer, n.carolServer, firstHop, hops, amount, htlcAmt, 889 htlcExpiry, 890 ).Wait(30 * time.Second) 891 892 // We should get an error, and that error should indicate that the HTLC 893 // should be rejected due to a policy violation. 894 if err == nil { 895 t.Fatalf("payment should have failed but didn't") 896 } 897 898 rtErr, ok := err.(ClearTextError) 899 if !ok { 900 t.Fatalf("expected a ClearTextError, instead got: %T", err) 901 } 902 903 switch rtErr.WireMessage().(type) { 904 case *lnwire.FailIncorrectCltvExpiry: 905 default: 906 t.Fatalf("incorrect error, expected incorrect cltv expiry, "+ 907 "instead have: %v", err) 908 } 909 } 910 911 // TestLinkForwardFeePolicyMismatch tests that if a node is an intermediate 912 // node in a multi-hop payment and receives an HTLC that violates its current 913 // fee policy, then the HTLC is rejected with the proper error. 914 func TestLinkForwardFeePolicyMismatch(t *testing.T) { 915 t.Parallel() 916 917 channels, cleanUp, _, err := createClusterChannels( 918 dcrutil.AtomsPerCoin*3, 919 dcrutil.AtomsPerCoin*5) 920 if err != nil { 921 t.Fatalf("unable to create channel: %v", err) 922 } 923 defer cleanUp() 924 925 n := newThreeHopNetwork(t, channels.aliceToBob, channels.bobToAlice, 926 channels.bobToCarol, channels.carolToBob, testStartingHeight) 927 if err := n.start(); err != nil { 928 t.Fatal(err) 929 } 930 defer n.stop() 931 932 // We'll be sending 1 DCR over a 2-hop (3 vertex) route. Given the 933 // current default fee of 1 Atom, if we just send a single DCR over in 934 // an HTLC, it should be rejected. 935 amountNoFee := lnwire.NewMAtomsFromAtoms(dcrutil.AtomsPerCoin) 936 937 // Generate the route over two hops, ignoring the amount we _should_ 938 // actually send in order to be able to cover fees. 939 _, htlcExpiry, hops := generateHops(amountNoFee, testStartingHeight, 940 n.firstBobChannelLink, n.carolChannelLink) 941 942 // Next, we'll make the payment which'll send an HTLC with our 943 // specified parameters to the first hop in the route. 944 firstHop := n.firstBobChannelLink.ShortChanID() 945 _, err = makePayment( 946 n.aliceServer, n.bobServer, firstHop, hops, amountNoFee, 947 amountNoFee, htlcExpiry, 948 ).Wait(30 * time.Second) 949 950 // We should get an error, and that error should indicate that the HTLC 951 // should be rejected due to a policy violation. 952 if err == nil { 953 t.Fatalf("payment should have failed but didn't") 954 } 955 956 rtErr, ok := err.(ClearTextError) 957 if !ok { 958 t.Fatalf("expected a ClearTextError, instead got: %T", err) 959 } 960 961 switch rtErr.WireMessage().(type) { 962 case *lnwire.FailFeeInsufficient: 963 default: 964 t.Fatalf("incorrect error, expected fee insufficient, "+ 965 "instead have: %T", err) 966 } 967 } 968 969 // TestLinkForwardFeePolicyMismatch tests that if a node is an intermediate 970 // node and receives an HTLC which is _below_ its min HTLC policy, then the 971 // HTLC will be rejected. 972 func TestLinkForwardMinHTLCPolicyMismatch(t *testing.T) { 973 t.Parallel() 974 975 channels, cleanUp, _, err := createClusterChannels( 976 dcrutil.AtomsPerCoin*5, 977 dcrutil.AtomsPerCoin*5) 978 if err != nil { 979 t.Fatalf("unable to create channel: %v", err) 980 } 981 defer cleanUp() 982 983 n := newThreeHopNetwork(t, channels.aliceToBob, channels.bobToAlice, 984 channels.bobToCarol, channels.carolToBob, testStartingHeight) 985 if err := n.start(); err != nil { 986 t.Fatal(err) 987 } 988 defer n.stop() 989 990 // The current default global min HTLC policy set in the default config 991 // for the three-hop-network is 5 Atoms. So in order to trigger this 992 // failure mode, we'll create an HTLC with 1 atom. 993 amountNoFee := lnwire.NewMAtomsFromAtoms(1) 994 995 // With the amount set, we'll generate a route over 2 hops within the 996 // network that attempts to pay out our specified amount. 997 htlcAmt, htlcExpiry, hops := generateHops(amountNoFee, testStartingHeight, 998 n.firstBobChannelLink, n.carolChannelLink) 999 1000 // Next, we'll make the payment which'll send an HTLC with our 1001 // specified parameters to the first hop in the route. 1002 firstHop := n.firstBobChannelLink.ShortChanID() 1003 _, err = makePayment( 1004 n.aliceServer, n.bobServer, firstHop, hops, amountNoFee, 1005 htlcAmt, htlcExpiry, 1006 ).Wait(30 * time.Second) 1007 1008 // We should get an error, and that error should indicate that the HTLC 1009 // should be rejected due to a policy violation (below min HTLC). 1010 if err == nil { 1011 t.Fatalf("payment should have failed but didn't") 1012 } 1013 1014 rtErr, ok := err.(ClearTextError) 1015 if !ok { 1016 t.Fatalf("expected a ClearTextError, instead got: %T", err) 1017 } 1018 1019 switch rtErr.WireMessage().(type) { 1020 case *lnwire.FailAmountBelowMinimum: 1021 default: 1022 t.Fatalf("incorrect error, expected amount below minimum, "+ 1023 "instead have: %v", err) 1024 } 1025 } 1026 1027 // TestLinkForwardMaxHTLCPolicyMismatch tests that if a node is an intermediate 1028 // node and receives an HTLC which is _above_ its max HTLC policy then the 1029 // HTLC will be rejected. 1030 func TestLinkForwardMaxHTLCPolicyMismatch(t *testing.T) { 1031 t.Parallel() 1032 1033 channels, cleanUp, _, err := createClusterChannels( 1034 dcrutil.AtomsPerCoin*5, dcrutil.AtomsPerCoin*5, 1035 ) 1036 if err != nil { 1037 t.Fatalf("unable to create channel: %v", err) 1038 } 1039 defer cleanUp() 1040 1041 n := newThreeHopNetwork( 1042 t, channels.aliceToBob, channels.bobToAlice, channels.bobToCarol, 1043 channels.carolToBob, testStartingHeight, 1044 ) 1045 if err := n.start(); err != nil { 1046 t.Fatal(err) 1047 } 1048 defer n.stop() 1049 1050 // In order to trigger this failure mode, we'll update our policy to 1051 // have a new max HTLC of 10 atoms. 1052 maxHtlc := lnwire.NewMAtomsFromAtoms(10) 1053 1054 // First we'll generate a route over 2 hops within the network that 1055 // attempts to pay out an amount greater than the max HTLC we're about to 1056 // set. 1057 amountNoFee := maxHtlc + 1 1058 htlcAmt, htlcExpiry, hops := generateHops( 1059 amountNoFee, testStartingHeight, n.firstBobChannelLink, 1060 n.carolChannelLink, 1061 ) 1062 1063 // We'll now update Bob's policy to set the max HTLC we chose earlier. 1064 n.secondBobChannelLink.cfg.FwrdingPolicy.MaxHTLC = maxHtlc 1065 1066 // Finally, we'll make the payment which'll send an HTLC with our 1067 // specified parameters. 1068 firstHop := n.firstBobChannelLink.ShortChanID() 1069 _, err = makePayment( 1070 n.aliceServer, n.carolServer, firstHop, hops, amountNoFee, 1071 htlcAmt, htlcExpiry, 1072 ).Wait(30 * time.Second) 1073 1074 // We should get an error indicating a temporary channel failure, The 1075 // failure is temporary because this payment would be allowed if Bob 1076 // updated his policy to increase the max HTLC. 1077 if err == nil { 1078 t.Fatalf("payment should have failed but didn't") 1079 } 1080 1081 rtErr, ok := err.(ClearTextError) 1082 if !ok { 1083 t.Fatalf("expected a ClearTextError, instead got: %T", err) 1084 } 1085 1086 switch rtErr.WireMessage().(type) { 1087 case *lnwire.FailTemporaryChannelFailure: 1088 default: 1089 t.Fatalf("incorrect error, expected temporary channel failure, "+ 1090 "instead have: %v", err) 1091 } 1092 } 1093 1094 // TestUpdateForwardingPolicy tests that the forwarding policy for a link is 1095 // able to be updated properly. We'll first create an HTLC that meets the 1096 // specified policy, assert that it succeeds, update the policy (to invalidate 1097 // the prior HTLC), and then ensure that the HTLC is rejected. 1098 func TestUpdateForwardingPolicy(t *testing.T) { 1099 t.Parallel() 1100 1101 channels, cleanUp, _, err := createClusterChannels( 1102 dcrutil.AtomsPerCoin*5, 1103 dcrutil.AtomsPerCoin*5) 1104 if err != nil { 1105 t.Fatalf("unable to create channel: %v", err) 1106 } 1107 defer cleanUp() 1108 1109 n := newThreeHopNetwork(t, channels.aliceToBob, channels.bobToAlice, 1110 channels.bobToCarol, channels.carolToBob, testStartingHeight) 1111 if err := n.start(); err != nil { 1112 t.Fatal(err) 1113 } 1114 defer n.stop() 1115 1116 carolBandwidthBefore := n.carolChannelLink.Bandwidth() 1117 firstBobBandwidthBefore := n.firstBobChannelLink.Bandwidth() 1118 secondBobBandwidthBefore := n.secondBobChannelLink.Bandwidth() 1119 aliceBandwidthBefore := n.aliceChannelLink.Bandwidth() 1120 1121 amountNoFee := lnwire.NewMAtomsFromAtoms(10) 1122 htlcAmt, htlcExpiry, hops := generateHops(amountNoFee, 1123 testStartingHeight, 1124 n.firstBobChannelLink, n.carolChannelLink) 1125 1126 // First, send this 10 milli-atoms payment over the three hops, the payment 1127 // should succeed, and all balances should be updated accordingly. 1128 firstHop := n.firstBobChannelLink.ShortChanID() 1129 payResp, err := makePayment( 1130 n.aliceServer, n.carolServer, firstHop, hops, amountNoFee, 1131 htlcAmt, htlcExpiry, 1132 ).Wait(30 * time.Second) 1133 if err != nil { 1134 t.Fatalf("unable to send payment: %v", err) 1135 } 1136 1137 // Carol's invoice should now be shown as settled as the payment 1138 // succeeded. 1139 invoice, err := n.carolServer.registry.LookupInvoice(payResp) 1140 if err != nil { 1141 t.Fatalf("unable to get invoice: %v", err) 1142 } 1143 if invoice.State != channeldb.ContractSettled { 1144 t.Fatal("carol invoice haven't been settled") 1145 } 1146 1147 expectedAliceBandwidth := aliceBandwidthBefore - htlcAmt 1148 if expectedAliceBandwidth != n.aliceChannelLink.Bandwidth() { 1149 t.Fatalf("channel bandwidth incorrect: expected %v, got %v", 1150 expectedAliceBandwidth, n.aliceChannelLink.Bandwidth()) 1151 } 1152 expectedBobBandwidth1 := firstBobBandwidthBefore + htlcAmt 1153 if expectedBobBandwidth1 != n.firstBobChannelLink.Bandwidth() { 1154 t.Fatalf("channel bandwidth incorrect: expected %v, got %v", 1155 expectedBobBandwidth1, n.firstBobChannelLink.Bandwidth()) 1156 } 1157 expectedBobBandwidth2 := secondBobBandwidthBefore - amountNoFee 1158 if expectedBobBandwidth2 != n.secondBobChannelLink.Bandwidth() { 1159 t.Fatalf("channel bandwidth incorrect: expected %v, got %v", 1160 expectedBobBandwidth2, n.secondBobChannelLink.Bandwidth()) 1161 } 1162 expectedCarolBandwidth := carolBandwidthBefore + amountNoFee 1163 if expectedCarolBandwidth != n.carolChannelLink.Bandwidth() { 1164 t.Fatalf("channel bandwidth incorrect: expected %v, got %v", 1165 expectedCarolBandwidth, n.carolChannelLink.Bandwidth()) 1166 } 1167 1168 // Now we'll update Bob's policy to jack up his free rate to an extent 1169 // that'll cause him to reject the same HTLC that we just sent. 1170 // 1171 // TODO(roasbeef): should implement grace period within link policy 1172 // update logic 1173 newPolicy := n.globalPolicy 1174 newPolicy.BaseFee = lnwire.NewMAtomsFromAtoms(1000) 1175 n.secondBobChannelLink.UpdateForwardingPolicy(newPolicy) 1176 1177 // Next, we'll send the payment again, using the exact same per-hop 1178 // payload for each node. This payment should fail as it won't factor 1179 // in Bob's new fee policy. 1180 _, err = makePayment( 1181 n.aliceServer, n.carolServer, firstHop, hops, amountNoFee, 1182 htlcAmt, htlcExpiry, 1183 ).Wait(30 * time.Second) 1184 if err == nil { 1185 t.Fatalf("payment should've been rejected") 1186 } 1187 1188 rtErr, ok := err.(ClearTextError) 1189 if !ok { 1190 t.Fatalf("expected a ClearTextError, instead got (%T): %v", err, err) 1191 } 1192 1193 switch rtErr.WireMessage().(type) { 1194 case *lnwire.FailFeeInsufficient: 1195 default: 1196 t.Fatalf("expected FailFeeInsufficient instead got: %v", err) 1197 } 1198 1199 // Reset the policy so we can then test updating the max HTLC policy. 1200 n.secondBobChannelLink.UpdateForwardingPolicy(n.globalPolicy) 1201 1202 // As a sanity check, ensure the original payment now succeeds again. 1203 _, err = makePayment( 1204 n.aliceServer, n.carolServer, firstHop, hops, amountNoFee, 1205 htlcAmt, htlcExpiry, 1206 ).Wait(30 * time.Second) 1207 if err != nil { 1208 t.Fatalf("unable to send payment: %v", err) 1209 } 1210 1211 // Now we'll update Bob's policy to lower his max HTLC to an extent 1212 // that'll cause him to reject the same HTLC that we just sent. 1213 newPolicy = n.globalPolicy 1214 newPolicy.MaxHTLC = amountNoFee - 1 1215 n.secondBobChannelLink.UpdateForwardingPolicy(newPolicy) 1216 1217 // Next, we'll send the payment again, using the exact same per-hop 1218 // payload for each node. This payment should fail as it won't factor 1219 // in Bob's new max HTLC policy. 1220 _, err = makePayment( 1221 n.aliceServer, n.carolServer, firstHop, hops, amountNoFee, 1222 htlcAmt, htlcExpiry, 1223 ).Wait(30 * time.Second) 1224 if err == nil { 1225 t.Fatalf("payment should've been rejected") 1226 } 1227 1228 rtErr, ok = err.(ClearTextError) 1229 if !ok { 1230 t.Fatalf("expected a ClearTextError, instead got (%T): %v", 1231 err, err) 1232 } 1233 1234 switch rtErr.WireMessage().(type) { 1235 case *lnwire.FailTemporaryChannelFailure: 1236 default: 1237 t.Fatalf("expected TemporaryChannelFailure, instead got: %v", 1238 err) 1239 } 1240 } 1241 1242 // TestChannelLinkMultiHopInsufficientPayment checks that we receive error if 1243 // bob<->alice channel has insufficient DCR capacity/bandwidth. In this test we 1244 // send the payment from Carol to Alice over Bob peer. (Carol -> Bob -> Alice) 1245 func TestChannelLinkMultiHopInsufficientPayment(t *testing.T) { 1246 t.Parallel() 1247 1248 channels, cleanUp, _, err := createClusterChannels( 1249 dcrutil.AtomsPerCoin*3, 1250 dcrutil.AtomsPerCoin*5) 1251 if err != nil { 1252 t.Fatalf("unable to create channel: %v", err) 1253 } 1254 defer cleanUp() 1255 1256 n := newThreeHopNetwork(t, channels.aliceToBob, channels.bobToAlice, 1257 channels.bobToCarol, channels.carolToBob, testStartingHeight) 1258 if err := n.start(); err != nil { 1259 t.Fatalf("unable to start three hop network: %v", err) 1260 } 1261 defer n.stop() 1262 1263 carolBandwidthBefore := n.carolChannelLink.Bandwidth() 1264 firstBobBandwidthBefore := n.firstBobChannelLink.Bandwidth() 1265 secondBobBandwidthBefore := n.secondBobChannelLink.Bandwidth() 1266 aliceBandwidthBefore := n.aliceChannelLink.Bandwidth() 1267 1268 // We'll attempt to send 4 DCR although the alice-to-bob channel only 1269 // has 3 DCR total capacity. As a result, this payment should be 1270 // rejected. 1271 amount := lnwire.NewMAtomsFromAtoms(4 * dcrutil.AtomsPerCoin) 1272 htlcAmt, totalTimelock, hops := generateHops(amount, testStartingHeight, 1273 n.firstBobChannelLink, n.carolChannelLink) 1274 1275 // Wait for: 1276 // * HTLC add request to be sent to from Alice to Bob. 1277 // * Alice<->Bob commitment states to be updated. 1278 // * Bob trying to add HTLC add request in Bob<->Carol channel. 1279 // * Cancel HTLC request to be sent back from Bob to Alice. 1280 // * user notification to be sent. 1281 1282 receiver := n.carolServer 1283 firstHop := n.firstBobChannelLink.ShortChanID() 1284 rhash, err := makePayment( 1285 n.aliceServer, n.carolServer, firstHop, hops, amount, htlcAmt, 1286 totalTimelock, 1287 ).Wait(30 * time.Second) 1288 if err == nil { 1289 t.Fatal("error haven't been received") 1290 } 1291 assertFailureCode(t, err, lnwire.CodeTemporaryChannelFailure) 1292 1293 // Wait for Alice to receive the revocation. 1294 // 1295 // TODO(roasbeef): add in ntfn hook for state transition completion 1296 time.Sleep(100 * time.Millisecond) 1297 1298 // Check that alice invoice wasn't settled and bandwidth of htlc 1299 // links hasn't been changed. 1300 invoice, err := receiver.registry.LookupInvoice(rhash) 1301 if err != nil { 1302 t.Fatalf("unable to get invoice: %v", err) 1303 } 1304 if invoice.State == channeldb.ContractSettled { 1305 t.Fatal("carol invoice have been settled") 1306 } 1307 1308 if n.aliceChannelLink.Bandwidth() != aliceBandwidthBefore { 1309 t.Fatal("the bandwidth of alice channel link which handles " + 1310 "alice->bob channel should be the same") 1311 } 1312 1313 if n.firstBobChannelLink.Bandwidth() != firstBobBandwidthBefore { 1314 t.Fatal("the bandwidth of bob channel link which handles " + 1315 "alice->bob channel should be the same") 1316 } 1317 1318 if n.secondBobChannelLink.Bandwidth() != secondBobBandwidthBefore { 1319 t.Fatal("the bandwidth of bob channel link which handles " + 1320 "bob->carol channel should be the same") 1321 } 1322 1323 if n.carolChannelLink.Bandwidth() != carolBandwidthBefore { 1324 t.Fatal("the bandwidth of carol channel link which handles " + 1325 "bob->carol channel should be the same") 1326 } 1327 } 1328 1329 // TestChannelLinkMultiHopUnknownPaymentHash checks that we receive remote error 1330 // from Alice if she received not suitable payment hash for htlc. 1331 func TestChannelLinkMultiHopUnknownPaymentHash(t *testing.T) { 1332 t.Parallel() 1333 1334 channels, cleanUp, _, err := createClusterChannels( 1335 dcrutil.AtomsPerCoin*5, 1336 dcrutil.AtomsPerCoin*5) 1337 if err != nil { 1338 t.Fatalf("unable to create channel: %v", err) 1339 } 1340 defer cleanUp() 1341 1342 n := newThreeHopNetwork(t, channels.aliceToBob, channels.bobToAlice, 1343 channels.bobToCarol, channels.carolToBob, testStartingHeight) 1344 if err := n.start(); err != nil { 1345 t.Fatalf("unable to start three hop network: %v", err) 1346 } 1347 defer n.stop() 1348 1349 carolBandwidthBefore := n.carolChannelLink.Bandwidth() 1350 firstBobBandwidthBefore := n.firstBobChannelLink.Bandwidth() 1351 secondBobBandwidthBefore := n.secondBobChannelLink.Bandwidth() 1352 aliceBandwidthBefore := n.aliceChannelLink.Bandwidth() 1353 1354 amount := lnwire.NewMAtomsFromAtoms(dcrutil.AtomsPerCoin) 1355 1356 htlcAmt, totalTimelock, hops := generateHops(amount, testStartingHeight, 1357 n.firstBobChannelLink, n.carolChannelLink) 1358 blob, err := generateRoute(hops...) 1359 if err != nil { 1360 t.Fatal(err) 1361 } 1362 1363 // Generate payment invoice and htlc, but don't add this invoice to the 1364 // receiver registry. This should trigger an unknown payment hash 1365 // failure. 1366 _, htlc, pid, err := generatePayment( 1367 amount, htlcAmt, totalTimelock, blob, 1368 ) 1369 if err != nil { 1370 t.Fatal(err) 1371 } 1372 1373 // Send payment and expose err channel. 1374 err = n.aliceServer.htlcSwitch.SendHTLC( 1375 n.firstBobChannelLink.ShortChanID(), pid, htlc, 1376 ) 1377 if err != nil { 1378 t.Fatalf("unable to get send payment: %v", err) 1379 } 1380 1381 resultChan, err := n.aliceServer.htlcSwitch.GetPaymentResult( 1382 pid, htlc.PaymentHash, newMockDeobfuscator(), 1383 ) 1384 if err != nil { 1385 t.Fatalf("unable to get payment result: %v", err) 1386 } 1387 1388 var result *PaymentResult 1389 var ok bool 1390 select { 1391 1392 case result, ok = <-resultChan: 1393 if !ok { 1394 t.Fatalf("unexpected shutdown") 1395 } 1396 case <-time.After(10 * time.Second): 1397 t.Fatalf("no result arrive") 1398 } 1399 1400 assertFailureCode( 1401 t, result.Error, lnwire.CodeIncorrectOrUnknownPaymentDetails, 1402 ) 1403 1404 // Wait for Alice to receive the revocation. 1405 require.Eventually(t, func() bool { 1406 if n.aliceChannelLink.Bandwidth() != aliceBandwidthBefore { 1407 return false 1408 } 1409 1410 if n.firstBobChannelLink.Bandwidth() != firstBobBandwidthBefore { 1411 return false 1412 } 1413 1414 if n.secondBobChannelLink.Bandwidth() != secondBobBandwidthBefore { 1415 return false 1416 } 1417 1418 if n.carolChannelLink.Bandwidth() != carolBandwidthBefore { 1419 return false 1420 } 1421 1422 return true 1423 }, 10*time.Second, 100*time.Millisecond) 1424 } 1425 1426 // TestChannelLinkMultiHopUnknownNextHop construct the chain of hops 1427 // Carol<->Bob<->Alice and checks that we receive remote error from Bob if he 1428 // has no idea about next hop (hop might goes down and routing info not updated 1429 // yet). 1430 func TestChannelLinkMultiHopUnknownNextHop(t *testing.T) { 1431 t.Parallel() 1432 1433 channels, cleanUp, _, err := createClusterChannels( 1434 dcrutil.AtomsPerCoin*5, 1435 dcrutil.AtomsPerCoin*5) 1436 if err != nil { 1437 t.Fatalf("unable to create channel: %v", err) 1438 } 1439 defer cleanUp() 1440 1441 n := newThreeHopNetwork(t, channels.aliceToBob, channels.bobToAlice, 1442 channels.bobToCarol, channels.carolToBob, testStartingHeight) 1443 if err := n.start(); err != nil { 1444 t.Fatal(err) 1445 } 1446 defer n.stop() 1447 1448 carolBandwidthBefore := n.carolChannelLink.Bandwidth() 1449 firstBobBandwidthBefore := n.firstBobChannelLink.Bandwidth() 1450 secondBobBandwidthBefore := n.secondBobChannelLink.Bandwidth() 1451 aliceBandwidthBefore := n.aliceChannelLink.Bandwidth() 1452 1453 amount := lnwire.NewMAtomsFromAtoms(dcrutil.AtomsPerCoin) 1454 htlcAmt, totalTimelock, hops := generateHops(amount, testStartingHeight, 1455 n.firstBobChannelLink, n.carolChannelLink) 1456 1457 // Remove bob's outgoing link with Carol. This will cause him to fail 1458 // back the payment to Alice since he is unaware of Carol when the 1459 // payment comes across. 1460 bobChanID := lnwire.NewChanIDFromOutPoint( 1461 &channels.bobToCarol.State().FundingOutpoint, 1462 ) 1463 n.bobServer.htlcSwitch.RemoveLink(bobChanID) 1464 1465 firstHop := n.firstBobChannelLink.ShortChanID() 1466 receiver := n.carolServer 1467 rhash, err := makePayment( 1468 n.aliceServer, receiver, firstHop, hops, amount, htlcAmt, 1469 totalTimelock).Wait(30 * time.Second) 1470 if err == nil { 1471 t.Fatal("error haven't been received") 1472 } 1473 rtErr, ok := err.(ClearTextError) 1474 if !ok { 1475 t.Fatalf("expected ClearTextError") 1476 } 1477 1478 if _, ok = rtErr.WireMessage().(*lnwire.FailUnknownNextPeer); !ok { 1479 t.Fatalf("wrong error has been received: %T", 1480 rtErr.WireMessage()) 1481 } 1482 1483 // Wait for Alice to receive the revocation. 1484 // 1485 // TODO(roasbeef): add in ntfn hook for state transition completion 1486 time.Sleep(100 * time.Millisecond) 1487 1488 // Check that alice invoice wasn't settled and bandwidth of htlc 1489 // links hasn't been changed. 1490 invoice, err := receiver.registry.LookupInvoice(rhash) 1491 if err != nil { 1492 t.Fatalf("unable to get invoice: %v", err) 1493 } 1494 if invoice.State == channeldb.ContractSettled { 1495 t.Fatal("carol invoice have been settled") 1496 } 1497 1498 if n.aliceChannelLink.Bandwidth() != aliceBandwidthBefore { 1499 t.Fatal("the bandwidth of alice channel link which handles " + 1500 "alice->bob channel should be the same") 1501 } 1502 1503 if n.firstBobChannelLink.Bandwidth() != firstBobBandwidthBefore { 1504 t.Fatal("the bandwidth of bob channel link which handles " + 1505 "alice->bob channel should be the same") 1506 } 1507 1508 if n.secondBobChannelLink.Bandwidth() != secondBobBandwidthBefore { 1509 t.Fatal("the bandwidth of bob channel link which handles " + 1510 "bob->carol channel should be the same") 1511 } 1512 1513 if n.carolChannelLink.Bandwidth() != carolBandwidthBefore { 1514 t.Fatal("the bandwidth of carol channel link which handles " + 1515 "bob->carol channel should be the same") 1516 } 1517 1518 // Load the forwarding packages for Bob's incoming link. The payment 1519 // should have been rejected by the switch, and the AddRef in this link 1520 // should be acked by the failed payment. 1521 bobInFwdPkgs, err := channels.bobToAlice.State().LoadFwdPkgs() 1522 if err != nil { 1523 t.Fatalf("unable to load bob's fwd pkgs: %v", err) 1524 } 1525 1526 // There should be exactly two forward packages, as a full state 1527 // transition requires two commitment dances. 1528 if len(bobInFwdPkgs) != 2 { 1529 t.Fatalf("bob should have exactly 2 fwdpkgs, has %d", 1530 len(bobInFwdPkgs)) 1531 } 1532 1533 // Only one of the forwarding package should have an Add in it, the 1534 // other will be empty. Either way, both AckFilters should be fully 1535 // acked. 1536 for _, fwdPkg := range bobInFwdPkgs { 1537 if !fwdPkg.AckFilter.IsFull() { 1538 t.Fatalf("fwdpkg chanid=%v height=%d AckFilter is not "+ 1539 "fully acked", fwdPkg.Source, fwdPkg.Height) 1540 } 1541 } 1542 } 1543 1544 // TestChannelLinkMultiHopDecodeError checks that we send HTLC cancel if 1545 // decoding of onion blob failed. 1546 func TestChannelLinkMultiHopDecodeError(t *testing.T) { 1547 t.Parallel() 1548 1549 channels, cleanUp, _, err := createClusterChannels( 1550 dcrutil.AtomsPerCoin*3, 1551 dcrutil.AtomsPerCoin*5) 1552 if err != nil { 1553 t.Fatalf("unable to create channel: %v", err) 1554 } 1555 defer cleanUp() 1556 1557 n := newThreeHopNetwork(t, channels.aliceToBob, channels.bobToAlice, 1558 channels.bobToCarol, channels.carolToBob, testStartingHeight) 1559 if err := n.start(); err != nil { 1560 t.Fatalf("unable to start three hop network: %v", err) 1561 } 1562 defer n.stop() 1563 1564 // Replace decode function with another which throws an error. 1565 n.carolChannelLink.cfg.ExtractErrorEncrypter = func( 1566 *secp256k1.PublicKey) (hop.ErrorEncrypter, lnwire.FailCode) { 1567 return nil, lnwire.CodeInvalidOnionVersion 1568 } 1569 1570 carolBandwidthBefore := n.carolChannelLink.Bandwidth() 1571 firstBobBandwidthBefore := n.firstBobChannelLink.Bandwidth() 1572 secondBobBandwidthBefore := n.secondBobChannelLink.Bandwidth() 1573 aliceBandwidthBefore := n.aliceChannelLink.Bandwidth() 1574 1575 amount := lnwire.NewMAtomsFromAtoms(dcrutil.AtomsPerCoin) 1576 htlcAmt, totalTimelock, hops := generateHops(amount, testStartingHeight, 1577 n.firstBobChannelLink, n.carolChannelLink) 1578 1579 receiver := n.carolServer 1580 firstHop := n.firstBobChannelLink.ShortChanID() 1581 rhash, err := makePayment( 1582 n.aliceServer, n.carolServer, firstHop, hops, amount, htlcAmt, 1583 totalTimelock, 1584 ).Wait(30 * time.Second) 1585 if err == nil { 1586 t.Fatal("error haven't been received") 1587 } 1588 1589 rtErr, ok := err.(ClearTextError) 1590 if !ok { 1591 t.Fatalf("expected a ClearTextError, instead got: %T", err) 1592 } 1593 1594 switch rtErr.WireMessage().(type) { 1595 case *lnwire.FailInvalidOnionVersion: 1596 default: 1597 t.Fatalf("wrong error have been received: %v", err) 1598 } 1599 1600 // Wait for Bob to receive the revocation. 1601 time.Sleep(100 * time.Millisecond) 1602 1603 // Check that alice invoice wasn't settled and bandwidth of htlc 1604 // links hasn't been changed. 1605 invoice, err := receiver.registry.LookupInvoice(rhash) 1606 if err != nil { 1607 t.Fatalf("unable to get invoice: %v", err) 1608 } 1609 if invoice.State == channeldb.ContractSettled { 1610 t.Fatal("carol invoice have been settled") 1611 } 1612 1613 if n.aliceChannelLink.Bandwidth() != aliceBandwidthBefore { 1614 t.Fatal("the bandwidth of alice channel link which handles " + 1615 "alice->bob channel should be the same") 1616 } 1617 1618 if n.firstBobChannelLink.Bandwidth() != firstBobBandwidthBefore { 1619 t.Fatal("the bandwidth of bob channel link which handles " + 1620 "alice->bob channel should be the same") 1621 } 1622 1623 if n.secondBobChannelLink.Bandwidth() != secondBobBandwidthBefore { 1624 t.Fatal("the bandwidth of bob channel link which handles " + 1625 "bob->carol channel should be the same") 1626 } 1627 1628 if n.carolChannelLink.Bandwidth() != carolBandwidthBefore { 1629 t.Fatal("the bandwidth of carol channel link which handles " + 1630 "bob->carol channel should be the same") 1631 } 1632 } 1633 1634 // TestChannelLinkExpiryTooSoonExitNode tests that if we send an HTLC to a node 1635 // with an expiry that is already expired, or too close to the current block 1636 // height, then it will cancel the HTLC. 1637 func TestChannelLinkExpiryTooSoonExitNode(t *testing.T) { 1638 t.Parallel() 1639 1640 // The starting height for this test will be 200. So we'll base all 1641 // HTLC starting points off of that. 1642 channels, cleanUp, _, err := createClusterChannels( 1643 dcrutil.AtomsPerCoin*3, 1644 dcrutil.AtomsPerCoin*5) 1645 if err != nil { 1646 t.Fatalf("unable to create channel: %v", err) 1647 } 1648 defer cleanUp() 1649 1650 const startingHeight = 200 1651 n := newThreeHopNetwork(t, channels.aliceToBob, channels.bobToAlice, 1652 channels.bobToCarol, channels.carolToBob, startingHeight) 1653 if err := n.start(); err != nil { 1654 t.Fatalf("unable to start three hop network: %v", err) 1655 } 1656 defer n.stop() 1657 1658 amount := lnwire.NewMAtomsFromAtoms(dcrutil.AtomsPerCoin) 1659 1660 // We'll craft an HTLC packet, but set the final hop CLTV to 5 blocks 1661 // after the current true height. This is less than the test invoice 1662 // cltv delta of 6, so we expect the incoming htlc to be failed by the 1663 // exit hop. 1664 htlcAmt, totalTimelock, hops := generateHops(amount, 1665 startingHeight-1, n.firstBobChannelLink) 1666 1667 // Now we'll send out the payment from Alice to Bob. 1668 firstHop := n.firstBobChannelLink.ShortChanID() 1669 _, err = makePayment( 1670 n.aliceServer, n.bobServer, firstHop, hops, amount, htlcAmt, 1671 totalTimelock, 1672 ).Wait(30 * time.Second) 1673 1674 // The payment should've failed as the time lock value was in the 1675 // _past_. 1676 if err == nil { 1677 t.Fatalf("payment should have failed due to a too early " + 1678 "time lock value") 1679 } 1680 1681 rtErr, ok := err.(ClearTextError) 1682 if !ok { 1683 t.Fatalf("expected a ClearTextError, instead got: %T %v", 1684 rtErr, err) 1685 } 1686 1687 switch rtErr.WireMessage().(type) { 1688 case *lnwire.FailIncorrectDetails: 1689 default: 1690 t.Fatalf("expected incorrect_or_unknown_payment_details, "+ 1691 "instead have: %v", err) 1692 } 1693 } 1694 1695 // TestChannelLinkExpiryTooSoonExitNode tests that if we send a multi-hop HTLC, 1696 // and the time lock is too early for an intermediate node, then they cancel 1697 // the HTLC back to the sender. 1698 func TestChannelLinkExpiryTooSoonMidNode(t *testing.T) { 1699 t.Parallel() 1700 1701 // The starting height for this test will be 200. So we'll base all 1702 // HTLC starting points off of that. 1703 channels, cleanUp, _, err := createClusterChannels( 1704 dcrutil.AtomsPerCoin*3, 1705 dcrutil.AtomsPerCoin*5) 1706 if err != nil { 1707 t.Fatalf("unable to create channel: %v", err) 1708 } 1709 defer cleanUp() 1710 1711 const startingHeight = 200 1712 n := newThreeHopNetwork(t, channels.aliceToBob, channels.bobToAlice, 1713 channels.bobToCarol, channels.carolToBob, startingHeight) 1714 if err := n.start(); err != nil { 1715 t.Fatalf("unable to start three hop network: %v", err) 1716 } 1717 defer n.stop() 1718 1719 amount := lnwire.NewMAtomsFromAtoms(dcrutil.AtomsPerCoin) 1720 1721 // We'll craft an HTLC packet, but set the starting height to 3 blocks 1722 // before the current true height. This means that the outgoing time 1723 // lock of the middle hop will be at starting height + 3 blocks (channel 1724 // policy time lock delta is 6 blocks). There is an expiry grace delta 1725 // of 3 blocks relative to the current height, meaning that htlc will 1726 // not be sent out by the middle hop. 1727 htlcAmt, totalTimelock, hops := generateHops(amount, 1728 startingHeight-3, n.firstBobChannelLink, n.carolChannelLink) 1729 1730 // Now we'll send out the payment from Alice to Bob. 1731 firstHop := n.firstBobChannelLink.ShortChanID() 1732 _, err = makePayment( 1733 n.aliceServer, n.bobServer, firstHop, hops, amount, htlcAmt, 1734 totalTimelock, 1735 ).Wait(30 * time.Second) 1736 1737 // The payment should've failed as the time lock value was in the 1738 // _past_. 1739 if err == nil { 1740 t.Fatalf("payment should have failed due to a too early " + 1741 "time lock value") 1742 } 1743 1744 rtErr, ok := err.(ClearTextError) 1745 if !ok { 1746 t.Fatalf("expected a ClearTextError, instead got: %T: %v", 1747 rtErr, err) 1748 } 1749 1750 switch rtErr.WireMessage().(type) { 1751 case *lnwire.FailExpiryTooSoon: 1752 default: 1753 t.Fatalf("incorrect error, expected final time lock too "+ 1754 "early, instead have: %v", err) 1755 } 1756 } 1757 1758 // TestChannelLinkSingleHopMessageOrdering test checks ordering of message which 1759 // flying around between Alice and Bob are correct when Bob sends payments to 1760 // Alice. 1761 func TestChannelLinkSingleHopMessageOrdering(t *testing.T) { 1762 t.Parallel() 1763 1764 channels, cleanUp, _, err := createClusterChannels( 1765 dcrutil.AtomsPerCoin*3, 1766 dcrutil.AtomsPerCoin*5) 1767 if err != nil { 1768 t.Fatalf("unable to create channel: %v", err) 1769 } 1770 defer cleanUp() 1771 1772 n := newThreeHopNetwork(t, channels.aliceToBob, channels.bobToAlice, 1773 channels.bobToCarol, channels.carolToBob, testStartingHeight) 1774 1775 chanID := n.aliceChannelLink.ChanID() 1776 1777 messages := []expectedMessage{ 1778 {"alice", "bob", &lnwire.ChannelReestablish{}, false}, 1779 {"bob", "alice", &lnwire.ChannelReestablish{}, false}, 1780 1781 {"alice", "bob", &lnwire.FundingLocked{}, false}, 1782 {"bob", "alice", &lnwire.FundingLocked{}, false}, 1783 1784 {"alice", "bob", &lnwire.UpdateAddHTLC{}, false}, 1785 {"alice", "bob", &lnwire.CommitSig{}, false}, 1786 {"bob", "alice", &lnwire.RevokeAndAck{}, false}, 1787 {"bob", "alice", &lnwire.CommitSig{}, false}, 1788 {"alice", "bob", &lnwire.RevokeAndAck{}, false}, 1789 1790 {"bob", "alice", &lnwire.UpdateFulfillHTLC{}, false}, 1791 {"bob", "alice", &lnwire.CommitSig{}, false}, 1792 {"alice", "bob", &lnwire.RevokeAndAck{}, false}, 1793 {"alice", "bob", &lnwire.CommitSig{}, false}, 1794 {"bob", "alice", &lnwire.RevokeAndAck{}, false}, 1795 } 1796 1797 debug := false 1798 if debug { 1799 // Log message that alice receives. 1800 n.aliceServer.intersect(createLogFunc("alice", 1801 n.aliceChannelLink.ChanID())) 1802 1803 // Log message that bob receives. 1804 n.bobServer.intersect(createLogFunc("bob", 1805 n.firstBobChannelLink.ChanID())) 1806 } 1807 1808 // Check that alice receives messages in right order. 1809 n.aliceServer.intersect(createInterceptorFunc("[alice] <-- [bob]", 1810 "alice", messages, chanID, false)) 1811 1812 // Check that bob receives messages in right order. 1813 n.bobServer.intersect(createInterceptorFunc("[alice] --> [bob]", 1814 "bob", messages, chanID, false)) 1815 1816 if err := n.start(); err != nil { 1817 t.Fatalf("unable to start three hop network: %v", err) 1818 } 1819 defer n.stop() 1820 1821 amount := lnwire.NewMAtomsFromAtoms(dcrutil.AtomsPerCoin) 1822 htlcAmt, totalTimelock, hops := generateHops(amount, testStartingHeight, 1823 n.firstBobChannelLink) 1824 1825 // Wait for: 1826 // * HTLC add request to be sent to bob. 1827 // * alice<->bob commitment state to be updated. 1828 // * settle request to be sent back from bob to alice. 1829 // * alice<->bob commitment state to be updated. 1830 // * user notification to be sent. 1831 firstHop := n.firstBobChannelLink.ShortChanID() 1832 _, err = makePayment( 1833 n.aliceServer, n.bobServer, firstHop, hops, amount, htlcAmt, 1834 totalTimelock, 1835 ).Wait(30 * time.Second) 1836 if err != nil { 1837 t.Fatalf("unable to make the payment: %v", err) 1838 } 1839 } 1840 1841 type mockPeer struct { 1842 sync.Mutex 1843 disconnected bool 1844 sentMsgs chan lnwire.Message 1845 quit chan struct{} 1846 } 1847 1848 func (m *mockPeer) QuitSignal() <-chan struct{} { 1849 return m.quit 1850 } 1851 1852 var _ lnpeer.Peer = (*mockPeer)(nil) 1853 1854 func (m *mockPeer) SendMessage(sync bool, msgs ...lnwire.Message) error { 1855 if m.disconnected { 1856 return fmt.Errorf("disconnected") 1857 } 1858 1859 select { 1860 case m.sentMsgs <- msgs[0]: 1861 case <-m.quit: 1862 return fmt.Errorf("mockPeer shutting down") 1863 } 1864 return nil 1865 } 1866 func (m *mockPeer) SendMessageLazy(sync bool, msgs ...lnwire.Message) error { 1867 return m.SendMessage(sync, msgs...) 1868 } 1869 func (m *mockPeer) AddNewChannel(_ *channeldb.OpenChannel, 1870 _ <-chan struct{}) error { 1871 return nil 1872 } 1873 func (m *mockPeer) WipeChannel(*wire.OutPoint) {} 1874 func (m *mockPeer) PubKey() [33]byte { 1875 return [33]byte{} 1876 } 1877 func (m *mockPeer) IdentityKey() *secp256k1.PublicKey { 1878 return nil 1879 } 1880 func (m *mockPeer) Address() net.Addr { 1881 return nil 1882 } 1883 func (m *mockPeer) Inbound() bool { 1884 return false 1885 } 1886 func (m *mockPeer) LocalFeatures() *lnwire.FeatureVector { 1887 return nil 1888 } 1889 func (m *mockPeer) RemoteFeatures() *lnwire.FeatureVector { 1890 return nil 1891 } 1892 1893 func newSingleLinkTestHarness(chanAmt, chanReserve dcrutil.Amount) ( 1894 ChannelLink, *lnwallet.LightningChannel, chan time.Time, func() error, 1895 func(), func() (*lnwallet.LightningChannel, error), error) { 1896 1897 var chanIDBytes [8]byte 1898 if _, err := io.ReadFull(rand.Reader, chanIDBytes[:]); err != nil { 1899 return nil, nil, nil, nil, nil, nil, err 1900 } 1901 1902 chanID := lnwire.NewShortChanIDFromInt( 1903 binary.BigEndian.Uint64(chanIDBytes[:])) 1904 1905 aliceLc, bobLc, fCleanUp, err := createTestChannel( 1906 alicePrivKey, bobPrivKey, chanAmt, chanAmt, 1907 chanReserve, chanReserve, chanID, 1908 ) 1909 if err != nil { 1910 return nil, nil, nil, nil, nil, nil, err 1911 } 1912 1913 var ( 1914 decoder = newMockIteratorDecoder() 1915 obfuscator = NewMockObfuscator() 1916 alicePeer = &mockPeer{ 1917 sentMsgs: make(chan lnwire.Message, 2000), 1918 quit: make(chan struct{}), 1919 } 1920 globalPolicy = ForwardingPolicy{ 1921 MinHTLCOut: lnwire.NewMAtomsFromAtoms(5), 1922 MaxHTLC: lnwire.NewMAtomsFromAtoms(chanAmt), 1923 BaseFee: lnwire.NewMAtomsFromAtoms(1), 1924 TimeLockDelta: 6, 1925 } 1926 invoiceRegistry = newMockRegistry(globalPolicy.TimeLockDelta) 1927 ) 1928 1929 pCache := newMockPreimageCache() 1930 1931 aliceDb := aliceLc.channel.State().Db.GetParentDB() 1932 aliceSwitch, err := initSwitchWithDB(testStartingHeight, aliceDb) 1933 if err != nil { 1934 return nil, nil, nil, nil, nil, nil, err 1935 } 1936 1937 // Instantiate with a long interval, so that we can precisely control 1938 // the firing via force feeding. 1939 bticker := ticker.NewForce(time.Hour) 1940 aliceCfg := ChannelLinkConfig{ 1941 FwrdingPolicy: globalPolicy, 1942 Peer: alicePeer, 1943 Switch: aliceSwitch, 1944 BestHeight: aliceSwitch.BestHeight, 1945 Circuits: aliceSwitch.CircuitModifier(), 1946 ForwardPackets: aliceSwitch.ForwardPackets, 1947 DecodeHopIterators: decoder.DecodeHopIterators, 1948 ExtractErrorEncrypter: func(*secp256k1.PublicKey) ( 1949 hop.ErrorEncrypter, lnwire.FailCode) { 1950 return obfuscator, lnwire.CodeNone 1951 }, 1952 FetchLastChannelUpdate: mockGetChanUpdateMessage, 1953 PreimageCache: pCache, 1954 OnChannelFailure: func(lnwire.ChannelID, 1955 lnwire.ShortChannelID, LinkFailureError) { 1956 }, 1957 UpdateContractSignals: func(*contractcourt.ContractSignals) error { 1958 return nil 1959 }, 1960 Registry: invoiceRegistry, 1961 FeeEstimator: newMockFeeEstimator(), 1962 ChainEvents: &contractcourt.ChainEventSubscription{}, 1963 BatchTicker: bticker, 1964 FwdPkgGCTicker: ticker.NewForce(15 * time.Second), 1965 PendingCommitTicker: ticker.New(time.Minute), 1966 // Make the BatchSize and Min/MaxFeeUpdateTimeout large enough 1967 // to not trigger commit updates automatically during tests. 1968 BatchSize: 10000, 1969 MinFeeUpdateTimeout: 30 * time.Minute, 1970 MaxFeeUpdateTimeout: 40 * time.Minute, 1971 MaxOutgoingCltvExpiry: DefaultMaxOutgoingCltvExpiry, 1972 MaxFeeAllocation: DefaultMaxLinkFeeAllocation, 1973 NotifyActiveLink: func(wire.OutPoint) {}, 1974 NotifyActiveChannel: func(wire.OutPoint) {}, 1975 NotifyInactiveChannel: func(wire.OutPoint) {}, 1976 HtlcNotifier: aliceSwitch.cfg.HtlcNotifier, 1977 1978 ResetChanReestablishWaitTime: aliceDb.ChannelStateDB().ResetChanReestablishWaitTime, 1979 AddToChanReestablishWaitTime: aliceDb.ChannelStateDB().AddToChanReestablishWaitTime, 1980 } 1981 1982 aliceLink := NewChannelLink(aliceCfg, aliceLc.channel) 1983 start := func() error { 1984 return aliceSwitch.AddLink(aliceLink) 1985 } 1986 go func() { 1987 for { 1988 select { 1989 case <-aliceLink.(*channelLink).htlcUpdates: 1990 case <-aliceLink.(*channelLink).quit: 1991 return 1992 } 1993 } 1994 }() 1995 1996 cleanUp := func() { 1997 close(alicePeer.quit) 1998 defer fCleanUp() 1999 } 2000 2001 return aliceLink, bobLc.channel, bticker.Force, start, cleanUp, 2002 aliceLc.restore, nil 2003 } 2004 2005 func assertLinkBandwidth(t *testing.T, link ChannelLink, 2006 expected lnwire.MilliAtom) { 2007 2008 currentBandwidth := link.Bandwidth() 2009 _, _, line, _ := runtime.Caller(1) 2010 if currentBandwidth != expected { 2011 t.Fatalf("line %v: alice's link bandwidth is incorrect: "+ 2012 "expected %v, got %v", line, expected, currentBandwidth) 2013 } 2014 } 2015 2016 // handleStateUpdate handles the messages sent from the link after 2017 // the batch ticker has triggered a state update. 2018 func handleStateUpdate(link *channelLink, 2019 remoteChannel *lnwallet.LightningChannel) error { 2020 sentMsgs := link.cfg.Peer.(*mockPeer).sentMsgs 2021 var msg lnwire.Message 2022 select { 2023 case msg = <-sentMsgs: 2024 case <-time.After(60 * time.Second): 2025 return fmt.Errorf("did not receive CommitSig from Alice") 2026 } 2027 2028 // The link should be sending a commit sig at this point. 2029 commitSig, ok := msg.(*lnwire.CommitSig) 2030 if !ok { 2031 return fmt.Errorf("expected CommitSig, got %T", msg) 2032 } 2033 2034 // Let the remote channel receive the commit sig, and 2035 // respond with a revocation + commitsig. 2036 err := remoteChannel.ReceiveNewCommitment( 2037 commitSig.CommitSig, commitSig.HtlcSigs) 2038 if err != nil { 2039 return err 2040 } 2041 2042 remoteRev, _, err := remoteChannel.RevokeCurrentCommitment() 2043 if err != nil { 2044 return err 2045 } 2046 link.HandleChannelUpdate(remoteRev) 2047 2048 remoteSig, remoteHtlcSigs, _, err := remoteChannel.SignNextCommitment() 2049 if err != nil { 2050 return err 2051 } 2052 commitSig = &lnwire.CommitSig{ 2053 CommitSig: remoteSig, 2054 HtlcSigs: remoteHtlcSigs, 2055 } 2056 link.HandleChannelUpdate(commitSig) 2057 2058 // This should make the link respond with a revocation. 2059 select { 2060 case msg = <-sentMsgs: 2061 case <-time.After(60 * time.Second): 2062 return fmt.Errorf("did not receive RevokeAndAck from Alice") 2063 } 2064 2065 revoke, ok := msg.(*lnwire.RevokeAndAck) 2066 if !ok { 2067 return fmt.Errorf("expected RevokeAndAck got %T", msg) 2068 } 2069 _, _, _, _, err = remoteChannel.ReceiveRevocation(revoke) 2070 if err != nil { 2071 return fmt.Errorf("unable to receive "+ 2072 "revocation: %v", err) 2073 } 2074 2075 return nil 2076 } 2077 2078 // updateState is used exchange the messages necessary to do a full state 2079 // transition. If initiateUpdate=true, then this call will make the link 2080 // trigger an update by sending on the batchTick channel, if not, it will 2081 // make the remoteChannel initiate the state update. 2082 func updateState(batchTick chan time.Time, link *channelLink, 2083 remoteChannel *lnwallet.LightningChannel, 2084 initiateUpdate bool) error { 2085 sentMsgs := link.cfg.Peer.(*mockPeer).sentMsgs 2086 2087 if initiateUpdate { 2088 // Trigger update by ticking the batchTicker. 2089 select { 2090 case batchTick <- time.Now(): 2091 case <-link.quit: 2092 return fmt.Errorf("link shutting down") 2093 } 2094 return handleStateUpdate(link, remoteChannel) 2095 } 2096 2097 // The remote is triggering the state update, emulate this by 2098 // signing and sending CommitSig to the link. 2099 remoteSig, remoteHtlcSigs, _, err := remoteChannel.SignNextCommitment() 2100 if err != nil { 2101 return err 2102 } 2103 2104 commitSig := &lnwire.CommitSig{ 2105 CommitSig: remoteSig, 2106 HtlcSigs: remoteHtlcSigs, 2107 } 2108 link.HandleChannelUpdate(commitSig) 2109 2110 // The link should respond with a revocation + commit sig. 2111 var msg lnwire.Message 2112 select { 2113 case msg = <-sentMsgs: 2114 case <-time.After(60 * time.Second): 2115 return fmt.Errorf("did not receive RevokeAndAck from Alice") 2116 } 2117 2118 revoke, ok := msg.(*lnwire.RevokeAndAck) 2119 if !ok { 2120 return fmt.Errorf("expected RevokeAndAck got %T", 2121 msg) 2122 } 2123 _, _, _, _, err = remoteChannel.ReceiveRevocation(revoke) 2124 if err != nil { 2125 return fmt.Errorf("unable to receive "+ 2126 "revocation: %v", err) 2127 } 2128 select { 2129 case msg = <-sentMsgs: 2130 case <-time.After(60 * time.Second): 2131 return fmt.Errorf("did not receive CommitSig from Alice") 2132 } 2133 2134 commitSig, ok = msg.(*lnwire.CommitSig) 2135 if !ok { 2136 return fmt.Errorf("expected CommitSig, got %T", msg) 2137 } 2138 2139 err = remoteChannel.ReceiveNewCommitment( 2140 commitSig.CommitSig, commitSig.HtlcSigs) 2141 if err != nil { 2142 return err 2143 } 2144 2145 // Lastly, send a revocation back to the link. 2146 remoteRev, _, err := remoteChannel.RevokeCurrentCommitment() 2147 if err != nil { 2148 return err 2149 } 2150 link.HandleChannelUpdate(remoteRev) 2151 2152 // Sleep to make sure Alice has handled the remote revocation. 2153 time.Sleep(500 * time.Millisecond) 2154 2155 return nil 2156 } 2157 2158 // TestChannelLinkBandwidthConsistency ensures that the reported bandwidth of a 2159 // given ChannelLink is properly updated in response to downstream messages 2160 // from the switch, and upstream messages from its channel peer. 2161 // 2162 // TODO(roasbeef): add sync hook into packet processing so can eliminate all 2163 // sleep in this test and the one below 2164 func TestChannelLinkBandwidthConsistency(t *testing.T) { 2165 if !build.IsDevBuild() { 2166 t.Fatalf("htlcswitch tests must be run with '-tags dev") 2167 } 2168 t.Parallel() 2169 2170 // TODO(roasbeef): replace manual bit twiddling with concept of 2171 // resource cost for packets? 2172 // * or also able to consult link 2173 2174 // We'll start the test by creating a single instance of 2175 const chanAmt = dcrutil.AtomsPerCoin * 5 2176 2177 aliceLink, bobChannel, tmr, start, cleanUp, _, err := 2178 newSingleLinkTestHarness(chanAmt, 0) 2179 if err != nil { 2180 t.Fatalf("unable to create link: %v", err) 2181 } 2182 defer cleanUp() 2183 2184 if err := start(); err != nil { 2185 t.Fatalf("unable to start test harness: %v", err) 2186 } 2187 2188 var ( 2189 carolChanID = lnwire.NewShortChanIDFromInt(3) 2190 mockBlob [lnwire.OnionPacketSize]byte 2191 coreChan = aliceLink.(*channelLink).channel 2192 coreLink = aliceLink.(*channelLink) 2193 defaultCommitFee = coreChan.StateSnapshot().CommitFee 2194 aliceStartingBandwidth = aliceLink.Bandwidth() 2195 aliceMsgs = coreLink.cfg.Peer.(*mockPeer).sentMsgs 2196 ) 2197 2198 // We put Alice into hodl.ExitSettle mode, such that she won't settle 2199 // incoming HTLCs automatically. 2200 coreLink.cfg.HodlMask = hodl.MaskFromFlags(hodl.ExitSettle) 2201 2202 estimator := chainfee.NewStaticEstimator(1e4, 0) 2203 feePerKB, err := estimator.EstimateFeePerKB(1) 2204 if err != nil { 2205 t.Fatalf("unable to query fee estimator: %v", err) 2206 } 2207 htlcFee := lnwire.NewMAtomsFromAtoms( 2208 feePerKB.FeeForSize(input.HTLCOutputSize), 2209 ) 2210 2211 // The starting bandwidth of the channel should be exactly the amount 2212 // that we created the channel between her and Bob, minus the 2213 // commitment fee and fee for adding an additional HTLC. 2214 expectedBandwidth := lnwire.NewMAtomsFromAtoms( 2215 chanAmt-defaultCommitFee, 2216 ) - htlcFee 2217 assertLinkBandwidth(t, aliceLink, expectedBandwidth) 2218 2219 // Next, we'll create an HTLC worth 1 DCR, and send it into the link as 2220 // a switch initiated payment. The resulting bandwidth should 2221 // now be decremented to reflect the new HTLC. 2222 htlcAmt := lnwire.NewMAtomsFromAtoms(dcrutil.AtomsPerCoin) 2223 invoice, htlc, _, err := generatePayment( 2224 htlcAmt, htlcAmt, 5, mockBlob, 2225 ) 2226 if err != nil { 2227 t.Fatalf("unable to create payment: %v", err) 2228 } 2229 addPkt := htlcPacket{ 2230 htlc: htlc, 2231 incomingChanID: hop.Source, 2232 incomingHTLCID: 0, 2233 obfuscator: NewMockObfuscator(), 2234 } 2235 2236 circuit := makePaymentCircuit(&htlc.PaymentHash, &addPkt) 2237 _, err = coreLink.cfg.Switch.commitCircuits(&circuit) 2238 if err != nil { 2239 t.Fatalf("unable to commit circuit: %v", err) 2240 } 2241 2242 addPkt.circuit = &circuit 2243 if err := aliceLink.handleSwitchPacket(&addPkt); err != nil { 2244 t.Fatalf("unable to handle switch packet: %v", err) 2245 } 2246 time.Sleep(time.Millisecond * 500) 2247 2248 // The resulting bandwidth should reflect that Alice is paying the 2249 // htlc amount in addition to the htlc fee. 2250 assertLinkBandwidth(t, aliceLink, aliceStartingBandwidth-htlcAmt-htlcFee) 2251 2252 // Alice should send the HTLC to Bob. 2253 var msg lnwire.Message 2254 select { 2255 case msg = <-aliceMsgs: 2256 case <-time.After(15 * time.Second): 2257 t.Fatalf("did not receive message") 2258 } 2259 2260 addHtlc, ok := msg.(*lnwire.UpdateAddHTLC) 2261 if !ok { 2262 t.Fatalf("expected UpdateAddHTLC, got %T", msg) 2263 } 2264 2265 bobIndex, err := bobChannel.ReceiveHTLC(addHtlc) 2266 if err != nil { 2267 t.Fatalf("bob failed receiving htlc: %v", err) 2268 } 2269 2270 // Lock in the HTLC. 2271 if err := updateState(tmr, coreLink, bobChannel, true); err != nil { 2272 t.Fatalf("unable to update state: %v", err) 2273 } 2274 // Locking in the HTLC should not change Alice's bandwidth. 2275 assertLinkBandwidth(t, aliceLink, aliceStartingBandwidth-htlcAmt-htlcFee) 2276 2277 // If we now send in a valid HTLC settle for the prior HTLC we added, 2278 // then the bandwidth should remain unchanged as the remote party will 2279 // gain additional channel balance. 2280 err = bobChannel.SettleHTLC(*invoice.Terms.PaymentPreimage, bobIndex, nil, nil, nil) 2281 if err != nil { 2282 t.Fatalf("unable to settle htlc: %v", err) 2283 } 2284 htlcSettle := &lnwire.UpdateFulfillHTLC{ 2285 ID: 0, 2286 PaymentPreimage: *invoice.Terms.PaymentPreimage, 2287 } 2288 aliceLink.HandleChannelUpdate(htlcSettle) 2289 time.Sleep(time.Millisecond * 500) 2290 2291 // Since the settle is not locked in yet, Alice's bandwidth should still 2292 // reflect that she has to pay the fee. 2293 assertLinkBandwidth(t, aliceLink, aliceStartingBandwidth-htlcAmt-htlcFee) 2294 2295 // Lock in the settle. 2296 if err := updateState(tmr, coreLink, bobChannel, false); err != nil { 2297 t.Fatalf("unable to update state: %v", err) 2298 } 2299 2300 // Now that it is settled, Alice should have gotten the htlc fee back. 2301 assertLinkBandwidth(t, aliceLink, aliceStartingBandwidth-htlcAmt) 2302 2303 // Next, we'll add another HTLC initiated by the switch (of the same 2304 // amount as the prior one). 2305 invoice, htlc, _, err = generatePayment(htlcAmt, htlcAmt, 5, mockBlob) 2306 if err != nil { 2307 t.Fatalf("unable to create payment: %v", err) 2308 } 2309 addPkt = htlcPacket{ 2310 htlc: htlc, 2311 incomingChanID: hop.Source, 2312 incomingHTLCID: 1, 2313 obfuscator: NewMockObfuscator(), 2314 } 2315 2316 circuit = makePaymentCircuit(&htlc.PaymentHash, &addPkt) 2317 _, err = coreLink.cfg.Switch.commitCircuits(&circuit) 2318 if err != nil { 2319 t.Fatalf("unable to commit circuit: %v", err) 2320 } 2321 2322 addPkt.circuit = &circuit 2323 if err := aliceLink.handleSwitchPacket(&addPkt); err != nil { 2324 t.Fatalf("unable to handle switch packet: %v", err) 2325 } 2326 time.Sleep(time.Millisecond * 500) 2327 2328 // Again, Alice's bandwidth decreases by htlcAmt+htlcFee. 2329 assertLinkBandwidth(t, aliceLink, aliceStartingBandwidth-2*htlcAmt-htlcFee) 2330 2331 // Alice will send the HTLC to Bob. 2332 select { 2333 case msg = <-aliceMsgs: 2334 case <-time.After(15 * time.Second): 2335 t.Fatalf("did not receive message") 2336 } 2337 2338 addHtlc, ok = msg.(*lnwire.UpdateAddHTLC) 2339 if !ok { 2340 t.Fatalf("expected UpdateAddHTLC, got %T", msg) 2341 } 2342 2343 bobIndex, err = bobChannel.ReceiveHTLC(addHtlc) 2344 if err != nil { 2345 t.Fatalf("bob failed receiving htlc: %v", err) 2346 } 2347 2348 // Lock in the HTLC, which should not affect the bandwidth. 2349 if err := updateState(tmr, coreLink, bobChannel, true); err != nil { 2350 t.Fatalf("unable to update state: %v", err) 2351 } 2352 2353 assertLinkBandwidth(t, aliceLink, aliceStartingBandwidth-htlcAmt*2-htlcFee) 2354 2355 // With that processed, we'll now generate an HTLC fail (sent by the 2356 // remote peer) to cancel the HTLC we just added. This should return us 2357 // back to the bandwidth of the link right before the HTLC was sent. 2358 err = bobChannel.FailHTLC(bobIndex, []byte("nop"), nil, nil, nil) 2359 if err != nil { 2360 t.Fatalf("unable to fail htlc: %v", err) 2361 } 2362 failMsg := &lnwire.UpdateFailHTLC{ 2363 ID: 1, 2364 Reason: lnwire.OpaqueReason([]byte("nop")), 2365 } 2366 2367 aliceLink.HandleChannelUpdate(failMsg) 2368 time.Sleep(time.Millisecond * 500) 2369 2370 // Before the Fail gets locked in, the bandwidth should remain unchanged. 2371 assertLinkBandwidth(t, aliceLink, aliceStartingBandwidth-htlcAmt*2-htlcFee) 2372 2373 // Lock in the Fail. 2374 if err := updateState(tmr, coreLink, bobChannel, false); err != nil { 2375 t.Fatalf("unable to update state: %v", err) 2376 } 2377 2378 // Now the bandwidth should reflect the failed HTLC. 2379 assertLinkBandwidth(t, aliceLink, aliceStartingBandwidth-htlcAmt) 2380 2381 // Moving along, we'll now receive a new HTLC from the remote peer, 2382 // with an ID of 0 as this is their first HTLC. The bandwidth should 2383 // remain unchanged (but Alice will need to pay the fee for the extra 2384 // HTLC). 2385 htlcAmt, totalTimelock, hops := generateHops(htlcAmt, testStartingHeight, 2386 coreLink) 2387 blob, err := generateRoute(hops...) 2388 if err != nil { 2389 t.Fatalf("unable to gen route: %v", err) 2390 } 2391 invoice, htlc, _, err = generatePayment( 2392 htlcAmt, htlcAmt, totalTimelock, blob, 2393 ) 2394 if err != nil { 2395 t.Fatalf("unable to create payment: %v", err) 2396 } 2397 2398 // We must add the invoice to the registry, such that Alice expects 2399 // this payment. 2400 err = coreLink.cfg.Registry.(*mockInvoiceRegistry).AddInvoice( 2401 *invoice, htlc.PaymentHash, 2402 ) 2403 if err != nil { 2404 t.Fatalf("unable to add invoice to registry: %v", err) 2405 } 2406 2407 htlc.ID = 0 2408 _, err = bobChannel.AddHTLC(htlc, nil) 2409 if err != nil { 2410 t.Fatalf("unable to add htlc: %v", err) 2411 } 2412 aliceLink.HandleChannelUpdate(htlc) 2413 2414 // Alice's balance remains unchanged until this HTLC is locked in. 2415 assertLinkBandwidth(t, aliceLink, aliceStartingBandwidth-htlcAmt) 2416 2417 // Lock in the HTLC. 2418 if err := updateState(tmr, coreLink, bobChannel, false); err != nil { 2419 t.Fatalf("unable to update state: %v", err) 2420 } 2421 2422 // Since Bob is adding this HTLC, Alice only needs to pay the fee. 2423 assertLinkBandwidth(t, aliceLink, aliceStartingBandwidth-htlcAmt-htlcFee) 2424 time.Sleep(time.Millisecond * 500) 2425 2426 addPkt = htlcPacket{ 2427 htlc: htlc, 2428 incomingChanID: aliceLink.ShortChanID(), 2429 incomingHTLCID: 0, 2430 obfuscator: NewMockObfuscator(), 2431 } 2432 2433 circuit = makePaymentCircuit(&htlc.PaymentHash, &addPkt) 2434 _, err = coreLink.cfg.Switch.commitCircuits(&circuit) 2435 if err != nil { 2436 t.Fatalf("unable to commit circuit: %v", err) 2437 } 2438 2439 addPkt.outgoingChanID = carolChanID 2440 addPkt.outgoingHTLCID = 0 2441 2442 err = coreLink.cfg.Circuits.OpenCircuits(addPkt.keystone()) 2443 if err != nil { 2444 t.Fatalf("unable to set keystone: %v", err) 2445 } 2446 2447 // Next, we'll settle the HTLC with our knowledge of the pre-image that 2448 // we eventually learn (simulating a multi-hop payment). The bandwidth 2449 // of the channel should now be re-balanced to the starting point. 2450 settlePkt := htlcPacket{ 2451 incomingChanID: aliceLink.ShortChanID(), 2452 incomingHTLCID: 0, 2453 circuit: &circuit, 2454 outgoingChanID: addPkt.outgoingChanID, 2455 outgoingHTLCID: addPkt.outgoingHTLCID, 2456 htlc: &lnwire.UpdateFulfillHTLC{ 2457 ID: 0, 2458 PaymentPreimage: *invoice.Terms.PaymentPreimage, 2459 }, 2460 obfuscator: NewMockObfuscator(), 2461 } 2462 2463 if err := aliceLink.handleSwitchPacket(&settlePkt); err != nil { 2464 t.Fatalf("unable to handle switch packet: %v", err) 2465 } 2466 time.Sleep(time.Millisecond * 500) 2467 2468 // Settling this HTLC gives Alice all her original bandwidth back. 2469 assertLinkBandwidth(t, aliceLink, aliceStartingBandwidth) 2470 2471 select { 2472 case msg = <-aliceMsgs: 2473 case <-time.After(15 * time.Second): 2474 t.Fatalf("did not receive message") 2475 } 2476 2477 settleMsg, ok := msg.(*lnwire.UpdateFulfillHTLC) 2478 if !ok { 2479 t.Fatalf("expected UpdateFulfillHTLC, got %T", msg) 2480 } 2481 err = bobChannel.ReceiveHTLCSettle(settleMsg.PaymentPreimage, settleMsg.ID) 2482 if err != nil { 2483 t.Fatalf("failed receiving fail htlc: %v", err) 2484 } 2485 2486 // After failing an HTLC, the link will automatically trigger 2487 // a state update. 2488 if err := handleStateUpdate(coreLink, bobChannel); err != nil { 2489 t.Fatalf("unable to update state: %v", err) 2490 } 2491 2492 // Finally, we'll test the scenario of failing an HTLC received by the 2493 // remote node. This should result in no perceived bandwidth changes. 2494 htlcAmt, totalTimelock, hops = generateHops(htlcAmt, testStartingHeight, 2495 coreLink) 2496 blob, err = generateRoute(hops...) 2497 if err != nil { 2498 t.Fatalf("unable to gen route: %v", err) 2499 } 2500 invoice, htlc, _, err = generatePayment( 2501 htlcAmt, htlcAmt, totalTimelock, blob, 2502 ) 2503 if err != nil { 2504 t.Fatalf("unable to create payment: %v", err) 2505 } 2506 err = coreLink.cfg.Registry.(*mockInvoiceRegistry).AddInvoice( 2507 *invoice, htlc.PaymentHash, 2508 ) 2509 if err != nil { 2510 t.Fatalf("unable to add invoice to registry: %v", err) 2511 } 2512 2513 // Since we are not using the link to handle HTLC IDs for the 2514 // remote channel, we must set this manually. This is the second 2515 // HTLC we add, hence it should have an ID of 1 (Alice's channel 2516 // link will set this automatically for her side). 2517 htlc.ID = 1 2518 _, err = bobChannel.AddHTLC(htlc, nil) 2519 if err != nil { 2520 t.Fatalf("unable to add htlc: %v", err) 2521 } 2522 aliceLink.HandleChannelUpdate(htlc) 2523 time.Sleep(time.Millisecond * 500) 2524 2525 // No changes before the HTLC is locked in. 2526 assertLinkBandwidth(t, aliceLink, aliceStartingBandwidth) 2527 if err := updateState(tmr, coreLink, bobChannel, false); err != nil { 2528 t.Fatalf("unable to update state: %v", err) 2529 } 2530 2531 // After lock-in, Alice will have to pay the htlc fee. 2532 assertLinkBandwidth(t, aliceLink, aliceStartingBandwidth-htlcFee) 2533 2534 addPkt = htlcPacket{ 2535 htlc: htlc, 2536 incomingChanID: aliceLink.ShortChanID(), 2537 incomingHTLCID: 1, 2538 obfuscator: NewMockObfuscator(), 2539 } 2540 2541 circuit = makePaymentCircuit(&htlc.PaymentHash, &addPkt) 2542 _, err = coreLink.cfg.Switch.commitCircuits(&circuit) 2543 if err != nil { 2544 t.Fatalf("unable to commit circuit: %v", err) 2545 } 2546 2547 addPkt.outgoingChanID = carolChanID 2548 addPkt.outgoingHTLCID = 1 2549 2550 err = coreLink.cfg.Circuits.OpenCircuits(addPkt.keystone()) 2551 if err != nil { 2552 t.Fatalf("unable to set keystone: %v", err) 2553 } 2554 2555 failPkt := htlcPacket{ 2556 incomingChanID: aliceLink.ShortChanID(), 2557 incomingHTLCID: 1, 2558 circuit: &circuit, 2559 outgoingChanID: addPkt.outgoingChanID, 2560 outgoingHTLCID: addPkt.outgoingHTLCID, 2561 htlc: &lnwire.UpdateFailHTLC{ 2562 ID: 1, 2563 }, 2564 obfuscator: NewMockObfuscator(), 2565 } 2566 2567 if err := aliceLink.handleSwitchPacket(&failPkt); err != nil { 2568 t.Fatalf("unable to handle switch packet: %v", err) 2569 } 2570 time.Sleep(time.Millisecond * 500) 2571 2572 // Alice should get all her bandwidth back. 2573 assertLinkBandwidth(t, aliceLink, aliceStartingBandwidth) 2574 2575 // Message should be sent to Bob. 2576 select { 2577 case msg = <-aliceMsgs: 2578 case <-time.After(15 * time.Second): 2579 t.Fatalf("did not receive message") 2580 } 2581 failMsg, ok = msg.(*lnwire.UpdateFailHTLC) 2582 if !ok { 2583 t.Fatalf("expected UpdateFailHTLC, got %T", msg) 2584 } 2585 err = bobChannel.ReceiveFailHTLC(failMsg.ID, []byte("fail")) 2586 if err != nil { 2587 t.Fatalf("failed receiving fail htlc: %v", err) 2588 } 2589 2590 // After failing an HTLC, the link will automatically trigger 2591 // a state update. 2592 if err := handleStateUpdate(coreLink, bobChannel); err != nil { 2593 t.Fatalf("unable to update state: %v", err) 2594 } 2595 assertLinkBandwidth(t, aliceLink, aliceStartingBandwidth) 2596 } 2597 2598 // genAddsAndCircuits creates `numHtlcs` sequential ADD packets and there 2599 // corresponding circuits. The provided `htlc` is used in all test packets. 2600 func genAddsAndCircuits(numHtlcs int, htlc *lnwire.UpdateAddHTLC) ( 2601 []*htlcPacket, []*PaymentCircuit) { 2602 2603 addPkts := make([]*htlcPacket, 0, numHtlcs) 2604 circuits := make([]*PaymentCircuit, 0, numHtlcs) 2605 for i := 0; i < numHtlcs; i++ { 2606 addPkt := htlcPacket{ 2607 htlc: htlc, 2608 incomingChanID: hop.Source, 2609 incomingHTLCID: uint64(i), 2610 obfuscator: NewMockObfuscator(), 2611 } 2612 2613 circuit := makePaymentCircuit(&htlc.PaymentHash, &addPkt) 2614 addPkt.circuit = &circuit 2615 2616 addPkts = append(addPkts, &addPkt) 2617 circuits = append(circuits, &circuit) 2618 } 2619 2620 return addPkts, circuits 2621 } 2622 2623 // TestChannelLinkTrimCircuitsPending checks that the switch and link properly 2624 // trim circuits if there are open circuits corresponding to ADDs on a pending 2625 // commmitment transaction. 2626 func TestChannelLinkTrimCircuitsPending(t *testing.T) { 2627 t.Parallel() 2628 2629 const ( 2630 chanAmt = dcrutil.AtomsPerCoin * 5 2631 numHtlcs = 4 2632 halfHtlcs = numHtlcs / 2 2633 ) 2634 2635 // We'll start by creating a new link with our chanAmt (5 DCR). We will 2636 // only be testing Alice's behavior, so the reference to Bob's channel 2637 // state is unnecessary. 2638 aliceLink, _, batchTicker, start, cleanUp, restore, err := 2639 newSingleLinkTestHarness(chanAmt, 0) 2640 if err != nil { 2641 t.Fatalf("unable to create link: %v", err) 2642 } 2643 defer cleanUp() 2644 2645 if err := start(); err != nil { 2646 t.Fatalf("unable to start test harness: %v", err) 2647 } 2648 2649 alice := newPersistentLinkHarness( 2650 t, aliceLink, batchTicker, restore, 2651 ) 2652 2653 // Compute the static fees that will be used to determine the 2654 // correctness of Alice's bandwidth when forwarding HTLCs. 2655 estimator := chainfee.NewStaticEstimator(1e4, 0) 2656 feePerKB, err := estimator.EstimateFeePerKB(1) 2657 if err != nil { 2658 t.Fatalf("unable to query fee estimator: %v", err) 2659 } 2660 2661 defaultCommitFee := alice.channel.StateSnapshot().CommitFee 2662 htlcFee := lnwire.NewMAtomsFromAtoms( 2663 feePerKB.FeeForSize(input.HTLCOutputSize), 2664 ) 2665 2666 // The starting bandwidth of the channel should be exactly the amount 2667 // that we created the channel between her and Bob, minus the 2668 // commitment fee and fee of adding an HTLC. 2669 expectedBandwidth := lnwire.NewMAtomsFromAtoms( 2670 chanAmt-defaultCommitFee, 2671 ) - htlcFee 2672 assertLinkBandwidth(t, alice.link, expectedBandwidth) 2673 2674 // Capture Alice's starting bandwidth to perform later, relative 2675 // bandwidth assertions. 2676 aliceStartingBandwidth := alice.link.Bandwidth() 2677 2678 // Next, we'll create an HTLC worth 1 DCR that will be used as a dummy 2679 // message for the test. 2680 var mockBlob [lnwire.OnionPacketSize]byte 2681 htlcAmt := lnwire.NewMAtomsFromAtoms(dcrutil.AtomsPerCoin) 2682 _, htlc, _, err := generatePayment(htlcAmt, htlcAmt, 5, mockBlob) 2683 if err != nil { 2684 t.Fatalf("unable to create payment: %v", err) 2685 } 2686 2687 // Create `numHtlc` htlcPackets and payment circuits that will be used 2688 // to drive the test. All of the packets will use the same dummy HTLC. 2689 addPkts, circuits := genAddsAndCircuits(numHtlcs, htlc) 2690 2691 // To begin the test, start by committing the circuits belong to our 2692 // first two HTLCs. 2693 fwdActions := alice.commitCircuits(circuits[:halfHtlcs]) 2694 2695 // Both of these circuits should have successfully added, as this is the 2696 // first attempt to send them. 2697 if len(fwdActions.Adds) != halfHtlcs { 2698 t.Fatalf("expected %d circuits to be added", halfHtlcs) 2699 } 2700 alice.assertNumPendingNumOpenCircuits(2, 0) 2701 2702 // Since both were committed successfully, we will now deliver them to 2703 // Alice's link. 2704 for _, addPkt := range addPkts[:halfHtlcs] { 2705 if err := alice.link.handleSwitchPacket(addPkt); err != nil { 2706 t.Fatalf("unable to handle switch packet: %v", err) 2707 } 2708 } 2709 2710 // Wait until Alice's link has sent both HTLCs via the peer. 2711 alice.checkSent(addPkts[:halfHtlcs]) 2712 2713 // The resulting bandwidth should reflect that Alice is paying both 2714 // htlc amounts, in addition to both htlc fees. 2715 assertLinkBandwidth(t, alice.link, 2716 aliceStartingBandwidth-halfHtlcs*(htlcAmt+htlcFee), 2717 ) 2718 2719 // Now, initiate a state transition by Alice so that the pending HTLCs 2720 // are locked in. This will *not* involve any participation by Bob, 2721 // which ensures the commitment will remain in a pending state. 2722 alice.trySignNextCommitment() 2723 alice.assertNumPendingNumOpenCircuits(2, 2) 2724 2725 // Restart Alice's link, which simulates a disconnection with the remote 2726 // peer. 2727 cleanUp = alice.restart(false, false) 2728 defer cleanUp() 2729 2730 alice.assertNumPendingNumOpenCircuits(2, 2) 2731 2732 // Make a second attempt to commit the first two circuits. This can 2733 // happen if the incoming link flaps, but also allows us to verify that 2734 // the circuits were trimmed properly. 2735 fwdActions = alice.commitCircuits(circuits[:halfHtlcs]) 2736 2737 // Since Alice has a pending commitment with the first two HTLCs, the 2738 // restart should not have trimmed them from the circuit map. 2739 // Therefore, we expect both of these circuits to be dropped by the 2740 // switch, as keystones should still be set. 2741 if len(fwdActions.Drops) != halfHtlcs { 2742 t.Fatalf("expected %d packets to be dropped", halfHtlcs) 2743 } 2744 2745 // The resulting bandwidth should remain unchanged from before, 2746 // reflecting that Alice is paying both htlc amounts, in addition to 2747 // both htlc fees. 2748 assertLinkBandwidth(t, alice.link, 2749 aliceStartingBandwidth-halfHtlcs*(htlcAmt+htlcFee), 2750 ) 2751 2752 // Now, restart Alice's link *and* the entire switch. This will ensure 2753 // that entire circuit map is reloaded from disk, and we can now test 2754 // against the behavioral differences of committing circuits that 2755 // conflict with duplicate circuits after a restart. 2756 cleanUp = alice.restart(true, false) 2757 defer cleanUp() 2758 2759 alice.assertNumPendingNumOpenCircuits(2, 2) 2760 2761 // Alice should not send out any messages. Even though Alice has a 2762 // pending commitment transaction, channel reestablishment is not 2763 // enabled in this test. 2764 select { 2765 case <-alice.msgs: 2766 t.Fatalf("message should not have been sent by Alice") 2767 case <-time.After(time.Second): 2768 } 2769 2770 // We will now try to commit the circuits for all of our HTLCs. The 2771 // first two are already on the pending commitment transaction, the 2772 // latter two are new HTLCs. 2773 fwdActions = alice.commitCircuits(circuits) 2774 2775 // The first two circuits should have been dropped, as they are still on 2776 // the pending commitment transaction, and the restart should not have 2777 // trimmed the circuits for these valid HTLCs. 2778 if len(fwdActions.Drops) != halfHtlcs { 2779 t.Fatalf("expected %d packets to be dropped", halfHtlcs) 2780 } 2781 // The latter two circuits are unknown the circuit map, and should 2782 // report being added. 2783 if len(fwdActions.Adds) != halfHtlcs { 2784 t.Fatalf("expected %d packets to be added", halfHtlcs) 2785 } 2786 2787 // Deliver the latter two HTLCs to Alice's links so that they can be 2788 // processed and added to the in-memory commitment state. 2789 for _, addPkt := range addPkts[halfHtlcs:] { 2790 if err := alice.link.handleSwitchPacket(addPkt); err != nil { 2791 t.Fatalf("unable to handle switch packet: %v", err) 2792 } 2793 } 2794 2795 // Wait for Alice to send the two latter HTLCs via the peer. 2796 alice.checkSent(addPkts[halfHtlcs:]) 2797 2798 // With two HTLCs on the pending commit, and two added to the in-memory 2799 // commitment state, the resulting bandwidth should reflect that Alice 2800 // is paying the all htlc amounts in addition to all htlc fees. 2801 assertLinkBandwidth(t, alice.link, 2802 aliceStartingBandwidth-numHtlcs*(htlcAmt+htlcFee), 2803 ) 2804 2805 // We will try to initiate a state transition for Alice, which will 2806 // ensure the circuits for the two in-memory HTLCs are opened. However, 2807 // since we have a pending commitment, these HTLCs will not actually be 2808 // included in a commitment. 2809 alice.trySignNextCommitment() 2810 alice.assertNumPendingNumOpenCircuits(4, 4) 2811 2812 // Restart Alice's link to simulate a disconnect. Since the switch 2813 // remains up throughout, the two latter HTLCs will remain in the link's 2814 // mailbox, and will reprocessed upon being reattached to the link. 2815 cleanUp = alice.restart(false, false) 2816 defer cleanUp() 2817 2818 alice.assertNumPendingNumOpenCircuits(4, 2) 2819 2820 // Again, try to recommit all of our circuits. 2821 fwdActions = alice.commitCircuits(circuits) 2822 2823 // It is expected that all of these will get dropped by the switch. 2824 // The first two circuits are still open as a result of being on the 2825 // commitment transaction. The latter two should have had their open 2826 // circuits trimmed, *but* since the HTLCs are still in Alice's mailbox, 2827 // the switch knows not to fail them as a result of the latter two 2828 // circuits never having been loaded from disk. 2829 if len(fwdActions.Drops) != numHtlcs { 2830 t.Fatalf("expected %d packets to be dropped", numHtlcs) 2831 } 2832 2833 // Wait for the latter two htlcs to be pulled from the mailbox, added to 2834 // the in-memory channel state, and sent out via the peer. 2835 alice.checkSent(addPkts[halfHtlcs:]) 2836 2837 // This should result in reconstructing the same bandwidth as our last 2838 // assertion. There are two HTLCs on the pending commit, and two added 2839 // to the in-memory commitment state, the resulting bandwidth should 2840 // reflect that Alice is paying the all htlc amounts in addition to all 2841 // htlc fees. 2842 assertLinkBandwidth(t, alice.link, 2843 aliceStartingBandwidth-numHtlcs*(htlcAmt+htlcFee), 2844 ) 2845 2846 // Again, we will try to initiate a state transition for Alice, which 2847 // will ensure the circuits for the two in-memory HTLCs are opened. 2848 // As before, these HTLCs will not actually be included in a commitment 2849 // since we have a pending commitment. 2850 alice.trySignNextCommitment() 2851 alice.assertNumPendingNumOpenCircuits(4, 4) 2852 2853 // As a final persistence check, we will restart the link and switch, 2854 // wiping the latter two HTLCs from memory, and forcing their circuits 2855 // to be reloaded from disk. 2856 cleanUp = alice.restart(true, false) 2857 defer cleanUp() 2858 2859 alice.assertNumPendingNumOpenCircuits(4, 2) 2860 2861 // Alice's mailbox will be empty after the restart, and no channel 2862 // reestablishment is configured, so no messages will be sent upon 2863 // restart. 2864 select { 2865 case <-alice.msgs: 2866 t.Fatalf("message should not have been sent by Alice") 2867 case <-time.After(time.Second): 2868 } 2869 2870 // Finally, make one last attempt to commit all circuits. 2871 fwdActions = alice.commitCircuits(circuits) 2872 2873 // The first two HTLCs should still be dropped by the htlcswitch. Their 2874 // existence on the pending commitment transaction should prevent their 2875 // open circuits from being trimmed. 2876 if len(fwdActions.Drops) != halfHtlcs { 2877 t.Fatalf("expected %d packets to be dropped", halfHtlcs) 2878 } 2879 // The latter two HTLCs should now be failed by the switch. These will 2880 // have been trimmed by the link or switch restarting, and since the 2881 // HTLCs are known to be lost from memory (since their circuits were 2882 // loaded from disk), it is safe fail them back as they won't ever be 2883 // delivered to the outgoing link. 2884 if len(fwdActions.Fails) != halfHtlcs { 2885 t.Fatalf("expected %d packets to be dropped", halfHtlcs) 2886 } 2887 2888 // Since the latter two HTLCs have been completely dropped from memory, 2889 // only the first two HTLCs we added should still be reflected in the 2890 // channel bandwidth. 2891 assertLinkBandwidth(t, alice.link, 2892 aliceStartingBandwidth-halfHtlcs*(htlcAmt+htlcFee), 2893 ) 2894 } 2895 2896 // TestChannelLinkTrimCircuitsNoCommit checks that the switch and link properly trim 2897 // circuits if the ADDs corresponding to open circuits are never committed. 2898 func TestChannelLinkTrimCircuitsNoCommit(t *testing.T) { 2899 if !build.IsDevBuild() { 2900 t.Fatalf("htlcswitch tests must be run with '-tags dev") 2901 } 2902 2903 t.Parallel() 2904 2905 const ( 2906 chanAmt = dcrutil.AtomsPerCoin * 5 2907 numHtlcs = 4 2908 halfHtlcs = numHtlcs / 2 2909 ) 2910 2911 // We'll start by creating a new link with our chanAmt (5 DCR). We will 2912 // only be testing Alice's behavior, so the reference to Bob's channel 2913 // state is unnecessary. 2914 aliceLink, _, batchTicker, start, cleanUp, restore, err := 2915 newSingleLinkTestHarness(chanAmt, 0) 2916 if err != nil { 2917 t.Fatalf("unable to create link: %v", err) 2918 } 2919 defer cleanUp() 2920 2921 if err := start(); err != nil { 2922 t.Fatalf("unable to start test harness: %v", err) 2923 } 2924 2925 alice := newPersistentLinkHarness( 2926 t, aliceLink, batchTicker, restore, 2927 ) 2928 2929 // We'll put Alice into hodl.Commit mode, such that the circuits for any 2930 // outgoing ADDs are opened, but the changes are not committed in the 2931 // channel state. 2932 alice.coreLink.cfg.HodlMask = hodl.Commit.Mask() 2933 2934 // Compute the static fees that will be used to determine the 2935 // correctness of Alice's bandwidth when forwarding HTLCs. 2936 estimator := chainfee.NewStaticEstimator(1e4, 0) 2937 feePerKB, err := estimator.EstimateFeePerKB(1) 2938 if err != nil { 2939 t.Fatalf("unable to query fee estimator: %v", err) 2940 } 2941 2942 defaultCommitFee := alice.channel.StateSnapshot().CommitFee 2943 htlcFee := lnwire.NewMAtomsFromAtoms( 2944 feePerKB.FeeForSize(input.HTLCOutputSize), 2945 ) 2946 2947 // The starting bandwidth of the channel should be exactly the amount 2948 // that we created the channel between her and Bob, minus the 2949 // commitment fee and fee for adding an additional HTLC. 2950 expectedBandwidth := lnwire.NewMAtomsFromAtoms( 2951 chanAmt-defaultCommitFee, 2952 ) - htlcFee 2953 assertLinkBandwidth(t, alice.link, expectedBandwidth) 2954 2955 // Capture Alice's starting bandwidth to perform later, relative 2956 // bandwidth assertions. 2957 aliceStartingBandwidth := alice.link.Bandwidth() 2958 2959 // Next, we'll create an HTLC worth 1 DCR that will be used as a dummy 2960 // message for the test. 2961 var mockBlob [lnwire.OnionPacketSize]byte 2962 htlcAmt := lnwire.NewMAtomsFromAtoms(dcrutil.AtomsPerCoin) 2963 _, htlc, _, err := generatePayment(htlcAmt, htlcAmt, 5, mockBlob) 2964 if err != nil { 2965 t.Fatalf("unable to create payment: %v", err) 2966 } 2967 2968 // Create `numHtlc` htlcPackets and payment circuits that will be used 2969 // to drive the test. All of the packets will use the same dummy HTLC. 2970 addPkts, circuits := genAddsAndCircuits(numHtlcs, htlc) 2971 2972 // To begin the test, start by committing the circuits belong to our 2973 // first two HTLCs. 2974 fwdActions := alice.commitCircuits(circuits[:halfHtlcs]) 2975 2976 // Both of these circuits should have successfully added, as this is the 2977 // first attempt to send them. 2978 if len(fwdActions.Adds) != halfHtlcs { 2979 t.Fatalf("expected %d circuits to be added", halfHtlcs) 2980 } 2981 2982 // Since both were committed successfully, we will now deliver them to 2983 // Alice's link. 2984 for _, addPkt := range addPkts[:halfHtlcs] { 2985 if err := alice.link.handleSwitchPacket(addPkt); err != nil { 2986 t.Fatalf("unable to handle switch packet: %v", err) 2987 } 2988 } 2989 2990 // Wait until Alice's link has sent both HTLCs via the peer. 2991 alice.checkSent(addPkts[:halfHtlcs]) 2992 2993 // The resulting bandwidth should reflect that Alice is paying both 2994 // htlc amounts, in addition to both htlc fees. 2995 assertLinkBandwidth(t, alice.link, 2996 aliceStartingBandwidth-halfHtlcs*(htlcAmt+htlcFee), 2997 ) 2998 2999 alice.assertNumPendingNumOpenCircuits(2, 0) 3000 3001 // Now, init a state transition by Alice to try and commit the HTLCs. 3002 // Since she is in hodl.Commit mode, this will fail, but the circuits 3003 // will be opened persistently. 3004 alice.trySignNextCommitment() 3005 3006 alice.assertNumPendingNumOpenCircuits(2, 2) 3007 3008 // Restart Alice's link, which simulates a disconnection with the remote 3009 // peer. Alice's link and switch should trim the circuits that were 3010 // opened but not committed. 3011 cleanUp = alice.restart(false, false, hodl.Commit) 3012 defer cleanUp() 3013 3014 alice.assertNumPendingNumOpenCircuits(2, 0) 3015 3016 // The first two HTLCs should have been reset in Alice's mailbox since 3017 // the switch was not shutdown. Knowing this the switch should drop the 3018 // two circuits, even if the circuits were trimmed. 3019 fwdActions = alice.commitCircuits(circuits[:halfHtlcs]) 3020 if len(fwdActions.Drops) != halfHtlcs { 3021 t.Fatalf("expected %d packets to be dropped since "+ 3022 "the switch has not been restarted", halfHtlcs) 3023 } 3024 3025 // Wait for alice to process the first two HTLCs resend them via the 3026 // peer. 3027 alice.checkSent(addPkts[:halfHtlcs]) 3028 3029 // The resulting bandwidth should reflect that Alice is paying both htlc 3030 // amounts, in addition to both htlc fees. 3031 assertLinkBandwidth(t, alice.link, 3032 aliceStartingBandwidth-halfHtlcs*(htlcAmt+htlcFee), 3033 ) 3034 3035 // Again, initiate another state transition by Alice to try and commit 3036 // the HTLCs. Since she is in hodl.Commit mode, this will fail, but the 3037 // circuits will be opened persistently. 3038 alice.trySignNextCommitment() 3039 alice.assertNumPendingNumOpenCircuits(2, 2) 3040 3041 // Now, we we will do a full restart of the link and switch, configuring 3042 // Alice again in hodl.Commit mode. Since none of the HTLCs were 3043 // actually committed, the previously opened circuits should be trimmed 3044 // by both the link and switch. 3045 cleanUp = alice.restart(true, false, hodl.Commit) 3046 defer cleanUp() 3047 3048 alice.assertNumPendingNumOpenCircuits(2, 0) 3049 3050 // Attempt another commit of our first two circuits. Both should fail, 3051 // as the opened circuits should have been trimmed, and circuit map 3052 // recognizes that these HTLCs were lost during the restart. 3053 fwdActions = alice.commitCircuits(circuits[:halfHtlcs]) 3054 if len(fwdActions.Fails) != halfHtlcs { 3055 t.Fatalf("expected %d packets to be failed", halfHtlcs) 3056 } 3057 3058 // Bob should not receive any HTLCs from Alice, since Alice's mailbox is 3059 // empty and there is no pending commitment. 3060 select { 3061 case <-alice.msgs: 3062 t.Fatalf("received unexpected message from Alice") 3063 case <-time.After(time.Second): 3064 } 3065 3066 // Alice's bandwidth should have reverted back to her starting value. 3067 assertLinkBandwidth(t, alice.link, aliceStartingBandwidth) 3068 3069 // Now, try to commit the last two payment circuits, which are unused 3070 // thus far. These should succeed without hesitation. 3071 fwdActions = alice.commitCircuits(circuits[halfHtlcs:]) 3072 if len(fwdActions.Adds) != halfHtlcs { 3073 t.Fatalf("expected %d packets to be added", halfHtlcs) 3074 } 3075 3076 // Deliver the last two HTLCs to the link via Alice's mailbox. 3077 for _, addPkt := range addPkts[halfHtlcs:] { 3078 if err := alice.link.handleSwitchPacket(addPkt); err != nil { 3079 t.Fatalf("unable to handle switch packet: %v", err) 3080 } 3081 } 3082 3083 // Verify that Alice processed and sent out the ADD packets via the 3084 // peer. 3085 alice.checkSent(addPkts[halfHtlcs:]) 3086 3087 // The resulting bandwidth should reflect that Alice is paying both htlc 3088 // amounts, in addition to both htlc fees. 3089 assertLinkBandwidth(t, alice.link, 3090 aliceStartingBandwidth-halfHtlcs*(htlcAmt+htlcFee), 3091 ) 3092 3093 // Now, initiate a state transition for Alice. Since we are hodl.Commit 3094 // mode, this will only open the circuits that were added to the 3095 // in-memory channel state. 3096 alice.trySignNextCommitment() 3097 alice.assertNumPendingNumOpenCircuits(4, 2) 3098 3099 // Restart Alice's link, and place her back in hodl.Commit mode. On 3100 // restart, all previously opened circuits should be trimmed by both the 3101 // link and the switch. 3102 cleanUp = alice.restart(false, false, hodl.Commit) 3103 defer cleanUp() 3104 3105 alice.assertNumPendingNumOpenCircuits(4, 0) 3106 3107 // Now, try to commit all of known circuits. 3108 fwdActions = alice.commitCircuits(circuits) 3109 3110 // The first two HTLCs will fail to commit for the same reason as 3111 // before, the circuits have been trimmed. 3112 if len(fwdActions.Fails) != halfHtlcs { 3113 t.Fatalf("expected %d packet to be failed", halfHtlcs) 3114 } 3115 3116 // The last two HTLCs will be dropped, as thought the circuits are 3117 // trimmed, the switch is aware that the HTLCs are still in Alice's 3118 // mailbox. 3119 if len(fwdActions.Drops) != halfHtlcs { 3120 t.Fatalf("expected %d packet to be dropped", halfHtlcs) 3121 } 3122 3123 // Wait until Alice reprocesses the last two HTLCs and sends them via 3124 // the peer. 3125 alice.checkSent(addPkts[halfHtlcs:]) 3126 3127 // Her bandwidth should now reflect having sent only those two HTLCs. 3128 assertLinkBandwidth(t, alice.link, 3129 aliceStartingBandwidth-halfHtlcs*(htlcAmt+htlcFee), 3130 ) 3131 3132 // Now, initiate a state transition for Alice. Since we are hodl.Commit 3133 // mode, this will only open the circuits that were added to the 3134 // in-memory channel state. 3135 alice.trySignNextCommitment() 3136 alice.assertNumPendingNumOpenCircuits(4, 2) 3137 3138 // Finally, do one last restart of both the link and switch. This will 3139 // flush the HTLCs from the mailbox. The circuits should now be trimmed 3140 // for all of the HTLCs. 3141 cleanUp = alice.restart(true, false, hodl.Commit) 3142 defer cleanUp() 3143 3144 alice.assertNumPendingNumOpenCircuits(4, 0) 3145 3146 // Bob should not receive any HTLCs from Alice, as none of the HTLCs are 3147 // in Alice's mailbox, and channel reestablishment is disabled. 3148 select { 3149 case <-alice.msgs: 3150 t.Fatalf("received unexpected message from Alice") 3151 case <-time.After(time.Second): 3152 } 3153 3154 // Attempt to commit the last two circuits, both should now fail since 3155 // though they were opened before shutting down, the circuits have been 3156 // properly trimmed. 3157 fwdActions = alice.commitCircuits(circuits[halfHtlcs:]) 3158 if len(fwdActions.Fails) != halfHtlcs { 3159 t.Fatalf("expected %d packet to be failed", halfHtlcs) 3160 } 3161 3162 // Alice balance should not have changed since the start. 3163 assertLinkBandwidth(t, alice.link, aliceStartingBandwidth) 3164 } 3165 3166 // TestChannelLinkTrimCircuitsRemoteCommit checks that the switch and link 3167 // don't trim circuits if the ADD is locked in on the remote commitment but 3168 // not on our local commitment. 3169 func TestChannelLinkTrimCircuitsRemoteCommit(t *testing.T) { 3170 t.Parallel() 3171 3172 const ( 3173 chanAmt = dcrutil.AtomsPerCoin * 5 3174 numHtlcs = 2 3175 ) 3176 3177 // We'll start by creating a new link with our chanAmt (5 BTC). 3178 aliceLink, bobChan, batchTicker, start, cleanUp, restore, err := 3179 newSingleLinkTestHarness(chanAmt, 0) 3180 if err != nil { 3181 t.Fatalf("unable to create link: %v", err) 3182 } 3183 3184 if err := start(); err != nil { 3185 t.Fatalf("unable to start test harness: %v", err) 3186 } 3187 defer cleanUp() 3188 3189 alice := newPersistentLinkHarness( 3190 t, aliceLink, batchTicker, restore, 3191 ) 3192 3193 // Compute the static fees that will be used to determine the 3194 // correctness of Alice's bandwidth when forwarding HTLCs. 3195 estimator := chainfee.NewStaticEstimator(1e4, 0) 3196 feePerKB, err := estimator.EstimateFeePerKB(1) 3197 if err != nil { 3198 t.Fatalf("unable to query fee estimator: %v", err) 3199 } 3200 3201 defaultCommitFee := alice.channel.StateSnapshot().CommitFee 3202 htlcFee := lnwire.NewMAtomsFromAtoms( 3203 feePerKB.FeeForSize(input.HTLCOutputSize), 3204 ) 3205 3206 // The starting bandwidth of the channel should be exactly the amount 3207 // that we created the channel between her and Bob, minus the commitment 3208 // fee and fee of adding an HTLC. 3209 expectedBandwidth := lnwire.NewMAtomsFromAtoms( 3210 chanAmt-defaultCommitFee, 3211 ) - htlcFee 3212 assertLinkBandwidth(t, alice.link, expectedBandwidth) 3213 3214 // Capture Alice's starting bandwidth to perform later, relative 3215 // bandwidth assertions. 3216 aliceStartingBandwidth := alice.link.Bandwidth() 3217 3218 // Next, we'll create an HTLC worth 1 BTC that will be used as a dummy 3219 // message for the test. 3220 var mockBlob [lnwire.OnionPacketSize]byte 3221 htlcAmt := lnwire.NewMAtomsFromAtoms(dcrutil.AtomsPerCoin) 3222 _, htlc, _, err := generatePayment(htlcAmt, htlcAmt, 5, mockBlob) 3223 if err != nil { 3224 t.Fatalf("unable to create payment: %v", err) 3225 } 3226 3227 // Create `numHtlc` htlcPackets and payment circuits that will be used 3228 // to drive the test. All of the packets will use the same dummy HTLC. 3229 addPkts, circuits := genAddsAndCircuits(numHtlcs, htlc) 3230 3231 // To begin the test, start by committing the circuits for our first two 3232 // HTLCs. 3233 fwdActions := alice.commitCircuits(circuits) 3234 3235 // Both of these circuits should have successfully added, as this is the 3236 // first attempt to send them. 3237 if len(fwdActions.Adds) != numHtlcs { 3238 t.Fatalf("expected %d circuits to be added", numHtlcs) 3239 } 3240 alice.assertNumPendingNumOpenCircuits(2, 0) 3241 3242 // Since both were committed successfully, we will now deliver them to 3243 // Alice's link. 3244 for _, addPkt := range addPkts { 3245 if err := alice.link.handleSwitchPacket(addPkt); err != nil { 3246 t.Fatalf("unable to handle switch packet: %v", err) 3247 } 3248 } 3249 3250 // Wait until Alice's link has sent both HTLCs via the peer. 3251 alice.checkSent(addPkts) 3252 3253 // Pass both of the htlcs to Bob. 3254 for i, addPkt := range addPkts { 3255 pkt, ok := addPkt.htlc.(*lnwire.UpdateAddHTLC) 3256 if !ok { 3257 t.Fatalf("unable to add packet") 3258 } 3259 3260 pkt.ID = uint64(i) 3261 3262 _, err := bobChan.ReceiveHTLC(pkt) 3263 if err != nil { 3264 t.Fatalf("unable to receive htlc: %v", err) 3265 } 3266 } 3267 3268 // The resulting bandwidth should reflect that Alice is paying both 3269 // htlc amounts, in addition to both htlc fees. 3270 assertLinkBandwidth(t, alice.link, 3271 aliceStartingBandwidth-numHtlcs*(htlcAmt+htlcFee), 3272 ) 3273 3274 // Now, initiate a state transition by Alice so that the pending HTLCs 3275 // are locked in. 3276 alice.trySignNextCommitment() 3277 alice.assertNumPendingNumOpenCircuits(2, 2) 3278 3279 select { 3280 case aliceMsg := <-alice.msgs: 3281 // Pass the commitment signature to Bob. 3282 sig, ok := aliceMsg.(*lnwire.CommitSig) 3283 if !ok { 3284 t.Fatalf("alice did not send commitment signature") 3285 } 3286 3287 err := bobChan.ReceiveNewCommitment(sig.CommitSig, sig.HtlcSigs) 3288 if err != nil { 3289 t.Fatalf("unable to receive new commitment: %v", err) 3290 } 3291 case <-time.After(time.Second): 3292 } 3293 3294 // Next, revoke Bob's current commitment and send it to Alice so that we 3295 // can test that Alice's circuits aren't trimmed. 3296 rev, _, err := bobChan.RevokeCurrentCommitment() 3297 if err != nil { 3298 t.Fatalf("unable to revoke current commitment: %v", err) 3299 } 3300 3301 _, _, _, _, err = alice.channel.ReceiveRevocation(rev) 3302 if err != nil { 3303 t.Fatalf("unable to receive revocation: %v", err) 3304 } 3305 3306 // Restart Alice's link, which simulates a disconnection with the remote 3307 // peer. 3308 cleanUp = alice.restart(false, false) 3309 defer cleanUp() 3310 3311 alice.assertNumPendingNumOpenCircuits(2, 2) 3312 3313 // Restart the link + switch and check that the number of open circuits 3314 // doesn't change. 3315 cleanUp = alice.restart(true, false) 3316 defer cleanUp() 3317 3318 alice.assertNumPendingNumOpenCircuits(2, 2) 3319 } 3320 3321 // TestChannelLinkBandwidthChanReserve checks that the bandwidth available 3322 // on the channel link reflects the channel reserve that must be kept 3323 // at all times. 3324 func TestChannelLinkBandwidthChanReserve(t *testing.T) { 3325 t.Parallel() 3326 3327 // First start a link that has a balance greater than it's 3328 // channel reserve. 3329 const chanAmt = dcrutil.AtomsPerCoin * 5 3330 const chanReserve = dcrutil.AtomsPerCoin * 1 3331 aliceLink, bobChannel, batchTimer, start, cleanUp, _, err := 3332 newSingleLinkTestHarness(chanAmt, chanReserve) 3333 if err != nil { 3334 t.Fatalf("unable to create link: %v", err) 3335 } 3336 defer cleanUp() 3337 3338 if err := start(); err != nil { 3339 t.Fatalf("unable to start test harness: %v", err) 3340 } 3341 3342 var ( 3343 mockBlob [lnwire.OnionPacketSize]byte 3344 coreLink = aliceLink.(*channelLink) 3345 coreChan = coreLink.channel 3346 defaultCommitFee = coreChan.StateSnapshot().CommitFee 3347 aliceStartingBandwidth = aliceLink.Bandwidth() 3348 aliceMsgs = coreLink.cfg.Peer.(*mockPeer).sentMsgs 3349 ) 3350 3351 estimator := chainfee.NewStaticEstimator(1e4, 0) 3352 feePerKB, err := estimator.EstimateFeePerKB(1) 3353 if err != nil { 3354 t.Fatalf("unable to query fee estimator: %v", err) 3355 } 3356 htlcFee := lnwire.NewMAtomsFromAtoms( 3357 feePerKB.FeeForSize(input.HTLCOutputSize), 3358 ) 3359 3360 // The starting bandwidth of the channel should be exactly the amount 3361 // that we created the channel between her and Bob, minus the channel 3362 // reserve, commitment fee and fee for adding an additional HTLC. 3363 expectedBandwidth := lnwire.NewMAtomsFromAtoms( 3364 chanAmt-defaultCommitFee-chanReserve) - htlcFee 3365 assertLinkBandwidth(t, aliceLink, expectedBandwidth) 3366 3367 // Next, we'll create an HTLC worth 3 DCR, and send it into the link as 3368 // a switch initiated payment. The resulting bandwidth should 3369 // now be decremented to reflect the new HTLC. 3370 htlcAmt := lnwire.NewMAtomsFromAtoms(3 * dcrutil.AtomsPerCoin) 3371 invoice, htlc, _, err := generatePayment(htlcAmt, htlcAmt, 5, mockBlob) 3372 if err != nil { 3373 t.Fatalf("unable to create payment: %v", err) 3374 } 3375 3376 addPkt := &htlcPacket{ 3377 htlc: htlc, 3378 obfuscator: NewMockObfuscator(), 3379 } 3380 circuit := makePaymentCircuit(&htlc.PaymentHash, addPkt) 3381 _, err = coreLink.cfg.Switch.commitCircuits(&circuit) 3382 if err != nil { 3383 t.Fatalf("unable to commit circuit: %v", err) 3384 } 3385 3386 _ = aliceLink.handleSwitchPacket(addPkt) 3387 time.Sleep(time.Millisecond * 100) 3388 assertLinkBandwidth(t, aliceLink, aliceStartingBandwidth-htlcAmt-htlcFee) 3389 3390 // Alice should send the HTLC to Bob. 3391 var msg lnwire.Message 3392 select { 3393 case msg = <-aliceMsgs: 3394 case <-time.After(15 * time.Second): 3395 t.Fatalf("did not receive message") 3396 } 3397 3398 addHtlc, ok := msg.(*lnwire.UpdateAddHTLC) 3399 if !ok { 3400 t.Fatalf("expected UpdateAddHTLC, got %T", msg) 3401 } 3402 3403 bobIndex, err := bobChannel.ReceiveHTLC(addHtlc) 3404 if err != nil { 3405 t.Fatalf("bob failed receiving htlc: %v", err) 3406 } 3407 3408 // Lock in the HTLC. 3409 if err := updateState(batchTimer, coreLink, bobChannel, true); err != nil { 3410 t.Fatalf("unable to update state: %v", err) 3411 } 3412 3413 assertLinkBandwidth(t, aliceLink, aliceStartingBandwidth-htlcAmt-htlcFee) 3414 3415 // If we now send in a valid HTLC settle for the prior HTLC we added, 3416 // then the bandwidth should remain unchanged as the remote party will 3417 // gain additional channel balance. 3418 err = bobChannel.SettleHTLC(*invoice.Terms.PaymentPreimage, bobIndex, nil, nil, nil) 3419 if err != nil { 3420 t.Fatalf("unable to settle htlc: %v", err) 3421 } 3422 htlcSettle := &lnwire.UpdateFulfillHTLC{ 3423 ID: bobIndex, 3424 PaymentPreimage: *invoice.Terms.PaymentPreimage, 3425 } 3426 aliceLink.HandleChannelUpdate(htlcSettle) 3427 time.Sleep(time.Millisecond * 500) 3428 3429 // Since the settle is not locked in yet, Alice's bandwidth should still 3430 // reflect that she has to pay the fee. 3431 assertLinkBandwidth(t, aliceLink, aliceStartingBandwidth-htlcAmt-htlcFee) 3432 3433 // Lock in the settle. 3434 if err := updateState(batchTimer, coreLink, bobChannel, false); err != nil { 3435 t.Fatalf("unable to update state: %v", err) 3436 } 3437 3438 time.Sleep(time.Millisecond * 100) 3439 assertLinkBandwidth(t, aliceLink, aliceStartingBandwidth-htlcAmt) 3440 3441 // Now we create a channel that has a channel reserve that is 3442 // greater than it's balance. In these case only payments can 3443 // be received on this channel, not sent. The available bandwidth 3444 // should therefore be 0. 3445 const bobChanAmt = dcrutil.AtomsPerCoin * 1 3446 const bobChanReserve = dcrutil.AtomsPerCoin * 1.5 3447 bobLink, _, _, start, bobCleanUp, _, err := 3448 newSingleLinkTestHarness(bobChanAmt, bobChanReserve) 3449 if err != nil { 3450 t.Fatalf("unable to create link: %v", err) 3451 } 3452 defer bobCleanUp() 3453 3454 if err := start(); err != nil { 3455 t.Fatalf("unable to start test harness: %v", err) 3456 } 3457 3458 // Make sure bandwidth is reported as 0. 3459 assertLinkBandwidth(t, bobLink, 0) 3460 } 3461 3462 // TestChannelRetransmission tests the ability of the channel links to 3463 // synchronize theirs states after abrupt disconnect. 3464 func TestChannelRetransmission(t *testing.T) { 3465 t.Parallel() 3466 3467 retransmissionTests := []struct { 3468 name string 3469 messages []expectedMessage 3470 }{ 3471 { 3472 // Tests the ability of the channel links states to be 3473 // synchronized after remote node haven't receive 3474 // revoke and ack message. 3475 name: "intercept last alice revoke_and_ack", 3476 messages: []expectedMessage{ 3477 // First initialization of the channel. 3478 {"alice", "bob", &lnwire.ChannelReestablish{}, false}, 3479 {"bob", "alice", &lnwire.ChannelReestablish{}, false}, 3480 3481 {"alice", "bob", &lnwire.FundingLocked{}, false}, 3482 {"bob", "alice", &lnwire.FundingLocked{}, false}, 3483 3484 // Send payment from Alice to Bob and intercept 3485 // the last revocation message, in this case 3486 // Bob should not proceed the payment farther. 3487 {"alice", "bob", &lnwire.UpdateAddHTLC{}, false}, 3488 {"alice", "bob", &lnwire.CommitSig{}, false}, 3489 {"bob", "alice", &lnwire.RevokeAndAck{}, false}, 3490 {"bob", "alice", &lnwire.CommitSig{}, false}, 3491 {"alice", "bob", &lnwire.RevokeAndAck{}, true}, 3492 3493 // Reestablish messages exchange on nodes restart. 3494 {"alice", "bob", &lnwire.ChannelReestablish{}, false}, 3495 {"bob", "alice", &lnwire.ChannelReestablish{}, false}, 3496 3497 // Alice should resend the revoke_and_ack 3498 // message to Bob because Bob claimed it in the 3499 // re-establish message. 3500 {"alice", "bob", &lnwire.RevokeAndAck{}, false}, 3501 3502 // Proceed the payment farther by sending the 3503 // fulfilment message and trigger the state 3504 // update. 3505 {"bob", "alice", &lnwire.UpdateFulfillHTLC{}, false}, 3506 {"bob", "alice", &lnwire.CommitSig{}, false}, 3507 {"alice", "bob", &lnwire.RevokeAndAck{}, false}, 3508 {"alice", "bob", &lnwire.CommitSig{}, false}, 3509 {"bob", "alice", &lnwire.RevokeAndAck{}, false}, 3510 }, 3511 }, 3512 { 3513 // Tests the ability of the channel links states to be 3514 // synchronized after remote node haven't receive 3515 // revoke and ack message. 3516 name: "intercept bob revoke_and_ack commit_sig messages", 3517 messages: []expectedMessage{ 3518 {"alice", "bob", &lnwire.ChannelReestablish{}, false}, 3519 {"bob", "alice", &lnwire.ChannelReestablish{}, false}, 3520 3521 {"alice", "bob", &lnwire.FundingLocked{}, false}, 3522 {"bob", "alice", &lnwire.FundingLocked{}, false}, 3523 3524 // Send payment from Alice to Bob and intercept 3525 // the last revocation message, in this case 3526 // Bob should not proceed the payment farther. 3527 {"alice", "bob", &lnwire.UpdateAddHTLC{}, false}, 3528 {"alice", "bob", &lnwire.CommitSig{}, false}, 3529 3530 // Intercept bob commit sig and revoke and ack 3531 // messages. 3532 {"bob", "alice", &lnwire.RevokeAndAck{}, true}, 3533 {"bob", "alice", &lnwire.CommitSig{}, true}, 3534 3535 // Reestablish messages exchange on nodes restart. 3536 {"alice", "bob", &lnwire.ChannelReestablish{}, false}, 3537 {"bob", "alice", &lnwire.ChannelReestablish{}, false}, 3538 3539 // Bob should resend previously intercepted messages. 3540 {"bob", "alice", &lnwire.RevokeAndAck{}, false}, 3541 {"bob", "alice", &lnwire.CommitSig{}, false}, 3542 3543 // Proceed the payment farther by sending the 3544 // fulfilment message and trigger the state 3545 // update. 3546 {"alice", "bob", &lnwire.RevokeAndAck{}, false}, 3547 {"bob", "alice", &lnwire.UpdateFulfillHTLC{}, false}, 3548 {"bob", "alice", &lnwire.CommitSig{}, false}, 3549 {"alice", "bob", &lnwire.RevokeAndAck{}, false}, 3550 {"alice", "bob", &lnwire.CommitSig{}, false}, 3551 {"bob", "alice", &lnwire.RevokeAndAck{}, false}, 3552 }, 3553 }, 3554 { 3555 // Tests the ability of the channel links states to be 3556 // synchronized after remote node haven't receive 3557 // update and commit sig messages. 3558 name: "intercept update add htlc and commit sig messages", 3559 messages: []expectedMessage{ 3560 {"alice", "bob", &lnwire.ChannelReestablish{}, false}, 3561 {"bob", "alice", &lnwire.ChannelReestablish{}, false}, 3562 3563 {"alice", "bob", &lnwire.FundingLocked{}, false}, 3564 {"bob", "alice", &lnwire.FundingLocked{}, false}, 3565 3566 // Attempt make a payment from Alice to Bob, 3567 // which is intercepted, emulating the Bob 3568 // server abrupt stop. 3569 {"alice", "bob", &lnwire.UpdateAddHTLC{}, true}, 3570 {"alice", "bob", &lnwire.CommitSig{}, true}, 3571 3572 // Restart of the nodes, and after that nodes 3573 // should exchange the reestablish messages. 3574 {"alice", "bob", &lnwire.ChannelReestablish{}, false}, 3575 {"bob", "alice", &lnwire.ChannelReestablish{}, false}, 3576 3577 {"alice", "bob", &lnwire.FundingLocked{}, false}, 3578 {"bob", "alice", &lnwire.FundingLocked{}, false}, 3579 3580 // After Bob has notified Alice that he didn't 3581 // receive updates Alice should re-send them. 3582 {"alice", "bob", &lnwire.UpdateAddHTLC{}, false}, 3583 {"alice", "bob", &lnwire.CommitSig{}, false}, 3584 3585 {"bob", "alice", &lnwire.RevokeAndAck{}, false}, 3586 {"bob", "alice", &lnwire.CommitSig{}, false}, 3587 {"alice", "bob", &lnwire.RevokeAndAck{}, false}, 3588 3589 {"bob", "alice", &lnwire.UpdateFulfillHTLC{}, false}, 3590 {"bob", "alice", &lnwire.CommitSig{}, false}, 3591 {"alice", "bob", &lnwire.RevokeAndAck{}, false}, 3592 {"alice", "bob", &lnwire.CommitSig{}, false}, 3593 {"bob", "alice", &lnwire.RevokeAndAck{}, false}, 3594 }, 3595 }, 3596 } 3597 paymentWithRestart := func(t *testing.T, messages []expectedMessage) { 3598 channels, cleanUp, restoreChannelsFromDb, err := createClusterChannels( 3599 dcrutil.AtomsPerCoin*5, 3600 dcrutil.AtomsPerCoin*5) 3601 if err != nil { 3602 t.Fatalf("unable to create channel: %v", err) 3603 } 3604 defer cleanUp() 3605 3606 chanID := lnwire.NewChanIDFromOutPoint(channels.aliceToBob.ChannelPoint()) 3607 serverErr := make(chan error, 4) 3608 3609 aliceInterceptor := createInterceptorFunc("[alice] <-- [bob]", 3610 "alice", messages, chanID, false) 3611 bobInterceptor := createInterceptorFunc("[alice] --> [bob]", 3612 "bob", messages, chanID, false) 3613 3614 ct := newConcurrentTester(t) 3615 3616 // Add interceptor to check the order of Bob and Alice 3617 // messages. 3618 n := newThreeHopNetwork(ct, 3619 channels.aliceToBob, channels.bobToAlice, 3620 channels.bobToCarol, channels.carolToBob, 3621 testStartingHeight, 3622 ) 3623 n.aliceServer.intersect(aliceInterceptor) 3624 n.bobServer.intersect(bobInterceptor) 3625 if err := n.start(); err != nil { 3626 ct.Fatalf("unable to start three hop network: %v", err) 3627 } 3628 defer n.stop() 3629 3630 bobBandwidthBefore := n.firstBobChannelLink.Bandwidth() 3631 aliceBandwidthBefore := n.aliceChannelLink.Bandwidth() 3632 3633 amount := lnwire.NewMAtomsFromAtoms(dcrutil.AtomsPerCoin) 3634 htlcAmt, totalTimelock, hops := generateHops(amount, testStartingHeight, 3635 n.firstBobChannelLink) 3636 3637 // Send payment which should fail because we intercept the 3638 // update and commit messages. 3639 // 3640 // TODO(roasbeef); increase timeout? 3641 receiver := n.bobServer 3642 firstHop := n.firstBobChannelLink.ShortChanID() 3643 rhash, err := makePayment( 3644 n.aliceServer, receiver, firstHop, hops, amount, 3645 htlcAmt, totalTimelock, 3646 ).Wait(time.Second * 5) 3647 if err == nil { 3648 ct.Fatalf("payment shouldn't haven been finished") 3649 } 3650 3651 // Stop network cluster and create new one, with the old 3652 // channels states. Also do the *hack* - save the payment 3653 // receiver to pass it in new channel link, otherwise payment 3654 // will be failed because of the unknown payment hash. Hack 3655 // will be removed with sphinx payment. 3656 bobRegistry := n.bobServer.registry 3657 n.stop() 3658 3659 channels, err = restoreChannelsFromDb() 3660 if err != nil { 3661 ct.Fatalf("unable to restore channels from database: %v", err) 3662 } 3663 3664 n = newThreeHopNetwork(ct, channels.aliceToBob, channels.bobToAlice, 3665 channels.bobToCarol, channels.carolToBob, testStartingHeight) 3666 n.firstBobChannelLink.cfg.Registry = bobRegistry 3667 n.aliceServer.intersect(aliceInterceptor) 3668 n.bobServer.intersect(bobInterceptor) 3669 3670 if err := n.start(); err != nil { 3671 ct.Fatalf("unable to start three hop network: %v", err) 3672 } 3673 defer n.stop() 3674 3675 // Wait for reestablishment to be proceeded and invoice to be settled. 3676 // TODO(andrew.shvv) Will be removed if we move the notification center 3677 // to the channel link itself. 3678 3679 var invoice channeldb.Invoice 3680 for i := 0; i < 20; i++ { 3681 select { 3682 case <-time.After(time.Millisecond * 200): 3683 case serverErr := <-serverErr: 3684 ct.Fatalf("server error: %v", serverErr) 3685 } 3686 3687 // Check that alice invoice wasn't settled and 3688 // bandwidth of htlc links hasn't been changed. 3689 invoice, err = receiver.registry.LookupInvoice(rhash) 3690 if err != nil { 3691 err = errors.Errorf("unable to get invoice: %v", err) 3692 continue 3693 } 3694 if invoice.State != channeldb.ContractSettled { 3695 err = errors.Errorf("alice invoice haven't been settled") 3696 continue 3697 } 3698 3699 aliceExpectedBandwidth := aliceBandwidthBefore - htlcAmt 3700 if aliceExpectedBandwidth != n.aliceChannelLink.Bandwidth() { 3701 err = errors.Errorf("expected alice to have %v, instead has %v", 3702 aliceExpectedBandwidth, n.aliceChannelLink.Bandwidth()) 3703 continue 3704 } 3705 3706 bobExpectedBandwidth := bobBandwidthBefore + htlcAmt 3707 if bobExpectedBandwidth != n.firstBobChannelLink.Bandwidth() { 3708 err = errors.Errorf("expected bob to have %v, instead has %v", 3709 bobExpectedBandwidth, n.firstBobChannelLink.Bandwidth()) 3710 continue 3711 } 3712 3713 break 3714 } 3715 3716 if err != nil { 3717 ct.Fatal(err) 3718 } 3719 } 3720 3721 for _, test := range retransmissionTests { 3722 passed := t.Run(test.name, func(t *testing.T) { 3723 paymentWithRestart(t, test.messages) 3724 }) 3725 3726 if !passed { 3727 break 3728 } 3729 } 3730 3731 } 3732 3733 // TestShouldAdjustCommitFee tests the shouldAdjustCommitFee pivot function to 3734 // ensure that ie behaves properly. We should only update the fee if it 3735 // deviates from our current fee by more 10% or more. 3736 func TestShouldAdjustCommitFee(t *testing.T) { 3737 tests := []struct { 3738 netFee chainfee.AtomPerKByte 3739 chanFee chainfee.AtomPerKByte 3740 minRelayFee chainfee.AtomPerKByte 3741 shouldAdjust bool 3742 }{ 3743 3744 // The network fee is 3x lower than the current commitment 3745 // transaction. As a result, we should adjust our fee to match 3746 // it. 3747 { 3748 netFee: 100, 3749 chanFee: 3000, 3750 shouldAdjust: true, 3751 }, 3752 3753 // The network fee is lower than the current commitment fee, 3754 // but only slightly so, so we won't update the commitment fee. 3755 { 3756 netFee: 2999, 3757 chanFee: 3000, 3758 shouldAdjust: false, 3759 }, 3760 3761 // The network fee is lower than the commitment fee, but only 3762 // right before it crosses our current threshold. 3763 { 3764 netFee: 1000, 3765 chanFee: 1099, 3766 shouldAdjust: false, 3767 }, 3768 3769 // The network fee is lower than the commitment fee, and within 3770 // our range of adjustment, so we should adjust. 3771 { 3772 netFee: 1000, 3773 chanFee: 1100, 3774 shouldAdjust: true, 3775 }, 3776 3777 // The network fee is 2x higher than our commitment fee, so we 3778 // should adjust upwards. 3779 { 3780 netFee: 2000, 3781 chanFee: 1000, 3782 shouldAdjust: true, 3783 }, 3784 3785 // The network fee is higher than our commitment fee, but only 3786 // slightly so, so we won't update. 3787 { 3788 netFee: 1001, 3789 chanFee: 1000, 3790 shouldAdjust: false, 3791 }, 3792 3793 // The network fee is higher than our commitment fee, but 3794 // hasn't yet crossed our activation threshold. 3795 { 3796 netFee: 1100, 3797 chanFee: 1099, 3798 shouldAdjust: false, 3799 }, 3800 3801 // The network fee is higher than our commitment fee, and 3802 // within our activation threshold, so we should update our 3803 // fee. 3804 { 3805 netFee: 1100, 3806 chanFee: 1000, 3807 shouldAdjust: true, 3808 }, 3809 3810 // Our fees match exactly, so we shouldn't update it at all. 3811 { 3812 netFee: 1000, 3813 chanFee: 1000, 3814 shouldAdjust: false, 3815 }, 3816 3817 // The network fee is higher than our commitment fee, 3818 // hasn't yet crossed our activation threshold, but the 3819 // current commitment fee is below the minimum relay fee and 3820 // so the fee should be updated. 3821 { 3822 netFee: 1100, 3823 chanFee: 1098, 3824 minRelayFee: 1099, 3825 shouldAdjust: true, 3826 }, 3827 } 3828 3829 for i, test := range tests { 3830 adjustedFee := shouldAdjustCommitFee( 3831 test.netFee, test.chanFee, test.minRelayFee, 3832 ) 3833 3834 if adjustedFee && !test.shouldAdjust { 3835 t.Fatalf("test #%v failed: net_fee=%v, "+ 3836 "chan_fee=%v, adjust_expect=%v, adjust_returned=%v", 3837 i, test.netFee, test.chanFee, test.shouldAdjust, 3838 adjustedFee) 3839 } 3840 } 3841 } 3842 3843 // TestChannelLinkShutdownDuringForward asserts that a link can be fully 3844 // stopped when it is trying to send synchronously through the switch. The 3845 // specific case this can occur is when a link forwards incoming Adds. We test 3846 // this by forcing the switch into a state where it will not accept new packets, 3847 // and then killing the link, which can only succeed if forwarding can be 3848 // canceled by a call to Stop. 3849 func TestChannelLinkShutdownDuringForward(t *testing.T) { 3850 t.Parallel() 3851 3852 // First, we'll create our traditional three hop network. We're 3853 // interested in testing the ability to stop the link when it is 3854 // synchronously forwarding to the switch, which happens when an 3855 // incoming link forwards Adds. Thus, the test will be performed 3856 // against Bob's first link. 3857 channels, cleanUp, _, err := createClusterChannels( 3858 dcrutil.AtomsPerCoin*3, 3859 dcrutil.AtomsPerCoin*5) 3860 if err != nil { 3861 t.Fatalf("unable to create channel: %v", err) 3862 } 3863 defer cleanUp() 3864 3865 n := newThreeHopNetwork(t, channels.aliceToBob, channels.bobToAlice, 3866 channels.bobToCarol, channels.carolToBob, testStartingHeight) 3867 3868 if err := n.start(); err != nil { 3869 t.Fatal(err) 3870 } 3871 defer n.stop() 3872 defer n.feeEstimator.Stop() 3873 3874 // Define a helper method that strobes the switch's log ticker, and 3875 // unblocks after nothing has been pulled for two seconds. 3876 waitForBobsSwitchToBlock := func() { 3877 bobSwitch := n.firstBobChannelLink.cfg.Switch 3878 ticker := bobSwitch.cfg.LogEventTicker.(*ticker.Force) 3879 timeout := time.After(15 * time.Second) 3880 for { 3881 time.Sleep(50 * time.Millisecond) 3882 select { 3883 case ticker.Force <- time.Now(): 3884 3885 case <-time.After(2 * time.Second): 3886 return 3887 3888 case <-timeout: 3889 t.Fatalf("switch did not block") 3890 } 3891 } 3892 } 3893 3894 // Define a helper method that strobes the link's batch ticker, and 3895 // unblocks after nothing has been pulled for two seconds. 3896 waitForBobsIncomingLinkToBlock := func() { 3897 ticker := n.firstBobChannelLink.cfg.BatchTicker.(*ticker.Force) 3898 timeout := time.After(15 * time.Second) 3899 for { 3900 time.Sleep(50 * time.Millisecond) 3901 select { 3902 case ticker.Force <- time.Now(): 3903 3904 case <-time.After(2 * time.Second): 3905 // We'll give a little extra time here, to 3906 // ensure that the packet is being pressed 3907 // against the htlcPlex. 3908 time.Sleep(50 * time.Millisecond) 3909 return 3910 3911 case <-timeout: 3912 t.Fatalf("link did not block") 3913 } 3914 } 3915 } 3916 3917 // To test that the cancellation is happening properly, we will set the 3918 // switch's htlcPlex to nil, so that calls to routeAsync block, and can 3919 // only exit if the link (or switch) is exiting. We will only be testing 3920 // the link here. 3921 // 3922 // In order to avoid data races, we need to ensure the switch isn't 3923 // selecting on that channel in the meantime. We'll prevent this by 3924 // first acquiring the index mutex and forcing a log event so that the 3925 // htlcForwarder is blocked inside the logTicker case, which also needs 3926 // the indexMtx. 3927 n.firstBobChannelLink.cfg.Switch.indexMtx.Lock() 3928 3929 // Strobe the log ticker, and wait for switch to stop accepting any more 3930 // log ticks. 3931 waitForBobsSwitchToBlock() 3932 3933 // While the htlcForwarder is blocked, swap out the htlcPlex with a nil 3934 // channel, and unlock the indexMtx to allow return to the 3935 // htlcForwarder's main select. After this, any attempt to forward 3936 // through the switch will block. 3937 n.firstBobChannelLink.cfg.Switch.htlcPlex = nil 3938 n.firstBobChannelLink.cfg.Switch.indexMtx.Unlock() 3939 3940 // Now, make a payment from Alice to Carol, which should cause Bob's 3941 // incoming link to block when it tries to submit the packet to the nil 3942 // htlcPlex. 3943 amount := lnwire.NewMAtomsFromAtoms(dcrutil.AtomsPerCoin) 3944 htlcAmt, totalTimelock, hops := generateHops( 3945 amount, testStartingHeight, 3946 n.firstBobChannelLink, n.carolChannelLink, 3947 ) 3948 3949 firstHop := n.firstBobChannelLink.ShortChanID() 3950 makePayment( 3951 n.aliceServer, n.carolServer, firstHop, hops, amount, htlcAmt, 3952 totalTimelock, 3953 ) 3954 3955 // Strobe the batch ticker of Bob's incoming link, waiting for it to 3956 // become fully blocked. 3957 waitForBobsIncomingLinkToBlock() 3958 3959 // Finally, stop the link to test that it can exit while synchronously 3960 // forwarding Adds to the switch. 3961 done := make(chan struct{}) 3962 go func() { 3963 n.firstBobChannelLink.Stop() 3964 close(done) 3965 }() 3966 3967 select { 3968 case <-time.After(3 * time.Second): 3969 t.Fatalf("unable to shutdown link while fwding incoming Adds") 3970 case <-done: 3971 } 3972 } 3973 3974 // TestChannelLinkUpdateCommitFee tests that when a new block comes in, the 3975 // channel link properly checks to see if it should update the commitment fee. 3976 func TestChannelLinkUpdateCommitFee(t *testing.T) { 3977 t.Parallel() 3978 3979 // First, we'll create our traditional three hop network. We'll only be 3980 // interacting with and asserting the state of two of the end points 3981 // for this test. 3982 const aliceInitialBalance = dcrutil.AtomsPerCoin * 3 3983 channels, cleanUp, _, err := createClusterChannels( 3984 aliceInitialBalance, dcrutil.AtomsPerCoin*5, 3985 ) 3986 if err != nil { 3987 t.Fatalf("unable to create channel: %v", err) 3988 } 3989 defer cleanUp() 3990 3991 n := newThreeHopNetwork(t, channels.aliceToBob, channels.bobToAlice, 3992 channels.bobToCarol, channels.carolToBob, testStartingHeight) 3993 3994 // First, we'll set up some message interceptors to ensure that the 3995 // proper messages are sent when updating fees. 3996 chanID := n.aliceChannelLink.ChanID() 3997 messages := []expectedMessage{ 3998 {"alice", "bob", &lnwire.ChannelReestablish{}, false}, 3999 {"bob", "alice", &lnwire.ChannelReestablish{}, false}, 4000 4001 {"alice", "bob", &lnwire.FundingLocked{}, false}, 4002 {"bob", "alice", &lnwire.FundingLocked{}, false}, 4003 4004 // First fee update. 4005 {"alice", "bob", &lnwire.UpdateFee{}, false}, 4006 {"alice", "bob", &lnwire.CommitSig{}, false}, 4007 {"bob", "alice", &lnwire.RevokeAndAck{}, false}, 4008 {"bob", "alice", &lnwire.CommitSig{}, false}, 4009 {"alice", "bob", &lnwire.RevokeAndAck{}, false}, 4010 4011 // Second fee update. 4012 {"alice", "bob", &lnwire.UpdateFee{}, false}, 4013 {"alice", "bob", &lnwire.CommitSig{}, false}, 4014 {"bob", "alice", &lnwire.RevokeAndAck{}, false}, 4015 {"bob", "alice", &lnwire.CommitSig{}, false}, 4016 {"alice", "bob", &lnwire.RevokeAndAck{}, false}, 4017 4018 // Third fee update. 4019 {"alice", "bob", &lnwire.UpdateFee{}, false}, 4020 {"alice", "bob", &lnwire.CommitSig{}, false}, 4021 {"bob", "alice", &lnwire.RevokeAndAck{}, false}, 4022 {"bob", "alice", &lnwire.CommitSig{}, false}, 4023 {"alice", "bob", &lnwire.RevokeAndAck{}, false}, 4024 } 4025 n.aliceServer.intersect(createInterceptorFunc("[alice] <-- [bob]", 4026 "alice", messages, chanID, false)) 4027 n.bobServer.intersect(createInterceptorFunc("[alice] --> [bob]", 4028 "bob", messages, chanID, false)) 4029 4030 if err := n.start(); err != nil { 4031 t.Fatal(err) 4032 } 4033 defer n.stop() 4034 defer n.feeEstimator.Stop() 4035 4036 startingFeeRate := channels.aliceToBob.CommitFeeRate() 4037 4038 // triggerFeeUpdate is a helper closure to determine whether a fee 4039 // update was triggered and completed properly. 4040 triggerFeeUpdate := func(feeEstimate, minRelayFee, 4041 newFeeRate chainfee.AtomPerKByte, shouldUpdate bool) { 4042 4043 t.Helper() 4044 4045 // Record the fee rates before the links process the fee update 4046 // to test the case where a fee update isn't triggered. 4047 aliceBefore := channels.aliceToBob.CommitFeeRate() 4048 bobBefore := channels.bobToAlice.CommitFeeRate() 4049 4050 // For the sake of this test, we'll reset the timer so that 4051 // Alice's link queries for a new network fee. 4052 n.aliceChannelLink.updateFeeTimer.Reset(time.Millisecond) 4053 4054 // Next, we'll send the first fee rate response to Alice. 4055 select { 4056 case n.feeEstimator.byteFeeIn <- feeEstimate: 4057 case <-time.After(time.Second * 5): 4058 t.Fatalf("alice didn't query for the new network fee") 4059 } 4060 4061 // We also send the min relay fee response to Alice. 4062 select { 4063 case n.feeEstimator.relayFee <- minRelayFee: 4064 case <-time.After(time.Second * 5): 4065 t.Fatalf("alice didn't query for the min relay fee") 4066 } 4067 4068 // Record the fee rates after the links have processed the fee 4069 // update and ensure they are correct based on whether a fee 4070 // update should have been triggered. 4071 require.Eventually(t, func() bool { 4072 aliceAfter := channels.aliceToBob.CommitFeeRate() 4073 bobAfter := channels.bobToAlice.CommitFeeRate() 4074 4075 switch { 4076 case shouldUpdate && aliceAfter != newFeeRate: 4077 return false 4078 4079 case shouldUpdate && bobAfter != newFeeRate: 4080 return false 4081 4082 case !shouldUpdate && aliceAfter != aliceBefore: 4083 return false 4084 4085 case !shouldUpdate && bobAfter != bobBefore: 4086 return false 4087 } 4088 4089 return true 4090 }, 10*time.Second, time.Second) 4091 } 4092 4093 minRelayFee := startingFeeRate / 3 4094 4095 // Triggering the link to update the fee of the channel with the same 4096 // fee rate should not send a fee update. 4097 triggerFeeUpdate(startingFeeRate, minRelayFee, startingFeeRate, false) 4098 4099 // Triggering the link to update the fee of the channel with a much 4100 // larger fee rate _should_ send a fee update. 4101 newFeeRate := startingFeeRate * 3 4102 triggerFeeUpdate(newFeeRate, minRelayFee, newFeeRate, true) 4103 4104 // Triggering the link to update the fee of the channel with a fee rate 4105 // that exceeds its maximum fee allocation should result in a fee rate 4106 // corresponding to the maximum fee allocation. 4107 const maxFeeRate chainfee.AtomPerKByte = 412086510 // 598180000 4108 triggerFeeUpdate(maxFeeRate+1, minRelayFee, maxFeeRate, true) 4109 4110 // Triggering the link to update the fee of the channel with a fee rate 4111 // that is below the current min relay fee rate should result in a fee 4112 // rate corresponding to the minimum relay fee. 4113 newFeeRate = minRelayFee / 2 4114 triggerFeeUpdate(newFeeRate, minRelayFee, chainfee.FeePerKBFloor, true) 4115 } 4116 4117 // TestChannelLinkAcceptDuplicatePayment tests that if a link receives an 4118 // incoming HTLC for a payment we have already settled, then it accepts the 4119 // HTLC. We do this to simplify the processing of settles after restarts or 4120 // failures, reducing ambiguity when a batch is only partially processed. 4121 func TestChannelLinkAcceptDuplicatePayment(t *testing.T) { 4122 t.Parallel() 4123 4124 // First, we'll create our traditional three hop network. We'll only be 4125 // interacting with and asserting the state of two of the end points 4126 // for this test. 4127 channels, cleanUp, _, err := createClusterChannels( 4128 dcrutil.AtomsPerCoin*3, 4129 dcrutil.AtomsPerCoin*5) 4130 if err != nil { 4131 t.Fatalf("unable to create channel: %v", err) 4132 } 4133 defer cleanUp() 4134 4135 n := newThreeHopNetwork(t, channels.aliceToBob, channels.bobToAlice, 4136 channels.bobToCarol, channels.carolToBob, testStartingHeight) 4137 if err := n.start(); err != nil { 4138 t.Fatalf("unable to start three hop network: %v", err) 4139 } 4140 defer n.stop() 4141 4142 amount := lnwire.NewMAtomsFromAtoms(dcrutil.AtomsPerCoin) 4143 4144 // We'll start off by making a payment from Alice to Carol. We'll 4145 // manually generate this request so we can control all the parameters. 4146 htlcAmt, totalTimelock, hops := generateHops(amount, testStartingHeight, 4147 n.firstBobChannelLink, n.carolChannelLink) 4148 blob, err := generateRoute(hops...) 4149 if err != nil { 4150 t.Fatal(err) 4151 } 4152 invoice, htlc, pid, err := generatePayment( 4153 amount, htlcAmt, totalTimelock, blob, 4154 ) 4155 if err != nil { 4156 t.Fatal(err) 4157 } 4158 4159 err = n.carolServer.registry.AddInvoice(*invoice, htlc.PaymentHash) 4160 if err != nil { 4161 t.Fatalf("unable to add invoice in carol registry: %v", err) 4162 } 4163 4164 // With the invoice now added to Carol's registry, we'll send the 4165 // payment. 4166 err = n.aliceServer.htlcSwitch.SendHTLC( 4167 n.firstBobChannelLink.ShortChanID(), pid, htlc, 4168 ) 4169 if err != nil { 4170 t.Fatalf("unable to send payment to carol: %v", err) 4171 } 4172 4173 resultChan, err := n.aliceServer.htlcSwitch.GetPaymentResult( 4174 pid, htlc.PaymentHash, newMockDeobfuscator(), 4175 ) 4176 if err != nil { 4177 t.Fatalf("unable to get payment result: %v", err) 4178 } 4179 4180 // Now, if we attempt to send the payment *again* it should be rejected 4181 // as it's a duplicate request. 4182 err = n.aliceServer.htlcSwitch.SendHTLC( 4183 n.firstBobChannelLink.ShortChanID(), pid, htlc, 4184 ) 4185 if err != ErrDuplicateAdd { 4186 t.Fatalf("ErrDuplicateAdd should have been "+ 4187 "received got: %v", err) 4188 } 4189 4190 select { 4191 case result, ok := <-resultChan: 4192 if !ok { 4193 t.Fatalf("unexpected shutdown") 4194 } 4195 4196 if result.Error != nil { 4197 t.Fatalf("payment failed: %v", result.Error) 4198 } 4199 case <-time.After(5 * time.Second): 4200 t.Fatalf("payment result did not arrive") 4201 } 4202 } 4203 4204 // TestChannelLinkAcceptOverpay tests that if we create an invoice for sender, 4205 // and the sender sends *more* than specified in the invoice, then we'll still 4206 // accept it and settle as normal. 4207 func TestChannelLinkAcceptOverpay(t *testing.T) { 4208 t.Parallel() 4209 4210 // First, we'll create our traditional three hop network. We'll only be 4211 // interacting with and asserting the state of two of the end points 4212 // for this test. 4213 channels, cleanUp, _, err := createClusterChannels( 4214 dcrutil.AtomsPerCoin*3, 4215 dcrutil.AtomsPerCoin*5) 4216 if err != nil { 4217 t.Fatalf("unable to create channel: %v", err) 4218 } 4219 defer cleanUp() 4220 4221 n := newThreeHopNetwork(t, channels.aliceToBob, channels.bobToAlice, 4222 channels.bobToCarol, channels.carolToBob, testStartingHeight) 4223 if err := n.start(); err != nil { 4224 t.Fatalf("unable to start three hop network: %v", err) 4225 } 4226 defer n.stop() 4227 4228 carolBandwidthBefore := n.carolChannelLink.Bandwidth() 4229 firstBobBandwidthBefore := n.firstBobChannelLink.Bandwidth() 4230 secondBobBandwidthBefore := n.secondBobChannelLink.Bandwidth() 4231 aliceBandwidthBefore := n.aliceChannelLink.Bandwidth() 4232 4233 // We'll request a route to send 10k atoms via Alice -> Bob -> 4234 // Carol. 4235 amount := lnwire.NewMAtomsFromAtoms(dcrutil.AtomsPerCoin) 4236 htlcAmt, totalTimelock, hops := generateHops( 4237 amount, testStartingHeight, 4238 n.firstBobChannelLink, n.carolChannelLink, 4239 ) 4240 4241 // When we actually go to send the payment, we'll actually create an 4242 // invoice at Carol for only half of this amount. 4243 receiver := n.carolServer 4244 firstHop := n.firstBobChannelLink.ShortChanID() 4245 rhash, err := makePayment( 4246 n.aliceServer, n.carolServer, firstHop, hops, amount/2, htlcAmt, 4247 totalTimelock, 4248 ).Wait(30 * time.Second) 4249 if err != nil { 4250 t.Fatalf("unable to send payment: %v", err) 4251 } 4252 4253 // Wait for Alice and Bob's second link to receive the revocation. 4254 time.Sleep(2 * time.Second) 4255 4256 // Even though we sent 2x what was asked for, Carol should still have 4257 // accepted the payment and marked it as settled. 4258 invoice, err := receiver.registry.LookupInvoice(rhash) 4259 if err != nil { 4260 t.Fatalf("unable to get invoice: %v", err) 4261 } 4262 if invoice.State != channeldb.ContractSettled { 4263 t.Fatal("carol invoice haven't been settled") 4264 } 4265 4266 expectedAliceBandwidth := aliceBandwidthBefore - htlcAmt 4267 if expectedAliceBandwidth != n.aliceChannelLink.Bandwidth() { 4268 t.Fatalf("channel bandwidth incorrect: expected %v, got %v", 4269 expectedAliceBandwidth, n.aliceChannelLink.Bandwidth()) 4270 } 4271 4272 expectedBobBandwidth1 := firstBobBandwidthBefore + htlcAmt 4273 if expectedBobBandwidth1 != n.firstBobChannelLink.Bandwidth() { 4274 t.Fatalf("channel bandwidth incorrect: expected %v, got %v", 4275 expectedBobBandwidth1, n.firstBobChannelLink.Bandwidth()) 4276 } 4277 4278 expectedBobBandwidth2 := secondBobBandwidthBefore - amount 4279 if expectedBobBandwidth2 != n.secondBobChannelLink.Bandwidth() { 4280 t.Fatalf("channel bandwidth incorrect: expected %v, got %v", 4281 expectedBobBandwidth2, n.secondBobChannelLink.Bandwidth()) 4282 } 4283 4284 expectedCarolBandwidth := carolBandwidthBefore + amount 4285 if expectedCarolBandwidth != n.carolChannelLink.Bandwidth() { 4286 t.Fatalf("channel bandwidth incorrect: expected %v, got %v", 4287 expectedCarolBandwidth, n.carolChannelLink.Bandwidth()) 4288 } 4289 4290 // Finally, we'll ensure that the amount we paid is properly reflected 4291 // in the stored invoice. 4292 if invoice.AmtPaid != amount { 4293 t.Fatalf("expected amt paid to be %v, is instead %v", amount, 4294 invoice.AmtPaid) 4295 } 4296 } 4297 4298 // persistentLinkHarness is used to control the lifecylce of a link and the 4299 // switch that operates it. It supports the ability to restart either the link 4300 // or both the link and the switch. 4301 type persistentLinkHarness struct { 4302 t *testing.T 4303 4304 link ChannelLink 4305 coreLink *channelLink 4306 channel *lnwallet.LightningChannel 4307 4308 batchTicker chan time.Time 4309 msgs chan lnwire.Message 4310 4311 restoreChan func() (*lnwallet.LightningChannel, error) 4312 } 4313 4314 // newPersistentLinkHarness initializes a new persistentLinkHarness and derives 4315 // the supporting references from the active link. 4316 func newPersistentLinkHarness(t *testing.T, link ChannelLink, 4317 batchTicker chan time.Time, 4318 restore func() (*lnwallet.LightningChannel, 4319 error)) *persistentLinkHarness { 4320 4321 coreLink := link.(*channelLink) 4322 4323 return &persistentLinkHarness{ 4324 t: t, 4325 link: link, 4326 coreLink: coreLink, 4327 channel: coreLink.channel, 4328 batchTicker: batchTicker, 4329 msgs: coreLink.cfg.Peer.(*mockPeer).sentMsgs, 4330 restoreChan: restore, 4331 } 4332 } 4333 4334 // restart facilitates a shutdown and restart of the link maintained by the 4335 // harness. The primary purpose of this method is to ensure the consistency of 4336 // the supporting references is maintained across restarts. 4337 // 4338 // If `restartSwitch` is set, the entire switch will also be restarted, 4339 // and will be reinitialized with the contents of the channeldb backing Alice's 4340 // channel. 4341 // 4342 // Any number of hodl flags can be passed as additional arguments to this 4343 // method. If none are provided, the mask will be extracted as hodl.MaskNone. 4344 func (h *persistentLinkHarness) restart(restartSwitch, syncStates bool, 4345 hodlFlags ...hodl.Flag) func() { 4346 4347 // First, remove the link from the switch. 4348 h.coreLink.cfg.Switch.RemoveLink(h.link.ChanID()) 4349 4350 if restartSwitch { 4351 // If a switch restart is requested, we will stop it. It will be 4352 // reinstantiated in restartLink. 4353 h.coreLink.cfg.Switch.Stop() 4354 } 4355 4356 // Since our in-memory state may have diverged from our persistent 4357 // state, we will restore the persisted state to ensure we always start 4358 // the link in a consistent state. 4359 var err error 4360 h.channel, err = h.restoreChan() 4361 if err != nil { 4362 h.t.Fatalf("unable to restore channels: %v", err) 4363 } 4364 4365 // Now, restart the link using the channel state. This will take care of 4366 // adding the link to an existing switch, or creating a new one using 4367 // the database owned by the link. 4368 var cleanUp func() 4369 h.link, h.batchTicker, cleanUp, err = h.restartLink( 4370 h.channel, restartSwitch, syncStates, hodlFlags, 4371 ) 4372 if err != nil { 4373 h.t.Fatalf("unable to restart alicelink: %v", err) 4374 } 4375 4376 // Repopulate the remaining fields in the harness. 4377 h.coreLink = h.link.(*channelLink) 4378 h.msgs = h.coreLink.cfg.Peer.(*mockPeer).sentMsgs 4379 4380 return cleanUp 4381 } 4382 4383 // checkSent reads the links message stream and verify that the messages are 4384 // dequeued in the same order as provided by `pkts`. 4385 func (h *persistentLinkHarness) checkSent(pkts []*htlcPacket) { 4386 for _, pkt := range pkts { 4387 var msg lnwire.Message 4388 select { 4389 case msg = <-h.msgs: 4390 case <-time.After(15 * time.Second): 4391 h.t.Fatalf("did not receive message") 4392 } 4393 4394 if !reflect.DeepEqual(msg, pkt.htlc) { 4395 h.t.Fatalf("unexpected packet, want %v, got %v", 4396 pkt.htlc, msg) 4397 } 4398 } 4399 } 4400 4401 // commitCircuits accepts a list of circuits and tries to commit them to the 4402 // switch's circuit map. The forwarding actions are returned if there was no 4403 // failure. 4404 func (h *persistentLinkHarness) commitCircuits(circuits []*PaymentCircuit) *CircuitFwdActions { 4405 fwdActions, err := h.coreLink.cfg.Switch.commitCircuits(circuits...) 4406 if err != nil { 4407 h.t.Fatalf("unable to commit circuit: %v", err) 4408 } 4409 4410 return fwdActions 4411 } 4412 4413 func (h *persistentLinkHarness) assertNumPendingNumOpenCircuits( 4414 wantPending, wantOpen int) { 4415 4416 _, _, line, _ := runtime.Caller(1) 4417 4418 numPending := h.coreLink.cfg.Switch.circuits.NumPending() 4419 if numPending != wantPending { 4420 h.t.Fatalf("line: %d: wrong number of pending circuits: "+ 4421 "want %d, got %d", line, wantPending, numPending) 4422 } 4423 numOpen := h.coreLink.cfg.Switch.circuits.NumOpen() 4424 if numOpen != wantOpen { 4425 h.t.Fatalf("line: %d: wrong number of open circuits: "+ 4426 "want %d, got %d", line, wantOpen, numOpen) 4427 } 4428 } 4429 4430 // trySignNextCommitment signals the batch ticker so that the link will try to 4431 // update its commitment transaction. 4432 func (h *persistentLinkHarness) trySignNextCommitment() { 4433 select { 4434 case h.batchTicker <- time.Now(): 4435 // Give the link enough time to process the request. 4436 time.Sleep(time.Millisecond * 500) 4437 4438 case <-time.After(15 * time.Second): 4439 h.t.Fatalf("did not initiate state transition") 4440 } 4441 } 4442 4443 // restartLink creates a new channel link from the given channel state, and adds 4444 // to an htlcswitch. If none is provided by the caller, a new one will be 4445 // created using Alice's database. 4446 func (h *persistentLinkHarness) restartLink( 4447 aliceChannel *lnwallet.LightningChannel, restartSwitch, syncStates bool, 4448 hodlFlags []hodl.Flag) ( 4449 ChannelLink, chan time.Time, func(), error) { 4450 4451 var ( 4452 decoder = newMockIteratorDecoder() 4453 obfuscator = NewMockObfuscator() 4454 alicePeer = &mockPeer{ 4455 sentMsgs: make(chan lnwire.Message, 2000), 4456 quit: make(chan struct{}), 4457 } 4458 4459 globalPolicy = ForwardingPolicy{ 4460 MinHTLCOut: lnwire.NewMAtomsFromAtoms(5), 4461 BaseFee: lnwire.NewMAtomsFromAtoms(1), 4462 TimeLockDelta: 6, 4463 } 4464 4465 pCache = newMockPreimageCache() 4466 ) 4467 4468 aliceDb := aliceChannel.State().Db.GetParentDB() 4469 aliceSwitch := h.coreLink.cfg.Switch 4470 if restartSwitch { 4471 var err error 4472 aliceSwitch, err = initSwitchWithDB(testStartingHeight, aliceDb) 4473 if err != nil { 4474 return nil, nil, nil, err 4475 } 4476 } 4477 4478 // Instantiate with a long interval, so that we can precisely control 4479 // the firing via force feeding. 4480 bticker := ticker.NewForce(time.Hour) 4481 aliceCfg := ChannelLinkConfig{ 4482 FwrdingPolicy: globalPolicy, 4483 Peer: alicePeer, 4484 Switch: aliceSwitch, 4485 BestHeight: aliceSwitch.BestHeight, 4486 Circuits: aliceSwitch.CircuitModifier(), 4487 ForwardPackets: aliceSwitch.ForwardPackets, 4488 DecodeHopIterators: decoder.DecodeHopIterators, 4489 ExtractErrorEncrypter: func(*secp256k1.PublicKey) ( 4490 hop.ErrorEncrypter, lnwire.FailCode) { 4491 return obfuscator, lnwire.CodeNone 4492 }, 4493 FetchLastChannelUpdate: mockGetChanUpdateMessage, 4494 PreimageCache: pCache, 4495 OnChannelFailure: func(lnwire.ChannelID, 4496 lnwire.ShortChannelID, LinkFailureError) { 4497 }, 4498 UpdateContractSignals: func(*contractcourt.ContractSignals) error { 4499 return nil 4500 }, 4501 Registry: h.coreLink.cfg.Registry, 4502 FeeEstimator: newMockFeeEstimator(), 4503 ChainEvents: &contractcourt.ChainEventSubscription{}, 4504 BatchTicker: bticker, 4505 FwdPkgGCTicker: ticker.New(5 * time.Second), 4506 PendingCommitTicker: ticker.New(time.Minute), 4507 // Make the BatchSize and Min/MaxFeeUpdateTimeout large enough 4508 // to not trigger commit updates automatically during tests. 4509 BatchSize: 10000, 4510 MinFeeUpdateTimeout: 30 * time.Minute, 4511 MaxFeeUpdateTimeout: 40 * time.Minute, 4512 // Set any hodl flags requested for the new link. 4513 HodlMask: hodl.MaskFromFlags(hodlFlags...), 4514 MaxOutgoingCltvExpiry: DefaultMaxOutgoingCltvExpiry, 4515 MaxFeeAllocation: DefaultMaxLinkFeeAllocation, 4516 NotifyActiveLink: func(wire.OutPoint) {}, 4517 NotifyActiveChannel: func(wire.OutPoint) {}, 4518 NotifyInactiveChannel: func(wire.OutPoint) {}, 4519 HtlcNotifier: aliceSwitch.cfg.HtlcNotifier, 4520 SyncStates: syncStates, 4521 4522 ResetChanReestablishWaitTime: aliceDb.ChannelStateDB().ResetChanReestablishWaitTime, 4523 AddToChanReestablishWaitTime: aliceDb.ChannelStateDB().AddToChanReestablishWaitTime, 4524 } 4525 4526 aliceLink := NewChannelLink(aliceCfg, aliceChannel) 4527 if err := aliceSwitch.AddLink(aliceLink); err != nil { 4528 return nil, nil, nil, err 4529 } 4530 go func() { 4531 for { 4532 select { 4533 case <-aliceLink.(*channelLink).htlcUpdates: 4534 case <-aliceLink.(*channelLink).quit: 4535 return 4536 } 4537 } 4538 }() 4539 4540 cleanUp := func() { 4541 close(alicePeer.quit) 4542 defer aliceLink.Stop() 4543 } 4544 4545 return aliceLink, bticker.Force, cleanUp, nil 4546 } 4547 4548 // gnerateHtlc generates a simple payment from Bob to Alice. 4549 func generateHtlc(t *testing.T, coreLink *channelLink, 4550 id uint64) *lnwire.UpdateAddHTLC { 4551 4552 t.Helper() 4553 4554 htlc, invoice := generateHtlcAndInvoice(t, id) 4555 4556 // We must add the invoice to the registry, such that Alice 4557 // expects this payment. 4558 err := coreLink.cfg.Registry.(*mockInvoiceRegistry).AddInvoice( 4559 *invoice, htlc.PaymentHash, 4560 ) 4561 if err != nil { 4562 t.Fatalf("unable to add invoice to registry: %v", err) 4563 } 4564 4565 return htlc 4566 } 4567 4568 // generateHtlcAndInvoice generates an invoice and a single hop htlc to send to 4569 // the receiver. 4570 func generateHtlcAndInvoice(t *testing.T, 4571 id uint64) (*lnwire.UpdateAddHTLC, *channeldb.Invoice) { 4572 4573 t.Helper() 4574 4575 htlcAmt := lnwire.NewMAtomsFromAtoms(20000) 4576 htlcExpiry := testStartingHeight + testInvoiceCltvExpiry 4577 hops := []*hop.Payload{ 4578 hop.NewLegacyPayload(&sphinx.HopData{ 4579 Realm: [1]byte{2}, // hop.DecredNetwork 4580 NextAddress: [8]byte{}, // hop.Exit, 4581 ForwardAmount: uint64(htlcAmt), 4582 OutgoingCltv: uint32(htlcExpiry), 4583 }), 4584 } 4585 blob, err := generateRoute(hops...) 4586 if err != nil { 4587 t.Fatalf("unable to generate route: %v", err) 4588 } 4589 4590 invoice, htlc, _, err := generatePayment( 4591 htlcAmt, htlcAmt, uint32(htlcExpiry), blob, 4592 ) 4593 if err != nil { 4594 t.Fatalf("unable to create payment: %v", err) 4595 } 4596 4597 htlc.ID = id 4598 4599 return htlc, invoice 4600 } 4601 4602 // TestChannelLinkNoMoreUpdates tests that we won't send a new commitment when 4603 // there are no new updates to sign. 4604 func TestChannelLinkNoMoreUpdates(t *testing.T) { 4605 t.Parallel() 4606 4607 const chanAmt = dcrutil.AtomsPerCoin * 5 4608 const chanReserve = dcrutil.AtomsPerCoin * 1 4609 aliceLink, bobChannel, _, start, cleanUp, _, err := 4610 newSingleLinkTestHarness(chanAmt, chanReserve) 4611 if err != nil { 4612 t.Fatalf("unable to create link: %v", err) 4613 } 4614 defer cleanUp() 4615 4616 if err := start(); err != nil { 4617 t.Fatalf("unable to start test harness: %v", err) 4618 } 4619 4620 var ( 4621 coreLink = aliceLink.(*channelLink) 4622 aliceMsgs = coreLink.cfg.Peer.(*mockPeer).sentMsgs 4623 ) 4624 4625 // Add two HTLCs to Alice's registry, that Bob can pay. 4626 htlc1 := generateHtlc(t, coreLink, 0) 4627 htlc2 := generateHtlc(t, coreLink, 1) 4628 4629 ctx := linkTestContext{ 4630 t: t, 4631 aliceLink: aliceLink, 4632 aliceMsgs: aliceMsgs, 4633 bobChannel: bobChannel, 4634 } 4635 4636 // We now play out the following scanario: 4637 // 4638 // (1) Alice receives htlc1 from Bob. 4639 // (2) Bob sends signature covering htlc1. 4640 // (3) Alice receives htlc2 from Bob. 4641 // (4) Since Bob has sent a new commitment signature, Alice should 4642 // first respond with a revocation. 4643 // (5) Alice should also send a commitment signature for the new state, 4644 // covering htlc1. 4645 // (6) Bob sends a new commitment signature, covering htlc2 that he sent 4646 // earlier. This signature should cover hltc1 + htlc2. 4647 // (7) Alice should revoke the old commitment. This ACKs htlc2. 4648 // (8) Bob can now revoke his old commitment in response to the 4649 // signature Alice sent covering htlc1. 4650 // (9) htlc1 is now locked in on Bob's commitment, and we expect Alice 4651 // to settle it. 4652 // (10) Alice should send a signature covering this settle to Bob. Only 4653 // htlc2 should now be covered by this signature. 4654 // (11) Bob can revoke his last state, which will also ACK the settle 4655 // of htlc1. 4656 // (12) Bob sends a new commitment signature. This signature should 4657 // cover htlc2. 4658 // (13) Alice will send a settle for htlc2. 4659 // (14) Alice will also send a signature covering the settle. 4660 // (15) Alice should send a revocation in response to the signature Bob 4661 // sent earlier. 4662 // (16) Bob will revoke his commitment in response to the commitment 4663 // Alice sent. 4664 // (17) Send a signature for the empty state. No HTLCs are left. 4665 // (18) Alice will revoke her previous state. 4666 // Alice Bob 4667 // | | 4668 // | ... | 4669 // | | <--- idle (no htlc on either side) 4670 // | | 4671 ctx.sendHtlcBobToAlice(htlc1) // |<----- add-1 ------| (1) 4672 ctx.sendCommitSigBobToAlice(1) // |<------ sig -------| (2) 4673 ctx.sendHtlcBobToAlice(htlc2) // |<----- add-2 ------| (3) 4674 ctx.receiveRevAndAckAliceToBob() // |------- rev ------>| (4) <--- Alice acks add-1 4675 ctx.receiveCommitSigAliceToBob(1) // |------- sig ------>| (5) <--- Alice signs add-1 4676 ctx.sendCommitSigBobToAlice(2) // |<------ sig -------| (6) 4677 ctx.receiveRevAndAckAliceToBob() // |------- rev ------>| (7) <--- Alice acks add-2 4678 ctx.sendRevAndAckBobToAlice() // |<------ rev -------| (8) 4679 ctx.receiveSettleAliceToBob() // |------ ful-1 ----->| (9) 4680 ctx.receiveCommitSigAliceToBob(1) // |------- sig ------>| (10) <--- Alice signs add-1 + add-2 + ful-1 = add-2 4681 ctx.sendRevAndAckBobToAlice() // |<------ rev -------| (11) 4682 ctx.sendCommitSigBobToAlice(1) // |<------ sig -------| (12) 4683 ctx.receiveSettleAliceToBob() // |------ ful-2 ----->| (13) 4684 ctx.receiveCommitSigAliceToBob(0) // |------- sig ------>| (14) <--- Alice signs add-2 + ful-2 = no htlcs 4685 ctx.receiveRevAndAckAliceToBob() // |------- rev ------>| (15) 4686 ctx.sendRevAndAckBobToAlice() // |<------ rev -------| (16) <--- Bob acks that there are no more htlcs 4687 ctx.sendCommitSigBobToAlice(0) // |<------ sig -------| (17) 4688 ctx.receiveRevAndAckAliceToBob() // |------- rev ------>| (18) <--- Alice acks that there are no htlcs on Alice's side 4689 4690 // No there are no more changes to ACK or sign, make sure Alice doesn't 4691 // attempt to send any more messages. 4692 var msg lnwire.Message 4693 select { 4694 case msg = <-aliceMsgs: 4695 t.Fatalf("did not expect message %T", msg) 4696 case <-time.After(100 * time.Millisecond): 4697 } 4698 } 4699 4700 // checkHasPreimages inspects Alice's preimage cache, and asserts whether the 4701 // preimages for the provided HTLCs are known and unknown, and that all of them 4702 // match the expected status of expOk. 4703 func checkHasPreimages(t *testing.T, coreLink *channelLink, 4704 htlcs []*lnwire.UpdateAddHTLC, expOk bool) { 4705 4706 t.Helper() 4707 4708 err := wait.NoError(func() error { 4709 for i := range htlcs { 4710 _, ok := coreLink.cfg.PreimageCache.LookupPreimage( 4711 htlcs[i].PaymentHash, 4712 ) 4713 if ok == expOk { 4714 continue 4715 } 4716 4717 return fmt.Errorf("expected to find witness: %v, "+ 4718 "got %v for hash=%x", expOk, ok, 4719 htlcs[i].PaymentHash) 4720 } 4721 4722 return nil 4723 }, 5*time.Second) 4724 if err != nil { 4725 t.Fatalf("unable to find preimages: %v", err) 4726 } 4727 } 4728 4729 // TestChannelLinkWaitForRevocation tests that we will keep accepting updates 4730 // to our commitment transaction, even when we are waiting for a revocation 4731 // from the remote node. 4732 func TestChannelLinkWaitForRevocation(t *testing.T) { 4733 t.Parallel() 4734 4735 const chanAmt = dcrutil.AtomsPerCoin * 5 4736 const chanReserve = dcrutil.AtomsPerCoin * 1 4737 aliceLink, bobChannel, _, start, cleanUp, _, err := 4738 newSingleLinkTestHarness(chanAmt, chanReserve) 4739 if err != nil { 4740 t.Fatalf("unable to create link: %v", err) 4741 } 4742 defer cleanUp() 4743 4744 if err := start(); err != nil { 4745 t.Fatalf("unable to start test harness: %v", err) 4746 } 4747 4748 var ( 4749 coreLink = aliceLink.(*channelLink) 4750 aliceMsgs = coreLink.cfg.Peer.(*mockPeer).sentMsgs 4751 ) 4752 4753 // We will send 10 HTLCs in total, from Bob to Alice. 4754 numHtlcs := 10 4755 var htlcs []*lnwire.UpdateAddHTLC 4756 for i := 0; i < numHtlcs; i++ { 4757 htlc := generateHtlc(t, coreLink, uint64(i)) 4758 htlcs = append(htlcs, htlc) 4759 } 4760 4761 ctx := linkTestContext{ 4762 t: t, 4763 aliceLink: aliceLink, 4764 aliceMsgs: aliceMsgs, 4765 bobChannel: bobChannel, 4766 } 4767 4768 assertNoMsgFromAlice := func() { 4769 select { 4770 case <-aliceMsgs: 4771 t.Fatalf("did not expect message from Alice") 4772 case <-time.After(50 * time.Millisecond): 4773 } 4774 } 4775 4776 // We play out the following scenario: 4777 // 4778 // (1) Add the first HTLC. 4779 // (2) Bob sends signature covering the htlc. 4780 // (3) Since Bob has sent a new commitment signature, Alice should first 4781 // respond with a revocation. This revocation will ACK the first htlc. 4782 // (4) Alice should also send a commitment signature for the new state, 4783 // locking in the HTLC on Bob's commitment. Note that we don't 4784 // immediately let Bob respond with a revocation in this case. 4785 // (5.i) Now we send the rest of the HTLCs from Bob to Alice. 4786 // (6.i) Bob sends a new commitment signature, covering all HTLCs up 4787 // to this point. 4788 // (7.i) Alice should respond to Bob's state updates with revocations, 4789 // but cannot send any new signatures for Bob's state because her 4790 // revocation window is exhausted. 4791 // (8) Now let Bob finally send his revocation. 4792 // (9) We expect Alice to settle her first HTLC, since it was already 4793 // locked in. 4794 // (10) Now Alice should send a signature covering this settle + lock 4795 // in the rest of the HTLCs on Bob's commitment. 4796 // (11) Bob receives the new signature for his commitment, and can 4797 // revoke his old state, ACKing the settle. 4798 // (12.i) Now Alice can settle all the HTLCs, since they are locked in 4799 // on both parties' commitments. 4800 // (13) Bob can send a signature covering the first settle Alice sent. 4801 // Bob's signature should cover all the remaining HTLCs as well, since 4802 // he hasn't ACKed the last settles yet. Alice receives the signature 4803 // from Bob. Alice's commitment now has the first HTLC settled, and all 4804 // the other HTLCs locked in. 4805 // (14) Alice will send a signature for all the settles she just sent. 4806 // (15) Bob can revoke his previous state, in response to Alice's 4807 // signature. 4808 // (16) In response to the signature Bob sent, Alice can 4809 // revoke her previous state. 4810 // (17) Bob still hasn't sent a commitment covering all settles, so do 4811 // that now. Since Bob ACKed all settles, no HTLCs should be left on 4812 // the commitment. 4813 // (18) Alice will revoke her previous state. 4814 // Alice Bob 4815 // | | 4816 // | ... | 4817 // | | <--- idle (no htlc on either side) 4818 // | | 4819 ctx.sendHtlcBobToAlice(htlcs[0]) // |<----- add-1 ------| (1) 4820 ctx.sendCommitSigBobToAlice(1) // |<------ sig -------| (2) 4821 ctx.receiveRevAndAckAliceToBob() // |------- rev ------>| (3) <--- Alice acks add-1 4822 ctx.receiveCommitSigAliceToBob(1) // |------- sig ------>| (4) <--- Alice signs add-1 4823 for i := 1; i < numHtlcs; i++ { // | | 4824 ctx.sendHtlcBobToAlice(htlcs[i]) // |<----- add-i ------| (5.i) 4825 ctx.sendCommitSigBobToAlice(i + 1) // |<------ sig -------| (6.i) 4826 ctx.receiveRevAndAckAliceToBob() // |------- rev ------>| (7.i) <--- Alice acks add-i 4827 assertNoMsgFromAlice() // | | 4828 // | | Alice should not send a sig for 4829 // | | Bob's last state, since she is 4830 // | | still waiting for a revocation 4831 // | | for the previous one. 4832 } // | | 4833 ctx.sendRevAndAckBobToAlice() // |<------ rev -------| (8) Finally let Bob send rev 4834 ctx.receiveSettleAliceToBob() // |------ ful-1 ----->| (9) 4835 ctx.receiveCommitSigAliceToBob(numHtlcs - 1) // |------- sig ------>| (10) <--- Alice signs add-i 4836 ctx.sendRevAndAckBobToAlice() // |<------ rev -------| (11) 4837 for i := 1; i < numHtlcs; i++ { // | | 4838 ctx.receiveSettleAliceToBob() // |------ ful-1 ----->| (12.i) 4839 } // | | 4840 ctx.sendCommitSigBobToAlice(numHtlcs - 1) // |<------ sig -------| (13) 4841 ctx.receiveCommitSigAliceToBob(0) // |------- sig ------>| (14) 4842 ctx.sendRevAndAckBobToAlice() // |<------ rev -------| (15) 4843 ctx.receiveRevAndAckAliceToBob() // |------- rev ------>| (16) 4844 ctx.sendCommitSigBobToAlice(0) // |<------ sig -------| (17) 4845 ctx.receiveRevAndAckAliceToBob() // |------- rev ------>| (18) 4846 4847 // Both side's state is now updated, no more messages should be sent. 4848 assertNoMsgFromAlice() 4849 } 4850 4851 // TestChannelLinkNoEmptySig asserts that no empty commit sig message is sent 4852 // when the commitment txes are out of sync. 4853 func TestChannelLinkNoEmptySig(t *testing.T) { 4854 t.Parallel() 4855 4856 const chanAmt = dcrutil.AtomsPerCoin * 5 4857 const chanReserve = dcrutil.AtomsPerCoin * 1 4858 aliceLink, bobChannel, batchTicker, start, cleanUp, _, err := 4859 newSingleLinkTestHarness(chanAmt, chanReserve) 4860 if err != nil { 4861 t.Fatalf("unable to create link: %v", err) 4862 } 4863 defer cleanUp() 4864 4865 if err := start(); err != nil { 4866 t.Fatalf("unable to start test harness: %v", err) 4867 } 4868 defer aliceLink.Stop() 4869 4870 var ( 4871 coreLink = aliceLink.(*channelLink) 4872 aliceMsgs = coreLink.cfg.Peer.(*mockPeer).sentMsgs 4873 ) 4874 4875 ctx := linkTestContext{ 4876 t: t, 4877 aliceLink: aliceLink, 4878 aliceMsgs: aliceMsgs, 4879 bobChannel: bobChannel, 4880 } 4881 4882 // Send htlc 1 from Alice to Bob. 4883 htlc1, _ := generateHtlcAndInvoice(t, 0) 4884 ctx.sendHtlcAliceToBob(0, htlc1) 4885 ctx.receiveHtlcAliceToBob() 4886 4887 // Tick the batch ticker to trigger a commitsig from Alice->Bob. 4888 select { 4889 case batchTicker <- time.Now(): 4890 case <-time.After(5 * time.Second): 4891 t.Fatalf("could not force commit sig") 4892 } 4893 4894 // Receive a CommitSig from Alice covering the Add from above. 4895 ctx.receiveCommitSigAliceToBob(1) 4896 4897 // Bob revokes previous commitment tx. 4898 ctx.sendRevAndAckBobToAlice() 4899 4900 // Alice sends htlc 2 to Bob. 4901 htlc2, _ := generateHtlcAndInvoice(t, 0) 4902 ctx.sendHtlcAliceToBob(1, htlc2) 4903 ctx.receiveHtlcAliceToBob() 4904 4905 // Tick the batch ticker to trigger a commitsig from Alice->Bob. 4906 select { 4907 case batchTicker <- time.Now(): 4908 case <-time.After(5 * time.Second): 4909 t.Fatalf("could not force commit sig") 4910 } 4911 4912 // Get the commit sig from Alice, but don't send it to Bob yet. 4913 commitSigAlice := ctx.receiveCommitSigAlice(2) 4914 4915 // Bob adds htlc 1 to its remote commit tx. 4916 ctx.sendCommitSigBobToAlice(1) 4917 4918 // Now send Bob the signature from Alice covering both htlcs. 4919 err = bobChannel.ReceiveNewCommitment( 4920 commitSigAlice.CommitSig, commitSigAlice.HtlcSigs, 4921 ) 4922 if err != nil { 4923 t.Fatalf("bob failed receiving commitment: %v", err) 4924 } 4925 4926 // Both Alice and Bob revoke their previous commitment txes. 4927 ctx.receiveRevAndAckAliceToBob() 4928 ctx.sendRevAndAckBobToAlice() 4929 4930 // The commit txes are not in sync, but it is Bob's turn to send a new 4931 // signature. We don't expect Alice to send out any message. This check 4932 // allows some time for the log commit ticker to trigger for Alice. 4933 ctx.assertNoMsgFromAlice(time.Second) 4934 } 4935 4936 // TestChannelLinkBatchPreimageWrite asserts that a link will batch preimage 4937 // writes when just as it receives a CommitSig to lock in any Settles, and also 4938 // if the link is aware of any uncommitted preimages if the link is stopped, 4939 // i.e. due to a disconnection or shutdown. 4940 func TestChannelLinkBatchPreimageWrite(t *testing.T) { 4941 t.Parallel() 4942 4943 tests := []struct { 4944 name string 4945 disconnect bool 4946 }{ 4947 { 4948 name: "flush on commit sig", 4949 disconnect: false, 4950 }, 4951 { 4952 name: "flush on disconnect", 4953 disconnect: true, 4954 }, 4955 } 4956 4957 for _, test := range tests { 4958 t.Run(test.name, func(t *testing.T) { 4959 testChannelLinkBatchPreimageWrite(t, test.disconnect) 4960 }) 4961 } 4962 } 4963 4964 func testChannelLinkBatchPreimageWrite(t *testing.T, disconnect bool) { 4965 const chanAmt = dcrutil.AtomsPerCoin * 5 4966 const chanReserve = dcrutil.AtomsPerCoin * 1 4967 aliceLink, bobChannel, batchTicker, startUp, cleanUp, _, err := 4968 newSingleLinkTestHarness(chanAmt, chanReserve) 4969 if err != nil { 4970 t.Fatalf("unable to create link: %v", err) 4971 } 4972 defer cleanUp() 4973 4974 if err := startUp(); err != nil { 4975 t.Fatalf("unable to start test harness: %v", err) 4976 } 4977 4978 var ( 4979 coreLink = aliceLink.(*channelLink) 4980 aliceMsgs = coreLink.cfg.Peer.(*mockPeer).sentMsgs 4981 ) 4982 4983 // We will send 10 HTLCs in total, from Bob to Alice. 4984 numHtlcs := 10 4985 var htlcs []*lnwire.UpdateAddHTLC 4986 var invoices []*channeldb.Invoice 4987 for i := 0; i < numHtlcs; i++ { 4988 htlc, invoice := generateHtlcAndInvoice(t, uint64(i)) 4989 htlcs = append(htlcs, htlc) 4990 invoices = append(invoices, invoice) 4991 } 4992 4993 ctx := linkTestContext{ 4994 t: t, 4995 aliceLink: aliceLink, 4996 aliceMsgs: aliceMsgs, 4997 bobChannel: bobChannel, 4998 } 4999 5000 // First, send a batch of Adds from Alice to Bob. 5001 for i, htlc := range htlcs { 5002 ctx.sendHtlcAliceToBob(i, htlc) 5003 ctx.receiveHtlcAliceToBob() 5004 } 5005 5006 // Assert that no preimages exist for these htlcs in Alice's cache. 5007 checkHasPreimages(t, coreLink, htlcs, false) 5008 5009 // Force alice's link to sign a commitment covering the htlcs sent thus 5010 // far. 5011 select { 5012 case batchTicker <- time.Now(): 5013 case <-time.After(15 * time.Second): 5014 t.Fatalf("could not force commit sig") 5015 } 5016 5017 // Do a commitment dance to lock in the Adds, we expect numHtlcs htlcs 5018 // to be on each party's commitment transactions. 5019 ctx.receiveCommitSigAliceToBob(numHtlcs) 5020 ctx.sendRevAndAckBobToAlice() 5021 ctx.sendCommitSigBobToAlice(numHtlcs) 5022 ctx.receiveRevAndAckAliceToBob() 5023 5024 // Check again that no preimages exist for these htlcs in Alice's cache. 5025 checkHasPreimages(t, coreLink, htlcs, false) 5026 5027 // Now, have Bob settle the HTLCs back to Alice using the preimages in 5028 // the invoice corresponding to each of the HTLCs. 5029 for i, invoice := range invoices { 5030 ctx.sendSettleBobToAlice( 5031 uint64(i), 5032 *invoice.Terms.PaymentPreimage, 5033 ) 5034 } 5035 5036 // Assert that Alice has not yet written the preimages, even though she 5037 // has received them in the UpdateFulfillHTLC messages. 5038 checkHasPreimages(t, coreLink, htlcs, false) 5039 5040 // If this is the disconnect run, we will having Bob send Alice his 5041 // CommitSig, and simply stop Alice's link. As she exits, we should 5042 // detect that she has uncommitted preimages and write them to disk. 5043 if disconnect { 5044 aliceLink.Stop() 5045 checkHasPreimages(t, coreLink, htlcs, true) 5046 return 5047 } 5048 5049 // Otherwise, we are testing that Alice commits the preimages after 5050 // receiving a CommitSig from Bob. Bob's commitment should now have 0 5051 // HTLCs. 5052 ctx.sendCommitSigBobToAlice(0) 5053 5054 // Since Alice will process the CommitSig asynchronously, we wait until 5055 // she replies with her RevokeAndAck to ensure the tests reliably 5056 // inspect her cache after advancing her state. 5057 select { 5058 5059 // Received Alice's RevokeAndAck, assert that she has written all of the 5060 // uncommitted preimages learned in this commitment. 5061 case <-aliceMsgs: 5062 checkHasPreimages(t, coreLink, htlcs, true) 5063 5064 // Alice didn't send her RevokeAndAck, something is wrong. 5065 case <-time.After(15 * time.Second): 5066 t.Fatalf("alice did not send her revocation") 5067 } 5068 } 5069 5070 // TestChannelLinkCleanupSpuriousResponses tests that we properly cleanup 5071 // references in the event that internal retransmission continues as a result of 5072 // not properly cleaning up Add/SettleFailRefs. 5073 func TestChannelLinkCleanupSpuriousResponses(t *testing.T) { 5074 t.Parallel() 5075 5076 const chanAmt = dcrutil.AtomsPerCoin * 5 5077 const chanReserve = dcrutil.AtomsPerCoin * 1 5078 aliceLink, bobChannel, _, start, cleanUp, _, err := 5079 newSingleLinkTestHarness(chanAmt, chanReserve) 5080 if err != nil { 5081 t.Fatalf("unable to create link: %v", err) 5082 } 5083 defer cleanUp() 5084 5085 if err := start(); err != nil { 5086 t.Fatalf("unable to start test harness: %v", err) 5087 } 5088 5089 var ( 5090 coreLink = aliceLink.(*channelLink) 5091 aliceMsgs = coreLink.cfg.Peer.(*mockPeer).sentMsgs 5092 ) 5093 5094 // Settle Alice in hodl ExitSettle mode so that she won't respond 5095 // immediately to the htlc's meant for her. This allows us to control 5096 // the responses she gives back to Bob. 5097 coreLink.cfg.HodlMask = hodl.ExitSettle.Mask() 5098 5099 // Add two HTLCs to Alice's registry, that Bob can pay. 5100 htlc1 := generateHtlc(t, coreLink, 0) 5101 htlc2 := generateHtlc(t, coreLink, 1) 5102 5103 ctx := linkTestContext{ 5104 t: t, 5105 aliceLink: aliceLink, 5106 aliceMsgs: aliceMsgs, 5107 bobChannel: bobChannel, 5108 } 5109 5110 // We start with he following scenario: Bob sends Alice two HTLCs, and a 5111 // commitment dance ensures, leaving two HTLCs that Alice can respond 5112 // to. Since Alice is in ExitSettle mode, we will then take over and 5113 // provide targeted fail messages to test the link's ability to cleanup 5114 // spurious responses. 5115 // 5116 // Bob Alice 5117 // |------ add-1 ----->| 5118 // |------ add-2 ----->| 5119 // |------ sig ----->| commits add-1 + add-2 5120 // |<----- rev ------| 5121 // |<----- sig ------| commits add-1 + add-2 5122 // |------ rev ----->| 5123 ctx.sendHtlcBobToAlice(htlc1) 5124 ctx.sendHtlcBobToAlice(htlc2) 5125 ctx.sendCommitSigBobToAlice(2) 5126 ctx.receiveRevAndAckAliceToBob() 5127 ctx.receiveCommitSigAliceToBob(2) 5128 ctx.sendRevAndAckBobToAlice() 5129 5130 // Give Alice to time to process the revocation. 5131 time.Sleep(time.Second) 5132 5133 aliceFwdPkgs, err := coreLink.channel.LoadFwdPkgs() 5134 if err != nil { 5135 t.Fatalf("unable to load alice's fwdpkgs: %v", err) 5136 } 5137 5138 // Alice should have exactly one forwarding package. 5139 if len(aliceFwdPkgs) != 1 { 5140 t.Fatalf("alice should have 1 fwd pkgs, has %d instead", 5141 len(aliceFwdPkgs)) 5142 } 5143 5144 // We'll stash the height of these AddRefs, so that we can reconstruct 5145 // the proper references later. 5146 addHeight := aliceFwdPkgs[0].Height 5147 5148 // The first fwdpkg should have exactly 2 entries, one for each Add that 5149 // was added during the last dance. 5150 if aliceFwdPkgs[0].AckFilter.Count() != 2 { 5151 t.Fatalf("alice fwdpkg should have 2 Adds, has %d instead", 5152 aliceFwdPkgs[0].AckFilter.Count()) 5153 } 5154 5155 // Both of the entries in the FwdFilter should be unacked. 5156 for i := 0; i < 2; i++ { 5157 if aliceFwdPkgs[0].AckFilter.Contains(uint16(i)) { 5158 t.Fatalf("alice fwdpkg index %d should not "+ 5159 "have ack", i) 5160 } 5161 } 5162 5163 // Now, construct a Fail packet for Bob settling the first HTLC. This 5164 // packet will NOT include a sourceRef, meaning the AddRef on disk will 5165 // not be acked after committing this response. 5166 fail0 := &htlcPacket{ 5167 incomingChanID: bobChannel.ShortChanID(), 5168 incomingHTLCID: 0, 5169 obfuscator: NewMockObfuscator(), 5170 htlc: &lnwire.UpdateFailHTLC{}, 5171 } 5172 _ = aliceLink.handleSwitchPacket(fail0) 5173 5174 // Bob Alice 5175 // |<----- fal-1 ------| 5176 // |<----- sig ------| commits fal-1 5177 ctx.receiveFailAliceToBob() 5178 ctx.receiveCommitSigAliceToBob(1) 5179 5180 aliceFwdPkgs, err = coreLink.channel.LoadFwdPkgs() 5181 if err != nil { 5182 t.Fatalf("unable to load alice's fwdpkgs: %v", err) 5183 } 5184 5185 // Alice should still only have one fwdpkg, as she hasn't yet received 5186 // another revocation from Bob. 5187 if len(aliceFwdPkgs) != 1 { 5188 t.Fatalf("alice should have 1 fwd pkgs, has %d instead", 5189 len(aliceFwdPkgs)) 5190 } 5191 5192 // Assert the fwdpkg still has 2 entries for the original Adds. 5193 if aliceFwdPkgs[0].AckFilter.Count() != 2 { 5194 t.Fatalf("alice fwdpkg should have 2 Adds, has %d instead", 5195 aliceFwdPkgs[0].AckFilter.Count()) 5196 } 5197 5198 // Since the fail packet was missing the AddRef, the forward filter for 5199 // either HTLC should not have been modified. 5200 for i := 0; i < 2; i++ { 5201 if aliceFwdPkgs[0].AckFilter.Contains(uint16(i)) { 5202 t.Fatalf("alice fwdpkg index %d should not "+ 5203 "have ack", i) 5204 } 5205 } 5206 5207 // Complete the rest of the commitment dance, now that the forwarding 5208 // packages have been verified. 5209 // 5210 // Bob Alice 5211 // |------ rev ----->| 5212 // |------ sig ----->| 5213 // |<----- rev ------| 5214 ctx.sendRevAndAckBobToAlice() 5215 ctx.sendCommitSigBobToAlice(1) 5216 ctx.receiveRevAndAckAliceToBob() 5217 5218 // Next, we'll construct a fail packet for add-2 (index 1), which we'll 5219 // send to Bob and lock in. Since the AddRef is set on this instance, we 5220 // should see the second HTLCs AddRef update the forward filter for the 5221 // first fwd pkg. 5222 fail1 := &htlcPacket{ 5223 sourceRef: &channeldb.AddRef{ 5224 Height: addHeight, 5225 Index: 1, 5226 }, 5227 incomingChanID: bobChannel.ShortChanID(), 5228 incomingHTLCID: 1, 5229 obfuscator: NewMockObfuscator(), 5230 htlc: &lnwire.UpdateFailHTLC{}, 5231 } 5232 _ = aliceLink.handleSwitchPacket(fail1) 5233 5234 // Bob Alice 5235 // |<----- fal-1 ------| 5236 // |<----- sig ------| commits fal-1 5237 ctx.receiveFailAliceToBob() 5238 ctx.receiveCommitSigAliceToBob(0) 5239 5240 aliceFwdPkgs, err = coreLink.channel.LoadFwdPkgs() 5241 if err != nil { 5242 t.Fatalf("unable to load alice's fwdpkgs: %v", err) 5243 } 5244 5245 // Now that another commitment dance has completed, Alice should have 2 5246 // forwarding packages. 5247 if len(aliceFwdPkgs) != 2 { 5248 t.Fatalf("alice should have 2 fwd pkgs, has %d instead", 5249 len(aliceFwdPkgs)) 5250 } 5251 5252 // The most recent package should have no new HTLCs, so it should be 5253 // empty. 5254 if aliceFwdPkgs[1].AckFilter.Count() != 0 { 5255 t.Fatalf("alice fwdpkg height=%d should have 0 Adds, "+ 5256 "has %d instead", aliceFwdPkgs[1].Height, 5257 aliceFwdPkgs[1].AckFilter.Count()) 5258 } 5259 5260 // The index for the first AddRef should still be unacked, as the 5261 // sourceRef was missing on the htlcPacket. 5262 if aliceFwdPkgs[0].AckFilter.Contains(0) { 5263 t.Fatalf("alice fwdpkg height=%d index=0 should not "+ 5264 "have an ack", aliceFwdPkgs[0].Height) 5265 } 5266 5267 // The index for the second AddRef should now be acked, as it was 5268 // properly constructed and committed in Alice's last commit sig. 5269 if !aliceFwdPkgs[0].AckFilter.Contains(1) { 5270 t.Fatalf("alice fwdpkg height=%d index=1 should have "+ 5271 "an ack", aliceFwdPkgs[0].Height) 5272 } 5273 5274 // Complete the rest of the commitment dance. 5275 // 5276 // Bob Alice 5277 // |------ rev ----->| 5278 // |------ sig ----->| 5279 // |<----- rev ------| 5280 ctx.sendRevAndAckBobToAlice() 5281 ctx.sendCommitSigBobToAlice(0) 5282 ctx.receiveRevAndAckAliceToBob() 5283 5284 // We'll do a quick sanity check, and blindly send the same fail packet 5285 // for the first HTLC. Since this HTLC index has already been settled, 5286 // this should trigger an attempt to cleanup the spurious response. 5287 // However, we expect it to result in a NOP since it is still missing 5288 // its sourceRef. 5289 _ = aliceLink.handleSwitchPacket(fail0) 5290 5291 // Allow the link enough time to process and reject the duplicate 5292 // packet, we'll also check that this doesn't trigger Alice to send the 5293 // fail to Bob. 5294 select { 5295 case <-aliceMsgs: 5296 t.Fatalf("message sent for duplicate fail") 5297 case <-time.After(time.Second): 5298 } 5299 5300 aliceFwdPkgs, err = coreLink.channel.LoadFwdPkgs() 5301 if err != nil { 5302 t.Fatalf("unable to load alice's fwdpkgs: %v", err) 5303 } 5304 5305 // Alice should now have 3 forwarding packages, and the latest should be 5306 // empty. 5307 if len(aliceFwdPkgs) != 3 { 5308 t.Fatalf("alice should have 3 fwd pkgs, has %d instead", 5309 len(aliceFwdPkgs)) 5310 } 5311 if aliceFwdPkgs[2].AckFilter.Count() != 0 { 5312 t.Fatalf("alice fwdpkg height=%d should have 0 Adds, "+ 5313 "has %d instead", aliceFwdPkgs[2].Height, 5314 aliceFwdPkgs[2].AckFilter.Count()) 5315 } 5316 5317 // The state of the forwarding packages should be unmodified from the 5318 // prior assertion, since the duplicate Fail for index 0 should have 5319 // been ignored. 5320 if aliceFwdPkgs[0].AckFilter.Contains(0) { 5321 t.Fatalf("alice fwdpkg height=%d index=0 should not "+ 5322 "have an ack", aliceFwdPkgs[0].Height) 5323 } 5324 if !aliceFwdPkgs[0].AckFilter.Contains(1) { 5325 t.Fatalf("alice fwdpkg height=%d index=1 should have "+ 5326 "an ack", aliceFwdPkgs[0].Height) 5327 } 5328 5329 // Finally, construct a new Fail packet for the first HTLC, this time 5330 // with the sourceRef properly constructed. When the link handles this 5331 // duplicate, it should clean up the remaining AddRef state maintained 5332 // in Alice's link, but it should not result in anything being sent to 5333 // Bob. 5334 fail0 = &htlcPacket{ 5335 sourceRef: &channeldb.AddRef{ 5336 Height: addHeight, 5337 Index: 0, 5338 }, 5339 incomingChanID: bobChannel.ShortChanID(), 5340 incomingHTLCID: 0, 5341 obfuscator: NewMockObfuscator(), 5342 htlc: &lnwire.UpdateFailHTLC{}, 5343 } 5344 _ = aliceLink.handleSwitchPacket(fail0) 5345 5346 // Allow the link enough time to process and reject the duplicate 5347 // packet, we'll also check that this doesn't trigger Alice to send the 5348 // fail to Bob. 5349 select { 5350 case <-aliceMsgs: 5351 t.Fatalf("message sent for duplicate fail") 5352 case <-time.After(time.Second): 5353 } 5354 5355 aliceFwdPkgs, err = coreLink.channel.LoadFwdPkgs() 5356 if err != nil { 5357 t.Fatalf("unable to load alice's fwdpkgs: %v", err) 5358 } 5359 5360 // Since no state transitions have been performed for the duplicate 5361 // packets, Alice should still have the same 3 forwarding packages. 5362 if len(aliceFwdPkgs) != 3 { 5363 t.Fatalf("alice should have 3 fwd pkgs, has %d instead", 5364 len(aliceFwdPkgs)) 5365 } 5366 5367 // Assert that all indices in our original forwarded have now been acked 5368 // as a result of our spurious cleanup logic. 5369 for i := 0; i < 2; i++ { 5370 if !aliceFwdPkgs[0].AckFilter.Contains(uint16(i)) { 5371 t.Fatalf("alice fwdpkg height=%d index=%d "+ 5372 "should have ack", aliceFwdPkgs[0].Height, i) 5373 } 5374 } 5375 } 5376 5377 type mockPackager struct { 5378 failLoadFwdPkgs bool 5379 } 5380 5381 func (*mockPackager) AddFwdPkg(tx kvdb.RwTx, fwdPkg *channeldb.FwdPkg) error { 5382 return nil 5383 } 5384 5385 func (*mockPackager) SetFwdFilter(tx kvdb.RwTx, height uint64, 5386 fwdFilter *channeldb.PkgFilter) error { 5387 return nil 5388 } 5389 5390 func (*mockPackager) AckAddHtlcs(tx kvdb.RwTx, 5391 addRefs ...channeldb.AddRef) error { 5392 return nil 5393 } 5394 5395 func (m *mockPackager) LoadFwdPkgs(tx kvdb.RTx) ([]*channeldb.FwdPkg, error) { 5396 if m.failLoadFwdPkgs { 5397 return nil, fmt.Errorf("failing LoadFwdPkgs") 5398 } 5399 return nil, nil 5400 } 5401 5402 func (*mockPackager) RemovePkg(tx kvdb.RwTx, height uint64) error { 5403 return nil 5404 } 5405 5406 func (*mockPackager) Wipe(tx kvdb.RwTx) error { 5407 return nil 5408 } 5409 5410 func (*mockPackager) AckSettleFails(tx kvdb.RwTx, 5411 settleFailRefs ...channeldb.SettleFailRef) error { 5412 return nil 5413 } 5414 5415 // TestChannelLinkFail tests that we will fail the channel, and force close the 5416 // channel in certain situations. 5417 func TestChannelLinkFail(t *testing.T) { 5418 t.Parallel() 5419 5420 testCases := []struct { 5421 // options is used to set up mocks and configure the link 5422 // before it is started. 5423 options func(*channelLink) 5424 5425 // link test is used to execute the given test on the channel 5426 // link after it is started. 5427 linkTest func(*testing.T, *channelLink, *lnwallet.LightningChannel) 5428 5429 // shouldForceClose indicates whether we expect the link to 5430 // force close the channel in response to the actions performed 5431 // during the linkTest. 5432 shouldForceClose bool 5433 5434 // permanentFailure indicates whether we expect the link to 5435 // consider the failure permanent in response to the actions 5436 // performed during the linkTest. 5437 permanentFailure bool 5438 }{ 5439 { 5440 // Test that we don't force close if syncing states 5441 // fails at startup. 5442 func(c *channelLink) { 5443 c.cfg.SyncStates = true 5444 5445 // Make the syncChanStateCall fail by making 5446 // the SendMessage call fail. 5447 c.cfg.Peer.(*mockPeer).disconnected = true 5448 }, 5449 func(t *testing.T, c *channelLink, _ *lnwallet.LightningChannel) { 5450 // Should fail at startup. 5451 }, 5452 false, 5453 false, 5454 }, 5455 { 5456 // Test that we don't force closes the channel if 5457 // resolving forward packages fails at startup. 5458 func(c *channelLink) { 5459 // We make the call to resolveFwdPkgs fail by 5460 // making the underlying forwarder fail. 5461 pkg := &mockPackager{ 5462 failLoadFwdPkgs: true, 5463 } 5464 c.channel.State().Packager = pkg 5465 }, 5466 func(t *testing.T, c *channelLink, _ *lnwallet.LightningChannel) { 5467 // Should fail at startup. 5468 }, 5469 false, 5470 false, 5471 }, 5472 { 5473 // Test that we force close the channel if we receive 5474 // an invalid Settle message. 5475 func(c *channelLink) { 5476 }, 5477 func(t *testing.T, c *channelLink, _ *lnwallet.LightningChannel) { 5478 // Recevive an htlc settle for an htlc that was 5479 // never added. 5480 htlcSettle := &lnwire.UpdateFulfillHTLC{ 5481 ID: 0, 5482 PaymentPreimage: [32]byte{}, 5483 } 5484 c.HandleChannelUpdate(htlcSettle) 5485 }, 5486 true, 5487 false, 5488 }, 5489 { 5490 // Test that we force close the channel if we receive 5491 // an invalid CommitSig, not containing enough HTLC 5492 // sigs. 5493 func(c *channelLink) { 5494 }, 5495 func(t *testing.T, c *channelLink, remoteChannel *lnwallet.LightningChannel) { 5496 5497 // Generate an HTLC and send to the link. 5498 htlc1 := generateHtlc(t, c, 0) 5499 ctx := linkTestContext{ 5500 t: t, 5501 aliceLink: c, 5502 bobChannel: remoteChannel, 5503 } 5504 ctx.sendHtlcBobToAlice(htlc1) 5505 5506 // Sign a commitment that will include 5507 // signature for the HTLC just sent. 5508 sig, htlcSigs, _, err := 5509 remoteChannel.SignNextCommitment() 5510 if err != nil { 5511 t.Fatalf("error signing commitment: %v", 5512 err) 5513 } 5514 5515 // Remove the HTLC sig, such that the commit 5516 // sig will be invalid. 5517 commitSig := &lnwire.CommitSig{ 5518 CommitSig: sig, 5519 HtlcSigs: htlcSigs[1:], 5520 } 5521 5522 c.HandleChannelUpdate(commitSig) 5523 }, 5524 true, 5525 false, 5526 }, 5527 { 5528 // Test that we force close the channel if we receive 5529 // an invalid CommitSig, where the sig itself is 5530 // corrupted. 5531 func(c *channelLink) { 5532 }, 5533 func(t *testing.T, c *channelLink, remoteChannel *lnwallet.LightningChannel) { 5534 5535 // Generate an HTLC and send to the link. 5536 htlc1 := generateHtlc(t, c, 0) 5537 ctx := linkTestContext{ 5538 t: t, 5539 aliceLink: c, 5540 bobChannel: remoteChannel, 5541 } 5542 5543 ctx.sendHtlcBobToAlice(htlc1) 5544 5545 // Sign a commitment that will include 5546 // signature for the HTLC just sent. 5547 sig, htlcSigs, _, err := 5548 remoteChannel.SignNextCommitment() 5549 if err != nil { 5550 t.Fatalf("error signing commitment: %v", 5551 err) 5552 } 5553 5554 // Flip a bit on the signature, rendering it 5555 // invalid. 5556 sig[19] ^= 1 5557 commitSig := &lnwire.CommitSig{ 5558 CommitSig: sig, 5559 HtlcSigs: htlcSigs, 5560 } 5561 5562 c.HandleChannelUpdate(commitSig) 5563 }, 5564 true, 5565 false, 5566 }, 5567 { 5568 // Test that we consider the failure permanent if we 5569 // receive a link error from the remote. 5570 func(c *channelLink) { 5571 }, 5572 func(t *testing.T, c *channelLink, remoteChannel *lnwallet.LightningChannel) { 5573 err := &lnwire.Error{} 5574 c.HandleChannelUpdate(err) 5575 }, 5576 false, 5577 // TODO(halseth) For compatibility with CL we currently 5578 // don't treat Errors as permanent errors. 5579 false, 5580 }, 5581 } 5582 5583 const chanAmt = dcrutil.AtomsPerCoin * 5 5584 5585 // Execute each test case. 5586 for i, test := range testCases { 5587 link, remoteChannel, _, start, cleanUp, _, err := 5588 newSingleLinkTestHarness(chanAmt, 0) 5589 if err != nil { 5590 t.Fatalf("unable to create link: %v", err) 5591 } 5592 5593 coreLink := link.(*channelLink) 5594 5595 // Set up a channel used to check whether the link error 5596 // force closed the channel. 5597 linkErrors := make(chan LinkFailureError, 1) 5598 coreLink.cfg.OnChannelFailure = func(_ lnwire.ChannelID, 5599 _ lnwire.ShortChannelID, linkErr LinkFailureError) { 5600 linkErrors <- linkErr 5601 } 5602 5603 // Set up the link before starting it. 5604 test.options(coreLink) 5605 if err := start(); err != nil { 5606 t.Fatalf("unable to start test harness: %v", err) 5607 } 5608 5609 // Execute the test case. 5610 test.linkTest(t, coreLink, remoteChannel) 5611 5612 // Currently we expect all test cases to lead to link error. 5613 var linkErr LinkFailureError 5614 select { 5615 case linkErr = <-linkErrors: 5616 case <-time.After(10 * time.Second): 5617 t.Fatalf("%d) Alice did not fail"+ 5618 "channel", i) 5619 } 5620 5621 // If we expect the link to force close the channel in this 5622 // case, check that it happens. If not, make sure it does not 5623 // happen. 5624 if test.shouldForceClose != linkErr.ForceClose { 5625 t.Fatalf("%d) Expected Alice to force close(%v), "+ 5626 "instead got(%v)", i, test.shouldForceClose, 5627 linkErr.ForceClose) 5628 } 5629 5630 if test.permanentFailure != linkErr.PermanentFailure { 5631 t.Fatalf("%d) Expected Alice set permanent failure(%v), "+ 5632 "instead got(%v)", i, test.permanentFailure, 5633 linkErr.PermanentFailure) 5634 } 5635 5636 // Clean up before starting next test case. 5637 cleanUp() 5638 } 5639 } 5640 5641 // TestExpectedFee tests calculation of ExpectedFee returns expected fee, given 5642 // a baseFee, a feeRate, and an htlc amount. 5643 func TestExpectedFee(t *testing.T) { 5644 testCases := []struct { 5645 baseFee lnwire.MilliAtom 5646 feeRate lnwire.MilliAtom 5647 htlcAmt lnwire.MilliAtom 5648 expected lnwire.MilliAtom 5649 }{ 5650 { 5651 lnwire.MilliAtom(0), 5652 lnwire.MilliAtom(0), 5653 lnwire.MilliAtom(0), 5654 lnwire.MilliAtom(0), 5655 }, 5656 { 5657 lnwire.MilliAtom(0), 5658 lnwire.MilliAtom(1), 5659 lnwire.MilliAtom(999999), 5660 lnwire.MilliAtom(0), 5661 }, 5662 { 5663 lnwire.MilliAtom(0), 5664 lnwire.MilliAtom(1), 5665 lnwire.MilliAtom(1000000), 5666 lnwire.MilliAtom(1), 5667 }, 5668 { 5669 lnwire.MilliAtom(0), 5670 lnwire.MilliAtom(1), 5671 lnwire.MilliAtom(1000001), 5672 lnwire.MilliAtom(1), 5673 }, 5674 { 5675 lnwire.MilliAtom(1), 5676 lnwire.MilliAtom(1), 5677 lnwire.MilliAtom(1000000), 5678 lnwire.MilliAtom(2), 5679 }, 5680 } 5681 5682 for _, test := range testCases { 5683 f := ForwardingPolicy{ 5684 BaseFee: test.baseFee, 5685 FeeRate: test.feeRate, 5686 } 5687 fee := ExpectedFee(f, test.htlcAmt) 5688 if fee != test.expected { 5689 t.Errorf("expected fee to be (%v), instead got (%v)", test.expected, 5690 fee) 5691 } 5692 } 5693 } 5694 5695 // TestForwardingAsymmetricTimeLockPolicies tests that each link is able to 5696 // properly handle forwarding HTLCs when their outgoing channels have 5697 // asymmetric policies w.r.t what they require for time locks. 5698 func TestForwardingAsymmetricTimeLockPolicies(t *testing.T) { 5699 t.Parallel() 5700 5701 // First, we'll create our traditional three hop network. Bob 5702 // interacting with and asserting the state of two of the end points 5703 // for this test. 5704 channels, cleanUp, _, err := createClusterChannels( 5705 dcrutil.AtomsPerCoin*3, 5706 dcrutil.AtomsPerCoin*5, 5707 ) 5708 if err != nil { 5709 t.Fatalf("unable to create channel: %v", err) 5710 } 5711 defer cleanUp() 5712 5713 n := newThreeHopNetwork( 5714 t, channels.aliceToBob, channels.bobToAlice, channels.bobToCarol, 5715 channels.carolToBob, testStartingHeight, 5716 ) 5717 if err := n.start(); err != nil { 5718 t.Fatalf("unable to start three hop network: %v", err) 5719 } 5720 defer n.stop() 5721 5722 // Now that each of the links are up, we'll modify the link from Alice 5723 // -> Bob to have a greater time lock delta than that of the link of 5724 // Bob -> Carol. 5725 newPolicy := n.firstBobChannelLink.cfg.FwrdingPolicy 5726 newPolicy.TimeLockDelta = 7 5727 n.firstBobChannelLink.UpdateForwardingPolicy(newPolicy) 5728 5729 // Now that the Alice -> Bob link has been updated, we'll craft and 5730 // send a payment from Alice -> Carol. This should succeed as normal, 5731 // even though Bob has asymmetric time lock policies. 5732 amount := lnwire.NewMAtomsFromAtoms(dcrutil.AtomsPerCoin) 5733 htlcAmt, totalTimelock, hops := generateHops( 5734 amount, testStartingHeight, n.firstBobChannelLink, 5735 n.carolChannelLink, 5736 ) 5737 5738 firstHop := n.firstBobChannelLink.ShortChanID() 5739 _, err = makePayment( 5740 n.aliceServer, n.carolServer, firstHop, hops, amount, htlcAmt, 5741 totalTimelock, 5742 ).Wait(30 * time.Second) 5743 if err != nil { 5744 t.Fatalf("unable to send payment: %v", err) 5745 } 5746 } 5747 5748 // TestCheckHtlcForward tests that a link is properly enforcing the HTLC 5749 // forwarding policy. 5750 func TestCheckHtlcForward(t *testing.T) { 5751 5752 fetchLastChannelUpdate := func(lnwire.ShortChannelID) ( 5753 *lnwire.ChannelUpdate, error) { 5754 5755 return &lnwire.ChannelUpdate{}, nil 5756 } 5757 5758 testChannel, _, fCleanUp, err := createTestChannel( 5759 alicePrivKey, bobPrivKey, 100000, 100000, 5760 1000, 1000, lnwire.ShortChannelID{}, 5761 ) 5762 if err != nil { 5763 t.Fatal(err) 5764 } 5765 defer fCleanUp() 5766 5767 link := channelLink{ 5768 cfg: ChannelLinkConfig{ 5769 FwrdingPolicy: ForwardingPolicy{ 5770 TimeLockDelta: 20, 5771 MinHTLCOut: 500, 5772 MaxHTLC: 1000, 5773 BaseFee: 10, 5774 }, 5775 FetchLastChannelUpdate: fetchLastChannelUpdate, 5776 MaxOutgoingCltvExpiry: DefaultMaxOutgoingCltvExpiry, 5777 HtlcNotifier: &mockHTLCNotifier{}, 5778 }, 5779 log: log, 5780 channel: testChannel.channel, 5781 } 5782 5783 var hash [32]byte 5784 5785 t.Run("satisfied", func(t *testing.T) { 5786 result := link.CheckHtlcForward(hash, 1500, 1000, 5787 200, 150, 0) 5788 if result != nil { 5789 t.Fatalf("expected policy to be satisfied") 5790 } 5791 }) 5792 5793 t.Run("below minhtlc", func(t *testing.T) { 5794 result := link.CheckHtlcForward(hash, 100, 50, 5795 200, 150, 0) 5796 if _, ok := result.WireMessage().(*lnwire.FailAmountBelowMinimum); !ok { 5797 t.Fatalf("expected FailAmountBelowMinimum failure code") 5798 } 5799 }) 5800 5801 t.Run("above maxhtlc", func(t *testing.T) { 5802 result := link.CheckHtlcForward(hash, 1500, 1200, 5803 200, 150, 0) 5804 if _, ok := result.WireMessage().(*lnwire.FailTemporaryChannelFailure); !ok { 5805 t.Fatalf("expected FailTemporaryChannelFailure failure code") 5806 } 5807 }) 5808 5809 t.Run("insufficient fee", func(t *testing.T) { 5810 result := link.CheckHtlcForward(hash, 1005, 1000, 5811 200, 150, 0) 5812 if _, ok := result.WireMessage().(*lnwire.FailFeeInsufficient); !ok { 5813 t.Fatalf("expected FailFeeInsufficient failure code") 5814 } 5815 }) 5816 5817 t.Run("expiry too soon", func(t *testing.T) { 5818 result := link.CheckHtlcForward(hash, 1500, 1000, 5819 200, 150, 190) 5820 if _, ok := result.WireMessage().(*lnwire.FailExpiryTooSoon); !ok { 5821 t.Fatalf("expected FailExpiryTooSoon failure code") 5822 } 5823 }) 5824 5825 t.Run("incorrect cltv expiry", func(t *testing.T) { 5826 result := link.CheckHtlcForward(hash, 1500, 1000, 5827 200, 190, 0) 5828 if _, ok := result.WireMessage().(*lnwire.FailIncorrectCltvExpiry); !ok { 5829 t.Fatalf("expected FailIncorrectCltvExpiry failure code") 5830 } 5831 5832 }) 5833 5834 t.Run("cltv expiry too far in the future", func(t *testing.T) { 5835 // Check that expiry isn't too far in the future. 5836 result := link.CheckHtlcForward(hash, 1500, 1000, 5837 10200, 10100, 0) 5838 if _, ok := result.WireMessage().(*lnwire.FailExpiryTooFar); !ok { 5839 t.Fatalf("expected FailExpiryTooFar failure code") 5840 } 5841 }) 5842 } 5843 5844 // TestChannelLinkCanceledInvoice in this test checks the interaction 5845 // between Alice and Bob for a canceled invoice. 5846 func TestChannelLinkCanceledInvoice(t *testing.T) { 5847 t.Parallel() 5848 5849 // Setup a alice-bob network. 5850 alice, bob, cleanUp, err := createTwoClusterChannels( 5851 dcrutil.AtomsPerCoin*3, 5852 dcrutil.AtomsPerCoin*5) 5853 if err != nil { 5854 t.Fatalf("unable to create channel: %v", err) 5855 } 5856 defer cleanUp() 5857 5858 n := newTwoHopNetwork(t, alice.channel, bob.channel, testStartingHeight) 5859 if err := n.start(); err != nil { 5860 t.Fatal(err) 5861 } 5862 defer n.stop() 5863 5864 // Prepare an alice -> bob payment. 5865 amount := lnwire.NewMAtomsFromAtoms(dcrutil.AtomsPerCoin) 5866 htlcAmt, totalTimelock, hops := generateHops(amount, testStartingHeight, 5867 n.bobChannelLink) 5868 5869 firstHop := n.bobChannelLink.ShortChanID() 5870 5871 invoice, payFunc, err := preparePayment( 5872 n.aliceServer, n.bobServer, firstHop, hops, amount, htlcAmt, 5873 totalTimelock, 5874 ) 5875 if err != nil { 5876 t.Fatalf("unable to prepare the payment: %v", err) 5877 } 5878 5879 // Cancel the invoice at bob's end. 5880 hash := invoice.Terms.PaymentPreimage.Hash() 5881 err = n.bobServer.registry.CancelInvoice(hash) 5882 if err != nil { 5883 t.Fatal(err) 5884 } 5885 5886 // Have Alice fire the payment. 5887 err = waitForPayFuncResult(payFunc, 30*time.Second) 5888 5889 // Because the invoice is canceled, we expect an unknown payment hash 5890 // result. 5891 rtErr, ok := err.(ClearTextError) 5892 if !ok { 5893 t.Fatalf("expected ClearTextError, but got %v", err) 5894 } 5895 _, ok = rtErr.WireMessage().(*lnwire.FailIncorrectDetails) 5896 if !ok { 5897 t.Fatalf("expected unknown payment hash, but got %v", err) 5898 } 5899 } 5900 5901 type hodlInvoiceTestCtx struct { 5902 n *twoHopNetwork 5903 startBandwidthAlice lnwire.MilliAtom 5904 startBandwidthBob lnwire.MilliAtom 5905 hash lntypes.Hash 5906 preimage lntypes.Preimage 5907 amount lnwire.MilliAtom 5908 errChan chan error 5909 5910 restoreBob func() (*lnwallet.LightningChannel, error) 5911 5912 cleanUp func() 5913 } 5914 5915 func newHodlInvoiceTestCtx(t *testing.T) (*hodlInvoiceTestCtx, error) { 5916 // Setup a alice-bob network. 5917 alice, bob, cleanUp, err := createTwoClusterChannels( 5918 dcrutil.AtomsPerCoin*3, 5919 dcrutil.AtomsPerCoin*5, 5920 ) 5921 if err != nil { 5922 t.Fatalf("unable to create channel: %v", err) 5923 } 5924 5925 n := newTwoHopNetwork(t, alice.channel, bob.channel, testStartingHeight) 5926 if err := n.start(); err != nil { 5927 t.Fatal(err) 5928 } 5929 5930 aliceBandwidthBefore := n.aliceChannelLink.Bandwidth() 5931 bobBandwidthBefore := n.bobChannelLink.Bandwidth() 5932 5933 debug := false 5934 if debug { 5935 // Log message that alice receives. 5936 n.aliceServer.intersect( 5937 createLogFunc("alice", n.aliceChannelLink.ChanID()), 5938 ) 5939 5940 // Log message that bob receives. 5941 n.bobServer.intersect( 5942 createLogFunc("bob", n.bobChannelLink.ChanID()), 5943 ) 5944 } 5945 5946 amount := lnwire.NewMAtomsFromAtoms(dcrutil.AtomsPerCoin) 5947 htlcAmt, totalTimelock, hops := generateHops( 5948 amount, testStartingHeight, n.bobChannelLink, 5949 ) 5950 5951 // Generate hold invoice preimage. 5952 r, err := generateRandomBytes(lntypes.HashSize) 5953 if err != nil { 5954 t.Fatal(err) 5955 } 5956 preimage, err := lntypes.MakePreimage(r) 5957 if err != nil { 5958 t.Fatal(err) 5959 } 5960 hash := preimage.Hash() 5961 5962 // Have alice pay the hodl invoice, wait for bob's commitment state to 5963 // be updated and the invoice state to be updated. 5964 receiver := n.bobServer 5965 receiver.registry.settleChan = make(chan lntypes.Hash) 5966 firstHop := n.bobChannelLink.ShortChanID() 5967 errChan := n.makeHoldPayment( 5968 n.aliceServer, receiver, firstHop, hops, amount, htlcAmt, 5969 totalTimelock, preimage, 5970 ) 5971 5972 select { 5973 case err := <-errChan: 5974 t.Fatalf("no payment result expected: %v", err) 5975 case <-time.After(5 * time.Second): 5976 t.Fatal("timeout") 5977 case h := <-receiver.registry.settleChan: 5978 if hash != h { 5979 t.Fatal("unexpect invoice settled") 5980 } 5981 } 5982 5983 return &hodlInvoiceTestCtx{ 5984 n: n, 5985 startBandwidthAlice: aliceBandwidthBefore, 5986 startBandwidthBob: bobBandwidthBefore, 5987 preimage: preimage, 5988 hash: hash, 5989 amount: amount, 5990 errChan: errChan, 5991 restoreBob: bob.restore, 5992 5993 cleanUp: func() { 5994 cleanUp() 5995 n.stop() 5996 }, 5997 }, nil 5998 } 5999 6000 // TestChannelLinkHoldInvoiceSettle asserts that a hodl invoice can be settled. 6001 func TestChannelLinkHoldInvoiceSettle(t *testing.T) { 6002 t.Parallel() 6003 6004 defer timeout(t)() 6005 6006 ctx, err := newHodlInvoiceTestCtx(t) 6007 if err != nil { 6008 t.Fatal(err) 6009 } 6010 defer ctx.cleanUp() 6011 6012 err = ctx.n.bobServer.registry.SettleHodlInvoice(ctx.preimage) 6013 if err != nil { 6014 t.Fatal(err) 6015 } 6016 6017 // Wait for payment to succeed. 6018 err = <-ctx.errChan 6019 if err != nil { 6020 t.Fatal(err) 6021 } 6022 6023 // Wait for Alice to receive the revocation. This is needed 6024 // because the settles are pipelined to the switch and otherwise 6025 // the bandwidth won't be updated by the time Alice receives a 6026 // response here. 6027 time.Sleep(2 * time.Second) 6028 6029 if ctx.startBandwidthAlice-ctx.amount != 6030 ctx.n.aliceChannelLink.Bandwidth() { 6031 6032 t.Fatal("alice bandwidth should have decrease on payment " + 6033 "amount") 6034 } 6035 6036 if ctx.startBandwidthBob+ctx.amount != 6037 ctx.n.bobChannelLink.Bandwidth() { 6038 6039 t.Fatalf("bob bandwidth isn't match: expected %v, got %v", 6040 ctx.startBandwidthBob+ctx.amount, 6041 ctx.n.bobChannelLink.Bandwidth()) 6042 } 6043 } 6044 6045 // TestChannelLinkHoldInvoiceSettle asserts that a hodl invoice can be canceled. 6046 func TestChannelLinkHoldInvoiceCancel(t *testing.T) { 6047 t.Parallel() 6048 6049 defer timeout(t)() 6050 6051 ctx, err := newHodlInvoiceTestCtx(t) 6052 if err != nil { 6053 t.Fatal(err) 6054 } 6055 defer ctx.cleanUp() 6056 6057 err = ctx.n.bobServer.registry.CancelInvoice(ctx.hash) 6058 if err != nil { 6059 t.Fatal(err) 6060 } 6061 6062 // Wait for payment to succeed. 6063 err = <-ctx.errChan 6064 assertFailureCode(t, err, lnwire.CodeIncorrectOrUnknownPaymentDetails) 6065 } 6066 6067 // TestChannelLinkHoldInvoiceRestart asserts hodl htlcs are held after blocks 6068 // are mined and the link is restarted. The initial expiry checks should not 6069 // apply to hodl htlcs after restart. 6070 func TestChannelLinkHoldInvoiceRestart(t *testing.T) { 6071 t.Parallel() 6072 6073 defer timeout(t)() 6074 6075 const ( 6076 chanAmt = dcrutil.AtomsPerCoin * 5 6077 ) 6078 6079 // We'll start by creating a new link with our chanAmt (5 DCR). We will 6080 // only be testing Alice's behavior, so the reference to Bob's channel 6081 // state is unnecessary. 6082 aliceLink, bobChannel, _, start, cleanUp, restore, err := 6083 newSingleLinkTestHarness(chanAmt, 0) 6084 if err != nil { 6085 t.Fatalf("unable to create link: %v", err) 6086 } 6087 defer cleanUp() 6088 6089 alice := newPersistentLinkHarness( 6090 t, aliceLink, nil, restore, 6091 ) 6092 6093 if err := start(); err != nil { 6094 t.Fatalf("unable to start test harness: %v", err) 6095 } 6096 6097 var ( 6098 coreLink = alice.coreLink 6099 registry = coreLink.cfg.Registry.(*mockInvoiceRegistry) 6100 ) 6101 6102 registry.settleChan = make(chan lntypes.Hash) 6103 6104 htlc, invoice := generateHtlcAndInvoice(t, 0) 6105 6106 // Convert into a hodl invoice and save the preimage for later. 6107 preimage := invoice.Terms.PaymentPreimage 6108 invoice.Terms.PaymentPreimage = nil 6109 invoice.HodlInvoice = true 6110 6111 // We must add the invoice to the registry, such that Alice 6112 // expects this payment. 6113 err = registry.AddInvoice( 6114 *invoice, htlc.PaymentHash, 6115 ) 6116 if err != nil { 6117 t.Fatalf("unable to add invoice to registry: %v", err) 6118 } 6119 6120 ctx := linkTestContext{ 6121 t: t, 6122 aliceLink: alice.link, 6123 aliceMsgs: alice.msgs, 6124 bobChannel: bobChannel, 6125 } 6126 6127 // Lock in htlc paying the hodl invoice. 6128 ctx.sendHtlcBobToAlice(htlc) 6129 ctx.sendCommitSigBobToAlice(1) 6130 ctx.receiveRevAndAckAliceToBob() 6131 ctx.receiveCommitSigAliceToBob(1) 6132 ctx.sendRevAndAckBobToAlice() 6133 6134 // We expect a call to the invoice registry to notify the arrival of the 6135 // htlc. 6136 <-registry.settleChan 6137 6138 // Increase block height. This height will be retrieved by the link 6139 // after restart. 6140 coreLink.cfg.Switch.bestHeight++ 6141 6142 // Restart link. 6143 alice.restart(false, false) 6144 ctx.aliceLink = alice.link 6145 ctx.aliceMsgs = alice.msgs 6146 6147 // Expect htlc to be reprocessed. 6148 <-registry.settleChan 6149 6150 // Settle the invoice with the preimage. 6151 err = registry.SettleHodlInvoice(*preimage) 6152 if err != nil { 6153 t.Fatalf("settle hodl invoice: %v", err) 6154 } 6155 6156 // Expect alice to send a settle and commitsig message to bob. 6157 ctx.receiveSettleAliceToBob() 6158 ctx.receiveCommitSigAliceToBob(0) 6159 6160 // Stop the link 6161 alice.link.Stop() 6162 6163 // Check that no unexpected messages were sent. 6164 select { 6165 case msg := <-alice.msgs: 6166 t.Fatalf("did not expect message %T", msg) 6167 default: 6168 } 6169 } 6170 6171 // TestChannelLinkRevocationWindowRegular asserts that htlcs paying to a regular 6172 // invoice are settled even if the revocation window gets exhausted. 6173 func TestChannelLinkRevocationWindowRegular(t *testing.T) { 6174 t.Parallel() 6175 6176 const ( 6177 chanAmt = dcrutil.AtomsPerCoin * 5 6178 ) 6179 6180 // We'll start by creating a new link with our chanAmt (5 DCR). We will 6181 // only be testing Alice's behavior, so the reference to Bob's channel 6182 // state is unnecessary. 6183 aliceLink, bobChannel, _, start, cleanUp, _, err := 6184 newSingleLinkTestHarness(chanAmt, 0) 6185 if err != nil { 6186 t.Fatalf("unable to create link: %v", err) 6187 } 6188 defer cleanUp() 6189 6190 if err := start(); err != nil { 6191 t.Fatalf("unable to start test harness: %v", err) 6192 } 6193 defer aliceLink.Stop() 6194 6195 var ( 6196 coreLink = aliceLink.(*channelLink) 6197 registry = coreLink.cfg.Registry.(*mockInvoiceRegistry) 6198 aliceMsgs = coreLink.cfg.Peer.(*mockPeer).sentMsgs 6199 ) 6200 6201 ctx := linkTestContext{ 6202 t: t, 6203 aliceLink: aliceLink, 6204 aliceMsgs: aliceMsgs, 6205 bobChannel: bobChannel, 6206 } 6207 6208 registry.settleChan = make(chan lntypes.Hash) 6209 6210 htlc1, invoice1 := generateHtlcAndInvoice(t, 0) 6211 htlc2, invoice2 := generateHtlcAndInvoice(t, 1) 6212 6213 // We must add the invoice to the registry, such that Alice 6214 // expects this payment. 6215 err = registry.AddInvoice(*invoice1, htlc1.PaymentHash) 6216 if err != nil { 6217 t.Fatalf("unable to add invoice to registry: %v", err) 6218 } 6219 err = registry.AddInvoice(*invoice2, htlc2.PaymentHash) 6220 if err != nil { 6221 t.Fatalf("unable to add invoice to registry: %v", err) 6222 } 6223 6224 // Lock in htlc 1 on both sides. 6225 ctx.sendHtlcBobToAlice(htlc1) 6226 ctx.sendCommitSigBobToAlice(1) 6227 ctx.receiveRevAndAckAliceToBob() 6228 ctx.receiveCommitSigAliceToBob(1) 6229 ctx.sendRevAndAckBobToAlice() 6230 6231 // We expect a call to the invoice registry to notify the arrival of the 6232 // htlc. 6233 select { 6234 case <-registry.settleChan: 6235 case <-time.After(5 * time.Second): 6236 t.Fatal("expected invoice to be settled") 6237 } 6238 6239 // Expect alice to send a settle and commitsig message to bob. Bob does 6240 // not yet send the revocation. 6241 ctx.receiveSettleAliceToBob() 6242 ctx.receiveCommitSigAliceToBob(0) 6243 6244 // Pay invoice 2. 6245 ctx.sendHtlcBobToAlice(htlc2) 6246 ctx.sendCommitSigBobToAlice(2) 6247 ctx.receiveRevAndAckAliceToBob() 6248 6249 // At this point, Alice cannot send a new commit sig to bob because the 6250 // revocation window is exhausted. 6251 6252 // Bob sends revocation and signs commit with htlc1 settled. 6253 ctx.sendRevAndAckBobToAlice() 6254 6255 // After the revocation, it is again possible for Alice to send a commit 6256 // sig with htlc2. 6257 ctx.receiveCommitSigAliceToBob(1) 6258 } 6259 6260 // TestChannelLinkRevocationWindowHodl asserts that htlcs paying to a hodl 6261 // invoice are settled even if the revocation window gets exhausted. 6262 func TestChannelLinkRevocationWindowHodl(t *testing.T) { 6263 t.Parallel() 6264 6265 const ( 6266 chanAmt = dcrutil.AtomsPerCoin * 5 6267 ) 6268 6269 // We'll start by creating a new link with our chanAmt (5 DCR). We will 6270 // only be testing Alice's behavior, so the reference to Bob's channel 6271 // state is unnecessary. 6272 aliceLink, bobChannel, batchTicker, start, cleanUp, _, err := 6273 newSingleLinkTestHarness(chanAmt, 0) 6274 if err != nil { 6275 t.Fatalf("unable to create link: %v", err) 6276 } 6277 defer cleanUp() 6278 6279 if err := start(); err != nil { 6280 t.Fatalf("unable to start test harness: %v", err) 6281 } 6282 6283 var ( 6284 coreLink = aliceLink.(*channelLink) 6285 registry = coreLink.cfg.Registry.(*mockInvoiceRegistry) 6286 aliceMsgs = coreLink.cfg.Peer.(*mockPeer).sentMsgs 6287 ) 6288 6289 registry.settleChan = make(chan lntypes.Hash) 6290 6291 // Generate two invoice-htlc pairs. 6292 htlc1, invoice1 := generateHtlcAndInvoice(t, 0) 6293 htlc2, invoice2 := generateHtlcAndInvoice(t, 1) 6294 6295 // Convert into hodl invoices and save the preimages for later. 6296 preimage1 := invoice1.Terms.PaymentPreimage 6297 invoice1.Terms.PaymentPreimage = nil 6298 invoice1.HodlInvoice = true 6299 6300 preimage2 := invoice2.Terms.PaymentPreimage 6301 invoice2.Terms.PaymentPreimage = nil 6302 invoice2.HodlInvoice = true 6303 6304 // We must add the invoices to the registry, such that Alice 6305 // expects the payments. 6306 err = registry.AddInvoice(*invoice1, htlc1.PaymentHash) 6307 if err != nil { 6308 t.Fatalf("unable to add invoice to registry: %v", err) 6309 } 6310 err = registry.AddInvoice(*invoice2, htlc2.PaymentHash) 6311 if err != nil { 6312 t.Fatalf("unable to add invoice to registry: %v", err) 6313 } 6314 6315 ctx := linkTestContext{ 6316 t: t, 6317 aliceLink: aliceLink, 6318 aliceMsgs: aliceMsgs, 6319 bobChannel: bobChannel, 6320 } 6321 6322 // Lock in htlc 1 on both sides. 6323 ctx.sendHtlcBobToAlice(htlc1) 6324 ctx.sendCommitSigBobToAlice(1) 6325 ctx.receiveRevAndAckAliceToBob() 6326 ctx.receiveCommitSigAliceToBob(1) 6327 ctx.sendRevAndAckBobToAlice() 6328 6329 // We expect a call to the invoice registry to notify the arrival of 6330 // htlc 1. 6331 select { 6332 case <-registry.settleChan: 6333 case <-time.After(15 * time.Second): 6334 t.Fatal("exit hop notification not received") 6335 } 6336 6337 // Lock in htlc 2 on both sides. 6338 ctx.sendHtlcBobToAlice(htlc2) 6339 ctx.sendCommitSigBobToAlice(2) 6340 ctx.receiveRevAndAckAliceToBob() 6341 ctx.receiveCommitSigAliceToBob(2) 6342 ctx.sendRevAndAckBobToAlice() 6343 6344 select { 6345 case <-registry.settleChan: 6346 case <-time.After(15 * time.Second): 6347 t.Fatal("exit hop notification not received") 6348 } 6349 6350 // Settle invoice 1 with the preimage. 6351 err = registry.SettleHodlInvoice(*preimage1) 6352 if err != nil { 6353 t.Fatalf("settle hodl invoice: %v", err) 6354 } 6355 6356 // Expect alice to send a settle and commitsig message to bob. Bob does 6357 // not yet send the revocation. 6358 ctx.receiveSettleAliceToBob() 6359 ctx.receiveCommitSigAliceToBob(1) 6360 6361 // Settle invoice 2 with the preimage. 6362 err = registry.SettleHodlInvoice(*preimage2) 6363 if err != nil { 6364 t.Fatalf("settle hodl invoice: %v", err) 6365 } 6366 6367 // Expect alice to send a settle for htlc 2. 6368 ctx.receiveSettleAliceToBob() 6369 6370 // At this point, Alice cannot send a new commit sig to bob because the 6371 // revocation window is exhausted. 6372 6373 // Sleep to let timer(s) expire. 6374 time.Sleep(time.Second) 6375 6376 // We don't expect a commitSig from Alice. 6377 select { 6378 case msg := <-aliceMsgs: 6379 t.Fatalf("did not expect message %T", msg) 6380 default: 6381 } 6382 6383 // Bob sends revocation and signs commit with htlc 1 settled. 6384 ctx.sendRevAndAckBobToAlice() 6385 6386 // Allow some time for it to be processed by the link. 6387 time.Sleep(time.Second) 6388 6389 // Trigger the batch timer as this may trigger Alice to send a commit 6390 // sig. 6391 batchTicker <- time.Time{} 6392 6393 // After the revocation, it is again possible for Alice to send a commit 6394 // sig no more htlcs. Bob acks the update. 6395 ctx.receiveCommitSigAliceToBob(0) 6396 ctx.sendRevAndAckBobToAlice() 6397 6398 // Bob updates his remote commit tx. 6399 ctx.sendCommitSigBobToAlice(0) 6400 ctx.receiveRevAndAckAliceToBob() 6401 6402 // Stop the link 6403 aliceLink.Stop() 6404 6405 // Check that no unexpected messages were sent. 6406 select { 6407 case msg := <-aliceMsgs: 6408 t.Fatalf("did not expect message %T", msg) 6409 default: 6410 } 6411 } 6412 6413 // TestChannelLinkReceiveEmptySig tests the response of the link to receiving an 6414 // empty commit sig. This should be tolerated, but we shouldn't send out an 6415 // empty sig ourselves. 6416 func TestChannelLinkReceiveEmptySig(t *testing.T) { 6417 t.Parallel() 6418 6419 const chanAmt = dcrutil.AtomsPerCoin * 5 6420 const chanReserve = dcrutil.AtomsPerCoin * 1 6421 aliceLink, bobChannel, batchTicker, start, cleanUp, _, err := 6422 newSingleLinkTestHarness(chanAmt, chanReserve) 6423 if err != nil { 6424 t.Fatalf("unable to create link: %v", err) 6425 } 6426 defer cleanUp() 6427 6428 if err := start(); err != nil { 6429 t.Fatalf("unable to start test harness: %v", err) 6430 } 6431 6432 var ( 6433 coreLink = aliceLink.(*channelLink) 6434 aliceMsgs = coreLink.cfg.Peer.(*mockPeer).sentMsgs 6435 ) 6436 6437 ctx := linkTestContext{ 6438 t: t, 6439 aliceLink: aliceLink, 6440 aliceMsgs: aliceMsgs, 6441 bobChannel: bobChannel, 6442 } 6443 6444 htlc, _ := generateHtlcAndInvoice(t, 0) 6445 6446 // First, send an Add from Alice to Bob. 6447 ctx.sendHtlcAliceToBob(0, htlc) 6448 ctx.receiveHtlcAliceToBob() 6449 6450 // Tick the batch ticker to trigger a commitsig from Alice->Bob. 6451 select { 6452 case batchTicker <- time.Now(): 6453 case <-time.After(5 * time.Second): 6454 t.Fatalf("could not force commit sig") 6455 } 6456 6457 // Make Bob send a CommitSig. Since Bob hasn't received Alice's sig, he 6458 // cannot add the htlc to his remote tx yet. The commit sig that we 6459 // force Bob to send will be empty. Note that this normally does not 6460 // happen, because the link (which is not present for Bob in this test) 6461 // check whether Bob actually owes a sig first. 6462 ctx.sendCommitSigBobToAlice(0) 6463 6464 // Receive a CommitSig from Alice covering the htlc from above. 6465 ctx.receiveCommitSigAliceToBob(1) 6466 6467 // Wait for RevokeAndAck Alice->Bob. Even though Bob sent an empty 6468 // commit sig, Alice still needs to revoke the previous commitment tx. 6469 ctx.receiveRevAndAckAliceToBob() 6470 6471 // Send RevokeAndAck Bob->Alice to ack the added htlc. 6472 ctx.sendRevAndAckBobToAlice() 6473 6474 // We received an empty commit sig, we accepted it, but there is nothing 6475 // new to sign for us. 6476 6477 // No other messages are expected. 6478 ctx.assertNoMsgFromAlice(time.Second) 6479 6480 // Stop the link 6481 aliceLink.Stop() 6482 } 6483 6484 // TestPendingCommitTicker tests that a link will fail itself after a timeout if 6485 // the commitment dance stalls out. 6486 func TestPendingCommitTicker(t *testing.T) { 6487 t.Parallel() 6488 6489 const chanAmt = dcrutil.AtomsPerCoin * 5 6490 const chanReserve = dcrutil.AtomsPerCoin * 1 6491 aliceLink, bobChannel, batchTicker, start, cleanUp, _, err := 6492 newSingleLinkTestHarness(chanAmt, chanReserve) 6493 if err != nil { 6494 t.Fatalf("unable to create link: %v", err) 6495 } 6496 6497 var ( 6498 coreLink = aliceLink.(*channelLink) 6499 aliceMsgs = coreLink.cfg.Peer.(*mockPeer).sentMsgs 6500 ) 6501 6502 coreLink.cfg.PendingCommitTicker = ticker.NewForce(time.Millisecond) 6503 6504 linkErrs := make(chan LinkFailureError) 6505 coreLink.cfg.OnChannelFailure = func(_ lnwire.ChannelID, 6506 _ lnwire.ShortChannelID, linkErr LinkFailureError) { 6507 6508 linkErrs <- linkErr 6509 } 6510 6511 if err := start(); err != nil { 6512 t.Fatalf("unable to start test harness: %v", err) 6513 } 6514 defer cleanUp() 6515 6516 ctx := linkTestContext{ 6517 t: t, 6518 aliceLink: aliceLink, 6519 bobChannel: bobChannel, 6520 aliceMsgs: aliceMsgs, 6521 } 6522 6523 // Send an HTLC from Alice to Bob, and signal the batch ticker to signa 6524 // a commitment. 6525 htlc, _ := generateHtlcAndInvoice(t, 0) 6526 ctx.sendHtlcAliceToBob(0, htlc) 6527 ctx.receiveHtlcAliceToBob() 6528 batchTicker <- time.Now() 6529 6530 select { 6531 case msg := <-aliceMsgs: 6532 if _, ok := msg.(*lnwire.CommitSig); !ok { 6533 t.Fatalf("expected CommitSig, got: %T", msg) 6534 } 6535 case <-time.After(time.Second): 6536 t.Fatalf("alice did not send commit sig") 6537 } 6538 6539 // Check that Alice hasn't failed. 6540 select { 6541 case linkErr := <-linkErrs: 6542 t.Fatalf("link failed unexpectedly: %v", linkErr) 6543 case <-time.After(50 * time.Millisecond): 6544 } 6545 6546 // Without completing the dance, send another HTLC from Alice to Bob. 6547 // Since the revocation window has been exhausted, we should see the 6548 // link fail itself immediately due to the low pending commit timeout. 6549 // In production this would be much longer, e.g. a minute. 6550 htlc, _ = generateHtlcAndInvoice(t, 1) 6551 ctx.sendHtlcAliceToBob(1, htlc) 6552 ctx.receiveHtlcAliceToBob() 6553 batchTicker <- time.Now() 6554 6555 // Assert that we get the expected link failure from Alice. 6556 select { 6557 case linkErr := <-linkErrs: 6558 if linkErr.code != ErrRemoteUnresponsive { 6559 t.Fatalf("error code mismatch, "+ 6560 "want: ErrRemoteUnresponsive, got: %v", 6561 linkErr.code) 6562 } 6563 6564 case <-time.After(time.Second): 6565 t.Fatalf("did not receive failure") 6566 } 6567 } 6568 6569 // TestShutdownIfChannelClean tests that a link will exit the htlcManager loop 6570 // if and only if the underlying channel state is clean. 6571 func TestShutdownIfChannelClean(t *testing.T) { 6572 t.Parallel() 6573 6574 const chanAmt = dcrutil.AtomsPerCoin * 5 6575 const chanReserve = dcrutil.AtomsPerCoin * 1 6576 aliceLink, bobChannel, batchTicker, start, cleanUp, _, err := 6577 newSingleLinkTestHarness(chanAmt, chanReserve) 6578 require.NoError(t, err) 6579 6580 var ( 6581 coreLink = aliceLink.(*channelLink) 6582 aliceMsgs = coreLink.cfg.Peer.(*mockPeer).sentMsgs 6583 ) 6584 6585 shutdownAssert := func(expectedErr error) { 6586 err = aliceLink.ShutdownIfChannelClean() 6587 if expectedErr != nil { 6588 require.Error(t, err, expectedErr) 6589 } else { 6590 require.NoError(t, err) 6591 } 6592 } 6593 6594 err = start() 6595 require.NoError(t, err) 6596 defer cleanUp() 6597 6598 ctx := linkTestContext{ 6599 t: t, 6600 aliceLink: aliceLink, 6601 bobChannel: bobChannel, 6602 aliceMsgs: aliceMsgs, 6603 } 6604 6605 // First send an HTLC from Bob to Alice and assert that the link can't 6606 // be shutdown while the update is outstanding. 6607 htlc := generateHtlc(t, coreLink, 0) 6608 6609 // <---add----- 6610 ctx.sendHtlcBobToAlice(htlc) 6611 // <---sig----- 6612 ctx.sendCommitSigBobToAlice(1) 6613 // ----rev----> 6614 ctx.receiveRevAndAckAliceToBob() 6615 shutdownAssert(ErrLinkFailedShutdown) 6616 6617 // ----sig----> 6618 ctx.receiveCommitSigAliceToBob(1) 6619 shutdownAssert(ErrLinkFailedShutdown) 6620 6621 // <---rev----- 6622 ctx.sendRevAndAckBobToAlice() 6623 shutdownAssert(ErrLinkFailedShutdown) 6624 6625 // ---settle--> 6626 ctx.receiveSettleAliceToBob() 6627 shutdownAssert(ErrLinkFailedShutdown) 6628 6629 // ----sig----> 6630 ctx.receiveCommitSigAliceToBob(0) 6631 shutdownAssert(ErrLinkFailedShutdown) 6632 6633 // <---rev----- 6634 ctx.sendRevAndAckBobToAlice() 6635 shutdownAssert(ErrLinkFailedShutdown) 6636 6637 // There is currently no controllable breakpoint between Alice 6638 // receiving the CommitSig and her sending out the RevokeAndAck. As 6639 // soon as the RevokeAndAck is generated, the channel becomes clean. 6640 // This can happen right after the CommitSig is received, so there is 6641 // no shutdown assertion here. 6642 // <---sig----- 6643 ctx.sendCommitSigBobToAlice(0) 6644 6645 // ----rev----> 6646 ctx.receiveRevAndAckAliceToBob() 6647 shutdownAssert(nil) 6648 6649 // Now that the link has exited the htlcManager loop, attempt to 6650 // trigger the batch ticker. It should not be possible. 6651 select { 6652 case batchTicker <- time.Now(): 6653 t.Fatalf("expected batch ticker to be inactive") 6654 case <-time.After(5 * time.Second): 6655 } 6656 } 6657 6658 // assertFailureCode asserts that an error is of type ClearTextError and that 6659 // the failure code is as expected. 6660 func assertFailureCode(t *testing.T, err error, code lnwire.FailCode) { 6661 rtErr, ok := err.(ClearTextError) 6662 if !ok { 6663 t.Fatalf("expected ClearTextError but got %T", err) 6664 } 6665 6666 if rtErr.WireMessage().Code() != code { 6667 t.Fatalf("expected %v but got %v", 6668 code, rtErr.WireMessage().Code()) 6669 } 6670 }