diff --git a/contracts/router-middleware/src/lib.rs b/contracts/router-middleware/src/lib.rs index 6752ade..2926e7c 100644 --- a/contracts/router-middleware/src/lib.rs +++ b/contracts/router-middleware/src/lib.rs @@ -498,6 +498,19 @@ impl RouterMiddleware { .get(&DataKey::CallLog(route)) .unwrap_or(Vec::new(&env)) } + + /// Get the number of call log entries for a route. + /// + /// More efficient than loading the full call log when callers only need + /// the current retained length. + pub fn get_call_log_length(env: Env, route: String) -> u32 { + env.storage() + .instance() + .get::>(&DataKey::CallLog(route)) + .map(|log| log.len()) + .unwrap_or(0) + } + /// Get rate limit state for a caller on a specific route. /// /// Returns the current [`RateLimitState`] for `caller` on `route`, which includes the @@ -821,6 +834,43 @@ mod tests { client.post_call(&caller, &route, &false); } + #[test] + fn test_get_call_log_length_zero_before_calls() { + let (env, admin, client) = setup(); + let route = String::from_str(&env, "oracle/get_price"); + client.configure_route(&admin, &route, &0, &0, &true, &0, &0, &3); + + assert_eq!(client.get_call_log_length(&route), 0); + } + + #[test] + fn test_get_call_log_length_matches_get_call_log() { + let (env, admin, client) = setup(); + let route = String::from_str(&env, "oracle/get_price"); + let caller = Address::generate(&env); + client.configure_route(&admin, &route, &0, &0, &true, &0, &0, &5); + + client.post_call(&caller, &route, &true); + client.post_call(&caller, &route, &false); + + assert_eq!(client.get_call_log_length(&route), client.get_call_log(&route).len()); + } + + #[test] + fn test_get_call_log_length_respects_retention() { + let (env, admin, client) = setup(); + let route = String::from_str(&env, "oracle/get_price"); + let caller = Address::generate(&env); + client.configure_route(&admin, &route, &0, &0, &true, &0, &0, &2); + + client.post_call(&caller, &route, &true); + client.post_call(&caller, &route, &false); + client.post_call(&caller, &route, &true); + + assert_eq!(client.get_call_log_length(&route), 2); + assert_eq!(client.get_call_log(&route).len(), 2); + } + #[test] fn test_rate_limit_isolated_per_route() { let (env, admin, client) = setup();