@@ -464,6 +464,24 @@ macro_rules! handle_error {
464
464
}
465
465
}
466
466
467
+ macro_rules! break_chan_entry {
468
+ ( $self: ident, $res: expr, $channel_state: expr, $entry: expr) => {
469
+ match $res {
470
+ Ok ( res) => res,
471
+ Err ( ChannelError :: Ignore ( msg) ) => {
472
+ break Err ( MsgHandleErrInternal :: from_chan_no_close( ChannelError :: Ignore ( msg) , $entry. key( ) . clone( ) ) )
473
+ } ,
474
+ Err ( ChannelError :: Close ( msg) ) => {
475
+ let ( channel_id, mut chan) = $entry. remove_entry( ) ;
476
+ if let Some ( short_id) = chan. get_short_channel_id( ) {
477
+ $channel_state. short_to_id. remove( & short_id) ;
478
+ }
479
+ break Err ( MsgHandleErrInternal :: from_finish_shutdown( msg, channel_id, chan. force_shutdown( ) , $self. get_channel_update( & chan) . ok( ) ) )
480
+ } ,
481
+ }
482
+ }
483
+ }
484
+
467
485
macro_rules! try_chan_entry {
468
486
( $self: ident, $res: expr, $channel_state: expr, $entry: expr) => {
469
487
match $res {
@@ -1259,63 +1277,72 @@ impl ChannelManager {
1259
1277
let onion_packet = ChannelManager :: construct_onion_packet ( onion_payloads, onion_keys, & payment_hash) ;
1260
1278
1261
1279
let _ = self . total_consistency_lock . read ( ) . unwrap ( ) ;
1262
- let mut channel_state = self . channel_state . lock ( ) . unwrap ( ) ;
1263
1280
1264
- let id = match channel_state. short_to_id . get ( & route. hops . first ( ) . unwrap ( ) . short_channel_id ) {
1265
- None => return Err ( APIError :: ChannelUnavailable { err : "No channel available with first hop!" } ) ,
1266
- Some ( id) => id. clone ( ) ,
1267
- } ;
1281
+ let err: Result < ( ) , _ > = loop {
1282
+ let mut channel_lock = self . channel_state . lock ( ) . unwrap ( ) ;
1268
1283
1269
- let res = {
1270
- let chan = channel_state. by_id . get_mut ( & id) . unwrap ( ) ;
1271
- if chan. get_their_node_id ( ) != route. hops . first ( ) . unwrap ( ) . pubkey {
1272
- return Err ( APIError :: RouteError { err : "Node ID mismatch on first hop!" } ) ;
1273
- }
1274
- if chan. is_awaiting_monitor_update ( ) {
1275
- return Err ( APIError :: MonitorUpdateFailed ) ;
1276
- }
1277
- if !chan. is_live ( ) {
1278
- return Err ( APIError :: ChannelUnavailable { err : "Peer for first hop currently disconnected!" } ) ;
1284
+ let id = match channel_lock. short_to_id . get ( & route. hops . first ( ) . unwrap ( ) . short_channel_id ) {
1285
+ None => return Err ( APIError :: ChannelUnavailable { err : "No channel available with first hop!" } ) ,
1286
+ Some ( id) => id. clone ( ) ,
1287
+ } ;
1288
+
1289
+ match {
1290
+ let channel_state = channel_lock. borrow_parts ( ) ;
1291
+ if let hash_map:: Entry :: Occupied ( mut chan) = channel_state. by_id . entry ( id) {
1292
+ if chan. get ( ) . get_their_node_id ( ) != route. hops . first ( ) . unwrap ( ) . pubkey {
1293
+ return Err ( APIError :: RouteError { err : "Node ID mismatch on first hop!" } ) ;
1294
+ }
1295
+ if chan. get ( ) . is_awaiting_monitor_update ( ) {
1296
+ return Err ( APIError :: MonitorUpdateFailed ) ;
1297
+ }
1298
+ if !chan. get ( ) . is_live ( ) {
1299
+ return Err ( APIError :: ChannelUnavailable { err : "Peer for first hop currently disconnected!" } ) ;
1300
+ }
1301
+ break_chan_entry ! ( self , chan. get_mut( ) . send_htlc_and_commit( htlc_msat, payment_hash. clone( ) , htlc_cltv, HTLCSource :: OutboundRoute {
1302
+ route: route. clone( ) ,
1303
+ session_priv: session_priv. clone( ) ,
1304
+ first_hop_htlc_msat: htlc_msat,
1305
+ } , onion_packet) , channel_state, chan)
1306
+ } else { unreachable ! ( ) ; }
1307
+ } {
1308
+ Some ( ( update_add, commitment_signed, chan_monitor) ) => {
1309
+ if let Err ( e) = self . monitor . add_update_monitor ( chan_monitor. get_funding_txo ( ) . unwrap ( ) , chan_monitor) {
1310
+ self . handle_monitor_update_fail ( channel_lock, & id, e, RAACommitmentOrder :: CommitmentFirst ) ;
1311
+ return Err ( APIError :: MonitorUpdateFailed ) ;
1312
+ }
1313
+
1314
+ channel_lock. pending_msg_events . push ( events:: MessageSendEvent :: UpdateHTLCs {
1315
+ node_id : route. hops . first ( ) . unwrap ( ) . pubkey ,
1316
+ updates : msgs:: CommitmentUpdate {
1317
+ update_add_htlcs : vec ! [ update_add] ,
1318
+ update_fulfill_htlcs : Vec :: new ( ) ,
1319
+ update_fail_htlcs : Vec :: new ( ) ,
1320
+ update_fail_malformed_htlcs : Vec :: new ( ) ,
1321
+ update_fee : None ,
1322
+ commitment_signed,
1323
+ } ,
1324
+ } ) ;
1325
+ } ,
1326
+ None => { } ,
1279
1327
}
1280
- chan. send_htlc_and_commit ( htlc_msat, payment_hash. clone ( ) , htlc_cltv, HTLCSource :: OutboundRoute {
1281
- route : route. clone ( ) ,
1282
- session_priv : session_priv. clone ( ) ,
1283
- first_hop_htlc_msat : htlc_msat,
1284
- } , onion_packet) . map_err ( |he|
1285
- match he {
1286
- ChannelError :: Close ( err) => {
1287
- // TODO: We need to close the channel here, but for that to be safe we have
1288
- // to do all channel closure inside the channel_state lock which is a
1289
- // somewhat-larger refactor, so we leave that for later.
1290
- APIError :: ChannelUnavailable { err }
1291
- } ,
1292
- ChannelError :: Ignore ( err) => APIError :: ChannelUnavailable { err } ,
1293
- }
1294
- ) ?
1328
+ return Ok ( ( ) ) ;
1295
1329
} ;
1296
- match res {
1297
- Some ( ( update_add, commitment_signed, chan_monitor) ) => {
1298
- if let Err ( e) = self . monitor . add_update_monitor ( chan_monitor. get_funding_txo ( ) . unwrap ( ) , chan_monitor) {
1299
- self . handle_monitor_update_fail ( channel_state, & id, e, RAACommitmentOrder :: CommitmentFirst ) ;
1300
- return Err ( APIError :: MonitorUpdateFailed ) ;
1301
- }
1302
1330
1303
- channel_state. pending_msg_events . push ( events:: MessageSendEvent :: UpdateHTLCs {
1304
- node_id : route. hops . first ( ) . unwrap ( ) . pubkey ,
1305
- updates : msgs:: CommitmentUpdate {
1306
- update_add_htlcs : vec ! [ update_add] ,
1307
- update_fulfill_htlcs : Vec :: new ( ) ,
1308
- update_fail_htlcs : Vec :: new ( ) ,
1309
- update_fail_malformed_htlcs : Vec :: new ( ) ,
1310
- update_fee : None ,
1311
- commitment_signed,
1312
- } ,
1313
- } ) ;
1331
+ match handle_error ! ( self , err, route. hops. first( ) . unwrap( ) . pubkey) {
1332
+ Ok ( _) => unreachable ! ( ) ,
1333
+ Err ( e) => {
1334
+ if let Some ( msgs:: ErrorAction :: IgnoreError ) = e. action {
1335
+ } else {
1336
+ log_error ! ( self , "Got bad keys: {}!" , e. err) ;
1337
+ let mut channel_state = self . channel_state . lock ( ) . unwrap ( ) ;
1338
+ channel_state. pending_msg_events . push ( events:: MessageSendEvent :: HandleError {
1339
+ node_id : route. hops . first ( ) . unwrap ( ) . pubkey ,
1340
+ action : e. action ,
1341
+ } ) ;
1342
+ }
1343
+ Err ( APIError :: ChannelUnavailable { err : e. err } )
1314
1344
} ,
1315
- None => { } ,
1316
1345
}
1317
-
1318
- Ok ( ( ) )
1319
1346
}
1320
1347
1321
1348
/// Call this upon creation of a funding transaction for the given channel.
0 commit comments