/ htlcswitch / link_isolated_test.go
link_isolated_test.go
1 package htlcswitch 2 3 import ( 4 "context" 5 "crypto/sha256" 6 "testing" 7 "time" 8 9 "github.com/lightningnetwork/lnd/lntypes" 10 "github.com/lightningnetwork/lnd/lnwallet" 11 "github.com/lightningnetwork/lnd/lnwire" 12 ) 13 14 type linkTestContext struct { 15 t *testing.T 16 17 aliceSwitch *Switch 18 aliceLink ChannelLink 19 bobChannel *lnwallet.LightningChannel 20 aliceMsgs <-chan lnwire.Message 21 } 22 23 // sendHtlcBobToAlice sends an HTLC from Bob to Alice, that pays to a preimage 24 // already in Alice's registry. 25 func (l *linkTestContext) sendHtlcBobToAlice(htlc *lnwire.UpdateAddHTLC) { 26 l.t.Helper() 27 28 _, err := l.bobChannel.AddHTLC(htlc, nil) 29 if err != nil { 30 l.t.Fatalf("bob failed adding htlc: %v", err) 31 } 32 33 l.aliceLink.HandleChannelUpdate(htlc) 34 } 35 36 // sendHtlcAliceToBob sends an HTLC from Alice to Bob, by first committing the 37 // HTLC in the circuit map, then delivering the outgoing packet to Alice's link. 38 // The HTLC will be sent to Bob via Alice's message stream. 39 func (l *linkTestContext) sendHtlcAliceToBob(htlcID int, 40 htlc *lnwire.UpdateAddHTLC) { 41 42 l.t.Helper() 43 44 circuitMap := l.aliceSwitch.circuits 45 fwdActions, err := circuitMap.CommitCircuits( 46 &PaymentCircuit{ 47 Incoming: CircuitKey{ 48 HtlcID: uint64(htlcID), 49 }, 50 PaymentHash: htlc.PaymentHash, 51 }, 52 ) 53 if err != nil { 54 l.t.Fatalf("unable to commit circuit: %v", err) 55 } 56 57 if len(fwdActions.Adds) != 1 { 58 l.t.Fatalf("expected 1 adds, found %d", len(fwdActions.Adds)) 59 } 60 61 err = l.aliceLink.handleSwitchPacket(&htlcPacket{ 62 incomingHTLCID: uint64(htlcID), 63 htlc: htlc, 64 }) 65 if err != nil { 66 l.t.Fatal(err) 67 } 68 } 69 70 // receiveHtlcAliceToBob pulls the next message from Alice's message stream, 71 // asserts that it is an UpdateAddHTLC, then applies it to Bob's state machine. 72 func (l *linkTestContext) receiveHtlcAliceToBob() { 73 l.t.Helper() 74 75 var msg lnwire.Message 76 select { 77 case msg = <-l.aliceMsgs: 78 case <-time.After(15 * time.Second): 79 l.t.Fatalf("did not received htlc from alice") 80 } 81 82 htlcAdd, ok := msg.(*lnwire.UpdateAddHTLC) 83 if !ok { 84 l.t.Fatalf("expected UpdateAddHTLC, got %T", msg) 85 } 86 87 _, err := l.bobChannel.ReceiveHTLC(htlcAdd) 88 if err != nil { 89 l.t.Fatalf("bob failed receiving htlc: %v", err) 90 } 91 } 92 93 // sendCommitSigBobToAlice makes Bob sign a new commitment and send it to 94 // Alice, asserting that it signs expHtlcs number of HTLCs. 95 func (l *linkTestContext) sendCommitSigBobToAlice(expHtlcs int) { 96 l.t.Helper() 97 98 testQuit, testQuitFunc := context.WithCancel(l.t.Context()) 99 defer testQuitFunc() 100 sigs, err := l.bobChannel.SignNextCommitment(testQuit) 101 if err != nil { 102 l.t.Fatalf("error signing commitment: %v", err) 103 } 104 105 commitSig := &lnwire.CommitSig{ 106 CommitSig: sigs.CommitSig, 107 HtlcSigs: sigs.HtlcSigs, 108 } 109 110 if len(commitSig.HtlcSigs) != expHtlcs { 111 l.t.Fatalf("Expected %d htlc sigs, got %d", expHtlcs, 112 len(commitSig.HtlcSigs)) 113 } 114 115 l.aliceLink.HandleChannelUpdate(commitSig) 116 } 117 118 // receiveRevAndAckAliceToBob waits for Alice to send a RevAndAck to Bob, then 119 // hands this to Bob. 120 func (l *linkTestContext) receiveRevAndAckAliceToBob() { 121 l.t.Helper() 122 123 var msg lnwire.Message 124 select { 125 case msg = <-l.aliceMsgs: 126 case <-time.After(15 * time.Second): 127 l.t.Fatalf("did not receive message") 128 } 129 130 rev, ok := msg.(*lnwire.RevokeAndAck) 131 if !ok { 132 l.t.Fatalf("expected RevokeAndAck, got %T", msg) 133 } 134 135 _, _, err := l.bobChannel.ReceiveRevocation(rev) 136 if err != nil { 137 l.t.Fatalf("bob failed receiving revocation: %v", err) 138 } 139 } 140 141 // receiveCommitSigAliceToBob waits for Alice to send a CommitSig to Bob, 142 // signing expHtlcs numbers of HTLCs, then hands this to Bob. 143 func (l *linkTestContext) receiveCommitSigAliceToBob(expHtlcs int) { 144 l.t.Helper() 145 146 comSig := l.receiveCommitSigAlice(expHtlcs) 147 148 err := l.bobChannel.ReceiveNewCommitment(&lnwallet.CommitSigs{ 149 CommitSig: comSig.CommitSig, 150 HtlcSigs: comSig.HtlcSigs, 151 }) 152 if err != nil { 153 l.t.Fatalf("bob failed receiving commitment: %v", err) 154 } 155 } 156 157 // receiveCommitSigAlice waits for Alice to send a CommitSig, signing expHtlcs 158 // numbers of HTLCs. 159 func (l *linkTestContext) receiveCommitSigAlice(expHtlcs int) *lnwire.CommitSig { 160 l.t.Helper() 161 162 var msg lnwire.Message 163 select { 164 case msg = <-l.aliceMsgs: 165 case <-time.After(15 * time.Second): 166 l.t.Fatalf("did not receive message") 167 } 168 169 comSig, ok := msg.(*lnwire.CommitSig) 170 if !ok { 171 l.t.Fatalf("expected CommitSig, got %T", msg) 172 } 173 174 if len(comSig.HtlcSigs) != expHtlcs { 175 l.t.Fatalf("expected %d htlc sigs, got %d", expHtlcs, 176 len(comSig.HtlcSigs)) 177 } 178 179 return comSig 180 } 181 182 // sendRevAndAckBobToAlice make Bob revoke his current commitment, then hand 183 // the RevokeAndAck to Alice. 184 func (l *linkTestContext) sendRevAndAckBobToAlice() { 185 l.t.Helper() 186 187 rev, _, _, err := l.bobChannel.RevokeCurrentCommitment() 188 if err != nil { 189 l.t.Fatalf("unable to revoke commitment: %v", err) 190 } 191 192 l.aliceLink.HandleChannelUpdate(rev) 193 } 194 195 // receiveSettleAliceToBob waits for Alice to send a HTLC settle message to 196 // Bob, then hands this to Bob. 197 func (l *linkTestContext) receiveSettleAliceToBob() { 198 l.t.Helper() 199 200 var msg lnwire.Message 201 select { 202 case msg = <-l.aliceMsgs: 203 case <-time.After(15 * time.Second): 204 l.t.Fatalf("did not receive message") 205 } 206 207 settleMsg, ok := msg.(*lnwire.UpdateFulfillHTLC) 208 if !ok { 209 l.t.Fatalf("expected UpdateFulfillHTLC, got %T", msg) 210 } 211 212 err := l.bobChannel.ReceiveHTLCSettle(settleMsg.PaymentPreimage, 213 settleMsg.ID) 214 if err != nil { 215 l.t.Fatalf("failed settling htlc: %v", err) 216 } 217 } 218 219 // sendSettleBobToAlice settles an HTLC on Bob's state machine, then sends an 220 // UpdateFulfillHTLC message to Alice's upstream inbox. 221 func (l *linkTestContext) sendSettleBobToAlice(htlcID uint64, 222 preimage lntypes.Preimage) { 223 224 l.t.Helper() 225 226 err := l.bobChannel.SettleHTLC(preimage, htlcID, nil, nil, nil) 227 if err != nil { 228 l.t.Fatalf("alice failed settling htlc id=%d hash=%x", 229 htlcID, sha256.Sum256(preimage[:])) 230 } 231 232 settle := &lnwire.UpdateFulfillHTLC{ 233 ID: htlcID, 234 PaymentPreimage: preimage, 235 } 236 237 l.aliceLink.HandleChannelUpdate(settle) 238 } 239 240 // receiveSettleAliceToBob waits for Alice to send a HTLC settle message to 241 // Bob, then hands this to Bob. 242 func (l *linkTestContext) receiveFailAliceToBob() { 243 l.t.Helper() 244 245 var msg lnwire.Message 246 select { 247 case msg = <-l.aliceMsgs: 248 case <-time.After(15 * time.Second): 249 l.t.Fatalf("did not receive message") 250 } 251 252 failMsg, ok := msg.(*lnwire.UpdateFailHTLC) 253 if !ok { 254 l.t.Fatalf("expected UpdateFailHTLC, got %T", msg) 255 } 256 257 err := l.bobChannel.ReceiveFailHTLC(failMsg.ID, failMsg.Reason) 258 if err != nil { 259 l.t.Fatalf("unable to apply received fail htlc: %v", err) 260 } 261 } 262 263 // assertNoMsgFromAlice asserts that Alice hasn't sent a message. Before 264 // calling, make sure that Alice has had the opportunity to send the message. 265 func (l *linkTestContext) assertNoMsgFromAlice(timeout time.Duration) { 266 l.t.Helper() 267 268 select { 269 case msg := <-l.aliceMsgs: 270 l.t.Fatalf("unexpected message from Alice: %v", msg) 271 case <-time.After(timeout): 272 } 273 }