@@ -736,6 +736,9 @@ pub(super) struct Channel<Signer: Sign> {
736
736
// don't currently support node id aliases and eventually privacy should be provided with
737
737
// blinded paths instead of simple scid+node_id aliases.
738
738
outbound_scid_alias : u64 ,
739
+
740
+ // We track whether we already emitted a `ChannelReady` event.
741
+ channel_ready_event_emitted : bool ,
739
742
}
740
743
741
744
#[ cfg( any( test, fuzzing) ) ]
@@ -1063,6 +1066,8 @@ impl<Signer: Sign> Channel<Signer> {
1063
1066
latest_inbound_scid_alias : None ,
1064
1067
outbound_scid_alias,
1065
1068
1069
+ channel_ready_event_emitted : false ,
1070
+
1066
1071
#[ cfg( any( test, fuzzing) ) ]
1067
1072
historical_inbound_htlc_fulfills : HashSet :: new ( ) ,
1068
1073
@@ -1397,6 +1402,8 @@ impl<Signer: Sign> Channel<Signer> {
1397
1402
latest_inbound_scid_alias : None ,
1398
1403
outbound_scid_alias,
1399
1404
1405
+ channel_ready_event_emitted : false ,
1406
+
1400
1407
#[ cfg( any( test, fuzzing) ) ]
1401
1408
historical_inbound_htlc_fulfills : HashSet :: new ( ) ,
1402
1409
@@ -2174,7 +2181,14 @@ impl<Signer: Sign> Channel<Signer> {
2174
2181
& self . get_counterparty_pubkeys ( ) . funding_pubkey
2175
2182
}
2176
2183
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 {
2178
2192
if self . is_outbound ( ) {
2179
2193
return Err ( ChannelError :: Close ( "Received funding_created for an outbound channel?" . to_owned ( ) ) ) ;
2180
2194
}
@@ -2252,9 +2266,16 @@ impl<Signer: Sign> Channel<Signer> {
2252
2266
} , channel_monitor, self . check_get_channel_ready ( 0 ) ) )
2253
2267
}
2254
2268
2255
- /// Handles a funding_signed message from the remote end.
2269
+ /// Handles a received [`FundingSigned`] message.
2270
+ ///
2256
2271
/// 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 {
2258
2279
if !self . is_outbound ( ) {
2259
2280
return Err ( ChannelError :: Close ( "Received funding_signed for an inbound channel?" . to_owned ( ) ) ) ;
2260
2281
}
@@ -4598,6 +4619,17 @@ impl<Signer: Sign> Channel<Signer> {
4598
4619
self . prev_config . map ( |prev_config| prev_config. 0 )
4599
4620
}
4600
4621
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
+
4601
4633
/// Tracks the number of ticks elapsed since the previous [`ChannelConfig`] was updated. Once
4602
4634
/// [`EXPIRE_PREV_CONFIG_TICKS`] is reached, the previous config is considered expired and will
4603
4635
/// no longer be considered when forwarding HTLCs.
@@ -4858,12 +4890,12 @@ impl<Signer: Sign> Channel<Signer> {
4858
4890
self . channel_update_status = status;
4859
4891
}
4860
4892
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 ) {
4862
4894
// Called:
4863
4895
// * always when a new block/transactions are confirmed with the new height
4864
4896
// * when funding is signed with a height of 0
4865
4897
if self . funding_tx_confirmation_height == 0 && self . minimum_depth != Some ( 0 ) {
4866
- return None ;
4898
+ return ( None , false ) ;
4867
4899
}
4868
4900
4869
4901
let funding_tx_confirmations = height as i64 - self . funding_tx_confirmation_height as i64 + 1 ;
@@ -4872,7 +4904,7 @@ impl<Signer: Sign> Channel<Signer> {
4872
4904
}
4873
4905
4874
4906
if funding_tx_confirmations < self . minimum_depth . unwrap_or ( 0 ) as i64 {
4875
- return None ;
4907
+ return ( None , false ) ;
4876
4908
}
4877
4909
4878
4910
let non_shutdown_state = self . channel_state & ( !MULTI_STATE_FLAGS ) ;
@@ -4904,27 +4936,34 @@ impl<Signer: Sign> Channel<Signer> {
4904
4936
if need_commitment_update {
4905
4937
if self . channel_state & ( ChannelState :: MonitorUpdateInProgress as u32 ) == 0 {
4906
4938
if self . channel_state & ( ChannelState :: PeerDisconnected as u32 ) == 0 {
4939
+ let emit_channel_ready_event = self . should_emit_channel_ready_event ( ) ;
4907
4940
let next_per_commitment_point =
4908
4941
self . holder_signer . get_per_commitment_point ( INITIAL_COMMITMENT_NUMBER - 1 , & self . secp_ctx ) ;
4909
- return Some ( msgs:: ChannelReady {
4942
+ return ( Some ( msgs:: ChannelReady {
4910
4943
channel_id : self . channel_id ,
4911
4944
next_per_commitment_point,
4912
4945
short_channel_id_alias : Some ( self . outbound_scid_alias ) ,
4913
- } ) ;
4946
+ } ) , emit_channel_ready_event ) ;
4914
4947
}
4915
4948
} else {
4916
4949
self . monitor_pending_channel_ready = true ;
4917
4950
}
4918
4951
}
4919
- None
4952
+ ( None , false )
4920
4953
}
4921
4954
4922
4955
/// When a transaction is confirmed, we check whether it is or spends the funding transaction
4923
4956
/// In the first case, we store the confirmation height and calculating the short channel id.
4924
4957
/// 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
4925
4964
pub fn transactions_confirmed < L : Deref > ( & mut self , block_hash : & BlockHash , height : u32 ,
4926
4965
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 {
4928
4967
if let Some ( funding_txo) = self . get_funding_txo ( ) {
4929
4968
for & ( index_in_block, tx) in txdata. iter ( ) {
4930
4969
// Check if the transaction is the expected funding transaction, and if it is,
@@ -4968,10 +5007,10 @@ impl<Signer: Sign> Channel<Signer> {
4968
5007
// If we allow 1-conf funding, we may need to check for channel_ready here and
4969
5008
// send it immediately instead of waiting for a best_block_updated call (which
4970
5009
// 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) {
4972
5011
log_info ! ( logger, "Sending a channel_ready to our peer for channel {}" , log_bytes!( self . channel_id) ) ;
4973
5012
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) ) ;
4975
5014
}
4976
5015
}
4977
5016
for inp in tx. input . iter ( ) {
@@ -4982,7 +5021,7 @@ impl<Signer: Sign> Channel<Signer> {
4982
5021
}
4983
5022
}
4984
5023
}
4985
- Ok ( ( None , None ) )
5024
+ Ok ( ( ( None , false ) , None ) )
4986
5025
}
4987
5026
4988
5027
/// 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> {
4994
5033
/// requirements apply - no calls may be made except those explicitly stated to be allowed
4995
5034
/// post-shutdown.
4996
5035
///
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
4999
5042
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 {
5001
5044
self . do_best_block_updated ( height, highest_header_time, Some ( ( genesis_block_hash, node_pk) ) , logger)
5002
5045
}
5003
5046
5004
5047
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 {
5006
5049
let mut timed_out_htlcs = Vec :: new ( ) ;
5007
5050
// This mirrors the check in ChannelManager::decode_update_add_htlc_onion, refusing to
5008
5051
// forward an HTLC when our counterparty should almost certainly just fail it for expiring
@@ -5022,12 +5065,12 @@ impl<Signer: Sign> Channel<Signer> {
5022
5065
5023
5066
self . update_time_counter = cmp:: max ( self . update_time_counter , highest_header_time) ;
5024
5067
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) {
5026
5069
let announcement_sigs = if let Some ( ( genesis_block_hash, node_pk) ) = genesis_node_pk {
5027
5070
self . get_announcement_sigs ( node_pk, genesis_block_hash, height, logger)
5028
5071
} else { None } ;
5029
5072
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) ) ;
5031
5074
}
5032
5075
5033
5076
let non_shutdown_state = self . channel_state & ( !MULTI_STATE_FLAGS ) ;
@@ -5067,7 +5110,7 @@ impl<Signer: Sign> Channel<Signer> {
5067
5110
let announcement_sigs = if let Some ( ( genesis_block_hash, node_pk) ) = genesis_node_pk {
5068
5111
self . get_announcement_sigs ( node_pk, genesis_block_hash, height, logger)
5069
5112
} else { None } ;
5070
- Ok ( ( None , timed_out_htlcs, announcement_sigs) )
5113
+ Ok ( ( ( None , false ) , timed_out_htlcs, announcement_sigs) )
5071
5114
}
5072
5115
5073
5116
/// Indicates the funding transaction is no longer confirmed in the main chain. This may
@@ -5083,8 +5126,9 @@ impl<Signer: Sign> Channel<Signer> {
5083
5126
// time we saw and it will be ignored.
5084
5127
let best_time = self . update_time_counter ;
5085
5128
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) ) => {
5087
5130
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?" ) ;
5088
5132
assert ! ( timed_out_htlcs. is_empty( ) , "We can't have accepted HTLCs with a timeout before our funding confirmation?" ) ;
5089
5133
assert ! ( announcement_sigs. is_none( ) , "We can't generate an announcement_sigs with 0 confirmations?" ) ;
5090
5134
Ok ( ( ) )
@@ -6666,6 +6710,8 @@ impl<'a, Signer: Sign, K: Deref> ReadableArgs<(&'a K, u32)> for Channel<Signer>
6666
6710
// Later in the ChannelManager deserialization phase we scan for channels and assign scid aliases if its missing
6667
6711
outbound_scid_alias : outbound_scid_alias. unwrap_or ( 0 ) ,
6668
6712
6713
+ channel_ready_event_emitted : false ,
6714
+
6669
6715
#[ cfg( any( test, fuzzing) ) ]
6670
6716
historical_inbound_htlc_fulfills,
6671
6717
0 commit comments