drt_sc_scenario/debug_executor/
contract_map.rs

1use super::*;
2
3use drt_chain_vm_executor::{
4    CompilationOptions, Executor, ExecutorError, Instance, OpcodeCost,
5};
6use std::{
7    collections::HashMap,
8    fmt,
9    sync::{Arc, Mutex, MutexGuard},
10};
11
12pub struct ContractMap {
13    contract_objs: HashMap<Vec<u8>, ContractContainerRef>,
14}
15
16impl fmt::Debug for ContractMap {
17    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
18        f.debug_struct("ContractMap").finish()
19    }
20}
21
22impl ContractMap {
23    pub fn new() -> Self {
24        ContractMap {
25            contract_objs: HashMap::new(),
26        }
27    }
28
29    pub fn get_contract(&self, contract_identifier: &[u8]) -> ContractContainerRef {
30        if let Some(contract_contatiner) = self.contract_objs.get(contract_identifier) {
31            contract_contatiner.clone()
32        } else {
33            unknown_contract_panic(contract_identifier)
34        }
35    }
36
37    pub fn register_contract(
38        &mut self,
39        contract_bytes: Vec<u8>,
40        contract_container: ContractContainer,
41    ) {
42        let previous_entry = self.contract_objs.insert(
43            contract_bytes,
44            ContractContainerRef::new(contract_container),
45        );
46        assert!(previous_entry.is_none(), "contract inserted twice");
47    }
48
49    pub fn contains_contract(&self, contract_bytes: &[u8]) -> bool {
50        self.contract_objs.contains_key(contract_bytes)
51    }
52}
53
54fn unknown_contract_panic(contract_identifier: &[u8]) -> ! {
55    if let Ok(s) = std::str::from_utf8(contract_identifier) {
56        panic!("Unknown contract: {s}")
57    } else {
58        panic!(
59            "Unknown contract of length {} bytes",
60            contract_identifier.len()
61        )
62    }
63}
64
65impl Default for ContractMap {
66    fn default() -> Self {
67        Self::new()
68    }
69}
70
71#[derive(Default, Clone, Debug)]
72pub struct ContractMapRef(Arc<Mutex<ContractMap>>);
73
74impl ContractMapRef {
75    pub fn new() -> Self {
76        ContractMapRef(Arc::new(Mutex::new(ContractMap::new())))
77    }
78
79    pub fn lock(&self) -> MutexGuard<ContractMap> {
80        self.0.lock().unwrap()
81    }
82}
83
84impl Executor for ContractMapRef {
85    fn set_vm_hooks_ptr(
86        &mut self,
87        _vm_hooks_ptr: *mut std::ffi::c_void,
88    ) -> Result<(), ExecutorError> {
89        todo!()
90    }
91
92    fn set_opcode_cost(&mut self, _opcode_cost: &OpcodeCost) -> Result<(), ExecutorError> {
93        Ok(())
94    }
95
96    fn new_instance(
97        &self,
98        wasm_bytes: &[u8],
99        _compilation_options: &CompilationOptions,
100    ) -> Result<Box<dyn Instance>, ExecutorError> {
101        Ok(Box::new(self.lock().get_contract(wasm_bytes)))
102    }
103
104    fn new_instance_from_cache(
105        &self,
106        _cache_bytes: &[u8],
107        _compilation_options: &CompilationOptions,
108    ) -> Result<Box<dyn Instance>, ExecutorError> {
109        panic!("ContractMap new_instance_from_cache not supported")
110    }
111}