@@ -367,7 +367,7 @@ impl OutboundHTLCState {
367
367
OutboundHTLCState::RemoteRemoved(OutboundHTLCOutcome::Success(preimage))
368
368
| OutboundHTLCState::AwaitingRemoteRevokeToRemove(OutboundHTLCOutcome::Success(preimage))
369
369
| OutboundHTLCState::AwaitingRemovedRemoteRevoke(OutboundHTLCOutcome::Success(preimage)) => {
370
- preimage.as_ref().copied( )
370
+ Some(*preimage )
371
371
},
372
372
_ => None,
373
373
}
@@ -377,20 +377,12 @@ impl OutboundHTLCState {
377
377
#[derive(Clone)]
378
378
#[cfg_attr(test, derive(Debug, PartialEq))]
379
379
enum OutboundHTLCOutcome {
380
- /// LDK version 0.0.105+ will always fill in the preimage here.
381
- Success(Option<PaymentPreimage>),
380
+ /// We started always filling in the preimages here in 0.0.105, and the requirement
381
+ /// that the preimages always be filled in was added in 0.2.
382
+ Success(PaymentPreimage),
382
383
Failure(HTLCFailReason),
383
384
}
384
385
385
- impl From<Option<HTLCFailReason>> for OutboundHTLCOutcome {
386
- fn from(o: Option<HTLCFailReason>) -> Self {
387
- match o {
388
- None => OutboundHTLCOutcome::Success(None),
389
- Some(r) => OutboundHTLCOutcome::Failure(r)
390
- }
391
- }
392
- }
393
-
394
386
impl<'a> Into<Option<&'a HTLCFailReason>> for &'a OutboundHTLCOutcome {
395
387
fn into(self) -> Option<&'a HTLCFailReason> {
396
388
match self {
@@ -3878,7 +3870,7 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
3878
3870
}
3879
3871
remote_htlc_total_msat += htlc.amount_msat;
3880
3872
} else {
3881
- if let InboundHTLCState::LocalRemoved(InboundHTLCRemovalReason::Fulfill(_preimage)) = htlc.state {
3873
+ if htlc.state.preimage().is_some() {
3882
3874
value_to_self_msat_offset += htlc.amount_msat as i64;
3883
3875
}
3884
3876
}
@@ -3891,10 +3883,7 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
3891
3883
}
3892
3884
local_htlc_total_msat += htlc.amount_msat;
3893
3885
} else {
3894
- if let OutboundHTLCState::AwaitingRemoteRevokeToRemove(OutboundHTLCOutcome::Success(_)) |
3895
- OutboundHTLCState::AwaitingRemovedRemoteRevoke(OutboundHTLCOutcome::Success(_)) |
3896
- OutboundHTLCState::RemoteRemoved(OutboundHTLCOutcome::Success(_))
3897
- = htlc.state {
3886
+ if htlc.state.preimage().is_some() {
3898
3887
value_to_self_msat_offset -= htlc.amount_msat as i64;
3899
3888
}
3900
3889
}
@@ -5801,20 +5790,15 @@ impl<SP: Deref> FundedChannel<SP> where
5801
5790
5802
5791
/// Marks an outbound HTLC which we have received update_fail/fulfill/malformed
5803
5792
#[inline]
5804
- fn mark_outbound_htlc_removed(&mut self, htlc_id: u64, check_preimage: Option<PaymentPreimage>, fail_reason: Option<HTLCFailReason>) -> Result<&OutboundHTLCOutput, ChannelError> {
5805
- assert!(!(check_preimage.is_some() && fail_reason.is_some()), "cannot fail while we have a preimage");
5793
+ fn mark_outbound_htlc_removed(&mut self, htlc_id: u64, outcome: OutboundHTLCOutcome) -> Result<&OutboundHTLCOutput, ChannelError> {
5806
5794
for htlc in self.context.pending_outbound_htlcs.iter_mut() {
5807
5795
if htlc.htlc_id == htlc_id {
5808
- let outcome = match check_preimage {
5809
- None => fail_reason.into(),
5810
- Some(payment_preimage) => {
5811
- let payment_hash = PaymentHash(Sha256::hash(&payment_preimage.0[..]).to_byte_array());
5812
- if payment_hash != htlc.payment_hash {
5813
- return Err(ChannelError::close(format!("Remote tried to fulfill HTLC ({}) with an incorrect preimage", htlc_id)));
5814
- }
5815
- OutboundHTLCOutcome::Success(Some(payment_preimage))
5796
+ if let OutboundHTLCOutcome::Success(ref payment_preimage) = outcome {
5797
+ let payment_hash = PaymentHash(Sha256::hash(&payment_preimage.0[..]).to_byte_array());
5798
+ if payment_hash != htlc.payment_hash {
5799
+ return Err(ChannelError::close(format!("Remote tried to fulfill HTLC ({}) with an incorrect preimage", htlc_id)));
5816
5800
}
5817
- };
5801
+ }
5818
5802
match htlc.state {
5819
5803
OutboundHTLCState::LocalAnnounced(_) =>
5820
5804
return Err(ChannelError::close(format!("Remote tried to fulfill/fail HTLC ({}) before it had been committed", htlc_id))),
@@ -5841,7 +5825,7 @@ impl<SP: Deref> FundedChannel<SP> where
5841
5825
return Err(ChannelError::close("Peer sent update_fulfill_htlc when we needed a channel_reestablish".to_owned()));
5842
5826
}
5843
5827
5844
- self.mark_outbound_htlc_removed(msg.htlc_id, Some (msg.payment_preimage), None ).map(|htlc| (htlc.source.clone(), htlc.amount_msat, htlc.skimmed_fee_msat))
5828
+ self.mark_outbound_htlc_removed(msg.htlc_id, OutboundHTLCOutcome::Success (msg.payment_preimage)).map(|htlc| (htlc.source.clone(), htlc.amount_msat, htlc.skimmed_fee_msat))
5845
5829
}
5846
5830
5847
5831
pub fn update_fail_htlc(&mut self, msg: &msgs::UpdateFailHTLC, fail_reason: HTLCFailReason) -> Result<(), ChannelError> {
@@ -5855,7 +5839,7 @@ impl<SP: Deref> FundedChannel<SP> where
5855
5839
return Err(ChannelError::close("Peer sent update_fail_htlc when we needed a channel_reestablish".to_owned()));
5856
5840
}
5857
5841
5858
- self.mark_outbound_htlc_removed(msg.htlc_id, None, Some (fail_reason))?;
5842
+ self.mark_outbound_htlc_removed(msg.htlc_id, OutboundHTLCOutcome::Failure (fail_reason))?;
5859
5843
Ok(())
5860
5844
}
5861
5845
@@ -5870,7 +5854,7 @@ impl<SP: Deref> FundedChannel<SP> where
5870
5854
return Err(ChannelError::close("Peer sent update_fail_malformed_htlc when we needed a channel_reestablish".to_owned()));
5871
5855
}
5872
5856
5873
- self.mark_outbound_htlc_removed(msg.htlc_id, None, Some (fail_reason))?;
5857
+ self.mark_outbound_htlc_removed(msg.htlc_id, OutboundHTLCOutcome::Failure (fail_reason))?;
5874
5858
Ok(())
5875
5859
}
5876
5860
@@ -6016,10 +6000,10 @@ impl<SP: Deref> FundedChannel<SP> where
6016
6000
if let &mut OutboundHTLCState::RemoteRemoved(ref mut outcome) = &mut htlc.state {
6017
6001
log_trace!(logger, "Updating HTLC {} to AwaitingRemoteRevokeToRemove due to commitment_signed in channel {}.",
6018
6002
&htlc.payment_hash, &self.context.channel_id);
6019
- // Grab the preimage, if it exists, instead of cloning
6020
- let mut reason = OutboundHTLCOutcome::Success(None );
6003
+ // Swap against a dummy variant to avoid a potentially expensive clone of `OutboundHTLCOutcome::Failure(HTLCFailReason)`
6004
+ let mut reason = OutboundHTLCOutcome::Success(PaymentPreimage([0u8; 32]) );
6021
6005
mem::swap(outcome, &mut reason);
6022
- if let OutboundHTLCOutcome::Success(Some( preimage) ) = reason {
6006
+ if let OutboundHTLCOutcome::Success(preimage) = reason {
6023
6007
// If a user (a) receives an HTLC claim using LDK 0.0.104 or before, then (b)
6024
6008
// upgrades to LDK 0.0.114 or later before the HTLC is fully resolved, we could
6025
6009
// have a `Success(None)` reason. In this case we could forget some HTLC
@@ -6437,8 +6421,8 @@ impl<SP: Deref> FundedChannel<SP> where
6437
6421
}
6438
6422
if let &mut OutboundHTLCState::AwaitingRemoteRevokeToRemove(ref mut outcome) = &mut htlc.state {
6439
6423
log_trace!(logger, " ...promoting outbound AwaitingRemoteRevokeToRemove {} to AwaitingRemovedRemoteRevoke", &htlc.payment_hash);
6440
- // Grab the preimage, if it exists, instead of cloning
6441
- let mut reason = OutboundHTLCOutcome::Success(None );
6424
+ // Swap against a dummy variant to avoid a potentially expensive clone of `OutboundHTLCOutcome::Failure(HTLCFailReason)`
6425
+ let mut reason = OutboundHTLCOutcome::Success(PaymentPreimage([0u8; 32]) );
6442
6426
mem::swap(outcome, &mut reason);
6443
6427
htlc.state = OutboundHTLCState::AwaitingRemovedRemoteRevoke(reason);
6444
6428
require_commitment = true;
@@ -9013,8 +8997,8 @@ impl<SP: Deref> FundedChannel<SP> where
9013
8997
for htlc in self.context.pending_outbound_htlcs.iter_mut() {
9014
8998
if let &mut OutboundHTLCState::AwaitingRemoteRevokeToRemove(ref mut outcome) = &mut htlc.state {
9015
8999
log_trace!(logger, " ...promoting outbound AwaitingRemoteRevokeToRemove {} to AwaitingRemovedRemoteRevoke", &htlc.payment_hash);
9016
- // Grab the preimage, if it exists, instead of cloning
9017
- let mut reason = OutboundHTLCOutcome::Success(None );
9000
+ // Swap against a dummy variant to avoid a potentially expensive clone of `OutboundHTLCOutcome::Failure(HTLCFailReason)`
9001
+ let mut reason = OutboundHTLCOutcome::Success(PaymentPreimage([0u8; 32]) );
9018
9002
mem::swap(outcome, &mut reason);
9019
9003
htlc.state = OutboundHTLCState::AwaitingRemovedRemoteRevoke(reason);
9020
9004
}
@@ -10639,7 +10623,9 @@ impl<SP: Deref> Writeable for FundedChannel<SP> where SP::Target: SignerProvider
10639
10623
}
10640
10624
}
10641
10625
10642
- let mut preimages: Vec<&Option<PaymentPreimage>> = vec![];
10626
+ // The elements of this vector will always be `Some` starting in 0.2,
10627
+ // but we still serialize the option to maintain backwards compatibility
10628
+ let mut preimages: Vec<Option<&PaymentPreimage>> = vec![];
10643
10629
let mut pending_outbound_skimmed_fees: Vec<Option<u64>> = Vec::new();
10644
10630
let mut pending_outbound_blinding_points: Vec<Option<PublicKey>> = Vec::new();
10645
10631
@@ -10666,15 +10652,15 @@ impl<SP: Deref> Writeable for FundedChannel<SP> where SP::Target: SignerProvider
10666
10652
&OutboundHTLCState::AwaitingRemoteRevokeToRemove(ref outcome) => {
10667
10653
3u8.write(writer)?;
10668
10654
if let OutboundHTLCOutcome::Success(preimage) = outcome {
10669
- preimages.push(preimage);
10655
+ preimages.push(Some( preimage) );
10670
10656
}
10671
10657
let reason: Option<&HTLCFailReason> = outcome.into();
10672
10658
reason.write(writer)?;
10673
10659
}
10674
10660
&OutboundHTLCState::AwaitingRemovedRemoteRevoke(ref outcome) => {
10675
10661
4u8.write(writer)?;
10676
10662
if let OutboundHTLCOutcome::Success(preimage) = outcome {
10677
- preimages.push(preimage);
10663
+ preimages.push(Some( preimage) );
10678
10664
}
10679
10665
let reason: Option<&HTLCFailReason> = outcome.into();
10680
10666
reason.write(writer)?;
@@ -11013,15 +10999,30 @@ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, &'c Channel
11013
10999
1 => OutboundHTLCState::Committed,
11014
11000
2 => {
11015
11001
let option: Option<HTLCFailReason> = Readable::read(reader)?;
11016
- OutboundHTLCState::RemoteRemoved(option.into())
11002
+ let outcome = match option {
11003
+ Some(r) => OutboundHTLCOutcome::Failure(r),
11004
+ // Initialize this variant with a dummy preimage, the actual preimage will be filled in further down
11005
+ None => OutboundHTLCOutcome::Success(PaymentPreimage([0u8; 32])),
11006
+ };
11007
+ OutboundHTLCState::RemoteRemoved(outcome)
11017
11008
},
11018
11009
3 => {
11019
11010
let option: Option<HTLCFailReason> = Readable::read(reader)?;
11020
- OutboundHTLCState::AwaitingRemoteRevokeToRemove(option.into())
11011
+ let outcome = match option {
11012
+ Some(r) => OutboundHTLCOutcome::Failure(r),
11013
+ // Initialize this variant with a dummy preimage, the actual preimage will be filled in further down
11014
+ None => OutboundHTLCOutcome::Success(PaymentPreimage([0u8; 32])),
11015
+ };
11016
+ OutboundHTLCState::AwaitingRemoteRevokeToRemove(outcome)
11021
11017
},
11022
11018
4 => {
11023
11019
let option: Option<HTLCFailReason> = Readable::read(reader)?;
11024
- OutboundHTLCState::AwaitingRemovedRemoteRevoke(option.into())
11020
+ let outcome = match option {
11021
+ Some(r) => OutboundHTLCOutcome::Failure(r),
11022
+ // Initialize this variant with a dummy preimage, the actual preimage will be filled in further down
11023
+ None => OutboundHTLCOutcome::Success(PaymentPreimage([0u8; 32])),
11024
+ };
11025
+ OutboundHTLCState::AwaitingRemovedRemoteRevoke(outcome)
11025
11026
},
11026
11027
_ => return Err(DecodeError::InvalidValue),
11027
11028
},
@@ -11168,7 +11169,9 @@ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, &'c Channel
11168
11169
// only, so we default to that if none was written.
11169
11170
let mut channel_type = Some(ChannelTypeFeatures::only_static_remote_key());
11170
11171
let mut channel_creation_height = 0u32;
11171
- let mut preimages_opt: Option<Vec<Option<PaymentPreimage>>> = None;
11172
+ // Starting in 0.2, all the elements in this vector will be `Some`, but they are still
11173
+ // serialized as options to maintain backwards compatibility
11174
+ let mut preimages: Vec<Option<PaymentPreimage>> = Vec::new();
11172
11175
11173
11176
// If we read an old Channel, for simplicity we just treat it as "we never sent an
11174
11177
// AnnouncementSignatures" which implies we'll re-send it on reconnect, but that's fine.
@@ -11222,7 +11225,7 @@ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, &'c Channel
11222
11225
(10, monitor_pending_update_adds, option), // Added in 0.0.122
11223
11226
(11, monitor_pending_finalized_fulfills, optional_vec),
11224
11227
(13, channel_creation_height, required),
11225
- (15, preimages_opt, optional_vec),
11228
+ (15, preimages, required_vec), // The preimages transitioned from optional to required in 0.2
11226
11229
(17, announcement_sigs_state, required),
11227
11230
(19, latest_inbound_scid_alias, option),
11228
11231
(21, outbound_scid_alias, required),
@@ -11250,23 +11253,27 @@ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, &'c Channel
11250
11253
11251
11254
let holder_signer = signer_provider.derive_channel_signer(channel_keys_id);
11252
11255
11253
- if let Some(preimages) = preimages_opt {
11254
- let mut iter = preimages.into_iter();
11255
- for htlc in pending_outbound_htlcs.iter_mut() {
11256
- match &htlc.state {
11257
- OutboundHTLCState::AwaitingRemoteRevokeToRemove(OutboundHTLCOutcome::Success(None)) => {
11258
- htlc.state = OutboundHTLCState::AwaitingRemoteRevokeToRemove(OutboundHTLCOutcome::Success(iter.next().ok_or(DecodeError::InvalidValue)?));
11259
- }
11260
- OutboundHTLCState::AwaitingRemovedRemoteRevoke(OutboundHTLCOutcome::Success(None)) => {
11261
- htlc.state = OutboundHTLCState::AwaitingRemovedRemoteRevoke(OutboundHTLCOutcome::Success(iter.next().ok_or(DecodeError::InvalidValue)?));
11262
- }
11263
- _ => {}
11256
+ let mut iter = preimages.into_iter();
11257
+ for htlc in pending_outbound_htlcs.iter_mut() {
11258
+ match &mut htlc.state {
11259
+ OutboundHTLCState::AwaitingRemoteRevokeToRemove(OutboundHTLCOutcome::Success(ref mut preimage)) => {
11260
+ // This variant was initialized like this further above
11261
+ debug_assert_eq!(preimage, &PaymentPreimage([0u8; 32]));
11262
+ // Flatten and unwrap the preimage; they are always set starting in 0.2.
11263
+ *preimage = iter.next().flatten().ok_or(DecodeError::InvalidValue)?;
11264
11264
}
11265
+ OutboundHTLCState::AwaitingRemovedRemoteRevoke(OutboundHTLCOutcome::Success(ref mut preimage)) => {
11266
+ // This variant was initialized like this further above
11267
+ debug_assert_eq!(preimage, &PaymentPreimage([0u8; 32]));
11268
+ // Flatten and unwrap the preimage; they are always set starting in 0.2.
11269
+ *preimage = iter.next().flatten().ok_or(DecodeError::InvalidValue)?;
11270
+ }
11271
+ _ => {}
11265
11272
}
11266
- // We expect all preimages to be consumed above
11267
- if iter.next().is_some() {
11268
- return Err(DecodeError::InvalidValue);
11269
- }
11273
+ }
11274
+ // We expect all preimages to be consumed above
11275
+ if iter.next().is_some() {
11276
+ return Err(DecodeError::InvalidValue);
11270
11277
}
11271
11278
11272
11279
let chan_features = channel_type.unwrap();
0 commit comments