@@ -400,6 +400,48 @@ struct PendingInboundPayment {
400
400
min_value_msat : Option < u64 > ,
401
401
}
402
402
403
+ /// XXX
404
+ enum PendingOutboundPayment {
405
+ Legacy {
406
+ session_privs : HashSet < [ u8 ; 32 ] > ,
407
+ } ,
408
+ Retryable {
409
+ session_privs : HashSet < [ u8 ; 32 ] > ,
410
+ payment_hash : PaymentHash ,
411
+ total_msat : u64 ,
412
+ // XXX add payment_secret
413
+ } ,
414
+ }
415
+
416
+ impl PendingOutboundPayment {
417
+ fn remove ( & mut self , session_priv : & [ u8 ; 32 ] ) -> bool {
418
+ match self {
419
+ PendingOutboundPayment :: Legacy { session_privs } |
420
+ PendingOutboundPayment :: Retryable { session_privs, .. } => {
421
+ session_privs. remove ( session_priv)
422
+ }
423
+ }
424
+ }
425
+
426
+ fn insert ( & mut self , session_priv : [ u8 ; 32 ] ) -> bool {
427
+ match self {
428
+ PendingOutboundPayment :: Legacy { session_privs } |
429
+ PendingOutboundPayment :: Retryable { session_privs, .. } => {
430
+ session_privs. insert ( session_priv)
431
+ }
432
+ }
433
+ }
434
+
435
+ fn num_parts ( & self ) -> usize {
436
+ match self {
437
+ PendingOutboundPayment :: Legacy { session_privs } |
438
+ PendingOutboundPayment :: Retryable { session_privs, .. } => {
439
+ session_privs. len ( )
440
+ }
441
+ }
442
+ }
443
+ }
444
+
403
445
/// SimpleArcChannelManager is useful when you need a ChannelManager with a static lifetime, e.g.
404
446
/// when you're using lightning-net-tokio (since tokio::spawn requires parameters with static
405
447
/// lifetimes). Other times you can afford a reference, which is more efficient, in which case
@@ -486,6 +528,8 @@ pub struct ChannelManager<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref,
486
528
/// Locked *after* channel_state.
487
529
pending_inbound_payments : Mutex < HashMap < PaymentHash , PendingInboundPayment > > ,
488
530
531
+ /// XXX update these
532
+ ///
489
533
/// The session_priv bytes of outbound payments which are pending resolution.
490
534
/// The authoritative state of these HTLCs resides either within Channels or ChannelMonitors
491
535
/// (if the channel has been force-closed), however we track them here to prevent duplicative
@@ -499,7 +543,7 @@ pub struct ChannelManager<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref,
499
543
/// payments over a single path).
500
544
///
501
545
/// Locked *after* channel_state.
502
- pending_outbound_payments : Mutex < HashMap < PaymentId , HashSet < [ u8 ; 32 ] > > > ,
546
+ pending_outbound_payments : Mutex < HashMap < PaymentId , PendingOutboundPayment > > ,
503
547
504
548
our_network_key : SecretKey ,
505
549
our_network_pubkey : PublicKey ,
@@ -1894,8 +1938,12 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
1894
1938
1895
1939
let _persistence_guard = PersistenceNotifierGuard :: notify_on_drop ( & self . total_consistency_lock , & self . persistence_notifier ) ;
1896
1940
let mut pending_outbounds = self . pending_outbound_payments . lock ( ) . unwrap ( ) ;
1897
- let sessions = pending_outbounds. entry ( payment_id) . or_insert ( HashSet :: new ( ) ) ;
1898
- assert ! ( sessions. insert( session_priv_bytes) ) ;
1941
+ let payment = pending_outbounds. entry ( payment_id) . or_insert ( PendingOutboundPayment :: Retryable {
1942
+ session_privs : HashSet :: new ( ) ,
1943
+ payment_hash : * payment_hash,
1944
+ total_msat : total_value,
1945
+ } ) ;
1946
+ payment. insert ( session_priv_bytes) ;
1899
1947
1900
1948
let err: Result < ( ) , _ > = loop {
1901
1949
let mut channel_lock = self . channel_state . lock ( ) . unwrap ( ) ;
@@ -2883,23 +2931,23 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
2883
2931
let mut session_priv_bytes = [ 0 ; 32 ] ;
2884
2932
session_priv_bytes. copy_from_slice ( & session_priv[ ..] ) ;
2885
2933
let mut outbounds = self . pending_outbound_payments . lock ( ) . unwrap ( ) ;
2886
- if let hash_map:: Entry :: Occupied ( mut sessions ) = outbounds. entry ( payment_id) {
2887
- if sessions . get_mut ( ) . remove ( & session_priv_bytes) {
2934
+ if let hash_map:: Entry :: Occupied ( mut payment ) = outbounds. entry ( payment_id) {
2935
+ if payment . get_mut ( ) . remove ( & session_priv_bytes) {
2888
2936
self . pending_events . lock ( ) . unwrap ( ) . push (
2889
2937
events:: Event :: PaymentPathFailed {
2890
2938
payment_hash,
2891
2939
rejected_by_dest : false ,
2892
2940
network_update : None ,
2893
- all_paths_failed : sessions . get ( ) . len ( ) == 0 ,
2941
+ all_paths_failed : payment . get ( ) . num_parts ( ) == 0 ,
2894
2942
path : path. clone ( ) ,
2895
2943
#[ cfg( test) ]
2896
2944
error_code : None ,
2897
2945
#[ cfg( test) ]
2898
2946
error_data : None ,
2899
2947
}
2900
2948
) ;
2901
- if sessions . get ( ) . len ( ) == 0 {
2902
- sessions . remove ( ) ;
2949
+ if payment . get ( ) . num_parts ( ) == 0 {
2950
+ payment . remove ( ) ;
2903
2951
}
2904
2952
}
2905
2953
} else {
@@ -2936,7 +2984,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
2936
2984
log_trace ! ( self . logger, "Received duplicative fail for HTLC with payment_hash {}" , log_bytes!( payment_hash. 0 ) ) ;
2937
2985
return ;
2938
2986
}
2939
- if sessions. get ( ) . len ( ) == 0 {
2987
+ if sessions. get ( ) . num_parts ( ) == 0 {
2940
2988
all_paths_failed = true ;
2941
2989
sessions. remove ( ) ;
2942
2990
}
@@ -5161,6 +5209,17 @@ impl_writeable_tlv_based!(PendingInboundPayment, {
5161
5209
( 8 , min_value_msat, required) ,
5162
5210
} ) ;
5163
5211
5212
+ impl_writeable_tlv_based_enum ! ( PendingOutboundPayment ,
5213
+ ( 0 , Legacy ) => {
5214
+ ( 0 , session_privs, required) ,
5215
+ } ,
5216
+ ( 2 , Retryable ) => {
5217
+ ( 0 , session_privs, required) ,
5218
+ ( 2 , payment_hash, required) ,
5219
+ ( 4 , total_msat, required) ,
5220
+ } ,
5221
+ ; ) ;
5222
+
5164
5223
impl < Signer : Sign , M : Deref , T : Deref , K : Deref , F : Deref , L : Deref > Writeable for ChannelManager < Signer , M , T , K , F , L >
5165
5224
where M :: Target : chain:: Watch < Signer > ,
5166
5225
T :: Target : BroadcasterInterface ,
@@ -5251,18 +5310,30 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> Writeable f
5251
5310
let pending_outbound_payments = self . pending_outbound_payments . lock ( ) . unwrap ( ) ;
5252
5311
// For backwards compat, write the session privs and their total length.
5253
5312
let mut num_pending_outbounds_compat: u64 = 0 ;
5254
- for ( _, outbounds) in pending_outbound_payments. iter ( ) {
5255
- num_pending_outbounds_compat += outbounds. len ( ) as u64 ;
5313
+ for ( _, outbound) in pending_outbound_payments. iter ( ) {
5314
+ match outbound {
5315
+ PendingOutboundPayment :: Legacy { session_privs } |
5316
+ PendingOutboundPayment :: Retryable { session_privs, .. } => {
5317
+ num_pending_outbounds_compat += session_privs. len ( ) as u64 ;
5318
+ }
5319
+ }
5256
5320
}
5257
5321
num_pending_outbounds_compat. write ( writer) ?;
5258
- for ( _, outbounds) in pending_outbound_payments. iter ( ) {
5259
- for outbound in outbounds. iter ( ) {
5260
- outbound. write ( writer) ?;
5322
+ for ( _, outbound) in pending_outbound_payments. iter ( ) {
5323
+ match outbound {
5324
+ PendingOutboundPayment :: Legacy { session_privs } |
5325
+ PendingOutboundPayment :: Retryable { session_privs, .. } => {
5326
+ for session_priv in session_privs. iter ( ) {
5327
+ session_priv. write ( writer) ?;
5328
+ }
5329
+ }
5261
5330
}
5262
5331
}
5263
5332
5333
+ let pending_outbound_payments_compat_2: HashMap < PaymentId , HashSet < [ u8 ; 32 ] > > = HashMap :: new ( ) ;
5264
5334
write_tlv_fields ! ( writer, {
5265
- ( 1 , pending_outbound_payments, required) ,
5335
+ ( 1 , pending_outbound_payments_compat_2, required) ,
5336
+ ( 3 , pending_outbound_payments, required) ,
5266
5337
} ) ;
5267
5338
5268
5339
Ok ( ( ) )
@@ -5522,21 +5593,32 @@ impl<'a, Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>
5522
5593
}
5523
5594
5524
5595
let pending_outbound_payments_count_compat: u64 = Readable :: read ( reader) ?;
5525
- let mut pending_outbound_payments_compat: HashMap < PaymentId , HashSet < [ u8 ; 32 ] > > =
5596
+ let mut pending_outbound_payments_compat: HashMap < PaymentId , PendingOutboundPayment > =
5526
5597
HashMap :: with_capacity ( cmp:: min ( pending_outbound_payments_count_compat as usize , MAX_ALLOC_SIZE /32 ) ) ;
5527
5598
for _ in 0 ..pending_outbound_payments_count_compat {
5528
5599
let session_priv = Readable :: read ( reader) ?;
5529
- if pending_outbound_payments_compat. insert ( PaymentId ( session_priv) , [ session_priv] . iter ( ) . cloned ( ) . collect ( ) ) . is_some ( ) {
5600
+ let payment = PendingOutboundPayment :: Legacy {
5601
+ session_privs : [ session_priv] . iter ( ) . cloned ( ) . collect ( )
5602
+ } ;
5603
+ if pending_outbound_payments_compat. insert ( PaymentId ( session_priv) , payment) . is_some ( ) {
5530
5604
return Err ( DecodeError :: InvalidValue )
5531
5605
} ;
5532
5606
}
5533
5607
5608
+ let mut pending_outbound_payments_compat_2: Option < HashMap < PaymentId , HashSet < [ u8 ; 32 ] > > > = None ;
5534
5609
let mut pending_outbound_payments = None ;
5535
5610
read_tlv_fields ! ( reader, {
5536
- ( 1 , pending_outbound_payments, option) ,
5611
+ ( 1 , pending_outbound_payments_compat_2, option) ,
5612
+ ( 3 , pending_outbound_payments, option) ,
5537
5613
} ) ;
5538
- if pending_outbound_payments. is_none ( ) {
5614
+ if pending_outbound_payments. is_none ( ) && pending_outbound_payments_compat_2 . is_none ( ) {
5539
5615
pending_outbound_payments = Some ( pending_outbound_payments_compat) ;
5616
+ } else if pending_outbound_payments. is_none ( ) {
5617
+ let mut outbounds = HashMap :: new ( ) ;
5618
+ for ( id, session_privs) in pending_outbound_payments_compat_2. unwrap ( ) . drain ( ) {
5619
+ outbounds. insert ( id, PendingOutboundPayment :: Legacy { session_privs } ) ;
5620
+ }
5621
+ pending_outbound_payments = Some ( outbounds) ;
5540
5622
}
5541
5623
5542
5624
let mut secp_ctx = Secp256k1 :: new ( ) ;
0 commit comments