1use vapory_types::H256;
19use tetsy_keccak_hash::{KECCAK_NULL_RLP, keccak};
20use tetsy_hash_db::{HashDB, AsHashDB, Prefix};
21use tetsy_keccak_hasher::KeccakHasher;
22use tetsy_kvdb::DBValue;
23use tetsy_rlp::NULL_RLP;
24
25#[inline]
28fn combine_key<'a>(address_hash: &'a H256, key: &'a H256) -> H256 {
29 let mut dst = key.clone();
30 {
31 let last_src: &[u8] = address_hash.as_bytes();
32 let last_dst: &mut [u8] = dst.as_bytes_mut();
33 for (k, a) in last_dst[12..].iter_mut().zip(&last_src[12..]) {
34 *k ^= *a
35 }
36 }
37
38 dst
39}
40
41#[derive(Debug, Clone)]
43pub enum Factory {
44 Mangled,
46 Plain,
48}
49
50impl Default for Factory {
51 fn default() -> Self { Factory::Mangled }
52}
53
54impl Factory {
55 pub fn readonly<'db>(&self, db: &'db dyn HashDB<KeccakHasher, DBValue>, address_hash: H256) -> Box<dyn HashDB<KeccakHasher, DBValue> + 'db> {
58 match *self {
59 Factory::Mangled => Box::new(AccountDB::from_hash(db, address_hash)),
60 Factory::Plain => Box::new(Wrapping(db)),
61 }
62 }
63
64 pub fn create<'db>(&self, db: &'db mut dyn HashDB<KeccakHasher, DBValue>, address_hash: H256) -> Box<dyn HashDB<KeccakHasher, DBValue> + 'db> {
66 match *self {
67 Factory::Mangled => Box::new(AccountDBMut::from_hash(db, address_hash)),
68 Factory::Plain => Box::new(WrappingMut(db)),
69 }
70 }
71}
72
73pub struct AccountDB<'db> {
77 db: &'db dyn HashDB<KeccakHasher, DBValue>,
78 address_hash: H256,
79}
80
81impl<'db> AccountDB<'db> {
82 pub fn from_hash(db: &'db dyn HashDB<KeccakHasher, DBValue>, address_hash: H256) -> Self {
84 AccountDB { db, address_hash }
85 }
86}
87
88impl<'db> AsHashDB<KeccakHasher, DBValue> for AccountDB<'db> {
89 fn as_hash_db(&self) -> &dyn HashDB<KeccakHasher, DBValue> { self }
90 fn as_hash_db_mut(&mut self) -> &mut dyn HashDB<KeccakHasher, DBValue> { self }
91}
92
93impl<'db> HashDB<KeccakHasher, DBValue> for AccountDB<'db> {
94 fn get(&self, key: &H256, prefix: Prefix) -> Option<DBValue> {
95 if key == &KECCAK_NULL_RLP {
96 return Some(NULL_RLP.to_vec());
97 }
98 self.db.get(&combine_key(&self.address_hash, key), prefix)
99 }
100
101 fn contains(&self, key: &H256, prefix: Prefix) -> bool {
102 if key == &KECCAK_NULL_RLP {
103 return true;
104 }
105 self.db.contains(&combine_key(&self.address_hash, key), prefix)
106 }
107
108 fn insert(&mut self, _prefix: Prefix, _value: &[u8]) -> H256 {
109 unimplemented!()
110 }
111
112 fn emplace(&mut self, _key: H256, _prefix: Prefix, _value: DBValue) {
113 unimplemented!()
114 }
115
116 fn remove(&mut self, _key: &H256, _prefix: Prefix) {
117 unimplemented!()
118 }
119}
120
121pub struct AccountDBMut<'db> {
123 db: &'db mut dyn HashDB<KeccakHasher, DBValue>,
124 address_hash: H256,
125}
126
127impl<'db> AccountDBMut<'db> {
128 pub fn from_hash(db: &'db mut dyn HashDB<KeccakHasher, DBValue>, address_hash: H256) -> Self {
130 AccountDBMut { db, address_hash }
131 }
132
133 pub fn immutable(&'db self) -> AccountDB<'db> {
135 AccountDB { db: self.db, address_hash: self.address_hash.clone() }
136 }
137}
138
139impl<'db> HashDB<KeccakHasher, DBValue> for AccountDBMut<'db>{
140 fn get(&self, key: &H256, prefix: Prefix) -> Option<DBValue> {
141 if key == &KECCAK_NULL_RLP {
142 return Some(NULL_RLP.to_vec());
143 }
144 self.db.get(&combine_key(&self.address_hash, key), prefix)
145 }
146
147 fn contains(&self, key: &H256, prefix: Prefix) -> bool {
148 if key == &KECCAK_NULL_RLP {
149 return true;
150 }
151 self.db.contains(&combine_key(&self.address_hash, key), prefix)
152 }
153
154 fn insert(&mut self, prefix: Prefix, value: &[u8]) -> H256 {
155 if value == &NULL_RLP {
156 return KECCAK_NULL_RLP.clone();
157 }
158 let k = keccak(value);
159 let ak = combine_key(&self.address_hash, &k);
160 self.db.emplace(ak, prefix, value.to_vec());
161 k
162 }
163
164 fn emplace(&mut self, key: H256, prefix: Prefix, value: DBValue) {
165 if key == KECCAK_NULL_RLP {
166 return;
167 }
168 let key = combine_key(&self.address_hash, &key);
169 self.db.emplace(key, prefix, value)
170 }
171
172 fn remove(&mut self, key: &H256, prefix: Prefix) {
173 if key == &KECCAK_NULL_RLP {
174 return;
175 }
176 let key = combine_key(&self.address_hash, key);
177 self.db.remove(&key, prefix)
178 }
179}
180
181impl<'db> AsHashDB<KeccakHasher, DBValue> for AccountDBMut<'db> {
182 fn as_hash_db(&self) -> &dyn HashDB<KeccakHasher, DBValue> { self }
183 fn as_hash_db_mut(&mut self) -> &mut dyn HashDB<KeccakHasher, DBValue> { self }
184}
185
186struct Wrapping<'db>(&'db dyn HashDB<KeccakHasher, DBValue>);
187
188impl<'db> AsHashDB<KeccakHasher, DBValue> for Wrapping<'db> {
189 fn as_hash_db(&self) -> &dyn HashDB<KeccakHasher, DBValue> { self }
190 fn as_hash_db_mut(&mut self) -> &mut dyn HashDB<KeccakHasher, DBValue> { self }
191}
192
193impl<'db> HashDB<KeccakHasher, DBValue> for Wrapping<'db> {
194 fn get(&self, key: &H256, prefix: Prefix) -> Option<DBValue> {
195 if key == &KECCAK_NULL_RLP {
196 return Some(NULL_RLP.to_vec());
197 }
198 self.0.get(key, prefix)
199 }
200
201 fn contains(&self, key: &H256, prefix: Prefix) -> bool {
202 if key == &KECCAK_NULL_RLP {
203 return true;
204 }
205 self.0.contains(key, prefix)
206 }
207
208 fn insert(&mut self, _prefix: Prefix, _value: &[u8]) -> H256 {
209 unimplemented!()
210 }
211
212 fn emplace(&mut self, _key: H256, _prefix: Prefix, _value: DBValue) {
213 unimplemented!()
214 }
215
216 fn remove(&mut self, _key: &H256, _prefix: Prefix) {
217 unimplemented!()
218 }
219}
220
221struct WrappingMut<'db>(&'db mut dyn HashDB<KeccakHasher, DBValue>);
222impl<'db> AsHashDB<KeccakHasher, DBValue> for WrappingMut<'db> {
223 fn as_hash_db(&self) -> &dyn HashDB<KeccakHasher, DBValue> { self }
224 fn as_hash_db_mut(&mut self) -> &mut dyn HashDB<KeccakHasher, DBValue> { self }
225}
226
227impl<'db> HashDB<KeccakHasher, DBValue> for WrappingMut<'db>{
228 fn get(&self, key: &H256, prefix: Prefix) -> Option<DBValue> {
229 if key == &KECCAK_NULL_RLP {
230 return Some(NULL_RLP.to_vec());
231 }
232 self.0.get(key, prefix)
233 }
234
235 fn contains(&self, key: &H256, prefix: Prefix) -> bool {
236 if key == &KECCAK_NULL_RLP {
237 return true;
238 }
239 self.0.contains(key, prefix)
240 }
241
242 fn insert(&mut self, prefix: Prefix, value: &[u8]) -> H256 {
243 if value == &NULL_RLP {
244 return KECCAK_NULL_RLP.clone();
245 }
246 self.0.insert(prefix, value)
247 }
248
249 fn emplace(&mut self, key: H256, prefix: Prefix, value: DBValue) {
250 if key == KECCAK_NULL_RLP {
251 return;
252 }
253 self.0.emplace(key, prefix, value)
254 }
255
256 fn remove(&mut self, key: &H256, prefix: Prefix) {
257 if key == &KECCAK_NULL_RLP {
258 return;
259 }
260 self.0.remove(key, prefix)
261 }
262}