@@ -696,6 +696,8 @@ pub type SimpleRefChannelManager<'a, 'b, 'c, 'd, 'e, M, T, F, L> = ChannelManage
696
696
// | |__`id_to_peer`
697
697
// | |
698
698
// | |__`short_to_chan_info`
699
+ // | | |
700
+ // | | |__`pending_intercepted_payments`
699
701
// | |
700
702
// | |__`per_peer_state`
701
703
// | |
@@ -2334,8 +2336,10 @@ impl<M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelManager<M, T, K, F
2334
2336
let forwarding_id_opt = match id_option {
2335
2337
None => { // unknown_next_peer
2336
2338
// Note that this is likely a timing oracle for detecting whether an scid is a
2337
- // phantom.
2338
- if fake_scid:: is_valid_phantom ( & self . fake_scid_rand_bytes , * short_channel_id) {
2339
+ // phantom or an intercept.
2340
+ if fake_scid:: is_valid_phantom ( & self . fake_scid_rand_bytes , * short_channel_id) ||
2341
+ fake_scid:: is_valid_intercept ( & self . fake_scid_rand_bytes , * short_channel_id)
2342
+ {
2339
2343
None
2340
2344
} else {
2341
2345
break Some ( ( "Don't have available channel for forwarding as requested." , 0x4000 | 10 , None ) ) ;
@@ -5115,28 +5119,81 @@ impl<M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelManager<M, T, K, F
5115
5119
fn forward_htlcs ( & self , per_source_pending_forwards : & mut [ ( u64 , OutPoint , Vec < ( PendingHTLCInfo , u64 ) > ) ] ) {
5116
5120
for & mut ( prev_short_channel_id, prev_funding_outpoint, ref mut pending_forwards) in per_source_pending_forwards {
5117
5121
let mut forward_event = None ;
5122
+ let mut new_intercept_events = Vec :: new ( ) ;
5123
+ let mut failed_intercept_forwards = Vec :: new ( ) ;
5118
5124
if !pending_forwards. is_empty ( ) {
5119
5125
let mut forward_htlcs = self . forward_htlcs . lock ( ) . unwrap ( ) ;
5120
- if forward_htlcs. is_empty ( ) {
5121
- forward_event = Some ( Duration :: from_millis ( MIN_HTLC_RELAY_HOLDING_CELL_MILLIS ) )
5122
- }
5126
+ let short_to_chan_info = self . short_to_chan_info . read ( ) . unwrap ( ) ;
5123
5127
for ( forward_info, prev_htlc_id) in pending_forwards. drain ( ..) {
5124
- match forward_htlcs. entry ( match forward_info. routing {
5125
- PendingHTLCRouting :: Forward { short_channel_id, .. } => short_channel_id,
5126
- PendingHTLCRouting :: Receive { .. } => 0 ,
5127
- PendingHTLCRouting :: ReceiveKeysend { .. } => 0 ,
5128
- } ) {
5128
+ let scid = match forward_info. routing {
5129
+ PendingHTLCRouting :: Forward { short_channel_id, .. } => short_channel_id,
5130
+ PendingHTLCRouting :: Receive { .. } => 0 ,
5131
+ PendingHTLCRouting :: ReceiveKeysend { .. } => 0 ,
5132
+ } ;
5133
+ let forward_htlcs_empty = forward_htlcs. is_empty ( ) ;
5134
+ match forward_htlcs. entry ( scid) {
5129
5135
hash_map:: Entry :: Occupied ( mut entry) => {
5130
5136
entry. get_mut ( ) . push ( HTLCForwardInfo :: AddHTLC ( PendingAddHTLCInfo {
5131
5137
prev_short_channel_id, prev_funding_outpoint, prev_htlc_id, forward_info } ) ) ;
5132
5138
} ,
5133
5139
hash_map:: Entry :: Vacant ( entry) => {
5134
- entry. insert ( vec ! ( HTLCForwardInfo :: AddHTLC ( PendingAddHTLCInfo {
5135
- prev_short_channel_id, prev_funding_outpoint, prev_htlc_id, forward_info } ) ) ) ;
5140
+ if !short_to_chan_info. contains_key ( & scid) &&
5141
+ forward_info. amt_incoming . is_some ( ) &&
5142
+ fake_scid:: is_valid_intercept ( & self . fake_scid_rand_bytes , scid)
5143
+ {
5144
+ let intercept_id = InterceptId ( Sha256 :: hash ( & forward_info. incoming_shared_secret ) . into_inner ( ) ) ;
5145
+ let mut pending_intercepts = self . pending_intercepted_payments . lock ( ) . unwrap ( ) ;
5146
+ match pending_intercepts. entry ( intercept_id) {
5147
+ hash_map:: Entry :: Vacant ( entry) => {
5148
+ new_intercept_events. push ( events:: Event :: PaymentIntercepted {
5149
+ short_channel_id : scid,
5150
+ payment_hash : forward_info. payment_hash ,
5151
+ inbound_amount_msat : forward_info. amt_incoming . unwrap ( ) ,
5152
+ expected_outbound_amount_msat : forward_info. amt_to_forward ,
5153
+ intercept_id
5154
+ } ) ;
5155
+ entry. insert ( PendingAddHTLCInfo {
5156
+ prev_short_channel_id, prev_funding_outpoint, prev_htlc_id, forward_info } ) ;
5157
+ } ,
5158
+ hash_map:: Entry :: Occupied ( _) => {
5159
+ log_info ! ( self . logger, "Failed to forward incoming HTLC: detected duplicate intercepted payment over short channel id {}" , scid) ;
5160
+ let htlc_source = HTLCSource :: PreviousHopData ( HTLCPreviousHopData {
5161
+ short_channel_id : prev_short_channel_id,
5162
+ outpoint : prev_funding_outpoint,
5163
+ htlc_id : prev_htlc_id,
5164
+ incoming_packet_shared_secret : forward_info. incoming_shared_secret ,
5165
+ phantom_shared_secret : None ,
5166
+ } ) ;
5167
+
5168
+ failed_intercept_forwards. push ( ( htlc_source, forward_info. payment_hash ,
5169
+ HTLCFailReason :: Reason { failure_code : 0x4000 | 10 , data : Vec :: new ( ) } ,
5170
+ HTLCDestination :: UnknownNextHop { requested_forward_scid : scid } ,
5171
+ ) ) ;
5172
+ }
5173
+ }
5174
+ } else {
5175
+ // We don't want to generate a PendingHTLCsForwardable event if only intercepted
5176
+ // payments are being forwarded.
5177
+ if forward_htlcs_empty {
5178
+ forward_event = Some ( Duration :: from_millis ( MIN_HTLC_RELAY_HOLDING_CELL_MILLIS ) ) ;
5179
+ }
5180
+ entry. insert ( vec ! ( HTLCForwardInfo :: AddHTLC ( PendingAddHTLCInfo {
5181
+ prev_short_channel_id, prev_funding_outpoint, prev_htlc_id, forward_info } ) ) ) ;
5182
+ }
5136
5183
}
5137
5184
}
5138
5185
}
5139
5186
}
5187
+
5188
+ for ( htlc_source, payment_hash, failure_reason, destination) in failed_intercept_forwards. drain ( ..) {
5189
+ self . fail_htlc_backwards_internal ( htlc_source, & payment_hash, failure_reason, destination) ;
5190
+ }
5191
+
5192
+ if !new_intercept_events. is_empty ( ) {
5193
+ let mut events = self . pending_events . lock ( ) . unwrap ( ) ;
5194
+ events. append ( & mut new_intercept_events) ;
5195
+ }
5196
+
5140
5197
match forward_event {
5141
5198
Some ( time) => {
5142
5199
let mut pending_events = self . pending_events . lock ( ) . unwrap ( ) ;
0 commit comments