@@ -1225,6 +1225,80 @@ impl<ChanSigner: ChannelKeys, M: Deref, T: Deref, K: Deref, F: Deref> ChannelMan
1225
1225
} )
1226
1226
}
1227
1227
1228
+ // Only public for testing, this should otherwise never be called direcly
1229
+ pub ( crate ) fn send_payment_along_path ( & self , path : & Vec < RouteHop > , payment_hash : & PaymentHash , payment_secret : & Option < PaymentSecret > , total_value : u64 , cur_height : u32 ) -> Result < ( ) , APIError > {
1230
+ log_trace ! ( self , "Attempting to send payment for path with next hop {}" , path. first( ) . unwrap( ) . short_channel_id) ;
1231
+ let ( session_priv, prng_seed) = self . keys_manager . get_onion_rand ( ) ;
1232
+
1233
+ let onion_keys = onion_utils:: construct_onion_keys ( & self . secp_ctx , & path, & session_priv)
1234
+ . map_err ( |_| APIError :: RouteError { err : "Pubkey along hop was maliciously selected" } ) ?;
1235
+ let ( onion_payloads, htlc_msat, htlc_cltv) = onion_utils:: build_onion_payloads ( path, total_value, payment_secret, cur_height) ?;
1236
+ if onion_utils:: route_size_insane ( & onion_payloads) {
1237
+ return Err ( APIError :: RouteError { err : "Route size too large considering onion data" } ) ;
1238
+ }
1239
+ let onion_packet = onion_utils:: construct_onion_packet ( onion_payloads, onion_keys, prng_seed, payment_hash) ;
1240
+
1241
+ let _ = self . total_consistency_lock . read ( ) . unwrap ( ) ;
1242
+
1243
+ let err: Result < ( ) , _ > = loop {
1244
+ let mut channel_lock = self . channel_state . lock ( ) . unwrap ( ) ;
1245
+ let id = match channel_lock. short_to_id . get ( & path. first ( ) . unwrap ( ) . short_channel_id ) {
1246
+ None => return Err ( APIError :: ChannelUnavailable { err : "No channel available with first hop!" } ) ,
1247
+ Some ( id) => id. clone ( ) ,
1248
+ } ;
1249
+
1250
+ let channel_state = & mut * channel_lock;
1251
+ if let hash_map:: Entry :: Occupied ( mut chan) = channel_state. by_id . entry ( id) {
1252
+ match {
1253
+ if chan. get ( ) . get_their_node_id ( ) != path. first ( ) . unwrap ( ) . pubkey {
1254
+ return Err ( APIError :: RouteError { err : "Node ID mismatch on first hop!" } ) ;
1255
+ }
1256
+ if !chan. get ( ) . is_live ( ) {
1257
+ return Err ( APIError :: ChannelUnavailable { err : "Peer for first hop currently disconnected/pending monitor update!" } ) ;
1258
+ }
1259
+ break_chan_entry ! ( self , chan. get_mut( ) . send_htlc_and_commit( htlc_msat, payment_hash. clone( ) , htlc_cltv, HTLCSource :: OutboundRoute {
1260
+ path: path. clone( ) ,
1261
+ session_priv: session_priv. clone( ) ,
1262
+ first_hop_htlc_msat: htlc_msat,
1263
+ } , onion_packet) , channel_state, chan)
1264
+ } {
1265
+ Some ( ( update_add, commitment_signed, monitor_update) ) => {
1266
+ if let Err ( e) = self . monitor . update_monitor ( chan. get ( ) . get_funding_txo ( ) . unwrap ( ) , monitor_update) {
1267
+ maybe_break_monitor_err ! ( self , e, channel_state, chan, RAACommitmentOrder :: CommitmentFirst , false , true ) ;
1268
+ // Note that MonitorUpdateFailed here indicates (per function docs)
1269
+ // that we will resend the commitment update once monitor updating
1270
+ // is restored. Therefore, we must return an error indicating that
1271
+ // it is unsafe to retry the payment wholesale, which we do in the
1272
+ // send_payment check for MonitorUpdateFailed, below.
1273
+ return Err ( APIError :: MonitorUpdateFailed ) ;
1274
+ }
1275
+
1276
+ channel_state. pending_msg_events . push ( events:: MessageSendEvent :: UpdateHTLCs {
1277
+ node_id : path. first ( ) . unwrap ( ) . pubkey ,
1278
+ updates : msgs:: CommitmentUpdate {
1279
+ update_add_htlcs : vec ! [ update_add] ,
1280
+ update_fulfill_htlcs : Vec :: new ( ) ,
1281
+ update_fail_htlcs : Vec :: new ( ) ,
1282
+ update_fail_malformed_htlcs : Vec :: new ( ) ,
1283
+ update_fee : None ,
1284
+ commitment_signed,
1285
+ } ,
1286
+ } ) ;
1287
+ } ,
1288
+ None => { } ,
1289
+ }
1290
+ } else { unreachable ! ( ) ; }
1291
+ return Ok ( ( ) ) ;
1292
+ } ;
1293
+
1294
+ match handle_error ! ( self , err, path. first( ) . unwrap( ) . pubkey) {
1295
+ Ok ( _) => unreachable ! ( ) ,
1296
+ Err ( e) => {
1297
+ Err ( APIError :: ChannelUnavailable { err : e. err } )
1298
+ } ,
1299
+ }
1300
+ }
1301
+
1228
1302
/// Sends a payment along a given route.
1229
1303
///
1230
1304
/// Value parameters are provided via the last hop in route, see documentation for RouteHop
@@ -1297,89 +1371,8 @@ impl<ChanSigner: ChannelKeys, M: Deref, T: Deref, K: Deref, F: Deref> ChannelMan
1297
1371
1298
1372
let cur_height = self . latest_block_height . load ( Ordering :: Acquire ) as u32 + 1 ;
1299
1373
let mut results = Vec :: new ( ) ;
1300
- ' path_loop: for path in route. paths . iter ( ) {
1301
- macro_rules! check_res_push {
1302
- ( $res: expr) => { match $res {
1303
- Ok ( r) => r,
1304
- Err ( e) => {
1305
- results. push( Err ( e) ) ;
1306
- continue ' path_loop;
1307
- } ,
1308
- }
1309
- }
1310
- }
1311
-
1312
- log_trace ! ( self , "Attempting to send payment for path with next hop {}" , path. first( ) . unwrap( ) . short_channel_id) ;
1313
- let ( session_priv, prng_seed) = self . keys_manager . get_onion_rand ( ) ;
1314
-
1315
- let onion_keys = check_res_push ! ( onion_utils:: construct_onion_keys( & self . secp_ctx, & path, & session_priv)
1316
- . map_err( |_| APIError :: RouteError { err: "Pubkey along hop was maliciously selected" } ) ) ;
1317
- let ( onion_payloads, htlc_msat, htlc_cltv) = check_res_push ! ( onion_utils:: build_onion_payloads( & path, total_value, payment_secret, cur_height) ) ;
1318
- if onion_utils:: route_size_insane ( & onion_payloads) {
1319
- check_res_push ! ( Err ( APIError :: RouteError { err: "Route size too large considering onion data" } ) ) ;
1320
- }
1321
- let onion_packet = onion_utils:: construct_onion_packet ( onion_payloads, onion_keys, prng_seed, & payment_hash) ;
1322
-
1323
- let _ = self . total_consistency_lock . read ( ) . unwrap ( ) ;
1324
-
1325
- let err: Result < ( ) , _ > = loop {
1326
- let mut channel_lock = self . channel_state . lock ( ) . unwrap ( ) ;
1327
- let id = match channel_lock. short_to_id . get ( & path. first ( ) . unwrap ( ) . short_channel_id ) {
1328
- None => check_res_push ! ( Err ( APIError :: ChannelUnavailable { err: "No channel available with first hop!" } ) ) ,
1329
- Some ( id) => id. clone ( ) ,
1330
- } ;
1331
-
1332
- let channel_state = & mut * channel_lock;
1333
- if let hash_map:: Entry :: Occupied ( mut chan) = channel_state. by_id . entry ( id) {
1334
- match {
1335
- if chan. get ( ) . get_their_node_id ( ) != path. first ( ) . unwrap ( ) . pubkey {
1336
- check_res_push ! ( Err ( APIError :: RouteError { err: "Node ID mismatch on first hop!" } ) ) ;
1337
- }
1338
- if !chan. get ( ) . is_live ( ) {
1339
- check_res_push ! ( Err ( APIError :: ChannelUnavailable { err: "Peer for first hop currently disconnected/pending monitor update!" } ) ) ;
1340
- }
1341
- break_chan_entry ! ( self , chan. get_mut( ) . send_htlc_and_commit( htlc_msat, payment_hash. clone( ) , htlc_cltv, HTLCSource :: OutboundRoute {
1342
- path: path. clone( ) ,
1343
- session_priv: session_priv. clone( ) ,
1344
- first_hop_htlc_msat: htlc_msat,
1345
- } , onion_packet) , channel_state, chan)
1346
- } {
1347
- Some ( ( update_add, commitment_signed, monitor_update) ) => {
1348
- if let Err ( e) = self . monitor . update_monitor ( chan. get ( ) . get_funding_txo ( ) . unwrap ( ) , monitor_update) {
1349
- maybe_break_monitor_err ! ( self , e, channel_state, chan, RAACommitmentOrder :: CommitmentFirst , false , true ) ;
1350
- // Note that MonitorUpdateFailed here indicates (per function docs)
1351
- // that we will resend the commitment update once monitor updating
1352
- // is restored. Therefore, we must return an error indicating that
1353
- // it is unsafe to retry the payment wholesale, which we do in the
1354
- // next check for MonitorUpdateFailed, below.
1355
- check_res_push ! ( Err ( APIError :: MonitorUpdateFailed ) ) ;
1356
- }
1357
-
1358
- channel_state. pending_msg_events . push ( events:: MessageSendEvent :: UpdateHTLCs {
1359
- node_id : path. first ( ) . unwrap ( ) . pubkey ,
1360
- updates : msgs:: CommitmentUpdate {
1361
- update_add_htlcs : vec ! [ update_add] ,
1362
- update_fulfill_htlcs : Vec :: new ( ) ,
1363
- update_fail_htlcs : Vec :: new ( ) ,
1364
- update_fail_malformed_htlcs : Vec :: new ( ) ,
1365
- update_fee : None ,
1366
- commitment_signed,
1367
- } ,
1368
- } ) ;
1369
- } ,
1370
- None => { } ,
1371
- }
1372
- } else { unreachable ! ( ) ; }
1373
- results. push ( Ok ( ( ) ) ) ;
1374
- continue ' path_loop;
1375
- } ;
1376
-
1377
- match handle_error ! ( self , err, path. first( ) . unwrap( ) . pubkey) {
1378
- Ok ( _) => unreachable ! ( ) ,
1379
- Err ( e) => {
1380
- check_res_push ! ( Err ( APIError :: ChannelUnavailable { err: e. err } ) ) ;
1381
- } ,
1382
- }
1374
+ for path in route. paths . iter ( ) {
1375
+ results. push ( self . send_payment_along_path ( & path, & payment_hash, payment_secret, total_value, cur_height) ) ;
1383
1376
}
1384
1377
let mut has_ok = false ;
1385
1378
let mut has_err = false ;
0 commit comments