@@ -92,8 +92,8 @@ use core::ops::Deref;
9292pub ( super ) enum PendingHTLCRouting {
9393 Forward {
9494 onion_packet : msgs:: OnionPacket ,
95- /// The SCID from the onion that we should forward to. This could be a " real" SCID, an
96- /// outbound SCID alias, or a phantom node SCID .
95+ /// The SCID from the onion that we should forward to. This could be a real SCID or a fake one
96+ /// generated using `get_fake_scid` from the scid_utils::fake_scid module .
9797 short_channel_id : u64 , // This should be NonZero<u64> eventually when we bump MSRV
9898 } ,
9999 Receive {
@@ -683,6 +683,8 @@ pub type SimpleRefChannelManager<'a, 'b, 'c, 'd, 'e, M, T, F, L> = ChannelManage
683683// `total_consistency_lock`
684684// |
685685// |__`forward_htlcs`
686+ // | |
687+ // | |__`pending_intercepted_htlcs`
686688// |
687689// |__`pending_inbound_payments`
688690// | |
@@ -2223,8 +2225,10 @@ impl<M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelManager<M, T, K, F
22232225 let forwarding_id_opt = match id_option {
22242226 None => { // unknown_next_peer
22252227 // Note that this is likely a timing oracle for detecting whether an scid is a
2226- // phantom.
2227- if fake_scid:: is_valid_phantom ( & self . fake_scid_rand_bytes , * short_channel_id, & self . genesis_hash ) {
2228+ // phantom or an intercept.
2229+ if fake_scid:: is_valid_phantom ( & self . fake_scid_rand_bytes , * short_channel_id, & self . genesis_hash ) ||
2230+ fake_scid:: is_valid_intercept ( & self . fake_scid_rand_bytes , * short_channel_id, & self . genesis_hash )
2231+ {
22282232 None
22292233 } else {
22302234 break Some ( ( "Don't have available channel for forwarding as requested." , 0x4000 | 10 , None ) ) ;
@@ -5083,28 +5087,82 @@ impl<M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelManager<M, T, K, F
50835087 fn forward_htlcs ( & self , per_source_pending_forwards : & mut [ ( u64 , OutPoint , Vec < ( PendingHTLCInfo , u64 ) > ) ] ) {
50845088 for & mut ( prev_short_channel_id, prev_funding_outpoint, ref mut pending_forwards) in per_source_pending_forwards {
50855089 let mut forward_event = None ;
5090+ let mut new_intercept_events = Vec :: new ( ) ;
5091+ let mut failed_intercept_forwards = Vec :: new ( ) ;
50865092 if !pending_forwards. is_empty ( ) {
5087- let mut forward_htlcs = self . forward_htlcs . lock ( ) . unwrap ( ) ;
5088- if forward_htlcs. is_empty ( ) {
5089- forward_event = Some ( Duration :: from_millis ( MIN_HTLC_RELAY_HOLDING_CELL_MILLIS ) )
5090- }
50915093 for ( forward_info, prev_htlc_id) in pending_forwards. drain ( ..) {
5092- match forward_htlcs. entry ( match forward_info. routing {
5093- PendingHTLCRouting :: Forward { short_channel_id, .. } => short_channel_id,
5094- PendingHTLCRouting :: Receive { .. } => 0 ,
5095- PendingHTLCRouting :: ReceiveKeysend { .. } => 0 ,
5096- } ) {
5094+ let scid = match forward_info. routing {
5095+ PendingHTLCRouting :: Forward { short_channel_id, .. } => short_channel_id,
5096+ PendingHTLCRouting :: Receive { .. } => 0 ,
5097+ PendingHTLCRouting :: ReceiveKeysend { .. } => 0 ,
5098+ } ;
5099+ // Pull this now to avoid introducing a lock order with `forward_htlcs`.
5100+ let is_our_scid = self . short_to_chan_info . read ( ) . unwrap ( ) . contains_key ( & scid) ;
5101+
5102+ let mut forward_htlcs = self . forward_htlcs . lock ( ) . unwrap ( ) ;
5103+ let forward_htlcs_empty = forward_htlcs. is_empty ( ) ;
5104+ match forward_htlcs. entry ( scid) {
50975105 hash_map:: Entry :: Occupied ( mut entry) => {
50985106 entry. get_mut ( ) . push ( HTLCForwardInfo :: AddHTLC ( PendingAddHTLCInfo {
50995107 prev_short_channel_id, prev_funding_outpoint, prev_htlc_id, forward_info } ) ) ;
51005108 } ,
51015109 hash_map:: Entry :: Vacant ( entry) => {
5102- entry. insert ( vec ! ( HTLCForwardInfo :: AddHTLC ( PendingAddHTLCInfo {
5103- prev_short_channel_id, prev_funding_outpoint, prev_htlc_id, forward_info } ) ) ) ;
5110+ if !is_our_scid && forward_info. incoming_amt_msat . is_some ( ) &&
5111+ fake_scid:: is_valid_intercept ( & self . fake_scid_rand_bytes , scid, & self . genesis_hash )
5112+ {
5113+ let intercept_id = InterceptId ( Sha256 :: hash ( & forward_info. incoming_shared_secret ) . into_inner ( ) ) ;
5114+ let mut pending_intercepts = self . pending_intercepted_htlcs . lock ( ) . unwrap ( ) ;
5115+ match pending_intercepts. entry ( intercept_id) {
5116+ hash_map:: Entry :: Vacant ( entry) => {
5117+ new_intercept_events. push ( events:: Event :: HTLCIntercepted {
5118+ requested_next_hop_scid : scid,
5119+ payment_hash : forward_info. payment_hash ,
5120+ inbound_amount_msat : forward_info. incoming_amt_msat . unwrap ( ) ,
5121+ expected_outbound_amount_msat : forward_info. outgoing_amt_msat ,
5122+ intercept_id
5123+ } ) ;
5124+ entry. insert ( PendingAddHTLCInfo {
5125+ prev_short_channel_id, prev_funding_outpoint, prev_htlc_id, forward_info } ) ;
5126+ } ,
5127+ hash_map:: Entry :: Occupied ( _) => {
5128+ log_info ! ( self . logger, "Failed to forward incoming HTLC: detected duplicate intercepted payment over short channel id {}" , scid) ;
5129+ let htlc_source = HTLCSource :: PreviousHopData ( HTLCPreviousHopData {
5130+ short_channel_id : prev_short_channel_id,
5131+ outpoint : prev_funding_outpoint,
5132+ htlc_id : prev_htlc_id,
5133+ incoming_packet_shared_secret : forward_info. incoming_shared_secret ,
5134+ phantom_shared_secret : None ,
5135+ } ) ;
5136+
5137+ failed_intercept_forwards. push ( ( htlc_source, forward_info. payment_hash ,
5138+ HTLCFailReason :: Reason { failure_code : 0x4000 | 10 , data : Vec :: new ( ) } ,
5139+ HTLCDestination :: InvalidForward { requested_forward_scid : scid } ,
5140+ ) ) ;
5141+ }
5142+ }
5143+ } else {
5144+ // We don't want to generate a PendingHTLCsForwardable event if only intercepted
5145+ // payments are being processed.
5146+ if forward_htlcs_empty {
5147+ forward_event = Some ( Duration :: from_millis ( MIN_HTLC_RELAY_HOLDING_CELL_MILLIS ) ) ;
5148+ }
5149+ entry. insert ( vec ! ( HTLCForwardInfo :: AddHTLC ( PendingAddHTLCInfo {
5150+ prev_short_channel_id, prev_funding_outpoint, prev_htlc_id, forward_info } ) ) ) ;
5151+ }
51045152 }
51055153 }
51065154 }
51075155 }
5156+
5157+ for ( htlc_source, payment_hash, failure_reason, destination) in failed_intercept_forwards. drain ( ..) {
5158+ self . fail_htlc_backwards_internal ( htlc_source, & payment_hash, failure_reason, destination) ;
5159+ }
5160+
5161+ if !new_intercept_events. is_empty ( ) {
5162+ let mut events = self . pending_events . lock ( ) . unwrap ( ) ;
5163+ events. append ( & mut new_intercept_events) ;
5164+ }
5165+
51085166 match forward_event {
51095167 Some ( time) => {
51105168 let mut pending_events = self . pending_events . lock ( ) . unwrap ( ) ;
0 commit comments