1use moka::future::Cache;
2use moka::Expiry;
3use std::sync::atomic::AtomicU64;
4use std::sync::Arc;
5use std::time::Duration;
6
7use hopr_crypto_types::prelude::*;
8use hopr_db_api::info::{IndexerData, SafeInfo};
9use hopr_internal_types::prelude::*;
10use hopr_primitive_types::prelude::{Address, Balance, U256};
11
12use crate::errors::DbSqlError;
13
14#[derive(Debug, Clone, PartialEq, strum::EnumDiscriminants)]
17#[strum_discriminants(derive(Hash))]
18pub enum CachedValue {
19 IndexerDataCache(IndexerData),
21 SafeInfoCache(Option<SafeInfo>),
23}
24
25impl TryFrom<CachedValue> for IndexerData {
26 type Error = DbSqlError;
27
28 fn try_from(value: CachedValue) -> Result<Self, Self::Error> {
29 match value {
30 CachedValue::IndexerDataCache(data) => Ok(data),
31 _ => Err(DbSqlError::DecodingError),
32 }
33 }
34}
35
36impl TryFrom<CachedValue> for Option<SafeInfo> {
37 type Error = DbSqlError;
38
39 fn try_from(value: CachedValue) -> Result<Self, Self::Error> {
40 match value {
41 CachedValue::SafeInfoCache(data) => Ok(data),
42 _ => Err(DbSqlError::DecodingError),
43 }
44 }
45}
46
47struct ExpiryNever;
48
49impl<K, V> Expiry<K, V> for ExpiryNever {
50 fn expire_after_create(&self, _key: &K, _value: &V, _current_time: std::time::Instant) -> Option<Duration> {
51 None
52 }
53}
54
55#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
56pub(crate) struct ChannelParties(pub(crate) Address, pub(crate) Address);
57
58#[derive(Debug, Clone)]
60pub struct HoprDbCaches {
61 pub(crate) single_values: Cache<CachedValueDiscriminants, CachedValue>,
62 pub(crate) unacked_tickets: Cache<HalfKeyChallenge, PendingAcknowledgement>,
63 pub(crate) ticket_index: Cache<Hash, Arc<AtomicU64>>,
64 pub(crate) unrealized_value: Cache<(Hash, U256), Balance>,
67 pub(crate) chain_to_offchain: Cache<Address, Option<OffchainPublicKey>>,
68 pub(crate) offchain_to_chain: Cache<OffchainPublicKey, Option<Address>>,
69 pub(crate) src_dst_to_channel: Cache<ChannelParties, Option<ChannelEntry>>,
70}
71
72impl Default for HoprDbCaches {
73 fn default() -> Self {
74 let single_values = Cache::builder().time_to_idle(Duration::from_secs(1800)).build();
75
76 let unacked_tickets = Cache::builder()
77 .time_to_live(Duration::from_secs(30))
78 .max_capacity(1_000_000_000)
79 .build();
80
81 let ticket_index = Cache::builder().expire_after(ExpiryNever).max_capacity(10_000).build();
82
83 let unrealized_value = Cache::builder().expire_after(ExpiryNever).max_capacity(10_000).build();
84
85 let chain_to_offchain = Cache::builder()
86 .time_to_live(Duration::from_secs(600))
87 .max_capacity(100_000)
88 .build();
89
90 let offchain_to_chain = Cache::builder()
91 .time_to_live(Duration::from_secs(600))
92 .max_capacity(100_000)
93 .build();
94
95 let src_dst_to_channel = Cache::builder()
96 .time_to_live(Duration::from_secs(600))
97 .max_capacity(10_000)
98 .build();
99
100 Self {
101 single_values,
102 unacked_tickets,
103 ticket_index,
104 unrealized_value,
105 chain_to_offchain,
106 offchain_to_chain,
107 src_dst_to_channel,
108 }
109 }
110}
111
112impl HoprDbCaches {
113 pub fn invalidate_all(&self) {
115 self.single_values.invalidate_all();
116 self.unacked_tickets.invalidate_all();
117 self.unrealized_value.invalidate_all();
118 self.chain_to_offchain.invalidate_all();
119 self.offchain_to_chain.invalidate_all();
120 self.src_dst_to_channel.invalidate_all();
121 }
122}