-
Notifications
You must be signed in to change notification settings - Fork 399
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
Async receive prefactor #3517
Async receive prefactor #3517
Conversation
e984b03
to
50fb8fe
Compare
@@ -1045,6 +1045,11 @@ impl OutboundPayments { | |||
abandon_with_entry!(entry, PaymentFailureReason::UnknownRequiredFeatures); | |||
return Err(Bolt12PaymentError::UnknownRequiredFeatures) | |||
} | |||
if duration_since_epoch > invoice.created_at().saturating_add(invoice.relative_expiry()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note for reviewers: for inbound payments, we buffer expiries by 2 hours to account for inaccurate block times in no-std
. So we could do that here too, but it seemed maybe unnecessary since static invoices are expected to have quite long expiries... Let me know if we'd prefer to do that. (Our other outbound expiry checks are std
-only, but I wanted no-std
here for ease of testing).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't think it matters much, but given we already do it in a few places seems like we could DRY it up into a utility function and do the offset. 🤷♂️
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I looked for a bit and couldn't find a good place to put the util (invoice_utils
might make sense but it's being deprecated IIUC?). So I might just leave this as-is until/unless we refactor outbound_payments to detect expired invoices in no-std
more generally.
50fb8fe
to
ddaf22f
Compare
Rebased on main after #3408 landed. |
@@ -1045,6 +1045,11 @@ impl OutboundPayments { | |||
abandon_with_entry!(entry, PaymentFailureReason::UnknownRequiredFeatures); | |||
return Err(Bolt12PaymentError::UnknownRequiredFeatures) | |||
} | |||
if duration_since_epoch > invoice.created_at().saturating_add(invoice.relative_expiry()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't think it matters much, but given we already do it in a few places seems like we could DRY it up into a utility function and do the offset. 🤷♂️
/// blinded path was not used. | ||
/// | ||
/// Used in part to determine the [`events::PaymentPurpose`]. | ||
payment_context: Option<PaymentContext>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, do we actually have to store the new field here? ISTM we could just fail earlier in create_recv_pending_htlc_info
, but do we need the new field for the full async receive work?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point, but yeah we do need the new field in #3440. Amended the commit message.
ddaf22f
to
ff84599
Compare
Squash-pushed with two small changes: diff --git a/lightning/src/ln/offers_tests.rs b/lightning/src/ln/offers_tests.rs
index 3f8f5a3fb..803441f09 100644
--- a/lightning/src/ln/offers_tests.rs
+++ b/lightning/src/ln/offers_tests.rs
@@ -2316,9 +2316,6 @@ fn rejects_keysend_to_non_static_invoice_path() {
nodes[0].node.handle_update_fail_htlc(nodes[1].node.get_our_node_id(), &updates.update_fail_htlcs[0]);
do_commitment_signed_dance(&nodes[0], &nodes[1], &updates.commitment_signed, false, false);
expect_payment_failed_conditions(&nodes[0], payment_hash, true, PaymentFailedConditions::new());
- nodes[1].logger.assert_log_contains(
- "lightning::ln::channelmanager", "received a keysend payment to a non-async payments context", 1
- );
}
#[test]
diff --git a/lightning/src/ln/outbound_payment.rs b/lightning/src/ln/outbound_payment.rs
index 743fff45e..38f841eac 100644
--- a/lightning/src/ln/outbound_payment.rs
+++ b/lightning/src/ln/outbound_payment.rs
@@ -458,7 +458,8 @@ impl_writeable_tlv_based_enum_legacy!(StaleExpiration,
/// [`Event::PaymentFailed`]: crate::events::Event::PaymentFailed
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum RetryableSendFailure {
- /// The provided [`PaymentParameters::expiry_time`] indicated that the payment has expired.
+ /// The provided invoice or [`PaymentParameters::expiry_time`] indicated that the payment has
+ /// expired.
#[cfg_attr(feature = "std", doc = "")]
#[cfg_attr(feature = "std", doc = "Note that this error is *not* caused by [`Retry::Timeout`].")]
/// |
ff84599
to
f81964f
Compare
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #3517 +/- ##
==========================================
+ Coverage 88.44% 88.55% +0.11%
==========================================
Files 149 149
Lines 113330 114969 +1639
Branches 113330 114969 +1639
==========================================
+ Hits 100238 101815 +1577
- Misses 10621 10622 +1
- Partials 2471 2532 +61 ☔ View full report in Codecov by Sentry. |
if payment_context.is_some() { | ||
if !matches!(payment_context, Some(PaymentContext::AsyncBolt12Offer(_))) { | ||
log_trace!(self.logger, "Failing new HTLC with payment_hash {}: received a keysend payment to a non-async payments context {:#?}", payment_hash, payment_context); | ||
} | ||
fail_htlc!(claimable_htlc, payment_hash); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just noting that these cases will be separated in the follow-up PR, AFAICT.
47ef7d1
to
694a8b9
Compare
Pushed another docs tweak at @TheBlueMatt's request: diff --git a/lightning/src/ln/outbound_payment.rs b/lightning/src/ln/outbound_payment.rs
index 8bf9d5696..9433c84a5 100644
--- a/lightning/src/ln/outbound_payment.rs
+++ b/lightning/src/ln/outbound_payment.rs
@@ -458,7 +458,8 @@ impl_writeable_tlv_based_enum_legacy!(StaleExpiration,
/// [`Event::PaymentFailed`]: crate::events::Event::PaymentFailed
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum RetryableSendFailure {
- /// The invoice or [`PaymentParameters::expiry_time`] indicated that the payment has expired.
+ /// The BOLT 12 invoice was expired by the time we received it or the
+ /// [`PaymentParameters::expiry_time`] were expired on a retry attempt.
#[cfg_attr(feature = "std", doc = "")]
#[cfg_attr(feature = "std", doc = "Note that this error is *not* caused by [`Retry::Timeout`].")]
/// |
Blinded HTLCs are always failed back with the same error, so DRY the test code that fails them backwards. This util will also be used for async payments testing in upcoming commits.
Needed to authenticate that the held_htlc_available message is being sent over a reply path that we originally created and that isn't expired before we reply with release_held_htlc. This context will be used in upcoming commits when we add support for async receive.
694a8b9
to
e047950
Compare
Rebased due to conflicts |
Prior to this patch, if we received an expired static invoice we would delay surfacing the payment failure until after the recipient had come online and sent the release_held_htlc OM, which could be a long time later. Now, we'll detect that the invoice is expired as soon as it's received.
Here we bubble up the payment context into PendingHTLCRouting::ReceiveKeysend and check it when receiving a spontaneous payment prior to generating a claimable event. Prior to this patch, we would have accepted out-of-context keysends sent over blinded paths taken from our BOLT 12 invoices. As a side effect of this, our blinded keysend success test cases now fail, so those tests are now removed. Their coverage is re-added in future commits when we add support for async receive, meaning we're able to receive blinded keysends in the correct payment context. While we could avoid storing the payment context for the purposes of this bugfix, we go ahead and store it now because it will be needed when support for receiving async payments is added.
e047950
to
db87b29
Compare
Another docs tweak: diff --git a/lightning/src/events/mod.rs b/lightning/src/events/mod.rs
index 1a212c7c4..07a97759f 100644
--- a/lightning/src/events/mod.rs
+++ b/lightning/src/events/mod.rs
@@ -561,8 +561,8 @@ pub enum PaymentFailureReason {
#[cfg_attr(feature = "std", doc = "")]
#[cfg_attr(feature = "std", doc = "[`Retry::Timeout`]: crate::ln::channelmanager::Retry::Timeout")]
RetriesExhausted,
- /// The payment expired while retrying, based on the provided
- /// [`PaymentParameters::expiry_time`].
+ /// Either the BOLT 12 invoice was expired by the time we received it or the payment expired while
+ /// retrying based on the provided [`PaymentParameters::expiry_time`].
///
/// Also used for [`InvoiceRequestExpired`] when downgrading to version prior to 0.0.124.
///
diff --git a/lightning/src/ln/outbound_payment.rs b/lightning/src/ln/outbound_payment.rs
index 5127cf47c..138f01007 100644
--- a/lightning/src/ln/outbound_payment.rs
+++ b/lightning/src/ln/outbound_payment.rs
@@ -458,8 +458,9 @@ impl_writeable_tlv_based_enum_legacy!(StaleExpiration,
/// [`Event::PaymentFailed`]: crate::events::Event::PaymentFailed
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum RetryableSendFailure {
- /// The BOLT 12 invoice was expired by the time we received it or the
- /// [`PaymentParameters::expiry_time`] were expired on a retry attempt.
+ /// The provided [`PaymentParameters::expiry_time`] indicated that the payment has expired or
+ /// the BOLT 12 invoice paid to via [`ChannelManager::send_payment_for_bolt12_invoice`] was
+ /// expired.
#[cfg_attr(feature = "std", doc = "")]
#[cfg_attr(feature = "std", doc = "Note that this error is *not* caused by [`Retry::Timeout`].")]
/// |
This error variant is also used when manually sending to BOLT 12 invoices is enabled, so document that.
db87b29
to
f799e6b
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM. Changes since @jkczyz's ACK are all doc things so just gonna land this.
Some test util refactors, additional test coverage, and one fix in preparation for finalizing support for async receive.
Based on #3408. Prepares for #3440