Skip to content

Commit 44f61af

Browse files
committed
Handle fallible commitment point when getting open_channel message
1 parent 9aca427 commit 44f61af

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
@@ -7587,6 +7587,12 @@ impl<SP: Deref> Channel<SP> where
75877587
pub(super) struct OutboundV1Channel<SP: Deref> where SP::Target: SignerProvider {
75887588
pub context: ChannelContext<SP>,
75897589
pub unfunded_context: UnfundedChannelContext,
7590+
/// We tried to send a `open_channel` message but our commitment point wasn't ready.
7591+
/// This flag tells us we need to send it when we are retried once the
7592+
/// commiment point is ready.
7593+
///
7594+
/// TODO: don't need to persist this since we'll send open_channel again on connect?
7595+
pub signer_pending_open_channel: bool,
75907596
}
75917597

75927598
impl<SP: Deref> OutboundV1Channel<SP> where SP::Target: SignerProvider {
@@ -7631,7 +7637,8 @@ impl<SP: Deref> OutboundV1Channel<SP> where SP::Target: SignerProvider {
76317637
pubkeys,
76327638
logger,
76337639
)?,
7634-
unfunded_context: UnfundedChannelContext { unfunded_channel_age_ticks: 0 }
7640+
unfunded_context: UnfundedChannelContext { unfunded_channel_age_ticks: 0 },
7641+
signer_pending_open_channel: false,
76357642
};
76367643
Ok(chan)
76377644
}
@@ -7730,14 +7737,15 @@ impl<SP: Deref> OutboundV1Channel<SP> where SP::Target: SignerProvider {
77307737
/// If we receive an error message, it may only be a rejection of the channel type we tried,
77317738
/// not of our ability to open any channel at all. Thus, on error, we should first call this
77327739
/// and see if we get a new `OpenChannel` message, otherwise the channel is failed.
7733-
pub(crate) fn maybe_handle_error_without_close<F: Deref>(
7734-
&mut self, chain_hash: ChainHash, fee_estimator: &LowerBoundedFeeEstimator<F>
7740+
pub(crate) fn maybe_handle_error_without_close<F: Deref, L: Deref>(
7741+
&mut self, chain_hash: ChainHash, fee_estimator: &LowerBoundedFeeEstimator<F>, logger: &L
77357742
) -> Result<msgs::OpenChannel, ()>
77367743
where
7737-
F::Target: FeeEstimator
7744+
F::Target: FeeEstimator,
7745+
L::Target: Logger,
77387746
{
77397747
self.context.maybe_downgrade_channel_features(fee_estimator)?;
7740-
Ok(self.get_open_channel(chain_hash))
7748+
self.get_open_channel(chain_hash, logger).ok_or(())
77417749
}
77427750

77437751
/// Returns true if we can resume the channel by sending the [`msgs::OpenChannel`] again.
@@ -7746,7 +7754,9 @@ impl<SP: Deref> OutboundV1Channel<SP> where SP::Target: SignerProvider {
77467754
self.context.holder_commitment_point.transaction_number() == INITIAL_COMMITMENT_NUMBER
77477755
}
77487756

7749-
pub fn get_open_channel(&self, chain_hash: ChainHash) -> msgs::OpenChannel {
7757+
pub fn get_open_channel<L: Deref>(&mut self, chain_hash: ChainHash, logger: &L) -> Option<msgs::OpenChannel>
7758+
where L::Target: Logger
7759+
{
77507760
if !self.context.is_outbound() {
77517761
panic!("Tried to open a channel for an inbound channel?");
77527762
}
@@ -7758,11 +7768,26 @@ impl<SP: Deref> OutboundV1Channel<SP> where SP::Target: SignerProvider {
77587768
panic!("Tried to send an open_channel for a channel that has already advanced");
77597769
}
77607770

7761-
debug_assert!(self.context.holder_commitment_point.is_available());
7762-
let first_per_commitment_point = self.context.holder_commitment_point.current_point().expect("TODO");
7771+
// Note: another option here is to make commitment point a parameter of this function
7772+
// and make a helper method get_point_for_open_channel to check + set signer_pending_open_channel
7773+
// and call that right before anytime we call this function, so this function can remain
7774+
// side-effect free.
7775+
let first_per_commitment_point = if let Some(point) = self.context.holder_commitment_point.current_point() {
7776+
self.signer_pending_open_channel = false;
7777+
point
7778+
} else {
7779+
#[cfg(not(async_signing))] {
7780+
panic!("Failed getting commitment point for open_channel message");
7781+
}
7782+
#[cfg(async_signing)] {
7783+
log_trace!(logger, "Unable to generate open_channel message, waiting for commitment point");
7784+
self.signer_pending_open_channel = true;
7785+
return None;
7786+
}
7787+
};
77637788
let keys = self.context.get_holder_pubkeys();
77647789

7765-
msgs::OpenChannel {
7790+
Some(msgs::OpenChannel {
77667791
common_fields: msgs::CommonOpenChannelFields {
77677792
chain_hash,
77687793
temporary_channel_id: self.context.channel_id,
@@ -7788,7 +7813,7 @@ impl<SP: Deref> OutboundV1Channel<SP> where SP::Target: SignerProvider {
77887813
},
77897814
push_msat: self.context.channel_value_satoshis * 1000 - self.context.value_to_self_msat,
77907815
channel_reserve_satoshis: self.context.holder_selected_channel_reserve_satoshis,
7791-
}
7816+
})
77927817
}
77937818

77947819
// Message handlers
@@ -9693,12 +9718,12 @@ mod tests {
96939718

96949719
let node_a_node_id = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42; 32]).unwrap());
96959720
let config = UserConfig::default();
9696-
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();
9721+
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();
96979722

96989723
// Now change the fee so we can check that the fee in the open_channel message is the
96999724
// same as the old fee.
97009725
fee_est.fee_est = 500;
9701-
let open_channel_msg = node_a_chan.get_open_channel(ChainHash::using_genesis_block(network));
9726+
let open_channel_msg = node_a_chan.get_open_channel(ChainHash::using_genesis_block(network), &&logger).unwrap();
97029727
assert_eq!(open_channel_msg.common_fields.commitment_feerate_sat_per_1000_weight, original_fee);
97039728
}
97049729

@@ -9724,7 +9749,7 @@ mod tests {
97249749

97259750
// Create Node B's channel by receiving Node A's open_channel message
97269751
// Make sure A's dust limit is as we expect.
9727-
let open_channel_msg = node_a_chan.get_open_channel(ChainHash::using_genesis_block(network));
9752+
let open_channel_msg = node_a_chan.get_open_channel(ChainHash::using_genesis_block(network), &&logger).unwrap();
97289753
let node_b_node_id = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[7; 32]).unwrap());
97299754
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();
97309755

@@ -9856,7 +9881,7 @@ mod tests {
98569881
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();
98579882

98589883
// Create Node B's channel by receiving Node A's open_channel message
9859-
let open_channel_msg = node_a_chan.get_open_channel(chain_hash);
9884+
let open_channel_msg = node_a_chan.get_open_channel(chain_hash, &&logger).unwrap();
98609885
let node_b_node_id = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[7; 32]).unwrap());
98619886
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();
98629887

@@ -9917,7 +9942,7 @@ mod tests {
99179942
// Test that `OutboundV1Channel::new` creates a channel with the correct value for
99189943
// `holder_max_htlc_value_in_flight_msat`, when configured with a valid percentage value,
99199944
// which is set to the lower bound + 1 (2%) of the `channel_value`.
9920-
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();
9945+
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();
99219946
let chan_1_value_msat = chan_1.context.channel_value_satoshis * 1000;
99229947
assert_eq!(chan_1.context.holder_max_htlc_value_in_flight_msat, (chan_1_value_msat as f64 * 0.02) as u64);
99239948

@@ -9926,7 +9951,7 @@ mod tests {
99269951
let chan_2_value_msat = chan_2.context.channel_value_satoshis * 1000;
99279952
assert_eq!(chan_2.context.holder_max_htlc_value_in_flight_msat, (chan_2_value_msat as f64 * 0.99) as u64);
99289953

9929-
let chan_1_open_channel_msg = chan_1.get_open_channel(ChainHash::using_genesis_block(network));
9954+
let chan_1_open_channel_msg = chan_1.get_open_channel(ChainHash::using_genesis_block(network), &&logger).unwrap();
99309955

99319956
// Test that `InboundV1Channel::new` creates a channel with the correct value for
99329957
// `holder_max_htlc_value_in_flight_msat`, when configured with a valid percentage value,
@@ -10002,12 +10027,12 @@ mod tests {
1000210027

1000310028
let mut outbound_node_config = UserConfig::default();
1000410029
outbound_node_config.channel_handshake_config.their_channel_reserve_proportional_millionths = (outbound_selected_channel_reserve_perc * 1_000_000.0) as u32;
10005-
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();
10030+
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();
1000610031

1000710032
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);
1000810033
assert_eq!(chan.context.holder_selected_channel_reserve_satoshis, expected_outbound_selected_chan_reserve);
1000910034

10010-
let chan_open_channel_msg = chan.get_open_channel(ChainHash::using_genesis_block(network));
10035+
let chan_open_channel_msg = chan.get_open_channel(ChainHash::using_genesis_block(network), &&logger).unwrap();
1001110036
let mut inbound_node_config = UserConfig::default();
1001210037
inbound_node_config.channel_handshake_config.their_channel_reserve_proportional_millionths = (inbound_selected_channel_reserve_perc * 1_000_000.0) as u32;
1001310038

@@ -10043,7 +10068,7 @@ mod tests {
1004310068

1004410069
// Create Node B's channel by receiving Node A's open_channel message
1004510070
// Make sure A's dust limit is as we expect.
10046-
let open_channel_msg = node_a_chan.get_open_channel(ChainHash::using_genesis_block(network));
10071+
let open_channel_msg = node_a_chan.get_open_channel(ChainHash::using_genesis_block(network), &&logger).unwrap();
1004710072
let node_b_node_id = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[7; 32]).unwrap());
1004810073
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();
1004910074

@@ -10120,7 +10145,7 @@ mod tests {
1012010145
).unwrap();
1012110146
let inbound_chan = InboundV1Channel::<&TestKeysInterface>::new(
1012210147
&feeest, &&keys_provider, &&keys_provider, node_b_node_id, &channelmanager::provided_channel_type_features(&config),
10123-
&features, &outbound_chan.get_open_channel(ChainHash::using_genesis_block(network)), 7, &config, 0, &&logger, false
10148+
&features, &outbound_chan.get_open_channel(ChainHash::using_genesis_block(network), &&logger).unwrap(), 7, &config, 0, &&logger, false
1012410149
).unwrap();
1012510150
outbound_chan.accept_channel(&inbound_chan.get_accept_channel_message(), &config.channel_handshake_limits, &features).unwrap();
1012610151
let tx = Transaction { version: Version::ONE, lock_time: LockTime::ZERO, input: Vec::new(), output: vec![TxOut {
@@ -11016,13 +11041,13 @@ mod tests {
1101611041

1101711042
let node_b_node_id = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42; 32]).unwrap());
1101811043
let config = UserConfig::default();
11019-
let node_a_chan = OutboundV1Channel::<&TestKeysInterface>::new(&feeest, &&keys_provider, &&keys_provider,
11044+
let mut node_a_chan = OutboundV1Channel::<&TestKeysInterface>::new(&feeest, &&keys_provider, &&keys_provider,
1102011045
node_b_node_id, &channelmanager::provided_init_features(&config), 10000000, 100000, 42, &config, 0, 42, None, &logger).unwrap();
1102111046

1102211047
let mut channel_type_features = ChannelTypeFeatures::only_static_remote_key();
1102311048
channel_type_features.set_zero_conf_required();
1102411049

11025-
let mut open_channel_msg = node_a_chan.get_open_channel(ChainHash::using_genesis_block(network));
11050+
let mut open_channel_msg = node_a_chan.get_open_channel(ChainHash::using_genesis_block(network), &&logger).unwrap();
1102611051
open_channel_msg.common_fields.channel_type = Some(channel_type_features);
1102711052
let node_b_node_id = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[7; 32]).unwrap());
1102811053
let res = InboundV1Channel::<&TestKeysInterface>::new(&feeest, &&keys_provider, &&keys_provider,
@@ -11060,13 +11085,13 @@ mod tests {
1106011085
expected_channel_type.set_static_remote_key_required();
1106111086
expected_channel_type.set_anchors_zero_fee_htlc_tx_required();
1106211087

11063-
let channel_a = OutboundV1Channel::<&TestKeysInterface>::new(
11088+
let mut channel_a = OutboundV1Channel::<&TestKeysInterface>::new(
1106411089
&fee_estimator, &&keys_provider, &&keys_provider, node_id_b,
1106511090
&channelmanager::provided_init_features(&config), 10000000, 100000, 42, &config, 0, 42,
1106611091
None, &logger
1106711092
).unwrap();
1106811093

11069-
let open_channel_msg = channel_a.get_open_channel(ChainHash::using_genesis_block(network));
11094+
let open_channel_msg = channel_a.get_open_channel(ChainHash::using_genesis_block(network), &&logger).unwrap();
1107011095
let channel_b = InboundV1Channel::<&TestKeysInterface>::new(
1107111096
&fee_estimator, &&keys_provider, &&keys_provider, node_id_a,
1107211097
&channelmanager::provided_channel_type_features(&config), &channelmanager::provided_init_features(&config),
@@ -11098,14 +11123,14 @@ mod tests {
1109811123
let raw_init_features = static_remote_key_required | simple_anchors_required;
1109911124
let init_features_with_simple_anchors = InitFeatures::from_le_bytes(raw_init_features.to_le_bytes().to_vec());
1110011125

11101-
let channel_a = OutboundV1Channel::<&TestKeysInterface>::new(
11126+
let mut channel_a = OutboundV1Channel::<&TestKeysInterface>::new(
1110211127
&fee_estimator, &&keys_provider, &&keys_provider, node_id_b,
1110311128
&channelmanager::provided_init_features(&config), 10000000, 100000, 42, &config, 0, 42,
1110411129
None, &logger
1110511130
).unwrap();
1110611131

1110711132
// Set `channel_type` to `None` to force the implicit feature negotiation.
11108-
let mut open_channel_msg = channel_a.get_open_channel(ChainHash::using_genesis_block(network));
11133+
let mut open_channel_msg = channel_a.get_open_channel(ChainHash::using_genesis_block(network), &&logger).unwrap();
1110911134
open_channel_msg.common_fields.channel_type = None;
1111011135

1111111136
// Since A supports both `static_remote_key` and `option_anchors`, but B only accepts
@@ -11145,13 +11170,13 @@ mod tests {
1114511170
// First, we'll try to open a channel between A and B where A requests a channel type for
1114611171
// the original `option_anchors` feature (non zero fee htlc tx). This should be rejected by
1114711172
// B as it's not supported by LDK.
11148-
let channel_a = OutboundV1Channel::<&TestKeysInterface>::new(
11173+
let mut channel_a = OutboundV1Channel::<&TestKeysInterface>::new(
1114911174
&fee_estimator, &&keys_provider, &&keys_provider, node_id_b,
1115011175
&channelmanager::provided_init_features(&config), 10000000, 100000, 42, &config, 0, 42,
1115111176
None, &logger
1115211177
).unwrap();
1115311178

11154-
let mut open_channel_msg = channel_a.get_open_channel(ChainHash::using_genesis_block(network));
11179+
let mut open_channel_msg = channel_a.get_open_channel(ChainHash::using_genesis_block(network), &&logger).unwrap();
1115511180
open_channel_msg.common_fields.channel_type = Some(simple_anchors_channel_type.clone());
1115611181

1115711182
let res = InboundV1Channel::<&TestKeysInterface>::new(
@@ -11170,7 +11195,7 @@ mod tests {
1117011195
10000000, 100000, 42, &config, 0, 42, None, &logger
1117111196
).unwrap();
1117211197

11173-
let open_channel_msg = channel_a.get_open_channel(ChainHash::using_genesis_block(network));
11198+
let open_channel_msg = channel_a.get_open_channel(ChainHash::using_genesis_block(network), &&logger).unwrap();
1117411199

1117511200
let channel_b = InboundV1Channel::<&TestKeysInterface>::new(
1117611201
&fee_estimator, &&keys_provider, &&keys_provider, node_id_a,
@@ -11221,7 +11246,7 @@ mod tests {
1122111246
&logger
1122211247
).unwrap();
1122311248

11224-
let open_channel_msg = node_a_chan.get_open_channel(ChainHash::using_genesis_block(network));
11249+
let open_channel_msg = node_a_chan.get_open_channel(ChainHash::using_genesis_block(network), &&logger).unwrap();
1122511250
let node_b_node_id = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[7; 32]).unwrap());
1122611251
let mut node_b_chan = InboundV1Channel::<&TestKeysInterface>::new(
1122711252
&feeest,

lightning/src/ln/channelmanager.rs

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3105,7 +3105,7 @@ where
31053105
}
31063106
}
31073107

3108-
let channel = {
3108+
let mut channel = {
31093109
let outbound_scid_alias = self.create_and_insert_outbound_scid_alias();
31103110
let their_features = &peer_state.latest_features;
31113111
let config = if override_config.is_some() { override_config.as_ref().unwrap() } else { &self.default_configuration };
@@ -3120,7 +3120,8 @@ where
31203120
},
31213121
}
31223122
};
3123-
let res = channel.get_open_channel(self.chain_hash);
3123+
let logger = WithChannelContext::from(&self.logger, &channel.context, None);
3124+
let res = channel.get_open_channel(self.chain_hash, &&logger);
31243125

31253126
let temporary_channel_id = channel.context.channel_id();
31263127
match peer_state.channel_by_id.entry(temporary_channel_id) {
@@ -3134,10 +3135,12 @@ where
31343135
hash_map::Entry::Vacant(entry) => { entry.insert(ChannelPhase::UnfundedOutboundV1(channel)); }
31353136
}
31363137

3137-
peer_state.pending_msg_events.push(events::MessageSendEvent::SendOpenChannel {
3138-
node_id: their_network_key,
3139-
msg: res,
3140-
});
3138+
if let Some(msg) = res {
3139+
peer_state.pending_msg_events.push(events::MessageSendEvent::SendOpenChannel {
3140+
node_id: their_network_key,
3141+
msg,
3142+
});
3143+
}
31413144
Ok(temporary_channel_id)
31423145
}
31433146

@@ -10334,10 +10337,13 @@ where
1033410337
}
1033510338

1033610339
ChannelPhase::UnfundedOutboundV1(chan) => {
10337-
pending_msg_events.push(events::MessageSendEvent::SendOpenChannel {
10338-
node_id: chan.context.get_counterparty_node_id(),
10339-
msg: chan.get_open_channel(self.chain_hash),
10340-
});
10340+
let logger = WithChannelContext::from(&self.logger, &chan.context, None);
10341+
if let Some(msg) = chan.get_open_channel(self.chain_hash, &&logger) {
10342+
pending_msg_events.push(events::MessageSendEvent::SendOpenChannel {
10343+
node_id: chan.context.get_counterparty_node_id(),
10344+
msg,
10345+
});
10346+
}
1034110347
}
1034210348

1034310349
// TODO(dual_funding): Combine this match arm with above once #[cfg(any(dual_funding, splicing))] is removed.
@@ -10452,7 +10458,8 @@ where
1045210458
let peer_state = &mut *peer_state_lock;
1045310459
match peer_state.channel_by_id.get_mut(&msg.channel_id) {
1045410460
Some(ChannelPhase::UnfundedOutboundV1(ref mut chan)) => {
10455-
if let Ok(msg) = chan.maybe_handle_error_without_close(self.chain_hash, &self.fee_estimator) {
10461+
let logger = WithChannelContext::from(&self.logger, &chan.context, None);
10462+
if let Ok(msg) = chan.maybe_handle_error_without_close(self.chain_hash, &self.fee_estimator, &&logger) {
1045610463
peer_state.pending_msg_events.push(events::MessageSendEvent::SendOpenChannel {
1045710464
node_id: *counterparty_node_id,
1045810465
msg,

0 commit comments

Comments
 (0)