Skip to main content

multiversx_sc_scenario/executor/debug/
contract_container.rs

1use multiversx_chain_vm::host::context::TxFunctionName;
2use multiversx_sc::contract_base::CallableContract;
3use std::sync::Arc;
4
5/// Contains a reference to a contract implementation.
6///
7/// It can optionally also contain an allowed endpoint whitelist, to simulate multi-contract.
8pub struct ContractContainer {
9    callable: Box<dyn CallableContract>,
10    function_whitelist: Option<Vec<String>>,
11    pub panic_message: bool,
12}
13
14impl ContractContainer {
15    pub fn new(
16        callable: Box<dyn CallableContract>,
17        function_whitelist: Option<Vec<String>>,
18        panic_message: bool,
19    ) -> Self {
20        ContractContainer {
21            callable,
22            function_whitelist,
23            panic_message,
24        }
25    }
26
27    /// Dummy object for tests where no proper context is created on stack.
28    pub fn dummy() -> Self {
29        ContractContainer {
30            callable: Box::new(DummyCallableContract),
31            function_whitelist: Some(Vec::new()),
32            panic_message: true,
33        }
34    }
35
36    pub fn validate_function_name(&self, function_name: &TxFunctionName) -> bool {
37        if let Some(function_whitelist) = &self.function_whitelist {
38            function_whitelist
39                .iter()
40                .any(|whitelisted_endpoint| whitelisted_endpoint.as_str() == function_name.as_str())
41        } else {
42            true
43        }
44    }
45
46    pub fn call(&self, function_name: &TxFunctionName) -> bool {
47        if self.validate_function_name(function_name) {
48            self.callable.call(function_name.as_str())
49        } else {
50            false
51        }
52    }
53}
54
55#[derive(Clone, Debug)]
56pub struct ContractContainerRef(pub(crate) Arc<ContractContainer>);
57
58impl ContractContainerRef {
59    pub fn new(contract_container: ContractContainer) -> Self {
60        ContractContainerRef(Arc::new(contract_container))
61    }
62
63    pub fn has_function(&self, func_name: &str) -> bool {
64        let tx_func_name = TxFunctionName::from(func_name);
65        self.0.validate_function_name(&tx_func_name)
66    }
67}
68
69impl core::fmt::Debug for ContractContainer {
70    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
71        f.debug_struct("ContractContainer")
72            .field("function_whitelist", &self.function_whitelist)
73            .finish()
74    }
75}
76
77pub struct DummyCallableContract;
78
79impl CallableContract for DummyCallableContract {
80    fn call(&self, _fn_name: &str) -> bool {
81        false
82    }
83}