cfx_executor/state/state_object/
mod.rs1mod contract_manager;
7
8mod basic_fields;
11
12mod cache_layer;
16
17mod checkpoints;
20
21mod collateral;
23
24mod commit;
26
27mod global_statistics;
29
30mod warm;
31
32mod pos;
34
35mod save;
36
37mod sponsor;
39
40mod staking;
42
43mod storage_entry;
45
46mod reward;
47
48mod state_override;
49
50#[cfg(test)]
51mod tests;
52
53pub use self::{
54 collateral::{initialize_cip107, settle_collateral_for_all},
55 commit::StateCommitResult,
56 pos::{distribute_pos_interest, update_pos_status},
57 reward::initialize_cip137,
58 sponsor::COMMISSION_PRIVILEGE_SPECIAL_KEY,
59 staking::initialize_or_update_dao_voted_params,
60};
61#[cfg(test)]
62pub use tests::{get_state_by_epoch_id, get_state_for_genesis_write};
63
64use self::checkpoints::CheckpointLayer;
65use super::{
66 checkpoints::LazyDiscardedVec,
67 global_stat::GlobalStat,
68 overlay_account::{
69 AccountEntry, AccountEntryWithWarm, OverlayAccount, RequireFields,
70 },
71};
72use crate::substate::Substate;
73use cfx_statedb::{Result as DbResult, StateDbExt, StateDbGeneric as StateDb};
74use cfx_types::{AddressWithSpace, H256};
75use parking_lot::RwLock;
76use std::collections::{BTreeSet, HashMap, HashSet};
77
78pub struct State {
82 pub(super) db: StateDb,
84
85 pub cache: RwLock<HashMap<AddressWithSpace, AccountEntryWithWarm>>,
90
91 pub committed_cache: HashMap<AddressWithSpace, AccountEntry>,
92 tx_access_list: Option<HashMap<AddressWithSpace, HashSet<H256>>>,
93
94 global_stat: GlobalStat,
97
98 checkpoints: RwLock<LazyDiscardedVec<CheckpointLayer>>,
102}
103
104impl State {
105 pub fn new(db: StateDb) -> DbResult<Self> {
106 let initialized = db.is_initialized()?;
107
108 let world_stat = if initialized {
109 GlobalStat::loaded(&db)?
110 } else {
111 GlobalStat::assert_non_inited(&db)?;
112 GlobalStat::new()
113 };
114
115 Ok(State {
116 db,
117 cache: Default::default(),
118 committed_cache: Default::default(),
119 checkpoints: Default::default(),
120 tx_access_list: None,
121 global_stat: world_stat,
122 })
123 }
124
125 pub fn prefetch_accounts(
126 &mut self, addresses: BTreeSet<AddressWithSpace>,
127 pool: &rayon::ThreadPool,
128 ) -> DbResult<()> {
129 use rayon::prelude::*;
130
131 pool.install(|| {
132 addresses
133 .into_par_iter()
134 .map(|addr| self.prefetch(&addr, RequireFields::Code))
135 })
136 .collect::<DbResult<()>>()?;
137
138 assert!(self.committed_cache.is_empty());
139 self.commit_cache(false);
140 Ok(())
141 }
142}