@@ -162,19 +162,43 @@ enum OutboundHTLCState {
162
162
Committed ,
163
163
/// Remote removed this (outbound) HTLC. We're waiting on their commitment_signed to finalize
164
164
/// the change (though they'll need to revoke before we fail the payment).
165
- RemoteRemoved ( Option < HTLCFailReason > ) ,
165
+ RemoteRemoved ( OutboundHTLCOutcome ) ,
166
166
/// Remote removed this and sent a commitment_signed (implying we've revoke_and_ack'ed it), but
167
167
/// the remote side hasn't yet revoked their previous state, which we need them to do before we
168
168
/// can do any backwards failing. Implies AwaitingRemoteRevoke.
169
169
/// We also have not yet removed this HTLC in a commitment_signed message, and are waiting on a
170
170
/// remote revoke_and_ack on a previous state before we can do so.
171
- AwaitingRemoteRevokeToRemove ( Option < HTLCFailReason > ) ,
171
+ AwaitingRemoteRevokeToRemove ( OutboundHTLCOutcome ) ,
172
172
/// Remote removed this and sent a commitment_signed (implying we've revoke_and_ack'ed it), but
173
173
/// the remote side hasn't yet revoked their previous state, which we need them to do before we
174
174
/// can do any backwards failing. Implies AwaitingRemoteRevoke.
175
175
/// We have removed this HTLC in our latest commitment_signed and are now just waiting on a
176
176
/// revoke_and_ack to drop completely.
177
- AwaitingRemovedRemoteRevoke ( Option < HTLCFailReason > ) ,
177
+ AwaitingRemovedRemoteRevoke ( OutboundHTLCOutcome ) ,
178
+ }
179
+
180
+ #[ derive( Clone ) ]
181
+ enum OutboundHTLCOutcome {
182
+ Success ( Option < PaymentPreimage > ) ,
183
+ Failure ( HTLCFailReason ) ,
184
+ }
185
+
186
+ impl From < Option < HTLCFailReason > > for OutboundHTLCOutcome {
187
+ fn from ( o : Option < HTLCFailReason > ) -> Self {
188
+ match o {
189
+ None => Self :: Success ( None ) ,
190
+ Some ( r) => Self :: Failure ( r)
191
+ }
192
+ }
193
+ }
194
+
195
+ impl Into < Option < HTLCFailReason > > for OutboundHTLCOutcome {
196
+ fn into ( self ) -> Option < HTLCFailReason > {
197
+ match self {
198
+ OutboundHTLCOutcome :: Success ( _) => None ,
199
+ OutboundHTLCOutcome :: Failure ( r) => Some ( r. clone ( ) )
200
+ }
201
+ }
178
202
}
179
203
180
204
struct OutboundHTLCOutput {
@@ -1289,10 +1313,10 @@ impl<Signer: Sign> Channel<Signer> {
1289
1313
} else {
1290
1314
log_trace ! ( logger, " ...not including outbound HTLC {} (hash {}) with value {} due to state ({})" , htlc. htlc_id, log_bytes!( htlc. payment_hash. 0 ) , htlc. amount_msat, state_name) ;
1291
1315
match htlc. state {
1292
- OutboundHTLCState :: AwaitingRemoteRevokeToRemove ( None ) |OutboundHTLCState :: AwaitingRemovedRemoteRevoke ( None ) => {
1316
+ OutboundHTLCState :: AwaitingRemoteRevokeToRemove ( OutboundHTLCOutcome :: Success ( _ ) ) |OutboundHTLCState :: AwaitingRemovedRemoteRevoke ( OutboundHTLCOutcome :: Success ( _ ) ) => {
1293
1317
value_to_self_msat_offset -= htlc. amount_msat as i64 ;
1294
1318
} ,
1295
- OutboundHTLCState :: RemoteRemoved ( None ) => {
1319
+ OutboundHTLCState :: RemoteRemoved ( OutboundHTLCOutcome :: Success ( _ ) ) => {
1296
1320
if !generated_by_local {
1297
1321
value_to_self_msat_offset -= htlc. amount_msat as i64 ;
1298
1322
}
@@ -2393,9 +2417,9 @@ impl<Signer: Sign> Channel<Signer> {
2393
2417
// transaction).
2394
2418
let mut removed_outbound_total_msat = 0 ;
2395
2419
for ref htlc in self . pending_outbound_htlcs . iter ( ) {
2396
- if let OutboundHTLCState :: AwaitingRemoteRevokeToRemove ( None ) = htlc. state {
2420
+ if let OutboundHTLCState :: AwaitingRemoteRevokeToRemove ( OutboundHTLCOutcome :: Success ( _ ) ) = htlc. state {
2397
2421
removed_outbound_total_msat += htlc. amount_msat ;
2398
- } else if let OutboundHTLCState :: AwaitingRemovedRemoteRevoke ( None ) = htlc. state {
2422
+ } else if let OutboundHTLCState :: AwaitingRemovedRemoteRevoke ( OutboundHTLCOutcome :: Success ( _ ) ) = htlc. state {
2399
2423
removed_outbound_total_msat += htlc. amount_msat ;
2400
2424
}
2401
2425
}
@@ -2494,21 +2518,25 @@ impl<Signer: Sign> Channel<Signer> {
2494
2518
2495
2519
/// Marks an outbound HTLC which we have received update_fail/fulfill/malformed
2496
2520
#[ inline]
2497
- fn mark_outbound_htlc_removed ( & mut self , htlc_id : u64 , check_preimage : Option < PaymentHash > , fail_reason : Option < HTLCFailReason > ) -> Result < & OutboundHTLCOutput , ChannelError > {
2521
+ fn mark_outbound_htlc_removed ( & mut self , htlc_id : u64 , check_preimage : Option < PaymentPreimage > , fail_reason : Option < HTLCFailReason > ) -> Result < & OutboundHTLCOutput , ChannelError > {
2522
+ assert ! ( !( check_preimage. is_some( ) && fail_reason. is_some( ) ) , "cannot fail while we have a preimage" ) ;
2498
2523
for htlc in self . pending_outbound_htlcs . iter_mut ( ) {
2499
2524
if htlc. htlc_id == htlc_id {
2500
- match check_preimage {
2501
- None => { } ,
2502
- Some ( payment_hash) =>
2525
+ let outcome = match check_preimage {
2526
+ None => fail_reason. into ( ) ,
2527
+ Some ( payment_preimage) => {
2528
+ let payment_hash = PaymentHash ( Sha256 :: hash ( & payment_preimage. 0 [ ..] ) . into_inner ( ) ) ;
2503
2529
if payment_hash != htlc. payment_hash {
2504
2530
return Err ( ChannelError :: Close ( format ! ( "Remote tried to fulfill HTLC ({}) with an incorrect preimage" , htlc_id) ) ) ;
2505
2531
}
2532
+ OutboundHTLCOutcome :: Success ( Some ( payment_preimage) )
2533
+ }
2506
2534
} ;
2507
2535
match htlc. state {
2508
2536
OutboundHTLCState :: LocalAnnounced ( _) =>
2509
2537
return Err ( ChannelError :: Close ( format ! ( "Remote tried to fulfill/fail HTLC ({}) before it had been committed" , htlc_id) ) ) ,
2510
2538
OutboundHTLCState :: Committed => {
2511
- htlc. state = OutboundHTLCState :: RemoteRemoved ( fail_reason ) ;
2539
+ htlc. state = OutboundHTLCState :: RemoteRemoved ( outcome ) ;
2512
2540
} ,
2513
2541
OutboundHTLCState :: AwaitingRemoteRevokeToRemove ( _) | OutboundHTLCState :: AwaitingRemovedRemoteRevoke ( _) | OutboundHTLCState :: RemoteRemoved ( _) =>
2514
2542
return Err ( ChannelError :: Close ( format ! ( "Remote tried to fulfill/fail HTLC ({}) that they'd already fulfilled/failed" , htlc_id) ) ) ,
@@ -2527,8 +2555,7 @@ impl<Signer: Sign> Channel<Signer> {
2527
2555
return Err ( ChannelError :: Close ( "Peer sent update_fulfill_htlc when we needed a channel_reestablish" . to_owned ( ) ) ) ;
2528
2556
}
2529
2557
2530
- let payment_hash = PaymentHash ( Sha256 :: hash ( & msg. payment_preimage . 0 [ ..] ) . into_inner ( ) ) ;
2531
- self . mark_outbound_htlc_removed ( msg. htlc_id , Some ( payment_hash) , None ) . map ( |htlc| ( htlc. source . clone ( ) , htlc. amount_msat ) )
2558
+ self . mark_outbound_htlc_removed ( msg. htlc_id , Some ( msg. payment_preimage ) , None ) . map ( |htlc| ( htlc. source . clone ( ) , htlc. amount_msat ) )
2532
2559
}
2533
2560
2534
2561
pub fn update_fail_htlc ( & mut self , msg : & msgs:: UpdateFailHTLC , fail_reason : HTLCFailReason ) -> Result < ( ) , ChannelError > {
@@ -2689,12 +2716,10 @@ impl<Signer: Sign> Channel<Signer> {
2689
2716
}
2690
2717
}
2691
2718
for htlc in self . pending_outbound_htlcs . iter_mut ( ) {
2692
- if let Some ( fail_reason) = if let & mut OutboundHTLCState :: RemoteRemoved ( ref mut fail_reason) = & mut htlc. state {
2693
- Some ( fail_reason. take ( ) )
2694
- } else { None } {
2719
+ if let & OutboundHTLCState :: RemoteRemoved ( ref fail_reason) = & htlc. state {
2695
2720
log_trace ! ( logger, "Updating HTLC {} to AwaitingRemoteRevokeToRemove due to commitment_signed in channel {}." ,
2696
2721
log_bytes!( htlc. payment_hash. 0 ) , log_bytes!( self . channel_id) ) ;
2697
- htlc. state = OutboundHTLCState :: AwaitingRemoteRevokeToRemove ( fail_reason) ;
2722
+ htlc. state = OutboundHTLCState :: AwaitingRemoteRevokeToRemove ( fail_reason. clone ( ) . into ( ) ) ;
2698
2723
need_commitment = true ;
2699
2724
}
2700
2725
}
@@ -2965,7 +2990,7 @@ impl<Signer: Sign> Channel<Signer> {
2965
2990
pending_outbound_htlcs. retain ( |htlc| {
2966
2991
if let & OutboundHTLCState :: AwaitingRemovedRemoteRevoke ( ref fail_reason) = & htlc. state {
2967
2992
log_trace ! ( logger, " ...removing outbound AwaitingRemovedRemoteRevoke {}" , log_bytes!( htlc. payment_hash. 0 ) ) ;
2968
- if let Some ( reason) = fail_reason. clone ( ) { // We really want take() here, but, again, non-mut ref :(
2993
+ if let OutboundHTLCOutcome :: Failure ( reason) = fail_reason. clone ( ) { // We really want take() here, but, again, non-mut ref :(
2969
2994
revoked_htlcs. push ( ( htlc. source . clone ( ) , htlc. payment_hash , reason) ) ;
2970
2995
} else {
2971
2996
finalized_claimed_htlcs. push ( htlc. source . clone ( ) ) ;
@@ -3019,11 +3044,9 @@ impl<Signer: Sign> Channel<Signer> {
3019
3044
log_trace ! ( logger, " ...promoting outbound LocalAnnounced {} to Committed" , log_bytes!( htlc. payment_hash. 0 ) ) ;
3020
3045
htlc. state = OutboundHTLCState :: Committed ;
3021
3046
}
3022
- if let Some ( fail_reason) = if let & mut OutboundHTLCState :: AwaitingRemoteRevokeToRemove ( ref mut fail_reason) = & mut htlc. state {
3023
- Some ( fail_reason. take ( ) )
3024
- } else { None } {
3047
+ if let & OutboundHTLCState :: AwaitingRemoteRevokeToRemove ( ref fail_reason) = & htlc. state {
3025
3048
log_trace ! ( logger, " ...promoting outbound AwaitingRemoteRevokeToRemove {} to AwaitingRemovedRemoteRevoke" , log_bytes!( htlc. payment_hash. 0 ) ) ;
3026
- htlc. state = OutboundHTLCState :: AwaitingRemovedRemoteRevoke ( fail_reason) ;
3049
+ htlc. state = OutboundHTLCState :: AwaitingRemovedRemoteRevoke ( fail_reason. clone ( ) . into ( ) ) ;
3027
3050
require_commitment = true ;
3028
3051
}
3029
3052
}
@@ -4891,11 +4914,9 @@ impl<Signer: Sign> Channel<Signer> {
4891
4914
}
4892
4915
}
4893
4916
for htlc in self . pending_outbound_htlcs . iter_mut ( ) {
4894
- if let Some ( fail_reason) = if let & mut OutboundHTLCState :: AwaitingRemoteRevokeToRemove ( ref mut fail_reason) = & mut htlc. state {
4895
- Some ( fail_reason. take ( ) )
4896
- } else { None } {
4917
+ if let & OutboundHTLCState :: AwaitingRemoteRevokeToRemove ( ref fail_reason) = & htlc. state {
4897
4918
log_trace ! ( logger, " ...promoting outbound AwaitingRemoteRevokeToRemove {} to AwaitingRemovedRemoteRevoke" , log_bytes!( htlc. payment_hash. 0 ) ) ;
4898
- htlc. state = OutboundHTLCState :: AwaitingRemovedRemoteRevoke ( fail_reason) ;
4919
+ htlc. state = OutboundHTLCState :: AwaitingRemovedRemoteRevoke ( fail_reason. clone ( ) . into ( ) ) ;
4899
4920
}
4900
4921
}
4901
4922
if let Some ( ( feerate, update_state) ) = self . pending_update_fee {
@@ -5253,6 +5274,8 @@ impl<Signer: Sign> Writeable for Channel<Signer> {
5253
5274
}
5254
5275
}
5255
5276
5277
+ let mut preimages: Vec < & Option < PaymentPreimage > > = vec ! [ ] ;
5278
+
5256
5279
( self . pending_outbound_htlcs . len ( ) as u64 ) . write ( writer) ?;
5257
5280
for htlc in self . pending_outbound_htlcs . iter ( ) {
5258
5281
htlc. htlc_id . write ( writer) ?;
@@ -5273,14 +5296,22 @@ impl<Signer: Sign> Writeable for Channel<Signer> {
5273
5296
// resend the claim/fail on reconnect as we all (hopefully) the missing CS.
5274
5297
1u8 . write ( writer) ?;
5275
5298
} ,
5276
- & OutboundHTLCState :: AwaitingRemoteRevokeToRemove ( ref fail_reason ) => {
5299
+ & OutboundHTLCState :: AwaitingRemoteRevokeToRemove ( ref outcome ) => {
5277
5300
3u8 . write ( writer) ?;
5278
- fail_reason. write ( writer) ?;
5279
- } ,
5280
- & OutboundHTLCState :: AwaitingRemovedRemoteRevoke ( ref fail_reason) => {
5301
+ if let OutboundHTLCOutcome :: Success ( preimage) = outcome {
5302
+ preimages. push ( preimage) ;
5303
+ }
5304
+ let reason: Option < HTLCFailReason > = outcome. clone ( ) . into ( ) ;
5305
+ reason. write ( writer) ?;
5306
+ }
5307
+ & OutboundHTLCState :: AwaitingRemovedRemoteRevoke ( ref outcome) => {
5281
5308
4u8 . write ( writer) ?;
5282
- fail_reason. write ( writer) ?;
5283
- } ,
5309
+ if let OutboundHTLCOutcome :: Success ( preimage) = outcome {
5310
+ preimages. push ( preimage) ;
5311
+ }
5312
+ let reason: Option < HTLCFailReason > = outcome. clone ( ) . into ( ) ;
5313
+ reason. write ( writer) ?;
5314
+ }
5284
5315
}
5285
5316
}
5286
5317
@@ -5434,6 +5465,7 @@ impl<Signer: Sign> Writeable for Channel<Signer> {
5434
5465
( 9 , self . target_closing_feerate_sats_per_kw, option) ,
5435
5466
( 11 , self . monitor_pending_finalized_fulfills, vec_type) ,
5436
5467
( 13 , self . channel_creation_height, required) ,
5468
+ ( 15 , preimages, vec_type) ,
5437
5469
} ) ;
5438
5470
5439
5471
Ok ( ( ) )
@@ -5519,9 +5551,18 @@ impl<'a, Signer: Sign, K: Deref> ReadableArgs<(&'a K, u32)> for Channel<Signer>
5519
5551
state : match <u8 as Readable >:: read ( reader) ? {
5520
5552
0 => OutboundHTLCState :: LocalAnnounced ( Box :: new ( Readable :: read ( reader) ?) ) ,
5521
5553
1 => OutboundHTLCState :: Committed ,
5522
- 2 => OutboundHTLCState :: RemoteRemoved ( Readable :: read ( reader) ?) ,
5523
- 3 => OutboundHTLCState :: AwaitingRemoteRevokeToRemove ( Readable :: read ( reader) ?) ,
5524
- 4 => OutboundHTLCState :: AwaitingRemovedRemoteRevoke ( Readable :: read ( reader) ?) ,
5554
+ 2 => {
5555
+ let option: Option < HTLCFailReason > = Readable :: read ( reader) ?;
5556
+ OutboundHTLCState :: RemoteRemoved ( option. into ( ) )
5557
+ } ,
5558
+ 3 => {
5559
+ let option: Option < HTLCFailReason > = Readable :: read ( reader) ?;
5560
+ OutboundHTLCState :: AwaitingRemoteRevokeToRemove ( option. into ( ) )
5561
+ } ,
5562
+ 4 => {
5563
+ let option: Option < HTLCFailReason > = Readable :: read ( reader) ?;
5564
+ OutboundHTLCState :: AwaitingRemovedRemoteRevoke ( option. into ( ) )
5565
+ } ,
5525
5566
_ => return Err ( DecodeError :: InvalidValue ) ,
5526
5567
} ,
5527
5568
} ) ;
@@ -5675,6 +5716,8 @@ impl<'a, Signer: Sign, K: Deref> ReadableArgs<(&'a K, u32)> for Channel<Signer>
5675
5716
// only, so we default to that if none was written.
5676
5717
let mut channel_type = Some ( ChannelTypeFeatures :: only_static_remote_key ( ) ) ;
5677
5718
let mut channel_creation_height = Some ( serialized_height) ;
5719
+ let mut preimages_opt: Option < Vec < Option < PaymentPreimage > > > = None ;
5720
+
5678
5721
read_tlv_fields ! ( reader, {
5679
5722
( 0 , announcement_sigs, option) ,
5680
5723
( 1 , minimum_depth, option) ,
@@ -5687,8 +5730,25 @@ impl<'a, Signer: Sign, K: Deref> ReadableArgs<(&'a K, u32)> for Channel<Signer>
5687
5730
( 9 , target_closing_feerate_sats_per_kw, option) ,
5688
5731
( 11 , monitor_pending_finalized_fulfills, vec_type) ,
5689
5732
( 13 , channel_creation_height, option) ,
5733
+ ( 15 , preimages_opt, vec_type) ,
5690
5734
} ) ;
5691
5735
5736
+ if let Some ( preimages) = preimages_opt {
5737
+ let mut iter = preimages. into_iter ( ) ;
5738
+ for htlc in pending_outbound_htlcs. iter_mut ( ) {
5739
+ match & htlc. state {
5740
+ OutboundHTLCState :: AwaitingRemoteRevokeToRemove ( OutboundHTLCOutcome :: Success ( None ) ) => {
5741
+ htlc. state = OutboundHTLCState :: AwaitingRemoteRevokeToRemove ( OutboundHTLCOutcome :: Success ( iter. next ( ) . expect ( "not enough preimages" ) ) ) ;
5742
+ }
5743
+ OutboundHTLCState :: AwaitingRemovedRemoteRevoke ( OutboundHTLCOutcome :: Success ( None ) ) => {
5744
+ htlc. state = OutboundHTLCState :: AwaitingRemovedRemoteRevoke ( OutboundHTLCOutcome :: Success ( iter. next ( ) . expect ( "not enough preimages" ) ) ) ;
5745
+ }
5746
+ _ => { }
5747
+ }
5748
+ }
5749
+ assert ! ( iter. next( ) . is_none( ) , "too many preimages" ) ;
5750
+ }
5751
+
5692
5752
let chan_features = channel_type. as_ref ( ) . unwrap ( ) ;
5693
5753
if chan_features. supports_unknown_bits ( ) || chan_features. requires_unknown_bits ( ) {
5694
5754
// If the channel was written by a new version and negotiated with features we don't
0 commit comments