@@ -211,7 +211,9 @@ enum InboundHTLCState {
211211 /// channel (before it can then get forwarded and/or removed).
212212 /// Implies AwaitingRemoteRevoke.
213213 AwaitingAnnouncedRemoteRevoke(InboundHTLCResolution),
214- Committed,
214+ Committed {
215+ update_add_htlc_opt: Option<msgs::UpdateAddHTLC>,
216+ },
215217 /// Removed by us and a new commitment_signed was sent (if we were AwaitingRemoteRevoke when we
216218 /// created it we would have put it in the holding cell instead). When they next revoke_and_ack
217219 /// we'll drop it.
@@ -235,7 +237,7 @@ impl From<&InboundHTLCState> for Option<InboundHTLCStateDetails> {
235237 InboundHTLCState::AwaitingAnnouncedRemoteRevoke(_) => {
236238 Some(InboundHTLCStateDetails::AwaitingRemoteRevokeToAdd)
237239 },
238- InboundHTLCState::Committed => Some(InboundHTLCStateDetails::Committed),
240+ InboundHTLCState::Committed { .. } => Some(InboundHTLCStateDetails::Committed),
239241 InboundHTLCState::LocalRemoved(InboundHTLCRemovalReason::FailRelay(_)) => {
240242 Some(InboundHTLCStateDetails::AwaitingRemoteRevokeToRemoveFail)
241243 },
@@ -256,7 +258,7 @@ impl fmt::Display for InboundHTLCState {
256258 InboundHTLCState::RemoteAnnounced(_) => write!(f, "RemoteAnnounced"),
257259 InboundHTLCState::AwaitingRemoteRevokeToAnnounce(_) => write!(f, "AwaitingRemoteRevokeToAnnounce"),
258260 InboundHTLCState::AwaitingAnnouncedRemoteRevoke(_) => write!(f, "AwaitingAnnouncedRemoteRevoke"),
259- InboundHTLCState::Committed => write!(f, "Committed"),
261+ InboundHTLCState::Committed { .. } => write!(f, "Committed"),
260262 InboundHTLCState::LocalRemoved(_) => write!(f, "LocalRemoved"),
261263 }
262264 }
@@ -268,7 +270,7 @@ impl InboundHTLCState {
268270 InboundHTLCState::RemoteAnnounced(_) => !generated_by_local,
269271 InboundHTLCState::AwaitingRemoteRevokeToAnnounce(_) => !generated_by_local,
270272 InboundHTLCState::AwaitingAnnouncedRemoteRevoke(_) => true,
271- InboundHTLCState::Committed => true,
273+ InboundHTLCState::Committed { .. } => true,
272274 InboundHTLCState::LocalRemoved(_) => !generated_by_local,
273275 }
274276 }
@@ -296,7 +298,7 @@ impl InboundHTLCState {
296298 },
297299 InboundHTLCResolution::Resolved { .. } => false,
298300 },
299- InboundHTLCState::Committed | InboundHTLCState::LocalRemoved(_) => false,
301+ InboundHTLCState::Committed { .. } | InboundHTLCState::LocalRemoved(_) => false,
300302 }
301303 }
302304}
@@ -4102,7 +4104,7 @@ where
41024104
41034105 if self.pending_inbound_htlcs.iter()
41044106 .any(|htlc| match htlc.state {
4105- InboundHTLCState::Committed => false,
4107+ InboundHTLCState::Committed { .. } => false,
41064108 // An HTLC removal from the local node is pending on the remote commitment.
41074109 InboundHTLCState::LocalRemoved(_) => true,
41084110 // An HTLC add from the remote node is pending on the local commitment.
@@ -4531,7 +4533,7 @@ where
45314533 (InboundHTLCState::RemoteAnnounced(..), _) => true,
45324534 (InboundHTLCState::AwaitingRemoteRevokeToAnnounce(..), _) => true,
45334535 (InboundHTLCState::AwaitingAnnouncedRemoteRevoke(..), _) => true,
4534- (InboundHTLCState::Committed, _) => true,
4536+ (InboundHTLCState::Committed { .. } , _) => true,
45354537 (InboundHTLCState::LocalRemoved(..), true) => true,
45364538 (InboundHTLCState::LocalRemoved(..), false) => false,
45374539 })
@@ -7320,7 +7322,7 @@ where
73207322 payment_preimage_arg
73217323 );
73227324 match htlc.state {
7323- InboundHTLCState::Committed => {},
7325+ InboundHTLCState::Committed { .. } => {},
73247326 InboundHTLCState::LocalRemoved(ref reason) => {
73257327 if let &InboundHTLCRemovalReason::Fulfill { .. } = reason {
73267328 } else {
@@ -7413,7 +7415,7 @@ where
74137415
74147416 {
74157417 let htlc = &mut self.context.pending_inbound_htlcs[pending_idx];
7416- if let InboundHTLCState::Committed = htlc.state {
7418+ if let InboundHTLCState::Committed { .. } = htlc.state {
74177419 } else {
74187420 debug_assert!(
74197421 false,
@@ -7548,7 +7550,7 @@ where
75487550 for (idx, htlc) in self.context.pending_inbound_htlcs.iter().enumerate() {
75497551 if htlc.htlc_id == htlc_id_arg {
75507552 match htlc.state {
7551- InboundHTLCState::Committed => {},
7553+ InboundHTLCState::Committed { .. } => {},
75527554 InboundHTLCState::LocalRemoved(_) => {
75537555 return Err(ChannelError::Ignore(format!("HTLC {} was already resolved", htlc.htlc_id)));
75547556 },
@@ -8716,7 +8718,7 @@ where
87168718 false
87178719 };
87188720 if swap {
8719- let mut state = InboundHTLCState::Committed;
8721+ let mut state = InboundHTLCState::Committed { update_add_htlc_opt: None } ;
87208722 mem::swap(&mut state, &mut htlc.state);
87218723
87228724 if let InboundHTLCState::AwaitingRemoteRevokeToAnnounce(resolution) = state {
@@ -8755,14 +8757,19 @@ where
87558757 PendingHTLCStatus::Forward(forward_info) => {
87568758 log_trace!(logger, " ...promoting inbound AwaitingAnnouncedRemoteRevoke {} to Committed, attempting to forward", &htlc.payment_hash);
87578759 to_forward_infos.push((forward_info, htlc.htlc_id));
8758- htlc.state = InboundHTLCState::Committed;
8760+ // TODO: this is currently unreachable, so is it okay? will we lose a forward?
8761+ htlc.state = InboundHTLCState::Committed {
8762+ update_add_htlc_opt: None,
8763+ };
87598764 },
87608765 }
87618766 },
87628767 InboundHTLCResolution::Pending { update_add_htlc } => {
87638768 log_trace!(logger, " ...promoting inbound AwaitingAnnouncedRemoteRevoke {} to Committed", &htlc.payment_hash);
8764- pending_update_adds.push(update_add_htlc);
8765- htlc.state = InboundHTLCState::Committed;
8769+ pending_update_adds.push(update_add_htlc.clone());
8770+ htlc.state = InboundHTLCState::Committed {
8771+ update_add_htlc_opt: Some(update_add_htlc),
8772+ };
87668773 },
87678774 }
87688775 }
@@ -9297,7 +9304,7 @@ where
92979304 // in response to it yet, so don't touch it.
92989305 true
92999306 },
9300- InboundHTLCState::Committed => true,
9307+ InboundHTLCState::Committed { .. } => true,
93019308 InboundHTLCState::LocalRemoved(_) => {
93029309 // We (hopefully) sent a commitment_signed updating this HTLC (which we can
93039310 // re-transmit if needed) and they may have even sent a revoke_and_ack back
@@ -14518,6 +14525,7 @@ where
1451814525 }
1451914526 }
1452014527 let mut removed_htlc_attribution_data: Vec<&Option<AttributionData>> = Vec::new();
14528+ let mut inbound_committed_update_adds: Vec<Option<msgs::UpdateAddHTLC>> = Vec::new();
1452114529 (self.context.pending_inbound_htlcs.len() as u64 - dropped_inbound_htlcs).write(writer)?;
1452214530 for htlc in self.context.pending_inbound_htlcs.iter() {
1452314531 if let &InboundHTLCState::RemoteAnnounced(_) = &htlc.state {
@@ -14537,8 +14545,9 @@ where
1453714545 2u8.write(writer)?;
1453814546 htlc_resolution.write(writer)?;
1453914547 },
14540- &InboundHTLCState::Committed => {
14548+ &InboundHTLCState::Committed { ref update_add_htlc_opt } => {
1454114549 3u8.write(writer)?;
14550+ inbound_committed_update_adds.push(update_add_htlc_opt.clone());
1454214551 },
1454314552 &InboundHTLCState::LocalRemoved(ref removal_reason) => {
1454414553 4u8.write(writer)?;
@@ -14914,6 +14923,7 @@ where
1491414923 (69, holding_cell_held_htlc_flags, optional_vec), // Added in 0.2
1491514924 (71, holder_commitment_point_previous_revoked, option), // Added in 0.3
1491614925 (73, holder_commitment_point_last_revoked, option), // Added in 0.3
14926+ (75, inbound_committed_update_adds, optional_vec),
1491714927 });
1491814928
1491914929 Ok(())
@@ -14997,7 +15007,7 @@ where
1499715007 };
1499815008 InboundHTLCState::AwaitingAnnouncedRemoteRevoke(resolution)
1499915009 },
15000- 3 => InboundHTLCState::Committed,
15010+ 3 => InboundHTLCState::Committed { update_add_htlc_opt: None } ,
1500115011 4 => {
1500215012 let reason = match <u8 as Readable>::read(reader)? {
1500315013 0 => InboundHTLCRemovalReason::FailRelay(msgs::OnionErrorPacket {
@@ -15301,6 +15311,7 @@ where
1530115311
1530215312 let mut pending_outbound_held_htlc_flags_opt: Option<Vec<Option<()>>> = None;
1530315313 let mut holding_cell_held_htlc_flags_opt: Option<Vec<Option<()>>> = None;
15314+ let mut inbound_committed_update_adds_opt: Option<Vec<Option<msgs::UpdateAddHTLC>>> = None;
1530415315
1530515316 read_tlv_fields!(reader, {
1530615317 (0, announcement_sigs, option),
@@ -15350,6 +15361,7 @@ where
1535015361 (69, holding_cell_held_htlc_flags_opt, optional_vec), // Added in 0.2
1535115362 (71, holder_commitment_point_previous_revoked_opt, option), // Added in 0.3
1535215363 (73, holder_commitment_point_last_revoked_opt, option), // Added in 0.3
15364+ (75, inbound_committed_update_adds_opt, optional_vec),
1535315365 });
1535415366
1535515367 let holder_signer = signer_provider.derive_channel_signer(channel_keys_id);
@@ -15473,6 +15485,17 @@ where
1547315485 return Err(DecodeError::InvalidValue);
1547415486 }
1547515487 }
15488+ if let Some(update_adds) = inbound_committed_update_adds_opt {
15489+ let mut iter = update_adds.into_iter();
15490+ for htlc in pending_inbound_htlcs.iter_mut() {
15491+ if let InboundHTLCState::Committed { ref mut update_add_htlc_opt } = htlc.state {
15492+ *update_add_htlc_opt = iter.next().ok_or(DecodeError::InvalidValue)?;
15493+ }
15494+ }
15495+ if iter.next().is_some() {
15496+ return Err(DecodeError::InvalidValue);
15497+ }
15498+ }
1547615499
1547715500 if let Some(attribution_data_list) = removed_htlc_attribution_data {
1547815501 let mut removed_htlcs = pending_inbound_htlcs.iter_mut().filter_map(|status| {
@@ -16057,7 +16080,7 @@ mod tests {
1605716080 amount_msat: htlc_amount_msat,
1605816081 payment_hash: PaymentHash(Sha256::hash(&[42; 32]).to_byte_array()),
1605916082 cltv_expiry: 300000000,
16060- state: InboundHTLCState::Committed,
16083+ state: InboundHTLCState::Committed { update_add_htlc_opt: None } ,
1606116084 });
1606216085
1606316086 node_a_chan.context.pending_outbound_htlcs.push(OutboundHTLCOutput {
@@ -16903,7 +16926,7 @@ mod tests {
1690316926 amount_msat: 1000000,
1690416927 cltv_expiry: 500,
1690516928 payment_hash: PaymentHash::from(payment_preimage_0),
16906- state: InboundHTLCState::Committed,
16929+ state: InboundHTLCState::Committed { update_add_htlc_opt: None } ,
1690716930 });
1690816931
1690916932 let payment_preimage_1 =
@@ -16913,7 +16936,7 @@ mod tests {
1691316936 amount_msat: 2000000,
1691416937 cltv_expiry: 501,
1691516938 payment_hash: PaymentHash::from(payment_preimage_1),
16916- state: InboundHTLCState::Committed,
16939+ state: InboundHTLCState::Committed { update_add_htlc_opt: None } ,
1691716940 });
1691816941
1691916942 let payment_preimage_2 =
@@ -16953,7 +16976,7 @@ mod tests {
1695316976 amount_msat: 4000000,
1695416977 cltv_expiry: 504,
1695516978 payment_hash: PaymentHash::from(payment_preimage_4),
16956- state: InboundHTLCState::Committed,
16979+ state: InboundHTLCState::Committed { update_add_htlc_opt: None } ,
1695716980 });
1695816981
1695916982 // commitment tx with all five HTLCs untrimmed (minimum feerate)
@@ -17342,7 +17365,7 @@ mod tests {
1734217365 amount_msat: 2000000,
1734317366 cltv_expiry: 501,
1734417367 payment_hash: PaymentHash::from(payment_preimage_1),
17345- state: InboundHTLCState::Committed,
17368+ state: InboundHTLCState::Committed { update_add_htlc_opt: None } ,
1734617369 });
1734717370
1734817371 chan.context.pending_outbound_htlcs.clear();
@@ -17593,7 +17616,7 @@ mod tests {
1759317616 amount_msat: 5000000,
1759417617 cltv_expiry: 920150,
1759517618 payment_hash: PaymentHash::from(htlc_in_preimage),
17596- state: InboundHTLCState::Committed,
17619+ state: InboundHTLCState::Committed { update_add_htlc_opt: None } ,
1759717620 }));
1759817621
1759917622 chan.context.pending_outbound_htlcs.extend(
@@ -17722,7 +17745,7 @@ mod tests {
1772217745 amount_msat: 100000,
1772317746 cltv_expiry: 920125,
1772417747 payment_hash: htlc_0_in_hash,
17725- state: InboundHTLCState::Committed,
17748+ state: InboundHTLCState::Committed { update_add_htlc_opt: None } ,
1772617749 });
1772717750
1772817751 let htlc_1_in_preimage =
@@ -17740,7 +17763,7 @@ mod tests {
1774017763 amount_msat: 49900000,
1774117764 cltv_expiry: 920125,
1774217765 payment_hash: htlc_1_in_hash,
17743- state: InboundHTLCState::Committed,
17766+ state: InboundHTLCState::Committed { update_add_htlc_opt: None } ,
1774417767 });
1774517768
1774617769 chan.context.pending_outbound_htlcs.extend(
@@ -17792,7 +17815,7 @@ mod tests {
1779217815 amount_msat: 30000,
1779317816 payment_hash,
1779417817 cltv_expiry: 920125,
17795- state: InboundHTLCState::Committed,
17818+ state: InboundHTLCState::Committed { update_add_htlc_opt: None } ,
1779617819 },
1779717820 ));
1779817821
@@ -17959,7 +17982,7 @@ mod tests {
1795917982 amount_msat,
1796017983 cltv_expiry,
1796117984 payment_hash,
17962- state: InboundHTLCState::Committed,
17985+ state: InboundHTLCState::Committed { update_add_htlc_opt: None } ,
1796317986 }),
1796417987 );
1796517988
0 commit comments