mirror of
https://github.com/lightningnetwork/lnd.git
synced 2025-08-28 06:32:18 +02:00
htlcswitch: add processRemoteUpdateFailHTLC
This commit is contained in:
@@ -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
|
||||
}
|
||||
|
Reference in New Issue
Block a user