@@ -436,6 +436,7 @@ pub(crate) enum PendingOutboundPayment {
436
436
payment_hash : PaymentHash ,
437
437
payment_secret : Option < PaymentSecret > ,
438
438
pending_amt_msat : u64 ,
439
+ pending_fee_msat : u64 ,
439
440
/// The total payment amount across all paths, used to verify that a retry is not overpaying.
440
441
total_msat : u64 ,
441
442
/// Our best known block height at the time this payment was initiated.
@@ -462,6 +463,12 @@ impl PendingOutboundPayment {
462
463
_ => false ,
463
464
}
464
465
}
466
+ fn get_total_fee_msat ( & self ) -> Option < u64 > {
467
+ match self {
468
+ PendingOutboundPayment :: Retryable { pending_fee_msat, .. } => Some ( * pending_fee_msat) ,
469
+ _ => None ,
470
+ }
471
+ }
465
472
466
473
fn mark_fulfilled ( & mut self ) {
467
474
let mut session_privs = HashSet :: new ( ) ;
@@ -475,7 +482,7 @@ impl PendingOutboundPayment {
475
482
}
476
483
477
484
/// panics if part_amt_msat is None and !self.is_fulfilled
478
- fn remove ( & mut self , session_priv : & [ u8 ; 32 ] , part_amt_msat : Option < u64 > ) -> bool {
485
+ fn remove ( & mut self , session_priv : & [ u8 ; 32 ] , part_amt_msat : Option < u64 > , part_fee_msat : Option < u64 > ) -> bool {
479
486
let remove_res = match self {
480
487
PendingOutboundPayment :: Legacy { session_privs } |
481
488
PendingOutboundPayment :: Retryable { session_privs, .. } |
@@ -484,14 +491,15 @@ impl PendingOutboundPayment {
484
491
}
485
492
} ;
486
493
if remove_res {
487
- if let PendingOutboundPayment :: Retryable { ref mut pending_amt_msat, .. } = self {
494
+ if let PendingOutboundPayment :: Retryable { ref mut pending_amt_msat, ref mut pending_fee_msat , .. } = self {
488
495
* pending_amt_msat -= part_amt_msat. expect ( "We must only not provide an amount if the payment was already fulfilled" ) ;
496
+ * pending_fee_msat -= part_fee_msat. expect ( "We must only not provide a fee if the payment was already fulfilled" ) ;
489
497
}
490
498
}
491
499
remove_res
492
500
}
493
501
494
- fn insert ( & mut self , session_priv : [ u8 ; 32 ] , part_amt_msat : u64 ) -> bool {
502
+ fn insert ( & mut self , session_priv : [ u8 ; 32 ] , part_amt_msat : u64 , part_fee_msat : u64 ) -> bool {
495
503
let insert_res = match self {
496
504
PendingOutboundPayment :: Legacy { session_privs } |
497
505
PendingOutboundPayment :: Retryable { session_privs, .. } => {
@@ -500,8 +508,9 @@ impl PendingOutboundPayment {
500
508
PendingOutboundPayment :: Fulfilled { .. } => false
501
509
} ;
502
510
if insert_res {
503
- if let PendingOutboundPayment :: Retryable { ref mut pending_amt_msat, .. } = self {
511
+ if let PendingOutboundPayment :: Retryable { ref mut pending_amt_msat, ref mut pending_fee_msat , .. } = self {
504
512
* pending_amt_msat += part_amt_msat;
513
+ * pending_fee_msat += part_fee_msat;
505
514
}
506
515
}
507
516
insert_res
@@ -2081,12 +2090,14 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
2081
2090
let payment = payment_entry. or_insert_with ( || PendingOutboundPayment :: Retryable {
2082
2091
session_privs : HashSet :: new ( ) ,
2083
2092
pending_amt_msat : 0 ,
2093
+ pending_fee_msat : 0 ,
2084
2094
payment_hash : * payment_hash,
2085
2095
payment_secret : * payment_secret,
2086
2096
starting_block_height : self . best_block . read ( ) . unwrap ( ) . height ( ) ,
2087
2097
total_msat : total_value,
2088
2098
} ) ;
2089
- assert ! ( payment. insert( session_priv_bytes, path. last( ) . unwrap( ) . fee_msat) ) ;
2099
+ assert ! ( payment. insert( session_priv_bytes, path. last( ) . unwrap( ) . fee_msat,
2100
+ path. split_last( ) . map( |( _, path_prefix) | path_prefix) . unwrap_or( & [ ] ) . iter( ) . map( |hop| hop. fee_msat) . sum( ) ) ) ;
2090
2101
2091
2102
send_res
2092
2103
} {
@@ -3108,7 +3119,8 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
3108
3119
let mut outbounds = self . pending_outbound_payments . lock ( ) . unwrap ( ) ;
3109
3120
if let hash_map:: Entry :: Occupied ( mut payment) = outbounds. entry ( payment_id) {
3110
3121
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 ) ) &&
3122
+ if payment. get_mut ( ) . remove ( & session_priv_bytes, Some ( path_last_hop. fee_msat ) ,
3123
+ Some ( path. split_last ( ) . map ( |( _, path_prefix) | path_prefix) . unwrap_or ( & [ ] ) . iter ( ) . map ( |hop| hop. fee_msat ) . sum ( ) ) ) &&
3112
3124
!payment. get ( ) . is_fulfilled ( )
3113
3125
{
3114
3126
let retry = if let Some ( payee_data) = payee {
@@ -3165,7 +3177,9 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
3165
3177
let mut all_paths_failed = false ;
3166
3178
let path_last_hop = path. last ( ) . expect ( "Outbound payments must have had a valid path" ) ;
3167
3179
if let hash_map:: Entry :: Occupied ( mut payment) = outbounds. entry ( payment_id) {
3168
- if !payment. get_mut ( ) . remove ( & session_priv_bytes, Some ( path_last_hop. fee_msat ) ) {
3180
+ if !payment. get_mut ( ) . remove ( & session_priv_bytes, Some ( path_last_hop. fee_msat ) ,
3181
+ Some ( path. split_last ( ) . map ( |( _, path_prefix) | path_prefix) . unwrap_or ( & [ ] ) . iter ( ) . map ( |hop| hop. fee_msat ) . sum ( ) ) )
3182
+ {
3169
3183
log_trace ! ( self . logger, "Received duplicative fail for HTLC with payment_hash {}" , log_bytes!( payment_hash. 0 ) ) ;
3170
3184
return ;
3171
3185
}
@@ -3438,7 +3452,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
3438
3452
let mut outbounds = self . pending_outbound_payments . lock ( ) . unwrap ( ) ;
3439
3453
if let hash_map:: Entry :: Occupied ( mut payment) = outbounds. entry ( payment_id) {
3440
3454
assert ! ( payment. get( ) . is_fulfilled( ) ) ;
3441
- payment. get_mut ( ) . remove ( & session_priv_bytes, None ) ;
3455
+ payment. get_mut ( ) . remove ( & session_priv_bytes, None , None ) ;
3442
3456
if payment. get ( ) . remaining_parts ( ) == 0 {
3443
3457
payment. remove ( ) ;
3444
3458
}
@@ -3454,8 +3468,9 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
3454
3468
let mut session_priv_bytes = [ 0 ; 32 ] ;
3455
3469
session_priv_bytes. copy_from_slice ( & session_priv[ ..] ) ;
3456
3470
let mut outbounds = self . pending_outbound_payments . lock ( ) . unwrap ( ) ;
3457
- let found_payment = if let hash_map:: Entry :: Occupied ( mut payment) = outbounds. entry ( payment_id) {
3471
+ if let hash_map:: Entry :: Occupied ( mut payment) = outbounds. entry ( payment_id) {
3458
3472
let found_payment = !payment. get ( ) . is_fulfilled ( ) ;
3473
+ let fee_paid_msat = payment. get ( ) . get_total_fee_msat ( ) ;
3459
3474
payment. get_mut ( ) . mark_fulfilled ( ) ;
3460
3475
if from_onchain {
3461
3476
// We currently immediately remove HTLCs which were fulfilled on-chain.
@@ -3464,21 +3479,22 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
3464
3479
// restart.
3465
3480
// TODO: We should have a second monitor event that informs us of payments
3466
3481
// irrevocably fulfilled.
3467
- payment. get_mut ( ) . remove ( & session_priv_bytes, Some ( path. last ( ) . unwrap ( ) . fee_msat ) ) ;
3482
+ payment. get_mut ( ) . remove ( & session_priv_bytes, Some ( path. last ( ) . unwrap ( ) . fee_msat ) ,
3483
+ Some ( path. split_last ( ) . map ( |( _, path_prefix) | path_prefix) . unwrap_or ( & [ ] ) . iter ( ) . map ( |hop| hop. fee_msat ) . sum ( ) ) ) ;
3468
3484
if payment. get ( ) . remaining_parts ( ) == 0 {
3469
3485
payment. remove ( ) ;
3470
3486
}
3471
3487
}
3472
- found_payment
3473
- } else { false } ;
3474
- if found_payment {
3475
- let payment_hash = PaymentHash ( Sha256 :: hash ( & payment_preimage . 0 ) . into_inner ( ) ) ;
3476
- self . pending_events . lock ( ) . unwrap ( ) . push (
3477
- events :: Event :: PaymentSent {
3478
- payment_preimage ,
3479
- payment_hash : payment_hash
3480
- }
3481
- ) ;
3488
+ if found_payment {
3489
+ let payment_hash = PaymentHash ( Sha256 :: hash ( & payment_preimage . 0 ) . into_inner ( ) ) ;
3490
+ self . pending_events . lock ( ) . unwrap ( ) . push (
3491
+ events :: Event :: PaymentSent {
3492
+ payment_preimage ,
3493
+ payment_hash : payment_hash ,
3494
+ fee_paid_msat ,
3495
+ }
3496
+ ) ;
3497
+ }
3482
3498
} else {
3483
3499
log_trace ! ( self . logger, "Received duplicative fulfill for HTLC with payment_preimage {}" , log_bytes!( payment_preimage. 0 ) ) ;
3484
3500
}
@@ -5496,6 +5512,7 @@ impl_writeable_tlv_based_enum_upgradable!(PendingOutboundPayment,
5496
5512
( 6 , total_msat, required) ,
5497
5513
( 8 , pending_amt_msat, required) ,
5498
5514
( 10 , starting_block_height, required) ,
5515
+ ( 12 , pending_fee_msat, required) ,
5499
5516
} ,
5500
5517
) ;
5501
5518
@@ -5943,11 +5960,12 @@ impl<'a, Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>
5943
5960
return Err ( DecodeError :: InvalidValue ) ;
5944
5961
}
5945
5962
let path_amt = path. last ( ) . unwrap ( ) . fee_msat ;
5963
+ let path_fee = path. split_last ( ) . map ( |( _, path_prefix) | path_prefix) . unwrap_or ( & [ ] ) . iter ( ) . map ( |hop| hop. fee_msat ) . sum ( ) ;
5946
5964
let mut session_priv_bytes = [ 0 ; 32 ] ;
5947
5965
session_priv_bytes[ ..] . copy_from_slice ( & session_priv[ ..] ) ;
5948
5966
match pending_outbound_payments. as_mut ( ) . unwrap ( ) . entry ( payment_id) {
5949
5967
hash_map:: Entry :: Occupied ( mut entry) => {
5950
- let newly_added = entry. get_mut ( ) . insert ( session_priv_bytes, path_amt) ;
5968
+ let newly_added = entry. get_mut ( ) . insert ( session_priv_bytes, path_amt, path_fee ) ;
5951
5969
log_info ! ( args. logger, "{} a pending payment path for {} msat for session priv {} on an existing pending payment with payment hash {}" ,
5952
5970
if newly_added { "Added" } else { "Had" } , path_amt, log_bytes!( session_priv_bytes) , log_bytes!( htlc. payment_hash. 0 ) ) ;
5953
5971
} ,
@@ -5957,6 +5975,7 @@ impl<'a, Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>
5957
5975
payment_hash : htlc. payment_hash ,
5958
5976
payment_secret,
5959
5977
pending_amt_msat : path_amt,
5978
+ pending_fee_msat : path_fee,
5960
5979
total_msat : path_amt,
5961
5980
starting_block_height : best_block_height,
5962
5981
} ) ;
@@ -6256,7 +6275,7 @@ mod tests {
6256
6275
// further events will be generated for subsequence path successes.
6257
6276
let events = nodes[ 0 ] . node . get_and_clear_pending_events ( ) ;
6258
6277
match events[ 0 ] {
6259
- Event :: PaymentSent { payment_preimage : ref preimage, payment_hash : ref hash } => {
6278
+ Event :: PaymentSent { payment_preimage : ref preimage, payment_hash : ref hash, .. } => {
6260
6279
assert_eq ! ( payment_preimage, * preimage) ;
6261
6280
assert_eq ! ( our_payment_hash, * hash) ;
6262
6281
} ,
0 commit comments