Skip to content

Commit 6dd807e

Browse files
Abandon payment if retry fails in process_pending_htlcs
1 parent 12b47f3 commit 6dd807e

File tree

2 files changed

+57
-4
lines changed

2 files changed

+57
-4
lines changed

lightning/src/ln/channelmanager.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3380,7 +3380,8 @@ where
33803380

33813381
let best_block_height = self.best_block.read().unwrap().height();
33823382
self.pending_outbound_payments.check_retry_payments(&self.router, || self.list_usable_channels(),
3383-
|| self.compute_inflight_htlcs(), &self.entropy_source, &self.node_signer, best_block_height, &self.logger,
3383+
|| self.compute_inflight_htlcs(), &self.entropy_source, &self.node_signer, best_block_height,
3384+
&self.pending_events, &self.logger,
33843385
|path, payment_params, payment_hash, payment_secret, total_value, cur_height, payment_id, keysend_preimage, session_priv|
33853386
self.send_payment_along_path(path, payment_params, payment_hash, payment_secret, total_value, cur_height, payment_id, keysend_preimage, session_priv));
33863387

lightning/src/ln/outbound_payment.rs

Lines changed: 55 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -489,7 +489,8 @@ impl OutboundPayments {
489489

490490
pub(super) fn check_retry_payments<R: Deref, ES: Deref, NS: Deref, SP, IH, FH, L: Deref>(
491491
&self, router: &R, first_hops: FH, inflight_htlcs: IH, entropy_source: &ES, node_signer: &NS,
492-
best_block_height: u32, logger: &L, send_payment_along_path: SP,
492+
best_block_height: u32, pending_events: &Mutex<Vec<events::Event>>, logger: &L,
493+
send_payment_along_path: SP,
493494
)
494495
where
495496
R::Target: Router,
@@ -523,10 +524,11 @@ impl OutboundPayments {
523524
}
524525
}
525526
}
527+
core::mem::drop(outbounds);
526528
if let Some((payment_id, route_params)) = retry_id_route_params {
527-
core::mem::drop(outbounds);
528529
if let Err(e) = self.pay_internal(payment_id, None, route_params, router, first_hops(), inflight_htlcs(), entropy_source, node_signer, best_block_height, logger, &send_payment_along_path) {
529530
log_info!(logger, "Errored retrying payment: {:?}", e);
531+
self.abandon_payment(payment_id, pending_events);
530532
}
531533
} else { break }
532534
}
@@ -1192,18 +1194,19 @@ impl_writeable_tlv_based_enum_upgradable!(PendingOutboundPayment,
11921194

11931195
#[cfg(test)]
11941196
mod tests {
1197+
use super::*;
11951198
use bitcoin::blockdata::constants::genesis_block;
11961199
use bitcoin::network::constants::Network;
11971200
use bitcoin::secp256k1::{PublicKey, Secp256k1, SecretKey};
11981201

11991202
use crate::ln::PaymentHash;
12001203
use crate::ln::channelmanager::{PaymentId, PaymentSendFailure};
12011204
use crate::ln::msgs::{ErrorAction, LightningError};
1202-
use crate::ln::outbound_payment::{OutboundPayments, Retry};
12031205
use crate::routing::gossip::NetworkGraph;
12041206
use crate::routing::router::{InFlightHtlcs, PaymentParameters, Route, RouteParameters};
12051207
use crate::sync::Arc;
12061208
use crate::util::errors::APIError;
1209+
use crate::util::events::Event;
12071210
use crate::util::test_utils;
12081211

12091212
#[test]
@@ -1288,4 +1291,53 @@ mod tests {
12881291
assert!(err.contains("Failed to find a route"));
12891292
} else { panic!("Unexpected error"); }
12901293
}
1294+
1295+
#[test]
1296+
fn fail_on_retry_error() {
1297+
let outbound_payments = OutboundPayments::new();
1298+
let logger = test_utils::TestLogger::new();
1299+
let genesis_hash = genesis_block(Network::Testnet).header.block_hash();
1300+
let network_graph = Arc::new(NetworkGraph::new(genesis_hash, &logger));
1301+
let router = test_utils::TestRouter::new(network_graph);
1302+
let secp_ctx = Secp256k1::new();
1303+
let session_priv = [42; 32];
1304+
let keys_manager = test_utils::TestKeysInterface::new(&[0; 32], Network::Testnet);
1305+
{
1306+
let mut random_bytes_override = keys_manager.override_random_bytes.lock().unwrap();
1307+
*random_bytes_override = Some(session_priv);
1308+
}
1309+
1310+
let payment_params = PaymentParameters::from_node_id(
1311+
PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42; 32]).unwrap()), 0);
1312+
let route_params = RouteParameters {
1313+
payment_params,
1314+
final_value_msat: 1000,
1315+
final_cltv_expiry_delta: 0,
1316+
};
1317+
router.expect_find_route(route_params.clone(),
1318+
Err(LightningError { err: String::new(), action: ErrorAction::IgnoreError }));
1319+
let our_payment_id = PaymentId([0; 32]);
1320+
let our_payment_hash = PaymentHash([0; 32]);
1321+
outbound_payments.add_new_pending_payment(our_payment_hash, None, our_payment_id, None,
1322+
&Route { paths: vec![], payment_params: None }, Some(Retry::Attempts(1)),
1323+
Some(route_params.payment_params.clone()), &&keys_manager, 0).unwrap();
1324+
{
1325+
let mut pending_outbounds = outbound_payments.pending_outbound_payments.lock().unwrap();
1326+
if let Some(PendingOutboundPayment::Retryable { ref mut total_msat, .. }) = pending_outbounds.get_mut(&our_payment_id) {
1327+
*total_msat += 1000;
1328+
}
1329+
}
1330+
1331+
let pending_events_mtx = Mutex::new(vec![]);
1332+
outbound_payments.check_retry_payments(&&router, || vec![], || InFlightHtlcs::new(), &&keys_manager, &&keys_manager, 0, &pending_events_mtx, &&logger, |_, _, _, _, _, _, _, _, _| Ok(()));
1333+
let pending_events = pending_events_mtx.lock().unwrap();
1334+
assert_eq!(pending_events.len(), 1);
1335+
match pending_events[0] {
1336+
Event::PaymentFailed { payment_id, payment_hash } => {
1337+
assert_eq!(payment_id, our_payment_id);
1338+
assert_eq!(payment_hash, our_payment_hash);
1339+
},
1340+
_ => panic!()
1341+
}
1342+
}
12911343
}

0 commit comments

Comments
 (0)