multiversx_chain_vm/vm_hooks/vh_handler/
vh_endpoint_arg.rs

1use num_bigint::{BigInt, BigUint};
2use num_traits::ToPrimitive;
3
4use crate::{vm_err_msg::ERROR_NO_CALLBACK_CLOSURE, vm_hooks::VMHooksHandlerSource};
5
6use crate::types::RawHandle;
7
8use super::VMHooksManagedTypes;
9
10/// Interface to only be used by code generated by the macros.
11/// The smart contract code doesn't have access to these methods directly.
12pub trait VMHooksEndpointArgument: VMHooksHandlerSource + VMHooksManagedTypes {
13    fn get_num_arguments(&self) -> i32 {
14        self.input_ref().args.len() as i32
15    }
16
17    fn get_argument_len(&self, arg_index: i32) -> usize {
18        let arg = self.input_ref().get_argument_vec_u8(arg_index);
19        arg.len()
20    }
21
22    fn load_argument_managed_buffer(&self, arg_index: i32, dest: RawHandle) {
23        let arg_bytes = self.input_ref().get_argument_vec_u8(arg_index);
24        self.m_types_lock().mb_set(dest, arg_bytes);
25    }
26
27    fn get_argument_i64(&self, arg_index: i32) -> i64 {
28        // specific implementation provided, in order to simulate the VM error (status 10 instead of 4)
29        let bytes = self.input_ref().get_argument_vec_u8(arg_index);
30        let bi = BigInt::from_signed_bytes_be(&bytes);
31        if let Some(v) = bi.to_i64() {
32            v
33        } else {
34            self.vm_error("argument out of range");
35        }
36    }
37
38    fn get_argument_u64(&self, arg_index: i32) -> u64 {
39        // specific implementation provided, in order to simulate the VM error (status 10 instead of 4)
40        let bytes = self.input_ref().get_argument_vec_u8(arg_index);
41        let bu = BigUint::from_bytes_be(&bytes);
42        if let Some(v) = bu.to_u64() {
43            v
44        } else {
45            self.vm_error("argument out of range");
46        }
47    }
48
49    fn load_callback_closure_buffer(&self, dest: RawHandle) {
50        if let Some(closure_data) = &self.input_ref().promise_callback_closure_data {
51            self.m_types_lock().mb_set(dest, closure_data.clone());
52        } else {
53            self.vm_error(ERROR_NO_CALLBACK_CLOSURE);
54        }
55    }
56}