drt_sc_scenario/debug_executor/
contract_container.rs1use drt_chain_vm::tx_mock::{TxContextRef, TxFunctionName, TxPanic};
2use drt_chain_vm_executor::{BreakpointValue, ExecutorError, Instance, MemLength, MemPtr};
3use drt_sc::contract_base::CallableContract;
4use std::sync::Arc;
5
6use super::{catch_tx_panic, StaticVarStack};
7
8pub struct ContractContainer {
12 callable: Box<dyn CallableContract>,
13 function_whitelist: Option<Vec<String>>,
14 pub panic_message: bool,
15}
16
17impl ContractContainer {
18 pub fn new(
19 callable: Box<dyn CallableContract>,
20 function_whitelist: Option<Vec<String>>,
21 panic_message: bool,
22 ) -> Self {
23 ContractContainer {
24 callable,
25 function_whitelist,
26 panic_message,
27 }
28 }
29
30 fn validate_function_name(&self, function_name: &TxFunctionName) -> bool {
31 if let Some(function_whitelist) = &self.function_whitelist {
32 function_whitelist
33 .iter()
34 .any(|whitelisted_endpoint| whitelisted_endpoint.as_str() == function_name.as_str())
35 } else {
36 true
37 }
38 }
39
40 pub fn call(&self, function_name: &TxFunctionName) -> bool {
41 if self.validate_function_name(function_name) {
42 self.callable.call(function_name.as_str())
43 } else {
44 false
45 }
46 }
47}
48
49pub fn contract_instance_wrapped_execution<F>(panic_message: bool, f: F)
52where
53 F: FnOnce() -> Result<(), TxPanic>,
54{
55 StaticVarStack::static_push();
56
57 let result = catch_tx_panic(panic_message, f);
58
59 if let Err(tx_panic) = result {
60 TxContextRef::new_from_static().replace_tx_result_with_error(tx_panic);
61 }
62
63 StaticVarStack::static_pop();
64}
65
66#[derive(Clone)]
67pub struct ContractContainerRef(pub(crate) Arc<ContractContainer>);
68
69impl ContractContainerRef {
70 pub fn new(contract_container: ContractContainer) -> Self {
71 ContractContainerRef(Arc::new(contract_container))
72 }
73}
74
75impl Instance for ContractContainerRef {
76 fn call(&self, func_name: &str) -> Result<(), String> {
77 let tx_func_name = TxFunctionName::from(func_name);
78
79 contract_instance_wrapped_execution(self.0.panic_message, || {
80 let call_successful = self.0.call(&tx_func_name);
81 if call_successful {
82 Ok(())
83 } else {
84 Err(TxPanic::new(1, "invalid function (not found)"))
85 }
86 });
87
88 Ok(())
89 }
90
91 fn check_signatures(&self) -> bool {
92 true
93 }
94
95 fn has_function(&self, func_name: &str) -> bool {
96 let tx_func_name = TxFunctionName::from(func_name);
97 self.0.validate_function_name(&tx_func_name)
98 }
99
100 fn get_exported_function_names(&self) -> Vec<String> {
101 panic!("ContractContainer get_exported_function_names not yet supported")
102 }
103
104 fn set_points_limit(&self, _limit: u64) -> Result<(), String> {
105 panic!("ContractContainerRef set_points_limit not supported")
106 }
107
108 fn set_points_used(&self, _points: u64) -> Result<(), String> {
109 panic!("ContractContainerRef set_points_used not supported")
110 }
111
112 fn get_points_used(&self) -> Result<u64, String> {
113 panic!("ContractContainerRef get_points_used not supported")
114 }
115
116 fn memory_length(&self) -> Result<u64, String> {
117 panic!("ContractContainerRef memory_length not supported")
118 }
119
120 fn memory_ptr(&self) -> Result<*mut u8, String> {
121 panic!("ContractContainerRef memory_ptr not supported")
122 }
123
124 fn memory_load(
125 &self,
126 _mem_ptr: MemPtr,
127 _mem_length: MemLength,
128 ) -> Result<&[u8], ExecutorError> {
129 panic!("ContractContainerRef memory_load not supported")
130 }
131
132 fn memory_store(&self, _mem_ptr: MemPtr, _data: &[u8]) -> Result<(), ExecutorError> {
133 panic!("ContractContainerRef memory_store not supported")
134 }
135
136 fn memory_grow(&self, _by_num_pages: u32) -> Result<u32, ExecutorError> {
137 panic!("ContractContainerRef memory_grow not supported")
138 }
139
140 fn set_breakpoint_value(&self, _value: BreakpointValue) -> Result<(), String> {
141 panic!("ContractContainerRef set_breakpoint_value not supported")
142 }
143
144 fn get_breakpoint_value(&self) -> Result<BreakpointValue, String> {
145 panic!("ContractContainerRef get_breakpoint_value not supported")
146 }
147
148 fn reset(&self) -> Result<(), String> {
149 panic!("ContractContainerRef reset not supported")
150 }
151
152 fn cache(&self) -> Result<Vec<u8>, String> {
153 panic!("ContractContainerRef cache not supported")
154 }
155}