Skip to content

Commit

Permalink
Add an option to disable inbound rate limiter (sigp#4327)
Browse files Browse the repository at this point in the history
On deneb devnetv5, lighthouse keeps rate limiting peers which makes it harder to bootstrap new nodes as there are very few peers in the network. This PR adds an option to disable the inbound rate limiter for testnets.

Added an option to configure inbound rate limits as well.

Co-authored-by: Diva M <divma@protonmail.com>
  • Loading branch information
2 people authored and Woodpile37 committed Jan 6, 2024
1 parent 7916324 commit dd19fed
Show file tree
Hide file tree
Showing 6 changed files with 84 additions and 26 deletions.
6 changes: 5 additions & 1 deletion beacon_node/lighthouse_network/src/config.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::listen_addr::{ListenAddr, ListenAddress};
use crate::rpc::config::OutboundRateLimiterConfig;
use crate::rpc::config::{InboundRateLimiterConfig, OutboundRateLimiterConfig};
use crate::types::GossipKind;
use crate::{Enr, PeerIdSerialized};
use directory::{
Expand Down Expand Up @@ -148,6 +148,9 @@ pub struct Config {

/// Configures if/where invalid blocks should be stored.
pub invalid_block_storage: Option<PathBuf>,

/// Configuration for the inbound rate limiter (requests received by this node).
pub inbound_rate_limiter_config: Option<InboundRateLimiterConfig>,
}

impl Config {
Expand Down Expand Up @@ -333,6 +336,7 @@ impl Default for Config {
enable_light_client_server: false,
outbound_rate_limiter_config: None,
invalid_block_storage: None,
inbound_rate_limiter_config: None,
}
}
}
Expand Down
47 changes: 24 additions & 23 deletions beacon_node/lighthouse_network/src/rpc/rate_limiter.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use super::config::RateLimiterConfig;
use crate::rpc::Protocol;
use fnv::FnvHashMap;
use libp2p::PeerId;
Expand Down Expand Up @@ -139,29 +140,6 @@ impl RPCRateLimiterBuilder {
self
}

/// Allow one token every `time_period` to be used for this `protocol`.
/// This produces a hard limit.
pub fn one_every(self, protocol: Protocol, time_period: Duration) -> Self {
self.set_quota(
protocol,
Quota {
replenish_all_every: time_period,
max_tokens: 1,
},
)
}

/// Allow `n` tokens to be use used every `time_period` for this `protocol`.
pub fn n_every(self, protocol: Protocol, n: u64, time_period: Duration) -> Self {
self.set_quota(
protocol,
Quota {
max_tokens: n,
replenish_all_every: time_period,
},
)
}

pub fn build(self) -> Result<RPCRateLimiter, &'static str> {
// get our quotas
let ping_quota = self.ping_quota.ok_or("Ping quota not specified")?;
Expand Down Expand Up @@ -230,6 +208,29 @@ impl<T: EthSpec> RateLimiterItem for super::OutboundRequest<T> {
}
}
impl RPCRateLimiter {
pub fn new_with_config(config: RateLimiterConfig) -> Result<Self, &'static str> {
// Destructure to make sure every configuration value is used.
let RateLimiterConfig {
ping_quota,
meta_data_quota,
status_quota,
goodbye_quota,
blocks_by_range_quota,
blocks_by_root_quota,
light_client_bootstrap_quota,
} = config;

Self::builder()
.set_quota(Protocol::Ping, ping_quota)
.set_quota(Protocol::MetaData, meta_data_quota)
.set_quota(Protocol::Status, status_quota)
.set_quota(Protocol::Goodbye, goodbye_quota)
.set_quota(Protocol::BlocksByRange, blocks_by_range_quota)
.set_quota(Protocol::BlocksByRoot, blocks_by_root_quota)
.set_quota(Protocol::LightClientBootstrap, light_client_bootstrap_quota)
.build()
}

/// Get a builder instance.
pub fn builder() -> RPCRateLimiterBuilder {
RPCRateLimiterBuilder::default()
Expand Down
1 change: 1 addition & 0 deletions beacon_node/lighthouse_network/src/service/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,7 @@ impl<AppReqId: ReqId, TSpec: EthSpec> Network<AppReqId, TSpec> {
let eth2_rpc = RPC::new(
ctx.fork_context.clone(),
config.enable_light_client_server,
config.inbound_rate_limiter_config.clone(),
config.outbound_rate_limiter_config.clone(),
log.clone(),
);
Expand Down
18 changes: 17 additions & 1 deletion beacon_node/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -289,7 +289,23 @@ pub fn cli_app<'a, 'b>() -> App<'a, 'b> {
for a beacon node being referenced by validator client using the --proposer-node flag. This configuration is for enabling more secure setups.")
.takes_value(false),
)

.arg(
Arg::with_name("inbound-rate-limiter")
.long("inbound-rate-limiter")
.help(
"Configures the inbound rate limiter (requests received by this node).\
\
Rate limit quotas per protocol can be set in the form of \
<protocol_name>:<tokens>/<time_in_seconds>. To set quotas for multiple protocols, \
separate them by ';'. If the inbound rate limiter is enabled and a protocol is not \
present in the configuration, the default quotas will be used. \
\
This is enabled by default, using default quotas. To disable rate limiting pass \
`disabled` to this option instead."
)
.takes_value(true)
.hidden(true)
)
.arg(
Arg::with_name("disable-backfill-rate-limiting")
.long("disable-backfill-rate-limiting")
Expand Down
18 changes: 17 additions & 1 deletion beacon_node/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1269,6 +1269,7 @@ pub fn set_network_config(
// Light client server config.
config.enable_light_client_server = cli_args.is_present("light-client-server");

// The self limiter is disabled by default.
// This flag can be used both with or without a value. Try to parse it first with a value, if
// no value is defined but the flag is present, use the default params.
config.outbound_rate_limiter_config = clap_utils::parse_optional(cli_args, "self-limiter")?;
Expand All @@ -1289,7 +1290,22 @@ pub fn set_network_config(
config.proposer_only = true;
warn!(log, "Proposer-only mode enabled"; "info"=> "Do not connect a validator client to this node unless via the --proposer-nodes flag");
}

// The inbound rate limiter is enabled by default unless `disabled` is passed to the
// `inbound-rate-limiter` flag. Any other value should be parsed as a configuration string.
config.inbound_rate_limiter_config = match cli_args.value_of("inbound-rate-limiter") {
None => {
// Enabled by default, with default values
Some(Default::default())
}
Some("disabled") => {
// Explicitly disabled
None
}
Some(config_str) => {
// Enabled with a custom configuration
Some(config_str.parse()?)
}
};
Ok(())
}

Expand Down
20 changes: 20 additions & 0 deletions lighthouse/tests/beacon_node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1451,6 +1451,26 @@ fn empty_self_limiter_flag() {
)
});
}

#[test]
fn empty_inbound_rate_limiter_flag() {
CommandLineTest::new()
.run_with_zero_port()
.with_config(|config| {
assert_eq!(
config.network.inbound_rate_limiter_config,
Some(lighthouse_network::rpc::config::InboundRateLimiterConfig::default())
)
});
}
#[test]
fn disable_inbound_rate_limiter_flag() {
CommandLineTest::new()
.flag("inbound-rate-limiter", Some("disabled"))
.run_with_zero_port()
.with_config(|config| assert_eq!(config.network.inbound_rate_limiter_config, None));
}

#[test]
fn http_allow_origin_flag() {
CommandLineTest::new()
Expand Down

0 comments on commit dd19fed

Please sign in to comment.