1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
// Copyright 2019 Conflux Foundation. All rights reserved.
// Conflux is free software and distributed under GNU General Public License.
// See http://www.gnu.org/licenses/

use cfxkey as keylib;
use keylib::KeyPair;
use malloc_size_of_derive::MallocSizeOf as DeriveMallocSizeOf;
use parking_lot::RwLock;
use std::{collections::HashMap, sync::Arc};

#[derive(DeriveMallocSizeOf)]
pub struct StoreInner {
    account_vec: Vec<KeyPair>,
    secret_map: HashMap<String, usize>,
}

impl StoreInner {
    pub fn new() -> Self {
        StoreInner {
            account_vec: Vec::new(),
            secret_map: HashMap::new(),
        }
    }

    pub fn insert(&mut self, kp: KeyPair) -> bool {
        let secret_string = kp.secret().to_hex();
        if self.secret_map.contains_key(&secret_string) {
            return false;
        }

        let index = self.count();
        self.secret_map.insert(secret_string, index);
        self.account_vec.push(kp);
        true
    }

    pub fn count(&self) -> usize { self.account_vec.len() }

    pub fn get_keypair(&self, index: usize) -> KeyPair {
        self.account_vec[index].clone()
    }

    pub fn remove_keypair(&mut self, index: usize) {
        let secret_string = self.account_vec[index].secret().to_hex();
        self.secret_map.remove(&secret_string);
        self.account_vec.remove(index);
    }
}

#[derive(DeriveMallocSizeOf)]
pub struct SecretStore {
    store: RwLock<StoreInner>,
}

pub type SharedSecretStore = Arc<SecretStore>;

impl SecretStore {
    pub fn new() -> Self {
        SecretStore {
            store: RwLock::new(StoreInner::new()),
        }
    }

    pub fn insert(&self, kp: KeyPair) -> bool { self.store.write().insert(kp) }

    pub fn count(&self) -> usize { self.store.read().count() }

    pub fn get_keypair(&self, index: usize) -> KeyPair {
        self.store.read().get_keypair(index)
    }

    pub fn remove_keypair(&self, index: usize) {
        self.store.write().remove_keypair(index);
    }
}