Skip to content

Payment Retries #1059

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
Oct 27, 2021
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions lightning/src/ln/chanmon_update_fail_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -304,7 +304,7 @@ fn do_test_monitor_temporary_update_fail(disconnect_count: usize) {
let events_3 = nodes[0].node.get_and_clear_pending_events();
assert_eq!(events_3.len(), 1);
match events_3[0] {
Event::PaymentSent { ref payment_preimage, ref payment_hash } => {
Event::PaymentSent { payment_id: _, ref payment_preimage, ref payment_hash } => {
assert_eq!(*payment_preimage, payment_preimage_1);
assert_eq!(*payment_hash, payment_hash_1);
},
Expand Down Expand Up @@ -397,7 +397,7 @@ fn do_test_monitor_temporary_update_fail(disconnect_count: usize) {
let events_3 = nodes[0].node.get_and_clear_pending_events();
assert_eq!(events_3.len(), 1);
match events_3[0] {
Event::PaymentSent { ref payment_preimage, ref payment_hash } => {
Event::PaymentSent { payment_id: _, ref payment_preimage, ref payment_hash } => {
assert_eq!(*payment_preimage, payment_preimage_1);
assert_eq!(*payment_hash, payment_hash_1);
},
Expand Down Expand Up @@ -1399,7 +1399,7 @@ fn claim_while_disconnected_monitor_update_fail() {
let events = nodes[0].node.get_and_clear_pending_events();
assert_eq!(events.len(), 1);
match events[0] {
Event::PaymentSent { ref payment_preimage, ref payment_hash } => {
Event::PaymentSent { payment_id: _, ref payment_preimage, ref payment_hash } => {
assert_eq!(*payment_preimage, payment_preimage_1);
assert_eq!(*payment_hash, payment_hash_1);
},
Expand Down Expand Up @@ -1806,7 +1806,7 @@ fn monitor_update_claim_fail_no_response() {
let events = nodes[0].node.get_and_clear_pending_events();
assert_eq!(events.len(), 1);
match events[0] {
Event::PaymentSent { ref payment_preimage, ref payment_hash } => {
Event::PaymentSent { payment_id: _, ref payment_preimage, ref payment_hash } => {
assert_eq!(*payment_preimage, payment_preimage_1);
assert_eq!(*payment_hash, payment_hash_1);
},
Expand Down
4 changes: 3 additions & 1 deletion lightning/src/ln/channelmanager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3475,6 +3475,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
let payment_hash = PaymentHash(Sha256::hash(&payment_preimage.0).into_inner());
self.pending_events.lock().unwrap().push(
events::Event::PaymentSent {
payment_id: Some(payment_id),
payment_preimage,
payment_hash: payment_hash
}
Expand Down Expand Up @@ -6256,7 +6257,8 @@ mod tests {
// further events will be generated for subsequence path successes.
let events = nodes[0].node.get_and_clear_pending_events();
match events[0] {
Event::PaymentSent { payment_preimage: ref preimage, payment_hash: ref hash } => {
Event::PaymentSent { payment_id: ref id, payment_preimage: ref preimage, payment_hash: ref hash } => {
assert_eq!(Some(payment_id), *id);
assert_eq!(payment_preimage, *preimage);
assert_eq!(our_payment_hash, *hash);
},
Expand Down
2 changes: 1 addition & 1 deletion lightning/src/ln/functional_test_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1085,7 +1085,7 @@ macro_rules! expect_payment_sent {
let expected_payment_hash = PaymentHash(Sha256::hash(&$expected_payment_preimage.0).into_inner());
assert_eq!(events.len(), 1);
match events[0] {
Event::PaymentSent { ref payment_preimage, ref payment_hash } => {
Event::PaymentSent { payment_id: _, ref payment_preimage, ref payment_hash } => {
assert_eq!($expected_payment_preimage, *payment_preimage);
assert_eq!(expected_payment_hash, *payment_hash);
},
Expand Down
16 changes: 8 additions & 8 deletions lightning/src/ln/functional_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2659,7 +2659,7 @@ fn test_htlc_on_chain_success() {
let mut first_claimed = false;
for event in events {
match event {
Event::PaymentSent { payment_preimage, payment_hash } => {
Event::PaymentSent { payment_id: _, payment_preimage, payment_hash } => {
if payment_preimage == our_payment_preimage && payment_hash == payment_hash_1 {
assert!(!first_claimed);
first_claimed = true;
Expand Down Expand Up @@ -3350,7 +3350,7 @@ fn test_simple_peer_disconnect() {
let events = nodes[0].node.get_and_clear_pending_events();
assert_eq!(events.len(), 2);
match events[0] {
Event::PaymentSent { payment_preimage, payment_hash } => {
Event::PaymentSent { payment_id: _, payment_preimage, payment_hash } => {
assert_eq!(payment_preimage, payment_preimage_3);
assert_eq!(payment_hash, payment_hash_3);
},
Expand Down Expand Up @@ -3514,7 +3514,7 @@ fn do_test_drop_messages_peer_disconnect(messages_delivered: u8, simulate_broken
let events_4 = nodes[0].node.get_and_clear_pending_events();
assert_eq!(events_4.len(), 1);
match events_4[0] {
Event::PaymentSent { ref payment_preimage, ref payment_hash } => {
Event::PaymentSent { payment_id: _, ref payment_preimage, ref payment_hash } => {
assert_eq!(payment_preimage_1, *payment_preimage);
assert_eq!(payment_hash_1, *payment_hash);
},
Expand Down Expand Up @@ -3555,7 +3555,7 @@ fn do_test_drop_messages_peer_disconnect(messages_delivered: u8, simulate_broken
let events_4 = nodes[0].node.get_and_clear_pending_events();
assert_eq!(events_4.len(), 1);
match events_4[0] {
Event::PaymentSent { ref payment_preimage, ref payment_hash } => {
Event::PaymentSent { payment_id: _, ref payment_preimage, ref payment_hash } => {
assert_eq!(payment_preimage_1, *payment_preimage);
assert_eq!(payment_hash_1, *payment_hash);
},
Expand Down Expand Up @@ -3790,7 +3790,7 @@ fn test_drop_messages_peer_disconnect_dual_htlc() {
let events_3 = nodes[0].node.get_and_clear_pending_events();
assert_eq!(events_3.len(), 1);
match events_3[0] {
Event::PaymentSent { ref payment_preimage, ref payment_hash } => {
Event::PaymentSent { payment_id: _, ref payment_preimage, ref payment_hash } => {
assert_eq!(*payment_preimage, payment_preimage_1);
assert_eq!(*payment_hash, payment_hash_1);
},
Expand Down Expand Up @@ -5059,7 +5059,7 @@ fn test_duplicate_payment_hash_one_failure_one_success() {

let events = nodes[0].node.get_and_clear_pending_events();
match events[0] {
Event::PaymentSent { ref payment_preimage, ref payment_hash } => {
Event::PaymentSent { payment_id: _, ref payment_preimage, ref payment_hash } => {
assert_eq!(*payment_preimage, our_payment_preimage);
assert_eq!(*payment_hash, duplicate_payment_hash);
}
Expand Down Expand Up @@ -5572,7 +5572,7 @@ fn do_htlc_claim_local_commitment_only(use_dust: bool) {
let events = nodes[0].node.get_and_clear_pending_events();
assert_eq!(events.len(), 1);
match events[0] {
Event::PaymentSent { payment_preimage, payment_hash } => {
Event::PaymentSent { payment_id: _, payment_preimage, payment_hash } => {
assert_eq!(payment_preimage, our_payment_preimage);
assert_eq!(payment_hash, our_payment_hash);
},
Expand Down Expand Up @@ -6000,7 +6000,7 @@ fn test_free_and_fail_holding_cell_htlcs() {
let events = nodes[0].node.get_and_clear_pending_events();
assert_eq!(events.len(), 1);
match events[0] {
Event::PaymentSent { ref payment_preimage, ref payment_hash } => {
Event::PaymentSent { payment_id: _, ref payment_preimage, ref payment_hash } => {
assert_eq!(*payment_preimage, payment_preimage_1);
assert_eq!(*payment_hash, payment_hash_1);
}
Expand Down
4 changes: 2 additions & 2 deletions lightning/src/ln/shutdown_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ fn updates_shutdown_wait() {
let events = nodes[0].node.get_and_clear_pending_events();
assert_eq!(events.len(), 1);
match events[0] {
Event::PaymentSent { ref payment_preimage, ref payment_hash } => {
Event::PaymentSent { payment_id: _, ref payment_preimage, ref payment_hash } => {
assert_eq!(our_payment_preimage, *payment_preimage);
assert_eq!(our_payment_hash, *payment_hash);
},
Expand Down Expand Up @@ -309,7 +309,7 @@ fn do_test_shutdown_rebroadcast(recv_count: u8) {
let events = nodes[0].node.get_and_clear_pending_events();
assert_eq!(events.len(), 1);
match events[0] {
Event::PaymentSent { ref payment_preimage, ref payment_hash } => {
Event::PaymentSent { payment_id: _, ref payment_preimage, ref payment_hash } => {
assert_eq!(our_payment_preimage, *payment_preimage);
assert_eq!(our_payment_hash, *payment_hash);
},
Expand Down
13 changes: 12 additions & 1 deletion lightning/src/util/events.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
//! few other things.

use chain::keysinterface::SpendableOutputDescriptor;
use ln::channelmanager::PaymentId;
use ln::msgs;
use ln::msgs::DecodeError;
use ln::{PaymentPreimage, PaymentHash, PaymentSecret};
Expand Down Expand Up @@ -178,6 +179,12 @@ pub enum Event {
/// Note for MPP payments: in rare cases, this event may be preceded by a `PaymentPathFailed`
/// event. In this situation, you SHOULD treat this payment as having succeeded.
PaymentSent {
/// The id returned by [`ChannelManager::send_payment`] and used with
/// [`ChannelManager::retry_payment`].
///
/// [`ChannelManager::send_payment`]: crate::ln::channelmanager::ChannelManager::send_payment
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, I just noticed that documentation for payment_id seems to be missing from ChannelMannager::send_payment. It would be nice to (a) document that the id should be stored for a retry, and (b) that it's needed because technically PaymentHashs can be non-unique.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Leaving unresolved pending discussions around changes to send_payment.

/// [`ChannelManager::retry_payment`]: crate::ln::channelmanager::ChannelManager::retry_payment
payment_id: Option<PaymentId>,
/// The preimage to the hash given to ChannelManager::send_payment.
/// Note that this serves as a payment receipt, if you wish to have such a thing, you must
/// store it somehow!
Expand Down Expand Up @@ -322,11 +329,12 @@ impl Writeable for Event {
(8, payment_preimage, option),
});
},
&Event::PaymentSent { ref payment_preimage, ref payment_hash} => {
&Event::PaymentSent { ref payment_id, ref payment_preimage, ref payment_hash} => {
2u8.write(writer)?;
write_tlv_fields!(writer, {
(0, payment_preimage, required),
(1, payment_hash, required),
(3, payment_id, option),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it'd be a little nicer public API-wise if payment_id were a non-Option, and set to 0 if serialized before 0.0.104 (or wtv). Similar for the next commit.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we leave it an Option for now and then just do a hard-break on our serialization backwards compat in like 2-3 versions?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fine by me! 🙂

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, maybe that is why we decided to key by payment_hash for now? I guess we could just not retry if PaymentId is None, though.

});
},
&Event::PaymentPathFailed {
Expand Down Expand Up @@ -435,14 +443,17 @@ impl MaybeReadable for Event {
let f = || {
let mut payment_preimage = PaymentPreimage([0; 32]);
let mut payment_hash = None;
let mut payment_id = None;
read_tlv_fields!(reader, {
(0, payment_preimage, required),
(1, payment_hash, option),
(3, payment_id, option),
});
if payment_hash.is_none() {
payment_hash = Some(PaymentHash(Sha256::hash(&payment_preimage.0[..]).into_inner()));
}
Ok(Some(Event::PaymentSent {
payment_id,
payment_preimage,
payment_hash: payment_hash.unwrap(),
}))
Expand Down