use {super::*, crate::declare_syscall};
declare_syscall!(
SyscallLog,
fn call(
&mut self,
addr: u64,
len: u64,
_arg3: u64,
_arg4: u64,
_arg5: u64,
memory_mapping: &mut MemoryMapping,
result: &mut Result<u64, EbpfError<BpfError>>,
) {
let invoke_context = question_mark!(
self.invoke_context
.try_borrow()
.map_err(|_| SyscallError::InvokeContextBorrowFailed),
result
);
let cost = invoke_context
.get_compute_budget()
.syscall_base_cost
.max(len);
question_mark!(invoke_context.get_compute_meter().consume(cost), result);
question_mark!(
translate_string_and_do(
memory_mapping,
addr,
len,
invoke_context.get_check_aligned(),
invoke_context.get_check_size(),
&mut |string: &str| {
stable_log::program_log(&invoke_context.get_log_collector(), string);
Ok(0)
}
),
result
);
*result = Ok(0);
}
);
declare_syscall!(
SyscallLogU64,
fn call(
&mut self,
arg1: u64,
arg2: u64,
arg3: u64,
arg4: u64,
arg5: u64,
_memory_mapping: &mut MemoryMapping,
result: &mut Result<u64, EbpfError<BpfError>>,
) {
let invoke_context = question_mark!(
self.invoke_context
.try_borrow()
.map_err(|_| SyscallError::InvokeContextBorrowFailed),
result
);
let cost = invoke_context.get_compute_budget().log_64_units;
question_mark!(invoke_context.get_compute_meter().consume(cost), result);
stable_log::program_log(
&invoke_context.get_log_collector(),
&format!(
"{:#x}, {:#x}, {:#x}, {:#x}, {:#x}",
arg1, arg2, arg3, arg4, arg5
),
);
*result = Ok(0);
}
);
declare_syscall!(
SyscallLogBpfComputeUnits,
fn call(
&mut self,
_arg1: u64,
_arg2: u64,
_arg3: u64,
_arg4: u64,
_arg5: u64,
_memory_mapping: &mut MemoryMapping,
result: &mut Result<u64, EbpfError<BpfError>>,
) {
let invoke_context = question_mark!(
self.invoke_context
.try_borrow()
.map_err(|_| SyscallError::InvokeContextBorrowFailed),
result
);
let cost = invoke_context.get_compute_budget().syscall_base_cost;
question_mark!(invoke_context.get_compute_meter().consume(cost), result);
ic_logger_msg!(
invoke_context.get_log_collector(),
"Program consumption: {} units remaining",
invoke_context.get_compute_meter().borrow().get_remaining()
);
*result = Ok(0);
}
);
declare_syscall!(
SyscallLogPubkey,
fn call(
&mut self,
pubkey_addr: u64,
_arg2: u64,
_arg3: u64,
_arg4: u64,
_arg5: u64,
memory_mapping: &mut MemoryMapping,
result: &mut Result<u64, EbpfError<BpfError>>,
) {
let invoke_context = question_mark!(
self.invoke_context
.try_borrow()
.map_err(|_| SyscallError::InvokeContextBorrowFailed),
result
);
let cost = invoke_context.get_compute_budget().log_pubkey_units;
question_mark!(invoke_context.get_compute_meter().consume(cost), result);
let pubkey = question_mark!(
translate_type::<Pubkey>(
memory_mapping,
pubkey_addr,
invoke_context.get_check_aligned()
),
result
);
stable_log::program_log(&invoke_context.get_log_collector(), &pubkey.to_string());
*result = Ok(0);
}
);
declare_syscall!(
SyscallLogData,
fn call(
&mut self,
addr: u64,
len: u64,
_arg3: u64,
_arg4: u64,
_arg5: u64,
memory_mapping: &mut MemoryMapping,
result: &mut Result<u64, EbpfError<BpfError>>,
) {
let invoke_context = question_mark!(
self.invoke_context
.try_borrow()
.map_err(|_| SyscallError::InvokeContextBorrowFailed),
result
);
let budget = invoke_context.get_compute_budget();
question_mark!(
invoke_context
.get_compute_meter()
.consume(budget.syscall_base_cost),
result
);
let untranslated_fields = question_mark!(
translate_slice::<&[u8]>(
memory_mapping,
addr,
len,
invoke_context.get_check_aligned(),
invoke_context.get_check_size(),
),
result
);
question_mark!(
invoke_context.get_compute_meter().consume(
budget
.syscall_base_cost
.saturating_mul(untranslated_fields.len() as u64)
),
result
);
question_mark!(
invoke_context.get_compute_meter().consume(
untranslated_fields
.iter()
.fold(0, |total, e| total.saturating_add(e.len() as u64))
),
result
);
let mut fields = Vec::with_capacity(untranslated_fields.len());
for untranslated_field in untranslated_fields {
fields.push(question_mark!(
translate_slice::<u8>(
memory_mapping,
untranslated_field.as_ptr() as *const _ as u64,
untranslated_field.len() as u64,
invoke_context.get_check_aligned(),
invoke_context.get_check_size(),
),
result
));
}
let log_collector = invoke_context.get_log_collector();
stable_log::program_data(&log_collector, &fields);
*result = Ok(0);
}
);