multiversx_chain_vm/vm_hooks/
vh_source.rs

1use std::{fmt::Debug, sync::MutexGuard};
2
3use multiversx_chain_core::types::ReturnCode;
4
5use crate::{
6    tx_mock::{BackTransfers, TxFunctionName, TxInput, TxLog, TxManagedTypes, TxResult},
7    types::{VMAddress, VMCodeMetadata, H256},
8    world_mock::{AccountData, BlockInfo},
9};
10
11/// Abstracts away the borrowing of a managed types structure.
12pub trait VMHooksHandlerSource: Debug {
13    fn m_types_lock(&self) -> MutexGuard<TxManagedTypes>;
14
15    fn halt_with_error(&self, status: ReturnCode, message: &str) -> !;
16
17    fn vm_error(&self, message: &str) -> ! {
18        self.halt_with_error(ReturnCode::ExecutionFailed, message)
19    }
20
21    fn input_ref(&self) -> &TxInput;
22
23    fn current_address(&self) -> &VMAddress {
24        &self.input_ref().to
25    }
26
27    fn tx_hash(&self) -> H256 {
28        self.input_ref().tx_hash.clone()
29    }
30
31    /// Random number generator, based on the blockchain randomness source.
32    fn random_next_bytes(&self, length: usize) -> Vec<u8>;
33
34    fn result_lock(&self) -> MutexGuard<TxResult>;
35
36    fn push_tx_log(&self, tx_log: TxLog) {
37        self.result_lock().result_logs.push(tx_log);
38    }
39
40    fn storage_read(&self, key: &[u8]) -> Vec<u8> {
41        self.storage_read_any_address(self.current_address(), key)
42    }
43
44    fn storage_read_any_address(&self, address: &VMAddress, key: &[u8]) -> Vec<u8>;
45
46    fn storage_write(&self, key: &[u8], value: &[u8]);
47
48    fn get_previous_block_info(&self) -> &BlockInfo;
49
50    fn get_current_block_info(&self) -> &BlockInfo;
51
52    fn back_transfers_lock(&self) -> MutexGuard<BackTransfers>;
53
54    /// For ownership reasons, needs to return a clone.
55    ///
56    /// Can be optimized, but is not a priority right now.
57    fn account_data(&self, address: &VMAddress) -> Option<AccountData>;
58
59    /// For ownership reasons, needs to return a clone.
60    ///
61    /// Can be optimized, but is not a priority right now.
62    fn current_account_data(&self) -> AccountData {
63        self.account_data(&self.input_ref().to)
64            .expect("missing current account")
65    }
66
67    fn account_code(&self, address: &VMAddress) -> Vec<u8>;
68
69    fn perform_async_call(
70        &self,
71        to: VMAddress,
72        egld_value: num_bigint::BigUint,
73        func_name: TxFunctionName,
74        args: Vec<Vec<u8>>,
75    ) -> !;
76
77    fn perform_execute_on_dest_context(
78        &self,
79        to: VMAddress,
80        egld_value: num_bigint::BigUint,
81        func_name: TxFunctionName,
82        args: Vec<Vec<u8>>,
83    ) -> Vec<Vec<u8>>;
84
85    fn perform_execute_on_dest_context_readonly(
86        &self,
87        to: VMAddress,
88        func_name: TxFunctionName,
89        arguments: Vec<Vec<u8>>,
90    ) -> Vec<Vec<u8>>;
91
92    fn perform_deploy(
93        &self,
94        egld_value: num_bigint::BigUint,
95        contract_code: Vec<u8>,
96        code_metadata: VMCodeMetadata,
97        args: Vec<Vec<u8>>,
98    ) -> (VMAddress, Vec<Vec<u8>>);
99
100    fn perform_transfer_execute(
101        &self,
102        to: VMAddress,
103        egld_value: num_bigint::BigUint,
104        func_name: TxFunctionName,
105        arguments: Vec<Vec<u8>>,
106    );
107}