Skip to content

Commit 16ca659

Browse files
committed
Test retrying payment on partial send failure
Add some test coverage for when InvoicePayer retries within pay_invoice because the Payer returned a partial failure.
1 parent 0d8e4e7 commit 16ca659

File tree

1 file changed

+48
-10
lines changed

1 file changed

+48
-10
lines changed

lightning-invoice/src/payment.rs

Lines changed: 48 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -627,6 +627,30 @@ mod tests {
627627
assert_eq!(*payer.attempts.borrow(), 2);
628628
}
629629

630+
#[test]
631+
fn pays_invoice_on_partial_failure() {
632+
let event_handler = |_: &_| { panic!() };
633+
634+
let payment_preimage = PaymentPreimage([1; 32]);
635+
let invoice = invoice(payment_preimage);
636+
let retry = TestRouter::retry_for_invoice(&invoice);
637+
let final_value_msat = invoice.amount_milli_satoshis().unwrap();
638+
639+
let payer = TestPayer::new()
640+
.fails_with_partial_failure(retry.clone(), OnAttempt(1))
641+
.fails_with_partial_failure(retry, OnAttempt(2))
642+
.expect_send(Amount::ForInvoice(final_value_msat))
643+
.expect_send(Amount::OnRetry(final_value_msat / 2))
644+
.expect_send(Amount::OnRetry(final_value_msat / 2));
645+
let router = TestRouter {};
646+
let scorer = RefCell::new(TestScorer::new());
647+
let logger = TestLogger::new();
648+
let invoice_payer =
649+
InvoicePayer::new(&payer, router, &scorer, &logger, event_handler, RetryAttempts(2));
650+
651+
assert!(invoice_payer.pay_invoice(&invoice).is_ok());
652+
}
653+
630654
#[test]
631655
fn retries_payment_path_for_unknown_payment() {
632656
let event_handled = core::cell::RefCell::new(false);
@@ -1232,7 +1256,7 @@ mod tests {
12321256
struct TestPayer {
12331257
expectations: core::cell::RefCell<VecDeque<Amount>>,
12341258
attempts: core::cell::RefCell<usize>,
1235-
failing_on_attempt: Option<usize>,
1259+
failing_on_attempt: core::cell::RefCell<HashMap<usize, PaymentSendFailure>>,
12361260
}
12371261

12381262
#[derive(Clone, Debug, PartialEq, Eq)]
@@ -1242,12 +1266,14 @@ mod tests {
12421266
OnRetry(u64),
12431267
}
12441268

1269+
struct OnAttempt(usize);
1270+
12451271
impl TestPayer {
12461272
fn new() -> Self {
12471273
Self {
12481274
expectations: core::cell::RefCell::new(VecDeque::new()),
12491275
attempts: core::cell::RefCell::new(0),
1250-
failing_on_attempt: None,
1276+
failing_on_attempt: core::cell::RefCell::new(HashMap::new()),
12511277
}
12521278
}
12531279

@@ -1257,27 +1283,39 @@ mod tests {
12571283
}
12581284

12591285
fn fails_on_attempt(self, attempt: usize) -> Self {
1260-
Self {
1261-
expectations: core::cell::RefCell::new(self.expectations.borrow().clone()),
1262-
attempts: core::cell::RefCell::new(0),
1263-
failing_on_attempt: Some(attempt),
1264-
}
1286+
let failure = PaymentSendFailure::ParameterError(APIError::MonitorUpdateFailed);
1287+
self.fails_with(failure, OnAttempt(attempt))
1288+
}
1289+
1290+
fn fails_with_partial_failure(self, retry: RouteParameters, attempt: OnAttempt) -> Self {
1291+
self.fails_with(PaymentSendFailure::PartialFailure {
1292+
results: vec![],
1293+
failed_paths_retry: Some(retry),
1294+
payment_id: PaymentId([1; 32]),
1295+
}, attempt)
1296+
}
1297+
1298+
fn fails_with(self, failure: PaymentSendFailure, attempt: OnAttempt) -> Self {
1299+
self.failing_on_attempt.borrow_mut().insert(attempt.0, failure);
1300+
self
12651301
}
12661302

12671303
fn check_attempts(&self) -> Result<PaymentId, PaymentSendFailure> {
12681304
let mut attempts = self.attempts.borrow_mut();
12691305
*attempts += 1;
1270-
match self.failing_on_attempt {
1306+
1307+
match self.failing_on_attempt.borrow_mut().remove(&*attempts) {
1308+
Some(failure) => Err(failure),
12711309
None => Ok(PaymentId([1; 32])),
1272-
Some(attempt) if attempt != *attempts => Ok(PaymentId([1; 32])),
1273-
Some(_) => Err(PaymentSendFailure::ParameterError(APIError::MonitorUpdateFailed)),
12741310
}
12751311
}
12761312

12771313
fn check_value_msats(&self, actual_value_msats: Amount) {
12781314
let expected_value_msats = self.expectations.borrow_mut().pop_front();
12791315
if let Some(expected_value_msats) = expected_value_msats {
12801316
assert_eq!(actual_value_msats, expected_value_msats);
1317+
} else {
1318+
panic!("Unexpected amount: {:?}", actual_value_msats);
12811319
}
12821320
}
12831321
}

0 commit comments

Comments
 (0)