@@ -1259,7 +1259,8 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
1259
1259
pub fn close_channel ( & self , channel_id : & [ u8 ; 32 ] ) -> Result < ( ) , APIError > {
1260
1260
let _persistence_guard = PersistenceNotifierGuard :: notify_on_drop ( & self . total_consistency_lock , & self . persistence_notifier ) ;
1261
1261
1262
- let ( mut failed_htlcs, chan_option) = {
1262
+ let mut error_to_handle = None ;
1263
+ let ( counterparty_node_id, shutdown_msg, mut failed_htlcs, chan_option) = {
1263
1264
let mut channel_state_lock = self . channel_state . lock ( ) . unwrap ( ) ;
1264
1265
let channel_state = & mut * channel_state_lock;
1265
1266
match channel_state. by_id . entry ( channel_id. clone ( ) ) {
@@ -1273,35 +1274,57 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
1273
1274
}
1274
1275
} ;
1275
1276
let ( shutdown_msg, monitor_update, failed_htlcs) = chan_entry. get_mut ( ) . get_shutdown ( & self . keys_manager , & their_features) ?;
1276
- channel_state. pending_msg_events . push ( events:: MessageSendEvent :: SendShutdown {
1277
- node_id : counterparty_node_id,
1278
- msg : shutdown_msg
1279
- } ) ;
1277
+
1278
+ // Update the monitor with the shutdown script if necessary.
1280
1279
if let Some ( monitor_update) = monitor_update {
1281
- if let Err ( _) = self . chain_monitor . update_channel ( chan_entry. get ( ) . get_funding_txo ( ) . unwrap ( ) , monitor_update) {
1282
- // TODO: How should this be handled?
1283
- unimplemented ! ( ) ;
1280
+ if let Err ( e) = self . chain_monitor . update_channel ( chan_entry. get ( ) . get_funding_txo ( ) . unwrap ( ) , monitor_update) {
1281
+ error_to_handle = Some ( handle_monitor_err ! ( self , e, channel_state. short_to_id, chan_entry. get_mut( ) , RAACommitmentOrder :: CommitmentFirst , false , false , Vec :: new( ) , Vec :: new( ) , chan_entry. key( ) ) ) ;
1284
1282
}
1285
1283
}
1286
- if chan_entry. get ( ) . is_shutdown ( ) {
1284
+
1285
+ // Clean up the channel mappings if necessary.
1286
+ let remove_chan_entry = {
1287
+ if chan_entry. get ( ) . is_shutdown ( ) { true }
1288
+ else if let Some ( ( _, is_permanent) ) = error_to_handle { is_permanent }
1289
+ else { false }
1290
+ } ;
1291
+ let chan_option = if remove_chan_entry {
1287
1292
if let Some ( short_id) = chan_entry. get ( ) . get_short_channel_id ( ) {
1288
1293
channel_state. short_to_id . remove ( & short_id) ;
1289
1294
}
1290
- ( failed_htlcs, Some ( chan_entry. remove_entry ( ) . 1 ) )
1291
- } else { ( failed_htlcs, None ) }
1295
+ Some ( chan_entry. remove_entry ( ) . 1 )
1296
+ } else { None } ;
1297
+
1298
+ ( counterparty_node_id, shutdown_msg, failed_htlcs, chan_option)
1292
1299
} ,
1293
1300
hash_map:: Entry :: Vacant ( _) => return Err ( APIError :: ChannelUnavailable { err : "No such channel" . to_owned ( ) } )
1294
1301
}
1295
1302
} ;
1303
+
1296
1304
for htlc_source in failed_htlcs. drain ( ..) {
1297
1305
self . fail_htlc_backwards_internal ( self . channel_state . lock ( ) . unwrap ( ) , htlc_source. 0 , & htlc_source. 1 , HTLCFailReason :: Reason { failure_code : 0x4000 | 8 , data : Vec :: new ( ) } ) ;
1298
1306
}
1307
+
1308
+ // Handle any ChannelMonitorUpdateErr, exiting early if it resulted in a force close.
1309
+ if let Some ( ( error, is_permanent) ) = error_to_handle {
1310
+ let _ = handle_error ! ( self , error, counterparty_node_id) ;
1311
+ if is_permanent {
1312
+ return Ok ( ( ) ) ;
1313
+ }
1314
+ }
1315
+
1316
+ // Send the shutdown message since any ChannelMonitorUpdateErr would have been temporary.
1317
+ let mut channel_state = self . channel_state . lock ( ) . unwrap ( ) ;
1318
+ channel_state. pending_msg_events . push ( events:: MessageSendEvent :: SendShutdown {
1319
+ node_id : counterparty_node_id,
1320
+ msg : shutdown_msg
1321
+ } ) ;
1322
+
1299
1323
let chan_update = if let Some ( chan) = chan_option {
1300
1324
self . get_channel_update_for_broadcast ( & chan) . ok ( )
1301
1325
} else { None } ;
1302
1326
1303
1327
if let Some ( update) = chan_update {
1304
- let mut channel_state = self . channel_state . lock ( ) . unwrap ( ) ;
1305
1328
channel_state. pending_msg_events . push ( events:: MessageSendEvent :: BroadcastChannelUpdate {
1306
1329
msg : update
1307
1330
} ) ;
@@ -3172,7 +3195,8 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
3172
3195
}
3173
3196
3174
3197
fn internal_shutdown ( & self , counterparty_node_id : & PublicKey , their_features : & InitFeatures , msg : & msgs:: Shutdown ) -> Result < ( ) , MsgHandleErrInternal > {
3175
- let ( mut dropped_htlcs, chan_option) = {
3198
+ let mut error_to_handle = None ;
3199
+ let ( shutdown, closing_signed, mut dropped_htlcs, chan_option) = {
3176
3200
let mut channel_state_lock = self . channel_state . lock ( ) . unwrap ( ) ;
3177
3201
let channel_state = & mut * channel_state_lock;
3178
3202
@@ -3181,41 +3205,62 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
3181
3205
if chan_entry. get ( ) . get_counterparty_node_id ( ) != * counterparty_node_id {
3182
3206
return Err ( MsgHandleErrInternal :: send_err_msg_no_close ( "Got a message for a channel from the wrong node!" . to_owned ( ) , msg. channel_id ) ) ;
3183
3207
}
3208
+
3184
3209
let ( shutdown, closing_signed, monitor_update, dropped_htlcs) = try_chan_entry ! ( self , chan_entry. get_mut( ) . shutdown( & self . fee_estimator, & self . keys_manager, & their_features, & msg) , channel_state, chan_entry) ;
3185
- if let Some ( msg) = shutdown {
3186
- channel_state. pending_msg_events . push ( events:: MessageSendEvent :: SendShutdown {
3187
- node_id : counterparty_node_id. clone ( ) ,
3188
- msg,
3189
- } ) ;
3190
- }
3191
- if let Some ( msg) = closing_signed {
3192
- channel_state. pending_msg_events . push ( events:: MessageSendEvent :: SendClosingSigned {
3193
- node_id : counterparty_node_id. clone ( ) ,
3194
- msg,
3195
- } ) ;
3196
- }
3210
+
3211
+ // Update the monitor with the shutdown script if necessary.
3197
3212
if let Some ( monitor_update) = monitor_update {
3198
- if let Err ( _) = self . chain_monitor . update_channel ( chan_entry. get ( ) . get_funding_txo ( ) . unwrap ( ) , monitor_update) {
3199
- // TODO: How should this be handled?
3200
- unimplemented ! ( ) ;
3213
+ if let Err ( e) = self . chain_monitor . update_channel ( chan_entry. get ( ) . get_funding_txo ( ) . unwrap ( ) , monitor_update) {
3214
+ error_to_handle = Some ( handle_monitor_err ! ( self , e, channel_state. short_to_id, chan_entry. get_mut( ) , RAACommitmentOrder :: CommitmentFirst , false , false , Vec :: new( ) , Vec :: new( ) , chan_entry. key( ) ) ) ;
3201
3215
}
3202
3216
}
3203
- if chan_entry. get ( ) . is_shutdown ( ) {
3217
+
3218
+ // Clean up the channel mappings if necessary.
3219
+ let remove_chan_entry = {
3220
+ if chan_entry. get ( ) . is_shutdown ( ) { true }
3221
+ else if let Some ( ( _, is_permanent) ) = error_to_handle { is_permanent }
3222
+ else { false }
3223
+ } ;
3224
+ let chan_option = if remove_chan_entry {
3204
3225
if let Some ( short_id) = chan_entry. get ( ) . get_short_channel_id ( ) {
3205
3226
channel_state. short_to_id . remove ( & short_id) ;
3206
3227
}
3207
- ( dropped_htlcs, Some ( chan_entry. remove_entry ( ) . 1 ) )
3208
- } else { ( dropped_htlcs, None ) }
3228
+ Some ( chan_entry. remove_entry ( ) . 1 )
3229
+ } else { None } ;
3230
+
3231
+ ( shutdown, closing_signed, dropped_htlcs, chan_option)
3209
3232
} ,
3210
3233
hash_map:: Entry :: Vacant ( _) => return Err ( MsgHandleErrInternal :: send_err_msg_no_close ( "Failed to find corresponding channel" . to_owned ( ) , msg. channel_id ) )
3211
3234
}
3212
3235
} ;
3213
3236
for htlc_source in dropped_htlcs. drain ( ..) {
3214
3237
self . fail_htlc_backwards_internal ( self . channel_state . lock ( ) . unwrap ( ) , htlc_source. 0 , & htlc_source. 1 , HTLCFailReason :: Reason { failure_code : 0x4000 | 8 , data : Vec :: new ( ) } ) ;
3215
3238
}
3239
+
3240
+ // Handle any ChannelMonitorUpdateErr, exiting early if it resulted in a force close.
3241
+ if let Some ( ( error, is_permanent) ) = error_to_handle {
3242
+ let _ = handle_error ! ( self , error, * counterparty_node_id) ;
3243
+ if is_permanent {
3244
+ return Ok ( ( ) ) ;
3245
+ }
3246
+ }
3247
+
3248
+ // Send the shutdown message since any ChannelMonitorUpdateErr would have been temporary.
3249
+ let mut channel_state = self . channel_state . lock ( ) . unwrap ( ) ;
3250
+ if let Some ( msg) = shutdown {
3251
+ channel_state. pending_msg_events . push ( events:: MessageSendEvent :: SendShutdown {
3252
+ node_id : * counterparty_node_id,
3253
+ msg,
3254
+ } ) ;
3255
+ }
3256
+ if let Some ( msg) = closing_signed {
3257
+ channel_state. pending_msg_events . push ( events:: MessageSendEvent :: SendClosingSigned {
3258
+ node_id : * counterparty_node_id,
3259
+ msg,
3260
+ } ) ;
3261
+ }
3216
3262
if let Some ( chan) = chan_option {
3217
3263
if let Ok ( update) = self . get_channel_update_for_broadcast ( & chan) {
3218
- let mut channel_state = self . channel_state . lock ( ) . unwrap ( ) ;
3219
3264
channel_state. pending_msg_events . push ( events:: MessageSendEvent :: BroadcastChannelUpdate {
3220
3265
msg : update
3221
3266
} ) ;
0 commit comments