drt_sc_scenario/debug_executor/
contract_map.rs1use 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}