@@ -364,9 +364,11 @@ impl OutboundHTLCState {
364364
365365 fn preimage(&self) -> Option<PaymentPreimage> {
366366 match self {
367- OutboundHTLCState::RemoteRemoved(OutboundHTLCOutcome::Success(p)) |
368- OutboundHTLCState::AwaitingRemoteRevokeToRemove(OutboundHTLCOutcome::Success(p)) |
369- OutboundHTLCState::AwaitingRemovedRemoteRevoke(OutboundHTLCOutcome::Success(p)) => p.as_ref().copied(),
367+ OutboundHTLCState::RemoteRemoved(OutboundHTLCOutcome::Success(preimage)) |
368+ OutboundHTLCState::AwaitingRemoteRevokeToRemove(OutboundHTLCOutcome::Success(preimage)) |
369+ OutboundHTLCState::AwaitingRemovedRemoteRevoke(OutboundHTLCOutcome::Success(preimage)) => {
370+ Some(*preimage)
371+ },
370372 _ => None,
371373 }
372374 }
@@ -375,20 +377,12 @@ impl OutboundHTLCState {
375377#[derive(Clone)]
376378#[cfg_attr(test, derive(Debug, PartialEq))]
377379enum OutboundHTLCOutcome {
378- /// LDK version 0.0.105+ will always fill in the preimage here.
379- 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),
380383 Failure(HTLCFailReason),
381384}
382385
383- impl From<Option<HTLCFailReason>> for OutboundHTLCOutcome {
384- fn from(o: Option<HTLCFailReason>) -> Self {
385- match o {
386- None => OutboundHTLCOutcome::Success(None),
387- Some(r) => OutboundHTLCOutcome::Failure(r)
388- }
389- }
390- }
391-
392386impl<'a> Into<Option<&'a HTLCFailReason>> for &'a OutboundHTLCOutcome {
393387 fn into(self) -> Option<&'a HTLCFailReason> {
394388 match self {
@@ -3876,7 +3870,7 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
38763870 }
38773871 remote_htlc_total_msat += htlc.amount_msat;
38783872 } else {
3879- if let InboundHTLCState::LocalRemoved(InboundHTLCRemovalReason::Fulfill(_preimage)) = htlc.state {
3873+ if htlc.state.preimage().is_some() {
38803874 value_to_self_msat_offset += htlc.amount_msat as i64;
38813875 }
38823876 }
@@ -3889,10 +3883,7 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
38893883 }
38903884 local_htlc_total_msat += htlc.amount_msat;
38913885 } else {
3892- if let OutboundHTLCState::AwaitingRemoteRevokeToRemove(OutboundHTLCOutcome::Success(_)) |
3893- OutboundHTLCState::AwaitingRemovedRemoteRevoke(OutboundHTLCOutcome::Success(_)) |
3894- OutboundHTLCState::RemoteRemoved(OutboundHTLCOutcome::Success(_))
3895- = htlc.state {
3886+ if htlc.state.preimage().is_some() {
38963887 value_to_self_msat_offset -= htlc.amount_msat as i64;
38973888 }
38983889 }
@@ -5801,16 +5792,18 @@ impl<SP: Deref> FundedChannel<SP> where
58015792 #[inline]
58025793 fn mark_outbound_htlc_removed(&mut self, htlc_id: u64, check_preimage: Option<PaymentPreimage>, fail_reason: Option<HTLCFailReason>) -> Result<&OutboundHTLCOutput, ChannelError> {
58035794 assert!(!(check_preimage.is_some() && fail_reason.is_some()), "cannot fail while we have a preimage");
5795+ assert!(!(check_preimage.is_none() && fail_reason.is_none()), "either provide a preimage, or a failure reason");
58045796 for htlc in self.context.pending_outbound_htlcs.iter_mut() {
58055797 if htlc.htlc_id == htlc_id {
58065798 let outcome = match check_preimage {
5807- None => fail_reason.into(),
5799+ // We checked that either check_preimage or fail_reason is set above, so we can safely unwrap here
5800+ None => OutboundHTLCOutcome::Failure(fail_reason.unwrap()),
58085801 Some(payment_preimage) => {
58095802 let payment_hash = PaymentHash(Sha256::hash(&payment_preimage.0[..]).to_byte_array());
58105803 if payment_hash != htlc.payment_hash {
58115804 return Err(ChannelError::close(format!("Remote tried to fulfill HTLC ({}) with an incorrect preimage", htlc_id)));
58125805 }
5813- OutboundHTLCOutcome::Success(Some( payment_preimage) )
5806+ OutboundHTLCOutcome::Success(payment_preimage)
58145807 }
58155808 };
58165809 match htlc.state {
@@ -6014,10 +6007,10 @@ impl<SP: Deref> FundedChannel<SP> where
60146007 if let &mut OutboundHTLCState::RemoteRemoved(ref mut outcome) = &mut htlc.state {
60156008 log_trace!(logger, "Updating HTLC {} to AwaitingRemoteRevokeToRemove due to commitment_signed in channel {}.",
60166009 &htlc.payment_hash, &self.context.channel_id);
6017- // Grab the preimage, if it exists, instead of cloning
6018- let mut reason = OutboundHTLCOutcome::Success(None );
6010+ // Swap against a dummy variant to avoid a potentially expensive clone of `OutboundHTLCOutcome::Failure(HTLCFailReason)`
6011+ let mut reason = OutboundHTLCOutcome::Success(PaymentPreimage([0u8; 32]) );
60196012 mem::swap(outcome, &mut reason);
6020- if let OutboundHTLCOutcome::Success(Some( preimage) ) = reason {
6013+ if let OutboundHTLCOutcome::Success(preimage) = reason {
60216014 // If a user (a) receives an HTLC claim using LDK 0.0.104 or before, then (b)
60226015 // upgrades to LDK 0.0.114 or later before the HTLC is fully resolved, we could
60236016 // have a `Success(None)` reason. In this case we could forget some HTLC
@@ -6435,8 +6428,8 @@ impl<SP: Deref> FundedChannel<SP> where
64356428 }
64366429 if let &mut OutboundHTLCState::AwaitingRemoteRevokeToRemove(ref mut outcome) = &mut htlc.state {
64376430 log_trace!(logger, " ...promoting outbound AwaitingRemoteRevokeToRemove {} to AwaitingRemovedRemoteRevoke", &htlc.payment_hash);
6438- // Grab the preimage, if it exists, instead of cloning
6439- let mut reason = OutboundHTLCOutcome::Success(None );
6431+ // Swap against a dummy variant to avoid a potentially expensive clone of `OutboundHTLCOutcome::Failure(HTLCFailReason)`
6432+ let mut reason = OutboundHTLCOutcome::Success(PaymentPreimage([0u8; 32]) );
64406433 mem::swap(outcome, &mut reason);
64416434 htlc.state = OutboundHTLCState::AwaitingRemovedRemoteRevoke(reason);
64426435 require_commitment = true;
@@ -9011,8 +9004,8 @@ impl<SP: Deref> FundedChannel<SP> where
90119004 for htlc in self.context.pending_outbound_htlcs.iter_mut() {
90129005 if let &mut OutboundHTLCState::AwaitingRemoteRevokeToRemove(ref mut outcome) = &mut htlc.state {
90139006 log_trace!(logger, " ...promoting outbound AwaitingRemoteRevokeToRemove {} to AwaitingRemovedRemoteRevoke", &htlc.payment_hash);
9014- // Grab the preimage, if it exists, instead of cloning
9015- let mut reason = OutboundHTLCOutcome::Success(None );
9007+ // Swap against a dummy variant to avoid a potentially expensive clone of `OutboundHTLCOutcome::Failure(HTLCFailReason)`
9008+ let mut reason = OutboundHTLCOutcome::Success(PaymentPreimage([0u8; 32]) );
90169009 mem::swap(outcome, &mut reason);
90179010 htlc.state = OutboundHTLCState::AwaitingRemovedRemoteRevoke(reason);
90189011 }
@@ -10637,7 +10630,9 @@ impl<SP: Deref> Writeable for FundedChannel<SP> where SP::Target: SignerProvider
1063710630 }
1063810631 }
1063910632
10640- let mut preimages: Vec<&Option<PaymentPreimage>> = vec![];
10633+ // The elements of this vector will always be `Some` starting in 0.2,
10634+ // but we still serialize the option to maintain backwards compatibility
10635+ let mut preimages: Vec<Option<&PaymentPreimage>> = vec![];
1064110636 let mut pending_outbound_skimmed_fees: Vec<Option<u64>> = Vec::new();
1064210637 let mut pending_outbound_blinding_points: Vec<Option<PublicKey>> = Vec::new();
1064310638
@@ -10664,15 +10659,15 @@ impl<SP: Deref> Writeable for FundedChannel<SP> where SP::Target: SignerProvider
1066410659 &OutboundHTLCState::AwaitingRemoteRevokeToRemove(ref outcome) => {
1066510660 3u8.write(writer)?;
1066610661 if let OutboundHTLCOutcome::Success(preimage) = outcome {
10667- preimages.push(preimage);
10662+ preimages.push(Some( preimage) );
1066810663 }
1066910664 let reason: Option<&HTLCFailReason> = outcome.into();
1067010665 reason.write(writer)?;
1067110666 }
1067210667 &OutboundHTLCState::AwaitingRemovedRemoteRevoke(ref outcome) => {
1067310668 4u8.write(writer)?;
1067410669 if let OutboundHTLCOutcome::Success(preimage) = outcome {
10675- preimages.push(preimage);
10670+ preimages.push(Some( preimage) );
1067610671 }
1067710672 let reason: Option<&HTLCFailReason> = outcome.into();
1067810673 reason.write(writer)?;
@@ -11011,15 +11006,30 @@ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, &'c Channel
1101111006 1 => OutboundHTLCState::Committed,
1101211007 2 => {
1101311008 let option: Option<HTLCFailReason> = Readable::read(reader)?;
11014- OutboundHTLCState::RemoteRemoved(option.into())
11009+ let outcome = match option {
11010+ Some(r) => OutboundHTLCOutcome::Failure(r),
11011+ // Initialize this variant with a dummy preimage, the actual preimage will be filled in further down
11012+ None => OutboundHTLCOutcome::Success(PaymentPreimage([0u8; 32])),
11013+ };
11014+ OutboundHTLCState::RemoteRemoved(outcome)
1101511015 },
1101611016 3 => {
1101711017 let option: Option<HTLCFailReason> = Readable::read(reader)?;
11018- OutboundHTLCState::AwaitingRemoteRevokeToRemove(option.into())
11018+ let outcome = match option {
11019+ Some(r) => OutboundHTLCOutcome::Failure(r),
11020+ // Initialize this variant with a dummy preimage, the actual preimage will be filled in further down
11021+ None => OutboundHTLCOutcome::Success(PaymentPreimage([0u8; 32])),
11022+ };
11023+ OutboundHTLCState::AwaitingRemoteRevokeToRemove(outcome)
1101911024 },
1102011025 4 => {
1102111026 let option: Option<HTLCFailReason> = Readable::read(reader)?;
11022- OutboundHTLCState::AwaitingRemovedRemoteRevoke(option.into())
11027+ let outcome = match option {
11028+ Some(r) => OutboundHTLCOutcome::Failure(r),
11029+ // Initialize this variant with a dummy preimage, the actual preimage will be filled in further down
11030+ None => OutboundHTLCOutcome::Success(PaymentPreimage([0u8; 32])),
11031+ };
11032+ OutboundHTLCState::AwaitingRemovedRemoteRevoke(outcome)
1102311033 },
1102411034 _ => return Err(DecodeError::InvalidValue),
1102511035 },
@@ -11166,7 +11176,9 @@ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, &'c Channel
1116611176 // only, so we default to that if none was written.
1116711177 let mut channel_type = Some(ChannelTypeFeatures::only_static_remote_key());
1116811178 let mut channel_creation_height = 0u32;
11169- let mut preimages_opt: Option<Vec<Option<PaymentPreimage>>> = None;
11179+ // Starting in 0.2, all the elements in this vector will be `Some`, but they are still
11180+ // serialized as options to maintain backwards compatibility
11181+ let mut preimages: Vec<Option<PaymentPreimage>> = Vec::new();
1117011182
1117111183 // If we read an old Channel, for simplicity we just treat it as "we never sent an
1117211184 // AnnouncementSignatures" which implies we'll re-send it on reconnect, but that's fine.
@@ -11220,7 +11232,7 @@ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, &'c Channel
1122011232 (10, monitor_pending_update_adds, option), // Added in 0.0.122
1122111233 (11, monitor_pending_finalized_fulfills, optional_vec),
1122211234 (13, channel_creation_height, required),
11223- (15, preimages_opt, optional_vec),
11235+ (15, preimages, required_vec), // The preimages transitioned from optional to required in 0.2
1122411236 (17, announcement_sigs_state, required),
1122511237 (19, latest_inbound_scid_alias, option),
1122611238 (21, outbound_scid_alias, required),
@@ -11248,23 +11260,27 @@ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, &'c Channel
1124811260
1124911261 let holder_signer = signer_provider.derive_channel_signer(channel_keys_id);
1125011262
11251- if let Some(preimages) = preimages_opt {
11252- let mut iter = preimages.into_iter();
11253- for htlc in pending_outbound_htlcs.iter_mut() {
11254- match &htlc.state {
11255- OutboundHTLCState::AwaitingRemoteRevokeToRemove(OutboundHTLCOutcome::Success(None)) => {
11256- htlc.state = OutboundHTLCState::AwaitingRemoteRevokeToRemove(OutboundHTLCOutcome::Success(iter.next().ok_or(DecodeError::InvalidValue)?));
11257- }
11258- OutboundHTLCState::AwaitingRemovedRemoteRevoke(OutboundHTLCOutcome::Success(None)) => {
11259- htlc.state = OutboundHTLCState::AwaitingRemovedRemoteRevoke(OutboundHTLCOutcome::Success(iter.next().ok_or(DecodeError::InvalidValue)?));
11260- }
11261- _ => {}
11263+ let mut iter = preimages.into_iter();
11264+ for htlc in pending_outbound_htlcs.iter_mut() {
11265+ match &mut htlc.state {
11266+ OutboundHTLCState::AwaitingRemoteRevokeToRemove(OutboundHTLCOutcome::Success(ref mut preimage)) => {
11267+ // This variant was initialized like this further above
11268+ debug_assert_eq!(preimage, &PaymentPreimage([0u8; 32]));
11269+ // Flatten and unwrap the preimage; they are always set starting in 0.2.
11270+ *preimage = iter.next().flatten().ok_or(DecodeError::InvalidValue)?;
1126211271 }
11272+ OutboundHTLCState::AwaitingRemovedRemoteRevoke(OutboundHTLCOutcome::Success(ref mut preimage)) => {
11273+ // This variant was initialized like this further above
11274+ debug_assert_eq!(preimage, &PaymentPreimage([0u8; 32]));
11275+ // Flatten and unwrap the preimage; they are always set starting in 0.2.
11276+ *preimage = iter.next().flatten().ok_or(DecodeError::InvalidValue)?;
11277+ }
11278+ _ => {}
1126311279 }
11264- // We expect all preimages to be consumed above
11265- if iter.next().is_some() {
11266- return Err(DecodeError::InvalidValue);
11267- }
11280+ }
11281+ // We expect all preimages to be consumed above
11282+ if iter.next().is_some() {
11283+ return Err(DecodeError::InvalidValue);
1126811284 }
1126911285
1127011286 let chan_features = channel_type.unwrap();
0 commit comments