Skip to content

Commit 7d86cde

Browse files
committed
Handle fallible commitment point when getting open_channel message
1 parent a60f761 commit 7d86cde

File tree

2 files changed

+73
-41
lines changed

2 files changed

+73
-41
lines changed

lightning/src/ln/channel.rs

Lines changed: 55 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -7631,6 +7631,12 @@ impl<SP: Deref> Channel<SP> where
76317631
pub(super) struct OutboundV1Channel<SP: Deref> where SP::Target: SignerProvider {
76327632
pub context: ChannelContext<SP>,
76337633
pub unfunded_context: UnfundedChannelContext,
7634+
/// We tried to send a `open_channel` message but our commitment point wasn't ready.
7635+
/// This flag tells us we need to send it when we are retried once the
7636+
/// commiment point is ready.
7637+
///
7638+
/// TODO: don't need to persist this since we'll send open_channel again on connect?
7639+
pub signer_pending_open_channel: bool,
76347640
}
76357641

76367642
impl<SP: Deref> OutboundV1Channel<SP> where SP::Target: SignerProvider {
@@ -7675,7 +7681,8 @@ impl<SP: Deref> OutboundV1Channel<SP> where SP::Target: SignerProvider {
76757681
pubkeys,
76767682
logger,
76777683
)?,
7678-
unfunded_context: UnfundedChannelContext { unfunded_channel_age_ticks: 0 }
7684+
unfunded_context: UnfundedChannelContext { unfunded_channel_age_ticks: 0 },
7685+
signer_pending_open_channel: false,
76797686
};
76807687
Ok(chan)
76817688
}
@@ -7774,14 +7781,15 @@ impl<SP: Deref> OutboundV1Channel<SP> where SP::Target: SignerProvider {
77747781
/// If we receive an error message, it may only be a rejection of the channel type we tried,
77757782
/// not of our ability to open any channel at all. Thus, on error, we should first call this
77767783
/// and see if we get a new `OpenChannel` message, otherwise the channel is failed.
7777-
pub(crate) fn maybe_handle_error_without_close<F: Deref>(
7778-
&mut self, chain_hash: ChainHash, fee_estimator: &LowerBoundedFeeEstimator<F>
7784+
pub(crate) fn maybe_handle_error_without_close<F: Deref, L: Deref>(
7785+
&mut self, chain_hash: ChainHash, fee_estimator: &LowerBoundedFeeEstimator<F>, logger: &L
77797786
) -> Result<msgs::OpenChannel, ()>
77807787
where
7781-
F::Target: FeeEstimator
7788+
F::Target: FeeEstimator,
7789+
L::Target: Logger,
77827790
{
77837791
self.context.maybe_downgrade_channel_features(fee_estimator)?;
7784-
Ok(self.get_open_channel(chain_hash))
7792+
self.get_open_channel(chain_hash, logger).ok_or(())
77857793
}
77867794

77877795
/// Returns true if we can resume the channel by sending the [`msgs::OpenChannel`] again.
@@ -7790,7 +7798,9 @@ impl<SP: Deref> OutboundV1Channel<SP> where SP::Target: SignerProvider {
77907798
self.context.holder_commitment_point.transaction_number() == INITIAL_COMMITMENT_NUMBER
77917799
}
77927800

7793-
pub fn get_open_channel(&self, chain_hash: ChainHash) -> msgs::OpenChannel {
7801+
pub fn get_open_channel<L: Deref>(&mut self, chain_hash: ChainHash, logger: &L) -> Option<msgs::OpenChannel>
7802+
where L::Target: Logger
7803+
{
77947804
if !self.context.is_outbound() {
77957805
panic!("Tried to open a channel for an inbound channel?");
77967806
}
@@ -7802,11 +7812,26 @@ impl<SP: Deref> OutboundV1Channel<SP> where SP::Target: SignerProvider {
78027812
panic!("Tried to send an open_channel for a channel that has already advanced");
78037813
}
78047814

7805-
debug_assert!(self.context.holder_commitment_point.is_available());
7806-
let first_per_commitment_point = self.context.holder_commitment_point.current_point().expect("TODO");
7815+
// Note: another option here is to make commitment point a parameter of this function
7816+
// and make a helper method get_point_for_open_channel to check + set signer_pending_open_channel
7817+
// and call that right before anytime we call this function, so this function can remain
7818+
// side-effect free.
7819+
let first_per_commitment_point = if let Some(point) = self.context.holder_commitment_point.current_point() {
7820+
self.signer_pending_open_channel = false;
7821+
point
7822+
} else {
7823+
#[cfg(not(async_signing))] {
7824+
panic!("Failed getting commitment point for open_channel message");
7825+
}
7826+
#[cfg(async_signing)] {
7827+
log_trace!(logger, "Unable to generate open_channel message, waiting for commitment point");
7828+
self.signer_pending_open_channel = true;
7829+
return None;
7830+
}
7831+
};
78077832
let keys = self.context.get_holder_pubkeys();
78087833

7809-
msgs::OpenChannel {
7834+
Some(msgs::OpenChannel {
78107835
common_fields: msgs::CommonOpenChannelFields {
78117836
chain_hash,
78127837
temporary_channel_id: self.context.channel_id,
@@ -7832,7 +7857,7 @@ impl<SP: Deref> OutboundV1Channel<SP> where SP::Target: SignerProvider {
78327857
},
78337858
push_msat: self.context.channel_value_satoshis * 1000 - self.context.value_to_self_msat,
78347859
channel_reserve_satoshis: self.context.holder_selected_channel_reserve_satoshis,
7835-
}
7860+
})
78367861
}
78377862

78387863
// Message handlers
@@ -9750,12 +9775,12 @@ mod tests {
97509775

97519776
let node_a_node_id = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42; 32]).unwrap());
97529777
let config = UserConfig::default();
9753-
let node_a_chan = OutboundV1Channel::<&TestKeysInterface>::new(&bounded_fee_estimator, &&keys_provider, &&keys_provider, node_a_node_id, &channelmanager::provided_init_features(&config), 10000000, 100000, 42, &config, 0, 42, None, &logger).unwrap();
9778+
let mut node_a_chan = OutboundV1Channel::<&TestKeysInterface>::new(&bounded_fee_estimator, &&keys_provider, &&keys_provider, node_a_node_id, &channelmanager::provided_init_features(&config), 10000000, 100000, 42, &config, 0, 42, None, &logger).unwrap();
97549779

97559780
// Now change the fee so we can check that the fee in the open_channel message is the
97569781
// same as the old fee.
97579782
fee_est.fee_est = 500;
9758-
let open_channel_msg = node_a_chan.get_open_channel(ChainHash::using_genesis_block(network));
9783+
let open_channel_msg = node_a_chan.get_open_channel(ChainHash::using_genesis_block(network), &&logger).unwrap();
97599784
assert_eq!(open_channel_msg.common_fields.commitment_feerate_sat_per_1000_weight, original_fee);
97609785
}
97619786

@@ -9781,7 +9806,7 @@ mod tests {
97819806

97829807
// Create Node B's channel by receiving Node A's open_channel message
97839808
// Make sure A's dust limit is as we expect.
9784-
let open_channel_msg = node_a_chan.get_open_channel(ChainHash::using_genesis_block(network));
9809+
let open_channel_msg = node_a_chan.get_open_channel(ChainHash::using_genesis_block(network), &&logger).unwrap();
97859810
let node_b_node_id = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[7; 32]).unwrap());
97869811
let mut node_b_chan = InboundV1Channel::<&TestKeysInterface>::new(&feeest, &&keys_provider, &&keys_provider, node_b_node_id, &channelmanager::provided_channel_type_features(&config), &channelmanager::provided_init_features(&config), &open_channel_msg, 7, &config, 0, &&logger, /*is_0conf=*/false).unwrap();
97879812

@@ -9913,7 +9938,7 @@ mod tests {
99139938
let mut node_a_chan = OutboundV1Channel::<&TestKeysInterface>::new(&feeest, &&keys_provider, &&keys_provider, node_b_node_id, &channelmanager::provided_init_features(&config), 10000000, 100000, 42, &config, 0, 42, None, &logger).unwrap();
99149939

99159940
// Create Node B's channel by receiving Node A's open_channel message
9916-
let open_channel_msg = node_a_chan.get_open_channel(chain_hash);
9941+
let open_channel_msg = node_a_chan.get_open_channel(chain_hash, &&logger).unwrap();
99179942
let node_b_node_id = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[7; 32]).unwrap());
99189943
let mut node_b_chan = InboundV1Channel::<&TestKeysInterface>::new(&feeest, &&keys_provider, &&keys_provider, node_b_node_id, &channelmanager::provided_channel_type_features(&config), &channelmanager::provided_init_features(&config), &open_channel_msg, 7, &config, 0, &&logger, /*is_0conf=*/false).unwrap();
99199944

@@ -9974,7 +9999,7 @@ mod tests {
99749999
// Test that `OutboundV1Channel::new` creates a channel with the correct value for
997510000
// `holder_max_htlc_value_in_flight_msat`, when configured with a valid percentage value,
997610001
// which is set to the lower bound + 1 (2%) of the `channel_value`.
9977-
let chan_1 = OutboundV1Channel::<&TestKeysInterface>::new(&feeest, &&keys_provider, &&keys_provider, outbound_node_id, &channelmanager::provided_init_features(&config_2_percent), 10000000, 100000, 42, &config_2_percent, 0, 42, None, &logger).unwrap();
10002+
let mut chan_1 = OutboundV1Channel::<&TestKeysInterface>::new(&feeest, &&keys_provider, &&keys_provider, outbound_node_id, &channelmanager::provided_init_features(&config_2_percent), 10000000, 100000, 42, &config_2_percent, 0, 42, None, &logger).unwrap();
997810003
let chan_1_value_msat = chan_1.context.channel_value_satoshis * 1000;
997910004
assert_eq!(chan_1.context.holder_max_htlc_value_in_flight_msat, (chan_1_value_msat as f64 * 0.02) as u64);
998010005

@@ -9983,7 +10008,7 @@ mod tests {
998310008
let chan_2_value_msat = chan_2.context.channel_value_satoshis * 1000;
998410009
assert_eq!(chan_2.context.holder_max_htlc_value_in_flight_msat, (chan_2_value_msat as f64 * 0.99) as u64);
998510010

9986-
let chan_1_open_channel_msg = chan_1.get_open_channel(ChainHash::using_genesis_block(network));
10011+
let chan_1_open_channel_msg = chan_1.get_open_channel(ChainHash::using_genesis_block(network), &&logger).unwrap();
998710012

998810013
// Test that `InboundV1Channel::new` creates a channel with the correct value for
998910014
// `holder_max_htlc_value_in_flight_msat`, when configured with a valid percentage value,
@@ -10059,12 +10084,12 @@ mod tests {
1005910084

1006010085
let mut outbound_node_config = UserConfig::default();
1006110086
outbound_node_config.channel_handshake_config.their_channel_reserve_proportional_millionths = (outbound_selected_channel_reserve_perc * 1_000_000.0) as u32;
10062-
let chan = OutboundV1Channel::<&TestKeysInterface>::new(&&fee_est, &&keys_provider, &&keys_provider, outbound_node_id, &channelmanager::provided_init_features(&outbound_node_config), channel_value_satoshis, 100_000, 42, &outbound_node_config, 0, 42, None, &logger).unwrap();
10087+
let mut chan = OutboundV1Channel::<&TestKeysInterface>::new(&&fee_est, &&keys_provider, &&keys_provider, outbound_node_id, &channelmanager::provided_init_features(&outbound_node_config), channel_value_satoshis, 100_000, 42, &outbound_node_config, 0, 42, None, &logger).unwrap();
1006310088

1006410089
let expected_outbound_selected_chan_reserve = cmp::max(MIN_THEIR_CHAN_RESERVE_SATOSHIS, (chan.context.channel_value_satoshis as f64 * outbound_selected_channel_reserve_perc) as u64);
1006510090
assert_eq!(chan.context.holder_selected_channel_reserve_satoshis, expected_outbound_selected_chan_reserve);
1006610091

10067-
let chan_open_channel_msg = chan.get_open_channel(ChainHash::using_genesis_block(network));
10092+
let chan_open_channel_msg = chan.get_open_channel(ChainHash::using_genesis_block(network), &&logger).unwrap();
1006810093
let mut inbound_node_config = UserConfig::default();
1006910094
inbound_node_config.channel_handshake_config.their_channel_reserve_proportional_millionths = (inbound_selected_channel_reserve_perc * 1_000_000.0) as u32;
1007010095

@@ -10100,7 +10125,7 @@ mod tests {
1010010125

1010110126
// Create Node B's channel by receiving Node A's open_channel message
1010210127
// Make sure A's dust limit is as we expect.
10103-
let open_channel_msg = node_a_chan.get_open_channel(ChainHash::using_genesis_block(network));
10128+
let open_channel_msg = node_a_chan.get_open_channel(ChainHash::using_genesis_block(network), &&logger).unwrap();
1010410129
let node_b_node_id = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[7; 32]).unwrap());
1010510130
let mut node_b_chan = InboundV1Channel::<&TestKeysInterface>::new(&feeest, &&keys_provider, &&keys_provider, node_b_node_id, &channelmanager::provided_channel_type_features(&config), &channelmanager::provided_init_features(&config), &open_channel_msg, 7, &config, 0, &&logger, /*is_0conf=*/false).unwrap();
1010610131

@@ -10177,7 +10202,7 @@ mod tests {
1017710202
).unwrap();
1017810203
let inbound_chan = InboundV1Channel::<&TestKeysInterface>::new(
1017910204
&feeest, &&keys_provider, &&keys_provider, node_b_node_id, &channelmanager::provided_channel_type_features(&config),
10180-
&features, &outbound_chan.get_open_channel(ChainHash::using_genesis_block(network)), 7, &config, 0, &&logger, false
10205+
&features, &outbound_chan.get_open_channel(ChainHash::using_genesis_block(network), &&logger).unwrap(), 7, &config, 0, &&logger, false
1018110206
).unwrap();
1018210207
outbound_chan.accept_channel(&inbound_chan.get_accept_channel_message(), &config.channel_handshake_limits, &features).unwrap();
1018310208
let tx = Transaction { version: Version::ONE, lock_time: LockTime::ZERO, input: Vec::new(), output: vec![TxOut {
@@ -11075,13 +11100,13 @@ mod tests {
1107511100

1107611101
let node_b_node_id = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42; 32]).unwrap());
1107711102
let config = UserConfig::default();
11078-
let node_a_chan = OutboundV1Channel::<&TestKeysInterface>::new(&feeest, &&keys_provider, &&keys_provider,
11103+
let mut node_a_chan = OutboundV1Channel::<&TestKeysInterface>::new(&feeest, &&keys_provider, &&keys_provider,
1107911104
node_b_node_id, &channelmanager::provided_init_features(&config), 10000000, 100000, 42, &config, 0, 42, None, &logger).unwrap();
1108011105

1108111106
let mut channel_type_features = ChannelTypeFeatures::only_static_remote_key();
1108211107
channel_type_features.set_zero_conf_required();
1108311108

11084-
let mut open_channel_msg = node_a_chan.get_open_channel(ChainHash::using_genesis_block(network));
11109+
let mut open_channel_msg = node_a_chan.get_open_channel(ChainHash::using_genesis_block(network), &&logger).unwrap();
1108511110
open_channel_msg.common_fields.channel_type = Some(channel_type_features);
1108611111
let node_b_node_id = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[7; 32]).unwrap());
1108711112
let res = InboundV1Channel::<&TestKeysInterface>::new(&feeest, &&keys_provider, &&keys_provider,
@@ -11119,13 +11144,13 @@ mod tests {
1111911144
expected_channel_type.set_static_remote_key_required();
1112011145
expected_channel_type.set_anchors_zero_fee_htlc_tx_required();
1112111146

11122-
let channel_a = OutboundV1Channel::<&TestKeysInterface>::new(
11147+
let mut channel_a = OutboundV1Channel::<&TestKeysInterface>::new(
1112311148
&fee_estimator, &&keys_provider, &&keys_provider, node_id_b,
1112411149
&channelmanager::provided_init_features(&config), 10000000, 100000, 42, &config, 0, 42,
1112511150
None, &logger
1112611151
).unwrap();
1112711152

11128-
let open_channel_msg = channel_a.get_open_channel(ChainHash::using_genesis_block(network));
11153+
let open_channel_msg = channel_a.get_open_channel(ChainHash::using_genesis_block(network), &&logger).unwrap();
1112911154
let channel_b = InboundV1Channel::<&TestKeysInterface>::new(
1113011155
&fee_estimator, &&keys_provider, &&keys_provider, node_id_a,
1113111156
&channelmanager::provided_channel_type_features(&config), &channelmanager::provided_init_features(&config),
@@ -11157,14 +11182,14 @@ mod tests {
1115711182
let raw_init_features = static_remote_key_required | simple_anchors_required;
1115811183
let init_features_with_simple_anchors = InitFeatures::from_le_bytes(raw_init_features.to_le_bytes().to_vec());
1115911184

11160-
let channel_a = OutboundV1Channel::<&TestKeysInterface>::new(
11185+
let mut channel_a = OutboundV1Channel::<&TestKeysInterface>::new(
1116111186
&fee_estimator, &&keys_provider, &&keys_provider, node_id_b,
1116211187
&channelmanager::provided_init_features(&config), 10000000, 100000, 42, &config, 0, 42,
1116311188
None, &logger
1116411189
).unwrap();
1116511190

1116611191
// Set `channel_type` to `None` to force the implicit feature negotiation.
11167-
let mut open_channel_msg = channel_a.get_open_channel(ChainHash::using_genesis_block(network));
11192+
let mut open_channel_msg = channel_a.get_open_channel(ChainHash::using_genesis_block(network), &&logger).unwrap();
1116811193
open_channel_msg.common_fields.channel_type = None;
1116911194

1117011195
// Since A supports both `static_remote_key` and `option_anchors`, but B only accepts
@@ -11204,13 +11229,13 @@ mod tests {
1120411229
// First, we'll try to open a channel between A and B where A requests a channel type for
1120511230
// the original `option_anchors` feature (non zero fee htlc tx). This should be rejected by
1120611231
// B as it's not supported by LDK.
11207-
let channel_a = OutboundV1Channel::<&TestKeysInterface>::new(
11232+
let mut channel_a = OutboundV1Channel::<&TestKeysInterface>::new(
1120811233
&fee_estimator, &&keys_provider, &&keys_provider, node_id_b,
1120911234
&channelmanager::provided_init_features(&config), 10000000, 100000, 42, &config, 0, 42,
1121011235
None, &logger
1121111236
).unwrap();
1121211237

11213-
let mut open_channel_msg = channel_a.get_open_channel(ChainHash::using_genesis_block(network));
11238+
let mut open_channel_msg = channel_a.get_open_channel(ChainHash::using_genesis_block(network), &&logger).unwrap();
1121411239
open_channel_msg.common_fields.channel_type = Some(simple_anchors_channel_type.clone());
1121511240

1121611241
let res = InboundV1Channel::<&TestKeysInterface>::new(
@@ -11229,7 +11254,7 @@ mod tests {
1122911254
10000000, 100000, 42, &config, 0, 42, None, &logger
1123011255
).unwrap();
1123111256

11232-
let open_channel_msg = channel_a.get_open_channel(ChainHash::using_genesis_block(network));
11257+
let open_channel_msg = channel_a.get_open_channel(ChainHash::using_genesis_block(network), &&logger).unwrap();
1123311258

1123411259
let channel_b = InboundV1Channel::<&TestKeysInterface>::new(
1123511260
&fee_estimator, &&keys_provider, &&keys_provider, node_id_a,
@@ -11280,7 +11305,7 @@ mod tests {
1128011305
&logger
1128111306
).unwrap();
1128211307

11283-
let open_channel_msg = node_a_chan.get_open_channel(ChainHash::using_genesis_block(network));
11308+
let open_channel_msg = node_a_chan.get_open_channel(ChainHash::using_genesis_block(network), &&logger).unwrap();
1128411309
let node_b_node_id = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[7; 32]).unwrap());
1128511310
let mut node_b_chan = InboundV1Channel::<&TestKeysInterface>::new(
1128611311
&feeest,

lightning/src/ln/channelmanager.rs

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3258,7 +3258,7 @@ where
32583258
}
32593259
}
32603260

3261-
let channel = {
3261+
let mut channel = {
32623262
let outbound_scid_alias = self.create_and_insert_outbound_scid_alias();
32633263
let their_features = &peer_state.latest_features;
32643264
let config = if override_config.is_some() { override_config.as_ref().unwrap() } else { &self.default_configuration };
@@ -3273,7 +3273,8 @@ where
32733273
},
32743274
}
32753275
};
3276-
let res = channel.get_open_channel(self.chain_hash);
3276+
let logger = WithChannelContext::from(&self.logger, &channel.context, None);
3277+
let res = channel.get_open_channel(self.chain_hash, &&logger);
32773278

32783279
let temporary_channel_id = channel.context.channel_id();
32793280
match peer_state.channel_by_id.entry(temporary_channel_id) {
@@ -3287,10 +3288,12 @@ where
32873288
hash_map::Entry::Vacant(entry) => { entry.insert(ChannelPhase::UnfundedOutboundV1(channel)); }
32883289
}
32893290

3290-
peer_state.pending_msg_events.push(events::MessageSendEvent::SendOpenChannel {
3291-
node_id: their_network_key,
3292-
msg: res,
3293-
});
3291+
if let Some(msg) = res {
3292+
peer_state.pending_msg_events.push(events::MessageSendEvent::SendOpenChannel {
3293+
node_id: their_network_key,
3294+
msg,
3295+
});
3296+
}
32943297
Ok(temporary_channel_id)
32953298
}
32963299

@@ -10736,10 +10739,13 @@ where
1073610739
}
1073710740

1073810741
ChannelPhase::UnfundedOutboundV1(chan) => {
10739-
pending_msg_events.push(events::MessageSendEvent::SendOpenChannel {
10740-
node_id: chan.context.get_counterparty_node_id(),
10741-
msg: chan.get_open_channel(self.chain_hash),
10742-
});
10742+
let logger = WithChannelContext::from(&self.logger, &chan.context, None);
10743+
if let Some(msg) = chan.get_open_channel(self.chain_hash, &&logger) {
10744+
pending_msg_events.push(events::MessageSendEvent::SendOpenChannel {
10745+
node_id: chan.context.get_counterparty_node_id(),
10746+
msg,
10747+
});
10748+
}
1074310749
}
1074410750

1074510751
// TODO(dual_funding): Combine this match arm with above once #[cfg(any(dual_funding, splicing))] is removed.
@@ -10854,7 +10860,8 @@ where
1085410860
let peer_state = &mut *peer_state_lock;
1085510861
match peer_state.channel_by_id.get_mut(&msg.channel_id) {
1085610862
Some(ChannelPhase::UnfundedOutboundV1(ref mut chan)) => {
10857-
if let Ok(msg) = chan.maybe_handle_error_without_close(self.chain_hash, &self.fee_estimator) {
10863+
let logger = WithChannelContext::from(&self.logger, &chan.context, None);
10864+
if let Ok(msg) = chan.maybe_handle_error_without_close(self.chain_hash, &self.fee_estimator, &&logger) {
1085810865
peer_state.pending_msg_events.push(events::MessageSendEvent::SendOpenChannel {
1085910866
node_id: counterparty_node_id,
1086010867
msg,

0 commit comments

Comments
 (0)