diff --git a/Cargo.lock b/Cargo.lock index 52a0e3626..9d50f9916 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -485,15 +485,6 @@ version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d86b93f97252c47b41663388e6d155714a9d0c398b99f1005cbc5f978b29f445" -[[package]] -name = "beef" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a8241f3ebb85c056b509d4327ad0358fbbba6ffb340bf388f26350aeda225b1" -dependencies = [ - "serde", -] - [[package]] name = "bindgen" version = "0.69.4" @@ -511,7 +502,7 @@ dependencies = [ "proc-macro2", "quote", "regex", - "rustc-hash", + "rustc-hash 1.1.0", "shlex", "syn 2.0.76", "which", @@ -691,6 +682,12 @@ dependencies = [ "shlex", ] +[[package]] +name = "cesu8" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c" + [[package]] name = "cexpr" version = "0.6.0" @@ -770,7 +767,7 @@ version = "4.5.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "501d359d5f3dcaf6ecdeee48833ae73ec6e42723a1e52419c79abf9507eec0a0" dependencies = [ - "heck 0.5.0", + "heck", "proc-macro2", "quote", "syn 2.0.76", @@ -2002,15 +1999,15 @@ checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" [[package]] name = "gloo-net" -version = "0.4.0" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ac9e8288ae2c632fa9f8657ac70bfe38a1530f345282d7ba66a1f70b72b7dc4" +checksum = "c06f627b1a58ca3d42b45d6104bf1e1a03799df472df00988b6ba21accc10580" dependencies = [ "futures-channel", "futures-core", "futures-sink", "gloo-utils", - "http 0.2.12", + "http 1.1.0", "js-sys", "pin-project", "serde", @@ -2131,12 +2128,6 @@ dependencies = [ "fxhash", ] -[[package]] -name = "heck" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" - [[package]] name = "heck" version = "0.5.0" @@ -2312,7 +2303,7 @@ dependencies = [ "hyper 0.14.30", "log", "rustls 0.20.9", - "rustls-native-certs", + "rustls-native-certs 0.6.3", "tokio", "tokio-rustls 0.23.4", ] @@ -2326,13 +2317,29 @@ dependencies = [ "futures-util", "http 0.2.12", "hyper 0.14.30", - "log", "rustls 0.21.12", - "rustls-native-certs", "tokio", "tokio-rustls 0.24.1", ] +[[package]] +name = "hyper-rustls" +version = "0.27.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ee4be2c948921a1a5320b629c4193916ed787a7f7f293fd3f7f5a6c9de74155" +dependencies = [ + "futures-util", + "http 1.1.0", + "hyper 1.4.1", + "hyper-util", + "log", + "rustls 0.23.12", + "rustls-pki-types", + "tokio", + "tokio-rustls 0.26.0", + "tower-service", +] + [[package]] name = "hyper-timeout" version = "0.5.1" @@ -2545,6 +2552,26 @@ version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" +[[package]] +name = "jni" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6df18c2e3db7e453d3c6ac5b3e9d5182664d28788126d39b91f2d1e22b017ec" +dependencies = [ + "cesu8", + "combine", + "jni-sys", + "log", + "thiserror", + "walkdir", +] + +[[package]] +name = "jni-sys" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" + [[package]] name = "jobserver" version = "0.1.32" @@ -2576,9 +2603,9 @@ dependencies = [ [[package]] name = "jsonrpsee" -version = "0.20.4" +version = "0.24.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "138572befc78a9793240645926f30161f8b4143d2be18d09e44ed9814bd7ee2c" +checksum = "5ec465b607a36dc5dd45d48b7689bc83f679f66a3ac6b6b21cc787a11e0f8685" dependencies = [ "jsonrpsee-client-transport", "jsonrpsee-core", @@ -2594,64 +2621,72 @@ dependencies = [ [[package]] name = "jsonrpsee-client-transport" -version = "0.20.4" +version = "0.24.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c671353e4adf926799107bd7f5724a06b6bc0a333db442a0843c58640bdd0c1" +checksum = "90f0977f9c15694371b8024c35ab58ca043dbbf4b51ccb03db8858a021241df1" dependencies = [ + "base64 0.22.1", "futures-channel", "futures-util", "gloo-net", - "http 0.2.12", + "http 1.1.0", "jsonrpsee-core", "pin-project", - "rustls-native-certs", + "rustls 0.23.12", + "rustls-pki-types", + "rustls-platform-verifier", "soketto", "thiserror", "tokio", - "tokio-rustls 0.24.1", + "tokio-rustls 0.26.0", "tokio-util", "tracing", "url", - "webpki-roots", ] [[package]] name = "jsonrpsee-core" -version = "0.20.4" +version = "0.24.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f24ea59b037b6b9b0e2ebe2c30a3e782b56bd7c76dcc5d6d70ba55d442af56e3" +checksum = "e942c55635fbf5dc421938b8558a8141c7e773720640f4f1dbe1f4164ca4e221" dependencies = [ - "anyhow", - "async-lock 2.8.0", "async-trait", - "beef", + "bytes", "futures-timer", "futures-util", - "hyper 0.14.30", + "http 1.1.0", + "http-body 1.0.1", + "http-body-util", "jsonrpsee-types", "parking_lot", + "pin-project", "rand", - "rustc-hash", + "rustc-hash 2.0.0", "serde", "serde_json", - "soketto", "thiserror", "tokio", + "tokio-stream", "tracing", "wasm-bindgen-futures", ] [[package]] name = "jsonrpsee-http-client" -version = "0.20.4" +version = "0.24.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57c7b9f95208927653e7965a98525e7fc641781cab89f0e27c43fa2974405683" +checksum = "e33774602df12b68a2310b38a535733c477ca4a498751739f89fe8dbbb62ec4c" dependencies = [ "async-trait", - "hyper 0.14.30", - "hyper-rustls 0.24.2", + "base64 0.22.1", + "http-body 1.0.1", + "hyper 1.4.1", + "hyper-rustls 0.27.2", + "hyper-util", "jsonrpsee-core", "jsonrpsee-types", + "rustls 0.23.12", + "rustls-platform-verifier", "serde", "serde_json", "thiserror", @@ -2663,28 +2698,32 @@ dependencies = [ [[package]] name = "jsonrpsee-proc-macros" -version = "0.20.4" +version = "0.24.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcc0eba68ba205452bcb4c7b80a79ddcb3bf36c261a841b239433142db632d24" +checksum = "6b07a2daf52077ab1b197aea69a5c990c060143835bf04c77070e98903791715" dependencies = [ - "heck 0.4.1", - "proc-macro-crate 1.3.1", + "heck", + "proc-macro-crate", "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.76", ] [[package]] name = "jsonrpsee-server" -version = "0.20.4" +version = "0.24.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a482bc4e25eebd0adb61a3468c722763c381225bd3ec46e926f709df8a8eb548" +checksum = "038fb697a709bec7134e9ccbdbecfea0e2d15183f7140254afef7c5610a3f488" dependencies = [ "futures-util", - "http 0.2.12", - "hyper 0.14.30", + "http 1.1.0", + "http-body 1.0.1", + "http-body-util", + "hyper 1.4.1", + "hyper-util", "jsonrpsee-core", "jsonrpsee-types", + "pin-project", "route-recognizer", "serde", "serde_json", @@ -2699,23 +2738,21 @@ dependencies = [ [[package]] name = "jsonrpsee-types" -version = "0.20.4" +version = "0.24.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3264e339143fe37ed081953842ee67bfafa99e3b91559bdded6e4abd8fc8535e" +checksum = "23b67d6e008164f027afbc2e7bb79662650158d26df200040282d2aa1cbb093b" dependencies = [ - "anyhow", - "beef", + "http 1.1.0", "serde", "serde_json", "thiserror", - "tracing", ] [[package]] name = "jsonrpsee-wasm-client" -version = "0.20.4" +version = "0.24.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9437dd0e8728897d0aa5a0075b8710266300e55ced07101ca0930fac4a611384" +checksum = "0470d0ae043ffcb0cd323797a631e637fb4b55fe3eaa6002934819458bba62a7" dependencies = [ "jsonrpsee-client-transport", "jsonrpsee-core", @@ -2724,11 +2761,11 @@ dependencies = [ [[package]] name = "jsonrpsee-ws-client" -version = "0.20.4" +version = "0.24.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d06eeabbb55f0af8405288390a358ebcceb6e79e1390741e6f152309c4d6076" +checksum = "992bf67d1132f88edf4a4f8cff474cf01abb2be203004a2b8e11c2b20795b99e" dependencies = [ - "http 0.2.12", + "http 1.1.0", "jsonrpsee-client-transport", "jsonrpsee-core", "jsonrpsee-types", @@ -3193,7 +3230,7 @@ version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "af1844ef2428cc3e1cb900be36181049ef3d3193c63e43026cfe202983b27a56" dependencies = [ - "proc-macro-crate 3.2.0", + "proc-macro-crate", "proc-macro2", "quote", "syn 2.0.76", @@ -3302,7 +3339,7 @@ version = "3.6.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d830939c76d294956402033aee57a6da7b438f2294eb94864c37b0569053a42c" dependencies = [ - "proc-macro-crate 3.2.0", + "proc-macro-crate", "proc-macro2", "quote", "syn 1.0.109", @@ -3711,23 +3748,13 @@ dependencies = [ "uint", ] -[[package]] -name = "proc-macro-crate" -version = "1.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" -dependencies = [ - "once_cell", - "toml_edit 0.19.15", -] - [[package]] name = "proc-macro-crate" version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ecf48c7ca261d60b74ab1a7b20da18bede46776b2e55535cb958eb595c5fa7b" dependencies = [ - "toml_edit 0.22.20", + "toml_edit", ] [[package]] @@ -3795,7 +3822,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5bb182580f71dd070f88d01ce3de9f4da5021db7115d2e1c3605a754153b77c1" dependencies = [ "bytes", - "heck 0.5.0", + "heck", "itertools 0.13.0", "log", "multimap", @@ -4049,7 +4076,7 @@ dependencies = [ "percent-encoding", "pin-project-lite", "rustls 0.21.12", - "rustls-pemfile", + "rustls-pemfile 1.0.4", "serde", "serde_json", "serde_urlencoded", @@ -4062,7 +4089,7 @@ dependencies = [ "wasm-bindgen", "wasm-bindgen-futures", "web-sys", - "webpki-roots", + "webpki-roots 0.25.4", "winreg", ] @@ -4544,6 +4571,12 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" +[[package]] +name = "rustc-hash" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "583034fd73374156e66797ed8e5b0d5690409c9226b22d87cb7f19821c05d152" + [[package]] name = "rustc-hex" version = "2.1.0" @@ -4619,6 +4652,7 @@ dependencies = [ "aws-lc-rs", "log", "once_cell", + "ring 0.17.8", "rustls-pki-types", "rustls-webpki 0.102.7", "subtle", @@ -4632,7 +4666,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a9aace74cb666635c918e9c12bc0d348266037aa8eb599b5cba565709a8dff00" dependencies = [ "openssl-probe", - "rustls-pemfile", + "rustls-pemfile 1.0.4", + "schannel", + "security-framework", +] + +[[package]] +name = "rustls-native-certs" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5bfb394eeed242e909609f56089eecfe5fda225042e8b171791b9c95f5931e5" +dependencies = [ + "openssl-probe", + "rustls-pemfile 2.1.3", + "rustls-pki-types", "schannel", "security-framework", ] @@ -4646,12 +4693,49 @@ dependencies = [ "base64 0.21.7", ] +[[package]] +name = "rustls-pemfile" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "196fe16b00e106300d3e45ecfcb764fa292a535d7326a29a5875c579c7417425" +dependencies = [ + "base64 0.22.1", + "rustls-pki-types", +] + [[package]] name = "rustls-pki-types" version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc0a2ce646f8655401bb81e7927b812614bd5d91dbc968696be50603510fcaf0" +[[package]] +name = "rustls-platform-verifier" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "afbb878bdfdf63a336a5e63561b1835e7a8c91524f51621db870169eac84b490" +dependencies = [ + "core-foundation", + "core-foundation-sys", + "jni", + "log", + "once_cell", + "rustls 0.23.12", + "rustls-native-certs 0.7.3", + "rustls-platform-verifier-android", + "rustls-webpki 0.102.7", + "security-framework", + "security-framework-sys", + "webpki-roots 0.26.3", + "winapi", +] + +[[package]] +name = "rustls-platform-verifier-android" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f87165f0995f63a9fbeea62b64d10b4d9d8e78ec6d7d51fb2125fda7bb36788f" + [[package]] name = "rustls-webpki" version = "0.101.7" @@ -4722,7 +4806,7 @@ version = "2.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2d35494501194174bda522a32605929eefc9ecf7e0a326c26db1fdd85881eb62" dependencies = [ - "proc-macro-crate 3.2.0", + "proc-macro-crate", "proc-macro2", "quote", "syn 1.0.109", @@ -4800,6 +4884,7 @@ dependencies = [ "core-foundation", "core-foundation-sys", "libc", + "num-bigint", "security-framework-sys", ] @@ -4917,19 +5002,6 @@ dependencies = [ "syn 2.0.76", ] -[[package]] -name = "sha-1" -version = "0.9.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99cd6713db3cf16b6c84e06321e049a9b9f699826e16096d23bbcc44d15d51a6" -dependencies = [ - "block-buffer 0.9.0", - "cfg-if", - "cpufeatures", - "digest 0.9.0", - "opaque-debug", -] - [[package]] name = "sha1" version = "0.10.6" @@ -5076,18 +5148,18 @@ dependencies = [ [[package]] name = "soketto" -version = "0.7.1" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41d1c5305e39e09653383c2c7244f2f78b3bcae37cf50c64cb4789c9f5096ec2" +checksum = "37468c595637c10857701c990f93a40ce0e357cedb0953d1c26c8d8027f9bb53" dependencies = [ - "base64 0.13.1", + "base64 0.22.1", "bytes", "futures", - "http 0.2.12", + "http 1.1.0", "httparse", "log", "rand", - "sha-1", + "sha1", ] [[package]] @@ -5222,7 +5294,7 @@ version = "0.26.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be" dependencies = [ - "heck 0.5.0", + "heck", "proc-macro2", "quote", "rustversion", @@ -5527,7 +5599,7 @@ dependencies = [ "tokio", "tokio-rustls 0.24.1", "tungstenite", - "webpki-roots", + "webpki-roots 0.25.4", ] [[package]] @@ -5553,7 +5625,7 @@ dependencies = [ "serde", "serde_spanned", "toml_datetime", - "toml_edit 0.22.20", + "toml_edit", ] [[package]] @@ -5565,17 +5637,6 @@ dependencies = [ "serde", ] -[[package]] -name = "toml_edit" -version = "0.19.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" -dependencies = [ - "indexmap 2.4.0", - "toml_datetime", - "winnow 0.5.40", -] - [[package]] name = "toml_edit" version = "0.22.20" @@ -5586,7 +5647,7 @@ dependencies = [ "serde", "serde_spanned", "toml_datetime", - "winnow 0.6.18", + "winnow", ] [[package]] @@ -6069,6 +6130,15 @@ version = "0.25.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" +[[package]] +name = "webpki-roots" +version = "0.26.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd7c23921eeb1713a4e851530e9b9756e4fb0e89978582942612524cf09f01cd" +dependencies = [ + "rustls-pki-types", +] + [[package]] name = "which" version = "4.4.2" @@ -6322,15 +6392,6 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" -[[package]] -name = "winnow" -version = "0.5.40" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" -dependencies = [ - "memchr", -] - [[package]] name = "winnow" version = "0.6.18" diff --git a/Cargo.toml b/Cargo.toml index 5db2aff77..d8ba3fdb4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,7 +21,7 @@ ethers = "2.0.14" futures = "0.3.30" futures-util = "0.3.30" itertools = "0.13.0" -jsonrpsee = "0.20.1" +jsonrpsee = "0.24.3" metrics = "0.23.0" mockall = "0.13.0" parse-display = "0.10.0" diff --git a/crates/builder/src/sender/bloxroute.rs b/crates/builder/src/sender/bloxroute.rs index 7137a4c6b..4f79a10c2 100644 --- a/crates/builder/src/sender/bloxroute.rs +++ b/crates/builder/src/sender/bloxroute.rs @@ -150,11 +150,9 @@ struct BloxrouteRequest { } impl ToRpcParams for BloxrouteRequest { - fn to_rpc_params(self) -> std::result::Result>, jsonrpsee::core::Error> { + fn to_rpc_params(self) -> std::result::Result>, serde_json::Error> { let s = String::from_utf8(serde_json::to_vec(&self)?).expect("Valid UTF8 format"); - RawValue::from_string(s) - .map(Some) - .map_err(jsonrpsee::core::Error::ParseError) + RawValue::from_string(s).map(Some) } } diff --git a/crates/builder/src/sender/mod.rs b/crates/builder/src/sender/mod.rs index 41955d7de..779651af0 100644 --- a/crates/builder/src/sender/mod.rs +++ b/crates/builder/src/sender/mod.rs @@ -295,10 +295,10 @@ impl From for TxSenderError { } } -impl From for TxSenderError { - fn from(value: jsonrpsee::core::Error) -> Self { +impl From for TxSenderError { + fn from(value: jsonrpsee::core::ClientError) -> Self { match &value { - jsonrpsee::core::Error::Call(e) => { + jsonrpsee::core::ClientError::Call(e) => { if e.message().contains("replacement transaction underpriced") { TxSenderError::ReplacementUnderpriced } else { diff --git a/crates/rpc/src/metrics.rs b/crates/rpc/src/metrics.rs index 0214daa78..ca21d5bc7 100644 --- a/crates/rpc/src/metrics.rs +++ b/crates/rpc/src/metrics.rs @@ -11,93 +11,135 @@ // You should have received a copy of the GNU General Public License along with Rundler. // If not, see https://www.gnu.org/licenses/. -use std::time::{Duration, Instant}; +use std::{ + collections::HashMap, + time::{Duration, Instant}, +}; -use jsonrpsee::{helpers::MethodResponseResult, server::logger::Logger}; +use futures_util::{future::BoxFuture, FutureExt}; +use jsonrpsee::{server::middleware::rpc::RpcServiceT, types::Request, MethodResponse, Methods}; +use metrics::{Counter, Gauge, Histogram}; +use tower::Layer; #[derive(Clone)] -pub(crate) struct RpcMetricsLogger; - -impl Logger for RpcMetricsLogger { - type Instant = Instant; +pub(crate) struct RpcMetricsMiddlewareLayer { + metrics: RpcMetrics, +} - fn on_connect( - &self, - _remote_addr: std::net::SocketAddr, - _request: &jsonrpsee::server::logger::HttpRequest, - _t: jsonrpsee::server::logger::TransportProtocol, - ) { +impl RpcMetricsMiddlewareLayer { + pub(crate) fn new(methods: &Methods) -> Self { + Self { + metrics: RpcMetrics::new(methods), + } } +} - fn on_request( - &self, - _transport: jsonrpsee::server::logger::TransportProtocol, - ) -> Self::Instant { - Instant::now() - } +impl Layer for RpcMetricsMiddlewareLayer { + type Service = RpcMetricsMiddleware; - fn on_call( - &self, - method_name: &str, - _params: jsonrpsee::types::Params<'_>, - _kind: jsonrpsee::server::logger::MethodKind, - _transport: jsonrpsee::server::logger::TransportProtocol, - ) { - RpcMetrics::increment_num_requests(method_name.to_string()); - RpcMetrics::increment_open_requests(method_name.to_string()); + fn layer(&self, service: S) -> Self::Service { + RpcMetricsMiddleware { + service, + metrics: self.metrics.clone(), + } } +} - fn on_result( - &self, - method_name: &str, - result: MethodResponseResult, - started_at: Self::Instant, - _transport: jsonrpsee::server::logger::TransportProtocol, - ) { - RpcMetrics::record_request_latency(method_name.to_string(), started_at.elapsed()); - RpcMetrics::decrement_open_requests(method_name.to_string()); - - if let MethodResponseResult::Failed(_) = result { - RpcMetrics::increment_rpc_error_count(method_name.to_string()); +#[derive(Clone)] +pub(crate) struct RpcMetricsMiddleware { + service: S, + metrics: RpcMetrics, +} + +impl<'a, S> RpcServiceT<'a> for RpcMetricsMiddleware +where + S: RpcServiceT<'a> + Send + Sync + Clone + 'static, +{ + type Future = BoxFuture<'a, MethodResponse>; + + fn call(&self, req: Request<'a>) -> Self::Future { + let method_metrics = self + .metrics + .method_metrics + .get(req.method.as_ref()) + .unwrap() + .clone(); + + method_metrics.increment_open_requests(); + method_metrics.increment_num_requests(); + let start = Instant::now(); + let svc = self.service.clone(); + + async move { + let rp = svc.call(req).await; + + method_metrics.record_request_latency(start.elapsed()); + method_metrics.decrement_open_requests(); + if rp.is_error() { + method_metrics.increment_error_count(); + } + + rp } + .boxed() } +} - fn on_response( - &self, - _result: &str, - _started_at: Self::Instant, - _transport: jsonrpsee::server::logger::TransportProtocol, - ) { - } +#[derive(Clone)] +struct RpcMetrics { + method_metrics: HashMap<&'static str, MethodMetrics>, +} - fn on_disconnect( - &self, - _remote_addr: std::net::SocketAddr, - _transport: jsonrpsee::server::logger::TransportProtocol, - ) { +impl RpcMetrics { + fn new(methods: &Methods) -> Self { + Self { + method_metrics: HashMap::from_iter( + methods + .method_names() + .map(|name| (name, MethodMetrics::new(name))), + ), + } } } -pub(crate) struct RpcMetrics {} +#[derive(Clone)] +struct MethodMetrics { + num_requests: Counter, + open_requests: Gauge, + error_count: Counter, + request_latency: Histogram, +} -impl RpcMetrics { - fn increment_num_requests(method_name: String) { - metrics::counter!("rpc_num_requests", "method_name" => method_name).increment(1); +impl MethodMetrics { + fn new(method_name: &str) -> Self { + Self { + num_requests: metrics::counter!("rpc_num_requests", "method_name" => method_name.to_string()), + open_requests: metrics::gauge!("rpc_open_requests", "method_name" => method_name.to_string()), + error_count: metrics::counter!("rpc_error_count", "method_name" => method_name.to_string()), + request_latency: metrics::histogram!( + "rpc_request_latency", + "method_name" => method_name.to_string() + ), + } + } + + fn increment_num_requests(&self) { + self.num_requests.increment(1); } - fn increment_open_requests(method_name: String) { - metrics::gauge!("rpc_open_requests", "method_name" => method_name).increment(1_f64); + fn increment_open_requests(&self) { + self.open_requests.increment(1); } - fn decrement_open_requests(method_name: String) { - metrics::gauge!("rpc_open_requests", "method_name" => method_name).decrement(1_f64); + fn decrement_open_requests(&self) { + self.open_requests.decrement(1); } - fn increment_rpc_error_count(method_name: String) { - metrics::counter!("rpc_error_count", "method_name" => method_name).increment(1); + fn increment_error_count(&self) { + self.error_count.increment(1); } - fn record_request_latency(method_name: String, latency: Duration) { - metrics::histogram!("rpc_request_latency", "method_name" => method_name).record(latency); + fn record_request_latency(&self, latency: Duration) { + self.request_latency.record(latency); } } diff --git a/crates/rpc/src/task.rs b/crates/rpc/src/task.rs index 25d4df4b5..91478e29f 100644 --- a/crates/rpc/src/task.rs +++ b/crates/rpc/src/task.rs @@ -17,7 +17,7 @@ use anyhow::bail; use async_trait::async_trait; use ethers::providers::{JsonRpcClient, Provider}; use jsonrpsee::{ - server::{middleware::ProxyGetRequestLayer, ServerBuilder}, + server::{middleware::http::ProxyGetRequestLayer, RpcServiceBuilder, ServerBuilder}, RpcModule, }; use rundler_provider::{EthersEntryPointV0_6, EthersEntryPointV0_7}; @@ -40,7 +40,7 @@ use crate::{ EthApiSettings, UserOperationEventProviderV0_6, UserOperationEventProviderV0_7, }, health::{HealthChecker, SystemApiServer}, - metrics::RpcMetricsLogger, + metrics::RpcMetricsMiddlewareLayer, rundler::{RundlerApi, RundlerApiServer, Settings as RundlerApiSettings}, types::ApiNamespace, }; @@ -177,14 +177,17 @@ where module.merge(health_checker.into_rpc())?; // Set up health check endpoint via GET /health registers the jsonrpc handler - let service_builder = tower::ServiceBuilder::new() + let http_middleware = tower::ServiceBuilder::new() // Proxy `GET /health` requests to internal `system_health` method. .layer(ProxyGetRequestLayer::new("/health", "system_health")?) .timeout(self.args.rpc_timeout); + let rpc_middleware = + RpcServiceBuilder::new().layer(RpcMetricsMiddlewareLayer::new(&module)); + let server = ServerBuilder::default() - .set_logger(RpcMetricsLogger) - .set_middleware(service_builder) + .set_http_middleware(http_middleware) + .set_rpc_middleware(rpc_middleware) .max_connections(self.args.max_connections) // Set max request body size to 2x the max transaction size as none of our // APIs should require more than that. @@ -196,6 +199,7 @@ where .http_only() .build(addr) .await?; + let handle = server.start(module); info!("Started RPC server");