1const HASH_SIZE: usize = sys::RANDOMX_HASH_SIZE as usize;
2
3pub struct VM {
4 cache_ptr: *mut sys::randomx_cache,
5 ptr: *mut sys::randomx_vm,
6}
7
8impl VM {
9 pub fn new(key: &[u8]) -> Self {
10 let cache_ptr = unsafe {
11 let ptr = sys::randomx_alloc_cache(sys::randomx_flags_RANDOMX_FLAG_DEFAULT);
12 sys::randomx_init_cache(
13 ptr,
14 key.as_ptr() as *const std::ffi::c_void,
15 key.len()
16 );
17
18 ptr
19 };
20
21 let ptr = unsafe {
22 sys::randomx_create_vm(
23 sys::randomx_flags_RANDOMX_FLAG_DEFAULT,
24 cache_ptr,
25 std::ptr::null_mut()
26 )
27 };
28
29 Self { cache_ptr, ptr }
30 }
31
32 pub fn calculate(&mut self, input: &[u8]) -> [u8; HASH_SIZE] {
33 let ret = [0u8; HASH_SIZE];
34
35 unsafe {
36 sys::randomx_calculate_hash(
37 self.ptr,
38 input.as_ptr() as *const std::ffi::c_void,
39 input.len(),
40 ret.as_ptr() as *mut std::ffi::c_void,
41 );
42 }
43
44 ret
45 }
46}
47
48impl Drop for VM {
49 fn drop(&mut self) {
50 unsafe {
51 sys::randomx_release_cache(self.cache_ptr);
52 sys::randomx_destroy_vm(self.ptr);
53 }
54 }
55}
56
57#[cfg(test)]
58mod tests {
59 use super::*;
60
61 #[test]
62 fn should_create_vm() {
63 let mut vm = VM::new(&b"RandomX example key"[..]);
64 let hash = vm.calculate(&b"RandomX example input"[..]);
65 assert_eq!(hash, [210, 164, 216, 149, 3, 68, 116, 1, 239, 110, 111, 48, 180, 102, 53, 180, 91, 84, 242, 90, 101, 12, 71, 70, 75, 83, 17, 249, 214, 253, 71, 89]);
66 }
67}