@@ -44,6 +44,10 @@ pub struct RpcTester<P: Provider<AnyNetwork>> {
4444 /// Whether to call rpc transaction methods for every transaction. Otherwise, just the first of
4545 /// the block.
4646 use_all_txes : bool ,
47+ /// Maximum requests per second for rate limiting.
48+ rate_limit_rps : Option < u32 > ,
49+ /// Last timestamp for rate limiting.
50+ last_request_time : tokio:: sync:: Mutex < std:: time:: Instant > ,
4751}
4852
4953impl < P : Provider < AnyNetwork > > RpcTester < P > {
@@ -196,6 +200,23 @@ where
196200 Ok ( ( block, block_hash, block_tag, block_id) )
197201 }
198202
203+ /// Apply rate limiting if configured.
204+ /// Sleeps if necessary to maintain the configured rate limit.
205+ async fn apply_rate_limit ( & self ) {
206+ if let Some ( rps) = self . rate_limit_rps {
207+ let min_interval = std:: time:: Duration :: from_secs_f64 ( 1.0 / rps as f64 ) ;
208+ let mut last_time = self . last_request_time . lock ( ) . await ;
209+ let now = std:: time:: Instant :: now ( ) ;
210+ let elapsed = now. duration_since ( * last_time) ;
211+ if elapsed < min_interval {
212+ let sleep_time = min_interval - elapsed;
213+ debug ! ( "Rate limiting: sleeping for {:?}" , sleep_time) ;
214+ tokio:: time:: sleep ( sleep_time) . await ;
215+ }
216+ * last_time = std:: time:: Instant :: now ( ) ;
217+ }
218+ }
219+
199220 /// Compares the response to a specific method between both rpcs. Only collects differences.
200221 ///
201222 /// If any namespace is disabled skip it.
@@ -215,6 +236,9 @@ where
215236 return ( name. to_string ( ) , Ok ( ( ) ) ) ;
216237 }
217238
239+ // Apply rate limiting if configured
240+ self . apply_rate_limit ( ) . await ;
241+
218242 trace ! ( "## {name}" ) ;
219243 let t = std:: time:: Instant :: now ( ) ;
220244 let ( rpc1_result, rpc2_result) =
@@ -254,12 +278,21 @@ pub struct RpcTesterBuilder<P: Provider<AnyNetwork>> {
254278 /// Whether to call rpc transaction methods for every transaction. Otherwise, just the first of
255279 /// the block.
256280 use_all_txes : bool ,
281+ /// Maximum requests per second for rate limiting.
282+ rate_limit_rps : Option < u32 > ,
257283}
258284
259285impl < P : Provider < AnyNetwork > > RpcTesterBuilder < P > {
260286 /// Creates a new builder with default settings.
261287 pub const fn new ( rpc1 : P , rpc2 : P ) -> Self {
262- Self { rpc1, rpc2, use_tracing : false , use_reth : false , use_all_txes : false }
288+ Self {
289+ rpc1,
290+ rpc2,
291+ use_tracing : false ,
292+ use_reth : false ,
293+ use_all_txes : false ,
294+ rate_limit_rps : None ,
295+ }
263296 }
264297
265298 /// Enables or disables tracing calls.
@@ -281,6 +314,13 @@ impl<P: Provider<AnyNetwork>> RpcTesterBuilder<P> {
281314 self
282315 }
283316
317+ /// Sets the rate limit in requests per second.
318+ /// If None, no rate limiting is applied.
319+ pub const fn with_rate_limit ( mut self , rps : Option < u32 > ) -> Self {
320+ self . rate_limit_rps = rps;
321+ self
322+ }
323+
284324 /// Builds and returns the [`RpcTester`].
285325 pub fn build ( self ) -> RpcTester < P > {
286326 RpcTester {
@@ -289,6 +329,8 @@ impl<P: Provider<AnyNetwork>> RpcTesterBuilder<P> {
289329 use_tracing : self . use_tracing ,
290330 use_reth : self . use_reth ,
291331 use_all_txes : self . use_all_txes ,
332+ rate_limit_rps : self . rate_limit_rps ,
333+ last_request_time : tokio:: sync:: Mutex :: new ( std:: time:: Instant :: now ( ) ) ,
292334 }
293335 }
294336}
0 commit comments