@@ -446,15 +446,6 @@ const CHECK_CLTV_EXPIRY_SANITY: u32 = CLTV_EXPIRY_DELTA as u32 - LATENCY_GRACE_P
446
446
#[ allow( dead_code) ]
447
447
const CHECK_CLTV_EXPIRY_SANITY_2 : u32 = CLTV_EXPIRY_DELTA as u32 - LATENCY_GRACE_PERIOD_BLOCKS - 2 * CLTV_CLAIM_BUFFER ;
448
448
449
- macro_rules! secp_call {
450
- ( $res: expr, $err: expr ) => {
451
- match $res {
452
- Ok ( key) => key,
453
- Err ( _) => return Err ( $err) ,
454
- }
455
- } ;
456
- }
457
-
458
449
/// Details of a channel, as returned by ChannelManager::list_channels and ChannelManager::list_usable_channels
459
450
pub struct ChannelDetails {
460
451
/// The channel's ID (prior to funding transaction generation, this is a random 32 bytes,
@@ -491,6 +482,42 @@ pub struct ChannelDetails {
491
482
pub is_live : bool ,
492
483
}
493
484
485
+ /// If a payment fails to send, it can be in one of several states. This enum is returned as the
486
+ /// Err() type describing which state the payment is in, see the description of individual enum
487
+ /// states for more.
488
+ #[ derive( Debug ) ]
489
+ pub enum PaymentSendFailure {
490
+ /// A parameter which was passed to send_payment was invalid, preventing us from attempting to
491
+ /// send the payment at all. No channel state has been changed or messages sent to peers, and
492
+ /// once you've changed the parameter at error, you can freely retry the payment in full.
493
+ ParameterError ( APIError ) ,
494
+ /// A parameter in a single path which was passed to send_payment was invalid, preventing us
495
+ /// from attempting to send the payment at all. No channel state has been changed or messages
496
+ /// sent to peers, and once you've changed the parameter at error, you can freely retry the
497
+ /// payment in full.
498
+ ///
499
+ /// The results here are ordered the same as the paths in the route object which was passed to
500
+ /// send_payment.
501
+ PathParameterError ( Vec < Result < ( ) , APIError > > ) ,
502
+ /// All paths which were attempted failed to send, with no channel state change taking place.
503
+ /// You can freely retry the payment in full (though you probably want to do so over different
504
+ /// paths than the ones selected).
505
+ AllFailedRetrySafe ( Vec < APIError > ) ,
506
+ /// Some paths which were attempted failed to send, though possibly not all. At least some
507
+ /// paths have irrevocably committed to the HTLC and retrying the payment in full would result
508
+ /// in over-/re-payment.
509
+ ///
510
+ /// The results here are ordered the same as the paths in the route object which was passed to
511
+ /// send_payment, and any Errs which are not APIError::MonitorUpdateFailed can be safely
512
+ /// retried (though there is currently no API with which to do so).
513
+ ///
514
+ /// Any entries which contain Err(APIError::MonitorUpdateFailed) or Ok(()) MUST NOT be retried
515
+ /// as they will result in over-/re-payment. These HTLCs all either successfully sent (in the
516
+ /// case of Ok(())) or will send once channel_monitor_updated is called on the next-hop channel
517
+ /// with the latest update_id.
518
+ PartialFailure ( Vec < Result < ( ) , APIError > > ) ,
519
+ }
520
+
494
521
macro_rules! handle_error {
495
522
( $self: ident, $internal: expr, $their_node_id: expr) => {
496
523
match $internal {
@@ -1207,20 +1234,24 @@ impl<ChanSigner: ChannelKeys, M: Deref, T: Deref, K: Deref, F: Deref> ChannelMan
1207
1234
/// payment_preimage tracking (which you should already be doing as they represent "proof of
1208
1235
/// payment") and prevent double-sends yourself.
1209
1236
///
1210
- /// May generate a SendHTLCs message event on success, which should be relayed.
1237
+ /// May generate SendHTLCs message(s) event on success, which should be relayed.
1238
+ ///
1239
+ /// Each path may have a different return value, and PaymentSendValue may return a Vec with
1240
+ /// each entry matching the corresponding-index entry in the route paths, see
1241
+ /// PaymentSendFailure for more info.
1211
1242
///
1212
- /// Raises APIError::RoutError when invalid route or forward parameter
1213
- /// (cltv_delta, fee, node public key) is specified.
1214
- /// Raises APIError::ChannelUnavailable if the next-hop channel is not available for updates
1215
- /// (including due to previous monitor update failure or new permanent monitor update failure).
1216
- /// Raised APIError::MonitorUpdateFailed if a new monitor update failure prevented sending the
1217
- /// relevant updates.
1243
+ /// In general, a path may raise:
1244
+ /// * APIError::RouteError when an invalid route or forwarding parameter (cltv_delta, fee,
1245
+ /// node public key) is specified.
1246
+ /// * APIError::ChannelUnavailable if the next-hop channel is not available for updates
1247
+ /// (including due to previous monitor update failure or new permanent monitor update
1248
+ /// failure).
1249
+ /// * APIError::MonitorUpdateFailed if a new monitor update failure prevented sending the
1250
+ /// relevant updates.
1218
1251
///
1219
- /// In case of APIError::RouteError/APIError::ChannelUnavailable, the payment send has failed
1220
- /// and you may wish to retry via a different route immediately.
1221
- /// In case of APIError::MonitorUpdateFailed, the commitment update has been irrevocably
1222
- /// committed on our end and we're just waiting for a monitor update to send it. Do NOT retry
1223
- /// the payment via a different route unless you intend to pay twice!
1252
+ /// Note that depending on the type of the PaymentSendFailure the HTLC may have been
1253
+ /// irrevocably committed to on our end. In such a case, do NOT retry the payment with a
1254
+ /// different route unless you intend to pay twice!
1224
1255
///
1225
1256
/// payment_secret is unrelated to payment_hash (or PaymentPreimage) and exists to authenticate
1226
1257
/// the sender to the recipient and prevent payment-probing (deanonymization) attacks. For
@@ -1230,87 +1261,139 @@ impl<ChanSigner: ChannelKeys, M: Deref, T: Deref, K: Deref, F: Deref> ChannelMan
1230
1261
/// If a payment_secret *is* provided, we assume that the invoice had the payment_secret feature
1231
1262
/// bit set (either as required or as available). If multiple paths are present in the Route,
1232
1263
/// we assume the invoice had the basic_mpp feature set.
1233
- pub fn send_payment ( & self , route : Route , payment_hash : PaymentHash , payment_secret : & Option < PaymentSecret > ) -> Result < ( ) , APIError > {
1234
- if route. paths . len ( ) < 1 || route . paths . len ( ) > 1 {
1235
- return Err ( APIError :: RouteError { err : "We currently don't support MPP, and we need at least one path" } ) ;
1264
+ pub fn send_payment ( & self , route : Route , payment_hash : PaymentHash , payment_secret : & Option < PaymentSecret > ) -> Result < ( ) , PaymentSendFailure > {
1265
+ if route. paths . len ( ) < 1 {
1266
+ return Err ( PaymentSendFailure :: ParameterError ( APIError :: RouteError { err : "There must be at least one path to send over" } ) ) ;
1236
1267
}
1237
- if route. paths [ 0 ] . len ( ) < 1 || route . paths [ 0 ] . len ( ) > 20 {
1238
- return Err ( APIError :: RouteError { err : "Path didn't go anywhere/had bogus size" } ) ;
1268
+ if route. paths . len ( ) > 10 {
1269
+ return Err ( PaymentSendFailure :: ParameterError ( APIError :: RouteError { err : "Sending over more than 10 paths is not currently supported" } ) ) ;
1239
1270
}
1271
+ let mut total_value = 0 ;
1240
1272
let our_node_id = self . get_our_node_id ( ) ;
1241
- for ( idx, hop) in route. paths [ 0 ] . iter ( ) . enumerate ( ) {
1242
- if idx != route. paths [ 0 ] . len ( ) - 1 && hop. pubkey == our_node_id {
1243
- return Err ( APIError :: RouteError { err : "Path went through us but wasn't a simple rebalance loop to us" } ) ;
1273
+ let mut path_errs = Vec :: with_capacity ( route. paths . len ( ) ) ;
1274
+ ' path_check: for path in route. paths . iter ( ) {
1275
+ if path. len ( ) < 1 || path. len ( ) > 20 {
1276
+ path_errs. push ( Err ( APIError :: RouteError { err : "Path didn't go anywhere/had bogus size" } ) ) ;
1277
+ continue ' path_check;
1278
+ }
1279
+ for ( idx, hop) in path. iter ( ) . enumerate ( ) {
1280
+ if idx != path. len ( ) - 1 && hop. pubkey == our_node_id {
1281
+ path_errs. push ( Err ( APIError :: RouteError { err : "Path went through us but wasn't a simple rebalance loop to us" } ) ) ;
1282
+ continue ' path_check;
1283
+ }
1244
1284
}
1285
+ total_value += path. last ( ) . unwrap ( ) . fee_msat ;
1286
+ path_errs. push ( Ok ( ( ) ) ) ;
1287
+ }
1288
+ if path_errs. iter ( ) . any ( |e| e. is_err ( ) ) {
1289
+ return Err ( PaymentSendFailure :: PathParameterError ( path_errs) ) ;
1245
1290
}
1246
-
1247
- let ( session_priv, prng_seed) = self . keys_manager . get_onion_rand ( ) ;
1248
1291
1249
1292
let cur_height = self . latest_block_height . load ( Ordering :: Acquire ) as u32 + 1 ;
1293
+ let mut results = Vec :: new ( ) ;
1294
+ ' path_loop: for path in route. paths . iter ( ) {
1295
+ macro_rules! check_res_push {
1296
+ ( $res: expr) => { match $res {
1297
+ Ok ( r) => r,
1298
+ Err ( e) => {
1299
+ results. push( Err ( e) ) ;
1300
+ continue ' path_loop;
1301
+ } ,
1302
+ }
1303
+ }
1304
+ }
1250
1305
1251
- let onion_keys = secp_call ! ( onion_utils:: construct_onion_keys( & self . secp_ctx, & route. paths[ 0 ] , & session_priv) ,
1252
- APIError :: RouteError { err: "Pubkey along hop was maliciously selected" } ) ;
1253
- let ( onion_payloads, htlc_msat, htlc_cltv) = onion_utils:: build_onion_payloads ( & route. paths [ 0 ] , payment_secret, cur_height) ?;
1254
- if onion_utils:: route_size_insane ( & onion_payloads) {
1255
- return Err ( APIError :: RouteError { err : "Route size too large considering onion data" } ) ;
1256
- }
1257
- let onion_packet = onion_utils:: construct_onion_packet ( onion_payloads, onion_keys, prng_seed, & payment_hash) ;
1306
+ log_trace ! ( self , "Attempting to send payment for path with next hop {}" , path. first( ) . unwrap( ) . short_channel_id) ;
1307
+ let ( session_priv, prng_seed) = self . keys_manager . get_onion_rand ( ) ;
1258
1308
1259
- let _ = self . total_consistency_lock . read ( ) . unwrap ( ) ;
1309
+ let onion_keys = check_res_push ! ( onion_utils:: construct_onion_keys( & self . secp_ctx, & path, & session_priv)
1310
+ . map_err( |_| APIError :: RouteError { err: "Pubkey along hop was maliciously selected" } ) ) ;
1311
+ let ( onion_payloads, htlc_msat, htlc_cltv) = check_res_push ! ( onion_utils:: build_onion_payloads( & path, total_value, payment_secret, cur_height) ) ;
1312
+ if onion_utils:: route_size_insane ( & onion_payloads) {
1313
+ check_res_push ! ( Err ( APIError :: RouteError { err: "Route size too large considering onion data" } ) ) ;
1314
+ }
1315
+ let onion_packet = onion_utils:: construct_onion_packet ( onion_payloads, onion_keys, prng_seed, & payment_hash) ;
1260
1316
1261
- let err: Result < ( ) , _ > = loop {
1262
- let mut channel_lock = self . channel_state . lock ( ) . unwrap ( ) ;
1263
- let id = match channel_lock. short_to_id . get ( & route. paths [ 0 ] . first ( ) . unwrap ( ) . short_channel_id ) {
1264
- None => return Err ( APIError :: ChannelUnavailable { err : "No channel available with first hop!" } ) ,
1265
- Some ( id) => id. clone ( ) ,
1266
- } ;
1317
+ let _ = self . total_consistency_lock . read ( ) . unwrap ( ) ;
1267
1318
1268
- let channel_state = & mut * channel_lock;
1269
- if let hash_map:: Entry :: Occupied ( mut chan) = channel_state. by_id . entry ( id) {
1270
- match {
1271
- if chan. get ( ) . get_their_node_id ( ) != route. paths [ 0 ] . first ( ) . unwrap ( ) . pubkey {
1272
- return Err ( APIError :: RouteError { err : "Node ID mismatch on first hop!" } ) ;
1273
- }
1274
- if !chan. get ( ) . is_live ( ) {
1275
- return Err ( APIError :: ChannelUnavailable { err : "Peer for first hop currently disconnected/pending monitor update!" } ) ;
1276
- }
1277
- break_chan_entry ! ( self , chan. get_mut( ) . send_htlc_and_commit( htlc_msat, payment_hash. clone( ) , htlc_cltv, HTLCSource :: OutboundRoute {
1278
- path: route. paths[ 0 ] . clone( ) ,
1279
- session_priv: session_priv. clone( ) ,
1280
- first_hop_htlc_msat: htlc_msat,
1281
- } , onion_packet) , channel_state, chan)
1282
- } {
1283
- Some ( ( update_add, commitment_signed, monitor_update) ) => {
1284
- if let Err ( e) = self . monitor . update_monitor ( chan. get ( ) . get_funding_txo ( ) . unwrap ( ) , monitor_update) {
1285
- maybe_break_monitor_err ! ( self , e, channel_state, chan, RAACommitmentOrder :: CommitmentFirst , false , true ) ;
1286
- // Note that MonitorUpdateFailed here indicates (per function docs)
1287
- // that we will resent the commitment update once we unfree monitor
1288
- // updating, so we have to take special care that we don't return
1289
- // something else in case we will resend later!
1290
- return Err ( APIError :: MonitorUpdateFailed ) ;
1319
+ let err: Result < ( ) , _ > = loop {
1320
+ let mut channel_lock = self . channel_state . lock ( ) . unwrap ( ) ;
1321
+ let id = match channel_lock. short_to_id . get ( & path. first ( ) . unwrap ( ) . short_channel_id ) {
1322
+ None => check_res_push ! ( Err ( APIError :: ChannelUnavailable { err: "No channel available with first hop!" } ) ) ,
1323
+ Some ( id) => id. clone ( ) ,
1324
+ } ;
1325
+
1326
+ let channel_state = & mut * channel_lock;
1327
+ if let hash_map:: Entry :: Occupied ( mut chan) = channel_state. by_id . entry ( id) {
1328
+ match {
1329
+ if chan. get ( ) . get_their_node_id ( ) != path. first ( ) . unwrap ( ) . pubkey {
1330
+ check_res_push ! ( Err ( APIError :: RouteError { err: "Node ID mismatch on first hop!" } ) ) ;
1291
1331
}
1332
+ if !chan. get ( ) . is_live ( ) {
1333
+ check_res_push ! ( Err ( APIError :: ChannelUnavailable { err: "Peer for first hop currently disconnected/pending monitor update!" } ) ) ;
1334
+ }
1335
+ break_chan_entry ! ( self , chan. get_mut( ) . send_htlc_and_commit( htlc_msat, payment_hash. clone( ) , htlc_cltv, HTLCSource :: OutboundRoute {
1336
+ path: path. clone( ) ,
1337
+ session_priv: session_priv. clone( ) ,
1338
+ first_hop_htlc_msat: htlc_msat,
1339
+ } , onion_packet) , channel_state, chan)
1340
+ } {
1341
+ Some ( ( update_add, commitment_signed, monitor_update) ) => {
1342
+ if let Err ( e) = self . monitor . update_monitor ( chan. get ( ) . get_funding_txo ( ) . unwrap ( ) , monitor_update) {
1343
+ maybe_break_monitor_err ! ( self , e, channel_state, chan, RAACommitmentOrder :: CommitmentFirst , false , true ) ;
1344
+ // Note that MonitorUpdateFailed here indicates (per function docs)
1345
+ // that we will resend the commitment update once monitor updating
1346
+ // is restored. Therefore, we must return an error indicating that
1347
+ // it is unsafe to retry the payment wholesale, which we do in the
1348
+ // next check for MonitorUpdateFailed, below.
1349
+ check_res_push ! ( Err ( APIError :: MonitorUpdateFailed ) ) ;
1350
+ }
1292
1351
1293
- channel_state. pending_msg_events . push ( events:: MessageSendEvent :: UpdateHTLCs {
1294
- node_id : route. paths [ 0 ] . first ( ) . unwrap ( ) . pubkey ,
1295
- updates : msgs:: CommitmentUpdate {
1296
- update_add_htlcs : vec ! [ update_add] ,
1297
- update_fulfill_htlcs : Vec :: new ( ) ,
1298
- update_fail_htlcs : Vec :: new ( ) ,
1299
- update_fail_malformed_htlcs : Vec :: new ( ) ,
1300
- update_fee : None ,
1301
- commitment_signed,
1302
- } ,
1303
- } ) ;
1304
- } ,
1305
- None => { } ,
1306
- }
1307
- } else { unreachable ! ( ) ; }
1308
- return Ok ( ( ) ) ;
1309
- } ;
1352
+ channel_state. pending_msg_events . push ( events:: MessageSendEvent :: UpdateHTLCs {
1353
+ node_id : path. first ( ) . unwrap ( ) . pubkey ,
1354
+ updates : msgs:: CommitmentUpdate {
1355
+ update_add_htlcs : vec ! [ update_add] ,
1356
+ update_fulfill_htlcs : Vec :: new ( ) ,
1357
+ update_fail_htlcs : Vec :: new ( ) ,
1358
+ update_fail_malformed_htlcs : Vec :: new ( ) ,
1359
+ update_fee : None ,
1360
+ commitment_signed,
1361
+ } ,
1362
+ } ) ;
1363
+ } ,
1364
+ None => { } ,
1365
+ }
1366
+ } else { unreachable ! ( ) ; }
1367
+ results. push ( Ok ( ( ) ) ) ;
1368
+ continue ' path_loop;
1369
+ } ;
1310
1370
1311
- match handle_error ! ( self , err, route. paths[ 0 ] . first( ) . unwrap( ) . pubkey) {
1312
- Ok ( _) => unreachable ! ( ) ,
1313
- Err ( e) => { Err ( APIError :: ChannelUnavailable { err : e. err } ) }
1371
+ match handle_error ! ( self , err, path. first( ) . unwrap( ) . pubkey) {
1372
+ Ok ( _) => unreachable ! ( ) ,
1373
+ Err ( e) => {
1374
+ check_res_push ! ( Err ( APIError :: ChannelUnavailable { err: e. err } ) ) ;
1375
+ } ,
1376
+ }
1377
+ }
1378
+ let mut has_ok = false ;
1379
+ let mut has_err = false ;
1380
+ for res in results. iter ( ) {
1381
+ if res. is_ok ( ) { has_ok = true ; }
1382
+ if res. is_err ( ) { has_err = true ; }
1383
+ if let & Err ( APIError :: MonitorUpdateFailed ) = res {
1384
+ // MonitorUpdateFailed is inherently unsafe to retry, so we call it a
1385
+ // PartialFailure.
1386
+ has_err = true ;
1387
+ has_ok = true ;
1388
+ break ;
1389
+ }
1390
+ }
1391
+ if has_err && has_ok {
1392
+ Err ( PaymentSendFailure :: PartialFailure ( results) )
1393
+ } else if has_err {
1394
+ Err ( PaymentSendFailure :: AllFailedRetrySafe ( results. drain ( ..) . map ( |r| r. unwrap_err ( ) ) . collect ( ) ) )
1395
+ } else {
1396
+ Ok ( ( ) )
1314
1397
}
1315
1398
}
1316
1399
0 commit comments