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