cfx_executor/state/overlay_account/
factory.rs1use std::sync::Arc;
2
3use cfx_types::{Address, AddressSpaceUtil, AddressWithSpace, Space, U256};
4use keccak_hash::KECCAK_EMPTY;
5use parking_lot::lock_api::RwLock;
6use primitives::{Account, SponsorInfo, StorageLayout};
7
8use super::{checkpoints::WriteCheckpointLayer, OverlayAccount};
9
10impl Default for OverlayAccount {
11 fn default() -> Self {
12 OverlayAccount {
13 address: Address::zero().with_native_space(),
14 balance: U256::zero(),
15 nonce: U256::zero(),
16 admin: Address::zero(),
17 sponsor_info: Default::default(),
18 storage_read_cache: Default::default(),
19 storage_committed_cache: Default::default(),
20 storage_write_cache: Default::default(),
21 storage_write_checkpoint: Default::default(),
22 transient_storage_cache: Default::default(),
23 transient_storage_checkpoint: Default::default(),
24 storage_layout_change: None,
25 staking_balance: 0.into(),
26 collateral_for_storage: 0.into(),
27 accumulated_interest_return: 0.into(),
28 deposit_list: None,
29 vote_stake_list: None,
30 code_hash: KECCAK_EMPTY,
31 code: None,
32 is_newly_created_contract: false,
33 pending_db_clear: false,
34 storage_overrided: false,
35 create_transaction_hash: None,
36 }
37 }
38}
39
40impl OverlayAccount {
41 pub fn from_loaded(address: &AddressWithSpace, account: Account) -> Self {
43 let overlay_account = OverlayAccount {
44 address: address.clone(),
45 balance: account.balance,
46 nonce: account.nonce,
47 admin: account.admin,
48 sponsor_info: account.sponsor_info,
49 staking_balance: account.staking_balance,
50 collateral_for_storage: account.collateral_for_storage,
51 accumulated_interest_return: account.accumulated_interest_return,
52 code_hash: account.code_hash,
53 ..Default::default()
54 };
55
56 overlay_account
57 }
58
59 pub fn new_basic(address: &AddressWithSpace, balance: U256) -> Self {
62 OverlayAccount {
63 address: address.clone(),
64 balance,
65 ..Default::default()
66 }
67 }
68
69 pub fn new_removed(address: &AddressWithSpace) -> Self {
72 OverlayAccount {
73 address: address.clone(),
74 pending_db_clear: true,
75 ..Default::default()
76 }
77 }
78
79 pub fn new_contract_with_admin(
82 address: &AddressWithSpace, balance: U256, admin: &Address,
83 pending_db_clear: bool, storage_layout: Option<StorageLayout>,
84 cip107: bool,
85 ) -> Self {
86 let sponsor_info = if cip107 && address.space == Space::Native {
87 SponsorInfo {
88 storage_points: Some(Default::default()),
89 ..Default::default()
90 }
91 } else {
92 Default::default()
93 };
94 OverlayAccount {
95 address: address.clone(),
96 balance,
97 nonce: U256::one(),
98 admin: admin.clone(),
99 sponsor_info,
100 storage_layout_change: storage_layout,
101 is_newly_created_contract: true,
102 pending_db_clear,
103 ..Default::default()
104 }
105 }
106
107 #[cfg(test)]
110 pub fn new_contract(
111 address: &AddressWithSpace, balance: U256, pending_db_clear: bool,
112 storage_layout: Option<StorageLayout>,
113 ) -> Self {
114 Self::new_contract_with_admin(
115 &address,
116 balance,
117 &Address::zero(),
118 pending_db_clear,
119 storage_layout,
120 false,
121 )
122 }
123
124 pub fn clone_account_for_checkpoint(&self, checkpoint_id: usize) -> Self {
138 OverlayAccount {
139 address: self.address,
140 balance: self.balance,
141 nonce: self.nonce,
142 admin: self.admin,
143
144 sponsor_info: self.sponsor_info.clone(),
145 staking_balance: self.staking_balance,
146 collateral_for_storage: self.collateral_for_storage,
147 accumulated_interest_return: self.accumulated_interest_return,
148 deposit_list: self.deposit_list.clone(),
149 vote_stake_list: self.vote_stake_list.clone(),
150 code_hash: self.code_hash,
151 code: self.code.clone(),
152 is_newly_created_contract: self.is_newly_created_contract,
153 pending_db_clear: self.pending_db_clear,
154 storage_write_cache: self.storage_write_cache.clone(),
155 storage_write_checkpoint: Some(RwLock::new(
156 WriteCheckpointLayer::new_empty(checkpoint_id),
157 )),
158 storage_committed_cache: self.storage_committed_cache.clone(),
159 storage_read_cache: self.storage_read_cache.clone(),
160 transient_storage_cache: self.transient_storage_cache.clone(),
161 transient_storage_checkpoint: Some(
162 WriteCheckpointLayer::new_empty(checkpoint_id),
163 ),
164 storage_layout_change: self.storage_layout_change.clone(),
165 storage_overrided: self.storage_overrided,
166 create_transaction_hash: self.create_transaction_hash.clone(),
167 }
168 }
169
170 pub fn clone_from_committed_cache(&self) -> Self {
171 assert!(self.storage_write_checkpoint.is_none());
172 assert!(self.transient_storage_checkpoint.is_none());
173 assert!(self.storage_write_cache.read().is_empty());
174 assert_eq!(Arc::strong_count(&self.storage_read_cache), 1);
175 assert_eq!(Arc::strong_count(&self.storage_committed_cache), 1);
176 assert_eq!(Arc::strong_count(&self.storage_write_cache), 1);
177 assert_eq!(Arc::strong_count(&self.transient_storage_cache), 1);
178
179 let transient_storage_cache =
182 Arc::new(RwLock::new(self.transient_storage_cache.read().clone()));
183
184 OverlayAccount {
185 address: self.address,
186 balance: self.balance,
187 nonce: self.nonce,
188 admin: self.admin,
189
190 sponsor_info: self.sponsor_info.clone(),
191 staking_balance: self.staking_balance,
192 collateral_for_storage: self.collateral_for_storage,
193 accumulated_interest_return: self.accumulated_interest_return,
194 deposit_list: self.deposit_list.clone(),
195 vote_stake_list: self.vote_stake_list.clone(),
196 code_hash: self.code_hash,
197 code: self.code.clone(),
198 is_newly_created_contract: self.is_newly_created_contract,
199 pending_db_clear: self.pending_db_clear,
200 storage_write_cache: Default::default(),
201 storage_write_checkpoint: None,
202 storage_committed_cache: self.storage_committed_cache.clone(),
203 storage_read_cache: self.storage_read_cache.clone(),
204 transient_storage_cache,
205 transient_storage_checkpoint: None,
206 storage_layout_change: self.storage_layout_change.clone(),
207 storage_overrided: self.storage_overrided,
208 create_transaction_hash: self.create_transaction_hash.clone(),
209 }
210 }
211
212 pub fn clone_account(&self) -> Self {
213 OverlayAccount {
214 address: self.address,
215 balance: self.balance,
216 nonce: self.nonce,
217 admin: self.admin,
218 sponsor_info: self.sponsor_info.clone(),
219 staking_balance: self.staking_balance,
220 collateral_for_storage: self.collateral_for_storage,
221 accumulated_interest_return: self.accumulated_interest_return,
222 deposit_list: self.deposit_list.clone(),
223 vote_stake_list: self.vote_stake_list.clone(),
224 code_hash: self.code_hash,
225 code: self.code.clone(),
226 is_newly_created_contract: self.is_newly_created_contract,
227 pending_db_clear: self.pending_db_clear,
228 storage_write_cache: Arc::new(RwLock::new(
229 self.storage_write_cache.read().clone(),
230 )),
231 storage_write_checkpoint: None,
232 storage_read_cache: Arc::new(RwLock::new(
233 self.storage_read_cache.read().clone(),
234 )),
235 transient_storage_cache: Arc::new(RwLock::new(
236 self.transient_storage_cache.read().clone(),
237 )),
238 storage_committed_cache: Arc::new(RwLock::new(
239 self.storage_committed_cache.read().clone(),
240 )),
241 transient_storage_checkpoint: None,
242 storage_layout_change: self.storage_layout_change.clone(),
243 storage_overrided: self.storage_overrided,
244 create_transaction_hash: self.create_transaction_hash.clone(),
245 }
246 }
247}
248
249impl OverlayAccount {
250 pub fn as_account(&self) -> Account {
251 let mut account = Account::new_empty(self.address());
252
253 account.balance = self.balance;
254 account.nonce = self.nonce;
255 account.code_hash = self.code_hash;
256 account.staking_balance = self.staking_balance;
257 account.collateral_for_storage = self.collateral_for_storage;
258 account.accumulated_interest_return = self.accumulated_interest_return;
259 account.admin = self.admin;
260 account.sponsor_info = self.sponsor_info.clone();
261 account.set_address(self.address);
262 account
263 }
264}