Skip to content

Commit 3b69431

Browse files
committed
Add tests for send_payment_for_bolt12_invoice
1 parent d5e99a0 commit 3b69431

File tree

2 files changed

+242
-2
lines changed

2 files changed

+242
-2
lines changed

lightning/src/ln/outbound_payment.rs

Lines changed: 241 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -442,6 +442,7 @@ pub enum PaymentSendFailure {
442442
}
443443

444444
/// An error when attempting to pay a BOLT 12 invoice.
445+
#[derive(Clone, Debug, PartialEq, Eq)]
445446
pub(super) enum Bolt12PaymentError {
446447
/// The invoice was not requested.
447448
UnexpectedInvoice,
@@ -1682,7 +1683,10 @@ mod tests {
16821683
use crate::ln::channelmanager::{PaymentId, RecipientOnionFields};
16831684
use crate::ln::features::{ChannelFeatures, NodeFeatures};
16841685
use crate::ln::msgs::{ErrorAction, LightningError};
1685-
use crate::ln::outbound_payment::{INVOICE_REQUEST_TIMEOUT_TICKS, OutboundPayments, Retry, RetryableSendFailure};
1686+
use crate::ln::outbound_payment::{Bolt12PaymentError, INVOICE_REQUEST_TIMEOUT_TICKS, OutboundPayments, Retry, RetryableSendFailure};
1687+
use crate::offers::invoice::DEFAULT_RELATIVE_EXPIRY;
1688+
use crate::offers::offer::OfferBuilder;
1689+
use crate::offers::test_utils::*;
16861690
use crate::routing::gossip::NetworkGraph;
16871691
use crate::routing::router::{InFlightHtlcs, Path, PaymentParameters, Route, RouteHop, RouteParameters};
16881692
use crate::sync::{Arc, Mutex, RwLock};
@@ -1932,4 +1936,240 @@ mod tests {
19321936
);
19331937
assert!(pending_events.lock().unwrap().is_empty());
19341938
}
1939+
1940+
#[cfg(feature = "std")]
1941+
#[test]
1942+
fn fails_sending_payment_for_expired_bolt12_invoice() {
1943+
let logger = test_utils::TestLogger::new();
1944+
let network_graph = Arc::new(NetworkGraph::new(Network::Testnet, &logger));
1945+
let scorer = RwLock::new(test_utils::TestScorer::new());
1946+
let router = test_utils::TestRouter::new(network_graph, &scorer);
1947+
let keys_manager = test_utils::TestKeysInterface::new(&[0; 32], Network::Testnet);
1948+
1949+
let pending_events = Mutex::new(VecDeque::new());
1950+
let outbound_payments = OutboundPayments::new();
1951+
let payment_id = PaymentId([0; 32]);
1952+
1953+
assert!(outbound_payments.add_new_awaiting_invoice(payment_id).is_ok());
1954+
assert!(outbound_payments.has_pending_payments());
1955+
1956+
let created_at = now() - DEFAULT_RELATIVE_EXPIRY;
1957+
let invoice = OfferBuilder::new("foo".into(), recipient_pubkey())
1958+
.amount_msats(1000)
1959+
.build().unwrap()
1960+
.request_invoice(vec![1; 32], payer_pubkey()).unwrap()
1961+
.build().unwrap()
1962+
.sign(payer_sign).unwrap()
1963+
.respond_with_no_std(payment_paths(), payment_hash(), created_at).unwrap()
1964+
.build().unwrap()
1965+
.sign(recipient_sign).unwrap();
1966+
1967+
assert_eq!(
1968+
outbound_payments.send_payment_for_bolt12_invoice(
1969+
&invoice, payment_id, &&router, vec![], || InFlightHtlcs::new(), &&keys_manager,
1970+
&&keys_manager, 0, &&logger, &pending_events, |_| panic!()
1971+
),
1972+
Ok(()),
1973+
);
1974+
assert!(!outbound_payments.has_pending_payments());
1975+
1976+
let payment_hash = invoice.payment_hash();
1977+
let reason = Some(PaymentFailureReason::PaymentExpired);
1978+
1979+
assert!(!pending_events.lock().unwrap().is_empty());
1980+
assert_eq!(
1981+
pending_events.lock().unwrap().pop_front(),
1982+
Some((Event::PaymentFailed { payment_id, payment_hash, reason }, None)),
1983+
);
1984+
assert!(pending_events.lock().unwrap().is_empty());
1985+
}
1986+
1987+
#[test]
1988+
fn fails_finding_route_for_bolt12_invoice() {
1989+
let logger = test_utils::TestLogger::new();
1990+
let network_graph = Arc::new(NetworkGraph::new(Network::Testnet, &logger));
1991+
let scorer = RwLock::new(test_utils::TestScorer::new());
1992+
let router = test_utils::TestRouter::new(network_graph, &scorer);
1993+
let keys_manager = test_utils::TestKeysInterface::new(&[0; 32], Network::Testnet);
1994+
1995+
let pending_events = Mutex::new(VecDeque::new());
1996+
let outbound_payments = OutboundPayments::new();
1997+
let payment_id = PaymentId([0; 32]);
1998+
1999+
assert!(outbound_payments.add_new_awaiting_invoice(payment_id).is_ok());
2000+
assert!(outbound_payments.has_pending_payments());
2001+
2002+
let invoice = OfferBuilder::new("foo".into(), recipient_pubkey())
2003+
.amount_msats(1000)
2004+
.build().unwrap()
2005+
.request_invoice(vec![1; 32], payer_pubkey()).unwrap()
2006+
.build().unwrap()
2007+
.sign(payer_sign).unwrap()
2008+
.respond_with_no_std(payment_paths(), payment_hash(), now()).unwrap()
2009+
.build().unwrap()
2010+
.sign(recipient_sign).unwrap();
2011+
2012+
router.expect_find_route(
2013+
RouteParameters {
2014+
payment_params: PaymentParameters::from_bolt12_invoice(&invoice),
2015+
final_value_msat: invoice.amount_msats(),
2016+
},
2017+
Err(LightningError { err: String::new(), action: ErrorAction::IgnoreError }),
2018+
);
2019+
2020+
assert_eq!(
2021+
outbound_payments.send_payment_for_bolt12_invoice(
2022+
&invoice, payment_id, &&router, vec![], || InFlightHtlcs::new(), &&keys_manager,
2023+
&&keys_manager, 0, &&logger, &pending_events, |_| panic!()
2024+
),
2025+
Ok(()),
2026+
);
2027+
assert!(!outbound_payments.has_pending_payments());
2028+
2029+
let payment_hash = invoice.payment_hash();
2030+
let reason = Some(PaymentFailureReason::RouteNotFound);
2031+
2032+
assert!(!pending_events.lock().unwrap().is_empty());
2033+
assert_eq!(
2034+
pending_events.lock().unwrap().pop_front(),
2035+
Some((Event::PaymentFailed { payment_id, payment_hash, reason }, None)),
2036+
);
2037+
assert!(pending_events.lock().unwrap().is_empty());
2038+
}
2039+
2040+
#[test]
2041+
fn fails_paying_for_bolt12_invoice() {
2042+
let logger = test_utils::TestLogger::new();
2043+
let network_graph = Arc::new(NetworkGraph::new(Network::Testnet, &logger));
2044+
let scorer = RwLock::new(test_utils::TestScorer::new());
2045+
let router = test_utils::TestRouter::new(network_graph, &scorer);
2046+
let keys_manager = test_utils::TestKeysInterface::new(&[0; 32], Network::Testnet);
2047+
2048+
let pending_events = Mutex::new(VecDeque::new());
2049+
let outbound_payments = OutboundPayments::new();
2050+
let payment_id = PaymentId([0; 32]);
2051+
2052+
assert!(outbound_payments.add_new_awaiting_invoice(payment_id).is_ok());
2053+
assert!(outbound_payments.has_pending_payments());
2054+
2055+
let invoice = OfferBuilder::new("foo".into(), recipient_pubkey())
2056+
.amount_msats(1000)
2057+
.build().unwrap()
2058+
.request_invoice(vec![1; 32], payer_pubkey()).unwrap()
2059+
.build().unwrap()
2060+
.sign(payer_sign).unwrap()
2061+
.respond_with_no_std(payment_paths(), payment_hash(), now()).unwrap()
2062+
.build().unwrap()
2063+
.sign(recipient_sign).unwrap();
2064+
2065+
let route_params = RouteParameters {
2066+
payment_params: PaymentParameters::from_bolt12_invoice(&invoice),
2067+
final_value_msat: invoice.amount_msats(),
2068+
};
2069+
router.expect_find_route(
2070+
route_params.clone(), Ok(Route { paths: vec![], route_params: Some(route_params) })
2071+
);
2072+
2073+
assert_eq!(
2074+
outbound_payments.send_payment_for_bolt12_invoice(
2075+
&invoice, payment_id, &&router, vec![], || InFlightHtlcs::new(), &&keys_manager,
2076+
&&keys_manager, 0, &&logger, &pending_events, |_| panic!()
2077+
),
2078+
Ok(()),
2079+
);
2080+
assert!(!outbound_payments.has_pending_payments());
2081+
2082+
let payment_hash = invoice.payment_hash();
2083+
let reason = Some(PaymentFailureReason::UnexpectedError);
2084+
2085+
assert!(!pending_events.lock().unwrap().is_empty());
2086+
assert_eq!(
2087+
pending_events.lock().unwrap().pop_front(),
2088+
Some((Event::PaymentFailed { payment_id, payment_hash, reason }, None)),
2089+
);
2090+
assert!(pending_events.lock().unwrap().is_empty());
2091+
}
2092+
2093+
#[test]
2094+
fn sends_payment_for_bolt12_invoice() {
2095+
let logger = test_utils::TestLogger::new();
2096+
let network_graph = Arc::new(NetworkGraph::new(Network::Testnet, &logger));
2097+
let scorer = RwLock::new(test_utils::TestScorer::new());
2098+
let router = test_utils::TestRouter::new(network_graph, &scorer);
2099+
let keys_manager = test_utils::TestKeysInterface::new(&[0; 32], Network::Testnet);
2100+
2101+
let pending_events = Mutex::new(VecDeque::new());
2102+
let outbound_payments = OutboundPayments::new();
2103+
let payment_id = PaymentId([0; 32]);
2104+
2105+
let invoice = OfferBuilder::new("foo".into(), recipient_pubkey())
2106+
.amount_msats(1000)
2107+
.build().unwrap()
2108+
.request_invoice(vec![1; 32], payer_pubkey()).unwrap()
2109+
.build().unwrap()
2110+
.sign(payer_sign).unwrap()
2111+
.respond_with_no_std(payment_paths(), payment_hash(), now()).unwrap()
2112+
.build().unwrap()
2113+
.sign(recipient_sign).unwrap();
2114+
2115+
let route_params = RouteParameters {
2116+
payment_params: PaymentParameters::from_bolt12_invoice(&invoice),
2117+
final_value_msat: invoice.amount_msats(),
2118+
};
2119+
router.expect_find_route(
2120+
route_params.clone(),
2121+
Ok(Route {
2122+
paths: vec![
2123+
Path {
2124+
hops: vec![
2125+
RouteHop {
2126+
pubkey: recipient_pubkey(),
2127+
node_features: NodeFeatures::empty(),
2128+
short_channel_id: 42,
2129+
channel_features: ChannelFeatures::empty(),
2130+
fee_msat: invoice.amount_msats(),
2131+
cltv_expiry_delta: 0,
2132+
}
2133+
],
2134+
blinded_tail: None,
2135+
}
2136+
],
2137+
route_params: Some(route_params),
2138+
})
2139+
);
2140+
2141+
assert!(!outbound_payments.has_pending_payments());
2142+
assert_eq!(
2143+
outbound_payments.send_payment_for_bolt12_invoice(
2144+
&invoice, payment_id, &&router, vec![], || InFlightHtlcs::new(), &&keys_manager,
2145+
&&keys_manager, 0, &&logger, &pending_events, |_| panic!()
2146+
),
2147+
Err(Bolt12PaymentError::UnexpectedInvoice),
2148+
);
2149+
assert!(!outbound_payments.has_pending_payments());
2150+
assert!(pending_events.lock().unwrap().is_empty());
2151+
2152+
assert!(outbound_payments.add_new_awaiting_invoice(payment_id).is_ok());
2153+
assert!(outbound_payments.has_pending_payments());
2154+
2155+
assert_eq!(
2156+
outbound_payments.send_payment_for_bolt12_invoice(
2157+
&invoice, payment_id, &&router, vec![], || InFlightHtlcs::new(), &&keys_manager,
2158+
&&keys_manager, 0, &&logger, &pending_events, |_| Ok(())
2159+
),
2160+
Ok(()),
2161+
);
2162+
assert!(outbound_payments.has_pending_payments());
2163+
assert!(pending_events.lock().unwrap().is_empty());
2164+
2165+
assert_eq!(
2166+
outbound_payments.send_payment_for_bolt12_invoice(
2167+
&invoice, payment_id, &&router, vec![], || InFlightHtlcs::new(), &&keys_manager,
2168+
&&keys_manager, 0, &&logger, &pending_events, |_| panic!()
2169+
),
2170+
Err(Bolt12PaymentError::DuplicateInvoice),
2171+
);
2172+
assert!(outbound_payments.has_pending_payments());
2173+
assert!(pending_events.lock().unwrap().is_empty());
2174+
}
19352175
}

lightning/src/offers/invoice.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ use crate::prelude::*;
129129
#[cfg(feature = "std")]
130130
use std::time::SystemTime;
131131

132-
const DEFAULT_RELATIVE_EXPIRY: Duration = Duration::from_secs(7200);
132+
pub(crate) const DEFAULT_RELATIVE_EXPIRY: Duration = Duration::from_secs(7200);
133133

134134
/// Tag for the hash function used when signing a [`Bolt12Invoice`]'s merkle root.
135135
pub const SIGNATURE_TAG: &'static str = concat!("lightning", "invoice", "signature");

0 commit comments

Comments
 (0)