@@ -925,6 +925,15 @@ pub(crate) const MPP_TIMEOUT_TICKS: u8 = 3;
925
925
/// [`OutboundPayments::remove_stale_resolved_payments`].
926
926
pub ( crate ) const IDEMPOTENCY_TIMEOUT_TICKS : u8 = 7 ;
927
927
928
+ /// The maximum number of unfunded channels we can have per-peer before we start rejecting new
929
+ /// (inbound) ones. The number of peers without funded channels is limited separately in
930
+ /// [`MAX_NO_CHANNEL_PEERS`].
931
+ const MAX_UNFUNDED_CHANS_PER_PEER : usize = 4 ;
932
+
933
+ /// The maximum number of peers which we do not have a (funded) channel with. Once we reach this
934
+ /// many peers we reject new (inbound) connections.
935
+ const MAX_NO_CHANNEL_PEERS : usize = 50 ;
936
+
928
937
/// Information needed for constructing an invoice route hint for this channel.
929
938
#[ derive( Clone , Debug , PartialEq ) ]
930
939
pub struct CounterpartyForwardingInfo {
@@ -4263,9 +4272,23 @@ where
4263
4272
}
4264
4273
let mut peer_state_lock = peer_state_mutex_opt. unwrap ( ) . lock ( ) . unwrap ( ) ;
4265
4274
let peer_state = & mut * peer_state_lock;
4275
+
4276
+ let mut unfunded_channels = 0 ;
4277
+ let best_block_height = self . best_block . read ( ) . unwrap ( ) . height ( ) ;
4278
+ for ( _, chan) in peer_state. channel_by_id . iter ( ) {
4279
+ if chan. get_funding_tx_confirmations ( best_block_height) == 0 {
4280
+ unfunded_channels += 1 ;
4281
+ }
4282
+ }
4283
+ if unfunded_channels > MAX_UNFUNDED_CHANS_PER_PEER {
4284
+ return Err ( MsgHandleErrInternal :: send_err_msg_no_close (
4285
+ format ! ( "Refusing more than {} unfunded channels." , MAX_UNFUNDED_CHANS_PER_PEER ) ,
4286
+ msg. temporary_channel_id . clone ( ) ) ) ;
4287
+ }
4288
+
4266
4289
let mut channel = match Channel :: new_from_req ( & self . fee_estimator , & self . entropy_source , & self . signer_provider ,
4267
- counterparty_node_id. clone ( ) , & self . channel_type_features ( ) , & peer_state. latest_features , msg, user_channel_id, & self . default_configuration ,
4268
- self . best_block . read ( ) . unwrap ( ) . height ( ) , & self . logger , outbound_scid_alias)
4290
+ counterparty_node_id. clone ( ) , & self . channel_type_features ( ) , & peer_state. latest_features , msg, user_channel_id,
4291
+ & self . default_configuration , best_block_height , & self . logger , outbound_scid_alias)
4269
4292
{
4270
4293
Err ( e) => {
4271
4294
self . outbound_scid_aliases . lock ( ) . unwrap ( ) . remove ( & outbound_scid_alias) ;
@@ -6210,7 +6233,7 @@ where
6210
6233
}
6211
6234
}
6212
6235
6213
- fn peer_connected ( & self , counterparty_node_id : & PublicKey , init_msg : & msgs:: Init , _inbound : bool ) -> Result < ( ) , ( ) > {
6236
+ fn peer_connected ( & self , counterparty_node_id : & PublicKey , init_msg : & msgs:: Init , inbound : bool ) -> Result < ( ) , ( ) > {
6214
6237
if !init_msg. features . supports_static_remote_key ( ) {
6215
6238
log_debug ! ( self . logger, "Peer {} does not support static remote key, disconnecting with no_connection_possible" , log_pubkey!( counterparty_node_id) ) ;
6216
6239
return Err ( ( ) ) ;
@@ -6220,6 +6243,24 @@ where
6220
6243
6221
6244
let _persistence_guard = PersistenceNotifierGuard :: notify_on_drop ( & self . total_consistency_lock , & self . persistence_notifier ) ;
6222
6245
6246
+ let mut peers_with_unfunded_channels = 0 ;
6247
+ let best_block_height = self . best_block . read ( ) . unwrap ( ) . height ( ) ;
6248
+ {
6249
+ let peer_state_lock = self . per_peer_state . read ( ) . unwrap ( ) ;
6250
+ for ( _, peer) in peer_state_lock. iter ( ) {
6251
+ let mut has_funded_channels = false ;
6252
+ for ( _, chan) in peer. lock ( ) . unwrap ( ) . channel_by_id . iter ( ) {
6253
+ if chan. get_funding_tx_confirmations ( best_block_height) != 0 {
6254
+ has_funded_channels = true ;
6255
+ }
6256
+ }
6257
+ if !has_funded_channels { peers_with_unfunded_channels += 1 }
6258
+ }
6259
+ }
6260
+ if inbound && peers_with_unfunded_channels > MAX_NO_CHANNEL_PEERS {
6261
+ return Err ( ( ) ) ;
6262
+ }
6263
+
6223
6264
{
6224
6265
let mut peer_state_lock = self . per_peer_state . write ( ) . unwrap ( ) ;
6225
6266
match peer_state_lock. entry ( counterparty_node_id. clone ( ) ) {
0 commit comments