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;
6
7use super::State;
8
9impl State {
10 pub fn is_warm_account(&self, address: &AddressWithSpace) -> bool {
11 if self
12 .tx_access_list
13 .as_ref()
14 .map_or(false, |x| x.contains_key(address))
15 {
16 return true;
17 }
18 self.cache.read().get(address).map_or(false, |x| x.warm)
19 }
20
21 pub fn is_warm_storage_entry(
22 &self, address: &AddressWithSpace, key: &H256,
23 ) -> DbResult<bool> {
24 if self.is_warm_storage_entry_in_access_list(address, key) {
25 return Ok(true);
26 }
27
28 let acc = try_loaded!(self.read_account_lock(address));
29 Ok(acc.is_warm_storage_entry(&key[..]))
30 }
31
32 fn is_warm_storage_entry_in_access_list(
33 &self, address: &AddressWithSpace, key: &H256,
34 ) -> bool {
35 let Some(access_list) = self.tx_access_list.as_ref() else {
36 return false;
37 };
38 let Some(account) = access_list.get(address) else {
39 return false;
40 };
41 account.contains(key)
42 }
43
44 pub fn set_tx_access_list(
45 &mut self, space: Space, access_list: &[AccessListItem],
46 ) {
47 let access_list = access_list
48 .iter()
49 .map(|x| {
50 (
51 x.address.with_space(space),
52 x.storage_keys.iter().cloned().collect(),
53 )
54 })
55 .collect();
56
57 self.tx_access_list = Some(access_list);
58 }
59
60 pub fn touch_tx_addresses(&self, params: &ActionParams) -> DbResult<()> {
61 self.touch(¶ms.address.with_space(params.space))?;
62 self.touch(¶ms.sender.with_space(params.space))?;
63 Ok(())
64 }
65
66 pub fn clear_tx_access_list(&mut self) { self.tx_access_list = None; }
67
68 pub fn update_state_post_tx_execution(
69 &mut self, retain_transient_storage: bool,
70 ) {
71 self.clear_tx_access_list();
72 self.commit_cache(retain_transient_storage);
73 }
74}