From 0ab7738393e982c1ec1eab833d0d047c20a67e63 Mon Sep 17 00:00:00 2001 From: Bryan Stitt Date: Tue, 21 Feb 2023 21:10:23 -0800 Subject: [PATCH] per-chain rpc rate limits --- TODO.md | 1 + web3_proxy/src/app/mod.rs | 46 +++++++++++++++++++-------------------- 2 files changed, 24 insertions(+), 23 deletions(-) diff --git a/TODO.md b/TODO.md index 5f3e18f3..9766b223 100644 --- a/TODO.md +++ b/TODO.md @@ -334,6 +334,7 @@ These are not yet ordered. There might be duplicates. We might not actually need - [x] improve eth_sendRawTransaction server selection - [x] don't cache methods that are usually very large - [x] use http provider when available +- [x] per-chain rpc rate limits - [ ] don't use new_head_provider anywhere except new head subscription - [-] proxy mode for benchmarking all backends - [-] proxy mode for sending to multiple backends diff --git a/web3_proxy/src/app/mod.rs b/web3_proxy/src/app/mod.rs index 06531264..6735f7f8 100644 --- a/web3_proxy/src/app/mod.rs +++ b/web3_proxy/src/app/mod.rs @@ -645,31 +645,31 @@ impl Web3ProxyApp { let mut login_rate_limiter = None; if let Some(redis_pool) = vredis_pool.as_ref() { - let rpc_rrl = RedisRateLimiter::new( - "web3_proxy", - "frontend", - // TODO: think about this unwrapping - top_config - .app - .public_requests_per_period - .unwrap_or(u64::MAX), - 60.0, - redis_pool.clone(), - ); + if let Some(public_requests_per_period) = top_config.app.public_requests_per_period { + // chain id is included in the app name so that rpc rate limits are per-chain + let rpc_rrl = RedisRateLimiter::new( + &format!("web3_proxy:{}", top_config.app.chain_id), + "frontend", + public_requests_per_period, + 60.0, + redis_pool.clone(), + ); - // these two rate limiters can share the base limiter - // these are deferred rate limiters because we don't want redis network requests on the hot path - // TODO: take cache_size from config - frontend_ip_rate_limiter = Some(DeferredRateLimiter::::new( - 10_000, - "ip", - rpc_rrl.clone(), - None, - )); - frontend_registered_user_rate_limiter = Some(DeferredRateLimiter::::new( - 10_000, "key", rpc_rrl, None, - )); + // these two rate limiters can share the base limiter + // these are deferred rate limiters because we don't want redis network requests on the hot path + // TODO: take cache_size from config + frontend_ip_rate_limiter = Some(DeferredRateLimiter::::new( + 10_000, + "ip", + rpc_rrl.clone(), + None, + )); + frontend_registered_user_rate_limiter = Some(DeferredRateLimiter::::new( + 10_000, "key", rpc_rrl, None, + )); + } + // login rate limiter login_rate_limiter = Some(RedisRateLimiter::new( "web3_proxy", "login",