multiversx_chain_vm/vm_hooks/vh_impl/
vh_single_tx_api.rs

1use std::{
2    collections::HashMap,
3    sync::{Arc, Mutex, MutexGuard},
4};
5
6use multiversx_chain_core::types::ReturnCode;
7
8use crate::{
9    tx_mock::{BackTransfers, TxFunctionName, TxInput, TxManagedTypes, TxResult},
10    types::{VMAddress, VMCodeMetadata},
11    vm_hooks::{
12        VMHooksBigFloat, VMHooksBigInt, VMHooksBlockchain, VMHooksCallValue, VMHooksCrypto,
13        VMHooksEndpointArgument, VMHooksEndpointFinish, VMHooksError, VMHooksErrorManaged,
14        VMHooksHandler, VMHooksHandlerSource, VMHooksLog, VMHooksManagedBuffer, VMHooksManagedMap,
15        VMHooksManagedTypes, VMHooksSend, VMHooksStorageRead, VMHooksStorageWrite,
16    },
17    world_mock::{AccountData, BlockInfo},
18};
19
20#[derive(Default, Debug)]
21pub struct SingleTxApiData {
22    pub tx_input_box: Box<TxInput>,
23    pub accounts: Mutex<HashMap<VMAddress, AccountData>>,
24    pub managed_types: Mutex<TxManagedTypes>,
25    pub tx_result_cell: Mutex<TxResult>,
26    pub previous_block_info: BlockInfo,
27    pub current_block_info: BlockInfo,
28}
29
30impl SingleTxApiData {
31    pub fn with_account_mut<R, F>(&self, address: &VMAddress, f: F) -> R
32    where
33        F: FnOnce(&mut AccountData) -> R,
34    {
35        let mut accounts = self.accounts.lock().unwrap();
36        let account = accounts
37            .entry(address.clone())
38            .or_insert(AccountData::new_empty(address.clone()));
39        f(account)
40    }
41}
42
43#[derive(Default, Debug, Clone)]
44pub struct SingleTxApiVMHooksHandler(Arc<SingleTxApiData>);
45
46impl SingleTxApiVMHooksHandler {
47    pub fn with_mut_data<F, R>(&mut self, f: F) -> R
48    where
49        F: FnOnce(&mut SingleTxApiData) -> R,
50    {
51        let data = Arc::get_mut(&mut self.0)
52            .expect("could not retrieve mutable reference to SingleTxApi data");
53        f(data)
54    }
55}
56
57impl VMHooksHandlerSource for SingleTxApiVMHooksHandler {
58    fn m_types_lock(&self) -> MutexGuard<TxManagedTypes> {
59        self.0.managed_types.lock().unwrap()
60    }
61
62    fn halt_with_error(&self, status: ReturnCode, message: &str) -> ! {
63        panic!("VM error occured, status: {status}, message: {message}")
64    }
65
66    fn input_ref(&self) -> &TxInput {
67        &self.0.tx_input_box
68    }
69
70    fn random_next_bytes(&self, _length: usize) -> Vec<u8> {
71        panic!("cannot access the random bytes generator in the SingleTxApi")
72    }
73
74    fn result_lock(&self) -> MutexGuard<TxResult> {
75        self.0.tx_result_cell.lock().unwrap()
76    }
77
78    fn storage_read_any_address(&self, address: &VMAddress, key: &[u8]) -> Vec<u8> {
79        self.0.with_account_mut(address, |account| {
80            account.storage.get(key).cloned().unwrap_or_default()
81        })
82    }
83
84    fn storage_write(&self, key: &[u8], value: &[u8]) {
85        self.0.with_account_mut(&self.0.tx_input_box.to, |account| {
86            account.storage.insert(key.to_vec(), value.to_vec());
87        });
88    }
89
90    fn get_previous_block_info(&self) -> &BlockInfo {
91        &self.0.previous_block_info
92    }
93
94    fn get_current_block_info(&self) -> &BlockInfo {
95        &self.0.current_block_info
96    }
97
98    fn back_transfers_lock(&self) -> MutexGuard<BackTransfers> {
99        panic!("cannot access back transfers in the SingleTxApi")
100    }
101
102    fn account_data(&self, address: &VMAddress) -> Option<AccountData> {
103        Some(self.0.with_account_mut(address, |account| account.clone()))
104    }
105
106    fn account_code(&self, _address: &VMAddress) -> Vec<u8> {
107        vec![]
108    }
109
110    fn perform_async_call(
111        &self,
112        _to: VMAddress,
113        _egld_value: num_bigint::BigUint,
114        _func_name: TxFunctionName,
115        _args: Vec<Vec<u8>>,
116    ) -> ! {
117        panic!("cannot launch contract calls in the SingleTxApi")
118    }
119
120    fn perform_execute_on_dest_context(
121        &self,
122        _to: VMAddress,
123        _egld_value: num_bigint::BigUint,
124        _func_name: TxFunctionName,
125        _args: Vec<Vec<u8>>,
126    ) -> Vec<Vec<u8>> {
127        panic!("cannot launch contract calls in the SingleTxApi")
128    }
129
130    fn perform_execute_on_dest_context_readonly(
131        &self,
132        _to: VMAddress,
133        _func_name: TxFunctionName,
134        _arguments: Vec<Vec<u8>>,
135    ) -> Vec<Vec<u8>> {
136        panic!("cannot launch contract calls in the SingleTxApi")
137    }
138
139    fn perform_deploy(
140        &self,
141        _egld_value: num_bigint::BigUint,
142        _contract_code: Vec<u8>,
143        _code_metadata: VMCodeMetadata,
144        _args: Vec<Vec<u8>>,
145    ) -> (VMAddress, Vec<Vec<u8>>) {
146        panic!("cannot launch contract calls in the SingleTxApi")
147    }
148
149    fn perform_transfer_execute(
150        &self,
151        _to: VMAddress,
152        _egld_value: num_bigint::BigUint,
153        _func_name: TxFunctionName,
154        _arguments: Vec<Vec<u8>>,
155    ) {
156        panic!("cannot launch contract calls in the SingleTxApi")
157    }
158}
159
160impl VMHooksBigInt for SingleTxApiVMHooksHandler {}
161impl VMHooksManagedBuffer for SingleTxApiVMHooksHandler {}
162impl VMHooksManagedMap for SingleTxApiVMHooksHandler {}
163impl VMHooksBigFloat for SingleTxApiVMHooksHandler {}
164impl VMHooksManagedTypes for SingleTxApiVMHooksHandler {}
165
166impl VMHooksCallValue for SingleTxApiVMHooksHandler {}
167impl VMHooksEndpointArgument for SingleTxApiVMHooksHandler {}
168impl VMHooksEndpointFinish for SingleTxApiVMHooksHandler {}
169impl VMHooksError for SingleTxApiVMHooksHandler {}
170impl VMHooksErrorManaged for SingleTxApiVMHooksHandler {}
171impl VMHooksStorageRead for SingleTxApiVMHooksHandler {}
172impl VMHooksStorageWrite for SingleTxApiVMHooksHandler {}
173impl VMHooksCrypto for SingleTxApiVMHooksHandler {}
174impl VMHooksBlockchain for SingleTxApiVMHooksHandler {}
175impl VMHooksLog for SingleTxApiVMHooksHandler {}
176impl VMHooksSend for SingleTxApiVMHooksHandler {}
177
178impl VMHooksHandler for SingleTxApiVMHooksHandler {}