Skip to content

Commit 8b9aa65

Browse files
committed
Add ChannelReady event
This adds a `ChannelReady` event that is emitted as soon as a new channel becomes usable, i.e., after both sides have sent `channel_ready`.
1 parent 3b2f694 commit 8b9aa65

File tree

3 files changed

+165
-28
lines changed

3 files changed

+165
-28
lines changed

lightning/src/ln/channel.rs

+72-21
Original file line numberDiff line numberDiff line change
@@ -736,6 +736,9 @@ pub(super) struct Channel<Signer: Sign> {
736736
// don't currently support node id aliases and eventually privacy should be provided with
737737
// blinded paths instead of simple scid+node_id aliases.
738738
outbound_scid_alias: u64,
739+
740+
// We track whether we already emitted a `ChannelReady` event.
741+
channel_ready_event_emitted: bool,
739742
}
740743

741744
#[cfg(any(test, fuzzing))]
@@ -1063,6 +1066,8 @@ impl<Signer: Sign> Channel<Signer> {
10631066
latest_inbound_scid_alias: None,
10641067
outbound_scid_alias,
10651068

1069+
channel_ready_event_emitted: false,
1070+
10661071
#[cfg(any(test, fuzzing))]
10671072
historical_inbound_htlc_fulfills: HashSet::new(),
10681073

@@ -1397,6 +1402,8 @@ impl<Signer: Sign> Channel<Signer> {
13971402
latest_inbound_scid_alias: None,
13981403
outbound_scid_alias,
13991404

1405+
channel_ready_event_emitted: false,
1406+
14001407
#[cfg(any(test, fuzzing))]
14011408
historical_inbound_htlc_fulfills: HashSet::new(),
14021409

@@ -2174,7 +2181,14 @@ impl<Signer: Sign> Channel<Signer> {
21742181
&self.get_counterparty_pubkeys().funding_pubkey
21752182
}
21762183

2177-
pub fn funding_created<L: Deref>(&mut self, msg: &msgs::FundingCreated, best_block: BestBlock, logger: &L) -> Result<(msgs::FundingSigned, ChannelMonitor<Signer>, Option<msgs::ChannelReady>), ChannelError> where L::Target: Logger {
2184+
/// Handles a received [`FundingCreated`] message.
2185+
///
2186+
/// May return the resulting [`ChannelReady`] message, as well as
2187+
/// a `bool` signalling whether a corresponding event should be emitted.
2188+
///
2189+
/// [`FundingCreated`]: msgs::FundingCreated
2190+
/// [`ChannelReady`]: msgs::ChannelReady
2191+
pub fn funding_created<L: Deref>(&mut self, msg: &msgs::FundingCreated, best_block: BestBlock, logger: &L) -> Result<(msgs::FundingSigned, ChannelMonitor<Signer>, (Option<msgs::ChannelReady>, bool)), ChannelError> where L::Target: Logger {
21782192
if self.is_outbound() {
21792193
return Err(ChannelError::Close("Received funding_created for an outbound channel?".to_owned()));
21802194
}
@@ -2252,9 +2266,16 @@ impl<Signer: Sign> Channel<Signer> {
22522266
}, channel_monitor, self.check_get_channel_ready(0)))
22532267
}
22542268

2255-
/// Handles a funding_signed message from the remote end.
2269+
/// Handles a received [`FundingSigned`] message.
2270+
///
22562271
/// If this call is successful, broadcast the funding transaction (and not before!)
2257-
pub fn funding_signed<L: Deref>(&mut self, msg: &msgs::FundingSigned, best_block: BestBlock, logger: &L) -> Result<(ChannelMonitor<Signer>, Transaction, Option<msgs::ChannelReady>), ChannelError> where L::Target: Logger {
2272+
///
2273+
/// May return the resulting [`ChannelReady`] message, as well as
2274+
/// a `bool` signalling whether a corresponding event should be emitted.
2275+
///
2276+
/// [`FundingSigned`]: msgs::FundingSigned
2277+
/// [`ChannelReady`]: msgs::ChannelReady
2278+
pub fn funding_signed<L: Deref>(&mut self, msg: &msgs::FundingSigned, best_block: BestBlock, logger: &L) -> Result<(ChannelMonitor<Signer>, Transaction, (Option<msgs::ChannelReady>, bool)), ChannelError> where L::Target: Logger {
22582279
if !self.is_outbound() {
22592280
return Err(ChannelError::Close("Received funding_signed for an inbound channel?".to_owned()));
22602281
}
@@ -4598,6 +4619,17 @@ impl<Signer: Sign> Channel<Signer> {
45984619
self.prev_config.map(|prev_config| prev_config.0)
45994620
}
46004621

4622+
// Checks whether we previously had emitted a `ChannelReady` event and sets the value if not.
4623+
pub(crate) fn should_emit_channel_ready_event(&mut self) -> bool {
4624+
if self.channel_ready_event_emitted {
4625+
// Do nothing, already emitted.
4626+
false
4627+
} else {
4628+
self.channel_ready_event_emitted = true;
4629+
true
4630+
}
4631+
}
4632+
46014633
/// Tracks the number of ticks elapsed since the previous [`ChannelConfig`] was updated. Once
46024634
/// [`EXPIRE_PREV_CONFIG_TICKS`] is reached, the previous config is considered expired and will
46034635
/// no longer be considered when forwarding HTLCs.
@@ -4858,12 +4890,12 @@ impl<Signer: Sign> Channel<Signer> {
48584890
self.channel_update_status = status;
48594891
}
48604892

4861-
fn check_get_channel_ready(&mut self, height: u32) -> Option<msgs::ChannelReady> {
4893+
fn check_get_channel_ready(&mut self, height: u32) -> (Option<msgs::ChannelReady>, bool) {
48624894
// Called:
48634895
// * always when a new block/transactions are confirmed with the new height
48644896
// * when funding is signed with a height of 0
48654897
if self.funding_tx_confirmation_height == 0 && self.minimum_depth != Some(0) {
4866-
return None;
4898+
return (None, false);
48674899
}
48684900

48694901
let funding_tx_confirmations = height as i64 - self.funding_tx_confirmation_height as i64 + 1;
@@ -4872,7 +4904,7 @@ impl<Signer: Sign> Channel<Signer> {
48724904
}
48734905

48744906
if funding_tx_confirmations < self.minimum_depth.unwrap_or(0) as i64 {
4875-
return None;
4907+
return (None, false);
48764908
}
48774909

48784910
let non_shutdown_state = self.channel_state & (!MULTI_STATE_FLAGS);
@@ -4904,27 +4936,34 @@ impl<Signer: Sign> Channel<Signer> {
49044936
if need_commitment_update {
49054937
if self.channel_state & (ChannelState::MonitorUpdateInProgress as u32) == 0 {
49064938
if self.channel_state & (ChannelState::PeerDisconnected as u32) == 0 {
4939+
let emit_channel_ready_event = self.should_emit_channel_ready_event();
49074940
let next_per_commitment_point =
49084941
self.holder_signer.get_per_commitment_point(INITIAL_COMMITMENT_NUMBER - 1, &self.secp_ctx);
4909-
return Some(msgs::ChannelReady {
4942+
return (Some(msgs::ChannelReady {
49104943
channel_id: self.channel_id,
49114944
next_per_commitment_point,
49124945
short_channel_id_alias: Some(self.outbound_scid_alias),
4913-
});
4946+
}), emit_channel_ready_event);
49144947
}
49154948
} else {
49164949
self.monitor_pending_channel_ready = true;
49174950
}
49184951
}
4919-
None
4952+
(None, false)
49204953
}
49214954

49224955
/// When a transaction is confirmed, we check whether it is or spends the funding transaction
49234956
/// In the first case, we store the confirmation height and calculating the short channel id.
49244957
/// In the second, we simply return an Err indicating we need to be force-closed now.
4958+
///
4959+
/// May return the resulting [`ChannelReady`] and [`AnnouncementSignatures`] messages, as well as
4960+
/// a `bool` signalling whether a corresponding `ChannelReady` event should be emitted.
4961+
///
4962+
/// [`ChannelReady`]: msgs::ChannelReady
4963+
/// [`AnnouncementSignatures`]: msgs::AnnouncementSignatures
49254964
pub fn transactions_confirmed<L: Deref>(&mut self, block_hash: &BlockHash, height: u32,
49264965
txdata: &TransactionData, genesis_block_hash: BlockHash, node_pk: PublicKey, logger: &L)
4927-
-> Result<(Option<msgs::ChannelReady>, Option<msgs::AnnouncementSignatures>), ClosureReason> where L::Target: Logger {
4966+
-> Result<((Option<msgs::ChannelReady>, bool), Option<msgs::AnnouncementSignatures>), ClosureReason> where L::Target: Logger {
49284967
if let Some(funding_txo) = self.get_funding_txo() {
49294968
for &(index_in_block, tx) in txdata.iter() {
49304969
// Check if the transaction is the expected funding transaction, and if it is,
@@ -4968,10 +5007,10 @@ impl<Signer: Sign> Channel<Signer> {
49685007
// If we allow 1-conf funding, we may need to check for channel_ready here and
49695008
// send it immediately instead of waiting for a best_block_updated call (which
49705009
// may have already happened for this block).
4971-
if let Some(channel_ready) = self.check_get_channel_ready(height) {
5010+
if let (Some(channel_ready), emit_channel_ready_event) = self.check_get_channel_ready(height) {
49725011
log_info!(logger, "Sending a channel_ready to our peer for channel {}", log_bytes!(self.channel_id));
49735012
let announcement_sigs = self.get_announcement_sigs(node_pk, genesis_block_hash, height, logger);
4974-
return Ok((Some(channel_ready), announcement_sigs));
5013+
return Ok(((Some(channel_ready), emit_channel_ready_event), announcement_sigs));
49755014
}
49765015
}
49775016
for inp in tx.input.iter() {
@@ -4982,7 +5021,7 @@ impl<Signer: Sign> Channel<Signer> {
49825021
}
49835022
}
49845023
}
4985-
Ok((None, None))
5024+
Ok(((None, false), None))
49865025
}
49875026

49885027
/// When a new block is connected, we check the height of the block against outbound holding
@@ -4994,15 +5033,19 @@ impl<Signer: Sign> Channel<Signer> {
49945033
/// requirements apply - no calls may be made except those explicitly stated to be allowed
49955034
/// post-shutdown.
49965035
///
4997-
/// May return some HTLCs (and their payment_hash) which have timed out and should be failed
4998-
/// back.
5036+
/// May return the resulting [`ChannelReady`] and [`AnnouncementSignatures`] messages, as well as
5037+
/// a `bool` signalling whether a corresponding `ChannelReady` event should be emitted and some HTLCs (and
5038+
/// their payment_hash) which have timed out and should be failed back.
5039+
///
5040+
/// [`ChannelReady`]: msgs::ChannelReady
5041+
/// [`AnnouncementSignatures`]: msgs::AnnouncementSignatures
49995042
pub fn best_block_updated<L: Deref>(&mut self, height: u32, highest_header_time: u32, genesis_block_hash: BlockHash, node_pk: PublicKey, logger: &L)
5000-
-> Result<(Option<msgs::ChannelReady>, Vec<(HTLCSource, PaymentHash)>, Option<msgs::AnnouncementSignatures>), ClosureReason> where L::Target: Logger {
5043+
-> Result<((Option<msgs::ChannelReady>, bool), Vec<(HTLCSource, PaymentHash)>, Option<msgs::AnnouncementSignatures>), ClosureReason> where L::Target: Logger {
50015044
self.do_best_block_updated(height, highest_header_time, Some((genesis_block_hash, node_pk)), logger)
50025045
}
50035046

50045047
fn do_best_block_updated<L: Deref>(&mut self, height: u32, highest_header_time: u32, genesis_node_pk: Option<(BlockHash, PublicKey)>, logger: &L)
5005-
-> Result<(Option<msgs::ChannelReady>, Vec<(HTLCSource, PaymentHash)>, Option<msgs::AnnouncementSignatures>), ClosureReason> where L::Target: Logger {
5048+
-> Result<((Option<msgs::ChannelReady>, bool), Vec<(HTLCSource, PaymentHash)>, Option<msgs::AnnouncementSignatures>), ClosureReason> where L::Target: Logger {
50065049
let mut timed_out_htlcs = Vec::new();
50075050
// This mirrors the check in ChannelManager::decode_update_add_htlc_onion, refusing to
50085051
// forward an HTLC when our counterparty should almost certainly just fail it for expiring
@@ -5022,12 +5065,12 @@ impl<Signer: Sign> Channel<Signer> {
50225065

50235066
self.update_time_counter = cmp::max(self.update_time_counter, highest_header_time);
50245067

5025-
if let Some(channel_ready) = self.check_get_channel_ready(height) {
5068+
if let (Some(channel_ready), emit_channel_ready_event) = self.check_get_channel_ready(height) {
50265069
let announcement_sigs = if let Some((genesis_block_hash, node_pk)) = genesis_node_pk {
50275070
self.get_announcement_sigs(node_pk, genesis_block_hash, height, logger)
50285071
} else { None };
50295072
log_info!(logger, "Sending a channel_ready to our peer for channel {}", log_bytes!(self.channel_id));
5030-
return Ok((Some(channel_ready), timed_out_htlcs, announcement_sigs));
5073+
return Ok(((Some(channel_ready), emit_channel_ready_event), timed_out_htlcs, announcement_sigs));
50315074
}
50325075

50335076
let non_shutdown_state = self.channel_state & (!MULTI_STATE_FLAGS);
@@ -5067,7 +5110,7 @@ impl<Signer: Sign> Channel<Signer> {
50675110
let announcement_sigs = if let Some((genesis_block_hash, node_pk)) = genesis_node_pk {
50685111
self.get_announcement_sigs(node_pk, genesis_block_hash, height, logger)
50695112
} else { None };
5070-
Ok((None, timed_out_htlcs, announcement_sigs))
5113+
Ok(((None, false), timed_out_htlcs, announcement_sigs))
50715114
}
50725115

50735116
/// Indicates the funding transaction is no longer confirmed in the main chain. This may
@@ -5083,8 +5126,9 @@ impl<Signer: Sign> Channel<Signer> {
50835126
// time we saw and it will be ignored.
50845127
let best_time = self.update_time_counter;
50855128
match self.do_best_block_updated(reorg_height, best_time, None, logger) {
5086-
Ok((channel_ready, timed_out_htlcs, announcement_sigs)) => {
5129+
Ok(((channel_ready, emit_channel_ready_event), timed_out_htlcs, announcement_sigs)) => {
50875130
assert!(channel_ready.is_none(), "We can't generate a funding with 0 confirmations?");
5131+
assert!(!emit_channel_ready_event, "We shouldn't emit a ChannelReady event for a funding with 0 confirmations?");
50885132
assert!(timed_out_htlcs.is_empty(), "We can't have accepted HTLCs with a timeout before our funding confirmation?");
50895133
assert!(announcement_sigs.is_none(), "We can't generate an announcement_sigs with 0 confirmations?");
50905134
Ok(())
@@ -6230,6 +6274,8 @@ impl<Signer: Sign> Writeable for Channel<Signer> {
62306274
if self.holder_max_htlc_value_in_flight_msat != Self::get_holder_max_htlc_value_in_flight_msat(self.channel_value_satoshis, &old_max_in_flight_percent_config)
62316275
{ Some(self.holder_max_htlc_value_in_flight_msat) } else { None };
62326276

6277+
let channel_ready_event_emitted = Some(self.channel_ready_event_emitted);
6278+
62336279
write_tlv_fields!(writer, {
62346280
(0, self.announcement_sigs, option),
62356281
// minimum_depth and counterparty_selected_channel_reserve_satoshis used to have a
@@ -6252,6 +6298,7 @@ impl<Signer: Sign> Writeable for Channel<Signer> {
62526298
(17, self.announcement_sigs_state, required),
62536299
(19, self.latest_inbound_scid_alias, option),
62546300
(21, self.outbound_scid_alias, required),
6301+
(23, channel_ready_event_emitted, option),
62556302
});
62566303

62576304
Ok(())
@@ -6509,6 +6556,7 @@ impl<'a, Signer: Sign, K: Deref> ReadableArgs<(&'a K, u32)> for Channel<Signer>
65096556
let mut announcement_sigs_state = Some(AnnouncementSigsState::NotSent);
65106557
let mut latest_inbound_scid_alias = None;
65116558
let mut outbound_scid_alias = None;
6559+
let mut channel_ready_event_emitted = None;
65126560

65136561
read_tlv_fields!(reader, {
65146562
(0, announcement_sigs, option),
@@ -6526,6 +6574,7 @@ impl<'a, Signer: Sign, K: Deref> ReadableArgs<(&'a K, u32)> for Channel<Signer>
65266574
(17, announcement_sigs_state, option),
65276575
(19, latest_inbound_scid_alias, option),
65286576
(21, outbound_scid_alias, option),
6577+
(23, channel_ready_event_emitted, option),
65296578
});
65306579

65316580
if let Some(preimages) = preimages_opt {
@@ -6666,6 +6715,8 @@ impl<'a, Signer: Sign, K: Deref> ReadableArgs<(&'a K, u32)> for Channel<Signer>
66666715
// Later in the ChannelManager deserialization phase we scan for channels and assign scid aliases if its missing
66676716
outbound_scid_alias: outbound_scid_alias.unwrap_or(0),
66686717

6718+
channel_ready_event_emitted: channel_ready_event_emitted.unwrap_or(false),
6719+
66696720
#[cfg(any(test, fuzzing))]
66706721
historical_inbound_htlc_fulfills,
66716722

0 commit comments

Comments
 (0)