@@ -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 ) ]
445446pub ( 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}
0 commit comments