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