Skip to content

Commit 3098689

Browse files
committed
Add tests for send_payment_for_bolt12_invoice
1 parent 94b3a0b commit 3098689

File tree

2 files changed

+244
-2
lines changed

2 files changed

+244
-2
lines changed

lightning/src/ln/outbound_payment.rs

Lines changed: 243 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};
@@ -1941,4 +1945,242 @@ mod tests {
19411945
);
19421946
assert!(pending_events.lock().unwrap().is_empty());
19431947
}
1948+
1949+
#[cfg(feature = "std")]
1950+
#[test]
1951+
fn fails_sending_payment_for_expired_bolt12_invoice() {
1952+
let logger = test_utils::TestLogger::new();
1953+
let network_graph = Arc::new(NetworkGraph::new(Network::Testnet, &logger));
1954+
let scorer = RwLock::new(test_utils::TestScorer::new());
1955+
let router = test_utils::TestRouter::new(network_graph, &scorer);
1956+
let keys_manager = test_utils::TestKeysInterface::new(&[0; 32], Network::Testnet);
1957+
1958+
let pending_events = Mutex::new(VecDeque::new());
1959+
let outbound_payments = OutboundPayments::new();
1960+
let payment_id = PaymentId([0; 32]);
1961+
1962+
assert!(outbound_payments.add_new_awaiting_invoice(payment_id).is_ok());
1963+
assert!(outbound_payments.has_pending_payments());
1964+
1965+
let created_at = now() - DEFAULT_RELATIVE_EXPIRY;
1966+
let invoice = OfferBuilder::new("foo".into(), recipient_pubkey())
1967+
.amount_msats(1000)
1968+
.build().unwrap()
1969+
.request_invoice(vec![1; 32], payer_pubkey()).unwrap()
1970+
.build().unwrap()
1971+
.sign(payer_sign).unwrap()
1972+
.respond_with_no_std(payment_paths(), payment_hash(), created_at).unwrap()
1973+
.build().unwrap()
1974+
.sign(recipient_sign).unwrap();
1975+
1976+
assert_eq!(
1977+
outbound_payments.send_payment_for_bolt12_invoice(
1978+
&invoice, payment_id, &&router, vec![], || InFlightHtlcs::new(), &&keys_manager,
1979+
&&keys_manager, 0, &&logger, &pending_events, |_| panic!()
1980+
),
1981+
Ok(()),
1982+
);
1983+
assert!(!outbound_payments.has_pending_payments());
1984+
1985+
let payment_hash = invoice.payment_hash();
1986+
let reason = Some(PaymentFailureReason::PaymentExpired);
1987+
1988+
assert!(!pending_events.lock().unwrap().is_empty());
1989+
assert_eq!(
1990+
pending_events.lock().unwrap().pop_front(),
1991+
Some((Event::PaymentFailed { payment_id, payment_hash, reason }, None)),
1992+
);
1993+
assert!(pending_events.lock().unwrap().is_empty());
1994+
}
1995+
1996+
#[test]
1997+
fn fails_finding_route_for_bolt12_invoice() {
1998+
let logger = test_utils::TestLogger::new();
1999+
let network_graph = Arc::new(NetworkGraph::new(Network::Testnet, &logger));
2000+
let scorer = RwLock::new(test_utils::TestScorer::new());
2001+
let router = test_utils::TestRouter::new(network_graph, &scorer);
2002+
let keys_manager = test_utils::TestKeysInterface::new(&[0; 32], Network::Testnet);
2003+
2004+
let pending_events = Mutex::new(VecDeque::new());
2005+
let outbound_payments = OutboundPayments::new();
2006+
let payment_id = PaymentId([0; 32]);
2007+
2008+
assert!(outbound_payments.add_new_awaiting_invoice(payment_id).is_ok());
2009+
assert!(outbound_payments.has_pending_payments());
2010+
2011+
let invoice = OfferBuilder::new("foo".into(), recipient_pubkey())
2012+
.amount_msats(1000)
2013+
.build().unwrap()
2014+
.request_invoice(vec![1; 32], payer_pubkey()).unwrap()
2015+
.build().unwrap()
2016+
.sign(payer_sign).unwrap()
2017+
.respond_with_no_std(payment_paths(), payment_hash(), now()).unwrap()
2018+
.build().unwrap()
2019+
.sign(recipient_sign).unwrap();
2020+
2021+
router.expect_find_route(
2022+
RouteParameters {
2023+
payment_params: PaymentParameters::from_bolt12_invoice(&invoice),
2024+
final_value_msat: invoice.amount_msats(),
2025+
},
2026+
Err(LightningError { err: String::new(), action: ErrorAction::IgnoreError }),
2027+
);
2028+
2029+
assert_eq!(
2030+
outbound_payments.send_payment_for_bolt12_invoice(
2031+
&invoice, payment_id, &&router, vec![], || InFlightHtlcs::new(), &&keys_manager,
2032+
&&keys_manager, 0, &&logger, &pending_events, |_| panic!()
2033+
),
2034+
Ok(()),
2035+
);
2036+
assert!(!outbound_payments.has_pending_payments());
2037+
2038+
let payment_hash = invoice.payment_hash();
2039+
let reason = Some(PaymentFailureReason::RouteNotFound);
2040+
2041+
assert!(!pending_events.lock().unwrap().is_empty());
2042+
assert_eq!(
2043+
pending_events.lock().unwrap().pop_front(),
2044+
Some((Event::PaymentFailed { payment_id, payment_hash, reason }, None)),
2045+
);
2046+
assert!(pending_events.lock().unwrap().is_empty());
2047+
}
2048+
2049+
#[test]
2050+
fn fails_paying_for_bolt12_invoice() {
2051+
let logger = test_utils::TestLogger::new();
2052+
let network_graph = Arc::new(NetworkGraph::new(Network::Testnet, &logger));
2053+
let scorer = RwLock::new(test_utils::TestScorer::new());
2054+
let router = test_utils::TestRouter::new(network_graph, &scorer);
2055+
let keys_manager = test_utils::TestKeysInterface::new(&[0; 32], Network::Testnet);
2056+
2057+
let pending_events = Mutex::new(VecDeque::new());
2058+
let outbound_payments = OutboundPayments::new();
2059+
let payment_id = PaymentId([0; 32]);
2060+
2061+
assert!(outbound_payments.add_new_awaiting_invoice(payment_id).is_ok());
2062+
assert!(outbound_payments.has_pending_payments());
2063+
2064+
let invoice = OfferBuilder::new("foo".into(), recipient_pubkey())
2065+
.amount_msats(1000)
2066+
.build().unwrap()
2067+
.request_invoice(vec![1; 32], payer_pubkey()).unwrap()
2068+
.build().unwrap()
2069+
.sign(payer_sign).unwrap()
2070+
.respond_with_no_std(payment_paths(), payment_hash(), now()).unwrap()
2071+
.build().unwrap()
2072+
.sign(recipient_sign).unwrap();
2073+
2074+
router.expect_find_route(
2075+
RouteParameters {
2076+
payment_params: PaymentParameters::from_bolt12_invoice(&invoice),
2077+
final_value_msat: invoice.amount_msats(),
2078+
},
2079+
Ok(Route {
2080+
paths: vec![],
2081+
payment_params: Some(PaymentParameters::from_bolt12_invoice(&invoice)),
2082+
})
2083+
);
2084+
2085+
assert_eq!(
2086+
outbound_payments.send_payment_for_bolt12_invoice(
2087+
&invoice, payment_id, &&router, vec![], || InFlightHtlcs::new(), &&keys_manager,
2088+
&&keys_manager, 0, &&logger, &pending_events, |_| panic!()
2089+
),
2090+
Ok(()),
2091+
);
2092+
assert!(!outbound_payments.has_pending_payments());
2093+
2094+
let payment_hash = invoice.payment_hash();
2095+
let reason = Some(PaymentFailureReason::UnexpectedError);
2096+
2097+
assert!(!pending_events.lock().unwrap().is_empty());
2098+
assert_eq!(
2099+
pending_events.lock().unwrap().pop_front(),
2100+
Some((Event::PaymentFailed { payment_id, payment_hash, reason }, None)),
2101+
);
2102+
assert!(pending_events.lock().unwrap().is_empty());
2103+
}
2104+
2105+
#[test]
2106+
fn sends_payment_for_bolt12_invoice() {
2107+
let logger = test_utils::TestLogger::new();
2108+
let network_graph = Arc::new(NetworkGraph::new(Network::Testnet, &logger));
2109+
let scorer = RwLock::new(test_utils::TestScorer::new());
2110+
let router = test_utils::TestRouter::new(network_graph, &scorer);
2111+
let keys_manager = test_utils::TestKeysInterface::new(&[0; 32], Network::Testnet);
2112+
2113+
let pending_events = Mutex::new(VecDeque::new());
2114+
let outbound_payments = OutboundPayments::new();
2115+
let payment_id = PaymentId([0; 32]);
2116+
2117+
let invoice = OfferBuilder::new("foo".into(), recipient_pubkey())
2118+
.amount_msats(1000)
2119+
.build().unwrap()
2120+
.request_invoice(vec![1; 32], payer_pubkey()).unwrap()
2121+
.build().unwrap()
2122+
.sign(payer_sign).unwrap()
2123+
.respond_with_no_std(payment_paths(), payment_hash(), now()).unwrap()
2124+
.build().unwrap()
2125+
.sign(recipient_sign).unwrap();
2126+
2127+
router.expect_find_route(
2128+
RouteParameters {
2129+
payment_params: PaymentParameters::from_bolt12_invoice(&invoice),
2130+
final_value_msat: invoice.amount_msats(),
2131+
},
2132+
Ok(Route {
2133+
paths: vec![
2134+
Path {
2135+
hops: vec![
2136+
RouteHop {
2137+
pubkey: recipient_pubkey(),
2138+
node_features: NodeFeatures::empty(),
2139+
short_channel_id: 42,
2140+
channel_features: ChannelFeatures::empty(),
2141+
fee_msat: invoice.amount_msats(),
2142+
cltv_expiry_delta: 0,
2143+
}
2144+
],
2145+
blinded_tail: None,
2146+
}
2147+
],
2148+
payment_params: Some(PaymentParameters::from_bolt12_invoice(&invoice)),
2149+
})
2150+
);
2151+
2152+
assert!(!outbound_payments.has_pending_payments());
2153+
assert_eq!(
2154+
outbound_payments.send_payment_for_bolt12_invoice(
2155+
&invoice, payment_id, &&router, vec![], || InFlightHtlcs::new(), &&keys_manager,
2156+
&&keys_manager, 0, &&logger, &pending_events, |_| panic!()
2157+
),
2158+
Err(Bolt12PaymentError::UnexpectedInvoice),
2159+
);
2160+
assert!(!outbound_payments.has_pending_payments());
2161+
assert!(pending_events.lock().unwrap().is_empty());
2162+
2163+
assert!(outbound_payments.add_new_awaiting_invoice(payment_id).is_ok());
2164+
assert!(outbound_payments.has_pending_payments());
2165+
2166+
assert_eq!(
2167+
outbound_payments.send_payment_for_bolt12_invoice(
2168+
&invoice, payment_id, &&router, vec![], || InFlightHtlcs::new(), &&keys_manager,
2169+
&&keys_manager, 0, &&logger, &pending_events, |_| Ok(())
2170+
),
2171+
Ok(()),
2172+
);
2173+
assert!(outbound_payments.has_pending_payments());
2174+
assert!(pending_events.lock().unwrap().is_empty());
2175+
2176+
assert_eq!(
2177+
outbound_payments.send_payment_for_bolt12_invoice(
2178+
&invoice, payment_id, &&router, vec![], || InFlightHtlcs::new(), &&keys_manager,
2179+
&&keys_manager, 0, &&logger, &pending_events, |_| panic!()
2180+
),
2181+
Err(Bolt12PaymentError::DuplicateInvoice),
2182+
);
2183+
assert!(outbound_payments.has_pending_payments());
2184+
assert!(pending_events.lock().unwrap().is_empty());
2185+
}
19442186
}

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)