cfx_executor/state/state_object/
contract_manager.rs

1use super::{OverlayAccount, State};
2use cfx_statedb::Result as DbResult;
3use cfx_types::{
4    Address, AddressSpaceUtil, AddressWithSpace, Space, H256, U256,
5};
6use primitives::{Account, StorageLayout};
7
8impl State {
9    pub fn new_contract_with_admin(
10        &mut self, contract: &AddressWithSpace, admin: &Address, balance: U256,
11        storage_layout: Option<StorageLayout>, cip107: bool,
12    ) -> DbResult<()> {
13        assert!(contract.space == Space::Native || admin.is_zero());
14        // Check if the new contract is deployed on a killed contract in the
15        // same block.
16        let pending_db_clear = self
17            .read_account_lock(contract)?
18            .map_or(false, |overlay| overlay.pending_db_clear());
19        let account = OverlayAccount::new_contract_with_admin(
20            contract,
21            balance,
22            admin,
23            pending_db_clear,
24            storage_layout,
25            cip107,
26        );
27        self.insert_to_cache(account);
28        Ok(())
29    }
30
31    /// Kill a contract
32    pub fn remove_contract(
33        &mut self, address: &AddressWithSpace,
34    ) -> DbResult<()> {
35        self.insert_to_cache(OverlayAccount::new_removed(address));
36
37        Ok(())
38    }
39
40    /// A special implementation to achieve the backward compatible for the
41    /// genesis (incorrect) behaviour.
42    pub fn genesis_special_remove_account(
43        &mut self, address: &Address,
44    ) -> DbResult<()> {
45        let address = address.with_native_space();
46        let mut account = Account::new_empty(&address);
47        account.code_hash = H256::default();
48        *self.write_account_or_new_lock(&address)? =
49            OverlayAccount::from_loaded(&address, account);
50        Ok(())
51    }
52}
53
54impl State {
55    #[cfg(test)]
56    pub fn new_contract_with_code(
57        &mut self, contract: &AddressWithSpace, balance: U256,
58    ) -> DbResult<()> {
59        self.new_contract(contract, balance)?;
60        self.init_code(
61            &contract,
62            vec![0x12, 0x34],
63            Address::zero(),
64            crate::tests::MOCK_TX_HASH,
65        )?;
66        Ok(())
67    }
68
69    #[cfg(test)]
70    pub fn new_contract(
71        &mut self, contract: &AddressWithSpace, balance: U256,
72    ) -> DbResult<()> {
73        use primitives::storage::STORAGE_LAYOUT_REGULAR_V0;
74
75        let pending_db_clear = self
76            .read_account_lock(contract)?
77            .map_or(false, |acc| acc.pending_db_clear());
78        let account = OverlayAccount::new_contract(
79            &contract,
80            balance,
81            pending_db_clear,
82            Some(STORAGE_LAYOUT_REGULAR_V0),
83        );
84        self.insert_to_cache(account);
85        Ok(())
86    }
87}