Skip to content

Commit

Permalink
Store invreqs in StaticInvoiceReceived outbound payments
Browse files Browse the repository at this point in the history
When transitioning outbound payments from AwaitingInvoice to
StaticInvoiceReceived, include the invreq in the new state's outbound payment
storage for future inclusion in an async payment onion.

Per <lightning/bolts#1149>, when paying a static
invoice we need to include our original invoice request in the HTLC onion since
the recipient wouldn't have received it previously.
  • Loading branch information
valentinewallace committed Sep 18, 2024
1 parent 3911bc6 commit fa3dc77
Showing 1 changed file with 19 additions and 1 deletion.
20 changes: 19 additions & 1 deletion lightning/src/ln/outbound_payment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ pub(crate) enum PendingOutboundPayment {
keysend_preimage: PaymentPreimage,
retry_strategy: Retry,
route_params: RouteParameters,
invoice_request: InvoiceRequest,
},
Retryable {
retry_strategy: Option<Retry>,
Expand Down Expand Up @@ -1003,7 +1004,7 @@ impl OutboundPayments {
}

match self.pending_outbound_payments.lock().unwrap().entry(payment_id) {
hash_map::Entry::Occupied(mut entry) => match entry.get() {
hash_map::Entry::Occupied(mut entry) => match entry.get_mut() {
PendingOutboundPayment::AwaitingInvoice {
retry_strategy, retryable_invoice_request, max_total_routing_fee_msat, ..
} => {
Expand Down Expand Up @@ -1047,6 +1048,11 @@ impl OutboundPayments {
keysend_preimage,
retry_strategy: *retry_strategy,
route_params,
invoice_request:
retryable_invoice_request
.take()
.ok_or(Bolt12PaymentError::UnexpectedInvoice)?
.invoice_request,
};
return Ok(())
},
Expand Down Expand Up @@ -2250,32 +2256,37 @@ impl_writeable_tlv_based_enum_upgradable!(PendingOutboundPayment,
(2, keysend_preimage, required),
(4, retry_strategy, required),
(6, route_params, required),
(8, invoice_request, required),
},
);

#[cfg(test)]
mod tests {
use bitcoin::hex::FromHex;
use bitcoin::network::Network;
use bitcoin::secp256k1::{PublicKey, Secp256k1, SecretKey};

use core::time::Duration;

use crate::blinded_path::EmptyNodeIdLookUp;
use crate::events::{Event, PathFailure, PaymentFailureReason};
use crate::io::Cursor;
use crate::ln::types::{PaymentHash, PaymentPreimage};
use crate::ln::channelmanager::{PaymentId, RecipientOnionFields};
use crate::ln::features::{Bolt12InvoiceFeatures, ChannelFeatures, NodeFeatures};
use crate::ln::msgs::{ErrorAction, LightningError};
use crate::ln::outbound_payment::{Bolt12PaymentError, OutboundPayments, PendingOutboundPayment, Retry, RetryableSendFailure, StaleExpiration};
#[cfg(feature = "std")]
use crate::offers::invoice::DEFAULT_RELATIVE_EXPIRY;
use crate::offers::invoice_request::InvoiceRequest;
use crate::offers::offer::OfferBuilder;
use crate::offers::test_utils::*;
use crate::routing::gossip::NetworkGraph;
use crate::routing::router::{InFlightHtlcs, Path, PaymentParameters, Route, RouteHop, RouteParameters};
use crate::sync::{Arc, Mutex, RwLock};
use crate::util::errors::APIError;
use crate::util::hash_tables::new_hash_map;
use crate::util::ser::Readable;
use crate::util::test_utils;

use alloc::collections::VecDeque;
Expand Down Expand Up @@ -2817,6 +2828,11 @@ mod tests {
assert!(pending_events.lock().unwrap().is_empty());
}

fn invoice_request() -> InvoiceRequest {
let invreq_bytes = <Vec<u8>>::from_hex("00200101010101010101010101010101010101010101010101010101010101010101080203e80a00162102bb58b5feca505c74edc000d8282fc556e51a1024fc8e7d7e56c6f887c5c8d5f25821035be5e9478209674a96e60f1f037f6176540fd001fa1d64694770c56a7709c42cf040a31d68198578a5aa1fe57de5f6d33f89c1556752cb333dbb56ac727f751893804d3a26b42909f1952fb1db8080238f9476b829160387692df35ff85dfe72e2ed").unwrap();
Readable::read(&mut Cursor::new(&invreq_bytes[..])).unwrap()
}

#[test]
fn time_out_unreleased_async_payments() {
let pending_events = Mutex::new(VecDeque::new());
Expand All @@ -2838,6 +2854,7 @@ mod tests {
keysend_preimage: PaymentPreimage([0; 32]),
retry_strategy: Retry::Attempts(0),
route_params,
invoice_request: invoice_request(),
};
outbounds.insert(payment_id, outbound);
core::mem::drop(outbounds);
Expand Down Expand Up @@ -2884,6 +2901,7 @@ mod tests {
keysend_preimage: PaymentPreimage([0; 32]),
retry_strategy: Retry::Attempts(0),
route_params,
invoice_request: invoice_request(),
};
outbounds.insert(payment_id, outbound);
core::mem::drop(outbounds);
Expand Down

0 comments on commit fa3dc77

Please sign in to comment.