Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

29 changes: 29 additions & 0 deletions crates/cli/commands/src/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,13 @@ pub struct NodeCommand<C: ChainSpecParser, Ext: clap::Args + fmt::Debug = NoArgs
#[arg(long, conflicts_with = "instance", global = true)]
pub with_unused_ports: bool,

/// Raise the open file descriptor resource limit.
///
/// Default: 0 (system default). When set to 0, uses the system's default file descriptor
/// limit. When set to a positive value, attempts to raise the limit to that value.
#[arg(long, value_name = "LIMIT", default_value_t = 0, global = true)]
pub fdlimit: u64,
Comment on lines +69 to +74
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not sure we really need this

imo always raising is appropriate

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Even if the system allows setting a higher file descriptor limit, the actual availability of resources such as memory and CPU can impact the stability and performance of the program. Setting the file descriptor limit too high can lead to resource exhaustion, which may cause the system or application to become unstable. This is because every open file descriptor consumes system resources, and if the number of file descriptors is increased significantly, it can strain the system's capacity to manage them effectively. Therefore, it's important to consider the overall resource usage and system capabilities when adjusting file descriptor limits.


/// All datadir related arguments
#[command(flatten)]
pub datadir: DatadirArgs,
Expand Down Expand Up @@ -158,6 +165,7 @@ where
metrics,
instance,
with_unused_ports,
fdlimit,
network,
rpc,
txpool,
Expand All @@ -179,6 +187,7 @@ where
chain,
metrics,
instance,
fdlimit,
network,
rpc,
txpool,
Expand Down Expand Up @@ -418,4 +427,24 @@ mod tests {
// make sure the ipc path is not the default
assert_ne!(cmd.rpc.ipcpath, String::from("/tmp/reth.ipc"));
}

#[test]
fn parse_fdlimit_default() {
let cmd: NodeCommand<EthereumChainSpecParser> = NodeCommand::parse_from(["reth"]);
assert_eq!(cmd.fdlimit, 0);
}

#[test]
fn parse_fdlimit_custom() {
let cmd: NodeCommand<EthereumChainSpecParser> =
NodeCommand::parse_from(["reth", "--fdlimit", "10000"]);
assert_eq!(cmd.fdlimit, 10000);
}

#[test]
fn parse_fdlimit_zero() {
let cmd: NodeCommand<EthereumChainSpecParser> =
NodeCommand::parse_from(["reth", "--fdlimit", "0"]);
assert_eq!(cmd.fdlimit, 0);
}
}
1 change: 1 addition & 0 deletions crates/node/builder/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ aquamarine.workspace = true
eyre.workspace = true
jsonrpsee.workspace = true
fdlimit.workspace = true
libc = "0.2"
rayon.workspace = true
serde_json.workspace = true

Expand Down
56 changes: 46 additions & 10 deletions crates/node/builder/src/launch/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -201,8 +201,8 @@ impl LaunchContext {
}

/// Convenience function to [`Self::configure_globals`]
pub fn with_configured_globals(self, reserved_cpu_cores: usize) -> Self {
self.configure_globals(reserved_cpu_cores);
pub fn with_configured_globals(self, reserved_cpu_cores: usize, fdlimit: u64) -> Self {
self.configure_globals(reserved_cpu_cores, fdlimit);
self
}

Expand All @@ -212,15 +212,51 @@ impl LaunchContext {
/// - Configuring the global rayon thread pool with available parallelism. Honoring
/// engine.reserved-cpu-cores to reserve given number of cores for O while using at least 1
/// core for the rayon thread pool
pub fn configure_globals(&self, reserved_cpu_cores: usize) {
pub fn configure_globals(&self, reserved_cpu_cores: usize, fdlimit: u64) {
// Raise the fd limit of the process.
// Does not do anything on windows.
match fdlimit::raise_fd_limit() {
Ok(fdlimit::Outcome::LimitRaised { from, to }) => {
debug!(from, to, "Raised file descriptor limit");
if fdlimit == 0 {
// Use system default (raise to maximum)
match fdlimit::raise_fd_limit() {
Comment on lines +218 to +220
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this will alter current behaviour and will likely be super annoying

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

0 for old behavior may be okay.

Ok(fdlimit::Outcome::LimitRaised { from, to }) => {
debug!(from, to, "Raised file descriptor limit");
}
Ok(fdlimit::Outcome::Unsupported) => {}
Err(err) => warn!(%err, "Failed to raise file descriptor limit"),
}
} else {
// Set to specific limit
#[cfg(unix)]
{
let result = unsafe {
let mut rlimit = libc::rlimit { rlim_cur: 0, rlim_max: 0 };
if libc::getrlimit(libc::RLIMIT_NOFILE, &raw mut rlimit) == 0 {
let old_limit = rlimit.rlim_cur;
rlimit.rlim_cur = fdlimit.min(rlimit.rlim_max) as libc::rlim_t;
if libc::setrlimit(libc::RLIMIT_NOFILE, &raw const rlimit) == 0 {
if rlimit.rlim_cur != old_limit {
debug!(
from = old_limit,
to = rlimit.rlim_cur,
"Set file descriptor limit"
);
}
Ok(())
} else {
Err(std::io::Error::last_os_error())
}
} else {
Err(std::io::Error::last_os_error())
}
};
if let Err(err) = result {
warn!(%err, limit = fdlimit, "Failed to set file descriptor limit");
}
}
#[cfg(not(unix))]
{
warn!("File descriptor limit setting is not supported on this platform");
}
Ok(fdlimit::Outcome::Unsupported) => {}
Err(err) => warn!(%err, "Failed to raise file descriptor limit"),
}

// Reserving the given number of CPU cores for the rest of OS.
Expand Down Expand Up @@ -261,8 +297,8 @@ impl<T> LaunchContextWith<T> {
///
/// - Raising the file descriptor limit
/// - Configuring the global rayon thread pool
pub fn configure_globals(&self, reserved_cpu_cores: u64) {
self.inner.configure_globals(reserved_cpu_cores.try_into().unwrap());
pub fn configure_globals(&self, reserved_cpu_cores: u64, fdlimit: u64) {
self.inner.configure_globals(reserved_cpu_cores.try_into().unwrap(), fdlimit);
}

/// Returns the data directory.
Expand Down
3 changes: 2 additions & 1 deletion crates/node/builder/src/launch/engine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,9 @@ impl EngineNodeLauncher {
let NodeHooks { on_component_initialized, on_node_started, .. } = hooks;

// setup the launch context
let fdlimit = config.fdlimit;
let ctx = ctx
.with_configured_globals(engine_tree_config.reserved_cpu_cores())
.with_configured_globals(engine_tree_config.reserved_cpu_cores(), fdlimit)
// load the toml config
.with_loaded_toml_config(config)?
// add resolved peers
Expand Down
11 changes: 11 additions & 0 deletions crates/node/core/src/node_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,12 @@ pub struct NodeConfig<ChainSpec> {
/// - `IPC_PATH`: default + `instance`
pub instance: Option<u16>,

/// File descriptor limit.
///
/// Default: 0 (system default). When set to 0, uses the system's default file descriptor
/// limit. When set to a positive value, attempts to raise the limit to that value.
pub fdlimit: u64,

/// All networking related arguments
pub network: NetworkArgs,

Expand Down Expand Up @@ -169,6 +175,7 @@ impl<ChainSpec> NodeConfig<ChainSpec> {
chain,
metrics: MetricArgs::default(),
instance: None,
fdlimit: 0,
network: NetworkArgs::default(),
rpc: RpcServerArgs::default(),
txpool: TxPoolArgs::default(),
Expand Down Expand Up @@ -244,6 +251,7 @@ impl<ChainSpec> NodeConfig<ChainSpec> {
config,
metrics,
instance,
fdlimit,
network,
rpc,
txpool,
Expand All @@ -263,6 +271,7 @@ impl<ChainSpec> NodeConfig<ChainSpec> {
chain: chain.into(),
metrics,
instance,
fdlimit,
network,
rpc,
txpool,
Expand Down Expand Up @@ -533,6 +542,7 @@ impl<ChainSpec> NodeConfig<ChainSpec> {
config: self.config,
metrics: self.metrics,
instance: self.instance,
fdlimit: self.fdlimit,
network: self.network,
rpc: self.rpc,
txpool: self.txpool,
Expand Down Expand Up @@ -573,6 +583,7 @@ impl<ChainSpec> Clone for NodeConfig<ChainSpec> {
config: self.config.clone(),
metrics: self.metrics.clone(),
instance: self.instance,
fdlimit: self.fdlimit,
network: self.network.clone(),
rpc: self.rpc.clone(),
txpool: self.txpool.clone(),
Expand Down
7 changes: 7 additions & 0 deletions docs/vocs/docs/pages/cli/op-reth/node.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,13 @@ Options:

Mutually exclusive with `--instance`.

--fdlimit <LIMIT>
Raise the open file descriptor resource limit.

Default: 0 (system default). When set to 0, uses the system's default file descriptor limit. When set to a positive value, attempts to raise the limit to that value.

[default: 0]

-h, --help
Print help (see a summary with '-h')

Expand Down
7 changes: 7 additions & 0 deletions docs/vocs/docs/pages/cli/reth/node.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,13 @@ Options:

Mutually exclusive with `--instance`.

--fdlimit <LIMIT>
Raise the open file descriptor resource limit.

Default: 0 (system default). When set to 0, uses the system's default file descriptor limit. When set to a positive value, attempts to raise the limit to that value.

[default: 0]

-h, --help
Print help (see a summary with '-h')

Expand Down
Loading