Skip to main content

hopper_runtime/
syscalls.rs

1//! Minimal syscall shims exposed through Hopper Runtime.
2//!
3//! Hopper-owned crates use this module instead of binding directly to backend
4//! SDK syscall paths. That keeps backend differences inside Hopper Runtime.
5
6/// Emit a `sol_log_data` event payload.
7///
8/// # Safety
9///
10/// `segments` must point to a valid array of slice descriptors for the active
11/// backend ABI, and `segments_len` must match the number of entries.
12#[inline(always)]
13pub unsafe fn sol_log_data(segments: *const u8, segments_len: u64) {
14    #[cfg(all(target_os = "solana", feature = "hopper-native-backend"))]
15    unsafe {
16        hopper_native::syscalls::sol_log_data(segments, segments_len);
17    }
18
19    #[cfg(all(target_os = "solana", feature = "legacy-pinocchio-compat"))]
20    unsafe {
21        pinocchio::syscalls::sol_log_data(segments, segments_len);
22    }
23
24    #[cfg(all(target_os = "solana", feature = "solana-program-backend"))]
25    {
26        let slices = unsafe {
27            core::slice::from_raw_parts(segments as *const &[u8], segments_len as usize)
28        };
29        ::solana_program::log::sol_log_data(slices);
30    }
31
32    #[cfg(not(target_os = "solana"))]
33    {
34        let _ = (segments, segments_len);
35    }
36}
37
38/// Compute SHA-256 over a slice-of-slices payload.
39///
40/// # Safety
41///
42/// `vals` must point to a valid array of slice descriptors and `result` must
43/// point to writable storage for 32 output bytes.
44#[inline(always)]
45pub unsafe fn sol_sha256(vals: *const u8, vals_len: u64, result: *mut u8) {
46    #[cfg(all(target_os = "solana", feature = "hopper-native-backend"))]
47    unsafe {
48        hopper_native::syscalls::sol_sha256(vals, vals_len, result);
49    }
50
51    #[cfg(all(target_os = "solana", feature = "legacy-pinocchio-compat"))]
52    unsafe {
53        pinocchio::syscalls::sol_sha256(vals, vals_len, result);
54    }
55
56    #[cfg(all(target_os = "solana", feature = "solana-program-backend"))]
57    {
58        let slices = unsafe {
59            core::slice::from_raw_parts(vals as *const &[u8], vals_len as usize)
60        };
61        let digest = ::solana_program::hash::hashv(slices).to_bytes();
62        unsafe {
63            core::ptr::copy_nonoverlapping(digest.as_ptr(), result, digest.len());
64        }
65    }
66
67    #[cfg(not(target_os = "solana"))]
68    {
69        let _ = (vals, vals_len, result);
70    }
71}