diem_secure_storage/
in_memory.rs

1// Copyright (c) The Diem Core Contributors
2// SPDX-License-Identifier: Apache-2.0
3
4// Copyright 2021 Conflux Foundation. All rights reserved.
5// Conflux is free software and distributed under GNU General Public License.
6// See http://www.gnu.org/licenses/
7
8use crate::{CryptoKVStorage, Error, GetResponse, KVStorage};
9use diem_time_service::{TimeService, TimeServiceTrait};
10use serde::{de::DeserializeOwned, Serialize};
11use std::collections::HashMap;
12
13/// InMemoryStorage represents a key value store that is purely in memory and
14/// intended for single threads (or must be wrapped by a Arc<RwLock<>>). This
15/// provides no permission checks and simply is a proof of concept to unblock
16/// building of applications without more complex data stores. Internally, it
17/// retains all data, which means that it must make copies of all key material
18/// which violates the Diem code base. It violates it because the anticipation
19/// is that data stores would securely handle key material. This should not be
20/// used in production.
21#[derive(Default)]
22pub struct InMemoryStorage {
23    data: HashMap<String, Vec<u8>>,
24    time_service: TimeService,
25}
26
27impl InMemoryStorage {
28    pub fn new() -> Self { Self::new_with_time_service(TimeService::real()) }
29}
30
31impl InMemoryStorage {
32    pub fn new_with_time_service(time_service: TimeService) -> Self {
33        Self {
34            data: HashMap::new(),
35            time_service,
36        }
37    }
38}
39
40impl KVStorage for InMemoryStorage {
41    fn available(&self) -> Result<(), Error> { Ok(()) }
42
43    fn get<V: DeserializeOwned>(
44        &self, key: &str,
45    ) -> Result<GetResponse<V>, Error> {
46        let response = self
47            .data
48            .get(key)
49            .ok_or_else(|| Error::KeyNotSet(key.to_string()))?;
50
51        serde_json::from_slice(&response).map_err(|e| e.into())
52    }
53
54    fn set<V: Serialize>(&mut self, key: &str, value: V) -> Result<(), Error> {
55        let now = self.time_service.now_secs();
56        self.data.insert(
57            key.to_string(),
58            serde_json::to_vec(&GetResponse::new(value, now))?,
59        );
60        Ok(())
61    }
62
63    #[cfg(any(test, feature = "testing"))]
64    fn reset_and_clear(&mut self) -> Result<(), Error> {
65        self.data.clear();
66        Ok(())
67    }
68}
69
70impl CryptoKVStorage for InMemoryStorage {}