@@ -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
@@ -1229,87 +1260,139 @@ impl<ChanSigner: ChannelKeys, M: Deref, T: Deref, K: Deref, F: Deref> ChannelMan
1229
1260
/// If a payment_secret *is* provided, we assume that the invoice had the payment_secret feature
1230
1261
/// bit set (either as required or as available). If multiple paths are present in the Route,
1231
1262
/// we assume the invoice had the basic_mpp feature set.
1232
- pub fn send_payment ( & self , route : Route , payment_hash : PaymentHash , payment_secret : & Option < PaymentSecret > ) -> Result < ( ) , APIError > {
1233
- if route. paths . len ( ) < 1 || route . paths . len ( ) > 1 {
1234
- return Err ( APIError :: RouteError { err : "We currently don't support MPP, and we need at least one path" } ) ;
1263
+ pub fn send_payment ( & self , route : Route , payment_hash : PaymentHash , payment_secret : & Option < PaymentSecret > ) -> Result < ( ) , PaymentSendFailure > {
1264
+ if route. paths . len ( ) < 1 {
1265
+ return Err ( PaymentSendFailure :: ParameterError ( APIError :: RouteError { err : "There must be at least one path to send over" } ) ) ;
1235
1266
}
1236
- if route. paths [ 0 ] . len ( ) < 1 || route . paths [ 0 ] . len ( ) > 20 {
1237
- return Err ( APIError :: RouteError { err : "Path didn't go anywhere/had bogus size" } ) ;
1267
+ if route. paths . len ( ) > 10 {
1268
+ return Err ( PaymentSendFailure :: ParameterError ( APIError :: RouteError { err : "Sending over more than 10 paths is not currently supported" } ) ) ;
1238
1269
}
1270
+ let mut total_value = 0 ;
1239
1271
let our_node_id = self . get_our_node_id ( ) ;
1240
- for ( idx, hop) in route. paths [ 0 ] . iter ( ) . enumerate ( ) {
1241
- if idx != route. paths [ 0 ] . len ( ) - 1 && hop. pubkey == our_node_id {
1242
- return Err ( APIError :: RouteError { err : "Path went through us but wasn't a simple rebalance loop to us" } ) ;
1272
+ let mut path_errs = Vec :: with_capacity ( route. paths . len ( ) ) ;
1273
+ ' path_check: for path in route. paths . iter ( ) {
1274
+ if path. len ( ) < 1 || path. len ( ) > 20 {
1275
+ path_errs. push ( Err ( APIError :: RouteError { err : "Path didn't go anywhere/had bogus size" } ) ) ;
1276
+ continue ' path_check;
1277
+ }
1278
+ for ( idx, hop) in path. iter ( ) . enumerate ( ) {
1279
+ if idx != path. len ( ) - 1 && hop. pubkey == our_node_id {
1280
+ path_errs. push ( Err ( APIError :: RouteError { err : "Path went through us but wasn't a simple rebalance loop to us" } ) ) ;
1281
+ continue ' path_check;
1282
+ }
1243
1283
}
1284
+ total_value += path. last ( ) . unwrap ( ) . fee_msat ;
1285
+ path_errs. push ( Ok ( ( ) ) ) ;
1286
+ }
1287
+ if path_errs. iter ( ) . any ( |e| e. is_err ( ) ) {
1288
+ return Err ( PaymentSendFailure :: PathParameterError ( path_errs) ) ;
1244
1289
}
1245
-
1246
- let ( session_priv, prng_seed) = self . keys_manager . get_onion_rand ( ) ;
1247
1290
1248
1291
let cur_height = self . latest_block_height . load ( Ordering :: Acquire ) as u32 + 1 ;
1292
+ let mut results = Vec :: new ( ) ;
1293
+ ' path_loop: for path in route. paths . iter ( ) {
1294
+ macro_rules! check_res_push {
1295
+ ( $res: expr) => { match $res {
1296
+ Ok ( r) => r,
1297
+ Err ( e) => {
1298
+ results. push( Err ( e) ) ;
1299
+ continue ' path_loop;
1300
+ } ,
1301
+ }
1302
+ }
1303
+ }
1249
1304
1250
- let onion_keys = secp_call ! ( onion_utils:: construct_onion_keys( & self . secp_ctx, & route. paths[ 0 ] , & session_priv) ,
1251
- APIError :: RouteError { err: "Pubkey along hop was maliciously selected" } ) ;
1252
- let ( onion_payloads, htlc_msat, htlc_cltv) = onion_utils:: build_onion_payloads ( & route. paths [ 0 ] , payment_secret, cur_height) ?;
1253
- if onion_utils:: route_size_insane ( & onion_payloads) {
1254
- return Err ( APIError :: RouteError { err : "Route size too large considering onion data" } ) ;
1255
- }
1256
- let onion_packet = onion_utils:: construct_onion_packet ( onion_payloads, onion_keys, prng_seed, & payment_hash) ;
1305
+ log_trace ! ( self , "Attempting to send payment for path with next hop {}" , path. first( ) . unwrap( ) . short_channel_id) ;
1306
+ let ( session_priv, prng_seed) = self . keys_manager . get_onion_rand ( ) ;
1257
1307
1258
- let _ = self . total_consistency_lock . read ( ) . unwrap ( ) ;
1308
+ let onion_keys = check_res_push ! ( onion_utils:: construct_onion_keys( & self . secp_ctx, & path, & session_priv)
1309
+ . map_err( |_| APIError :: RouteError { err: "Pubkey along hop was maliciously selected" } ) ) ;
1310
+ let ( onion_payloads, htlc_msat, htlc_cltv) = check_res_push ! ( onion_utils:: build_onion_payloads( & path, total_value, payment_secret, cur_height) ) ;
1311
+ if onion_utils:: route_size_insane ( & onion_payloads) {
1312
+ check_res_push ! ( Err ( APIError :: RouteError { err: "Route size too large considering onion data" } ) ) ;
1313
+ }
1314
+ let onion_packet = onion_utils:: construct_onion_packet ( onion_payloads, onion_keys, prng_seed, & payment_hash) ;
1259
1315
1260
- let err: Result < ( ) , _ > = loop {
1261
- let mut channel_lock = self . channel_state . lock ( ) . unwrap ( ) ;
1262
- let id = match channel_lock. short_to_id . get ( & route. paths [ 0 ] . first ( ) . unwrap ( ) . short_channel_id ) {
1263
- None => return Err ( APIError :: ChannelUnavailable { err : "No channel available with first hop!" } ) ,
1264
- Some ( id) => id. clone ( ) ,
1265
- } ;
1316
+ let _ = self . total_consistency_lock . read ( ) . unwrap ( ) ;
1266
1317
1267
- let channel_state = & mut * channel_lock;
1268
- if let hash_map:: Entry :: Occupied ( mut chan) = channel_state. by_id . entry ( id) {
1269
- match {
1270
- if chan. get ( ) . get_their_node_id ( ) != route. paths [ 0 ] . first ( ) . unwrap ( ) . pubkey {
1271
- return Err ( APIError :: RouteError { err : "Node ID mismatch on first hop!" } ) ;
1272
- }
1273
- if !chan. get ( ) . is_live ( ) {
1274
- return Err ( APIError :: ChannelUnavailable { err : "Peer for first hop currently disconnected/pending monitor update!" } ) ;
1275
- }
1276
- break_chan_entry ! ( self , chan. get_mut( ) . send_htlc_and_commit( htlc_msat, payment_hash. clone( ) , htlc_cltv, HTLCSource :: OutboundRoute {
1277
- path: route. paths[ 0 ] . clone( ) ,
1278
- session_priv: session_priv. clone( ) ,
1279
- first_hop_htlc_msat: htlc_msat,
1280
- } , onion_packet) , channel_state, chan)
1281
- } {
1282
- Some ( ( update_add, commitment_signed, monitor_update) ) => {
1283
- if let Err ( e) = self . monitor . update_monitor ( chan. get ( ) . get_funding_txo ( ) . unwrap ( ) , monitor_update) {
1284
- maybe_break_monitor_err ! ( self , e, channel_state, chan, RAACommitmentOrder :: CommitmentFirst , false , true ) ;
1285
- // Note that MonitorUpdateFailed here indicates (per function docs)
1286
- // that we will resent the commitment update once we unfree monitor
1287
- // updating, so we have to take special care that we don't return
1288
- // something else in case we will resend later!
1289
- return Err ( APIError :: MonitorUpdateFailed ) ;
1318
+ let err: Result < ( ) , _ > = loop {
1319
+ let mut channel_lock = self . channel_state . lock ( ) . unwrap ( ) ;
1320
+ let id = match channel_lock. short_to_id . get ( & path. first ( ) . unwrap ( ) . short_channel_id ) {
1321
+ None => check_res_push ! ( Err ( APIError :: ChannelUnavailable { err: "No channel available with first hop!" } ) ) ,
1322
+ Some ( id) => id. clone ( ) ,
1323
+ } ;
1324
+
1325
+ let channel_state = & mut * channel_lock;
1326
+ if let hash_map:: Entry :: Occupied ( mut chan) = channel_state. by_id . entry ( id) {
1327
+ match {
1328
+ if chan. get ( ) . get_their_node_id ( ) != path. first ( ) . unwrap ( ) . pubkey {
1329
+ check_res_push ! ( Err ( APIError :: RouteError { err: "Node ID mismatch on first hop!" } ) ) ;
1290
1330
}
1331
+ if !chan. get ( ) . is_live ( ) {
1332
+ check_res_push ! ( Err ( APIError :: ChannelUnavailable { err: "Peer for first hop currently disconnected/pending monitor update!" } ) ) ;
1333
+ }
1334
+ break_chan_entry ! ( self , chan. get_mut( ) . send_htlc_and_commit( htlc_msat, payment_hash. clone( ) , htlc_cltv, HTLCSource :: OutboundRoute {
1335
+ path: path. clone( ) ,
1336
+ session_priv: session_priv. clone( ) ,
1337
+ first_hop_htlc_msat: htlc_msat,
1338
+ } , onion_packet) , channel_state, chan)
1339
+ } {
1340
+ Some ( ( update_add, commitment_signed, monitor_update) ) => {
1341
+ if let Err ( e) = self . monitor . update_monitor ( chan. get ( ) . get_funding_txo ( ) . unwrap ( ) , monitor_update) {
1342
+ maybe_break_monitor_err ! ( self , e, channel_state, chan, RAACommitmentOrder :: CommitmentFirst , false , true ) ;
1343
+ // Note that MonitorUpdateFailed here indicates (per function docs)
1344
+ // that we will resend the commitment update once monitor updating
1345
+ // is restored. Therefore, we must return an error indicating that
1346
+ // it is unsafe to retry the payment wholesale, which we do in the
1347
+ // next check for MonitorUpdateFailed, below.
1348
+ check_res_push ! ( Err ( APIError :: MonitorUpdateFailed ) ) ;
1349
+ }
1291
1350
1292
- channel_state. pending_msg_events . push ( events:: MessageSendEvent :: UpdateHTLCs {
1293
- node_id : route. paths [ 0 ] . first ( ) . unwrap ( ) . pubkey ,
1294
- updates : msgs:: CommitmentUpdate {
1295
- update_add_htlcs : vec ! [ update_add] ,
1296
- update_fulfill_htlcs : Vec :: new ( ) ,
1297
- update_fail_htlcs : Vec :: new ( ) ,
1298
- update_fail_malformed_htlcs : Vec :: new ( ) ,
1299
- update_fee : None ,
1300
- commitment_signed,
1301
- } ,
1302
- } ) ;
1303
- } ,
1304
- None => { } ,
1305
- }
1306
- } else { unreachable ! ( ) ; }
1307
- return Ok ( ( ) ) ;
1308
- } ;
1351
+ channel_state. pending_msg_events . push ( events:: MessageSendEvent :: UpdateHTLCs {
1352
+ node_id : path. first ( ) . unwrap ( ) . pubkey ,
1353
+ updates : msgs:: CommitmentUpdate {
1354
+ update_add_htlcs : vec ! [ update_add] ,
1355
+ update_fulfill_htlcs : Vec :: new ( ) ,
1356
+ update_fail_htlcs : Vec :: new ( ) ,
1357
+ update_fail_malformed_htlcs : Vec :: new ( ) ,
1358
+ update_fee : None ,
1359
+ commitment_signed,
1360
+ } ,
1361
+ } ) ;
1362
+ } ,
1363
+ None => { } ,
1364
+ }
1365
+ } else { unreachable ! ( ) ; }
1366
+ results. push ( Ok ( ( ) ) ) ;
1367
+ continue ' path_loop;
1368
+ } ;
1309
1369
1310
- match handle_error ! ( self , err, route. paths[ 0 ] . first( ) . unwrap( ) . pubkey) {
1311
- Ok ( _) => unreachable ! ( ) ,
1312
- Err ( e) => { Err ( APIError :: ChannelUnavailable { err : e. err } ) }
1370
+ match handle_error ! ( self , err, path. first( ) . unwrap( ) . pubkey) {
1371
+ Ok ( _) => unreachable ! ( ) ,
1372
+ Err ( e) => {
1373
+ check_res_push ! ( Err ( APIError :: ChannelUnavailable { err: e. err } ) ) ;
1374
+ } ,
1375
+ }
1376
+ }
1377
+ let mut has_ok = false ;
1378
+ let mut has_err = false ;
1379
+ for res in results. iter ( ) {
1380
+ if res. is_ok ( ) { has_ok = true ; }
1381
+ if res. is_err ( ) { has_err = true ; }
1382
+ if let & Err ( APIError :: MonitorUpdateFailed ) = res {
1383
+ // MonitorUpdateFailed is inherently unsafe to retry, so we call it a
1384
+ // PartialFailure.
1385
+ has_err = true ;
1386
+ has_ok = true ;
1387
+ break ;
1388
+ }
1389
+ }
1390
+ if has_err && has_ok {
1391
+ Err ( PaymentSendFailure :: PartialFailure ( results) )
1392
+ } else if has_err {
1393
+ Err ( PaymentSendFailure :: AllFailedRetrySafe ( results. drain ( ..) . map ( |r| r. unwrap_err ( ) ) . collect ( ) ) )
1394
+ } else {
1395
+ Ok ( ( ) )
1313
1396
}
1314
1397
}
1315
1398
0 commit comments