Skip to content

Commit b60dca5

Browse files
committed
Add reason to Event::PaymentFailed
1 parent e886138 commit b60dca5

File tree

6 files changed

+39
-19
lines changed

6 files changed

+39
-19
lines changed

lightning/src/events/mod.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -463,6 +463,8 @@ pub enum Event {
463463
///
464464
/// [`ChannelManager::send_payment`]: crate::ln::channelmanager::ChannelManager::send_payment
465465
payment_hash: PaymentHash,
466+
/// The reason the payment failed.
467+
reason: PaymentFailureReason
466468
},
467469
/// Indicates that a path for an outbound payment was successful.
468470
///
@@ -901,10 +903,11 @@ impl Writeable for Event {
901903
(4, *path, vec_type)
902904
})
903905
},
904-
&Event::PaymentFailed { ref payment_id, ref payment_hash } => {
906+
&Event::PaymentFailed { ref payment_id, ref payment_hash, ref reason } => {
905907
15u8.write(writer)?;
906908
write_tlv_fields!(writer, {
907909
(0, payment_id, required),
910+
(1, reason, required),
908911
(2, payment_hash, required),
909912
})
910913
},
@@ -1193,13 +1196,16 @@ impl MaybeReadable for Event {
11931196
let f = || {
11941197
let mut payment_hash = PaymentHash([0; 32]);
11951198
let mut payment_id = PaymentId([0; 32]);
1199+
let mut reason = UpgradableRequired(None);
11961200
read_tlv_fields!(reader, {
11971201
(0, payment_id, required),
1202+
(1, reason, upgradable_required),
11981203
(2, payment_hash, required),
11991204
});
12001205
Ok(Some(Event::PaymentFailed {
12011206
payment_id,
12021207
payment_hash,
1208+
reason: _init_tlv_based_struct_field!(reason, upgradable_required),
12031209
}))
12041210
};
12051211
f()

lightning/src/ln/functional_test_utils.rs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
use crate::chain::{BestBlock, ChannelMonitorUpdateStatus, Confirm, Listen, Watch, keysinterface::EntropySource};
1414
use crate::chain::channelmonitor::ChannelMonitor;
1515
use crate::chain::transaction::OutPoint;
16-
use crate::events::{ClosureReason, Event, HTLCDestination, MessageSendEvent, MessageSendEventsProvider, PathFailure, PaymentPurpose};
16+
use crate::events::{ClosureReason, Event, HTLCDestination, MessageSendEvent, MessageSendEventsProvider, PathFailure, PaymentPurpose, PaymentFailureReason};
1717
use crate::ln::{PaymentPreimage, PaymentHash, PaymentSecret};
1818
use crate::ln::channelmanager::{ChainParameters, ChannelManager, ChannelManagerReadArgs, RAACommitmentOrder, PaymentSendFailure, PaymentId, MIN_CLTV_EXPIRY_DELTA};
1919
use crate::routing::gossip::{P2PGossipSync, NetworkGraph, NetworkUpdate};
@@ -1920,9 +1920,10 @@ pub fn expect_payment_failed_conditions_event<'a, 'b, 'c, 'd, 'e>(
19201920
};
19211921
if !conditions.expected_mpp_parts_remain {
19221922
match &payment_failed_events[1] {
1923-
Event::PaymentFailed { ref payment_hash, ref payment_id } => {
1923+
Event::PaymentFailed { ref payment_hash, ref payment_id, ref reason } => {
19241924
assert_eq!(*payment_hash, expected_payment_hash, "unexpected second payment_hash");
19251925
assert_eq!(*payment_id, expected_payment_id);
1926+
assert_eq!(*reason, PaymentFailureReason::RecipientRejected);
19261927
}
19271928
_ => panic!("Unexpected second event"),
19281929
}
@@ -2216,10 +2217,10 @@ pub fn fail_payment_along_route<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, expe
22162217
let expected_destinations: Vec<HTLCDestination> = repeat(HTLCDestination::FailedPayment { payment_hash: our_payment_hash }).take(expected_paths.len()).collect();
22172218
expect_pending_htlcs_forwardable_and_htlc_handling_failed!(expected_paths[0].last().unwrap(), expected_destinations);
22182219

2219-
pass_failed_payment_back(origin_node, expected_paths, skip_last, our_payment_hash);
2220+
pass_failed_payment_back(origin_node, expected_paths, skip_last, our_payment_hash, PaymentFailureReason::RecipientRejected);
22202221
}
22212222

2222-
pub fn pass_failed_payment_back<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, expected_paths_slice: &[&[&Node<'a, 'b, 'c>]], skip_last: bool, our_payment_hash: PaymentHash) {
2223+
pub fn pass_failed_payment_back<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, expected_paths_slice: &[&[&Node<'a, 'b, 'c>]], skip_last: bool, our_payment_hash: PaymentHash, expected_fail_reason: PaymentFailureReason) {
22232224
let mut expected_paths: Vec<_> = expected_paths_slice.iter().collect();
22242225
check_added_monitors!(expected_paths[0].last().unwrap(), expected_paths.len());
22252226

@@ -2305,9 +2306,10 @@ pub fn pass_failed_payment_back<'a, 'b, 'c>(origin_node: &Node<'a, 'b, 'c>, expe
23052306
};
23062307
if i == expected_paths.len() - 1 {
23072308
match events[1] {
2308-
Event::PaymentFailed { ref payment_hash, ref payment_id } => {
2309+
Event::PaymentFailed { ref payment_hash, ref payment_id, ref reason } => {
23092310
assert_eq!(*payment_hash, our_payment_hash, "unexpected second payment_hash");
23102311
assert_eq!(*payment_id, expected_payment_id);
2312+
assert_eq!(*reason, expected_fail_reason);
23112313
}
23122314
_ => panic!("Unexpected second event"),
23132315
}

lightning/src/ln/functional_tests.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use crate::chain::channelmonitor;
1818
use crate::chain::channelmonitor::{CLTV_CLAIM_BUFFER, LATENCY_GRACE_PERIOD_BLOCKS, ANTI_REORG_DELAY};
1919
use crate::chain::transaction::OutPoint;
2020
use crate::chain::keysinterface::{ChannelSigner, EcdsaChannelSigner, EntropySource};
21-
use crate::events::{Event, MessageSendEvent, MessageSendEventsProvider, PathFailure, PaymentPurpose, ClosureReason, HTLCDestination};
21+
use crate::events::{Event, MessageSendEvent, MessageSendEventsProvider, PathFailure, PaymentPurpose, ClosureReason, HTLCDestination, PaymentFailureReason};
2222
use crate::ln::{PaymentPreimage, PaymentSecret, PaymentHash};
2323
use crate::ln::channel::{commitment_tx_base_weight, COMMITMENT_TX_WEIGHT_PER_HTLC, CONCURRENT_INBOUND_HTLC_FEE_BUFFER, FEE_SPIKE_BUFFER_FEE_INCREASE_MULTIPLE, MIN_AFFORDABLE_HTLC_COUNT};
2424
use crate::ln::channelmanager::{self, PaymentId, RAACommitmentOrder, PaymentSendFailure, BREAKDOWN_TIMEOUT, MIN_CLTV_EXPIRY_DELTA};
@@ -9501,7 +9501,7 @@ fn test_double_partial_claim() {
95019501
];
95029502
expect_pending_htlcs_forwardable_and_htlc_handling_failed!(nodes[3], failed_destinations);
95039503

9504-
pass_failed_payment_back(&nodes[0], &[&[&nodes[1], &nodes[3]], &[&nodes[2], &nodes[3]]], false, payment_hash);
9504+
pass_failed_payment_back(&nodes[0], &[&[&nodes[1], &nodes[3]], &[&nodes[2], &nodes[3]]], false, payment_hash, PaymentFailureReason::RecipientRejected);
95059505

95069506
// nodes[1] now retries one of the two paths...
95079507
nodes[0].node.send_payment(&route, payment_hash, &Some(payment_secret), PaymentId(payment_hash.0)).unwrap();

lightning/src/ln/onion_route_tests.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
1414
use crate::chain::channelmonitor::{CLTV_CLAIM_BUFFER, LATENCY_GRACE_PERIOD_BLOCKS};
1515
use crate::chain::keysinterface::{EntropySource, NodeSigner, Recipient};
16-
use crate::events::{Event, HTLCDestination, MessageSendEvent, MessageSendEventsProvider, PathFailure};
16+
use crate::events::{Event, HTLCDestination, MessageSendEvent, MessageSendEventsProvider, PathFailure, PaymentFailureReason};
1717
use crate::ln::{PaymentHash, PaymentSecret};
1818
use crate::ln::channel::EXPIRE_PREV_CONFIG_TICKS;
1919
use crate::ln::channelmanager::{HTLCForwardInfo, FailureCode, CLTV_FAR_FAR_AWAY, MIN_CLTV_EXPIRY_DELTA, PendingAddHTLCInfo, PendingHTLCInfo, PendingHTLCRouting, PaymentId};
@@ -212,9 +212,10 @@ fn run_onion_failure_test_with_fail_intercept<F1,F2,F3>(_name: &str, test_case:
212212
panic!("Unexpected event");
213213
}
214214
match events[1] {
215-
Event::PaymentFailed { payment_hash: ev_payment_hash, payment_id: ev_payment_id } => {
215+
Event::PaymentFailed { payment_hash: ev_payment_hash, payment_id: ev_payment_id, reason: ref ev_reason } => {
216216
assert_eq!(*payment_hash, ev_payment_hash);
217217
assert_eq!(payment_id, ev_payment_id);
218+
assert_eq!(PaymentFailureReason::RecipientRejected, *ev_reason);
218219
}
219220
_ => panic!("Unexpected second event"),
220221
}

lightning/src/ln/outbound_payment.rs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -550,6 +550,7 @@ impl OutboundPayments {
550550
pending_events.lock().unwrap().push(events::Event::PaymentFailed {
551551
payment_id: *pmt_id,
552552
payment_hash: pmt.payment_hash().expect("PendingOutboundPayments::Retryable always has a payment hash set"),
553+
reason: events::PaymentFailureReason::ExhaustedRetryAttempts
553554
});
554555
retain = false;
555556
}
@@ -666,6 +667,7 @@ impl OutboundPayments {
666667
pending_events.lock().unwrap().push(events::Event::PaymentFailed {
667668
payment_id,
668669
payment_hash,
670+
reason: $reason,
669671
});
670672
$payment.remove();
671673
}
@@ -1176,6 +1178,7 @@ impl OutboundPayments {
11761178
full_failure_ev = Some(events::Event::PaymentFailed {
11771179
payment_id: *payment_id,
11781180
payment_hash: payment.get().payment_hash().expect("PendingOutboundPayments::RetriesExceeded always has a payment hash set"),
1181+
reason: PaymentFailureReason::RecipientRejected
11791182
});
11801183
}
11811184
payment.remove();
@@ -1242,6 +1245,7 @@ impl OutboundPayments {
12421245
pending_events.lock().unwrap().push(events::Event::PaymentFailed {
12431246
payment_id,
12441247
payment_hash: payment.get().payment_hash().expect("PendingOutboundPayments::RetriesExceeded always has a payment hash set"),
1248+
reason,
12451249
});
12461250
payment.remove();
12471251
}
@@ -1312,7 +1316,7 @@ mod tests {
13121316
use bitcoin::network::constants::Network;
13131317
use bitcoin::secp256k1::{PublicKey, Secp256k1, SecretKey};
13141318

1315-
use crate::events::{Event, PathFailure};
1319+
use crate::events::{Event, PathFailure, PaymentFailureReason};
13161320
use crate::ln::PaymentHash;
13171321
use crate::ln::channelmanager::PaymentId;
13181322
use crate::ln::features::{ChannelFeatures, NodeFeatures};
@@ -1332,6 +1336,7 @@ mod tests {
13321336
}
13331337
#[cfg(feature = "std")]
13341338
fn do_fails_paying_after_expiration(on_retry: bool) {
1339+
13351340
let outbound_payments = OutboundPayments::new();
13361341
let logger = test_utils::TestLogger::new();
13371342
let network_graph = Arc::new(NetworkGraph::new(Network::Testnet, &logger));
@@ -1360,7 +1365,9 @@ mod tests {
13601365
&pending_events, &|_, _, _, _, _, _, _, _| Ok(()));
13611366
let events = pending_events.lock().unwrap();
13621367
assert_eq!(events.len(), 1);
1363-
if let Event::PaymentFailed { .. } = events[0] { } else { panic!("Unexpected event"); }
1368+
if let Event::PaymentFailed { ref reason, .. } = events[0] {
1369+
assert_eq!(*reason, PaymentFailureReason::PaymentExpired);
1370+
} else { panic!("Unexpected event"); }
13641371
} else {
13651372
let err = outbound_payments.send_payment(
13661373
PaymentHash([0; 32]), &None, PaymentId([0; 32]), Retry::Attempts(0), expired_route_params,

lightning/src/ln/payment_tests.rs

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use crate::chain::{ChannelMonitorUpdateStatus, Confirm, Listen, Watch};
1515
use crate::chain::channelmonitor::{ANTI_REORG_DELAY, LATENCY_GRACE_PERIOD_BLOCKS};
1616
use crate::chain::keysinterface::EntropySource;
1717
use crate::chain::transaction::OutPoint;
18-
use crate::events::{ClosureReason, Event, HTLCDestination, MessageSendEvent, MessageSendEventsProvider, PathFailure};
18+
use crate::events::{ClosureReason, Event, HTLCDestination, MessageSendEvent, MessageSendEventsProvider, PathFailure, PaymentFailureReason};
1919
use crate::ln::channel::EXPIRE_PREV_CONFIG_TICKS;
2020
use crate::ln::channelmanager::{BREAKDOWN_TIMEOUT, ChannelManager, MPP_TIMEOUT_TICKS, MIN_CLTV_EXPIRY_DELTA, PaymentId, PaymentSendFailure, IDEMPOTENCY_TIMEOUT_TICKS, RecentPaymentDetails};
2121
use crate::ln::features::InvoiceFeatures;
@@ -1169,7 +1169,7 @@ fn abandoned_send_payment_idempotent() {
11691169
}
11701170
check_send_rejected!();
11711171

1172-
pass_failed_payment_back(&nodes[0], &[&[&nodes[1]]], false, first_payment_hash);
1172+
pass_failed_payment_back(&nodes[0], &[&[&nodes[1]]], false, first_payment_hash, PaymentFailureReason::RecipientRejected);
11731173

11741174
// However, we can reuse the PaymentId immediately after we `abandon_payment` upon passing the
11751175
// failed payment back.
@@ -1702,9 +1702,10 @@ fn do_automatic_retries(test: AutoRetry) {
17021702
let mut events = nodes[0].node.get_and_clear_pending_events();
17031703
assert_eq!(events.len(), 1);
17041704
match events[0] {
1705-
Event::PaymentFailed { payment_hash: ref ev_payment_hash, payment_id: ref ev_payment_id } => {
1705+
Event::PaymentFailed { payment_hash: ref ev_payment_hash, payment_id: ref ev_payment_id, reason: ref ev_reason } => {
17061706
assert_eq!(payment_hash, *ev_payment_hash);
17071707
assert_eq!(PaymentId(payment_hash.0), *ev_payment_id);
1708+
assert_eq!(PaymentFailureReason::ExhaustedRetryAttempts, *ev_reason);
17081709
},
17091710
_ => panic!("Unexpected event"),
17101711
}
@@ -1737,9 +1738,10 @@ fn do_automatic_retries(test: AutoRetry) {
17371738
let mut events = nodes[0].node.get_and_clear_pending_events();
17381739
assert_eq!(events.len(), 1);
17391740
match events[0] {
1740-
Event::PaymentFailed { payment_hash: ref ev_payment_hash, payment_id: ref ev_payment_id } => {
1741+
Event::PaymentFailed { payment_hash: ref ev_payment_hash, payment_id: ref ev_payment_id, reason: ref ev_reason } => {
17411742
assert_eq!(payment_hash, *ev_payment_hash);
17421743
assert_eq!(PaymentId(payment_hash.0), *ev_payment_id);
1744+
assert_eq!(PaymentFailureReason::ExhaustedRetryAttempts, *ev_reason);
17431745
},
17441746
_ => panic!("Unexpected event"),
17451747
}
@@ -1756,9 +1758,10 @@ fn do_automatic_retries(test: AutoRetry) {
17561758
let mut events = nodes[0].node.get_and_clear_pending_events();
17571759
assert_eq!(events.len(), 1);
17581760
match events[0] {
1759-
Event::PaymentFailed { payment_hash: ref ev_payment_hash, payment_id: ref ev_payment_id } => {
1761+
Event::PaymentFailed { payment_hash: ref ev_payment_hash, payment_id: ref ev_payment_id, reason: ref ev_reason } => {
17601762
assert_eq!(payment_hash, *ev_payment_hash);
17611763
assert_eq!(PaymentId(payment_hash.0), *ev_payment_id);
1764+
assert_eq!(PaymentFailureReason::FailedRoutingRetry, *ev_reason);
17621765
},
17631766
_ => panic!("Unexpected event"),
17641767
}
@@ -2059,7 +2062,7 @@ fn fails_paying_after_rejected_by_payee() {
20592062

20602063
nodes[1].node.fail_htlc_backwards(&payment_hash);
20612064
expect_pending_htlcs_forwardable_and_htlc_handling_failed!(nodes[1], [HTLCDestination::FailedPayment { payment_hash }]);
2062-
pass_failed_payment_back(&nodes[0], &[&[&nodes[1]]], false, payment_hash);
2065+
pass_failed_payment_back(&nodes[0], &[&[&nodes[1]]], false, payment_hash, PaymentFailureReason::RecipientRejected);
20632066
}
20642067

20652068
#[test]
@@ -2432,9 +2435,10 @@ fn no_extra_retries_on_back_to_back_fail() {
24322435
_ => panic!("Unexpected event"),
24332436
}
24342437
match events[1] {
2435-
Event::PaymentFailed { payment_hash: ref ev_payment_hash, payment_id: ref ev_payment_id } => {
2438+
Event::PaymentFailed { payment_hash: ref ev_payment_hash, payment_id: ref ev_payment_id, reason: ref ev_reason } => {
24362439
assert_eq!(payment_hash, *ev_payment_hash);
24372440
assert_eq!(PaymentId(payment_hash.0), *ev_payment_id);
2441+
assert_eq!(PaymentFailureReason::RecipientRejected, *ev_reason);
24382442
},
24392443
_ => panic!("Unexpected event"),
24402444
}

0 commit comments

Comments
 (0)