multiversx_sc_scenario/api/core_api_vh/
blockchain_api_vh.rs

1use multiversx_sc::{
2    api::{BlockchainApi, BlockchainApiImpl, HandleConstraints, ManagedBufferApiImpl, RawHandle},
3    types::{Address, EsdtLocalRoleFlags, H256},
4};
5
6use crate::api::{i32_to_bool, VMHooksApi, VMHooksApiBackend};
7
8impl<VHB: VMHooksApiBackend> BlockchainApi for VMHooksApi<VHB> {
9    type BlockchainApiImpl = Self;
10
11    fn blockchain_api_impl() -> Self::BlockchainApiImpl {
12        Self::api_impl()
13    }
14}
15
16impl<VHB: VMHooksApiBackend> BlockchainApiImpl for VMHooksApi<VHB> {
17    fn get_caller_legacy(&self) -> Address {
18        panic!("legacy BlockchainApi functionality no longer supported")
19    }
20
21    fn load_caller_managed(&self, dest: Self::ManagedBufferHandle) {
22        self.assert_live_handle(&dest);
23        self.with_vm_hooks(|vh| vh.managed_caller(dest.get_raw_handle_unchecked()));
24    }
25
26    fn get_sc_address_legacy(&self) -> Address {
27        panic!("legacy BlockchainApi functionality no longer supported")
28    }
29
30    fn load_sc_address_managed(&self, dest: Self::ManagedBufferHandle) {
31        self.assert_live_handle(&dest);
32        self.with_vm_hooks(|vh| vh.managed_sc_address(dest.get_raw_handle_unchecked()));
33    }
34
35    fn load_owner_address_managed(&self, dest: Self::ManagedBufferHandle) {
36        self.with_vm_hooks(|vh| vh.managed_owner_address(dest.get_raw_handle_unchecked()));
37    }
38
39    fn get_shard_of_address_legacy(&self, _address: &Address) -> u32 {
40        panic!("legacy BlockchainApi functionality no longer supported")
41    }
42
43    fn get_shard_of_address(&self, address_handle: Self::ManagedBufferHandle) -> u32 {
44        self.assert_live_handle(&address_handle);
45        self.with_temp_address_ptr(address_handle, |address_ptr| {
46            self.with_vm_hooks(|vh| vh.get_shard_of_address(address_ptr))
47        }) as u32
48    }
49
50    fn is_smart_contract_legacy(&self, _address: &Address) -> bool {
51        panic!("legacy BlockchainApi functionality no longer supported")
52    }
53
54    fn is_smart_contract(&self, address_handle: Self::ManagedBufferHandle) -> bool {
55        self.assert_live_handle(&address_handle);
56        let result = self.with_temp_address_ptr(address_handle, |address_ptr| {
57            self.with_vm_hooks(|vh| vh.is_smart_contract(address_ptr))
58        });
59        i32_to_bool(result)
60    }
61
62    fn load_balance_legacy(&self, _dest: Self::BigIntHandle, _address: &Address) {
63        panic!("legacy BlockchainApi functionality no longer supported")
64    }
65
66    fn load_balance(&self, dest: Self::BigIntHandle, address_handle: Self::ManagedBufferHandle) {
67        self.assert_live_handle(&dest);
68        self.assert_live_handle(&address_handle);
69        self.with_temp_address_ptr(address_handle, |address_ptr: isize| {
70            self.with_vm_hooks(|vh| {
71                vh.big_int_get_external_balance(address_ptr, dest.get_raw_handle_unchecked())
72            })
73        });
74    }
75
76    fn load_state_root_hash_managed(&self, _dest: Self::ManagedBufferHandle) {
77        panic!("state root hash not implemented")
78    }
79
80    fn get_tx_hash_legacy(&self) -> H256 {
81        panic!("legacy BlockchainApi functionality no longer supported")
82    }
83
84    fn load_tx_hash_managed(&self, dest: Self::ManagedBufferHandle) {
85        self.assert_live_handle(&dest);
86        self.with_vm_hooks(|vh| vh.managed_get_original_tx_hash(dest.get_raw_handle_unchecked()));
87    }
88
89    fn get_gas_left(&self) -> u64 {
90        self.with_vm_hooks(|vh| vh.get_gas_left()) as u64
91    }
92
93    fn get_block_timestamp(&self) -> u64 {
94        self.with_vm_hooks(|vh| vh.get_block_timestamp()) as u64
95    }
96
97    fn get_block_timestamp_ms(&self) -> u64 {
98        self.with_vm_hooks(|vh| vh.get_block_timestamp_ms()) as u64
99    }
100
101    fn get_block_nonce(&self) -> u64 {
102        self.with_vm_hooks(|vh| vh.get_block_nonce()) as u64
103    }
104
105    fn get_block_round(&self) -> u64 {
106        self.with_vm_hooks(|vh| vh.get_block_round()) as u64
107    }
108
109    fn get_block_epoch(&self) -> u64 {
110        self.with_vm_hooks(|vh| vh.get_block_epoch()) as u64
111    }
112
113    fn load_block_random_seed_managed(&self, dest: Self::ManagedBufferHandle) {
114        self.assert_live_handle(&dest);
115        self.with_vm_hooks(|vh| vh.managed_get_block_random_seed(dest.get_raw_handle_unchecked()));
116    }
117
118    fn get_prev_block_timestamp(&self) -> u64 {
119        self.with_vm_hooks(|vh| vh.get_prev_block_timestamp()) as u64
120    }
121
122    fn get_prev_block_timestamp_ms(&self) -> u64 {
123        self.with_vm_hooks(|vh| vh.get_prev_block_timestamp_ms()) as u64
124    }
125
126    fn get_prev_block_nonce(&self) -> u64 {
127        self.with_vm_hooks(|vh| vh.get_prev_block_nonce()) as u64
128    }
129
130    fn get_prev_block_round(&self) -> u64 {
131        self.with_vm_hooks(|vh| vh.get_prev_block_round()) as u64
132    }
133
134    fn get_prev_block_epoch(&self) -> u64 {
135        self.with_vm_hooks(|vh| vh.get_prev_block_epoch()) as u64
136    }
137
138    fn get_prev_block_random_seed_legacy(&self) -> Box<[u8; 48]> {
139        panic!("legacy BlockchainApi functionality no longer supported")
140    }
141
142    fn load_prev_block_random_seed_managed(&self, dest: Self::ManagedBufferHandle) {
143        self.assert_live_handle(&dest);
144        self.with_vm_hooks(|vh| {
145            vh.managed_get_prev_block_random_seed(dest.get_raw_handle_unchecked())
146        });
147    }
148
149    fn get_block_round_time_ms(&self) -> u64 {
150        self.with_vm_hooks(|vh| vh.get_block_round_time_ms()) as u64
151    }
152
153    fn epoch_start_block_timestamp_ms(&self) -> u64 {
154        self.with_vm_hooks(|vh| vh.epoch_start_block_timestamp_ms()) as u64
155    }
156
157    fn epoch_start_block_nonce(&self) -> u64 {
158        self.with_vm_hooks(|vh| vh.epoch_start_block_nonce()) as u64
159    }
160
161    fn epoch_start_block_round(&self) -> u64 {
162        self.with_vm_hooks(|vh| vh.epoch_start_block_round()) as u64
163    }
164
165    fn get_current_esdt_nft_nonce(
166        &self,
167        address_handle: Self::ManagedBufferHandle,
168        token_id_handle: Self::ManagedBufferHandle,
169    ) -> u64 {
170        self.assert_live_handle(&address_handle);
171        self.assert_live_handle(&token_id_handle);
172        let token_id_len = self.mb_len(token_id_handle.clone());
173        let result = self.with_temp_address_ptr(address_handle, |address_ptr| {
174            self.with_temp_buffer_ptr(token_id_handle, token_id_len, |token_id_ptr| {
175                self.with_vm_hooks(|vh| {
176                    vh.get_current_esdt_nft_nonce(address_ptr, token_id_ptr, token_id_len as isize)
177                })
178            })
179        });
180        result as u64
181    }
182
183    fn load_esdt_balance(
184        &self,
185        address_handle: Self::ManagedBufferHandle,
186        token_id_handle: Self::ManagedBufferHandle,
187        nonce: u64,
188        dest: Self::BigIntHandle,
189    ) {
190        self.assert_live_handle(&address_handle);
191        self.assert_live_handle(&token_id_handle);
192        let token_id_len = self.mb_len(token_id_handle.clone());
193        self.with_temp_address_ptr(address_handle, |address_ptr| {
194            self.with_temp_buffer_ptr(token_id_handle, token_id_len, |token_id_ptr| {
195                self.with_vm_hooks(|vh| {
196                    vh.big_int_get_esdt_external_balance(
197                        address_ptr,
198                        token_id_ptr,
199                        token_id_len as isize,
200                        nonce as i64,
201                        dest.get_raw_handle_unchecked(),
202                    )
203                })
204            })
205        });
206    }
207
208    fn managed_get_esdt_token_data(
209        &self,
210        address_handle: RawHandle,
211        token_id_handle: RawHandle,
212        nonce: u64,
213        value_handle: RawHandle,
214        properties_handle: RawHandle,
215        hash_handle: RawHandle,
216        name_handle: RawHandle,
217        attributes_handle: RawHandle,
218        creator_handle: RawHandle,
219        royalties_handle: RawHandle,
220        uris_handle: RawHandle,
221    ) {
222        self.with_vm_hooks(|vh| {
223            vh.managed_get_esdt_token_data(
224                address_handle,
225                token_id_handle,
226                nonce as i64,
227                value_handle,
228                properties_handle,
229                hash_handle,
230                name_handle,
231                attributes_handle,
232                creator_handle,
233                royalties_handle,
234                uris_handle,
235            )
236        });
237    }
238
239    fn managed_get_back_transfers(
240        &self,
241        esdt_transfer_value_handle: RawHandle,
242        call_value_handle: RawHandle,
243    ) {
244        self.with_vm_hooks(|vh| {
245            vh.managed_get_back_transfers(esdt_transfer_value_handle, call_value_handle)
246        });
247    }
248
249    fn check_esdt_frozen(
250        &self,
251        address_handle: Self::ManagedBufferHandle,
252        token_id_handle: Self::ManagedBufferHandle,
253        nonce: u64,
254    ) -> bool {
255        self.assert_live_handle(&address_handle);
256        self.assert_live_handle(&token_id_handle);
257        let result = self.with_vm_hooks(|vh| {
258            vh.managed_is_esdt_frozen(
259                address_handle.get_raw_handle_unchecked(),
260                token_id_handle.get_raw_handle_unchecked(),
261                nonce as i64,
262            )
263        });
264        i32_to_bool(result)
265    }
266
267    fn check_esdt_paused(&self, token_id_handle: Self::ManagedBufferHandle) -> bool {
268        self.assert_live_handle(&token_id_handle);
269        let result = self.with_vm_hooks(|vh| {
270            vh.managed_is_esdt_paused(token_id_handle.get_raw_handle_unchecked())
271        });
272        i32_to_bool(result)
273    }
274
275    fn check_esdt_limited_transfer(&self, token_id_handle: Self::ManagedBufferHandle) -> bool {
276        self.assert_live_handle(&token_id_handle);
277        let result = self.with_vm_hooks(|vh| {
278            vh.managed_is_esdt_limited_transfer(token_id_handle.get_raw_handle_unchecked())
279        });
280        i32_to_bool(result)
281    }
282
283    fn load_esdt_local_roles(
284        &self,
285        token_id_handle: Self::ManagedBufferHandle,
286    ) -> EsdtLocalRoleFlags {
287        self.assert_live_handle(&token_id_handle);
288        let result = self.with_vm_hooks(|vh| {
289            vh.get_esdt_local_roles(token_id_handle.get_raw_handle_unchecked())
290        });
291
292        multiversx_sc::types::EsdtLocalRoleFlags::from_bits_retain(result as u64)
293    }
294
295    fn managed_is_builtin_function(&self, function_name_handle: Self::ManagedBufferHandle) -> bool {
296        i32_to_bool(self.with_vm_hooks(|vh| {
297            vh.managed_is_builtin_function(function_name_handle.get_raw_handle_unchecked())
298        }))
299    }
300
301    fn managed_get_code_metadata(
302        &self,
303        address_handle: Self::ManagedBufferHandle,
304        response_handle: Self::ManagedBufferHandle,
305    ) {
306        self.with_vm_hooks(|vh| {
307            vh.managed_get_code_metadata(
308                address_handle.get_raw_handle_unchecked(),
309                response_handle.get_raw_handle_unchecked(),
310            )
311        });
312    }
313
314    fn managed_get_code_hash(
315        &self,
316        address_handle: Self::ManagedBufferHandle,
317        code_hash_handle: Self::ManagedBufferHandle,
318    ) {
319        self.with_vm_hooks(|vh| {
320            vh.managed_get_code_hash(
321                address_handle.get_raw_handle_unchecked(),
322                code_hash_handle.get_raw_handle_unchecked(),
323            )
324        });
325    }
326
327    fn managed_get_esdt_token_type(
328        &self,
329        address_handle: Self::ManagedBufferHandle,
330        token_id_handle: Self::ManagedBufferHandle,
331        nonce: u64,
332        dest_handle: Self::BigIntHandle,
333    ) {
334        self.with_vm_hooks(|vh| {
335            vh.managed_get_esdt_token_type(
336                address_handle.get_raw_handle_unchecked(),
337                token_id_handle.get_raw_handle_unchecked(),
338                nonce as i64,
339                dest_handle.get_raw_handle_unchecked(),
340            )
341        });
342    }
343}