htlcswitch: add tests to ensure we don't forward to inactive links

This commit is contained in:
Olaoluwa Osuntokun 2017-12-10 16:19:40 -08:00
parent c3d345b575
commit 8da46e0b5a
No known key found for this signature in database
GPG Key ID: 964EA263DD637C21
2 changed files with 119 additions and 9 deletions

@ -397,16 +397,19 @@ type mockChannelLink struct {
peer Peer
packets chan *htlcPacket
eligible bool
}
func newMockChannelLink(chanID lnwire.ChannelID, shortChanID lnwire.ShortChannelID,
peer Peer) *mockChannelLink {
peer Peer, eligible bool) *mockChannelLink {
return &mockChannelLink{
chanID: chanID,
shortChanID: shortChanID,
packets: make(chan *htlcPacket, 1),
peer: peer,
eligible: eligible,
}
}
@ -430,7 +433,7 @@ func (f *mockChannelLink) Bandwidth() lnwire.MilliSatoshi { return 99999999
func (f *mockChannelLink) Peer() Peer { return f.peer }
func (f *mockChannelLink) Start() error { return nil }
func (f *mockChannelLink) Stop() {}
func (f *mockChannelLink) EligibleToForward() bool { return true }
func (f *mockChannelLink) EligibleToForward() bool { return f.eligible }
var _ ChannelLink = (*mockChannelLink)(nil)

@ -37,8 +37,12 @@ func TestSwitchForward(t *testing.T) {
alicePeer := newMockServer(t, "alice")
bobPeer := newMockServer(t, "bob")
aliceChannelLink := newMockChannelLink(chanID1, aliceChanID, alicePeer)
bobChannelLink := newMockChannelLink(chanID2, bobChanID, bobPeer)
aliceChannelLink := newMockChannelLink(
chanID1, aliceChanID, alicePeer, true,
)
bobChannelLink := newMockChannelLink(
chanID2, bobChanID, bobPeer, true,
)
s := New(Config{})
s.Start()
@ -105,6 +109,99 @@ func TestSwitchForward(t *testing.T) {
}
}
// TestSkipIneligibleLinksMultiHopForward tests that if a multi-hop HTLC comes
// along, then we won't attempt to froward it down al ink that isn't yet able
// to forward any HTLC's.
func TestSkipIneligibleLinksMultiHopForward(t *testing.T) {
t.Parallel()
var packet *htlcPacket
alicePeer := newMockServer(t, "alice")
bobPeer := newMockServer(t, "bob")
aliceChannelLink := newMockChannelLink(
chanID1, aliceChanID, alicePeer, true,
)
// We'll create a link for Bob, but mark the link as unable to forward
// any new outgoing HTLC's.
bobChannelLink := newMockChannelLink(
chanID2, bobChanID, bobPeer, false,
)
s := New(Config{})
s.Start()
if err := s.AddLink(aliceChannelLink); err != nil {
t.Fatalf("unable to add alice link: %v", err)
}
if err := s.AddLink(bobChannelLink); err != nil {
t.Fatalf("unable to add bob link: %v", err)
}
// Create a new packet that's destined for Bob as an incoming HTLC from
// Alice.
preimage := [sha256.Size]byte{1}
rhash := fastsha256.Sum256(preimage[:])
packet = newAddPacket(
aliceChannelLink.ShortChanID(),
bobChannelLink.ShortChanID(),
&lnwire.UpdateAddHTLC{
PaymentHash: rhash,
Amount: 1,
}, newMockObfuscator(),
)
// The request to forward should fail as
err := s.forward(packet)
if err == nil {
t.Fatalf("forwarding should have failed due to inactive link")
}
if s.circuits.pending() != 0 {
t.Fatal("wrong amount of circuits")
}
}
// TestSkipIneligibleLinksLocalForward ensures that the switch will not attempt
// to forward any HTLC's down a link that isn't yet eligible for forwarding.
func TestSkipIneligibleLinksLocalForward(t *testing.T) {
t.Parallel()
// We'll create a single link for this test, marking it as being unable
// to forward form the get go.
alicePeer := newMockServer(t, "alice")
aliceChannelLink := newMockChannelLink(
chanID1, aliceChanID, alicePeer, false,
)
s := New(Config{})
s.Start()
if err := s.AddLink(aliceChannelLink); err != nil {
t.Fatalf("unable to add alice link: %v", err)
}
preimage := [sha256.Size]byte{1}
rhash := fastsha256.Sum256(preimage[:])
addMsg := &lnwire.UpdateAddHTLC{
PaymentHash: rhash,
Amount: 1,
}
// We'll attempt to send out a new HTLC that has Alice as the first
// outgoing link. This should fail as Alice isn't yet able to forward
// any active HTLC's.
alicePub := aliceChannelLink.Peer().PubKey()
_, err := s.SendHTLC(alicePub, addMsg, nil)
if err == nil {
t.Fatalf("local forward should fail due to inactive link")
}
if s.circuits.pending() != 0 {
t.Fatal("wrong amount of circuits")
}
}
// TestSwitchCancel checks that if htlc was rejected we remove unused
// circuits.
func TestSwitchCancel(t *testing.T) {
@ -115,8 +212,12 @@ func TestSwitchCancel(t *testing.T) {
alicePeer := newMockServer(t, "alice")
bobPeer := newMockServer(t, "bob")
aliceChannelLink := newMockChannelLink(chanID1, aliceChanID, alicePeer)
bobChannelLink := newMockChannelLink(chanID2, bobChanID, bobPeer)
aliceChannelLink := newMockChannelLink(
chanID1, aliceChanID, alicePeer, true,
)
bobChannelLink := newMockChannelLink(
chanID2, bobChanID, bobPeer, true,
)
s := New(Config{})
s.Start()
@ -191,8 +292,12 @@ func TestSwitchAddSamePayment(t *testing.T) {
alicePeer := newMockServer(t, "alice")
bobPeer := newMockServer(t, "bob")
aliceChannelLink := newMockChannelLink(chanID1, aliceChanID, alicePeer)
bobChannelLink := newMockChannelLink(chanID2, bobChanID, bobPeer)
aliceChannelLink := newMockChannelLink(
chanID1, aliceChanID, alicePeer, true,
)
bobChannelLink := newMockChannelLink(
chanID2, bobChanID, bobPeer, true,
)
s := New(Config{})
s.Start()
@ -288,7 +393,9 @@ func TestSwitchSendPayment(t *testing.T) {
t.Parallel()
alicePeer := newMockServer(t, "alice")
aliceChannelLink := newMockChannelLink(chanID1, aliceChanID, alicePeer)
aliceChannelLink := newMockChannelLink(
chanID1, aliceChanID, alicePeer, true,
)
s := New(Config{})
s.Start()