@@ -443,6 +443,7 @@ struct OutboundHTLCOutput {
443443 blinding_point: Option<PublicKey>,
444444 skimmed_fee_msat: Option<u64>,
445445 send_timestamp: Option<Duration>,
446+ hold_htlc: Option<()>,
446447}
447448
448449impl OutboundHTLCOutput {
@@ -477,6 +478,7 @@ enum HTLCUpdateAwaitingACK {
477478 // The extra fee we're skimming off the top of this HTLC.
478479 skimmed_fee_msat: Option<u64>,
479480 blinding_point: Option<PublicKey>,
481+ hold_htlc: Option<()>,
480482 },
481483 ClaimHTLC {
482484 payment_preimage: PaymentPreimage,
@@ -8046,6 +8048,7 @@ where
80468048 ref onion_routing_packet,
80478049 skimmed_fee_msat,
80488050 blinding_point,
8051+ hold_htlc: _,
80498052 ..
80508053 } => {
80518054 match self.send_htlc(
@@ -12131,6 +12134,7 @@ where
1213112134 onion_routing_packet,
1213212135 skimmed_fee_msat,
1213312136 blinding_point,
12137+ hold_htlc: None,
1213412138 });
1213512139 return Ok(false);
1213612140 }
@@ -12152,6 +12156,7 @@ where
1215212156 blinding_point,
1215312157 skimmed_fee_msat,
1215412158 send_timestamp,
12159+ hold_htlc: None,
1215512160 });
1215612161 self.context.next_holder_htlc_id += 1;
1215712162
@@ -13990,6 +13995,7 @@ where
1399013995 let mut fulfill_attribution_data = vec![];
1399113996 let mut pending_outbound_skimmed_fees: Vec<Option<u64>> = Vec::new();
1399213997 let mut pending_outbound_blinding_points: Vec<Option<PublicKey>> = Vec::new();
13998+ let mut pending_outbound_held_htlc_flags: Vec<Option<()>> = Vec::new();
1399313999
1399414000 (self.context.pending_outbound_htlcs.len() as u64).write(writer)?;
1399514001 for htlc in self.context.pending_outbound_htlcs.iter() {
@@ -14032,6 +14038,7 @@ where
1403214038 }
1403314039 pending_outbound_skimmed_fees.push(htlc.skimmed_fee_msat);
1403414040 pending_outbound_blinding_points.push(htlc.blinding_point);
14041+ pending_outbound_held_htlc_flags.push(htlc.hold_htlc);
1403514042 }
1403614043
1403714044 let holding_cell_htlc_update_count = self.context.holding_cell_htlc_updates.len();
@@ -14041,6 +14048,8 @@ where
1404114048 Vec::with_capacity(holding_cell_htlc_update_count);
1404214049 let mut holding_cell_attribution_data: Vec<Option<&AttributionData>> =
1404314050 Vec::with_capacity(holding_cell_htlc_update_count);
14051+ let mut holding_cell_held_htlc_flags: Vec<Option<()>> =
14052+ Vec::with_capacity(holding_cell_htlc_update_count);
1404414053 // Vec of (htlc_id, failure_code, sha256_of_onion)
1404514054 let mut malformed_htlcs: Vec<(u64, u16, [u8; 32])> = Vec::new();
1404614055 (holding_cell_htlc_update_count as u64).write(writer)?;
@@ -14054,6 +14063,7 @@ where
1405414063 ref onion_routing_packet,
1405514064 blinding_point,
1405614065 skimmed_fee_msat,
14066+ hold_htlc,
1405714067 } => {
1405814068 0u8.write(writer)?;
1405914069 amount_msat.write(writer)?;
@@ -14064,6 +14074,7 @@ where
1406414074
1406514075 holding_cell_skimmed_fees.push(skimmed_fee_msat);
1406614076 holding_cell_blinding_points.push(blinding_point);
14077+ holding_cell_held_htlc_flags.push(hold_htlc);
1406714078 },
1406814079 &HTLCUpdateAwaitingACK::ClaimHTLC {
1406914080 ref payment_preimage,
@@ -14311,6 +14322,8 @@ where
1431114322 (63, holder_commitment_point_current, option), // Added in 0.2
1431214323 (64, self.pending_splice, option), // Added in 0.2
1431314324 (65, self.quiescent_action, option), // Added in 0.2
14325+ (67, pending_outbound_held_htlc_flags, optional_vec), // Added in 0.2
14326+ (69, holding_cell_held_htlc_flags, optional_vec), // Added in 0.2
1431414327 });
1431514328
1431614329 Ok(())
@@ -14459,6 +14472,7 @@ where
1445914472 skimmed_fee_msat: None,
1446014473 blinding_point: None,
1446114474 send_timestamp: None,
14475+ hold_htlc: None,
1446214476 });
1446314477 }
1446414478
@@ -14477,6 +14491,7 @@ where
1447714491 onion_routing_packet: Readable::read(reader)?,
1447814492 skimmed_fee_msat: None,
1447914493 blinding_point: None,
14494+ hold_htlc: None,
1448014495 },
1448114496 1 => HTLCUpdateAwaitingACK::ClaimHTLC {
1448214497 payment_preimage: Readable::read(reader)?,
@@ -14674,6 +14689,9 @@ where
1467414689 let mut pending_splice: Option<PendingFunding> = None;
1467514690 let mut quiescent_action = None;
1467614691
14692+ let mut pending_outbound_held_htlc_flags_opt: Option<Vec<Option<()>>> = None;
14693+ let mut holding_cell_held_htlc_flags_opt: Option<Vec<Option<()>>> = None;
14694+
1467714695 read_tlv_fields!(reader, {
1467814696 (0, announcement_sigs, option),
1467914697 (1, minimum_depth, option),
@@ -14718,6 +14736,8 @@ where
1471814736 (63, holder_commitment_point_current_opt, option), // Added in 0.2
1471914737 (64, pending_splice, option), // Added in 0.2
1472014738 (65, quiescent_action, upgradable_option), // Added in 0.2
14739+ (67, pending_outbound_held_htlc_flags_opt, optional_vec), // Added in 0.2
14740+ (69, holding_cell_held_htlc_flags_opt, optional_vec), // Added in 0.2
1472114741 });
1472214742
1472314743 let holder_signer = signer_provider.derive_channel_signer(channel_keys_id);
@@ -14819,6 +14839,28 @@ where
1481914839 return Err(DecodeError::InvalidValue);
1482014840 }
1482114841 }
14842+ if let Some(held_htlcs) = pending_outbound_held_htlc_flags_opt {
14843+ let mut iter = held_htlcs.into_iter();
14844+ for htlc in pending_outbound_htlcs.iter_mut() {
14845+ htlc.hold_htlc = iter.next().ok_or(DecodeError::InvalidValue)?;
14846+ }
14847+ // We expect all held HTLC flags to be consumed above
14848+ if iter.next().is_some() {
14849+ return Err(DecodeError::InvalidValue);
14850+ }
14851+ }
14852+ if let Some(held_htlcs) = holding_cell_held_htlc_flags_opt {
14853+ let mut iter = held_htlcs.into_iter();
14854+ for htlc in holding_cell_htlc_updates.iter_mut() {
14855+ if let HTLCUpdateAwaitingACK::AddHTLC { ref mut hold_htlc, .. } = htlc {
14856+ *hold_htlc = iter.next().ok_or(DecodeError::InvalidValue)?;
14857+ }
14858+ }
14859+ // We expect all held HTLC flags to be consumed above
14860+ if iter.next().is_some() {
14861+ return Err(DecodeError::InvalidValue);
14862+ }
14863+ }
1482214864
1482314865 if let Some(attribution_data_list) = removed_htlc_attribution_data {
1482414866 let mut removed_htlcs = pending_inbound_htlcs.iter_mut().filter_map(|status| {
@@ -15391,6 +15433,7 @@ mod tests {
1539115433 skimmed_fee_msat: None,
1539215434 blinding_point: None,
1539315435 send_timestamp: None,
15436+ hold_htlc: None,
1539415437 });
1539515438
1539615439 // Make sure when Node A calculates their local commitment transaction, none of the HTLCs pass
@@ -15845,6 +15888,7 @@ mod tests {
1584515888 skimmed_fee_msat: None,
1584615889 blinding_point: None,
1584715890 send_timestamp: None,
15891+ hold_htlc: None,
1584815892 };
1584915893 let mut pending_outbound_htlcs = vec![dummy_outbound_output.clone(); 10];
1585015894 for (idx, htlc) in pending_outbound_htlcs.iter_mut().enumerate() {
@@ -15870,6 +15914,7 @@ mod tests {
1587015914 },
1587115915 skimmed_fee_msat: None,
1587215916 blinding_point: None,
15917+ hold_htlc: None,
1587315918 };
1587415919 let dummy_holding_cell_claim_htlc = |attribution_data| HTLCUpdateAwaitingACK::ClaimHTLC {
1587515920 payment_preimage: PaymentPreimage([42; 32]),
@@ -16193,6 +16238,7 @@ mod tests {
1619316238 skimmed_fee_msat: None,
1619416239 blinding_point: None,
1619516240 send_timestamp: None,
16241+ hold_htlc: None,
1619616242 };
1619716243 out.payment_hash.0 = Sha256::hash(&<Vec<u8>>::from_hex("0202020202020202020202020202020202020202020202020202020202020202").unwrap()).to_byte_array();
1619816244 out
@@ -16208,6 +16254,7 @@ mod tests {
1620816254 skimmed_fee_msat: None,
1620916255 blinding_point: None,
1621016256 send_timestamp: None,
16257+ hold_htlc: None,
1621116258 };
1621216259 out.payment_hash.0 = Sha256::hash(&<Vec<u8>>::from_hex("0303030303030303030303030303030303030303030303030303030303030303").unwrap()).to_byte_array();
1621316260 out
@@ -16621,6 +16668,7 @@ mod tests {
1662116668 skimmed_fee_msat: None,
1662216669 blinding_point: None,
1662316670 send_timestamp: None,
16671+ hold_htlc: None,
1662416672 };
1662516673 out.payment_hash.0 = Sha256::hash(&<Vec<u8>>::from_hex("0505050505050505050505050505050505050505050505050505050505050505").unwrap()).to_byte_array();
1662616674 out
@@ -16636,6 +16684,7 @@ mod tests {
1663616684 skimmed_fee_msat: None,
1663716685 blinding_point: None,
1663816686 send_timestamp: None,
16687+ hold_htlc: None,
1663916688 };
1664016689 out.payment_hash.0 = Sha256::hash(&<Vec<u8>>::from_hex("0505050505050505050505050505050505050505050505050505050505050505").unwrap()).to_byte_array();
1664116690 out
0 commit comments