Skip to content

Commit f2c1712

Browse files
committed
Make channel fields which are from accept_channel Optional
These fields are set with a dummy value, which we should generally be avoiding since Rust gives us a nice `Option` type to use instead. Further, we stop rejecting channel_update messages outright when the htlc_maximum_msat field includes the reserve values, which nodes could reasonably do without it meriting a channel closure.
1 parent fbb36a0 commit f2c1712

File tree

1 file changed

+57
-27
lines changed

1 file changed

+57
-27
lines changed

lightning/src/ln/channel.rs

Lines changed: 57 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -396,7 +396,7 @@ pub(super) struct Channel<Signer: Sign> {
396396
counterparty_max_htlc_value_in_flight_msat: u64,
397397
//get_holder_max_htlc_value_in_flight_msat(): u64,
398398
/// minimum channel reserve for self to maintain - set by them.
399-
counterparty_selected_channel_reserve_satoshis: u64,
399+
counterparty_selected_channel_reserve_satoshis: Option<u64>,
400400
// get_holder_selected_channel_reserve_satoshis(channel_value_sats: u64): u64
401401
counterparty_htlc_minimum_msat: u64,
402402
holder_htlc_minimum_msat: u64,
@@ -405,7 +405,7 @@ pub(super) struct Channel<Signer: Sign> {
405405
#[cfg(not(test))]
406406
counterparty_max_accepted_htlcs: u16,
407407
//implied by OUR_MAX_HTLCS: max_accepted_htlcs: u16,
408-
minimum_depth: u32,
408+
minimum_depth: Option<u32>,
409409

410410
counterparty_forwarding_info: Option<CounterpartyForwardingInfo>,
411411

@@ -609,11 +609,11 @@ impl<Signer: Sign> Channel<Signer> {
609609
counterparty_dust_limit_satoshis: 0,
610610
holder_dust_limit_satoshis: MIN_DUST_LIMIT_SATOSHIS,
611611
counterparty_max_htlc_value_in_flight_msat: 0,
612-
counterparty_selected_channel_reserve_satoshis: 0,
612+
counterparty_selected_channel_reserve_satoshis: None, // Filled in in accept_channel
613613
counterparty_htlc_minimum_msat: 0,
614614
holder_htlc_minimum_msat: if config.own_channel_config.our_htlc_minimum_msat == 0 { 1 } else { config.own_channel_config.our_htlc_minimum_msat },
615615
counterparty_max_accepted_htlcs: 0,
616-
minimum_depth: 0, // Filled in in accept_channel
616+
minimum_depth: None, // Filled in in accept_channel
617617

618618
counterparty_forwarding_info: None,
619619

@@ -851,11 +851,11 @@ impl<Signer: Sign> Channel<Signer> {
851851
counterparty_dust_limit_satoshis: msg.dust_limit_satoshis,
852852
holder_dust_limit_satoshis: MIN_DUST_LIMIT_SATOSHIS,
853853
counterparty_max_htlc_value_in_flight_msat: cmp::min(msg.max_htlc_value_in_flight_msat, msg.funding_satoshis * 1000),
854-
counterparty_selected_channel_reserve_satoshis: msg.channel_reserve_satoshis,
854+
counterparty_selected_channel_reserve_satoshis: Some(msg.channel_reserve_satoshis),
855855
counterparty_htlc_minimum_msat: msg.htlc_minimum_msat,
856856
holder_htlc_minimum_msat: if config.own_channel_config.our_htlc_minimum_msat == 0 { 1 } else { config.own_channel_config.our_htlc_minimum_msat },
857857
counterparty_max_accepted_htlcs: msg.max_accepted_htlcs,
858-
minimum_depth: config.own_channel_config.minimum_depth,
858+
minimum_depth: Some(config.own_channel_config.minimum_depth),
859859

860860
counterparty_forwarding_info: None,
861861

@@ -1036,7 +1036,7 @@ impl<Signer: Sign> Channel<Signer> {
10361036
} else {
10371037
self.counterparty_max_commitment_tx_output.lock().unwrap()
10381038
};
1039-
debug_assert!(broadcaster_max_commitment_tx_output.0 <= value_to_self_msat as u64 || value_to_self_msat / 1000 >= self.counterparty_selected_channel_reserve_satoshis as i64);
1039+
debug_assert!(broadcaster_max_commitment_tx_output.0 <= value_to_self_msat as u64 || value_to_self_msat / 1000 >= self.counterparty_selected_channel_reserve_satoshis.unwrap() as i64);
10401040
broadcaster_max_commitment_tx_output.0 = cmp::max(broadcaster_max_commitment_tx_output.0, value_to_self_msat as u64);
10411041
debug_assert!(broadcaster_max_commitment_tx_output.1 <= value_to_remote_msat as u64 || value_to_remote_msat / 1000 >= Channel::<Signer>::get_holder_selected_channel_reserve_satoshis(self.channel_value_satoshis) as i64);
10421042
broadcaster_max_commitment_tx_output.1 = cmp::max(broadcaster_max_commitment_tx_output.1, value_to_remote_msat as u64);
@@ -1220,7 +1220,12 @@ impl<Signer: Sign> Channel<Signer> {
12201220
/// @local is used only to convert relevant internal structures which refer to remote vs local
12211221
/// to decide value of outputs and direction of HTLCs.
12221222
fn build_htlc_transaction(&self, prev_hash: &Txid, htlc: &HTLCOutputInCommitment, local: bool, keys: &TxCreationKeys, feerate_per_kw: u32) -> Transaction {
1223-
chan_utils::build_htlc_transaction(prev_hash, feerate_per_kw, if local { self.get_counterparty_selected_contest_delay() } else { self.get_holder_selected_contest_delay() }, htlc, &keys.broadcaster_delayed_payment_key, &keys.revocation_key)
1223+
chan_utils::build_htlc_transaction(prev_hash, feerate_per_kw,
1224+
if local {
1225+
self.get_counterparty_selected_contest_delay().unwrap()
1226+
} else {
1227+
self.get_holder_selected_contest_delay()
1228+
}, htlc, &keys.broadcaster_delayed_payment_key, &keys.revocation_key)
12241229
}
12251230

12261231
/// Per HTLC, only one get_update_fail_htlc or get_update_fulfill_htlc call may be made.
@@ -1517,10 +1522,10 @@ impl<Signer: Sign> Channel<Signer> {
15171522

15181523
self.counterparty_dust_limit_satoshis = msg.dust_limit_satoshis;
15191524
self.counterparty_max_htlc_value_in_flight_msat = cmp::min(msg.max_htlc_value_in_flight_msat, self.channel_value_satoshis * 1000);
1520-
self.counterparty_selected_channel_reserve_satoshis = msg.channel_reserve_satoshis;
1525+
self.counterparty_selected_channel_reserve_satoshis = Some(msg.channel_reserve_satoshis);
15211526
self.counterparty_htlc_minimum_msat = msg.htlc_minimum_msat;
15221527
self.counterparty_max_accepted_htlcs = msg.max_accepted_htlcs;
1523-
self.minimum_depth = msg.minimum_depth;
1528+
self.minimum_depth = Some(msg.minimum_depth);
15241529

15251530
let counterparty_pubkeys = ChannelPublicKeys {
15261531
funding_pubkey: msg.funding_pubkey,
@@ -2070,7 +2075,7 @@ impl<Signer: Sign> Channel<Signer> {
20702075
// Check that they won't violate our local required channel reserve by adding this HTLC.
20712076
let htlc_candidate = HTLCCandidate::new(msg.amount_msat, HTLCInitiator::RemoteOffered);
20722077
let local_commit_tx_fee_msat = self.next_local_commit_tx_fee_msat(htlc_candidate, None);
2073-
if self.value_to_self_msat < self.counterparty_selected_channel_reserve_satoshis * 1000 + local_commit_tx_fee_msat {
2078+
if self.value_to_self_msat < self.counterparty_selected_channel_reserve_satoshis.unwrap() * 1000 + local_commit_tx_fee_msat {
20742079
return Err(ChannelError::Close("Cannot accept HTLC that would put our balance under counterparty-announced channel reserve value".to_owned()));
20752080
}
20762081
}
@@ -3369,8 +3374,9 @@ impl<Signer: Sign> Channel<Signer> {
33693374
&self.channel_transaction_parameters.holder_pubkeys
33703375
}
33713376

3372-
fn get_counterparty_selected_contest_delay(&self) -> u16 {
3373-
self.channel_transaction_parameters.counterparty_parameters.as_ref().unwrap().selected_contest_delay
3377+
fn get_counterparty_selected_contest_delay(&self) -> Option<u16> {
3378+
self.channel_transaction_parameters.counterparty_parameters
3379+
.as_ref().map(|params| params.selected_contest_delay)
33743380
}
33753381

33763382
fn get_counterparty_pubkeys(&self) -> &ChannelPublicKeys {
@@ -3444,7 +3450,7 @@ impl<Signer: Sign> Channel<Signer> {
34443450
ChannelValueStat {
34453451
value_to_self_msat: self.value_to_self_msat,
34463452
channel_value_msat: self.channel_value_satoshis * 1000,
3447-
channel_reserve_msat: self.counterparty_selected_channel_reserve_satoshis * 1000,
3453+
channel_reserve_msat: self.counterparty_selected_channel_reserve_satoshis.unwrap() * 1000,
34483454
pending_outbound_htlcs_amount_msat: self.pending_outbound_htlcs.iter().map(|ref h| h.amount_msat).sum::<u64>(),
34493455
pending_inbound_htlcs_amount_msat: self.pending_inbound_htlcs.iter().map(|ref h| h.amount_msat).sum::<u64>(),
34503456
holding_cell_outbound_amount_msat: {
@@ -3561,7 +3567,7 @@ impl<Signer: Sign> Channel<Signer> {
35613567
self.funding_tx_confirmation_height = 0;
35623568
}
35633569

3564-
if funding_tx_confirmations < self.minimum_depth as i64 {
3570+
if funding_tx_confirmations < self.minimum_depth.unwrap_or(0) as i64 {
35653571
return None;
35663572
}
35673573

@@ -3716,10 +3722,10 @@ impl<Signer: Sign> Channel<Signer> {
37163722
// the funding transaction's confirmation count has dipped below minimum_depth / 2,
37173723
// close the channel and hope we can get the latest state on chain (because presumably
37183724
// the funding transaction is at least still in the mempool of most nodes).
3719-
if funding_tx_confirmations < self.minimum_depth as i64 / 2 {
3725+
if funding_tx_confirmations < self.minimum_depth.unwrap() as i64 / 2 {
37203726
return Err(msgs::ErrorMessage {
37213727
channel_id: self.channel_id(),
3722-
data: format!("Funding transaction was un-confirmed. Locked at {} confs, now have {} confs.", self.minimum_depth, funding_tx_confirmations),
3728+
data: format!("Funding transaction was un-confirmed. Locked at {} confs, now have {} confs.", self.minimum_depth.unwrap(), funding_tx_confirmations),
37233729
});
37243730
}
37253731
}
@@ -3814,7 +3820,7 @@ impl<Signer: Sign> Channel<Signer> {
38143820
max_htlc_value_in_flight_msat: Channel::<Signer>::get_holder_max_htlc_value_in_flight_msat(self.channel_value_satoshis),
38153821
channel_reserve_satoshis: Channel::<Signer>::get_holder_selected_channel_reserve_satoshis(self.channel_value_satoshis),
38163822
htlc_minimum_msat: self.holder_htlc_minimum_msat,
3817-
minimum_depth: self.minimum_depth,
3823+
minimum_depth: self.minimum_depth.unwrap(),
38183824
to_self_delay: self.get_holder_selected_contest_delay(),
38193825
max_accepted_htlcs: OUR_MAX_HTLCS,
38203826
funding_pubkey: keys.funding_pubkey,
@@ -4112,7 +4118,7 @@ impl<Signer: Sign> Channel<Signer> {
41124118

41134119
// Check self.counterparty_selected_channel_reserve_satoshis (the amount we must keep as
41144120
// reserve for the remote to have something to claim if we misbehave)
4115-
let chan_reserve_msat = self.counterparty_selected_channel_reserve_satoshis * 1000;
4121+
let chan_reserve_msat = self.counterparty_selected_channel_reserve_satoshis.unwrap() * 1000;
41164122
if pending_value_to_self_msat - amount_msat - commit_tx_fee_msat < chan_reserve_msat {
41174123
return Err(ChannelError::Ignore(format!("Cannot send value that would put our balance under counterparty-announced channel reserve value ({})", chan_reserve_msat)));
41184124
}
@@ -4317,8 +4323,7 @@ impl<Signer: Sign> Channel<Signer> {
43174323
}
43184324

43194325
pub fn channel_update(&mut self, msg: &msgs::ChannelUpdate) -> Result<(), ChannelError> {
4320-
let usable_channel_value_msat = (self.channel_value_satoshis - self.counterparty_selected_channel_reserve_satoshis) * 1000;
4321-
if msg.contents.htlc_minimum_msat >= usable_channel_value_msat {
4326+
if msg.contents.htlc_minimum_msat >= self.channel_value_satoshis * 1000 {
43224327
return Err(ChannelError::Close("Minimum htlc value is greater than channel value".to_string()));
43234328
}
43244329
self.counterparty_forwarding_info = Some(CounterpartyForwardingInfo {
@@ -4646,11 +4651,11 @@ impl<Signer: Sign> Writeable for Channel<Signer> {
46464651
self.counterparty_dust_limit_satoshis.write(writer)?;
46474652
self.holder_dust_limit_satoshis.write(writer)?;
46484653
self.counterparty_max_htlc_value_in_flight_msat.write(writer)?;
4649-
self.counterparty_selected_channel_reserve_satoshis.write(writer)?;
4654+
self.counterparty_selected_channel_reserve_satoshis.unwrap_or(0).write(writer)?;
46504655
self.counterparty_htlc_minimum_msat.write(writer)?;
46514656
self.holder_htlc_minimum_msat.write(writer)?;
46524657
self.counterparty_max_accepted_htlcs.write(writer)?;
4653-
self.minimum_depth.write(writer)?;
4658+
self.minimum_depth.unwrap_or(0).write(writer)?;
46544659

46554660
match &self.counterparty_forwarding_info {
46564661
Some(info) => {
@@ -4675,7 +4680,17 @@ impl<Signer: Sign> Writeable for Channel<Signer> {
46754680

46764681
self.channel_update_status.write(writer)?;
46774682

4678-
write_tlv_fields!(writer, {(0, self.announcement_sigs, option)});
4683+
write_tlv_fields!(writer, {
4684+
(0, self.announcement_sigs, option),
4685+
// minimum_depth and counterparty_selected_channel_reserve_satoshis used to have a
4686+
// default value instead of being Option<>al. Thus, to maintain compatibility we write
4687+
// them twice, once with their original default values above, and once as an option
4688+
// here. On the read side, old versions will simply ignore the odd-type entries here,
4689+
// and new versions map the default values to None and allow the TLV entries here to
4690+
// override that.
4691+
(1, self.minimum_depth, option),
4692+
(3, self.counterparty_selected_channel_reserve_satoshis, option),
4693+
});
46794694

46804695
Ok(())
46814696
}
@@ -4818,11 +4833,21 @@ impl<'a, Signer: Sign, K: Deref> ReadableArgs<&'a K> for Channel<Signer>
48184833
let counterparty_dust_limit_satoshis = Readable::read(reader)?;
48194834
let holder_dust_limit_satoshis = Readable::read(reader)?;
48204835
let counterparty_max_htlc_value_in_flight_msat = Readable::read(reader)?;
4821-
let counterparty_selected_channel_reserve_satoshis = Readable::read(reader)?;
4836+
let mut counterparty_selected_channel_reserve_satoshis = Some(Readable::read(reader)?);
4837+
if counterparty_selected_channel_reserve_satoshis == Some(0) {
4838+
// Versions up to 0.0.98 had counterparty_selected_channel_reserve_satoshis as a
4839+
// non-option, writing 0 for what we now consider None.
4840+
counterparty_selected_channel_reserve_satoshis = None;
4841+
}
48224842
let counterparty_htlc_minimum_msat = Readable::read(reader)?;
48234843
let holder_htlc_minimum_msat = Readable::read(reader)?;
48244844
let counterparty_max_accepted_htlcs = Readable::read(reader)?;
4825-
let minimum_depth = Readable::read(reader)?;
4845+
let mut minimum_depth = Some(Readable::read(reader)?);
4846+
if minimum_depth == Some(0) {
4847+
// Versions up to 0.0.98 had minimum_depth as a non-option, writing 0 for what we now
4848+
// consider None.
4849+
minimum_depth = None;
4850+
}
48264851

48274852
let counterparty_forwarding_info = match <u8 as Readable>::read(reader)? {
48284853
0 => None,
@@ -4848,7 +4873,11 @@ impl<'a, Signer: Sign, K: Deref> ReadableArgs<&'a K> for Channel<Signer>
48484873
let channel_update_status = Readable::read(reader)?;
48494874

48504875
let mut announcement_sigs = None;
4851-
read_tlv_fields!(reader, {(0, announcement_sigs, option)});
4876+
read_tlv_fields!(reader, {
4877+
(0, announcement_sigs, option),
4878+
(1, minimum_depth, option),
4879+
(3, counterparty_selected_channel_reserve_satoshis, option),
4880+
});
48524881

48534882
let mut secp_ctx = Secp256k1::new();
48544883
secp_ctx.seeded_randomize(&keys_source.get_secure_random_bytes());
@@ -5303,6 +5332,7 @@ mod tests {
53035332
config.channel_options.announced_channel = false;
53045333
let mut chan = Channel::<InMemorySigner>::new_outbound(&&feeest, &&keys_provider, counterparty_node_id, 10_000_000, 100000, 42, &config).unwrap(); // Nothing uses their network key in this test
53055334
chan.holder_dust_limit_satoshis = 546;
5335+
chan.counterparty_selected_channel_reserve_satoshis = Some(0); // Filled in in accept_channel
53065336

53075337
let funding_info = OutPoint{ txid: Txid::from_hex("8984484a580b825b9972d7adb15050b3ab624ccd731946b3eeddb92f4e7ef6be").unwrap(), index: 0 };
53085338

0 commit comments

Comments
 (0)