1use ethereum_types::H256;
2use ethrex_rlp::encode::RLPEncode;
3
4use crate::{Nibbles, Node, Trie, error::TrieError};
5use std::{
6 collections::BTreeMap,
7 sync::{Arc, Mutex},
8};
9
10pub type NodeMap = Arc<Mutex<BTreeMap<Vec<u8>, Vec<u8>>>>;
12
13pub trait TrieDB: Send + Sync {
14 fn get(&self, key: Nibbles) -> Result<Option<Vec<u8>>, TrieError>;
15 fn put_batch(&self, key_values: Vec<(Nibbles, Vec<u8>)>) -> Result<(), TrieError>;
16 fn put_batch_no_alloc(&self, key_values: &[(Nibbles, Node)]) -> Result<(), TrieError> {
18 self.put_batch(
19 key_values
20 .iter()
21 .map(|node| (node.0.clone(), node.1.encode_to_vec()))
22 .collect(),
23 )
24 }
25 fn put(&self, key: Nibbles, value: Vec<u8>) -> Result<(), TrieError> {
26 self.put_batch(vec![(key, value)])
27 }
28 fn commit(&self) -> Result<(), TrieError> {
31 Ok(())
32 }
33
34 fn flatkeyvalue_computed(&self, _key: Nibbles) -> bool {
35 false
36 }
37}
38
39#[derive(Default)]
42pub struct InMemoryTrieDB {
43 inner: NodeMap,
44 prefix: Option<Nibbles>,
45}
46
47impl InMemoryTrieDB {
48 pub const fn new(map: NodeMap) -> Self {
49 Self {
50 inner: map,
51 prefix: None,
52 }
53 }
54
55 pub const fn new_with_prefix(map: NodeMap, prefix: Nibbles) -> Self {
56 Self {
57 inner: map,
58 prefix: Some(prefix),
59 }
60 }
61
62 pub fn new_empty() -> Self {
63 Self {
64 inner: Default::default(),
65 prefix: None,
66 }
67 }
68
69 pub fn from_nodes(
71 root_hash: H256,
72 state_nodes: &BTreeMap<H256, Node>,
73 ) -> Result<Self, TrieError> {
74 let mut embedded_root = Trie::get_embedded_root(state_nodes, root_hash)?;
75 let mut hashed_nodes = vec![];
76 embedded_root.commit(
77 Nibbles::default(),
78 &mut hashed_nodes,
79 ðrex_crypto::NativeCrypto,
80 );
81
82 let hashed_nodes = hashed_nodes
83 .into_iter()
84 .map(|(k, v)| (k.into_vec(), v))
85 .collect();
86
87 let in_memory_trie = Arc::new(Mutex::new(hashed_nodes));
88 Ok(Self::new(in_memory_trie))
89 }
90
91 fn apply_prefix(&self, path: Nibbles) -> Nibbles {
92 match &self.prefix {
93 Some(prefix) => prefix.concat(&path),
94 None => path,
95 }
96 }
97
98 pub fn inner(&self) -> NodeMap {
100 Arc::clone(&self.inner)
101 }
102}
103
104impl TrieDB for InMemoryTrieDB {
105 fn get(&self, key: Nibbles) -> Result<Option<Vec<u8>>, TrieError> {
106 Ok(self
107 .inner
108 .lock()
109 .map_err(|_| TrieError::LockError)?
110 .get(self.apply_prefix(key).as_ref())
111 .cloned())
112 }
113
114 fn put_batch(&self, key_values: Vec<(Nibbles, Vec<u8>)>) -> Result<(), TrieError> {
115 let mut db = self.inner.lock().map_err(|_| TrieError::LockError)?;
116
117 for (key, value) in key_values {
118 let prefixed_key = self.apply_prefix(key);
119 db.insert(prefixed_key.into_vec(), value);
120 }
121
122 Ok(())
123 }
124}