Add a cache for the credentials seen before on top-up

This commit is contained in:
Bogdan-Ștefan Neacşu
2025-05-16 15:38:23 +03:00
parent 7a9c41ad73
commit aa58c80db9
3 changed files with 63 additions and 1 deletions
@@ -10,3 +10,4 @@ pub mod error;
pub mod mixnet_client;
pub mod mixnet_listener;
mod peer_manager;
mod seen_credential_cache;
@@ -7,7 +7,7 @@ use std::{
time::{Duration, SystemTime},
};
use crate::{config::Config, error::*};
use crate::{config::Config, error::*, seen_credential_cache::SeenCredentialCache};
use crate::{error::AuthenticatorError, peer_manager::PeerManager};
use defguard_wireguard_rs::net::IpAddrMask;
use defguard_wireguard_rs::{host::Peer, key::Key};
@@ -77,6 +77,8 @@ pub(crate) struct MixnetListener {
pub(crate) ecash_verifier: Option<Arc<EcashManager>>,
pub(crate) timeout_check_interval: IntervalStream,
pub(crate) seen_credential_cache: SeenCredentialCache,
}
impl MixnetListener {
@@ -98,6 +100,7 @@ impl MixnetListener {
peer_manager: PeerManager::new(wireguard_gateway_data),
ecash_verifier,
timeout_check_interval,
seen_credential_cache: SeenCredentialCache::new(),
}
}
@@ -0,0 +1,58 @@
// Copyright 2025 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use std::{
collections::HashMap,
time::{Duration, SystemTime},
};
use nym_credentials_interface::CredentialSpendingData;
use nym_wireguard_types::PeerPublicKey;
const SEEN_CREDENTIAL_CACHE_TIME: Duration = Duration::from_secs(60 * 60); // 1 hour
#[derive(Eq, Hash, PartialEq)]
struct TimestampedPeerPubKey {
peer_pub_key: PeerPublicKey,
timestamp: SystemTime,
}
pub(crate) struct SeenCredentialCache {
cached_credentials: HashMap<String, TimestampedPeerPubKey>,
}
impl SeenCredentialCache {
pub(crate) fn new() -> Self {
SeenCredentialCache {
cached_credentials: HashMap::new(),
}
}
pub(crate) fn insert_credential(
&mut self,
credential: CredentialSpendingData,
peer_pub_key: PeerPublicKey,
) {
let value = TimestampedPeerPubKey {
peer_pub_key,
timestamp: SystemTime::now(),
};
self.cached_credentials
.insert(credential.serial_number_b58(), value);
}
pub(crate) fn contains(&self, credential: &CredentialSpendingData) -> bool {
self.cached_credentials
.contains_key(&credential.serial_number_b58())
}
pub(crate) fn remove_stale(&mut self) {
let now = SystemTime::now();
self.cached_credentials.retain(|_, value| {
let Ok(cache_time) = now.duration_since(value.timestamp) else {
return false;
};
cache_time < SEEN_CREDENTIAL_CACHE_TIME
});
}
}