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