use std::{fmt::Debug, sync::MutexGuard};
use multiversx_chain_vm_executor::{MemLength, MemPtr, VMHooksEarlyExit};
use crate::{
blockchain::state::{AccountData, BlockConfig},
host::context::{
BackTransfers, ManagedTypeContainer, TxErrorTrace, TxFunctionName, TxInput, TxLog, TxResult,
},
schedule::GasSchedule,
types::{Address, H256, VMCodeMetadata},
};
pub trait VMHooksContext: Debug {
unsafe fn memory_load(&self, offset: MemPtr, length: MemLength) -> Vec<u8>;
unsafe fn memory_store(&self, mem_ptr: MemPtr, data: &[u8]);
fn m_types_lock(&self) -> MutexGuard<'_, ManagedTypeContainer>;
fn gas_schedule(&self) -> &GasSchedule;
fn use_gas(&mut self, gas: u64) -> Result<(), VMHooksEarlyExit>;
fn input_ref(&self) -> &TxInput;
fn current_address(&self) -> &Address {
&self.input_ref().to
}
fn tx_hash(&self) -> H256 {
self.input_ref().tx_hash.clone()
}
fn random_next_bytes(&self, length: usize) -> Vec<u8>;
fn result_lock(&self) -> MutexGuard<'_, TxResult>;
fn push_tx_log(&self, tx_log: TxLog) {
self.result_lock().result_logs.push(tx_log);
}
fn log_error_trace(&mut self, trace_message: &str) {
let func_name = self.input_ref().func_name.clone();
log::info!("Error in {func_name}: {trace_message}");
let mut tx_result = self.result_lock();
tx_result.error_trace.push(TxErrorTrace {
function_name: func_name,
error_trace_message: trace_message.to_string(),
additional_info: Vec::new(),
});
}
fn storage_read(&self, key: &[u8]) -> Vec<u8> {
self.storage_read_any_address(self.current_address(), key)
}
fn storage_read_any_address(&self, address: &Address, key: &[u8]) -> Vec<u8>;
fn storage_write(&mut self, key: &[u8], value: &[u8]) -> Result<(), VMHooksEarlyExit>;
fn get_block_config(&self) -> &BlockConfig;
fn back_transfers_lock(&self) -> MutexGuard<'_, BackTransfers>;
fn account_data(&self, address: &Address) -> Option<AccountData>;
fn account_code(&self, address: &Address) -> Vec<u8>;
fn perform_async_call(
&mut self,
to: Address,
egld_value: num_bigint::BigUint,
func_name: TxFunctionName,
args: Vec<Vec<u8>>,
) -> Result<(), VMHooksEarlyExit>;
fn perform_execute_on_dest_context(
&mut self,
to: Address,
egld_value: num_bigint::BigUint,
func_name: TxFunctionName,
args: Vec<Vec<u8>>,
) -> Result<TxResult, VMHooksEarlyExit>;
fn perform_execute_on_dest_context_readonly(
&mut self,
to: Address,
func_name: TxFunctionName,
arguments: Vec<Vec<u8>>,
) -> Result<Vec<Vec<u8>>, VMHooksEarlyExit>;
fn perform_deploy(
&mut self,
egld_value: num_bigint::BigUint,
contract_code: Vec<u8>,
code_metadata: VMCodeMetadata,
args: Vec<Vec<u8>>,
) -> Result<(Address, Vec<Vec<u8>>), VMHooksEarlyExit>;
fn perform_transfer_execute(
&mut self,
to: Address,
egld_value: num_bigint::BigUint,
func_name: TxFunctionName,
arguments: Vec<Vec<u8>>,
) -> Result<(), VMHooksEarlyExit>;
}