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