Skip to content

Commit 424d826

Browse files
committed
Introduce retry_invoice_request_messages function
We need to retry InvoiceRequest messages in a smaller time duration than timer_tick_occurred. This function provides the base for doing the retry, by getting the InvoiceRequest for PendingOutboundPayments and using a new reply_path to create and enqueue InvoiceRequest messages.
1 parent 03da11e commit 424d826

File tree

2 files changed

+63
-24
lines changed

2 files changed

+63
-24
lines changed

lightning/src/ln/channelmanager.rs

Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,8 @@ use crate::util::string::UntrustedString;
7575
use crate::util::ser::{BigSize, FixedLengthReader, Readable, ReadableArgs, MaybeReadable, Writeable, Writer, VecWriter};
7676
use crate::util::logger::{Level, Logger, WithContext};
7777
use crate::util::errors::APIError;
78+
use super::onion_utils::construct_invoice_request_message;
79+
7880
#[cfg(not(c_bindings))]
7981
use {
8082
crate::offers::offer::DerivedMetadata,
@@ -6022,6 +6024,27 @@ where
60226024
});
60236025
}
60246026

6027+
/// Performs actions that should happen roughly once every 5 seconds.
6028+
///
6029+
/// Currently, this includes retrying the sending of [`InvoiceRequest`] messages using newly
6030+
/// generated `reply_path` for payments that are still awaiting their corresponding
6031+
/// [`Bolt12Invoice`].
6032+
///
6033+
/// [`InvoiceRequest`]: crate::offers::invoice_request::InvoiceRequest
6034+
/// [`Bolt12Invoice`]: crate::offers::invoice::Bolt12Invoice
6035+
fn retry_invoice_request_messages(&self) -> Result<(), Bolt12SemanticError> {
6036+
let invoice_requests = self.pending_outbound_payments.get_invoice_request_awaiting_invoice();
6037+
if invoice_requests.is_empty() { return Ok(()); }
6038+
if let Ok(reply_path) = self.create_blinded_path() {
6039+
let mut pending_offers_messages = self.pending_offers_messages.lock().unwrap();
6040+
6041+
for invoice_request in invoice_requests {
6042+
pending_offers_messages.extend(construct_invoice_request_message(invoice_request, reply_path.clone())?);
6043+
}
6044+
}
6045+
Ok(())
6046+
}
6047+
60256048
/// Indicates that the preimage for payment_hash is unknown or the received amount is incorrect
60266049
/// after a PaymentClaimable event, failing the HTLC back to its origin and freeing resources
60276050
/// along the path (including in our own channel on which we received it).
@@ -8757,30 +8780,7 @@ where
87578780
.map_err(|_| Bolt12SemanticError::DuplicatePaymentId)?;
87588781

87598782
let mut pending_offers_messages = self.pending_offers_messages.lock().unwrap();
8760-
if !offer.paths().is_empty() {
8761-
// Send as many invoice requests as there are paths in the offer (with an upper bound).
8762-
// Using only one path could result in a failure if the path no longer exists. But only
8763-
// one invoice for a given payment id will be paid, even if more than one is received.
8764-
const REQUEST_LIMIT: usize = 10;
8765-
for path in offer.paths().into_iter().take(REQUEST_LIMIT) {
8766-
let message = new_pending_onion_message(
8767-
OffersMessage::InvoiceRequest(invoice_request.clone()),
8768-
Destination::BlindedPath(path.clone()),
8769-
Some(reply_path.clone()),
8770-
);
8771-
pending_offers_messages.push(message);
8772-
}
8773-
} else if let Some(signing_pubkey) = offer.signing_pubkey() {
8774-
let message = new_pending_onion_message(
8775-
OffersMessage::InvoiceRequest(invoice_request),
8776-
Destination::Node(signing_pubkey),
8777-
Some(reply_path),
8778-
);
8779-
pending_offers_messages.push(message);
8780-
} else {
8781-
debug_assert!(false);
8782-
return Err(Bolt12SemanticError::MissingSigningPubkey);
8783-
}
8783+
pending_offers_messages.extend(construct_invoice_request_message(invoice_request, reply_path)?);
87848784

87858785
Ok(())
87868786
}

lightning/src/ln/onion_utils.rs

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,19 @@
77
// You may not use this file except in accordance with one or both of these
88
// licenses.
99

10+
use crate::blinded_path::BlindedPath;
1011
use crate::crypto::chacha20::ChaCha20;
1112
use crate::crypto::streams::ChaChaReader;
1213
use crate::ln::channelmanager::{HTLCSource, RecipientOnionFields};
1314
use crate::ln::msgs;
1415
use crate::ln::wire::Encode;
1516
use crate::ln::{PaymentHash, PaymentPreimage};
17+
use crate::offers::invoice_request::InvoiceRequest;
18+
use crate::offers::parse::Bolt12SemanticError;
19+
use crate::onion_message::messenger::{
20+
new_pending_onion_message, Destination, PendingOnionMessage,
21+
};
22+
use crate::onion_message::offers::OffersMessage;
1623
use crate::routing::gossip::NetworkUpdate;
1724
use crate::routing::router::{BlindedTail, Path, RouteHop};
1825
use crate::sign::NodeSigner;
@@ -1235,6 +1242,38 @@ fn decode_next_hop<T, R: ReadableArgs<T>, N: NextPacketBytes>(
12351242
}
12361243
}
12371244

1245+
pub fn construct_invoice_request_message(
1246+
invoice_request: InvoiceRequest, reply_path: BlindedPath,
1247+
) -> Result<Vec<PendingOnionMessage<OffersMessage>>, Bolt12SemanticError> {
1248+
let mut messages = vec![];
1249+
if !invoice_request.paths().is_empty() {
1250+
// Send as many invoice requests as there are paths in the offer (with an upper bound).
1251+
// Using only one path could result in a failure if the path no longer exists. But only
1252+
// one invoice for a given payment id will be paid, even if more than one is received.
1253+
const REQUEST_LIMIT: usize = 10;
1254+
for path in invoice_request.paths().into_iter().take(REQUEST_LIMIT) {
1255+
let message = new_pending_onion_message(
1256+
OffersMessage::InvoiceRequest(invoice_request.clone()),
1257+
Destination::BlindedPath(path.clone()),
1258+
Some(reply_path.clone()),
1259+
);
1260+
messages.push(message);
1261+
}
1262+
} else if let Some(signing_pubkey) = invoice_request.signing_pubkey() {
1263+
let message = new_pending_onion_message(
1264+
OffersMessage::InvoiceRequest(invoice_request),
1265+
Destination::Node(signing_pubkey),
1266+
Some(reply_path),
1267+
);
1268+
messages.push(message);
1269+
} else {
1270+
debug_assert!(false);
1271+
return Err(Bolt12SemanticError::MissingSigningPubkey);
1272+
}
1273+
1274+
Ok(messages)
1275+
}
1276+
12381277
#[cfg(test)]
12391278
mod tests {
12401279
use crate::io;

0 commit comments

Comments
 (0)