solana/programs/bpf_loader/src/syscalls/sysvar.rs

142 lines
3.8 KiB
Rust
Raw Normal View History

use {super::*, crate::declare_syscall};
fn get_sysvar<T: std::fmt::Debug + Sysvar + SysvarId + Clone>(
sysvar: Result<Arc<T>, InstructionError>,
var_addr: u64,
check_aligned: bool,
memory_mapping: &mut MemoryMapping,
invoke_context: &mut InvokeContext,
) -> Result<u64, EbpfError<BpfError>> {
invoke_context.get_compute_meter().consume(
invoke_context
.get_compute_budget()
.sysvar_base_cost
.saturating_add(size_of::<T>() as u64),
)?;
let var = translate_type_mut::<T>(memory_mapping, var_addr, check_aligned)?;
let sysvar: Arc<T> = sysvar.map_err(SyscallError::InstructionError)?;
*var = T::clone(sysvar.as_ref());
Ok(SUCCESS)
}
declare_syscall!(
/// Get a Clock sysvar
SyscallGetClockSysvar,
fn call(
&mut self,
var_addr: u64,
_arg2: u64,
_arg3: u64,
_arg4: u64,
_arg5: u64,
memory_mapping: &mut MemoryMapping,
result: &mut Result<u64, EbpfError<BpfError>>,
) {
let mut invoke_context = question_mark!(
self.invoke_context
.try_borrow_mut()
.map_err(|_| SyscallError::InvokeContextBorrowFailed),
result
);
*result = get_sysvar(
invoke_context.get_sysvar_cache().get_clock(),
var_addr,
invoke_context.get_check_aligned(),
memory_mapping,
&mut invoke_context,
);
}
);
declare_syscall!(
/// Get a EpochSchedule sysvar
SyscallGetEpochScheduleSysvar,
fn call(
&mut self,
var_addr: u64,
_arg2: u64,
_arg3: u64,
_arg4: u64,
_arg5: u64,
memory_mapping: &mut MemoryMapping,
result: &mut Result<u64, EbpfError<BpfError>>,
) {
let mut invoke_context = question_mark!(
self.invoke_context
.try_borrow_mut()
.map_err(|_| SyscallError::InvokeContextBorrowFailed),
result
);
*result = get_sysvar(
invoke_context.get_sysvar_cache().get_epoch_schedule(),
var_addr,
invoke_context.get_check_aligned(),
memory_mapping,
&mut invoke_context,
);
}
);
declare_syscall!(
/// Get a Fees sysvar
SyscallGetFeesSysvar,
fn call(
&mut self,
var_addr: u64,
_arg2: u64,
_arg3: u64,
_arg4: u64,
_arg5: u64,
memory_mapping: &mut MemoryMapping,
result: &mut Result<u64, EbpfError<BpfError>>,
) {
let mut invoke_context = question_mark!(
self.invoke_context
.try_borrow_mut()
.map_err(|_| SyscallError::InvokeContextBorrowFailed),
result
);
#[allow(deprecated)]
{
*result = get_sysvar(
invoke_context.get_sysvar_cache().get_fees(),
var_addr,
invoke_context.get_check_aligned(),
memory_mapping,
&mut invoke_context,
);
}
}
);
declare_syscall!(
/// Get a Rent sysvar
SyscallGetRentSysvar,
fn call(
&mut self,
var_addr: u64,
_arg2: u64,
_arg3: u64,
_arg4: u64,
_arg5: u64,
memory_mapping: &mut MemoryMapping,
result: &mut Result<u64, EbpfError<BpfError>>,
) {
let mut invoke_context = question_mark!(
self.invoke_context
.try_borrow_mut()
.map_err(|_| SyscallError::InvokeContextBorrowFailed),
result
);
*result = get_sysvar(
invoke_context.get_sysvar_cache().get_rent(),
var_addr,
invoke_context.get_check_aligned(),
memory_mapping,
&mut invoke_context,
);
}
);