@@ -1434,14 +1434,22 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
1434
1434
return_err ! ( "Upstream node set CLTV to the wrong value" , 18 , & byte_utils:: be32_to_array( msg. cltv_expiry) ) ;
1435
1435
}
1436
1436
1437
- let ( payment_data, keysend_preimage) = match next_hop_data. format {
1437
+ let ( mut payment_data, keysend_preimage) = match next_hop_data. format {
1438
1438
msgs:: OnionHopDataFormat :: Legacy { .. } => ( None , None ) ,
1439
1439
msgs:: OnionHopDataFormat :: NonFinalNode { .. } => return_err ! ( "Got non final data with an HMAC of 0" , 0x4000 | 22 , & [ 0 ; 0 ] ) ,
1440
1440
msgs:: OnionHopDataFormat :: FinalNode { payment_data, keysend_preimage } => ( payment_data, keysend_preimage) ,
1441
1441
} ;
1442
1442
1443
1443
if payment_data. is_none ( ) {
1444
- return_err ! ( "We require payment_secrets" , 0x4000 |0x2000 |3 , & [ 0 ; 0 ] ) ;
1444
+ match keysend_preimage {
1445
+ Some ( _) => {
1446
+ payment_data = Some ( msgs:: FinalOnionHopData {
1447
+ payment_secret : PaymentSecret ( [ 0 ; 32 ] ) ,
1448
+ total_msat : msg. amount_msat
1449
+ } ) ;
1450
+ } ,
1451
+ None => return_err ! ( "We require payment_secrets" , 0x4000 |0x2000 |3 , & [ 0 ; 0 ] )
1452
+ }
1445
1453
}
1446
1454
1447
1455
// Note that we could obviously respond immediately with an update_fulfill_htlc
@@ -1622,15 +1630,15 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
1622
1630
}
1623
1631
1624
1632
// Only public for testing, this should otherwise never be called direcly
1625
- pub ( crate ) fn send_payment_along_path ( & self , path : & Vec < RouteHop > , payment_hash : & PaymentHash , payment_secret : & Option < PaymentSecret > , total_value : u64 , cur_height : u32 ) -> Result < ( ) , APIError > {
1633
+ pub ( crate ) fn send_payment_along_path ( & self , path : & Vec < RouteHop > , payment_hash : & PaymentHash , payment_secret : & Option < PaymentSecret > , total_value : u64 , cur_height : u32 , keysend_preimage : & Option < PaymentPreimage > ) -> Result < ( ) , APIError > {
1626
1634
log_trace ! ( self . logger, "Attempting to send payment for path with next hop {}" , path. first( ) . unwrap( ) . short_channel_id) ;
1627
1635
let prng_seed = self . keys_manager . get_secure_random_bytes ( ) ;
1628
1636
let session_priv_bytes = self . keys_manager . get_secure_random_bytes ( ) ;
1629
1637
let session_priv = SecretKey :: from_slice ( & session_priv_bytes[ ..] ) . expect ( "RNG is busted" ) ;
1630
1638
1631
1639
let onion_keys = onion_utils:: construct_onion_keys ( & self . secp_ctx , & path, & session_priv)
1632
1640
. map_err ( |_| APIError :: RouteError { err : "Pubkey along hop was maliciously selected" } ) ?;
1633
- let ( onion_payloads, htlc_msat, htlc_cltv) = onion_utils:: build_onion_payloads ( path, total_value, payment_secret, cur_height) ?;
1641
+ let ( onion_payloads, htlc_msat, htlc_cltv) = onion_utils:: build_onion_payloads ( path, total_value, payment_secret, cur_height, keysend_preimage ) ?;
1634
1642
if onion_utils:: route_size_insane ( & onion_payloads) {
1635
1643
return Err ( APIError :: RouteError { err : "Route size too large considering onion data" } ) ;
1636
1644
}
@@ -1738,6 +1746,10 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
1738
1746
/// bit set (either as required or as available). If multiple paths are present in the Route,
1739
1747
/// we assume the invoice had the basic_mpp feature set.
1740
1748
pub fn send_payment ( & self , route : & Route , payment_hash : PaymentHash , payment_secret : & Option < PaymentSecret > ) -> Result < ( ) , PaymentSendFailure > {
1749
+ self . send_payment_internal ( route, payment_hash, payment_secret, None )
1750
+ }
1751
+
1752
+ fn send_payment_internal ( & self , route : & Route , payment_hash : PaymentHash , payment_secret : & Option < PaymentSecret > , keysend_preimage : Option < PaymentPreimage > ) -> Result < ( ) , PaymentSendFailure > {
1741
1753
if route. paths . len ( ) < 1 {
1742
1754
return Err ( PaymentSendFailure :: ParameterError ( APIError :: RouteError { err : "There must be at least one path to send over" } ) ) ;
1743
1755
}
@@ -1771,7 +1783,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
1771
1783
let cur_height = self . best_block . read ( ) . unwrap ( ) . height ( ) + 1 ;
1772
1784
let mut results = Vec :: new ( ) ;
1773
1785
for path in route. paths . iter ( ) {
1774
- results. push ( self . send_payment_along_path ( & path, & payment_hash, payment_secret, total_value, cur_height) ) ;
1786
+ results. push ( self . send_payment_along_path ( & path, & payment_hash, payment_secret, total_value, cur_height, & keysend_preimage ) ) ;
1775
1787
}
1776
1788
let mut has_ok = false ;
1777
1789
let mut has_err = false ;
@@ -1795,6 +1807,23 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
1795
1807
}
1796
1808
}
1797
1809
1810
+ /// Send a spontaneous payment, which is a payment that does not require the recipient to have
1811
+ /// generated an invoice. Optionally, you may specify the preimage. If you do choose to specify
1812
+ /// the preimage, it must be a secure, random value that no intermediate node would be able to
1813
+ /// guess -- otherwise, an intermediate node may claim the payment and it will never reach the
1814
+ /// recipient.
1815
+ pub fn send_spontaneous_payment ( & self , route : & Route , payment_preimage : Option < PaymentPreimage > ) -> Result < PaymentHash , PaymentSendFailure > {
1816
+ let preimage = match payment_preimage {
1817
+ Some ( p) => p,
1818
+ None => PaymentPreimage ( self . keys_manager . get_secure_random_bytes ( ) ) ,
1819
+ } ;
1820
+ let payment_hash = PaymentHash ( Sha256 :: hash ( & preimage. 0 ) . into_inner ( ) ) ;
1821
+ match self . send_payment_internal ( route, payment_hash, & None , Some ( preimage) ) {
1822
+ Ok ( ( ) ) => Ok ( payment_hash) ,
1823
+ Err ( e) => Err ( e)
1824
+ }
1825
+ }
1826
+
1798
1827
/// Handles the generation of a funding transaction, optionally (for tests) with a function
1799
1828
/// which checks the correctness of the funding transaction given the associated channel.
1800
1829
fn funding_transaction_generated_intern < FundingOutput : Fn ( & Channel < Signer > , & Transaction ) -> Result < OutPoint , APIError > >
@@ -3057,6 +3086,23 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
3057
3086
let ( pending_forward_info, mut channel_state_lock) = self . decode_update_add_htlc_onion ( msg) ;
3058
3087
let channel_state = & mut * channel_state_lock;
3059
3088
3089
+ // If we're receiving a keysend payment, then no payment will have been added to
3090
+ // `self.pending_inbound_payments` in preparation to receive said payment. Thus, if a
3091
+ // keysend_preimage is present, add the pending inbound payment now.
3092
+ match pending_forward_info {
3093
+ PendingHTLCStatus :: Forward ( PendingHTLCInfo { ref routing, .. } ) => {
3094
+ match routing {
3095
+ PendingHTLCRouting :: Receive { payment_data, keysend_preimage : Some ( preimage) , .. } => {
3096
+ let hash = PaymentHash ( Sha256 :: hash ( & preimage. 0 [ ..] ) . into_inner ( ) ) ;
3097
+ let default_invoice_expiry_secs = 60 * 60 ; // 1 hour
3098
+ self . set_payment_hash_secret_map ( hash, Some ( preimage. clone ( ) ) , Some ( payment_data. payment_secret ) , Some ( payment_data. total_msat ) , default_invoice_expiry_secs, 0 ) . unwrap ( ) ;
3099
+ } ,
3100
+ _ => { }
3101
+ }
3102
+ } ,
3103
+ _ => { }
3104
+ }
3105
+
3060
3106
match channel_state. by_id . entry ( msg. channel_id ) {
3061
3107
hash_map:: Entry :: Occupied ( mut chan) => {
3062
3108
if chan. get ( ) . get_counterparty_node_id ( ) != * counterparty_node_id {
@@ -3586,10 +3632,13 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
3586
3632
}
3587
3633
}
3588
3634
3589
- fn set_payment_hash_secret_map ( & self , payment_hash : PaymentHash , payment_preimage : Option < PaymentPreimage > , min_value_msat : Option < u64 > , invoice_expiry_delta_secs : u32 , user_payment_id : u64 ) -> Result < PaymentSecret , APIError > {
3635
+ fn set_payment_hash_secret_map ( & self , payment_hash : PaymentHash , payment_preimage : Option < PaymentPreimage > , payment_secret : Option < PaymentSecret > , min_value_msat : Option < u64 > , invoice_expiry_delta_secs : u32 , user_payment_id : u64 ) -> Result < PaymentSecret , APIError > {
3590
3636
assert ! ( invoice_expiry_delta_secs <= 60 * 60 * 24 * 365 ) ; // Sadly bitcoin timestamps are u32s, so panic before 2106
3591
3637
3592
- let payment_secret = PaymentSecret ( self . keys_manager . get_secure_random_bytes ( ) ) ;
3638
+ let payment_secret = match payment_secret {
3639
+ Some ( secret) => secret,
3640
+ None => PaymentSecret ( self . keys_manager . get_secure_random_bytes ( ) )
3641
+ } ;
3593
3642
3594
3643
let _persistence_guard = PersistenceNotifierGuard :: notify_on_drop ( & self . total_consistency_lock , & self . persistence_notifier ) ;
3595
3644
let mut payment_secrets = self . pending_inbound_payments . lock ( ) . unwrap ( ) ;
@@ -3633,7 +3682,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
3633
3682
let payment_hash = PaymentHash ( Sha256 :: hash ( & payment_preimage. 0 ) . into_inner ( ) ) ;
3634
3683
3635
3684
( payment_hash,
3636
- self . set_payment_hash_secret_map ( payment_hash, Some ( payment_preimage) , min_value_msat, invoice_expiry_delta_secs, user_payment_id)
3685
+ self . set_payment_hash_secret_map ( payment_hash, Some ( payment_preimage) , None , min_value_msat, invoice_expiry_delta_secs, user_payment_id)
3637
3686
. expect ( "RNG Generated Duplicate PaymentHash" ) )
3638
3687
}
3639
3688
@@ -3683,7 +3732,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
3683
3732
/// [`PaymentReceived`]: events::Event::PaymentReceived
3684
3733
/// [`PaymentReceived::user_payment_id`]: events::Event::PaymentReceived::user_payment_id
3685
3734
pub fn create_inbound_payment_for_hash ( & self , payment_hash : PaymentHash , min_value_msat : Option < u64 > , invoice_expiry_delta_secs : u32 , user_payment_id : u64 ) -> Result < PaymentSecret , APIError > {
3686
- self . set_payment_hash_secret_map ( payment_hash, None , min_value_msat, invoice_expiry_delta_secs, user_payment_id)
3735
+ self . set_payment_hash_secret_map ( payment_hash, None , None , min_value_msat, invoice_expiry_delta_secs, user_payment_id)
3687
3736
}
3688
3737
3689
3738
#[ cfg( any( test, feature = "fuzztarget" , feature = "_test_utils" ) ) ]
0 commit comments