cfx_executor/internal_contract/components/
contract_map.rs1use std::collections::BTreeMap;
2
3use cfx_types::{Address, AddressWithSpace, Space};
4use cfx_vm_types::Spec;
5use primitives::BlockNumber;
6
7use super::{super::contracts::all_internal_contracts, InternalContractTrait};
8use crate::spec::CommonParams;
9
10#[derive(Default)]
11pub struct InternalContractMap {
12 builtin: BTreeMap<Address, Box<dyn InternalContractTrait>>,
13 activation_info: BTreeMap<BlockNumber, Vec<Address>>,
14}
15
16impl std::ops::Deref for InternalContractMap {
17 type Target = BTreeMap<Address, Box<dyn InternalContractTrait>>;
18
19 fn deref(&self) -> &Self::Target { &self.builtin }
20}
21
22impl InternalContractMap {
23 pub fn new(params: &CommonParams) -> Self {
24 let mut builtin = BTreeMap::new();
25 let mut activation_info = BTreeMap::new();
26 let mut internal_contracts = all_internal_contracts();
31
32 while let Some(contract) = internal_contracts.pop() {
33 let address = *contract.address();
34 let transition_block = if params.early_set_internal_contracts_states
35 {
36 0
37 } else {
38 contract.initialize_block(params)
39 };
40
41 builtin.insert(*contract.address(), contract);
42 activation_info
43 .entry(transition_block)
44 .or_insert(vec![])
45 .push(address);
46 }
47
48 Self {
49 builtin,
50 activation_info,
51 }
52 }
53
54 #[cfg(test)]
55 pub fn initialize_for_test() -> Vec<Address> {
56 all_internal_contracts()
57 .iter()
58 .map(|contract| *contract.address())
59 .collect()
60 }
61
62 pub fn initialized_at_genesis(&self) -> &[Address] {
63 self.initialized_at(0)
64 }
65
66 pub fn initialized_at(&self, number: BlockNumber) -> &[Address] {
67 self.activation_info
68 .get(&number)
69 .map_or(&[], |vec| vec.as_slice())
70 }
71
72 pub fn contract(
73 &self, address: &AddressWithSpace, spec: &Spec,
74 ) -> Option<&Box<dyn InternalContractTrait>> {
75 if address.space != Space::Native {
76 return None;
77 }
78 self.builtin
79 .get(&address.address)
80 .filter(|&contract| contract.is_active(spec))
81 }
82}