Skip to content

Commit bf30fcb

Browse files
committed
htlcswitch: return temporary channel failure
Only return a permanent "unknown next peer" error if we are unable to find the channel link. In other cases, especially if the peer is just offline, return a "temporary channel failure" so that future retries are encouraged. fixes #6603
1 parent a04dbc2 commit bf30fcb

File tree

3 files changed

+66
-13
lines changed

3 files changed

+66
-13
lines changed

docs/release-notes/release-notes-0.15.1.md

+3
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,9 @@
115115
* [Re-initialise registered middleware index lookup map after removal of a
116116
registered middleware](https://github.com/lightningnetwork/lnd/pull/6739)
117117

118+
* [Only return permanent "Unknown next peer" error if peer/channel is
119+
unknown](https://github.com/lightningnetwork/lnd/pull/6803)
120+
118121
## Code Health
119122

120123
### Code cleanup, refactor, typo fixes

htlcswitch/switch.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -867,7 +867,7 @@ func (s *Switch) getLocalLink(pkt *htlcPacket, htlc *lnwire.UpdateAddHTLC) (
867867
link, err = s.getLinkByShortID(baseScid)
868868
if err != nil {
869869
log.Errorf("Link %v not found", baseScid)
870-
return nil, NewLinkError(&lnwire.FailUnknownNextPeer{})
870+
return nil, NewLinkError(&lnwire.FailTemporaryChannelFailure{})
871871
}
872872
}
873873

htlcswitch/switch_test.go

+62-12
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,20 @@ import (
3030
var zeroCircuit = channeldb.CircuitKey{}
3131
var emptyScid = lnwire.ShortChannelID{}
3232

33+
type SuccessOrFailureOption string
34+
35+
const (
36+
Success SuccessOrFailureOption = "success"
37+
PeerOffline = "peerOffline"
38+
UnknownChannel = "unknownChannel"
39+
)
40+
41+
var SuccessOrFailureOptions = []SuccessOrFailureOption{
42+
Success,
43+
PeerOffline,
44+
UnknownChannel,
45+
}
46+
3347
func genPreimage() ([32]byte, error) {
3448
var preimage [32]byte
3549
if _, err := io.ReadFull(rand.Reader, preimage[:]); err != nil {
@@ -656,22 +670,40 @@ func TestSwitchSendHTLCMapping(t *testing.T) {
656670
TxPosition: 45,
657671
},
658672
},
673+
{
674+
name: "zero-conf unknown scid",
675+
zeroConf: true,
676+
useAlias: false,
677+
alias: lnwire.ShortChannelID{
678+
BlockHeight: 10035,
679+
TxIndex: 35,
680+
TxPosition: 35,
681+
},
682+
real: lnwire.ShortChannelID{
683+
BlockHeight: 470000,
684+
TxIndex: 35,
685+
TxPosition: 45,
686+
},
687+
},
659688
}
660689

661-
for _, test := range tests {
662-
test := test
663-
t.Run(test.name, func(t *testing.T) {
664-
t.Parallel()
665-
testSwitchSendHtlcMapping(
666-
t, test.zeroConf, test.useAlias, test.alias,
667-
test.real, test.optionFeature,
668-
)
669-
})
690+
for _, successOrFailure := range SuccessOrFailureOptions {
691+
for _, test := range tests {
692+
test := test
693+
testName := fmt.Sprintf("%s[%s]", test.name, successOrFailure)
694+
t.Run(testName, func(t *testing.T) {
695+
testSwitchSendHtlcMapping(
696+
t, test.zeroConf, test.useAlias, test.alias,
697+
test.real, test.optionFeature, successOrFailure,
698+
)
699+
})
700+
}
670701
}
671702
}
672703

673704
func testSwitchSendHtlcMapping(t *testing.T, zeroConf, useAlias bool, alias,
674-
realScid lnwire.ShortChannelID, optionFeature bool) {
705+
realScid lnwire.ShortChannelID, optionFeature bool,
706+
successOrFailureOption SuccessOrFailureOption) {
675707

676708
peer, err := newMockServer(
677709
t, "alice", testStartingHeight, nil, testDefaultDelta,
@@ -708,6 +740,10 @@ func testSwitchSendHtlcMapping(t *testing.T, zeroConf, useAlias bool, alias,
708740
err = s.AddLink(link)
709741
require.NoError(t, err)
710742

743+
if successOrFailureOption == PeerOffline {
744+
s.RemoveLink(link.chanID)
745+
}
746+
711747
// Generate preimage.
712748
preimage, err := genPreimage()
713749
require.NoError(t, err)
@@ -718,15 +754,29 @@ func testSwitchSendHtlcMapping(t *testing.T, zeroConf, useAlias bool, alias,
718754
if useAlias {
719755
outgoingSCID = alias
720756
}
757+
if successOrFailureOption == UnknownChannel {
758+
outgoingSCID = lnwire.ShortChannelID{
759+
BlockHeight: 123,
760+
TxIndex: 123,
761+
TxPosition: 123,
762+
}
763+
}
721764

722765
// Send the HTLC and assert that we don't get an error.
723766
htlc := &lnwire.UpdateAddHTLC{
724767
PaymentHash: rhash,
725768
Amount: 1,
726769
}
727-
728770
err = s.SendHTLC(outgoingSCID, 0, htlc)
729-
require.NoError(t, err)
771+
772+
switch successOrFailureOption {
773+
case Success:
774+
require.NoError(t, err)
775+
case PeerOffline:
776+
require.EqualError(t, err, "TemporaryChannelFailure")
777+
case UnknownChannel:
778+
require.EqualError(t, err, "UnknownNextPeer")
779+
}
730780
}
731781

732782
// TestSwitchUpdateScid verifies that zero-conf and non-zero-conf

0 commit comments

Comments
 (0)