diff --git a/Cargo.lock b/Cargo.lock index 7cb6200..c65a31d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -360,6 +360,7 @@ dependencies = [ "clap-verbosity-flag", "env_logger", "faster-hex 0.9.0", + "fdlimit", "jsonrpc-core", "jsonrpc-derive", "jsonrpc-http-server", @@ -1142,6 +1143,16 @@ version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" +[[package]] +name = "fdlimit" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e182f7dbc2ef73d9ef67351c5fbbea084729c48362d3ce9dd44c28e32e277fe5" +dependencies = [ + "libc", + "thiserror", +] + [[package]] name = "fixed-hash" version = "0.8.0" diff --git a/Cargo.toml b/Cargo.toml index 9c33a8f..afe4afc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,6 +20,7 @@ zeroize = { version = "1.7", features = ["derive"] } url = "2.5" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" +fdlimit = "0.3" reqwest = { version = "0.11", default-features = false, features = ["json", "blocking"] } jsonrpc-core = "18.0" diff --git a/src/cli/serve.rs b/src/cli/serve.rs index 4177a8e..c742b25 100644 --- a/src/cli/serve.rs +++ b/src/cli/serve.rs @@ -37,6 +37,7 @@ use crate::{ }, prelude::*, result::{Error, Result}, + utilities::try_raise_fd_limit, }; #[derive(Parser)] @@ -83,6 +84,8 @@ impl Args { pub fn execute(&self) -> Result<()> { log::info!("Starting the Bitcoin SPV service"); + try_raise_fd_limit(); + let storage = Storage::new(&self.data_dir)?; if !storage.is_initialized()? { let msg = format!( diff --git a/src/cli/watch.rs b/src/cli/watch.rs index 5ba909b..9c5c555 100644 --- a/src/cli/watch.rs +++ b/src/cli/watch.rs @@ -8,6 +8,7 @@ use crate::{ components::{ApiServiceConfig, SpvService, Storage}, prelude::*, result::{Error, Result}, + utilities::try_raise_fd_limit, }; #[derive(Parser)] @@ -45,6 +46,8 @@ impl Args { pub fn execute(&self) -> Result<()> { log::info!("Starting the Bitcoin SPV service (readonly)"); + try_raise_fd_limit(); + let storage = Storage::new(&self.data_dir)?; if !storage.is_initialized()? { let msg = format!( diff --git a/src/components/api_service/mod.rs b/src/components/api_service/mod.rs index fa067d8..52271bd 100644 --- a/src/components/api_service/mod.rs +++ b/src/components/api_service/mod.rs @@ -128,7 +128,6 @@ impl SpvRpc for SpvRpcImpl { })?; log::trace!(">>> tip height in local storage is {stg_tip_height}"); - // TODO Define server errors with enum. if stg_tip_height < target_height { let desc = format!( "target transaction is in header#{target_height}, \ diff --git a/src/utilities/mod.rs b/src/utilities/mod.rs index 46c7d7c..8a4c8a7 100644 --- a/src/utilities/mod.rs +++ b/src/utilities/mod.rs @@ -1,8 +1,10 @@ //! Utilities. mod key; +mod platform; mod type_id; pub(crate) mod value_parsers; pub(crate) use key::Key256Bits; +pub(crate) use platform::try_raise_fd_limit; pub(crate) use type_id::calculate_type_id; diff --git a/src/utilities/platform.rs b/src/utilities/platform.rs new file mode 100644 index 0000000..bef480c --- /dev/null +++ b/src/utilities/platform.rs @@ -0,0 +1,17 @@ +//! Enhance the platform environment for continuously running services. + +use fdlimit::{raise_fd_limit, Outcome}; + +pub fn try_raise_fd_limit() { + match raise_fd_limit() { + Ok(Outcome::LimitRaised { from, to }) => { + log::info!("raise file descriptor resource limit from {from} to {to}"); + } + Ok(Outcome::Unsupported) => { + log::warn!("raising limit is not supported on this platform"); + } + Err(err) => { + log::error!("failed to raise file descriptor resource limit, since {err}"); + } + } +}