Skip to content

Commit 6b49961

Browse files
committed
Simpficiation with interior mutaility
1 parent 55d65b8 commit 6b49961

2 files changed

Lines changed: 37 additions & 36 deletions

File tree

keyhive_core/src/store/secret_key.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,11 @@ pub trait SecretKeyStore<F: FutureForm>: Sized {
6060
///
6161
/// If a key with the same public key already exists, it is
6262
/// overwritten.
63+
///
64+
/// Interior mutability is used — callers pass `&self`, and the
65+
/// store handles synchronization internally.
6366
fn import_secret_key<'a>(
64-
&'a mut self,
67+
&'a self,
6568
secret_key: Self::SecretKey,
6669
) -> F::Future<'a, Result<ShareKey, Self::ImportError>>;
6770

@@ -70,7 +73,7 @@ pub trait SecretKeyStore<F: FutureForm>: Sized {
7073
/// This is separate from [`import_secret_key`] because external
7174
/// stores may need to convert raw bytes into an opaque handle.
7275
fn import_raw_secret_key<'a>(
73-
&'a mut self,
76+
&'a self,
7477
raw: ShareSecretKey,
7578
) -> F::Future<'a, Result<Self::SecretKey, Self::ImportError>>;
7679

@@ -79,7 +82,7 @@ pub trait SecretKeyStore<F: FutureForm>: Sized {
7982
/// Returns the secret key handle. The corresponding public key
8083
/// can be obtained via [`AsyncSecretKey::to_share_key`].
8184
fn generate_secret_key<'a>(
82-
&'a mut self,
85+
&'a self,
8386
) -> F::Future<'a, Result<Self::SecretKey, Self::GenerateError>>;
8487

8588
/// Check if a secret key for the given public key exists.

keyhive_core/src/store/secret_key/memory.rs

Lines changed: 31 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -5,45 +5,37 @@
55
66
use super::SecretKeyStore;
77
use future_form::{future_form, FutureForm, Local, Sendable};
8+
use futures::lock::Mutex;
89
use keyhive_crypto::share_key::{ShareKey, ShareSecretKey};
910
use serde::{Deserialize, Serialize};
1011
use std::{collections::BTreeMap, convert::Infallible};
1112

12-
/// In-memory secret key store backed by a `BTreeMap`.
13+
/// In-memory secret key store backed by a `BTreeMap` with interior
14+
/// mutability via [`futures::lock::Mutex`].
1315
///
1416
/// This is the default store for development and testing.
1517
/// For production use with durable keys, implement
1618
/// [`SecretKeyStore`] for your storage backend.
17-
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
19+
#[derive(Debug, Default)]
1820
pub struct MemorySecretKeyStore {
19-
keys: BTreeMap<ShareKey, ShareSecretKey>,
21+
keys: Mutex<BTreeMap<ShareKey, ShareSecretKey>>,
2022
}
2123

2224
impl MemorySecretKeyStore {
2325
pub fn new() -> Self {
2426
Self {
25-
keys: BTreeMap::new(),
27+
keys: Mutex::new(BTreeMap::new()),
2628
}
2729
}
2830

2931
/// Number of keys in the store.
30-
pub fn len(&self) -> usize {
31-
self.keys.len()
32+
pub async fn len(&self) -> usize {
33+
self.keys.lock().await.len()
3234
}
3335

3436
/// Whether the store is empty.
35-
pub fn is_empty(&self) -> bool {
36-
self.keys.is_empty()
37-
}
38-
39-
/// Iterate over all (public, secret) key pairs.
40-
pub fn iter(&self) -> impl Iterator<Item = (&ShareKey, &ShareSecretKey)> {
41-
self.keys.iter()
42-
}
43-
44-
/// Extend the store with key pairs from another source.
45-
pub fn extend(&mut self, other: impl IntoIterator<Item = (ShareKey, ShareSecretKey)>) {
46-
self.keys.extend(other);
37+
pub async fn is_empty(&self) -> bool {
38+
self.keys.lock().await.is_empty()
4739
}
4840
}
4941

@@ -58,39 +50,45 @@ impl<F: FutureForm> SecretKeyStore<F> for MemorySecretKeyStore {
5850
&'a self,
5951
public_key: &'a ShareKey,
6052
) -> F::Future<'a, Result<Option<ShareSecretKey>, Infallible>> {
61-
F::ready(Ok(self.keys.get(public_key).copied()))
53+
F::from_future(async move { Ok(self.keys.lock().await.get(public_key).copied()) })
6254
}
6355

6456
fn import_secret_key<'a>(
65-
&'a mut self,
57+
&'a self,
6658
secret_key: ShareSecretKey,
6759
) -> F::Future<'a, Result<ShareKey, Infallible>> {
68-
let pk = secret_key.share_key();
69-
self.keys.insert(pk, secret_key);
70-
F::ready(Ok(pk))
60+
F::from_future(async move {
61+
let pk = secret_key.share_key();
62+
self.keys.lock().await.insert(pk, secret_key);
63+
Ok(pk)
64+
})
7165
}
7266

7367
fn import_raw_secret_key<'a>(
74-
&'a mut self,
68+
&'a self,
7569
raw: ShareSecretKey,
7670
) -> F::Future<'a, Result<ShareSecretKey, Infallible>> {
77-
let pk = raw.share_key();
78-
self.keys.insert(pk, raw);
79-
F::ready(Ok(raw))
71+
F::from_future(async move {
72+
let pk = raw.share_key();
73+
self.keys.lock().await.insert(pk, raw);
74+
Ok(raw)
75+
})
8076
}
8177

82-
fn generate_secret_key<'a>(&'a mut self) -> F::Future<'a, Result<ShareSecretKey, Infallible>> {
83-
let sk = ShareSecretKey::generate(&mut rand::thread_rng());
84-
let pk = sk.share_key();
85-
self.keys.insert(pk, sk);
86-
F::ready(Ok(sk))
78+
fn generate_secret_key<'a>(&'a self) -> F::Future<'a, Result<ShareSecretKey, Infallible>> {
79+
F::from_future(async move {
80+
let sk = ShareSecretKey::generate(&mut rand::thread_rng());
81+
let pk = sk.share_key();
82+
self.keys.lock().await.insert(pk, sk);
83+
Ok(sk)
84+
})
8785
}
8886

8987
fn contains_secret_key<'a>(
9088
&'a self,
9189
public_key: &'a ShareKey,
9290
) -> F::Future<'a, Result<bool, Infallible>> {
93-
F::ready(Ok(self.keys.contains_key(public_key)))
91+
F::from_future(async move { Ok(self.keys.lock().await.contains_key(public_key)) })
9492
}
9593
}
9694

0 commit comments

Comments
 (0)