2727//! # extern crate lightning_invoice;
2828//! # extern crate secp256k1;
2929//! #
30- //! # use lightning::ln::{PaymentHash, PaymentSecret};
30+ //! # use lightning::ln::{PaymentHash, PaymentPreimage, PaymentSecret};
3131//! # use lightning::ln::channelmanager::{ChannelDetails, PaymentId, PaymentSendFailure};
3232//! # use lightning::ln::msgs::LightningError;
3333//! # use lightning::routing;
5353//! # fn send_payment(
5454//! # &self, route: &Route, payment_hash: PaymentHash, payment_secret: &Option<PaymentSecret>
5555//! # ) -> Result<PaymentId, PaymentSendFailure> { unimplemented!() }
56+ //! # fn send_spontaneous_payment(
57+ //! # &self, route: &Route, payment_preimage: PaymentPreimage
58+ //! # ) -> Result<PaymentId, PaymentSendFailure> { unimplemented!() }
5659//! # fn retry_payment(
5760//! # &self, route: &Route, payment_id: PaymentId
5861//! # ) -> Result<(), PaymentSendFailure> { unimplemented!() }
110113//! as updates to the network graph or changes to channel scores should be applied prior to
111114//! retries, typically by way of composing [`EventHandler`]s accordingly.
112115
113- use crate :: Invoice ;
116+ use crate :: { DEFAULT_MIN_FINAL_CLTV_EXPIRY , Invoice } ;
114117
115118use bitcoin_hashes:: Hash ;
119+ use bitcoin_hashes:: sha256:: Hash as Sha256 ;
116120
117- use lightning:: ln:: { PaymentHash , PaymentSecret } ;
121+ use lightning:: ln:: { PaymentHash , PaymentPreimage , PaymentSecret } ;
118122use lightning:: ln:: channelmanager:: { ChannelDetails , PaymentId , PaymentSendFailure } ;
119123use lightning:: ln:: msgs:: LightningError ;
120124use lightning:: routing;
@@ -161,6 +165,11 @@ pub trait Payer {
161165 & self , route : & Route , payment_hash : PaymentHash , payment_secret : & Option < PaymentSecret >
162166 ) -> Result < PaymentId , PaymentSendFailure > ;
163167
168+ /// Sends a spontaneous payment over the Lightning Network using the given [`Route`].
169+ fn send_spontaneous_payment (
170+ & self , route : & Route , payment_preimage : PaymentPreimage
171+ ) -> Result < PaymentId , PaymentSendFailure > ;
172+
164173 /// Retries a failed payment path for the [`PaymentId`] using the given [`Route`].
165174 fn retry_payment ( & self , route : & Route , payment_id : PaymentId ) -> Result < ( ) , PaymentSendFailure > ;
166175}
@@ -282,15 +291,54 @@ where
282291 final_cltv_expiry_delta : invoice. min_final_cltv_expiry ( ) as u32 ,
283292 } ;
284293
285- self . pay_internal ( & mut entry, & params, payment_hash, & payment_secret)
294+ let send_payment = |route : & Route | {
295+ self . payer . send_payment ( route, payment_hash, & payment_secret)
296+ } ;
297+ self . pay_internal ( & mut entry, & params, send_payment)
298+ . map_err ( |e| { entry. remove ( ) ; e } )
299+ }
300+
301+ /// Pays `pubkey` an amount using the hash of the given preimage, caching it for later use in
302+ /// case a retry is needed.
303+ ///
304+ /// You should ensure that `payment_preimage` is unique and that its `payment_hash` has never
305+ /// been paid before. Because [`InvoicePayer`] is stateless no effort is made to do so for you.
306+ pub fn pay_pubkey (
307+ & self , pubkey : PublicKey , payment_preimage : PaymentPreimage , amount_msats : u64
308+ ) -> Result < PaymentId , PaymentError > {
309+ let payment_hash = PaymentHash ( Sha256 :: hash ( & payment_preimage. 0 ) . into_inner ( ) ) ;
310+ let mut payment_cache = self . payment_cache . lock ( ) . unwrap ( ) ;
311+ let mut entry = match payment_cache. entry ( payment_hash) {
312+ hash_map:: Entry :: Occupied ( _) => return Err ( PaymentError :: Invoice ( "payment pending" ) ) ,
313+ hash_map:: Entry :: Vacant ( entry) => {
314+ // TODO: Replace with hash_map::Entry::insert once no longer experimental
315+ entry. insert ( 0 ) ;
316+ match payment_cache. entry ( payment_hash) {
317+ hash_map:: Entry :: Occupied ( entry) => entry,
318+ hash_map:: Entry :: Vacant ( _) => unreachable ! ( ) ,
319+ }
320+ } ,
321+ } ;
322+
323+ let payee = Payee :: for_keysend ( pubkey) ;
324+ let params = RouteParameters {
325+ payee,
326+ final_value_msat : amount_msats,
327+ final_cltv_expiry_delta : DEFAULT_MIN_FINAL_CLTV_EXPIRY as u32 ,
328+ } ;
329+
330+ let send_payment = |route : & Route | {
331+ self . payer . send_spontaneous_payment ( route, payment_preimage)
332+ } ;
333+ self . pay_internal ( & mut entry, & params, send_payment)
286334 . map_err ( |e| { entry. remove ( ) ; e } )
287335 }
288336
289- fn pay_internal (
290- & self , entry : & mut PaymentEntry , params : & RouteParameters , payment_hash : PaymentHash ,
291- payment_secret : & Option < PaymentSecret > ,
337+ fn pay_internal < F : FnOnce ( & Route ) -> Result < PaymentId , PaymentSendFailure > + Copy > (
338+ & self , entry : & mut PaymentEntry , params : & RouteParameters , send_payment : F ,
292339 ) -> Result < PaymentId , PaymentError > {
293340 if has_expired ( params) {
341+ let payment_hash = entry. key ( ) ;
294342 log_trace ! ( self . logger, "Invoice expired prior to send for payment {}" , log_bytes!( payment_hash. 0 ) ) ;
295343 return Err ( PaymentError :: Invoice ( "Invoice expired prior to send" ) ) ;
296344 }
@@ -304,7 +352,7 @@ where
304352 & self . scorer . lock ( ) ,
305353 ) . map_err ( |e| PaymentError :: Routing ( e) ) ?;
306354
307- match self . payer . send_payment ( & route, payment_hash , payment_secret ) {
355+ match send_payment ( & route) {
308356 Ok ( payment_id) => Ok ( payment_id) ,
309357 Err ( e) => match e {
310358 PaymentSendFailure :: ParameterError ( _) => Err ( e) ,
@@ -315,7 +363,7 @@ where
315363 Err ( e)
316364 } else {
317365 * retry_count += 1 ;
318- Ok ( self . pay_internal ( entry, params, payment_hash , payment_secret ) ?)
366+ Ok ( self . pay_internal ( entry, params, send_payment ) ?)
319367 }
320368 } ,
321369 PaymentSendFailure :: PartialFailure { failed_paths_retry, payment_id, .. } => {
@@ -530,6 +578,10 @@ mod tests {
530578 . unwrap ( )
531579 }
532580
581+ fn pubkey ( ) -> PublicKey {
582+ PublicKey :: from_slice ( & hex:: decode ( "02eec7245d6b7d2ccb30380bfbe2a3648cd7a942653f5aa340edcea1f283686619" ) . unwrap ( ) [ ..] ) . unwrap ( )
583+ }
584+
533585 #[ test]
534586 fn pays_invoice_on_first_attempt ( ) {
535587 let event_handled = core:: cell:: RefCell :: new ( false ) ;
@@ -985,6 +1037,55 @@ mod tests {
9851037 }
9861038 }
9871039
1040+ #[ test]
1041+ fn pays_pubkey_with_amount ( ) {
1042+ let event_handled = core:: cell:: RefCell :: new ( false ) ;
1043+ let event_handler = |_: & _ | { * event_handled. borrow_mut ( ) = true ; } ;
1044+
1045+ let pubkey = pubkey ( ) ;
1046+ let payment_preimage = PaymentPreimage ( [ 1 ; 32 ] ) ;
1047+ let payment_hash = PaymentHash ( Sha256 :: hash ( & payment_preimage. 0 ) . into_inner ( ) ) ;
1048+ let final_value_msat = 100 ;
1049+
1050+ let payer = TestPayer :: new ( )
1051+ . expect_send ( Amount :: Spontaneous ( final_value_msat) )
1052+ . expect_send ( Amount :: ForInvoiceOrRetry ( final_value_msat) ) ;
1053+ let router = TestRouter { } ;
1054+ let scorer = RefCell :: new ( TestScorer :: new ( ) ) ;
1055+ let logger = TestLogger :: new ( ) ;
1056+ let invoice_payer =
1057+ InvoicePayer :: new ( & payer, router, & scorer, & logger, event_handler, RetryAttempts ( 2 ) ) ;
1058+
1059+ let payment_id =
1060+ Some ( invoice_payer. pay_pubkey ( pubkey, payment_preimage, final_value_msat) . unwrap ( ) ) ;
1061+ assert_eq ! ( * payer. attempts. borrow( ) , 1 ) ;
1062+
1063+ let retry = RouteParameters {
1064+ payee : Payee :: for_keysend ( pubkey) ,
1065+ final_value_msat,
1066+ final_cltv_expiry_delta : DEFAULT_MIN_FINAL_CLTV_EXPIRY as u32 ,
1067+ } ;
1068+ let event = Event :: PaymentPathFailed {
1069+ payment_id,
1070+ payment_hash,
1071+ network_update : None ,
1072+ rejected_by_dest : false ,
1073+ all_paths_failed : false ,
1074+ path : vec ! [ ] ,
1075+ short_channel_id : None ,
1076+ retry : Some ( retry) ,
1077+ } ;
1078+ invoice_payer. handle_event ( & event) ;
1079+ assert_eq ! ( * event_handled. borrow( ) , false ) ;
1080+ assert_eq ! ( * payer. attempts. borrow( ) , 2 ) ;
1081+
1082+ invoice_payer. handle_event ( & Event :: PaymentSent {
1083+ payment_id, payment_preimage, payment_hash, fee_paid_msat : None
1084+ } ) ;
1085+ assert_eq ! ( * event_handled. borrow( ) , true ) ;
1086+ assert_eq ! ( * payer. attempts. borrow( ) , 2 ) ;
1087+ }
1088+
9881089 #[ test]
9891090 fn scores_failed_channel ( ) {
9901091 let event_handled = core:: cell:: RefCell :: new ( false ) ;
@@ -1132,11 +1233,17 @@ mod tests {
11321233 }
11331234
11341235 struct TestPayer {
1135- expectations : core:: cell:: RefCell < VecDeque < u64 > > ,
1236+ expectations : core:: cell:: RefCell < VecDeque < Amount > > ,
11361237 attempts : core:: cell:: RefCell < usize > ,
11371238 failing_on_attempt : Option < usize > ,
11381239 }
11391240
1241+ #[ derive( Clone , Debug , PartialEq , Eq ) ]
1242+ enum Amount {
1243+ ForInvoiceOrRetry ( u64 ) ,
1244+ Spontaneous ( u64 ) ,
1245+ }
1246+
11401247 impl TestPayer {
11411248 fn new ( ) -> Self {
11421249 Self {
@@ -1147,6 +1254,11 @@ mod tests {
11471254 }
11481255
11491256 fn expect_value_msat ( self , value_msat : u64 ) -> Self {
1257+ self . expectations . borrow_mut ( ) . push_back ( Amount :: ForInvoiceOrRetry ( value_msat) ) ;
1258+ self
1259+ }
1260+
1261+ fn expect_send ( self , value_msat : Amount ) -> Self {
11501262 self . expectations . borrow_mut ( ) . push_back ( value_msat) ;
11511263 self
11521264 }
@@ -1169,10 +1281,9 @@ mod tests {
11691281 }
11701282 }
11711283
1172- fn check_value_msats ( & self , route : & Route ) {
1284+ fn check_value_msats ( & self , actual_value_msats : Amount ) {
11731285 let expected_value_msats = self . expectations . borrow_mut ( ) . pop_front ( ) ;
11741286 if let Some ( expected_value_msats) = expected_value_msats {
1175- let actual_value_msats = route. get_total_amount ( ) ;
11761287 assert_eq ! ( actual_value_msats, expected_value_msats) ;
11771288 }
11781289 }
@@ -1207,7 +1318,20 @@ mod tests {
12071318 _payment_secret : & Option < PaymentSecret >
12081319 ) -> Result < PaymentId , PaymentSendFailure > {
12091320 if self . check_attempts ( ) {
1210- self . check_value_msats ( route) ;
1321+ self . check_value_msats ( Amount :: ForInvoiceOrRetry ( route. get_total_amount ( ) ) ) ;
1322+ Ok ( PaymentId ( [ 1 ; 32 ] ) )
1323+ } else {
1324+ Err ( PaymentSendFailure :: ParameterError ( APIError :: MonitorUpdateFailed ) )
1325+ }
1326+ }
1327+
1328+ fn send_spontaneous_payment (
1329+ & self ,
1330+ route : & Route ,
1331+ _payment_preimage : PaymentPreimage ,
1332+ ) -> Result < PaymentId , PaymentSendFailure > {
1333+ if self . check_attempts ( ) {
1334+ self . check_value_msats ( Amount :: Spontaneous ( route. get_total_amount ( ) ) ) ;
12111335 Ok ( PaymentId ( [ 1 ; 32 ] ) )
12121336 } else {
12131337 Err ( PaymentSendFailure :: ParameterError ( APIError :: MonitorUpdateFailed ) )
@@ -1218,7 +1342,7 @@ mod tests {
12181342 & self , route : & Route , _payment_id : PaymentId
12191343 ) -> Result < ( ) , PaymentSendFailure > {
12201344 if self . check_attempts ( ) {
1221- self . check_value_msats ( route) ;
1345+ self . check_value_msats ( Amount :: ForInvoiceOrRetry ( route. get_total_amount ( ) ) ) ;
12221346 Ok ( ( ) )
12231347 } else {
12241348 Err ( PaymentSendFailure :: ParameterError ( APIError :: MonitorUpdateFailed ) )
0 commit comments