use {
super::*, solana_program_runtime::memory::translate_vm_slice, solana_sbpf::vm::ContextObject,
};
declare_builtin_function!(
SyscallLog,
fn rust(
invoke_context: &mut InvokeContext,
addr: u64,
len: u64,
_arg3: u64,
_arg4: u64,
_arg5: u64,
memory_mapping: &mut MemoryMapping,
) -> Result<u64, Error> {
let cost = invoke_context
.get_execution_cost()
.syscall_base_cost
.max(len);
consume_compute_meter(invoke_context, cost)?;
translate_string_and_do(
memory_mapping,
addr,
len,
invoke_context.get_check_aligned(),
&mut |string: &str| {
stable_log::program_log(&invoke_context.get_log_collector(), string);
Ok(0)
},
)?;
Ok(0)
}
);
declare_builtin_function!(
SyscallLogU64,
fn rust(
invoke_context: &mut InvokeContext,
arg1: u64,
arg2: u64,
arg3: u64,
arg4: u64,
arg5: u64,
_memory_mapping: &mut MemoryMapping,
) -> Result<u64, Error> {
let cost = invoke_context.get_execution_cost().log_64_units;
consume_compute_meter(invoke_context, cost)?;
stable_log::program_log(
&invoke_context.get_log_collector(),
&format!("{arg1:#x}, {arg2:#x}, {arg3:#x}, {arg4:#x}, {arg5:#x}"),
);
Ok(0)
}
);
declare_builtin_function!(
SyscallLogBpfComputeUnits,
fn rust(
invoke_context: &mut InvokeContext,
_arg1: u64,
_arg2: u64,
_arg3: u64,
_arg4: u64,
_arg5: u64,
_memory_mapping: &mut MemoryMapping,
) -> Result<u64, Error> {
let cost = invoke_context.get_execution_cost().syscall_base_cost;
consume_compute_meter(invoke_context, cost)?;
ic_logger_msg!(
invoke_context.get_log_collector(),
"Program consumption: {} units remaining",
invoke_context.get_remaining(),
);
Ok(0)
}
);
declare_builtin_function!(
SyscallLogPubkey,
fn rust(
invoke_context: &mut InvokeContext,
pubkey_addr: u64,
_arg2: u64,
_arg3: u64,
_arg4: u64,
_arg5: u64,
memory_mapping: &mut MemoryMapping,
) -> Result<u64, Error> {
let cost = invoke_context.get_execution_cost().log_pubkey_units;
consume_compute_meter(invoke_context, cost)?;
let pubkey = translate_type::<Pubkey>(
memory_mapping,
pubkey_addr,
invoke_context.get_check_aligned(),
)?;
stable_log::program_log(&invoke_context.get_log_collector(), &pubkey.to_string());
Ok(0)
}
);
declare_builtin_function!(
SyscallLogData,
fn rust(
invoke_context: &mut InvokeContext,
addr: u64,
len: u64,
_arg3: u64,
_arg4: u64,
_arg5: u64,
memory_mapping: &mut MemoryMapping,
) -> Result<u64, Error> {
let execution_cost = invoke_context.get_execution_cost();
consume_compute_meter(invoke_context, execution_cost.syscall_base_cost)?;
let untranslated_fields = translate_slice::<VmSlice<u8>>(
memory_mapping,
addr,
len,
invoke_context.get_check_aligned(),
)?;
consume_compute_meter(
invoke_context,
execution_cost
.syscall_base_cost
.saturating_mul(untranslated_fields.len() as u64),
)?;
consume_compute_meter(
invoke_context,
untranslated_fields
.iter()
.fold(0, |total, e| total.saturating_add(e.len())),
)?;
let mut fields = Vec::with_capacity(untranslated_fields.len());
for untranslated_field in untranslated_fields {
fields.push(translate_vm_slice(untranslated_field, memory_mapping, invoke_context.get_check_aligned())?);
}
let log_collector = invoke_context.get_log_collector();
stable_log::program_data(&log_collector, &fields);
Ok(0)
}
);