identity_storage/key_id_storage/
memstore.rs

1// Copyright 2020-2023 IOTA Stiftung
2// SPDX-License-Identifier: Apache-2.0
3
4use crate::key_id_storage::key_id_storage::KeyIdStorage;
5use crate::key_id_storage::key_id_storage_error::KeyIdStorageError;
6use crate::key_id_storage::key_id_storage_error::KeyIdStorageErrorKind;
7use crate::key_storage::shared::Shared;
8use crate::key_storage::KeyId;
9use async_trait::async_trait;
10use std::collections::HashMap;
11use tokio::sync::RwLockReadGuard;
12use tokio::sync::RwLockWriteGuard;
13
14use super::key_id_storage::KeyIdStorageResult;
15use super::method_digest::MethodDigest;
16
17type KeyIdStore = HashMap<MethodDigest, KeyId>;
18
19/// An insecure, in-memory [`KeyIdStorage`] implementation that serves as an example and may be used in tests.
20#[derive(Debug)]
21pub struct KeyIdMemstore {
22  key_id_store: Shared<KeyIdStore>,
23}
24
25impl KeyIdMemstore {
26  /// Creates a new, empty `KeyIdMemstore` instance.
27  pub fn new() -> Self {
28    Self {
29      key_id_store: Shared::new(HashMap::new()),
30    }
31  }
32
33  /// Returns the number of items contained in the [`KeyIdMemstore`].
34  pub async fn count(&self) -> usize {
35    self.key_id_store.read().await.keys().count()
36  }
37}
38
39impl Default for KeyIdMemstore {
40  fn default() -> Self {
41    Self::new()
42  }
43}
44
45#[cfg_attr(not(feature = "send-sync-storage"), async_trait(? Send))]
46#[cfg_attr(feature = "send-sync-storage", async_trait)]
47impl KeyIdStorage for KeyIdMemstore {
48  async fn insert_key_id(&self, key: MethodDigest, value: KeyId) -> KeyIdStorageResult<()> {
49    let mut key_id_store: RwLockWriteGuard<'_, KeyIdStore> = self.key_id_store.write().await;
50    if key_id_store.contains_key(&key) {
51      return Err(KeyIdStorageError::new(KeyIdStorageErrorKind::KeyIdAlreadyExists));
52    }
53    key_id_store.insert(key, value);
54    Ok(())
55  }
56
57  async fn get_key_id(&self, key: &MethodDigest) -> KeyIdStorageResult<KeyId> {
58    let key_id_store: RwLockReadGuard<'_, KeyIdStore> = self.key_id_store.read().await;
59    Ok(
60      key_id_store
61        .get(key)
62        .ok_or_else(|| KeyIdStorageError::new(KeyIdStorageErrorKind::KeyIdNotFound))?
63        .clone(),
64    )
65  }
66
67  async fn delete_key_id(&self, key: &MethodDigest) -> KeyIdStorageResult<()> {
68    let mut key_id_store: RwLockWriteGuard<'_, KeyIdStore> = self.key_id_store.write().await;
69    key_id_store
70      .remove(key)
71      .ok_or_else(|| KeyIdStorageError::new(KeyIdStorageErrorKind::KeyIdNotFound))?;
72    Ok(())
73  }
74}
75
76#[cfg(test)]
77mod tests {
78  use crate::key_id_storage::key_id_storage::KeyIdStorage;
79  use crate::key_id_storage::memstore::KeyIdMemstore;
80  use crate::key_id_storage::method_digest::MethodDigest;
81  use crate::key_id_storage::KeyIdStorageError;
82  use crate::key_id_storage::KeyIdStorageErrorKind;
83  use crate::key_storage::KeyId;
84  use identity_verification::VerificationMethod;
85
86  #[tokio::test]
87  async fn memstore_operations() {
88    let verification_method: VerificationMethod = crate::storage::tests::test_utils::create_verification_method();
89
90    // Test insertion.
91    let memstore: KeyIdMemstore = KeyIdMemstore::new();
92    let key_id_1 = KeyId::new("keyid");
93    let method_digest: MethodDigest = MethodDigest::new(&verification_method).unwrap();
94    memstore
95      .insert_key_id(method_digest.clone(), key_id_1.clone())
96      .await
97      .expect("inserting into memstore failed");
98
99    // Double insertion.
100    let insertion_result = memstore.insert_key_id(method_digest.clone(), key_id_1.clone()).await;
101    let _expected_error: KeyIdStorageError = KeyIdStorageError::new(KeyIdStorageErrorKind::KeyIdAlreadyExists);
102    assert!(matches!(insertion_result.unwrap_err(), _expected_error));
103
104    // Test retrieving.
105    let key_id: KeyId = memstore.get_key_id(&method_digest).await.unwrap();
106    assert_eq!(key_id_1, key_id);
107
108    // Test deletion.
109    memstore.delete_key_id(&method_digest).await.expect("deletion failed");
110
111    let repeat_deletion_result: Result<(), KeyIdStorageError> = memstore.delete_key_id(&method_digest).await;
112    let _expected_error: KeyIdStorageError = KeyIdStorageError::new(KeyIdStorageErrorKind::KeyIdNotFound);
113    assert!(matches!(repeat_deletion_result.unwrap_err(), _expected_error));
114  }
115}