@@ -2198,6 +2198,10 @@ impl<ChanSigner: ChannelKeys, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>
2198
2198
/// ChannelMonitorUpdateErr::TemporaryFailures is fine. The highest_applied_update_id field
2199
2199
/// exists largely only to prevent races between this and concurrent update_monitor calls.
2200
2200
///
2201
+ /// XXX: Update to note re-entrancy - this is really terrible - the reentrancy only happens in
2202
+ /// a really rare case making it incredibly likely users will miss it and never hit it in
2203
+ /// testing.
2204
+ ///
2201
2205
/// Thus, the anticipated use is, at a high level:
2202
2206
/// 1) You register a chain::Watch with this ChannelManager,
2203
2207
/// 2) it stores each update to disk, and begins updating any remote (eg watchtower) copies of
@@ -2209,42 +2213,53 @@ impl<ChanSigner: ChannelKeys, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>
2209
2213
pub fn channel_monitor_updated ( & self , funding_txo : & OutPoint , highest_applied_update_id : u64 ) {
2210
2214
let _consistency_lock = self . total_consistency_lock . read ( ) . unwrap ( ) ;
2211
2215
2212
- let mut close_results = Vec :: new ( ) ;
2213
- let mut htlc_forwards = Vec :: new ( ) ;
2214
- let mut htlc_failures = Vec :: new ( ) ;
2215
- let mut pending_events = Vec :: new ( ) ;
2216
+ let mut htlc_forwards = None ;
2217
+ let mut htlc_failures ;
2218
+ let htlc_forwarding_failures ;
2219
+ let mut pending_event = None ;
2216
2220
2217
- {
2221
+ let ( counterparty_node_id , res ) = loop {
2218
2222
let mut channel_lock = self . channel_state . lock ( ) . unwrap ( ) ;
2219
2223
let channel_state = & mut * channel_lock;
2220
- let short_to_id = & mut channel_state. short_to_id ;
2221
2224
let pending_msg_events = & mut channel_state. pending_msg_events ;
2222
- let channel = match channel_state. by_id . get_mut ( & funding_txo. to_channel_id ( ) ) {
2223
- Some ( chan ) => chan ,
2224
- None => return ,
2225
+ let mut channel = match channel_state. by_id . entry ( funding_txo. to_channel_id ( ) ) {
2226
+ hash_map :: Entry :: Vacant ( _ ) => return ,
2227
+ hash_map :: Entry :: Occupied ( e ) => e ,
2225
2228
} ;
2226
- if !channel. is_awaiting_monitor_update ( ) || channel. get_latest_monitor_update_id ( ) != highest_applied_update_id {
2229
+ if !channel. get ( ) . is_awaiting_monitor_update ( ) || channel. get ( ) . get_latest_monitor_update_id ( ) != highest_applied_update_id {
2227
2230
return ;
2228
2231
}
2232
+ let counterparty_node_id = channel. get ( ) . get_counterparty_node_id ( ) ;
2229
2233
2230
- let ( raa, commitment_update, order, pending_forwards, mut pending_failures, needs_broadcast_safe, funding_locked) = channel. monitor_updating_restored ( & self . logger ) ;
2234
+ let ( raa, commitment_update, order, chanmon_update , pending_forwards, pending_failures, forwarding_failds , needs_broadcast_safe, funding_locked) = channel. get_mut ( ) . monitor_updating_restored ( & self . logger ) ;
2231
2235
if !pending_forwards. is_empty ( ) {
2232
- htlc_forwards. push ( ( channel. get_short_channel_id ( ) . expect ( "We can't have pending forwards before funding confirmation" ) , funding_txo. clone ( ) , pending_forwards) ) ;
2236
+ htlc_forwards = Some ( ( channel. get ( ) . get_short_channel_id ( ) . expect ( "We can't have pending forwards before funding confirmation" ) , funding_txo. clone ( ) , pending_forwards) ) ;
2233
2237
}
2234
- htlc_failures. append ( & mut pending_failures) ;
2238
+ htlc_failures = pending_failures;
2239
+ htlc_forwarding_failures = forwarding_failds;
2235
2240
2236
2241
macro_rules! handle_cs { ( ) => {
2242
+ if let Some ( monitor_update) = chanmon_update {
2243
+ assert!( order == RAACommitmentOrder :: RevokeAndACKFirst ) ;
2244
+ assert!( !needs_broadcast_safe) ;
2245
+ assert!( funding_locked. is_none( ) ) ;
2246
+ assert!( commitment_update. is_some( ) ) ;
2247
+ if let Err ( e) = self . chain_monitor. update_channel( * funding_txo, monitor_update) {
2248
+ break ( counterparty_node_id,
2249
+ handle_monitor_err!( self , e, channel_state, channel, RAACommitmentOrder :: CommitmentFirst , false , true ) ) ;
2250
+ }
2251
+ }
2237
2252
if let Some ( update) = commitment_update {
2238
2253
pending_msg_events. push( events:: MessageSendEvent :: UpdateHTLCs {
2239
- node_id: channel . get_counterparty_node_id ( ) ,
2254
+ node_id: counterparty_node_id ,
2240
2255
updates: update,
2241
2256
} ) ;
2242
2257
}
2243
2258
} }
2244
2259
macro_rules! handle_raa { ( ) => {
2245
2260
if let Some ( revoke_and_ack) = raa {
2246
2261
pending_msg_events. push( events:: MessageSendEvent :: SendRevokeAndACK {
2247
- node_id: channel . get_counterparty_node_id ( ) ,
2262
+ node_id: counterparty_node_id ,
2248
2263
msg: revoke_and_ack,
2249
2264
} ) ;
2250
2265
}
@@ -2260,35 +2275,38 @@ impl<ChanSigner: ChannelKeys, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>
2260
2275
} ,
2261
2276
}
2262
2277
if needs_broadcast_safe {
2263
- pending_events . push ( events:: Event :: FundingBroadcastSafe {
2264
- funding_txo : channel. get_funding_txo ( ) . unwrap ( ) ,
2265
- user_channel_id : channel. get_user_id ( ) ,
2278
+ pending_event = Some ( events:: Event :: FundingBroadcastSafe {
2279
+ funding_txo : channel. get ( ) . get_funding_txo ( ) . unwrap ( ) ,
2280
+ user_channel_id : channel. get ( ) . get_user_id ( ) ,
2266
2281
} ) ;
2267
2282
}
2268
2283
if let Some ( msg) = funding_locked {
2269
2284
pending_msg_events. push ( events:: MessageSendEvent :: SendFundingLocked {
2270
- node_id : channel . get_counterparty_node_id ( ) ,
2285
+ node_id : counterparty_node_id ,
2271
2286
msg,
2272
2287
} ) ;
2273
- if let Some ( announcement_sigs) = self . get_announcement_sigs ( channel) {
2288
+ if let Some ( announcement_sigs) = self . get_announcement_sigs ( channel. get ( ) ) {
2274
2289
pending_msg_events. push ( events:: MessageSendEvent :: SendAnnouncementSignatures {
2275
- node_id : channel . get_counterparty_node_id ( ) ,
2290
+ node_id : counterparty_node_id ,
2276
2291
msg : announcement_sigs,
2277
2292
} ) ;
2278
2293
}
2279
- short_to_id. insert ( channel. get_short_channel_id ( ) . unwrap ( ) , channel. channel_id ( ) ) ;
2294
+ channel_state . short_to_id . insert ( channel. get ( ) . get_short_channel_id ( ) . unwrap ( ) , channel. get ( ) . channel_id ( ) ) ;
2280
2295
}
2281
- }
2296
+ break ( counterparty_node_id, Ok ( ( ) ) ) ;
2297
+ } ;
2298
+ let _ = handle_error ! ( self , res, counterparty_node_id) ;
2282
2299
2283
- self . pending_events . lock ( ) . unwrap ( ) . append ( & mut pending_events) ;
2300
+ if let Some ( ev) = pending_event {
2301
+ self . pending_events . lock ( ) . unwrap ( ) . push ( ev) ;
2302
+ }
2284
2303
2304
+ self . fail_holding_cell_htlcs ( htlc_forwarding_failures, funding_txo. to_channel_id ( ) ) ;
2285
2305
for failure in htlc_failures. drain ( ..) {
2286
2306
self . fail_htlc_backwards_internal ( self . channel_state . lock ( ) . unwrap ( ) , failure. 0 , & failure. 1 , failure. 2 ) ;
2287
2307
}
2288
- self . forward_htlcs ( & mut htlc_forwards[ ..] ) ;
2289
-
2290
- for res in close_results. drain ( ..) {
2291
- self . finish_force_close_channel ( res) ;
2308
+ if let Some ( forwards) = htlc_forwards {
2309
+ self . forward_htlcs ( & mut [ forwards] [ ..] ) ;
2292
2310
}
2293
2311
}
2294
2312
0 commit comments