1use ahash::{AHashMap as HashMap, AHashSet as HashSet};
2
3use crate::{
4 call::Head,
5 chain::Fetched,
6 state::{Account, State},
7 trace::{Event, Target, Trace, filter},
8};
9use futures::channel::mpsc;
10use yevm_base::{Acc, Int, math::lift};
11use yevm_misc::buf::Buf;
12
13#[derive(Default)]
14struct Slot {
15 original: Int,
16 current: Int,
17}
18
19struct AccountEntry {
20 account: Account,
21 storage: HashMap<Int, Slot>,
22}
23
24impl AccountEntry {
25 fn new(account: Account) -> Self {
26 Self {
27 account,
28 storage: HashMap::new(),
29 }
30 }
31}
32
33impl Default for AccountEntry {
34 fn default() -> Self {
35 Self {
36 account: Account {
37 value: Int::ZERO,
38 nonce: Int::ZERO,
39 code: (vec![].into(), Int::ZERO),
40 },
41 storage: HashMap::new(),
42 }
43 }
44}
45
46enum Revert {
47 WarmAcc(Acc),
48 WarmKey(Acc, Int),
49 Store(Acc, Int, Int),
50 Nonce(Acc, Int),
51 Value(Acc, Int),
52 Temp(Acc, Int, Int),
53 Code(Acc, Int),
54 Create(Acc),
55 Delete(Acc),
56}
57
58#[derive(Default)]
59pub struct Cache {
60 accounts: HashMap<Acc, AccountEntry>,
61 transient: HashMap<(Acc, Int), Int>,
62 warm_accs: HashSet<Acc>,
63 warm_keys: HashSet<(Acc, Int)>,
64 created: HashSet<Acc>,
65 destroyed: HashSet<Acc>,
66 hash: HashMap<u64, Int>,
67 depth: usize,
68 pub logs: Vec<(Buf, Vec<Int>)>,
69 pub events: Vec<Trace>,
70 pub sender: Option<mpsc::Sender<Trace>>,
71 pub filter: u32,
72 pub fetched: Vec<Fetched>,
73 pub index: usize,
74 offline: bool,
75 chain_id: u64,
76}
77
78impl Cache {
79 pub fn new() -> Self {
80 Self::default()
81 }
82
83 pub fn with_sender(sender: mpsc::Sender<Trace>, filter: u32) -> Self {
84 Self {
85 sender: Some(sender),
86 filter,
87 ..Self::default()
88 }
89 }
90
91 pub fn insert_account(&mut self, addr: Acc, account: Account) {
92 let entry = self.accounts.entry(addr).or_default();
93 entry.account = account;
94 }
95
96 pub fn account(&self, addr: &Acc) -> Option<&Account> {
97 self.accounts.get(addr).map(|e| &e.account)
98 }
99
100 pub fn storage(&self, addr: &Acc, key: &Int) -> Option<Int> {
101 self.accounts.get(addr)?.storage.get(key).map(|s| s.current)
102 }
103
104 pub fn reset(&mut self) {
105 self.transient.clear();
106 self.warm_accs.clear();
107 self.warm_keys.clear();
108 self.created.clear();
109 self.destroyed.clear();
110 self.depth = 0;
111 self.logs.clear();
112 self.events.clear();
113
114 for (_, account) in self.accounts.iter_mut() {
116 for (_, slot) in account.storage.iter_mut() {
117 slot.original = slot.current;
118 }
119 }
120 }
121}
122
123impl State for Cache {
124 fn get(&mut self, acc: &Acc, key: &Int) -> Option<(Int, Int)> {
126 let entry = self.accounts.get(acc)?;
127 let (cur, org) = entry.storage.get(key).map(|s| (s.current, s.original))?;
128 self.emit(Event::Get(Target::Store {
129 acc: *acc,
130 key: *key,
131 val: cur,
132 }));
133 Some((cur, org))
134 }
135
136 fn put(&mut self, acc: &Acc, key: &Int, val: Int) -> Option<Int> {
137 let entry = self.accounts.entry(*acc).or_default();
138 let slot = entry.storage.entry(*key).or_default();
139 let prev = slot.current;
140 slot.current = val;
141 self.emit(Event::Put(
142 Target::Store {
143 acc: *acc,
144 key: *key,
145 val: prev,
146 },
147 val,
148 ));
149 Some(prev)
150 }
151
152 fn init(&mut self, acc: &Acc, key: &Int, val: Int) {
153 let entry = self.accounts.entry(*acc).or_default();
154 entry.storage.insert(
155 *key,
156 Slot {
157 original: val,
158 current: val,
159 },
160 );
161 }
162
163 fn tget(&mut self, acc: &Acc, key: &Int) -> Option<Int> {
164 let val = self.transient.get(&(*acc, *key)).copied();
165 self.emit(Event::Get(Target::Temp {
166 acc: *acc,
167 key: *key,
168 val: val.unwrap_or_default(),
169 }));
170 val
171 }
172
173 fn tput(&mut self, acc: Acc, key: Int, val: Int) -> Option<Int> {
174 let prev = self.transient.insert((acc, key), val);
175 self.emit(Event::Put(
176 Target::Temp {
177 acc,
178 key,
179 val: prev.unwrap_or_default(),
180 },
181 val,
182 ));
183 prev
184 }
185
186 fn inc_nonce(&mut self, acc: &Acc, by: Int) -> Int {
188 let (old, new) = {
189 let entry = self.accounts.entry(*acc).or_default();
190 let old = entry.account.nonce;
191 let f = lift(|[a, b]| a + b);
192 let new = f([old, by]);
193 entry.account.nonce = new;
194 (old, new)
195 };
196 self.emit(Event::Put(
197 Target::Nonce {
198 acc: *acc,
199 val: old,
200 },
201 new,
202 ));
203 new
204 }
205
206 fn set_value(&mut self, acc: &Acc, value: Int) -> Int {
207 let prev = {
208 let entry = self.accounts.entry(*acc).or_default();
209 let prev = entry.account.value;
210 entry.account.value = value;
211 prev
212 };
213 self.emit(Event::Put(
214 Target::Value {
215 acc: *acc,
216 val: prev,
217 },
218 value,
219 ));
220 prev
221 }
222
223 fn set_code(&mut self, acc: &Acc, code: Buf, hash: Int) -> Int {
224 let prev = {
225 let entry = self.accounts.entry(*acc).or_default();
226 let (_, prev) = entry.account.code;
227 entry.account.code = (code, hash);
228 prev
229 };
230 self.emit(Event::Put(
231 Target::Code {
232 acc: *acc,
233 hash: prev,
234 },
235 hash,
236 ));
237 prev
239 }
240
241 fn set_auth(&mut self, src: &Acc, dst: &Acc) {
242 let mut code = vec![0; 23];
243 code[..3].copy_from_slice(&[0xEF, 0x01, 0x00]);
245 code[3..].copy_from_slice(dst.as_ref());
246 self.set_code(src, code.into(), Int::ZERO);
247 }
248
249 fn merge(&mut self, acc: &Acc, chain: Account) {
250 self.accounts.entry(*acc).or_default().account = chain;
251 }
252
253 fn balance(&mut self, acc: &Acc) -> Option<Int> {
254 let val = self.accounts.get(acc).map(|e| e.account.value);
255 self.emit(Event::Get(Target::Value {
256 acc: *acc,
257 val: val.unwrap_or_default(),
258 }));
259 val
260 }
261
262 fn nonce(&mut self, acc: &Acc) -> Option<Int> {
263 let val = self.accounts.get(acc).map(|e| e.account.nonce);
264 self.emit(Event::Get(Target::Nonce {
265 acc: *acc,
266 val: val.unwrap_or_default(),
267 }));
268 val
269 }
270
271 fn code(&mut self, acc: &Acc) -> Option<(Buf, Int)> {
272 let (code, hash) = self.accounts.get(acc).map(|e| e.account.code.clone())?;
273 self.emit(Event::Get(Target::Code { acc: *acc, hash }));
274 if !code.is_empty() {
275 self.emit(Event::Code(code.clone(), hash));
276 }
277 Some((code, hash))
278 }
279
280 fn acc(&mut self, acc: &Acc) -> Option<Account> {
281 self.accounts.get(acc).map(|e| Account {
282 value: e.account.value,
283 nonce: e.account.nonce,
284 code: e.account.code.clone(),
285 })
286 }
287
288 fn is_cold_acc(&self, acc: &Acc) -> bool {
289 !self.warm_accs.contains(acc)
290 }
291
292 fn is_cold_key(&self, acc: &Acc, key: &Int) -> bool {
293 !self.warm_keys.contains(&(*acc, *key))
294 }
295
296 fn warm_acc(&mut self, acc: &Acc) -> bool {
297 let cold = self.warm_accs.insert(*acc);
298 if cold {
299 self.emit(Event::WarmAcc(*acc));
300 }
301 cold
302 }
303
304 fn warm_key(&mut self, acc: &Acc, key: &Int) -> bool {
305 let cold = self.warm_keys.insert((*acc, *key));
306 if cold {
307 self.emit(Event::WarmKey(*acc, *key));
308 }
309 cold
310 }
311
312 fn create(&mut self, acc: Acc, info: Account) {
313 if !info.nonce.is_zero() {
314 self.emit(Event::Put(
315 Target::Nonce {
316 acc,
317 val: Int::ZERO,
318 },
319 info.nonce,
320 ));
321 }
322 if !info.value.is_zero() {
323 self.emit(Event::Put(
324 Target::Value {
325 acc,
326 val: Int::ZERO,
327 },
328 info.value,
329 ));
330 }
331 self.emit(Event::Create(acc));
332 self.accounts.insert(acc, AccountEntry::new(info));
333 self.created.insert(acc);
334 }
335
336 fn destroy(&mut self, acc: &Acc) {
337 self.destroyed.insert(*acc);
338 self.emit(Event::Delete(*acc));
339 }
340
341 fn created(&self) -> Vec<Acc> {
342 self.created.iter().cloned().collect()
343 }
344
345 fn destroyed(&self) -> Vec<Acc> {
346 self.destroyed.iter().cloned().collect()
347 }
348
349 fn head(&self, number: u64) -> Option<Head> {
350 self.hash.get(&number).map(|&hash| Head {
351 number: number.into(),
352 hash,
353 ..Head::default()
354 })
355 }
356
357 fn hash(&mut self, number: u64, hash: Int) {
358 self.hash.insert(number, hash);
359 }
360
361 fn auth(&self, acc: &Acc) -> Option<Acc> {
362 let entry = self.accounts.get(acc)?;
363 let (code, _) = &entry.account.code;
364 if code.0.len() == 23 && code.0.starts_with(&[0xEF, 0x01, 0x00]) {
365 let acc = Acc::from(&code.0[3..]);
366 if acc.is_zero() { None } else { Some(acc) }
367 } else {
368 None
369 }
370 }
371
372 fn log(&mut self, data: Buf, topics: Vec<Int>) {
373 self.emit(Event::Log(topics.clone(), data.clone()));
374 self.logs.push((data, topics));
375 }
376
377 fn get_depth(&mut self) -> usize {
378 self.depth
379 }
380
381 fn set_depth(&mut self, depth: usize) {
382 self.depth = depth;
383 }
384
385 fn emit(&mut self, mut event: Event) -> usize {
386 let id = self.events.len();
387 if let Event::Step(step) = &mut event {
388 step.debug.push(format!("depth={}", self.depth));
389 }
390 let trace = Trace {
391 seq: id,
392 event,
393 depth: self.depth,
394 reverted: false,
395 };
396 if self.filter & trace.event.filter_bit() != 0
397 && let Some(sender) = self.sender.as_mut()
398 {
399 let _ = sender.try_send(trace.clone());
400 }
401 self.events.push(trace);
402 id
403 }
404
405 fn save_fetched(&mut self, fetched: Fetched) {
406 self.fetched.push(fetched);
407 }
408
409 fn next_fetched(&mut self) -> Option<Fetched> {
410 self.index += 1;
411 self.fetched.get(self.index).cloned()
412 }
413
414 fn prefetched(&mut self, fetched: Vec<Fetched>) {
415 self.fetched = fetched;
416 self.offline = true;
417 self.index = 1; }
419
420 fn is_offline(&self) -> bool {
421 self.offline
422 }
423
424 fn checkpoint(&mut self) -> usize {
425 self.events.len()
426 }
427
428 fn revert_to(&mut self, cp: usize) {
429 if cp >= self.events.len() {
430 return;
431 }
432 let to = self.events.len();
433
434 let logs_to_remove = self.events[cp..]
436 .iter()
437 .filter(|t| !t.reverted)
438 .filter(|t| matches!(t.event, Event::Log(..)))
439 .count();
440 self.logs
441 .truncate(self.logs.len().saturating_sub(logs_to_remove));
442
443 let undos: Vec<Revert> = self.events[cp..]
445 .iter()
446 .filter(|t| !t.reverted)
447 .filter_map(|trace| match &trace.event {
448 Event::Put(Target::Store { acc, key, val }, _) => {
449 Some(Revert::Store(*acc, *key, *val))
450 }
451 Event::Put(Target::Nonce { acc, val }, _) => Some(Revert::Nonce(*acc, *val)),
452 Event::Put(Target::Value { acc, val }, _) => Some(Revert::Value(*acc, *val)),
453 Event::Put(Target::Temp { acc, key, val }, _) => {
454 Some(Revert::Temp(*acc, *key, *val))
455 }
456 Event::Put(Target::Code { acc, hash }, _) => Some(Revert::Code(*acc, *hash)),
457 Event::WarmAcc(acc) => Some(Revert::WarmAcc(*acc)),
458 Event::WarmKey(acc, key) => Some(Revert::WarmKey(*acc, *key)),
459 Event::Create(acc) => Some(Revert::Create(*acc)),
460 Event::Delete(acc) => Some(Revert::Delete(*acc)),
461 _ => None,
462 })
463 .collect();
464
465 for t in &mut self.events[cp..] {
467 t.reverted = true;
468 }
469
470 for undo in undos.into_iter().rev() {
472 match undo {
473 Revert::Store(acc, key, val) => {
474 if let Some(entry) = self.accounts.get_mut(&acc)
475 && let Some(slot) = entry.storage.get_mut(&key)
476 {
477 slot.current = val;
478 }
479 }
480 Revert::Nonce(acc, val) => {
481 if let Some(entry) = self.accounts.get_mut(&acc) {
482 entry.account.nonce = val;
483 }
484 }
485 Revert::Value(acc, val) => {
486 if let Some(entry) = self.accounts.get_mut(&acc) {
487 entry.account.value = val;
488 }
489 }
490 Revert::Temp(acc, key, val) => {
491 if val.is_zero() {
492 self.transient.remove(&(acc, key));
493 } else {
494 self.transient.insert((acc, key), val);
495 }
496 }
497 Revert::Code(acc, _prev_hash) => {
498 if let Some(entry) = self.accounts.get_mut(&acc) {
499 entry.account.code = (Buf::default(), Int::ZERO);
500 }
501 }
502 Revert::Create(acc) => {
503 self.created.remove(&acc);
504 self.accounts.remove(&acc);
505 }
506 Revert::Delete(acc) => {
507 self.destroyed.remove(&acc);
508 }
509 Revert::WarmAcc(acc) => {
510 self.warm_accs.remove(&acc);
511 }
512 Revert::WarmKey(acc, key) => {
513 self.warm_keys.remove(&(acc, key));
514 }
515 }
516 }
517
518 if self.filter & filter::REVERT != 0
519 && let Some(sender) = self.sender.as_mut()
520 {
521 let _ = sender.try_send(Trace {
522 seq: cp,
523 event: Event::Undo(cp, to),
524 depth: self.depth,
525 reverted: true,
526 });
527 }
528 }
529
530 fn apply(&mut self) {
531 let destroyed = std::mem::take(&mut self.destroyed);
532 for acc in destroyed {
533 if let Some(entry) = self.accounts.get_mut(&acc) {
534 entry.account.value = Int::ZERO;
536 entry.account.code = (Buf::default(), Int::ZERO);
537 entry.storage.clear();
538 }
539 self.created.remove(&acc);
540 }
541 }
542
543 fn set_chain_id(&mut self, id: u64) {
544 self.chain_id = id;
545 }
546
547 fn get_chain_id(&self) -> u64 {
548 self.chain_id
549 }
550
551 fn is_tracing(&self) -> bool {
552 self.sender.is_some()
553 }
554}
555
556pub type Env = Vec<(Acc, Account, Vec<(Int, Int)>)>;
557
558impl Cache {
559 pub fn snapshot(&self) -> Env {
560 let mut ret = Vec::with_capacity(self.accounts.len());
561 for (acc, entry) in &self.accounts {
562 let mut kv = Vec::with_capacity(entry.storage.len());
563 for (key, slot) in &entry.storage {
564 kv.push((*key, slot.current));
565 }
566 kv.sort_by_key(|(k, _)| *k);
567 ret.push((*acc, entry.account.clone(), kv));
568 }
569 ret.sort_by_key(|(acc, _, _)| *acc);
570 ret
571 }
572}