@@ -67,12 +67,12 @@ var (
6767
6868 // ErrValueMismatch is returned if we try to register a non-MPP attempt
6969 // with an amount that doesn't match the payment amount.
70- ErrValueMismatch = errors .New ("attempted value doesn't match payment" +
70+ ErrValueMismatch = errors .New ("attempted value doesn't match payment " +
7171 "amount" )
7272
7373 // ErrValueExceedsAmt is returned if we try to register an attempt that
7474 // would take the total sent amount above the payment amount.
75- ErrValueExceedsAmt = errors .New ("attempted value exceeds payment" +
75+ ErrValueExceedsAmt = errors .New ("attempted value exceeds payment " +
7676 "amount" )
7777
7878 // ErrNonMPPayment is returned if we try to register an MPP attempt for
8383 // a payment that already has an MPP attempt registered.
8484 ErrMPPayment = errors .New ("payment has MPP attempts" )
8585
86+ // ErrMPPRecordInBlindedPayment is returned if we try to register an
87+ // attempt with an MPP record for a payment to a blinded path.
88+ ErrMPPRecordInBlindedPayment = errors .New ("blinded payment cannot " +
89+ "contain MPP records" )
90+
91+ // ErrBlindedPaymentTotalAmountMismatch is returned if we try to
92+ // register an HTLC shard to a blinded route where the total amount
93+ // doesn't match existing shards.
94+ ErrBlindedPaymentTotalAmountMismatch = errors .New ("blinded path " +
95+ "total amount mismatch" )
96+
8697 // ErrMPPPaymentAddrMismatch is returned if we try to register an MPP
8798 // shard where the payment address doesn't match existing shards.
8899 ErrMPPPaymentAddrMismatch = errors .New ("payment address mismatch" )
96107 // attempt to a payment that has at least one of its HTLCs settled.
97108 ErrPaymentPendingSettled = errors .New ("payment has settled htlcs" )
98109
99- // ErrPaymentAlreadyFailed is returned when we try to add a new attempt
110+ // ErrPaymentPendingFailed is returned when we try to add a new attempt
100111 // to a payment that already has a failure reason.
101112 ErrPaymentPendingFailed = errors .New ("payment has failure reason" )
102113
@@ -334,12 +345,48 @@ func (p *PaymentControl) RegisterAttempt(paymentHash lntypes.Hash,
334345 return err
335346 }
336347
348+ // If the final hop has encrypted data, then we know this is a
349+ // blinded payment. In blinded payments, MPP records are not set
350+ // for split payments and the recipient is responsible for using
351+ // a consistent PathID across the various encrypted data
352+ // payloads that we received from them for this payment. All we
353+ // need to check is that the total amount field for each HTLC
354+ // in the split payment is correct.
355+ isBlinded := len (attempt .Route .FinalHop ().EncryptedData ) != 0
356+
337357 // Make sure any existing shards match the new one with regards
338358 // to MPP options.
339359 mpp := attempt .Route .FinalHop ().MPP
360+
361+ // MPP records should not be set for attempts to blinded paths.
362+ if isBlinded && mpp != nil {
363+ return ErrMPPRecordInBlindedPayment
364+ }
365+
340366 for _ , h := range payment .InFlightHTLCs () {
341367 hMpp := h .Route .FinalHop ().MPP
342368
369+ // If this is a blinded payment, then no existing HTLCs
370+ // should have MPP records.
371+ if isBlinded && hMpp != nil {
372+ return ErrMPPRecordInBlindedPayment
373+ }
374+
375+ // If this is a blinded payment, then we just need to
376+ // check that the TotalAmtMsat field for this shard
377+ // is equal to that of any other shard in the same
378+ // payment.
379+ if isBlinded {
380+ if attempt .Route .FinalHop ().TotalAmtMsat !=
381+ h .Route .FinalHop ().TotalAmtMsat {
382+
383+ //nolint:lll
384+ return ErrBlindedPaymentTotalAmountMismatch
385+ }
386+
387+ continue
388+ }
389+
343390 switch {
344391 // We tried to register a non-MPP attempt for a MPP
345392 // payment.
@@ -367,9 +414,10 @@ func (p *PaymentControl) RegisterAttempt(paymentHash lntypes.Hash,
367414 }
368415
369416 // If this is a non-MPP attempt, it must match the total amount
370- // exactly.
417+ // exactly. Note that a blinded payment is considered an MPP
418+ // attempt.
371419 amt := attempt .Route .ReceiverAmt ()
372- if mpp == nil && amt != payment .Info .Value {
420+ if ! isBlinded && mpp == nil && amt != payment .Info .Value {
373421 return ErrValueMismatch
374422 }
375423
0 commit comments