drt_chain_vm/vm_hooks/vh_impl/
vh_single_tx_api.rs

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