RPC: add caching to getLargestAccounts (#15154)
* introduce get largest accounts cache * remove cache size and change hash key * remove eq and hash derivation from commitment config * add slot to the cache
This commit is contained in:
@@ -8,6 +8,7 @@ pub mod mock_sender;
|
||||
pub mod nonce_utils;
|
||||
pub mod perf_utils;
|
||||
pub mod pubsub_client;
|
||||
pub mod rpc_cache;
|
||||
pub mod rpc_client;
|
||||
pub mod rpc_config;
|
||||
pub mod rpc_custom_error;
|
||||
|
75
client/src/rpc_cache.rs
Normal file
75
client/src/rpc_cache.rs
Normal file
@@ -0,0 +1,75 @@
|
||||
use crate::{rpc_config::RpcLargestAccountsFilter, rpc_response::RpcAccountBalance};
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
time::{Duration, SystemTime},
|
||||
};
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct LargestAccountsCache {
|
||||
duration: u64,
|
||||
cache: HashMap<Option<RpcLargestAccountsFilter>, LargestAccountsCacheValue>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
struct LargestAccountsCacheValue {
|
||||
accounts: Vec<RpcAccountBalance>,
|
||||
slot: u64,
|
||||
cached_time: SystemTime,
|
||||
}
|
||||
|
||||
impl LargestAccountsCache {
|
||||
pub fn new(duration: u64) -> Self {
|
||||
Self {
|
||||
duration,
|
||||
cache: HashMap::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_largest_accounts(
|
||||
&self,
|
||||
filter: &Option<RpcLargestAccountsFilter>,
|
||||
) -> Option<(u64, Vec<RpcAccountBalance>)> {
|
||||
self.cache.get(&filter).and_then(|value| {
|
||||
if let Ok(elapsed) = value.cached_time.elapsed() {
|
||||
if elapsed < Duration::from_secs(self.duration) {
|
||||
return Some((value.slot, value.accounts.clone()));
|
||||
}
|
||||
}
|
||||
None
|
||||
})
|
||||
}
|
||||
|
||||
pub fn set_largest_accounts(
|
||||
&mut self,
|
||||
filter: &Option<RpcLargestAccountsFilter>,
|
||||
slot: u64,
|
||||
accounts: &[RpcAccountBalance],
|
||||
) {
|
||||
self.cache.insert(
|
||||
filter.clone(),
|
||||
LargestAccountsCacheValue {
|
||||
accounts: accounts.to_owned(),
|
||||
slot,
|
||||
cached_time: SystemTime::now(),
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
pub mod test {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_old_entries_expire() {
|
||||
let mut cache = LargestAccountsCache::new(1);
|
||||
|
||||
let filter = Some(RpcLargestAccountsFilter::Circulating);
|
||||
|
||||
let accounts: Vec<RpcAccountBalance> = Vec::new();
|
||||
|
||||
cache.set_largest_accounts(&filter, 1000, &accounts);
|
||||
std::thread::sleep(Duration::from_secs(1));
|
||||
assert_eq!(cache.get_largest_accounts(&filter), None);
|
||||
}
|
||||
}
|
@@ -31,7 +31,7 @@ pub struct RpcSimulateTransactionConfig {
|
||||
pub encoding: Option<UiTransactionEncoding>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub enum RpcLargestAccountsFilter {
|
||||
Circulating,
|
||||
|
Reference in New Issue
Block a user