Skip to content

Commit d529d7b

Browse files
Support manual signaling of channel readiness
1 parent 2d213a4 commit d529d7b

File tree

4 files changed

+160
-3
lines changed

4 files changed

+160
-3
lines changed

lightning/src/ln/channel.rs

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -612,6 +612,14 @@ pub(super) struct Channel<Signer: ChannelSigner> {
612612
/// `accept_inbound_channel`, and `funding_created` should therefore not execute successfully.
613613
inbound_awaiting_accept: bool,
614614

615+
/// A flag that indicates whether the channel requires the user to signal readiness to send
616+
/// the `msgs::ChannelReady` message. This is only set to true if the channel was created with a
617+
/// `ChannelHandshakeConfig::manually_signal_channel_ready` flag set to true.
618+
///
619+
/// When a user signals readiness via `ChannelManager::signal_channel_readiness` this flag is
620+
/// flipped to false.
621+
requires_manual_readiness_signal: bool,
622+
615623
/// The hash of the block in which the funding transaction was included.
616624
funding_tx_confirmed_in: Option<BlockHash>,
617625
funding_tx_confirmation_height: u32,
@@ -1049,6 +1057,7 @@ impl<Signer: WriteableEcdsaChannelSigner> Channel<Signer> {
10491057
target_closing_feerate_sats_per_kw: None,
10501058

10511059
inbound_awaiting_accept: false,
1060+
requires_manual_readiness_signal: config.channel_handshake_config.manually_signal_channel_ready,
10521061

10531062
funding_tx_confirmed_in: None,
10541063
funding_tx_confirmation_height: 0,
@@ -1393,6 +1402,7 @@ impl<Signer: WriteableEcdsaChannelSigner> Channel<Signer> {
13931402
target_closing_feerate_sats_per_kw: None,
13941403

13951404
inbound_awaiting_accept: true,
1405+
requires_manual_readiness_signal: config.channel_handshake_config.manually_signal_channel_ready,
13961406

13971407
funding_tx_confirmed_in: None,
13981408
funding_tx_confirmation_height: 0,
@@ -4968,10 +4978,11 @@ impl<Signer: WriteableEcdsaChannelSigner> Channel<Signer> {
49684978
self.channel_update_status = status;
49694979
}
49704980

4971-
fn check_get_channel_ready(&mut self, height: u32) -> Option<msgs::ChannelReady> {
4981+
pub fn check_get_channel_ready(&mut self, height: u32) -> Option<msgs::ChannelReady> {
49724982
// Called:
49734983
// * always when a new block/transactions are confirmed with the new height
49744984
// * when funding is signed with a height of 0
4985+
// * when user calls ChannelManager::signal_channel_readiness
49754986
if self.funding_tx_confirmation_height == 0 && self.minimum_depth != Some(0) {
49764987
return None;
49774988
}
@@ -5273,6 +5284,10 @@ impl<Signer: WriteableEcdsaChannelSigner> Channel<Signer> {
52735284
self.inbound_awaiting_accept
52745285
}
52755286

5287+
pub fn requires_manual_readiness_signal(&self) -> bool {
5288+
self.requires_manual_readiness_signal
5289+
}
5290+
52765291
/// Sets this channel to accepting 0conf, must be done before `get_accept_channel`
52775292
pub fn set_0conf(&mut self) {
52785293
assert!(self.inbound_awaiting_accept);
@@ -6426,6 +6441,8 @@ impl<Signer: WriteableEcdsaChannelSigner> Writeable for Channel<Signer> {
64266441
// versions prior to 0.0.113, the u128 is serialized as two separate u64 values. Therefore,
64276442
// we write the high bytes as an option here.
64286443
let user_id_high_opt = Some((self.user_id >> 64) as u64);
6444+
6445+
let requires_manual_readiness_signal = Some(self.requires_manual_readiness_signal);
64296446

64306447
write_tlv_fields!(writer, {
64316448
(0, self.announcement_sigs, option),
@@ -6452,6 +6469,7 @@ impl<Signer: WriteableEcdsaChannelSigner> Writeable for Channel<Signer> {
64526469
(23, channel_ready_event_emitted, option),
64536470
(25, user_id_high_opt, option),
64546471
(27, self.channel_keys_id, required),
6472+
(29, requires_manual_readiness_signal, option)
64556473
});
64566474

64576475
Ok(())
@@ -6723,6 +6741,7 @@ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, u32, &'c Ch
67236741

67246742
let mut user_id_high_opt: Option<u64> = None;
67256743
let mut channel_keys_id: Option<[u8; 32]> = None;
6744+
let mut requires_manual_readiness_signal: Option<bool> = Some(false);
67266745

67276746
read_tlv_fields!(reader, {
67286747
(0, announcement_sigs, option),
@@ -6743,6 +6762,7 @@ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, u32, &'c Ch
67436762
(23, channel_ready_event_emitted, option),
67446763
(25, user_id_high_opt, option),
67456764
(27, channel_keys_id, option),
6765+
(29, requires_manual_readiness_signal, option),
67466766
});
67476767

67486768
let (channel_keys_id, holder_signer) = if let Some(channel_keys_id) = channel_keys_id {
@@ -6853,6 +6873,7 @@ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, u32, &'c Ch
68536873
target_closing_feerate_sats_per_kw,
68546874

68556875
inbound_awaiting_accept: false,
6876+
requires_manual_readiness_signal: requires_manual_readiness_signal.unwrap(),
68566877

68576878
funding_tx_confirmed_in,
68586879
funding_tx_confirmation_height,

lightning/src/ln/channelmanager.rs

Lines changed: 50 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1449,6 +1449,22 @@ macro_rules! remove_channel {
14491449
}
14501450
}
14511451

1452+
macro_rules! channel_ready_pending {
1453+
($self: ident, $pending_msg_events: expr, $channel: expr, $channel_ready_msg: expr) => {{
1454+
if $channel.requires_manual_readiness_signal() {
1455+
let mut pending_events = $self.pending_events.lock().unwrap();
1456+
pending_events.push(events::Event::PendingChannelReady {
1457+
channel_id: $channel.channel_id(),
1458+
user_channel_id: $channel.get_user_id(),
1459+
counterparty_node_id: $channel.get_counterparty_node_id(),
1460+
funding_outpoint: $channel.get_funding_txo().unwrap(),
1461+
});
1462+
} else {
1463+
send_channel_ready!($self, $pending_msg_events, $channel, $channel_ready_msg);
1464+
}
1465+
}}
1466+
}
1467+
14521468
macro_rules! send_channel_ready {
14531469
($self: ident, $pending_msg_events: expr, $channel: expr, $channel_ready_msg: expr) => {{
14541470
$pending_msg_events.push(events::MessageSendEvent::SendChannelReady {
@@ -4175,7 +4191,7 @@ where
41754191
}
41764192

41774193
if let Some(msg) = channel_ready {
4178-
send_channel_ready!(self, pending_msg_events, channel, msg);
4194+
channel_ready_pending!(self, pending_msg_events, channel, msg);
41794195
}
41804196
if let Some(msg) = announcement_sigs {
41814197
pending_msg_events.push(events::MessageSendEvent::SendAnnouncementSignatures {
@@ -4354,6 +4370,38 @@ where
43544370
Ok(())
43554371
}
43564372

4373+
/// Signals channel readiness after a [`Event::PendingChannelReady`].
4374+
///
4375+
/// The `channel_id` parameter indicates which channel should signal readiness,
4376+
/// and the `counterparty_node_id` parameter is the id of the peer the channel is with.
4377+
///
4378+
/// [`Event::PendingChannelReady`]: events::Event::PendingChannelReady
4379+
pub fn signal_channel_readiness(&self, channel_id: &[u8; 32], counterparty_node_id: &PublicKey) -> Result<(), APIError> {
4380+
let _persistence_guard = PersistenceNotifierGuard::notify_on_drop(&self.total_consistency_lock, &self.persistence_notifier);
4381+
4382+
let per_peer_state = self.per_peer_state.read().unwrap();
4383+
let peer_state_mutex = per_peer_state.get(counterparty_node_id)
4384+
.ok_or_else(|| APIError::ChannelUnavailable { err: format!("Can't find a peer matching the passed counterparty node_id {}", counterparty_node_id) })?;
4385+
let mut peer_state_lock = peer_state_mutex.lock().unwrap();
4386+
let peer_state = &mut *peer_state_lock;
4387+
let pending_msg_events = &mut peer_state.pending_msg_events;
4388+
match peer_state.channel_by_id.entry(channel_id.clone()) {
4389+
hash_map::Entry::Occupied(mut channel) => {
4390+
let best_block_height = self.best_block.read().unwrap().height();
4391+
let channel = channel.get_mut();
4392+
match channel.check_get_channel_ready(best_block_height) {
4393+
Some(channel_ready) => send_channel_ready!(self, pending_msg_events, channel, channel_ready),
4394+
None => return Err(APIError::APIMisuseError { err: "The channel isn't currently in a state where we can signal readiness.".to_owned() })
4395+
}
4396+
}
4397+
hash_map::Entry::Vacant(_) => {
4398+
return Err(APIError::ChannelUnavailable { err: format!("Channel with id {} not found for the passed counterparty node_id {}", log_bytes!(*channel_id), counterparty_node_id) });
4399+
}
4400+
}
4401+
4402+
Ok(())
4403+
}
4404+
43574405
/// Gets the number of peers which match the given filter and do not have any funded, outbound,
43584406
/// or 0-conf channels.
43594407
///
@@ -5953,7 +6001,7 @@ where
59536001
HTLCDestination::NextHopChannel { node_id: Some(channel.get_counterparty_node_id()), channel_id: channel.channel_id() }));
59546002
}
59556003
if let Some(channel_ready) = channel_ready_opt {
5956-
send_channel_ready!(self, pending_msg_events, channel, channel_ready);
6004+
channel_ready_pending!(self, pending_msg_events, channel, channel_ready);
59576005
if channel.is_usable() {
59586006
log_trace!(self.logger, "Sending channel_ready with private initial channel_update for our counterparty on channel {}", log_bytes!(channel.channel_id()));
59596007
if let Ok(msg) = self.get_channel_update_for_unicast(channel) {

lightning/src/util/config.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,17 @@ pub struct ChannelHandshakeConfig {
149149
/// Maximum value: 1,000,000, any values larger than 1 Million will be treated as 1 Million (or 100%)
150150
/// instead, although channel negotiations will fail in that case.
151151
pub their_channel_reserve_proportional_millionths: u32,
152+
/// If this is set to true, the user needs to manually signal readiness for an inbound channel.
153+
///
154+
/// When set to true, [`Event::PendingChannelReady`] will be triggered once LDK has seen sufficient
155+
/// confirmations of the funding transaction. In that case, a [`msgs::ChannelReady`] message will not be
156+
/// sent to the counterparty node unless the user explicitly chooses to signal readiness.
157+
///
158+
/// Default value: false.
159+
///
160+
/// [`Event::PendingChannelReady`]: crate::util::events::Event::PendingChannelReady
161+
/// [`msgs::ChannelReady`]: crate::ln::msgs::ChannelReady
162+
pub manually_signal_channel_ready: bool,
152163
#[cfg(anchors)]
153164
/// If set, we attempt to negotiate the `anchors_zero_fee_htlc_tx`option for outbound channels.
154165
///
@@ -183,6 +194,7 @@ impl Default for ChannelHandshakeConfig {
183194
announced_channel: false,
184195
commit_upfront_shutdown_pubkey: true,
185196
their_channel_reserve_proportional_millionths: 10_000,
197+
manually_signal_channel_ready: false,
186198
#[cfg(anchors)]
187199
negotiate_anchors_zero_fee_htlc_tx: false,
188200
}

lightning/src/util/events.rs

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
//! few other things.
1616
1717
use crate::chain::keysinterface::SpendableOutputDescriptor;
18+
use crate::chain::transaction::OutPoint;
1819
#[cfg(anchors)]
1920
use crate::ln::chan_utils::{self, ChannelTransactionParameters, HTLCOutputInCommitment};
2021
use crate::ln::channelmanager::{InterceptId, PaymentId};
@@ -817,6 +818,50 @@ pub enum Event {
817818
/// transaction.
818819
claim_from_onchain_tx: bool,
819820
},
821+
/// Indicates a channel has received sufficient confirmations and LDK is ready to send [`msgs::ChannelReady`].
822+
///
823+
/// To signal readiness, call [`ChannelManager::signal_channel_readiness`]. To reject the
824+
/// request, call [`ChannelManager::force_close_without_broadcasting_txn`].
825+
///
826+
/// The event is only triggered when the [`UserConfig::manually_signal_channel_ready`]
827+
/// config flag is set to true.
828+
///
829+
/// [`ChannelManager::signal_channel_readiness`]: crate::ln::channelmanager::ChannelManager::signal_channel_readiness
830+
/// [`ChannelManager::force_close_without_broadcasting_txn`]: crate::ln::channelmanager::ChannelManager::force_close_without_broadcasting_txn
831+
/// [`UserConfig::manually_signal_channel_ready`]: crate::util::config::UserConfig::manually_signal_channel_ready
832+
/// [`msgs::ChannelReady`]: crate::ln::msgs::ChannelReady
833+
PendingChannelReady {
834+
/// The channel ID of the channel.
835+
///
836+
/// When responding to the request, the `channel_id` should be passed
837+
/// back to the ChannelManager through [`ChannelManager::signal_channel_readiness`] to signal,
838+
/// or through [`ChannelManager::force_close_without_broadcasting_txn`] to reject.
839+
///
840+
/// [`ChannelManager::signal_channel_readiness`]: crate::ln::channelmanager::ChannelManager::signal_channel_readiness
841+
/// [`ChannelManager::force_close_without_broadcasting_txn`]: crate::ln::channelmanager::ChannelManager::force_close_without_broadcasting_txn
842+
channel_id: [u8; 32],
843+
/// The `user_channel_id` value passed in to [`ChannelManager::create_channel`] for outbound
844+
/// channels, or to [`ChannelManager::accept_inbound_channel`] for inbound channels if
845+
/// [`UserConfig::manually_accept_inbound_channels`] config flag is set to true. Otherwise
846+
/// `user_channel_id` will be randomized for an inbound channel.
847+
///
848+
/// [`ChannelManager::create_channel`]: crate::ln::channelmanager::ChannelManager::create_channel
849+
/// [`ChannelManager::accept_inbound_channel`]: crate::ln::channelmanager::ChannelManager::accept_inbound_channel
850+
/// [`UserConfig::manually_accept_inbound_channels`]: crate::util::config::UserConfig::manually_accept_inbound_channels
851+
user_channel_id: u128,
852+
/// The node_id of the counterparty requesting to open the channel.
853+
///
854+
/// When responding to the request, the `counterparty_node_id` should be passed
855+
/// back to the `ChannelManager` through [`ChannelManager::signal_channel_readiness`] to
856+
/// signal readiness, or through [`ChannelManager::force_close_without_broadcasting_txn`] to reject the
857+
/// request.
858+
///
859+
/// [`ChannelManager::signal_channel_readiness`]: crate::ln::channelmanager::ChannelManager::signal_channel_readiness
860+
/// [`ChannelManager::force_close_without_broadcasting_txn`]: crate::ln::channelmanager::ChannelManager::force_close_without_broadcasting_txn
861+
counterparty_node_id: PublicKey,
862+
/// The outpoint that holds the channel funds on-chain.
863+
funding_outpoint: OutPoint,
864+
},
820865
/// Used to indicate that a channel with the given `channel_id` is ready to
821866
/// be used. This event is emitted either when the funding transaction has been confirmed
822867
/// on-chain, or, in case of a 0conf channel, when both parties have confirmed the channel
@@ -1136,6 +1181,15 @@ impl Writeable for Event {
11361181
(6, channel_type, required),
11371182
});
11381183
},
1184+
&Event::PendingChannelReady { ref channel_id, ref user_channel_id, ref counterparty_node_id, ref funding_outpoint } => {
1185+
31u8.write(writer)?;
1186+
write_tlv_fields!(writer, {
1187+
(0, channel_id, required),
1188+
(2, user_channel_id, required),
1189+
(4, counterparty_node_id, required),
1190+
(6, funding_outpoint, required)
1191+
});
1192+
},
11391193
// Note that, going forward, all new events must only write data inside of
11401194
// `write_tlv_fields`. Versions 0.0.101+ will ignore odd-numbered events that write
11411195
// data via `write_tlv_fields`.
@@ -1471,6 +1525,28 @@ impl MaybeReadable for Event {
14711525
};
14721526
f()
14731527
},
1528+
31u8 => {
1529+
let f = || {
1530+
let mut channel_id = [0; 32];
1531+
let mut user_channel_id: u128 = 0;
1532+
let mut counterparty_node_id = RequiredWrapper(None);
1533+
let mut funding_outpoint = RequiredWrapper(None);
1534+
read_tlv_fields!(reader, {
1535+
(0, channel_id, required),
1536+
(2, user_channel_id, required),
1537+
(4, counterparty_node_id, required),
1538+
(6, funding_outpoint, required),
1539+
});
1540+
1541+
Ok(Some(Event::PendingChannelReady {
1542+
channel_id,
1543+
user_channel_id,
1544+
counterparty_node_id: counterparty_node_id.0.unwrap(),
1545+
funding_outpoint: funding_outpoint.0.unwrap()
1546+
}))
1547+
};
1548+
f()
1549+
},
14741550
// Versions prior to 0.0.100 did not ignore odd types, instead returning InvalidValue.
14751551
// Version 0.0.100 failed to properly ignore odd types, possibly resulting in corrupt
14761552
// reads.

0 commit comments

Comments
 (0)