use crate::rpc::eth::{filter::Filter, filter::FilterManager, FilterID};
use crate::rpc::Arc;
use ahash::AHashMap as HashMap;
use anyhow::{Context, Result};
use parking_lot::RwLock;
use std::any::Any;
#[allow(dead_code)]
#[derive(Debug, PartialEq)]
pub struct MempoolFilter {
id: FilterID, max_results: usize, }
impl MempoolFilter {
pub fn new(max_results: usize) -> Result<Arc<Self>, uuid::Error> {
let id = FilterID::new()?;
Ok(Arc::new(Self { id, max_results }))
}
}
impl Filter for MempoolFilter {
fn id(&self) -> &FilterID {
&self.id
}
fn as_any(&self) -> &dyn Any {
self
}
}
#[derive(Debug)]
pub struct MempoolFilterManager {
filters: RwLock<HashMap<FilterID, Arc<dyn Filter>>>,
max_filter_results: usize,
}
impl MempoolFilterManager {
pub fn new(max_filter_results: usize) -> Arc<Self> {
Arc::new(Self {
filters: RwLock::new(HashMap::new()),
max_filter_results,
})
}
}
impl FilterManager for MempoolFilterManager {
fn install(&self) -> Result<Arc<dyn Filter>> {
let filter = MempoolFilter::new(self.max_filter_results)
.context("Failed to create a new mempool filter")?;
let id = filter.id().clone();
self.filters.write().insert(id, filter.clone());
Ok(filter)
}
fn remove(&self, id: &FilterID) -> Option<Arc<dyn Filter>> {
let mut filters = self.filters.write();
filters.remove(id)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_mempool_filter() {
let max_results = 10;
let filter = MempoolFilter::new(max_results).expect("Failed to create mempool filter");
assert_eq!(filter.max_results, max_results);
let mempool_manager = MempoolFilterManager::new(max_results);
let installed_filter = mempool_manager
.install()
.expect("Failed to install mempool filter");
{
let filters = mempool_manager.filters.read();
assert!(filters.contains_key(installed_filter.id()));
}
let filter_id = installed_filter.id().clone();
let removed = mempool_manager.remove(&filter_id);
assert_eq!(
removed.map(|f| f.id().clone()),
Some(installed_filter.id().clone()),
"Filter should be successfully removed"
);
{
let filters = mempool_manager.filters.read();
assert!(!filters.contains_key(&filter_id));
}
}
}