Skip to content

Commit 3d63d2e

Browse files
htlcswitch: adding temporary_channel_failure
This commit modifies the behaviour when a node can't forward an HTLC due to a temporary channel failure. Rather than return unknown_next_peer which instructs the sender to fully remove the channel from the graph temporary_channel_failure gives the sender the change to handle it more gracefully. We also return the latest channel update to the sender.
1 parent 4cc4bbc commit 3d63d2e

2 files changed

Lines changed: 27 additions & 6 deletions

File tree

htlcswitch/switch.go

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2671,6 +2671,25 @@ func (s *Switch) failMailboxUpdate(outgoingScid,
26712671
return lnwire.NewTemporaryChannelFailure(update)
26722672
}
26732673

2674+
// temporaryChannelFailure constructs a temporary_channel_failure for the given
2675+
// outgoing SCID. It attempts to include the latest channel update so the
2676+
// sender can immediately update their routing graph. If no update is
2677+
// available it falls back to FailTemporaryNodeFailure.
2678+
func (s *Switch) temporaryChannelFailure(
2679+
scid lnwire.ShortChannelID) lnwire.FailureMessage {
2680+
2681+
update := s.failAliasUpdate(scid, false)
2682+
if update == nil {
2683+
var err error
2684+
update, err = s.cfg.FetchLastChannelUpdate(scid)
2685+
if err != nil {
2686+
return &lnwire.FailTemporaryNodeFailure{}
2687+
}
2688+
}
2689+
2690+
return lnwire.NewTemporaryChannelFailure(update)
2691+
}
2692+
26742693
// failAliasUpdate prepares a ChannelUpdate for a failed incoming or outgoing
26752694
// HTLC on a channel where the option-scid-alias feature bit was negotiated. If
26762695
// the associated channel is not one of these, this function will return nil
@@ -2886,8 +2905,9 @@ func (s *Switch) handlePacketAdd(packet *htlcPacket,
28862905
log.Debugf("unable to find link with "+
28872906
"destination %v", packet.outgoingChanID)
28882907

2889-
// If packet was forwarded from another channel link than we
2890-
// should notify this link that some error occurred.
2908+
// The link was not found in the forwarding index — it has been
2909+
// removed (e.g. channel closed). Signal to the sender that the
2910+
// next hop is unknown.
28912911
linkError := NewLinkError(
28922912
&lnwire.FailUnknownNextPeer{},
28932913
)
@@ -2909,11 +2929,12 @@ func (s *Switch) handlePacketAdd(packet *htlcPacket,
29092929
for _, link := range interfaceLinks {
29102930
var failure *LinkError
29112931

2912-
// We'll skip any links that aren't yet eligible for
2913-
// forwarding.
2932+
// We'll skip any links that aren't yet eligible for forwarding.
2933+
// Use temporary_channel_failure with latest channel update so the
2934+
// sender can update their routing graph.
29142935
if !link.EligibleToForward() {
29152936
failure = NewDetailedLinkError(
2916-
&lnwire.FailUnknownNextPeer{},
2937+
s.temporaryChannelFailure(link.ShortChanID()),
29172938
OutgoingFailureLinkNotEligible,
29182939
)
29192940
} else {

htlcswitch/switch_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2143,7 +2143,7 @@ func TestSkipIneligibleLinksMultiHopForward(t *testing.T) {
21432143
// None of the channels is eligible.
21442144
{
21452145
name: "not eligible",
2146-
expectedReply: lnwire.CodeUnknownNextPeer,
2146+
expectedReply: lnwire.CodeTemporaryChannelFailure,
21472147
},
21482148

21492149
// Channel one has a policy failure and the other channel isn't

0 commit comments

Comments
 (0)