@@ -26,7 +26,7 @@ use crate::ln::channel::FUNDING_CONF_DEADLINE_BLOCKS;
26
26
use crate :: offers:: invoice:: Bolt12Invoice ;
27
27
use crate :: offers:: static_invoice:: StaticInvoice ;
28
28
use crate :: types:: features:: ChannelTypeFeatures ;
29
- use crate :: ln:: msgs;
29
+ use crate :: ln:: { msgs, LocalHTLCFailureReason } ;
30
30
use crate :: ln:: types:: ChannelId ;
31
31
use crate :: types:: payment:: { PaymentPreimage , PaymentHash , PaymentSecret } ;
32
32
use crate :: onion_message:: messenger:: Responder ;
@@ -466,12 +466,12 @@ impl_writeable_tlv_based_enum_upgradable!(ClosureReason,
466
466
} ,
467
467
) ;
468
468
469
- /// Intended destination of a failed HTLC as indicated in [`Event::HTLCHandlingFailed`].
469
+ /// The type of HTLC handling performed in [`Event::HTLCHandlingFailed`].
470
470
#[ derive( Clone , Debug , PartialEq , Eq ) ]
471
- pub enum HTLCDestination {
471
+ pub enum HTLCHandlingFailureType {
472
472
/// We tried forwarding to a channel but failed to do so. An example of such an instance is when
473
473
/// there is insufficient capacity in our outbound channel.
474
- NextHopChannel {
474
+ Forward {
475
475
/// The `node_id` of the next node. For backwards compatibility, this field is
476
476
/// marked as optional, versions prior to 0.0.110 may not always be able to provide
477
477
/// counterparty node information.
@@ -480,12 +480,17 @@ pub enum HTLCDestination {
480
480
channel_id : ChannelId ,
481
481
} ,
482
482
/// Scenario where we are unsure of the next node to forward the HTLC to.
483
+ ///
484
+ /// Deprecated: will only be used in versions before LDK v0.2.0. Downgrades will result in
485
+ /// this type being represented as [`Self::InvalidForward`].
483
486
UnknownNextHop {
484
487
/// Short channel id we are requesting to forward an HTLC to.
485
488
requested_forward_scid : u64 ,
486
489
} ,
487
490
/// We couldn't forward to the outgoing scid. An example would be attempting to send a duplicate
488
491
/// intercept HTLC.
492
+ ///
493
+ /// In LDK v0.2.0 and greater, this variant replaces [`Self::UnknownNextHop`].
489
494
InvalidForward {
490
495
/// Short channel id we are requesting to forward an HTLC to.
491
496
requested_forward_scid : u64
@@ -502,14 +507,14 @@ pub enum HTLCDestination {
502
507
/// * The counterparty node modified the HTLC in transit,
503
508
/// * A probing attack where an intermediary node is trying to detect if we are the ultimate
504
509
/// recipient for a payment.
505
- FailedPayment {
510
+ Receive {
506
511
/// The payment hash of the payment we attempted to process.
507
512
payment_hash : PaymentHash
508
513
} ,
509
514
}
510
515
511
- impl_writeable_tlv_based_enum_upgradable ! ( HTLCDestination ,
512
- ( 0 , NextHopChannel ) => {
516
+ impl_writeable_tlv_based_enum_upgradable ! ( HTLCHandlingFailureType ,
517
+ ( 0 , Forward ) => {
513
518
( 0 , node_id, required) ,
514
519
( 2 , channel_id, required) ,
515
520
} ,
@@ -520,11 +525,36 @@ impl_writeable_tlv_based_enum_upgradable!(HTLCDestination,
520
525
( 0 , requested_forward_scid, required) ,
521
526
} ,
522
527
( 3 , InvalidOnion ) => { } ,
523
- ( 4 , FailedPayment ) => {
528
+ ( 4 , Receive ) => {
524
529
( 0 , payment_hash, required) ,
525
530
} ,
526
531
) ;
527
532
533
+ /// The reason for HTLC failures in [`Event::HTLCHandlingFailed`].
534
+ #[ derive( Clone , Debug , PartialEq , Eq ) ]
535
+ pub enum HTLCHandlingFailureReason {
536
+ /// The forwarded HTLC was failed back by the downstream node with an encrypted error reason.
537
+ Downstream ,
538
+ /// The HTLC was failed locally by our node.
539
+ Local {
540
+ /// The reason that our node chose to fail the HTLC.
541
+ reason : LocalHTLCFailureReason ,
542
+ } ,
543
+ }
544
+
545
+ impl_writeable_tlv_based_enum ! ( HTLCHandlingFailureReason ,
546
+ ( 1 , Downstream ) => { } ,
547
+ ( 3 , Local ) => {
548
+ ( 0 , reason, required) ,
549
+ } ,
550
+ ) ;
551
+
552
+ impl From < LocalHTLCFailureReason > for HTLCHandlingFailureReason {
553
+ fn from ( value : LocalHTLCFailureReason ) -> Self {
554
+ HTLCHandlingFailureReason :: Local { reason : value }
555
+ }
556
+ }
557
+
528
558
/// Will be used in [`Event::HTLCIntercepted`] to identify the next hop in the HTLC's path.
529
559
/// Currently only used in serialization for the sake of maintaining compatibility. More variants
530
560
/// will be added for general-purpose HTLC forward intercepts as well as trampoline forward
@@ -1460,8 +1490,12 @@ pub enum Event {
1460
1490
HTLCHandlingFailed {
1461
1491
/// The channel over which the HTLC was received.
1462
1492
prev_channel_id : ChannelId ,
1463
- /// Destination of the HTLC that failed to be processed.
1464
- failed_next_destination : HTLCDestination ,
1493
+ /// The type of HTLC handling that failed.
1494
+ failure_type : HTLCHandlingFailureType ,
1495
+ /// The reason that the HTLC failed.
1496
+ ///
1497
+ /// This field will be `None` only for objects serialized prior to LDK 0.2.0.
1498
+ failure_reason : Option < HTLCHandlingFailureReason >
1465
1499
} ,
1466
1500
/// Indicates that a transaction originating from LDK needs to have its fee bumped. This event
1467
1501
/// requires confirmed external funds to be readily available to spend.
@@ -1766,11 +1800,12 @@ impl Writeable for Event {
1766
1800
( 8 , path. blinded_tail, option) ,
1767
1801
} )
1768
1802
} ,
1769
- & Event :: HTLCHandlingFailed { ref prev_channel_id, ref failed_next_destination } => {
1803
+ & Event :: HTLCHandlingFailed { ref prev_channel_id, ref failure_type , ref failure_reason } => {
1770
1804
25u8 . write ( writer) ?;
1771
1805
write_tlv_fields ! ( writer, {
1772
1806
( 0 , prev_channel_id, required) ,
1773
- ( 2 , failed_next_destination, required) ,
1807
+ ( 1 , failure_reason, option) ,
1808
+ ( 2 , failure_type, required) ,
1774
1809
} )
1775
1810
} ,
1776
1811
& Event :: BumpTransaction ( ref event) => {
@@ -2218,14 +2253,24 @@ impl MaybeReadable for Event {
2218
2253
25u8 => {
2219
2254
let mut f = || {
2220
2255
let mut prev_channel_id = ChannelId :: new_zero ( ) ;
2221
- let mut failed_next_destination_opt = UpgradableRequired ( None ) ;
2256
+ let mut failure_reason = None ;
2257
+ let mut failure_type_opt = UpgradableRequired ( None ) ;
2222
2258
read_tlv_fields ! ( reader, {
2223
2259
( 0 , prev_channel_id, required) ,
2224
- ( 2 , failed_next_destination_opt, upgradable_required) ,
2260
+ ( 1 , failure_reason, option) ,
2261
+ ( 2 , failure_type_opt, upgradable_required) ,
2225
2262
} ) ;
2263
+
2264
+ // If a legacy HTLCHandlingFailureType::UnknownNextHop was written, upgrade
2265
+ // it to its new representation, otherwise leave unchanged.
2266
+ if let Some ( HTLCHandlingFailureType :: UnknownNextHop { requested_forward_scid } ) = failure_type_opt. 0 {
2267
+ failure_type_opt. 0 = Some ( HTLCHandlingFailureType :: InvalidForward { requested_forward_scid } ) ;
2268
+ failure_reason = Some ( LocalHTLCFailureReason :: UnknownNextPeer . into ( ) ) ;
2269
+ }
2226
2270
Ok ( Some ( Event :: HTLCHandlingFailed {
2227
2271
prev_channel_id,
2228
- failed_next_destination : _init_tlv_based_struct_field ! ( failed_next_destination_opt, upgradable_required) ,
2272
+ failure_type : _init_tlv_based_struct_field ! ( failure_type_opt, upgradable_required) ,
2273
+ failure_reason
2229
2274
} ) )
2230
2275
} ;
2231
2276
f ( )
0 commit comments