Compare commits

...

2 Commits

Author SHA1 Message Date
Bogdan-Ștefan Neacşu a75e99d59f Remove empty ephemeral keys 2025-01-21 14:32:26 +01:00
Bogdan-Ștefan Neacşu f6f7d3b175 Uncouple storage reference for bandwidth client 2025-01-21 14:19:59 +01:00
10 changed files with 49 additions and 23 deletions
@@ -15,6 +15,7 @@ pub mod error;
mod manager; mod manager;
mod models; mod models;
#[derive(Clone)]
pub struct OnDiskGatewaysDetails { pub struct OnDiskGatewaysDetails {
manager: StorageManager, manager: StorageManager,
} }
@@ -20,12 +20,12 @@ pub enum InMemStorageError {
MalformedGateway(#[from] BadGateway), MalformedGateway(#[from] BadGateway),
} }
#[derive(Debug, Default)] #[derive(Clone, Debug, Default)]
pub struct InMemGatewaysDetails { pub struct InMemGatewaysDetails {
inner: Arc<RwLock<InMemStorageInner>>, inner: Arc<RwLock<InMemStorageInner>>,
} }
#[derive(Debug, Default)] #[derive(Clone, Debug, Default)]
struct InMemStorageInner { struct InMemStorageInner {
active_gateway: Option<String>, active_gateway: Option<String>,
gateways: HashMap<String, GatewayRegistration>, gateways: HashMap<String, GatewayRegistration>,
@@ -4,6 +4,8 @@
// TODO: combine those more closely. Perhaps into a single underlying store. // TODO: combine those more closely. Perhaps into a single underlying store.
// Like for persistent, on-disk, storage, what's the point of having 3 different databases? // Like for persistent, on-disk, storage, what's the point of having 3 different databases?
use rand::rngs::OsRng;
use crate::client::key_manager::persistence::{InMemEphemeralKeys, KeyStore}; use crate::client::key_manager::persistence::{InMemEphemeralKeys, KeyStore};
use crate::client::replies::reply_storage; use crate::client::replies::reply_storage;
use crate::client::replies::reply_storage::ReplyStorageBackend; use crate::client::replies::reply_storage::ReplyStorageBackend;
@@ -63,7 +65,7 @@ pub trait MixnetClientStorage {
fn gateway_details_store(&self) -> &Self::GatewaysDetailsStore; fn gateway_details_store(&self) -> &Self::GatewaysDetailsStore;
} }
#[derive(Default)] #[derive(Clone)]
pub struct Ephemeral { pub struct Ephemeral {
key_store: InMemEphemeralKeys, key_store: InMemEphemeralKeys,
reply_store: reply_storage::Empty, reply_store: reply_storage::Empty,
@@ -71,9 +73,14 @@ pub struct Ephemeral {
gateway_details_store: InMemGatewaysDetails, gateway_details_store: InMemGatewaysDetails,
} }
impl Ephemeral { impl Default for Ephemeral {
pub fn new() -> Self { fn default() -> Self {
Default::default() Ephemeral {
key_store: InMemEphemeralKeys::new(&mut OsRng),
reply_store: Default::default(),
credential_store: Default::default(),
gateway_details_store: Default::default(),
}
} }
} }
@@ -114,6 +121,7 @@ impl MixnetClientStorage for Ephemeral {
} }
} }
#[derive(Clone)]
#[cfg(all( #[cfg(all(
not(target_arch = "wasm32"), not(target_arch = "wasm32"),
feature = "fs-surb-storage", feature = "fs-surb-storage",
@@ -3,7 +3,9 @@
use crate::client::key_manager::ClientKeys; use crate::client::key_manager::ClientKeys;
use async_trait::async_trait; use async_trait::async_trait;
use rand::{CryptoRng, RngCore};
use std::error::Error; use std::error::Error;
use std::sync::Arc;
use tokio::sync::Mutex; use tokio::sync::Mutex;
#[cfg(not(target_arch = "wasm32"))] #[cfg(not(target_arch = "wasm32"))]
@@ -64,6 +66,7 @@ pub enum OnDiskKeysError {
}, },
} }
#[derive(Clone)]
#[cfg(not(target_arch = "wasm32"))] #[cfg(not(target_arch = "wasm32"))]
pub struct OnDiskKeys { pub struct OnDiskKeys {
paths: ClientKeysPaths, paths: ClientKeysPaths,
@@ -193,9 +196,20 @@ impl KeyStore for OnDiskKeys {
} }
} }
#[derive(Default)] #[derive(Clone)]
pub struct InMemEphemeralKeys { pub struct InMemEphemeralKeys {
keys: Mutex<Option<ClientKeys>>, keys: Arc<Mutex<ClientKeys>>,
}
impl InMemEphemeralKeys {
pub fn new<R>(rng: &mut R) -> Self
where
R: RngCore + CryptoRng,
{
InMemEphemeralKeys {
keys: Arc::new(Mutex::new(ClientKeys::generate_new(rng))),
}
}
} }
#[derive(Debug, thiserror::Error)] #[derive(Debug, thiserror::Error)]
@@ -208,11 +222,11 @@ impl KeyStore for InMemEphemeralKeys {
type StorageError = EphemeralKeysError; type StorageError = EphemeralKeysError;
async fn load_keys(&self) -> Result<ClientKeys, Self::StorageError> { async fn load_keys(&self) -> Result<ClientKeys, Self::StorageError> {
self.keys.lock().await.clone().ok_or(EphemeralKeysError) Ok(self.keys.lock().await.clone())
} }
async fn store_keys(&self, keys: &ClientKeys) -> Result<(), Self::StorageError> { async fn store_keys(&self, keys: &ClientKeys) -> Result<(), Self::StorageError> {
*self.keys.lock().await = Some(keys.clone()); *self.keys.lock().await = keys.clone();
Ok(()) Ok(())
} }
} }
@@ -22,7 +22,7 @@ mod error;
mod manager; mod manager;
mod models; mod models;
#[derive(Debug)] #[derive(Clone, Debug)]
pub struct Backend { pub struct Backend {
temporary_old_path: Option<PathBuf>, temporary_old_path: Option<PathBuf>,
database_path: PathBuf, database_path: PathBuf,
@@ -19,7 +19,7 @@ pub mod fs_backend;
#[error("no information provided")] #[error("no information provided")]
pub struct UndefinedError; pub struct UndefinedError;
#[derive(Debug)] #[derive(Clone, Debug)]
pub struct Empty { pub struct Empty {
// we need to keep 'basic' metadata here to "load" the CombinedReplyStorage // we need to keep 'basic' metadata here to "load" the CombinedReplyStorage
pub min_surb_threshold: usize, pub min_surb_threshold: usize,
+1 -1
View File
@@ -19,7 +19,7 @@ use std::error::Error;
// `SELECT total_tickets, used_tickets FROM ecash_ticketbook WHERE expiration_date >= ?`, today_date // `SELECT total_tickets, used_tickets FROM ecash_ticketbook WHERE expiration_date >= ?`, today_date
// then for each calculate the diff total_tickets - used_tickets and multiply the result by the size of the ticket // then for each calculate the diff total_tickets - used_tickets and multiply the result by the size of the ticket
#[async_trait] #[async_trait]
pub trait Storage: Send + Sync { pub trait Storage: Clone + Send + Sync {
type StorageError: Error; type StorageError: Error;
async fn close(&self); async fn close(&self);
@@ -40,6 +40,7 @@ async fn main() {
client.disconnect().await; client.disconnect().await;
} }
#[derive(Clone)]
#[allow(unused)] #[allow(unused)]
struct MockClientStorage { struct MockClientStorage {
pub key_store: MockKeyStore, pub key_store: MockKeyStore,
@@ -96,6 +97,7 @@ impl MixnetClientStorage for MockClientStorage {
} }
} }
#[derive(Clone)]
struct MockKeyStore; struct MockKeyStore;
#[async_trait] #[async_trait]
@@ -115,6 +117,7 @@ impl KeyStore for MockKeyStore {
} }
} }
#[derive(Clone)]
struct MockGatewayDetailsStore; struct MockGatewayDetailsStore;
#[async_trait] #[async_trait]
+6 -6
View File
@@ -17,22 +17,22 @@ use zeroize::Zeroizing;
/// The way to create this client is by calling /// The way to create this client is by calling
/// [`crate::mixnet::DisconnectedMixnetClient::create_bandwidth_client`] on the associated mixnet /// [`crate::mixnet::DisconnectedMixnetClient::create_bandwidth_client`] on the associated mixnet
/// client. /// client.
pub struct BandwidthAcquireClient<'a, St: Storage> { pub struct BandwidthAcquireClient<St: Storage + Clone> {
client: DirectSigningHttpRpcNyxdClient, client: DirectSigningHttpRpcNyxdClient,
storage: &'a St, storage: St,
client_id: Zeroizing<Vec<u8>>, client_id: Zeroizing<Vec<u8>>,
ticketbook_type: TicketType, ticketbook_type: TicketType,
} }
impl<'a, St> BandwidthAcquireClient<'a, St> impl<St> BandwidthAcquireClient<St>
where where
St: Storage, St: Storage + Clone,
<St as Storage>::StorageError: Send + Sync + 'static, <St as Storage>::StorageError: Send + Sync + 'static,
{ {
pub(crate) fn new( pub(crate) fn new(
network_details: NymNetworkDetails, network_details: NymNetworkDetails,
mnemonic: String, mnemonic: String,
storage: &'a St, storage: St,
client_id: Vec<u8>, client_id: Vec<u8>,
ticketbook_type: TicketType, ticketbook_type: TicketType,
) -> Result<Self> { ) -> Result<Self> {
@@ -55,7 +55,7 @@ where
pub async fn acquire(&self) -> Result<()> { pub async fn acquire(&self) -> Result<()> {
issue_credential( issue_credential(
&self.client, &self.client,
self.storage, &self.storage,
self.client_id.deref(), self.client_id.deref(),
self.ticketbook_type, self.ticketbook_type,
) )
+4 -4
View File
@@ -108,7 +108,7 @@ impl MixnetClientBuilder<OnDiskPersistent> {
impl<S> MixnetClientBuilder<S> impl<S> MixnetClientBuilder<S>
where where
S: MixnetClientStorage + 'static, S: MixnetClientStorage + Clone + 'static,
S::ReplyStore: Send + Sync, S::ReplyStore: Send + Sync,
S::GatewaysDetailsStore: Sync, S::GatewaysDetailsStore: Sync,
<S::ReplyStore as ReplyStorageBackend>::StorageError: Sync + Send, <S::ReplyStore as ReplyStorageBackend>::StorageError: Sync + Send,
@@ -326,7 +326,7 @@ where
/// client. /// client.
pub struct DisconnectedMixnetClient<S> pub struct DisconnectedMixnetClient<S>
where where
S: MixnetClientStorage, S: MixnetClientStorage + Clone,
{ {
/// Client configuration /// Client configuration
config: Config, config: Config,
@@ -371,7 +371,7 @@ where
impl<S> DisconnectedMixnetClient<S> impl<S> DisconnectedMixnetClient<S>
where where
S: MixnetClientStorage + 'static, S: MixnetClientStorage + Clone + 'static,
S::ReplyStore: Send + Sync, S::ReplyStore: Send + Sync,
S::GatewaysDetailsStore: Sync, S::GatewaysDetailsStore: Sync,
<S::ReplyStore as ReplyStorageBackend>::StorageError: Sync + Send, <S::ReplyStore as ReplyStorageBackend>::StorageError: Sync + Send,
@@ -622,7 +622,7 @@ where
BandwidthAcquireClient::new( BandwidthAcquireClient::new(
self.config.network_details.clone(), self.config.network_details.clone(),
mnemonic, mnemonic,
self.storage.credential_store(), self.storage.credential_store().clone(),
client_id, client_id,
ticketbook_type, ticketbook_type,
) )