use std::marker::PhantomData;
use crate::bindings::vm::*;
use crate::cache::Cache;
use crate::dataset::Dataset;
use crate::errors::VmCreationError;
use crate::flags::RandomXFlags;
use crate::result_hash::ResultHash;
use crate::try_alloc;
use crate::RResult;
pub struct RandomXVM<'state, T: 'state> {
vm: *mut randomx_vm,
state: PhantomData<&'state T>,
}
impl RandomXVM<'_, Cache> {
pub fn light(flags: RandomXFlags, cache: &'_ Cache) -> RResult<Self> {
if !flags.is_light_mode() {
return Err(VmCreationError::IncorrectFastModeFlag { flags })?;
}
let vm = try_alloc! { randomx_create_vm(flags.bits(), cache.raw(), std::ptr::null_mut()), VmCreationError::AllocationFailed {flags} };
let vm = RandomXVM {
vm,
state: PhantomData,
};
Ok(vm)
}
pub fn set_new_cache(&mut self, cache: &'_ Cache) {
unsafe { randomx_vm_set_cache(self.vm, cache.raw()) }
}
}
impl RandomXVM<'_, Dataset> {
pub fn fast(flags: RandomXFlags, dataset: &'_ Dataset) -> RResult<Self> {
if !flags.is_fast_mode() {
return Err(VmCreationError::IncorrectLightModeFlag { flags })?;
}
let vm = try_alloc! { randomx_create_vm(flags.bits(), std::ptr::null_mut(), dataset.raw()), VmCreationError::AllocationFailed {flags} };
let vm = RandomXVM {
vm,
state: PhantomData,
};
Ok(vm)
}
pub fn set_new_dataset(&mut self, dataset: &'_ Dataset) {
unsafe { randomx_vm_set_dataset(self.vm, dataset.raw()) }
}
}
impl<T> Drop for RandomXVM<'_, T> {
fn drop(&mut self) {
unsafe { randomx_destroy_vm(self.vm) }
}
}
impl<T> RandomXVM<'_, T> {
pub fn calculate_hash(&self, local_nonce: &[u8]) -> ResultHash {
let mut hash = ResultHash::empty();
unsafe {
randomx_calculate_hash(
self.vm,
local_nonce.as_ptr() as *const std::ffi::c_void,
local_nonce.len(),
hash.as_raw_mut(),
)
};
hash
}
pub fn calculuate_hash_first(&self, local_nonce: &[u8]) {
unsafe {
randomx_calculate_hash_first(
self.vm,
local_nonce.as_ptr() as *const std::ffi::c_void,
local_nonce.len(),
)
};
}
pub fn calculuate_hash_next(&self, local_nonce: &[u8]) -> ResultHash {
let mut hash = ResultHash::empty();
unsafe {
randomx_calculate_hash_next(
self.vm,
local_nonce.as_ptr() as *const std::ffi::c_void,
local_nonce.len(),
hash.as_raw_mut(),
)
};
hash
}
pub fn calculuate_hash_last(&self) -> ResultHash {
let mut hash = ResultHash::empty();
unsafe { randomx_calculate_hash_last(self.vm, hash.as_raw_mut()) };
hash
}
}