@@ -3491,21 +3491,63 @@ where
3491
3491
/// [`events::Event::PaymentClaimed`] events even for payments you intend to fail, especially on
3492
3492
/// startup during which time claims that were in-progress at shutdown may be replayed.
3493
3493
pub fn fail_htlc_backwards ( & self , payment_hash : & PaymentHash ) {
3494
+ self . fail_htlc_backwards_with_reason ( payment_hash, & FailureCode :: IncorrectOrUnknownPaymentDetails ) ;
3495
+ }
3496
+
3497
+ /// This is a variant of [`ChannelManager::fail_htlc_backwards`] that allows you to specify the
3498
+ /// reason for the failure.
3499
+ ///
3500
+ /// See [`FailureCode`] for valid failure codes.
3501
+ pub fn fail_htlc_backwards_with_reason ( & self , payment_hash : & PaymentHash , failure_code : & FailureCode ) {
3494
3502
let _persistence_guard = PersistenceNotifierGuard :: notify_on_drop ( & self . total_consistency_lock , & self . persistence_notifier ) ;
3495
3503
3496
3504
let removed_source = self . claimable_payments . lock ( ) . unwrap ( ) . claimable_htlcs . remove ( payment_hash) ;
3497
3505
if let Some ( ( _, mut sources) ) = removed_source {
3498
3506
for htlc in sources. drain ( ..) {
3499
- let mut htlc_msat_height_data = htlc. value . to_be_bytes ( ) . to_vec ( ) ;
3500
- htlc_msat_height_data. extend_from_slice ( & self . best_block . read ( ) . unwrap ( ) . height ( ) . to_be_bytes ( ) ) ;
3501
- let source = HTLCSource :: PreviousHopData ( htlc. prev_hop ) ;
3502
- let reason = HTLCFailReason :: reason ( 0x4000 | 15 , htlc_msat_height_data) ;
3507
+ let source = HTLCSource :: PreviousHopData ( htlc. prev_hop . clone ( ) ) ;
3503
3508
let receiver = HTLCDestination :: FailedPayment { payment_hash : * payment_hash } ;
3509
+
3510
+ let reason = match failure_code {
3511
+ FailureCode :: TemporaryNodeFailure => HTLCFailReason :: from_failure_code ( * failure_code as u16 ) ,
3512
+ FailureCode :: RequiredNodeFeatureMissing => HTLCFailReason :: from_failure_code ( * failure_code as u16 ) ,
3513
+ FailureCode :: ExpiryTooSoon => {
3514
+ let short_channel_id = htlc. prev_hop . short_channel_id ;
3515
+ let ( counterparty_node_id, chan_id) = self . short_to_chan_info . read ( ) . unwrap ( ) . get ( & short_channel_id) . cloned ( ) . unwrap ( ) ;
3516
+ let per_peer_state = self . per_peer_state . read ( ) . unwrap ( ) ;
3517
+ let peer_state = per_peer_state. get ( & counterparty_node_id) . unwrap ( ) . lock ( ) . unwrap ( ) ;
3518
+ let chan = peer_state. channel_by_id . get ( & chan_id) . unwrap ( ) ;
3519
+ let channel_update = self . get_channel_update_for_onion ( short_channel_id, chan) . unwrap ( ) ;
3520
+ let mut channel_update_data = Vec :: new ( ) ;
3521
+ ( channel_update. serialized_length ( ) as u16 + 2 ) . write ( & mut channel_update_data) . expect ( "Writes cannot fail" ) ;
3522
+ msgs:: ChannelUpdate :: TYPE . write ( & mut channel_update_data) . expect ( "Writes cannot fail" ) ;
3523
+ channel_update. write ( & mut channel_update_data) . expect ( "Writes cannot fail" ) ;
3524
+ HTLCFailReason :: reason ( * failure_code as u16 , channel_update_data)
3525
+ } ,
3526
+ FailureCode :: IncorrectOrUnknownPaymentDetails => {
3527
+ let mut htlc_msat_height_data = htlc. value . to_be_bytes ( ) . to_vec ( ) ;
3528
+ htlc_msat_height_data. extend_from_slice ( & self . best_block . read ( ) . unwrap ( ) . height ( ) . to_be_bytes ( ) ) ;
3529
+ HTLCFailReason :: reason ( * failure_code as u16 , htlc_msat_height_data)
3530
+ }
3531
+ } ;
3532
+
3504
3533
self . fail_htlc_backwards_internal ( & source, & payment_hash, & reason, receiver) ;
3505
3534
}
3506
3535
}
3507
3536
}
3508
3537
3538
+ /// Gets error data to form an [`HTLCFailReason`] given a [`FailureCode`] and [`ClaimableHTLC`].
3539
+ fn get_htlc_fail_reason_from_failure_code ( & self , failure_code : & FailureCode , htlc : & ClaimableHTLC ) -> HTLCFailReason {
3540
+ match failure_code {
3541
+ FailureCode :: TemporaryNodeFailure => HTLCFailReason :: from_failure_code ( * failure_code as u16 ) ,
3542
+ FailureCode :: RequiredNodeFeatureMissing => HTLCFailReason :: from_failure_code ( * failure_code as u16 ) ,
3543
+ FailureCode :: IncorrectOrUnknownPaymentDetails => {
3544
+ let mut htlc_msat_height_data = htlc. value . to_be_bytes ( ) . to_vec ( ) ;
3545
+ htlc_msat_height_data. extend_from_slice ( & self . best_block . read ( ) . unwrap ( ) . height ( ) . to_be_bytes ( ) ) ;
3546
+ HTLCFailReason :: reason ( * failure_code as u16 , htlc_msat_height_data)
3547
+ }
3548
+ }
3549
+ }
3550
+
3509
3551
/// Gets an HTLC onion failure code and error data for an `UPDATE` error, given the error code
3510
3552
/// that we want to return and a channel.
3511
3553
///
0 commit comments