barreleye_common/cache/
mod.rs

1use async_trait::async_trait;
2use derive_more::Display;
3use eyre::{Result, WrapErr};
4use serde::{de::DeserializeOwned, Deserialize, Serialize};
5use std::sync::Arc;
6
7use crate::{cache::rocksdb::RocksDb, Settings};
8
9mod rocksdb;
10
11#[derive(Display, Debug, Clone)]
12pub enum CacheKey {
13	#[display(fmt = "ex:{}:{}", "_0", "_1")]
14	EvmSmartContract(u64, String), /* (network_id, address) ->
15	                                * is_smart_contract: bool */
16	#[display(fmt = "bx:{}:{}", "_0", "_1")]
17	BitcoinTxIndex(u64, String), // (network_id, txid) -> block_height: u64
18}
19
20impl From<CacheKey> for String {
21	fn from(cache_key: CacheKey) -> String {
22		cache_key.to_string()
23	}
24}
25
26#[derive(Display, Debug, Serialize, Deserialize, Eq, PartialEq)]
27pub enum Driver {
28	#[display(fmt = "RocksDB")]
29	#[serde(rename = "rocksdb")]
30	RocksDB,
31}
32
33#[async_trait]
34pub trait CacheTrait: Send + Sync {
35	async fn set(&self, cache_key: &str, value: &[u8]) -> Result<()>;
36	async fn get(&self, cache_key: &str) -> Result<Option<Vec<u8>>>;
37	async fn delete(&self, cache_key: &str) -> Result<()>;
38}
39
40pub struct Cache {
41	settings: Arc<Settings>,
42	cache: Box<dyn CacheTrait>,
43}
44
45impl Cache {
46	pub async fn new(settings: Arc<Settings>) -> Result<Self> {
47		Ok(Self {
48			settings: settings.clone(),
49			cache: match settings.cache.driver {
50				Driver::RocksDB => Box::new(
51					RocksDb::new(settings.clone(), true)
52						.await
53						.wrap_err(settings.dsn.rocksdb.clone())?,
54				),
55			},
56		})
57	}
58
59	pub async fn set_read_only(&mut self, is_read_only: bool) -> Result<()> {
60		self.cache = match self.settings.cache.driver {
61			Driver::RocksDB => Box::new(RocksDb::new(self.settings.clone(), is_read_only).await?),
62		};
63
64		Ok(())
65	}
66
67	pub async fn set<T>(&self, cache_key: CacheKey, value: T) -> Result<()>
68	where
69		T: Serialize,
70	{
71		let key = cache_key.to_string();
72		let value = rmp_serde::to_vec(&value)?;
73
74		self.cache.set(&key, &value).await
75	}
76
77	pub async fn get<T>(&self, cache_key: CacheKey) -> Result<Option<T>>
78	where
79		T: DeserializeOwned,
80	{
81		let key = cache_key.to_string();
82		Ok(self.cache.get(&key).await?.and_then(|v| rmp_serde::from_slice(&v).ok()))
83	}
84
85	pub async fn delete(&self, cache_key: CacheKey) -> Result<()> {
86		let key = cache_key.to_string();
87		self.cache.delete(&key).await
88	}
89}