You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
268 lines
6.6 KiB
268 lines
6.6 KiB
package htlcswitch |
|
|
|
import ( |
|
"crypto/sha256" |
|
"testing" |
|
"time" |
|
|
|
"github.com/lightningnetwork/lnd/lntypes" |
|
"github.com/lightningnetwork/lnd/lnwallet" |
|
"github.com/lightningnetwork/lnd/lnwire" |
|
) |
|
|
|
type linkTestContext struct { |
|
t *testing.T |
|
|
|
aliceLink ChannelLink |
|
bobChannel *lnwallet.LightningChannel |
|
aliceMsgs <-chan lnwire.Message |
|
} |
|
|
|
// sendHtlcBobToAlice sends an HTLC from Bob to Alice, that pays to a preimage |
|
// already in Alice's registry. |
|
func (l *linkTestContext) sendHtlcBobToAlice(htlc *lnwire.UpdateAddHTLC) { |
|
l.t.Helper() |
|
|
|
_, err := l.bobChannel.AddHTLC(htlc, nil) |
|
if err != nil { |
|
l.t.Fatalf("bob failed adding htlc: %v", err) |
|
} |
|
|
|
l.aliceLink.HandleChannelUpdate(htlc) |
|
} |
|
|
|
// sendHtlcAliceToBob sends an HTLC from Alice to Bob, by first committing the |
|
// HTLC in the circuit map, then delivering the outgoing packet to Alice's link. |
|
// The HTLC will be sent to Bob via Alice's message stream. |
|
func (l *linkTestContext) sendHtlcAliceToBob(htlcID int, |
|
htlc *lnwire.UpdateAddHTLC) { |
|
|
|
l.t.Helper() |
|
|
|
circuitMap := l.aliceLink.(*channelLink).cfg.Switch.circuits |
|
fwdActions, err := circuitMap.CommitCircuits( |
|
&PaymentCircuit{ |
|
Incoming: CircuitKey{ |
|
HtlcID: uint64(htlcID), |
|
}, |
|
PaymentHash: htlc.PaymentHash, |
|
}, |
|
) |
|
if err != nil { |
|
l.t.Fatalf("unable to commit circuit: %v", err) |
|
} |
|
|
|
if len(fwdActions.Adds) != 1 { |
|
l.t.Fatalf("expected 1 adds, found %d", len(fwdActions.Adds)) |
|
} |
|
|
|
err = l.aliceLink.HandleSwitchPacket(&htlcPacket{ |
|
incomingHTLCID: uint64(htlcID), |
|
htlc: htlc, |
|
}) |
|
if err != nil { |
|
l.t.Fatal(err) |
|
} |
|
} |
|
|
|
// receiveHtlcAliceToBob pulls the next message from Alice's message stream, |
|
// asserts that it is an UpdateAddHTLC, then applies it to Bob's state machine. |
|
func (l *linkTestContext) receiveHtlcAliceToBob() { |
|
l.t.Helper() |
|
|
|
var msg lnwire.Message |
|
select { |
|
case msg = <-l.aliceMsgs: |
|
case <-time.After(15 * time.Second): |
|
l.t.Fatalf("did not received htlc from alice") |
|
} |
|
|
|
htlcAdd, ok := msg.(*lnwire.UpdateAddHTLC) |
|
if !ok { |
|
l.t.Fatalf("expected UpdateAddHTLC, got %T", msg) |
|
} |
|
|
|
_, err := l.bobChannel.ReceiveHTLC(htlcAdd) |
|
if err != nil { |
|
l.t.Fatalf("bob failed receiving htlc: %v", err) |
|
} |
|
} |
|
|
|
// sendCommitSigBobToAlice makes Bob sign a new commitment and send it to |
|
// Alice, asserting that it signs expHtlcs number of HTLCs. |
|
func (l *linkTestContext) sendCommitSigBobToAlice(expHtlcs int) { |
|
l.t.Helper() |
|
|
|
sig, htlcSigs, _, err := l.bobChannel.SignNextCommitment() |
|
if err != nil { |
|
l.t.Fatalf("error signing commitment: %v", err) |
|
} |
|
|
|
commitSig := &lnwire.CommitSig{ |
|
CommitSig: sig, |
|
HtlcSigs: htlcSigs, |
|
} |
|
|
|
if len(commitSig.HtlcSigs) != expHtlcs { |
|
l.t.Fatalf("Expected %d htlc sigs, got %d", expHtlcs, |
|
len(commitSig.HtlcSigs)) |
|
} |
|
|
|
l.aliceLink.HandleChannelUpdate(commitSig) |
|
} |
|
|
|
// receiveRevAndAckAliceToBob waits for Alice to send a RevAndAck to Bob, then |
|
// hands this to Bob. |
|
func (l *linkTestContext) receiveRevAndAckAliceToBob() { |
|
l.t.Helper() |
|
|
|
var msg lnwire.Message |
|
select { |
|
case msg = <-l.aliceMsgs: |
|
case <-time.After(15 * time.Second): |
|
l.t.Fatalf("did not receive message") |
|
} |
|
|
|
rev, ok := msg.(*lnwire.RevokeAndAck) |
|
if !ok { |
|
l.t.Fatalf("expected RevokeAndAck, got %T", msg) |
|
} |
|
|
|
_, _, _, _, err := l.bobChannel.ReceiveRevocation(rev) |
|
if err != nil { |
|
l.t.Fatalf("bob failed receiving revocation: %v", err) |
|
} |
|
} |
|
|
|
// receiveCommitSigAliceToBob waits for Alice to send a CommitSig to Bob, |
|
// signing expHtlcs numbers of HTLCs, then hands this to Bob. |
|
func (l *linkTestContext) receiveCommitSigAliceToBob(expHtlcs int) { |
|
l.t.Helper() |
|
|
|
comSig := l.receiveCommitSigAlice(expHtlcs) |
|
|
|
err := l.bobChannel.ReceiveNewCommitment( |
|
comSig.CommitSig, comSig.HtlcSigs, |
|
) |
|
if err != nil { |
|
l.t.Fatalf("bob failed receiving commitment: %v", err) |
|
} |
|
} |
|
|
|
// receiveCommitSigAlice waits for Alice to send a CommitSig, signing expHtlcs |
|
// numbers of HTLCs. |
|
func (l *linkTestContext) receiveCommitSigAlice(expHtlcs int) *lnwire.CommitSig { |
|
l.t.Helper() |
|
|
|
var msg lnwire.Message |
|
select { |
|
case msg = <-l.aliceMsgs: |
|
case <-time.After(15 * time.Second): |
|
l.t.Fatalf("did not receive message") |
|
} |
|
|
|
comSig, ok := msg.(*lnwire.CommitSig) |
|
if !ok { |
|
l.t.Fatalf("expected CommitSig, got %T", msg) |
|
} |
|
|
|
if len(comSig.HtlcSigs) != expHtlcs { |
|
l.t.Fatalf("expected %d htlc sigs, got %d", expHtlcs, |
|
len(comSig.HtlcSigs)) |
|
} |
|
|
|
return comSig |
|
} |
|
|
|
// sendRevAndAckBobToAlice make Bob revoke his current commitment, then hand |
|
// the RevokeAndAck to Alice. |
|
func (l *linkTestContext) sendRevAndAckBobToAlice() { |
|
l.t.Helper() |
|
|
|
rev, _, err := l.bobChannel.RevokeCurrentCommitment() |
|
if err != nil { |
|
l.t.Fatalf("unable to revoke commitment: %v", err) |
|
} |
|
|
|
l.aliceLink.HandleChannelUpdate(rev) |
|
} |
|
|
|
// receiveSettleAliceToBob waits for Alice to send a HTLC settle message to |
|
// Bob, then hands this to Bob. |
|
func (l *linkTestContext) receiveSettleAliceToBob() { |
|
l.t.Helper() |
|
|
|
var msg lnwire.Message |
|
select { |
|
case msg = <-l.aliceMsgs: |
|
case <-time.After(15 * time.Second): |
|
l.t.Fatalf("did not receive message") |
|
} |
|
|
|
settleMsg, ok := msg.(*lnwire.UpdateFulfillHTLC) |
|
if !ok { |
|
l.t.Fatalf("expected UpdateFulfillHTLC, got %T", msg) |
|
} |
|
|
|
err := l.bobChannel.ReceiveHTLCSettle(settleMsg.PaymentPreimage, |
|
settleMsg.ID) |
|
if err != nil { |
|
l.t.Fatalf("failed settling htlc: %v", err) |
|
} |
|
} |
|
|
|
// sendSettleBobToAlice settles an HTLC on Bob's state machine, then sends an |
|
// UpdateFulfillHTLC message to Alice's upstream inbox. |
|
func (l *linkTestContext) sendSettleBobToAlice(htlcID uint64, |
|
preimage lntypes.Preimage) { |
|
|
|
l.t.Helper() |
|
|
|
err := l.bobChannel.SettleHTLC(preimage, htlcID, nil, nil, nil) |
|
if err != nil { |
|
l.t.Fatalf("alice failed settling htlc id=%d hash=%x", |
|
htlcID, sha256.Sum256(preimage[:])) |
|
} |
|
|
|
settle := &lnwire.UpdateFulfillHTLC{ |
|
ID: htlcID, |
|
PaymentPreimage: preimage, |
|
} |
|
|
|
l.aliceLink.HandleChannelUpdate(settle) |
|
} |
|
|
|
// receiveSettleAliceToBob waits for Alice to send a HTLC settle message to |
|
// Bob, then hands this to Bob. |
|
func (l *linkTestContext) receiveFailAliceToBob() { |
|
l.t.Helper() |
|
|
|
var msg lnwire.Message |
|
select { |
|
case msg = <-l.aliceMsgs: |
|
case <-time.After(15 * time.Second): |
|
l.t.Fatalf("did not receive message") |
|
} |
|
|
|
failMsg, ok := msg.(*lnwire.UpdateFailHTLC) |
|
if !ok { |
|
l.t.Fatalf("expected UpdateFailHTLC, got %T", msg) |
|
} |
|
|
|
err := l.bobChannel.ReceiveFailHTLC(failMsg.ID, failMsg.Reason) |
|
if err != nil { |
|
l.t.Fatalf("unable to apply received fail htlc: %v", err) |
|
} |
|
} |
|
|
|
// assertNoMsgFromAlice asserts that Alice hasn't sent a message. Before |
|
// calling, make sure that Alice has had the opportunity to send the message. |
|
func (l *linkTestContext) assertNoMsgFromAlice(timeout time.Duration) { |
|
l.t.Helper() |
|
|
|
select { |
|
case msg := <-l.aliceMsgs: |
|
l.t.Fatalf("unexpected message from Alice: %v", msg) |
|
case <-time.After(timeout): |
|
} |
|
}
|
|
|