htlcswitch: add processRemoteUpdateFailHTLC

This commit is contained in:
yyforyongyu
2025-06-30 21:38:13 +08:00
parent e883a51a63
commit ad1566ee3f

View File

@@ -1945,40 +1945,9 @@ func (l *channelLink) handleUpstreamMsg(ctx context.Context,
}
case *lnwire.UpdateFailHTLC:
// Verify that the failure reason is at least 256 bytes plus
// overhead.
const minimumFailReasonLength = lnwire.FailureMessageLength +
2 + 2 + 32
if len(msg.Reason) < minimumFailReasonLength {
// We've received a reason with a non-compliant length.
// Older nodes happily relay back these failures that
// may originate from a node further downstream.
// Therefore we can't just fail the channel.
//
// We want to be compliant ourselves, so we also can't
// pass back the reason unmodified. And we must make
// sure that we don't hit the magic length check of 260
// bytes in processRemoteSettleFails either.
//
// Because the reason is unreadable for the payer
// anyway, we just replace it by a compliant-length
// series of random bytes.
msg.Reason = make([]byte, minimumFailReasonLength)
_, err := crand.Read(msg.Reason[:])
if err != nil {
l.log.Errorf("Random generation error: %v", err)
return
}
}
// Add fail to the update log.
idx := msg.ID
err := l.channel.ReceiveFailHTLC(idx, msg.Reason[:])
err := l.processRemoteUpdateFailHTLC(msg)
if err != nil {
l.failf(LinkFailureError{code: ErrInvalidUpdate},
"unable to handle upstream fail HTLC: %v", err)
l.log.Errorf("failed to process remote fail: %v", err)
return
}
@@ -4684,3 +4653,44 @@ func (l *channelLink) processRemoteUpdateFailMalformedHTLC(
return nil
}
// processRemoteUpdateFailHTLC takes an `UpdateFailHTLC` msg sent from the
// remote and processes it.
func (l *channelLink) processRemoteUpdateFailHTLC(
msg *lnwire.UpdateFailHTLC) error {
// Verify that the failure reason is at least 256 bytes plus overhead.
const minimumFailReasonLength = lnwire.FailureMessageLength + 2 + 2 + 32
if len(msg.Reason) < minimumFailReasonLength {
// We've received a reason with a non-compliant length. Older
// nodes happily relay back these failures that may originate
// from a node further downstream. Therefore we can't just fail
// the channel.
//
// We want to be compliant ourselves, so we also can't pass back
// the reason unmodified. And we must make sure that we don't
// hit the magic length check of 260 bytes in
// processRemoteSettleFails either.
//
// Because the reason is unreadable for the payer anyway, we
// just replace it by a compliant-length series of random bytes.
msg.Reason = make([]byte, minimumFailReasonLength)
_, err := crand.Read(msg.Reason[:])
if err != nil {
return fmt.Errorf("random generation error: %w", err)
}
}
// Add fail to the update log.
idx := msg.ID
err := l.channel.ReceiveFailHTLC(idx, msg.Reason[:])
if err != nil {
l.failf(LinkFailureError{code: ErrInvalidUpdate},
"unable to handle upstream fail HTLC: %v", err)
return err
}
return nil
}