@@ -1793,8 +1793,20 @@ func (l *channelLink) handleDownstreamPkt(pkt *htlcPacket) {
17931793 htlc .ID = pkt .incomingHTLCID
17941794
17951795 // We send the HTLC message to the peer which initially created
1796- // the HTLC.
1797- l .cfg .Peer .SendMessage (false , htlc )
1796+ // the HTLC. If the incoming blinding point is non-nil, we
1797+ // know that we are a relaying node in a blinded path.
1798+ // Otherwise, we're either an introduction node or not part of
1799+ // a blinded path at all.
1800+ if err := l .sendIncomingHTLCFailureMsg (
1801+ htlc .ID ,
1802+ pkt .obfuscator ,
1803+ htlc .Reason ,
1804+ ); err != nil {
1805+ l .log .Errorf ("unable to send HTLC failure: %v" ,
1806+ err )
1807+
1808+ return
1809+ }
17981810
17991811 // If the packet does not have a link failure set, it failed
18001812 // further down the route so we notify a forwarding failure.
@@ -3720,11 +3732,14 @@ func (l *channelLink) sendHTLCError(pd *lnwallet.PaymentDescriptor,
37203732 return
37213733 }
37223734
3723- l .cfg .Peer .SendMessage (false , & lnwire.UpdateFailHTLC {
3724- ChanID : l .ChanID (),
3725- ID : pd .HtlcIndex ,
3726- Reason : reason ,
3727- })
3735+ // Send the appropriate failure message depending on whether we're
3736+ // in a blinded route or not.
3737+ if err := l .sendIncomingHTLCFailureMsg (
3738+ pd .HtlcIndex , e , reason ,
3739+ ); err != nil {
3740+ l .log .Errorf ("unable to send HTLC failure: %v" , err )
3741+ return
3742+ }
37283743
37293744 // Notify a link failure on our incoming link. Outgoing htlc information
37303745 // is not available at this point, because we have not decrypted the
@@ -3753,6 +3768,95 @@ func (l *channelLink) sendHTLCError(pd *lnwallet.PaymentDescriptor,
37533768 )
37543769}
37553770
3771+ // sendPeerHTLCFailure handles sending a HTLC failure message back to the
3772+ // peer from which the HTLC was received. This function is primarily used to
3773+ // handle the special requirements of route blinding, specifically:
3774+ // - Forwarding nodes must switch out any errors with MalformedFailHTLC
3775+ // - Introduction nodes should return regular HTLC failure messages.
3776+ //
3777+ // It accepts the original opaque failure, which will be used in the case
3778+ // that we're not part of a blinded route and an error encrypter that'll be
3779+ // used if we are the introduction node and need to present an error as if
3780+ // we're the failing party.
3781+ //
3782+ // Note: this function does not yet handle special error cases for receiving
3783+ // nodes in blinded paths, as LND does not support blinded receives.
3784+ func (l * channelLink ) sendIncomingHTLCFailureMsg (htlcIndex uint64 ,
3785+ e hop.ErrorEncrypter ,
3786+ originalFailure lnwire.OpaqueReason ) error {
3787+
3788+ var msg lnwire.Message
3789+ switch {
3790+ // Our circuit's error encrypter will be nil if this was a locally
3791+ // initiated payment. We can only hit a blinded error for a locally
3792+ // initiated payment if we allow ourselves to be picked as the
3793+ // introduction node for our own payments and in that case we
3794+ // shouldn't reach this code. To prevent the HTLC getting stuck,
3795+ // we fail it back and log an error.
3796+ // code.
3797+ case e == nil :
3798+ msg = & lnwire.UpdateFailHTLC {
3799+ ChanID : l .ChanID (),
3800+ ID : htlcIndex ,
3801+ Reason : originalFailure ,
3802+ }
3803+
3804+ l .log .Errorf ("Unexpected blinded failure when " +
3805+ "we are the sending node, incoming htlc: %v(%v)" ,
3806+ l .ShortChanID (), htlcIndex )
3807+
3808+ // For cleartext hops (ie, non-blinded/normal) we don't need any
3809+ // transformation on the error message and can just send the original.
3810+ case ! e .Type ().IsBlinded ():
3811+ msg = & lnwire.UpdateFailHTLC {
3812+ ChanID : l .ChanID (),
3813+ ID : htlcIndex ,
3814+ Reason : originalFailure ,
3815+ }
3816+
3817+ // When we're the introduction node, we need to convert the error to
3818+ // a UpdateFailHTLC.
3819+ case e .Type () == hop .EncrypterTypeIntroduction :
3820+ l .log .Debugf ("Introduction blinded node switching out failure " +
3821+ "error: %v" , htlcIndex )
3822+
3823+ // The specification does not require that we set the onion
3824+ // blob.
3825+ failureMsg := lnwire .NewInvalidBlinding (nil )
3826+ reason , err := e .EncryptFirstHop (failureMsg )
3827+ if err != nil {
3828+ return err
3829+ }
3830+
3831+ msg = & lnwire.UpdateFailHTLC {
3832+ ChanID : l .ChanID (),
3833+ ID : htlcIndex ,
3834+ Reason : reason ,
3835+ }
3836+
3837+ // If we are a relaying node, we need to switch out any error that
3838+ // we've received to a malformed HTLC error.
3839+ case e .Type () == hop .EncrypterTypeRelaying :
3840+ l .log .Debugf ("Relaying blinded node switching out malformed " +
3841+ "error: %v" , htlcIndex )
3842+
3843+ msg = & lnwire.UpdateFailMalformedHTLC {
3844+ ChanID : l .ChanID (),
3845+ ID : htlcIndex ,
3846+ FailureCode : lnwire .CodeInvalidBlinding ,
3847+ }
3848+
3849+ default :
3850+ return fmt .Errorf ("unexpected encrypter: %d" , e )
3851+ }
3852+
3853+ if err := l .cfg .Peer .SendMessage (false , msg ); err != nil {
3854+ l .log .Warnf ("Send update fail failed: %v" , err )
3855+ }
3856+
3857+ return nil
3858+ }
3859+
37563860// sendMalformedHTLCError helper function which sends the malformed HTLC update
37573861// to the payment sender.
37583862func (l * channelLink ) sendMalformedHTLCError (htlcIndex uint64 ,
0 commit comments