cfx_executor/state/state_object/
warm.rs1use crate::try_loaded;
2use cfx_statedb::Result as DbResult;
3use cfx_types::{AddressSpaceUtil, AddressWithSpace, Space, H256};
4use cfx_vm_types::ActionParams;
5use primitives::AccessListItem;
6use std::collections::{HashMap, HashSet};
7
8use super::State;
9
10impl State {
11 pub fn is_warm_account(&self, address: &AddressWithSpace) -> bool {
12 if self
13 .tx_access_list
14 .as_ref()
15 .map_or(false, |x| x.contains_key(address))
16 {
17 return true;
18 }
19 self.cache.read().get(address).map_or(false, |x| x.warm)
20 }
21
22 pub fn is_warm_storage_entry(
23 &self, address: &AddressWithSpace, key: &H256,
24 ) -> DbResult<bool> {
25 if self.is_warm_storage_entry_in_access_list(address, key) {
26 return Ok(true);
27 }
28
29 let acc = try_loaded!(self.read_account_lock(address));
30 Ok(acc.is_warm_storage_entry(&key[..]))
31 }
32
33 fn is_warm_storage_entry_in_access_list(
34 &self, address: &AddressWithSpace, key: &H256,
35 ) -> bool {
36 let Some(access_list) = self.tx_access_list.as_ref() else {
37 return false;
38 };
39 let Some(account) = access_list.get(address) else {
40 return false;
41 };
42 account.contains(key)
43 }
44
45 pub fn set_tx_access_list(
54 &mut self, space: Space, access_list: &[AccessListItem], cip176: bool,
55 ) {
56 let access_list = if cip176 {
57 let mut warmed: HashMap<AddressWithSpace, HashSet<H256>> =
58 HashMap::new();
59 for x in access_list {
60 warmed
61 .entry(x.address.with_space(space))
62 .or_default()
63 .extend(x.storage_keys.iter().cloned());
64 }
65 warmed
66 } else {
67 access_list
68 .iter()
69 .map(|x| {
70 (
71 x.address.with_space(space),
72 x.storage_keys.iter().cloned().collect(),
73 )
74 })
75 .collect()
76 };
77
78 self.tx_access_list = Some(access_list);
79 }
80
81 pub fn touch_tx_addresses(&self, params: &ActionParams) -> DbResult<()> {
82 self.touch(¶ms.address.with_space(params.space))?;
83 self.touch(¶ms.sender.with_space(params.space))?;
84 Ok(())
85 }
86
87 pub fn clear_tx_access_list(&mut self) { self.tx_access_list = None; }
88
89 pub fn update_state_post_tx_execution(
90 &mut self, retain_transient_storage: bool,
91 ) {
92 self.clear_tx_access_list();
93 self.commit_cache(retain_transient_storage);
94 }
95}