Skip to content

Commit 94d3167

Browse files
Persist hold_htlc flags in Channel
As part of supporting sending payments as an often-offline sender, the sender needs to be able to set a flag in their update_add_htlc message indicating that the HTLC should be held until receipt of a release_held_htlc onion message from the often-offline payment recipient. We don't yet ever set this flag, but lay the groundwork by including the field in Channel serialization. See-also BOLTs PR 989
1 parent 1c776a9 commit 94d3167

File tree

1 file changed

+49
-0
lines changed

1 file changed

+49
-0
lines changed

lightning/src/ln/channel.rs

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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

448449
impl 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

Comments
 (0)