@@ -45,7 +45,7 @@ use chain::transaction::{OutPoint, TransactionData};
45
45
use ln:: { PaymentHash , PaymentPreimage , PaymentSecret } ;
46
46
use ln:: channel:: { Channel , ChannelError , ChannelUpdateStatus , UpdateFulfillCommitFetch } ;
47
47
use ln:: features:: { InitFeatures , NodeFeatures } ;
48
- use routing:: router:: { Route , RouteHop } ;
48
+ use routing:: router:: { Payee , PaymentPathRetry , Route , RouteHop } ;
49
49
use ln:: msgs;
50
50
use ln:: msgs:: NetAddress ;
51
51
use ln:: onion_utils;
@@ -201,6 +201,7 @@ pub(crate) enum HTLCSource {
201
201
first_hop_htlc_msat : u64 ,
202
202
payment_id : PaymentId ,
203
203
payment_secret : Option < PaymentSecret > ,
204
+ payee : Option < Payee > ,
204
205
} ,
205
206
}
206
207
#[ allow( clippy:: derive_hash_xor_eq) ] // Our Hash is faithful to the data, we just don't have SecretKey::hash
@@ -211,13 +212,14 @@ impl core::hash::Hash for HTLCSource {
211
212
0u8 . hash ( hasher) ;
212
213
prev_hop_data. hash ( hasher) ;
213
214
} ,
214
- HTLCSource :: OutboundRoute { path, session_priv, payment_id, payment_secret, first_hop_htlc_msat } => {
215
+ HTLCSource :: OutboundRoute { path, session_priv, payment_id, payment_secret, first_hop_htlc_msat, payee } => {
215
216
1u8 . hash ( hasher) ;
216
217
path. hash ( hasher) ;
217
218
session_priv[ ..] . hash ( hasher) ;
218
219
payment_id. hash ( hasher) ;
219
220
payment_secret. hash ( hasher) ;
220
221
first_hop_htlc_msat. hash ( hasher) ;
222
+ payee. hash ( hasher) ;
221
223
} ,
222
224
}
223
225
}
@@ -231,6 +233,7 @@ impl HTLCSource {
231
233
first_hop_htlc_msat : 0 ,
232
234
payment_id : PaymentId ( [ 2 ; 32 ] ) ,
233
235
payment_secret : None ,
236
+ payee : None ,
234
237
}
235
238
}
236
239
}
@@ -2021,7 +2024,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
2021
2024
}
2022
2025
2023
2026
// Only public for testing, this should otherwise never be called direcly
2024
- pub ( crate ) fn send_payment_along_path ( & self , path : & Vec < RouteHop > , payment_hash : & PaymentHash , payment_secret : & Option < PaymentSecret > , total_value : u64 , cur_height : u32 , payment_id : PaymentId , keysend_preimage : & Option < PaymentPreimage > ) -> Result < ( ) , APIError > {
2027
+ pub ( crate ) fn send_payment_along_path ( & self , path : & Vec < RouteHop > , payee : & Option < Payee > , payment_hash : & PaymentHash , payment_secret : & Option < PaymentSecret > , total_value : u64 , cur_height : u32 , payment_id : PaymentId , keysend_preimage : & Option < PaymentPreimage > ) -> Result < ( ) , APIError > {
2025
2028
log_trace ! ( self . logger, "Attempting to send payment for path with next hop {}" , path. first( ) . unwrap( ) . short_channel_id) ;
2026
2029
let prng_seed = self . keys_manager . get_secure_random_bytes ( ) ;
2027
2030
let session_priv_bytes = self . keys_manager . get_secure_random_bytes ( ) ;
@@ -2071,6 +2074,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
2071
2074
first_hop_htlc_msat: htlc_msat,
2072
2075
payment_id,
2073
2076
payment_secret: payment_secret. clone( ) ,
2077
+ payee: payee. clone( ) ,
2074
2078
} , onion_packet, & self . logger) ,
2075
2079
channel_state, chan) ;
2076
2080
@@ -2209,7 +2213,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
2209
2213
let cur_height = self . best_block . read ( ) . unwrap ( ) . height ( ) + 1 ;
2210
2214
let mut results = Vec :: new ( ) ;
2211
2215
for path in route. paths . iter ( ) {
2212
- results. push ( self . send_payment_along_path ( & path, & payment_hash, payment_secret, total_value, cur_height, payment_id, & keysend_preimage) ) ;
2216
+ results. push ( self . send_payment_along_path ( & path, & route . payee , & payment_hash, payment_secret, total_value, cur_height, payment_id, & keysend_preimage) ) ;
2213
2217
}
2214
2218
let mut has_ok = false ;
2215
2219
let mut has_err = false ;
@@ -3098,14 +3102,22 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
3098
3102
self . fail_htlc_backwards_internal ( channel_state,
3099
3103
htlc_src, & payment_hash, HTLCFailReason :: Reason { failure_code, data : onion_failure_data} ) ;
3100
3104
} ,
3101
- HTLCSource :: OutboundRoute { session_priv, payment_id, path, .. } => {
3105
+ HTLCSource :: OutboundRoute { session_priv, payment_id, path, payee , .. } => {
3102
3106
let mut session_priv_bytes = [ 0 ; 32 ] ;
3103
3107
session_priv_bytes. copy_from_slice ( & session_priv[ ..] ) ;
3104
3108
let mut outbounds = self . pending_outbound_payments . lock ( ) . unwrap ( ) ;
3105
3109
if let hash_map:: Entry :: Occupied ( mut payment) = outbounds. entry ( payment_id) {
3106
- if payment. get_mut ( ) . remove ( & session_priv_bytes, Some ( path. last ( ) . unwrap ( ) . fee_msat ) ) &&
3110
+ let path_last_hop = path. last ( ) . expect ( "Outbound payments must have had a valid path" ) ;
3111
+ if payment. get_mut ( ) . remove ( & session_priv_bytes, Some ( path_last_hop. fee_msat ) ) &&
3107
3112
!payment. get ( ) . is_fulfilled ( )
3108
3113
{
3114
+ let retry = if let Some ( payee_data) = payee {
3115
+ Some ( PaymentPathRetry {
3116
+ payee : payee_data,
3117
+ final_value_msat : path_last_hop. fee_msat ,
3118
+ final_cltv_expiry_delta : path_last_hop. cltv_expiry_delta ,
3119
+ } )
3120
+ } else { None } ;
3109
3121
self . pending_events . lock ( ) . unwrap ( ) . push (
3110
3122
events:: Event :: PaymentPathFailed {
3111
3123
payment_hash,
@@ -3114,7 +3126,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
3114
3126
all_paths_failed : payment. get ( ) . remaining_parts ( ) == 0 ,
3115
3127
path : path. clone ( ) ,
3116
3128
short_channel_id : None ,
3117
- retry : None ,
3129
+ retry,
3118
3130
#[ cfg( test) ]
3119
3131
error_code : None ,
3120
3132
#[ cfg( test) ]
@@ -3146,13 +3158,14 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
3146
3158
// from block_connected which may run during initialization prior to the chain_monitor
3147
3159
// being fully configured. See the docs for `ChannelManagerReadArgs` for more.
3148
3160
match source {
3149
- HTLCSource :: OutboundRoute { ref path, session_priv, payment_id, .. } => {
3161
+ HTLCSource :: OutboundRoute { ref path, session_priv, payment_id, ref payee , .. } => {
3150
3162
let mut session_priv_bytes = [ 0 ; 32 ] ;
3151
3163
session_priv_bytes. copy_from_slice ( & session_priv[ ..] ) ;
3152
3164
let mut outbounds = self . pending_outbound_payments . lock ( ) . unwrap ( ) ;
3153
3165
let mut all_paths_failed = false ;
3166
+ let path_last_hop = path. last ( ) . expect ( "Outbound payments must have had a valid path" ) ;
3154
3167
if let hash_map:: Entry :: Occupied ( mut payment) = outbounds. entry ( payment_id) {
3155
- if !payment. get_mut ( ) . remove ( & session_priv_bytes, Some ( path . last ( ) . unwrap ( ) . fee_msat ) ) {
3168
+ if !payment. get_mut ( ) . remove ( & session_priv_bytes, Some ( path_last_hop . fee_msat ) ) {
3156
3169
log_trace ! ( self . logger, "Received duplicative fail for HTLC with payment_hash {}" , log_bytes!( payment_hash. 0 ) ) ;
3157
3170
return ;
3158
3171
}
@@ -3167,8 +3180,15 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
3167
3180
log_trace ! ( self . logger, "Received duplicative fail for HTLC with payment_hash {}" , log_bytes!( payment_hash. 0 ) ) ;
3168
3181
return ;
3169
3182
}
3170
- log_trace ! ( self . logger, "Failing outbound payment HTLC with payment_hash {}" , log_bytes!( payment_hash. 0 ) ) ;
3171
3183
mem:: drop ( channel_state_lock) ;
3184
+ let retry = if let Some ( payee_data) = payee {
3185
+ Some ( PaymentPathRetry {
3186
+ payee : payee_data. clone ( ) ,
3187
+ final_value_msat : path_last_hop. fee_msat ,
3188
+ final_cltv_expiry_delta : path_last_hop. cltv_expiry_delta ,
3189
+ } )
3190
+ } else { None } ;
3191
+ log_trace ! ( self . logger, "Failing outbound payment HTLC with payment_hash {}" , log_bytes!( payment_hash. 0 ) ) ;
3172
3192
match & onion_error {
3173
3193
& HTLCFailReason :: LightningError { ref err } => {
3174
3194
#[ cfg( test) ]
@@ -3186,7 +3206,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
3186
3206
all_paths_failed,
3187
3207
path : path. clone ( ) ,
3188
3208
short_channel_id,
3189
- retry : None ,
3209
+ retry,
3190
3210
#[ cfg( test) ]
3191
3211
error_code : onion_error_code,
3192
3212
#[ cfg( test) ]
@@ -3215,7 +3235,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
3215
3235
all_paths_failed,
3216
3236
path : path. clone ( ) ,
3217
3237
short_channel_id : Some ( path. first ( ) . unwrap ( ) . short_channel_id ) ,
3218
- retry : None ,
3238
+ retry,
3219
3239
#[ cfg( test) ]
3220
3240
error_code : Some ( * failure_code) ,
3221
3241
#[ cfg( test) ]
@@ -5378,12 +5398,14 @@ impl Readable for HTLCSource {
5378
5398
let mut path = Some ( Vec :: new ( ) ) ;
5379
5399
let mut payment_id = None ;
5380
5400
let mut payment_secret = None ;
5401
+ let mut payee = None ;
5381
5402
read_tlv_fields ! ( reader, {
5382
5403
( 0 , session_priv, required) ,
5383
5404
( 1 , payment_id, option) ,
5384
5405
( 2 , first_hop_htlc_msat, required) ,
5385
5406
( 3 , payment_secret, option) ,
5386
5407
( 4 , path, vec_type) ,
5408
+ ( 5 , payee, option) ,
5387
5409
} ) ;
5388
5410
if payment_id. is_none ( ) {
5389
5411
// For backwards compat, if there was no payment_id written, use the session_priv bytes
@@ -5396,6 +5418,7 @@ impl Readable for HTLCSource {
5396
5418
path : path. unwrap ( ) ,
5397
5419
payment_id : payment_id. unwrap ( ) ,
5398
5420
payment_secret,
5421
+ payee,
5399
5422
} )
5400
5423
}
5401
5424
1 => Ok ( HTLCSource :: PreviousHopData ( Readable :: read ( reader) ?) ) ,
@@ -5407,7 +5430,7 @@ impl Readable for HTLCSource {
5407
5430
impl Writeable for HTLCSource {
5408
5431
fn write < W : Writer > ( & self , writer : & mut W ) -> Result < ( ) , :: io:: Error > {
5409
5432
match self {
5410
- HTLCSource :: OutboundRoute { ref session_priv, ref first_hop_htlc_msat, ref path, payment_id, payment_secret } => {
5433
+ HTLCSource :: OutboundRoute { ref session_priv, ref first_hop_htlc_msat, ref path, payment_id, payment_secret, payee } => {
5411
5434
0u8 . write ( writer) ?;
5412
5435
let payment_id_opt = Some ( payment_id) ;
5413
5436
write_tlv_fields ! ( writer, {
@@ -5416,6 +5439,7 @@ impl Writeable for HTLCSource {
5416
5439
( 2 , first_hop_htlc_msat, required) ,
5417
5440
( 3 , payment_secret, option) ,
5418
5441
( 4 , path, vec_type) ,
5442
+ ( 5 , payee, option) ,
5419
5443
} ) ;
5420
5444
}
5421
5445
HTLCSource :: PreviousHopData ( ref field) => {
@@ -6160,7 +6184,7 @@ mod tests {
6160
6184
// Use the utility function send_payment_along_path to send the payment with MPP data which
6161
6185
// indicates there are more HTLCs coming.
6162
6186
let cur_height = CHAN_CONFIRM_DEPTH + 1 ; // route_payment calls send_payment, which adds 1 to the current height. So we do the same here to match.
6163
- nodes[ 0 ] . node . send_payment_along_path ( & route. paths [ 0 ] , & our_payment_hash, & Some ( payment_secret) , 200_000 , cur_height, payment_id, & None ) . unwrap ( ) ;
6187
+ nodes[ 0 ] . node . send_payment_along_path ( & route. paths [ 0 ] , & route . payee , & our_payment_hash, & Some ( payment_secret) , 200_000 , cur_height, payment_id, & None ) . unwrap ( ) ;
6164
6188
check_added_monitors ! ( nodes[ 0 ] , 1 ) ;
6165
6189
let mut events = nodes[ 0 ] . node . get_and_clear_pending_msg_events ( ) ;
6166
6190
assert_eq ! ( events. len( ) , 1 ) ;
@@ -6190,7 +6214,7 @@ mod tests {
6190
6214
expect_payment_failed ! ( nodes[ 0 ] , our_payment_hash, true ) ;
6191
6215
6192
6216
// Send the second half of the original MPP payment.
6193
- nodes[ 0 ] . node . send_payment_along_path ( & route. paths [ 0 ] , & our_payment_hash, & Some ( payment_secret) , 200_000 , cur_height, payment_id, & None ) . unwrap ( ) ;
6217
+ nodes[ 0 ] . node . send_payment_along_path ( & route. paths [ 0 ] , & route . payee , & our_payment_hash, & Some ( payment_secret) , 200_000 , cur_height, payment_id, & None ) . unwrap ( ) ;
6194
6218
check_added_monitors ! ( nodes[ 0 ] , 1 ) ;
6195
6219
let mut events = nodes[ 0 ] . node . get_and_clear_pending_msg_events ( ) ;
6196
6220
assert_eq ! ( events. len( ) , 1 ) ;
0 commit comments