Trait SyscallImpls

Source
pub trait SyscallImpls {
Show 30 methods // Provided methods fn syscall( &self, _a0: u64, _a1: u64, _a2: u64, _a3: u64, _a4: u64, _a5: u64, _n: u64, ) -> u64 { ... } fn syscall_load( &self, buf: &mut [u8], offset: usize, a3: u64, a4: u64, a5: u64, syscall_num: u64, ) -> IoResult { ... } fn debug(&self, s: &CStr) { ... } fn exit(&self, code: i8) -> ! { ... } fn load_cell( &self, buf: &mut [u8], offset: usize, index: usize, source: Source, ) -> IoResult { ... } fn load_cell_by_field( &self, buf: &mut [u8], offset: usize, index: usize, source: Source, field: CellField, ) -> IoResult { ... } fn load_cell_code( &self, buf_ptr: *mut u8, len: usize, content_offset: usize, content_size: usize, index: usize, source: Source, ) -> Result<(), Error> { ... } fn load_cell_data( &self, buf: &mut [u8], offset: usize, index: usize, source: Source, ) -> IoResult { ... } fn load_header( &self, buf: &mut [u8], offset: usize, index: usize, source: Source, ) -> IoResult { ... } fn load_header_by_field( &self, buf: &mut [u8], offset: usize, index: usize, source: Source, field: HeaderField, ) -> IoResult { ... } fn load_input( &self, buf: &mut [u8], offset: usize, index: usize, source: Source, ) -> IoResult { ... } fn load_input_by_field( &self, buf: &mut [u8], offset: usize, index: usize, source: Source, field: InputField, ) -> IoResult { ... } fn load_script(&self, buf: &mut [u8], offset: usize) -> IoResult { ... } fn load_script_hash(&self, buf: &mut [u8], offset: usize) -> IoResult { ... } fn load_transaction(&self, buf: &mut [u8], offset: usize) -> IoResult { ... } fn load_tx_hash(&self, buf: &mut [u8], offset: usize) -> IoResult { ... } fn load_witness( &self, buf: &mut [u8], offset: usize, index: usize, source: Source, ) -> IoResult { ... } fn vm_version(&self) -> u64 { ... } fn current_cycles(&self) -> u64 { ... } fn exec( &self, index: usize, source: Source, place: usize, bounds: usize, argv: &[&CStr], ) -> Result<(), Error> { ... } fn spawn( &self, index: usize, source: Source, place: usize, bounds: usize, argv: &[&CStr], inherited_fds: &[u64], ) -> Result<u64, Error> { ... } fn pipe(&self) -> Result<(u64, u64), Error> { ... } fn inherited_fds(&self, fds: &mut [u64]) -> Result<usize, Error> { ... } fn read(&self, fd: u64, buffer: &mut [u8]) -> Result<usize, Error> { ... } fn write(&self, fd: u64, buffer: &[u8]) -> Result<usize, Error> { ... } fn close(&self, fd: u64) -> Result<(), Error> { ... } fn wait(&self, pid: u64) -> Result<i8, Error> { ... } fn process_id(&self) -> u64 { ... } fn load_block_extension( &self, buf: &mut [u8], offset: usize, index: usize, source: Source, ) -> IoResult { ... } fn debug_s(&self, s: String) { ... }
}
Expand description

This trait serves several purposes:

  • Current ckb-std syscall implementations were written at different time with different mindsets, and accumulated throughout the years. As a result, it presents certain inconsistencies and issues. Just to name a few:
    • The newly introduced read syscall interprets its return values differently from old load_* syscalls. However they share the same return value type, which can be a source of confusion.
    • Some signature design could use a little work: for example, spawn sets returned process ID both in one of the mutable argument, and also in its return values. This is really duplicate information that can be revisited. In addition, the argv data structured, used by both spawn and exec, are passed differently in both syscalls. In hindset, maybe we don’t need to expose the C style SpawnArgs structure in Rust APIs, but keep it as an internal data structure.
    • The return value of inherited_fds syscall is completely ignored, only the length of written fds is returned.
  • New features such as native simulators, or fuzzing require customized syscall implementations. There is no proper way we can customize a CKB script for alternative syscall implementations.

On the other hand, compatibility remains a consideration, it might not be possible to alter current syscall implementations, which might affect real usage.

This trait aims to provide a new solution, where all CKB syscalls can be provided by a single trait. It also attempts to clear and unify syscall APIs, in a clear and easy to understand fashion.

Provided Methods§

Source

fn syscall( &self, _a0: u64, _a1: u64, _a2: u64, _a3: u64, _a4: u64, _a5: u64, _n: u64, ) -> u64

There are 2 ways you can implement this trait: you can either implement this generic syscall function, where you detect the syscall by the last n field, or you can implement each invididual syscall in a type-safe way. Dummy implementations are provided for each trait method so one can override only the needed ones.

Source

fn syscall_load( &self, buf: &mut [u8], offset: usize, a3: u64, a4: u64, a5: u64, syscall_num: u64, ) -> IoResult

Source

fn debug(&self, s: &CStr)

Source

fn exit(&self, code: i8) -> !

Source

fn load_cell( &self, buf: &mut [u8], offset: usize, index: usize, source: Source, ) -> IoResult

Source

fn load_cell_by_field( &self, buf: &mut [u8], offset: usize, index: usize, source: Source, field: CellField, ) -> IoResult

Source

fn load_cell_code( &self, buf_ptr: *mut u8, len: usize, content_offset: usize, content_size: usize, index: usize, source: Source, ) -> Result<(), Error>

Source

fn load_cell_data( &self, buf: &mut [u8], offset: usize, index: usize, source: Source, ) -> IoResult

Source

fn load_header( &self, buf: &mut [u8], offset: usize, index: usize, source: Source, ) -> IoResult

Source

fn load_header_by_field( &self, buf: &mut [u8], offset: usize, index: usize, source: Source, field: HeaderField, ) -> IoResult

Source

fn load_input( &self, buf: &mut [u8], offset: usize, index: usize, source: Source, ) -> IoResult

Source

fn load_input_by_field( &self, buf: &mut [u8], offset: usize, index: usize, source: Source, field: InputField, ) -> IoResult

Source

fn load_script(&self, buf: &mut [u8], offset: usize) -> IoResult

Source

fn load_script_hash(&self, buf: &mut [u8], offset: usize) -> IoResult

Source

fn load_transaction(&self, buf: &mut [u8], offset: usize) -> IoResult

Source

fn load_tx_hash(&self, buf: &mut [u8], offset: usize) -> IoResult

Source

fn load_witness( &self, buf: &mut [u8], offset: usize, index: usize, source: Source, ) -> IoResult

Source

fn vm_version(&self) -> u64

Source

fn current_cycles(&self) -> u64

Source

fn exec( &self, index: usize, source: Source, place: usize, bounds: usize, argv: &[&CStr], ) -> Result<(), Error>

Source

fn spawn( &self, index: usize, source: Source, place: usize, bounds: usize, argv: &[&CStr], inherited_fds: &[u64], ) -> Result<u64, Error>

Spawned process ID is returned when the syscall succeeds

Source

fn pipe(&self) -> Result<(u64, u64), Error>

Source

fn inherited_fds(&self, fds: &mut [u64]) -> Result<usize, Error>

Number of available fds is returned when the syscall succeeds, which can be bigger than the length of the passed argument fds slice

Source

fn read(&self, fd: u64, buffer: &mut [u8]) -> Result<usize, Error>

Number of read bytes is returned when the syscall succeeds. Note this syscall works unlike the load_* syscalls, it only returns the number of bytes read to passed buffer. The syscall has no way of knowing how many bytes are availble to read.

Source

fn write(&self, fd: u64, buffer: &[u8]) -> Result<usize, Error>

Number of written bytes is returned when the syscall succeeds.

Source

fn close(&self, fd: u64) -> Result<(), Error>

Source

fn wait(&self, pid: u64) -> Result<i8, Error>

Exit code of waited process is returned when the syscall succeeds.

Source

fn process_id(&self) -> u64

Source

fn load_block_extension( &self, buf: &mut [u8], offset: usize, index: usize, source: Source, ) -> IoResult

Source

fn debug_s(&self, s: String)

Implementors§