From f588ac1f57a7cb68b513d6b304e706abefd3f00e Mon Sep 17 00:00:00 2001 From: Sss_is_me <107824088+linnnsss@users.noreply.github.com> Date: Thu, 10 Oct 2024 12:44:21 +0800 Subject: [PATCH] update vm syscalls, error codes. fix table format (#466) --- .../docs/script/common-script-error-code.mdx | 17 +- website/docs/script/syscalls_for_script.mdx | 268 ++++++++++++++++-- website/docs/script/vm-cycle-limits.mdx | 2 +- website/docs/serialization/encoding-specs.mdx | 12 +- 4 files changed, 263 insertions(+), 36 deletions(-) diff --git a/website/docs/script/common-script-error-code.mdx b/website/docs/script/common-script-error-code.mdx index ffb5f7b7..d57c979f 100644 --- a/website/docs/script/common-script-error-code.mdx +++ b/website/docs/script/common-script-error-code.mdx @@ -7,10 +7,19 @@ title: "Common Script Error Code" CKB defines some basic error codes: -- 1: CKB_INDEX_OUT_OF_BOUND, means you have finished fetching all indices in a kind -- 2: CKB_ITEM_MISSING, means an entity is not present, such as fetching a type script from a cell that doesn’t have one. -- 3: CKB_LENGTH_NOT_ENOUGH, means some data length is wrong such as invalid script args or signature length. -- 4: CKB_INVALID_DATA, means there is something wrong with the [molecule serialization](https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0008-serialization/0008-serialization.md). +| No. | Error code | Discription | +| --- | ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| 1 | CKB_INDEX_OUT_OF_BOUND | All indices of the specified type have been fetched. | +| 2 | CKB_ITEM_MISSING | The requested entity is not present, such as fetching a Type Script from a cell that doesn’t have one. | +| 3 | CKB_LENGTH_NOT_ENOUGH | The data length is invalid, such as incorrect script arguments or signature length. | +| 4 | CKB_INVALID_DATA | Error in [molecule serialization](https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0008-serialization/0008-serialization.md). | +| 5 | CKB_WAIT_FAILURE | The file descriptor is invalid during syscall [Wait](https://github.com/nervosnetwork/rfcs/diffs?base_sha=198fc90ab7582953ed85a6655e88e51346857475&bytes=0&commentable=true&head_user=libraries&lines=0&pull_number=436&responsive=true&sha1=198fc90ab7582953ed85a6655e88e51346857475&sha2=cb0d1c2fde54b8520c33b7ac91f9e2e150df2ab2&short_path=fe60e15&start_entry=0&sticky=true&unchanged=expanded&w=false#wait). | +| 6 | CKB_INVALID_FD | The file descriptor is not owned by this process. | +| 7 | CKB_OTHER_END_CLOSED | The other end of the pipe is closed. | +| 8 | CKB_MAX_VMS_SPAWNED | The maximum count of spawned processes has been reached. | +| 9 | CKB_MAX_FDS_CREATED | The maximum count of created pipes has been reached. | + +In scenarios where read, write, or wait operations block each other, the system could enter a deadlock state. In such cases, CKB-VM will throw an internal error and terminate immediately. Molecule Error Codes from [CKB standard C library](https://github.com/nervosnetwork/ckb-c-stdlib/blob/61c7819c9ccf164f5e13d8439c554f80857e2c4b/molecule/molecule2_reader.h#L78-L85) diff --git a/website/docs/script/syscalls_for_script.mdx b/website/docs/script/syscalls_for_script.mdx index 441b701c..cada0018 100644 --- a/website/docs/script/syscalls_for_script.mdx +++ b/website/docs/script/syscalls_for_script.mdx @@ -3,37 +3,44 @@ id: syscalls-for-script title: "CKB Syscalls for Script" --- +import Tabs from "@theme/Tabs"; +import TabItem from "@theme/TabItem"; + # CKB Syscalls for Script A collection of CKB-VM syscalls. Also include relevant constant, such as return codes, sources, Cell fields, header fields, and input fields. ## CKB-VM Syscalls -| VM Ver. | Syscall ID | C Function Name | Rust Function Name | Description | -| ------- | ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| 1 | 93 | [ckb_exit](https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0009-vm-syscalls/0009-vm-syscalls.md#exit) | [exit](https://docs.rs/ckb-std/latest/ckb_std/syscalls/fn.exit.html) | Immediately terminate the execution of the currently running Script and exit with the specified return code. | -| 1 | 2061 | [ckb_load_tx_hash](https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0009-vm-syscalls/0009-vm-syscalls.md#load-transaction-hash) | [load_tx_hash](https://docs.rs/ckb-std/latest/ckb_std/high_level/fn.load_tx_hash.html) | Calculate the hash of the current transaction and copy it using partial loading. | -| 1 | 2051 | [ckb_load_transaction](https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0009-vm-syscalls/0009-vm-syscalls.md#load-transaction) | [load_transaction](https://docs.rs/ckb-std/latest/ckb_std/high_level/fn.load_transaction.html) | Serialize the full transaction of the running Script using the Molecule Encoding 1 format and copy it using partial loading. | -| 1 | 2062 | [ckb_load_script_hash](https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0009-vm-syscalls/0009-vm-syscalls.md#load-script-hash) | [load_script_hash](https://docs.rs/ckb-std/latest/ckb_std/high_level/fn.load_script_hash.html) | Calculate the hash of currently running Script and copy it using partial loading. | -| 1 | 2052 | [ckb_load_script](https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0009-vm-syscalls/0009-vm-syscalls.md#load-script) | [load_script](https://docs.rs/ckb-std/latest/ckb_std/high_level/fn.load_script.html) | Serialize the currently running Script using the Molecule Encoding 1 format and copy it using partial loading. | -| 1 | 2071 | [ckb_load_cell](https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0009-vm-syscalls/0009-vm-syscalls.md#load-cell) | [load_cell](https://docs.rs/ckb-std/latest/ckb_std/high_level/fn.load_cell.html) | Serialize the specified Cell in the current transaction using the Molecule Encoding 1 format and copy it using partial loading. | -| 1 | 2081 | [ckb_load_cell_by_field](https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0009-vm-syscalls/0009-vm-syscalls.md#load-cell-by-field) | [load_cell_by_field](https://docs.rs/ckb-std/latest/ckb_std/syscalls/fn.load_cell_by_field.html) | Load a single field from the specified Cell in the current transaction and copy it using partial loading. | -| 1 | 2092 | [ckb_load_cell_data](https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0009-vm-syscalls/0009-vm-syscalls.md#load-cell-data) | [load_cell_data](https://docs.rs/ckb-std/latest/ckb_std/high_level/fn.load_cell_data.html) | Load the data from the Cell data field in the specified Cell from the current transaction and copy it using partial loading. | -| 1 | 2091 | [ckb_load_cell_data_as_code](https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0009-vm-syscalls/0009-vm-syscalls.md#load-cell-data-as-code) | [load_cell_code](https://docs.rs/ckb-std/latest/ckb_std/syscalls/fn.load_cell_code.html) | Load the data from the Cell data field in the specified Cell from the current transaction, mark the loaded memory page as executable, and copy it using partial loading. The loaded code can then be executed by CKB-VM at a later time. | -| 1 | 2073 | [ckb_load_input](https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0009-vm-syscalls/0009-vm-syscalls.md#load-input) | [load_input](https://docs.rs/ckb-std/latest/ckb_std/high_level/fn.load_input.html) | Serialize the specified input Cell in the current transaction using the Molecule Encoding 1 format and copy it using partial loading. | -| 1 | 2083 | [ckb_load_input_by_field](https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0009-vm-syscalls/0009-vm-syscalls.md#load-input-by-field) | [load_input_by_field](https://docs.rs/ckb-std/latest/ckb_std/syscalls/fn.load_input_by_field.html) | Load a single field from the specified input Cell in the current transaction and copy it using partial loading. | -| 1 | 2072 | [ckb_load_header](https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0009-vm-syscalls/0009-vm-syscalls.md#load-header) | [load_header](https://docs.rs/ckb-std/latest/ckb_std/high_level/fn.load_header.html) | Serialize the specified header associated with an input Cell, dep Cell, or header dep using the Molecule Encoding 1 format and copy it using partial loading. | -| 1 | 2082 | [ckb_load_header_by_field](https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0009-vm-syscalls/0009-vm-syscalls.md#load-header-by-field) | [load_header_by_field](https://docs.rs/ckb-std/latest/ckb_std/syscalls/fn.load_header_by_field.html) | Load a single field from the specified header associated with an input Cell, dep Cell, or header dep and copy it using partial loading. | -| 1 | 2074 | [ckb_load_witness](https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0009-vm-syscalls/0009-vm-syscalls.md#load-witness) | [load_witness](https://docs.rs/ckb-std/latest/ckb_std/high_level/fn.load_witness.html) | Load the specified witness in the current transaction and copy it using partial loading. | -| 1 | 2177 | [ckb_debug](https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0009-vm-syscalls/0009-vm-syscalls.md#debug) | [debug](https://docs.rs/ckb-std/latest/ckb_std/syscalls/fn.debug.html) | Print the specified message in CKB's terminal output for the purposes of debugging. | -| 2 | 2041 | [ckb_vm_version](https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0034-vm-syscalls-2/0034-vm-syscalls-2.md#vm-version) | [vm_version](https://docs.rs/ckb-std/latest/ckb_std/syscalls/fn.vm_version.html) | Return the version of CKB-VM being used to execute the current Script. | -| 2 | 2042 | [ckb_current_cycles](https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0034-vm-syscalls-2/0034-vm-syscalls-2.md#current-cycles) | [current_cycles](https://docs.rs/ckb-std/latest/ckb_std/syscalls/fn.current_cycles.html) | Return the number of cycles consumed by the currently running Script _immediately before_ executing this syscall. This syscall will consume an additional 500 cycles. | -| 2 | 2043 | [ckb_exec](https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0034-vm-syscalls-2/0034-vm-syscalls-2.md#exec) | [exec](https://docs.rs/ckb-std/latest/ckb_std/syscalls/fn.exec.html) | Run a Script executable from the specified Cell using the current VM context. This replaces the original calling running Script executable with the new specified Script executable. This is similar to the [exec call]() found in several operating systems. | -| 2 | 2101 | [ckb_spawn](https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0050-vm-syscalls-3/0050-vm-syscalls-3.md#spawn) | [spawn](https://docs.rs/ckb-std/latest/ckb_std/syscalls/fn.spawn.html) | Run a Script executable from the specified Cell using the current VM context, but return to the original calling Script executable upon termination. This is similar to the [spawn function]() found in several operating systems and programming languages. | -| 2 | 2102 | [ckb_get_memory_limit](https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0050-vm-syscalls-3/0050-vm-syscalls-3.md#get-memory-limit) | [get_memory_limit](https://docs.rs/ckb-std/latest/ckb_std/syscalls/fn.get_memory_limit.html) | Return the maximum amount of memory available to the current Script being executed. | -| 2 | 2105 | [ckb_current_memory](https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0050-vm-syscalls-3/0050-vm-syscalls-3.md#current-memory) | [current_memory](https://docs.rs/ckb-std/latest/ckb_std/syscalls/fn.current_memory.html) | Get the Current Memory Usage. The result is the sum of the memory usage of the parent Script and the child Script.| | -| 2 | 2103 | [ckb_set_content](https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0050-vm-syscalls-3/0050-vm-syscalls-3.md#set-content) | [set_content](https://docs.rs/ckb-std/latest/ckb_std/syscalls/fn.set_content.html) | Set the content of the designated memory region that can be read by the parent (calling) Script which executed the current Script via the spawn function. | -| 2 | 2104 | [ckb_load_extension](https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0050-vm-syscalls-3/0050-vm-syscalls-3.md#load-block-extension) | [load_block_extension](https://docs.rs/ckb-std/latest/ckb_std/syscalls/fn.load_block_extension.html) | Load the extension field data and copy it using partial loading. | +| VM Ver. | Syscall ID | C Function Name | Rust Function Name | Description | +| ------- | ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| 1 | 93 | [ckb_exit](https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0009-vm-syscalls/0009-vm-syscalls.md#exit) | [exit](https://docs.rs/ckb-std/latest/ckb_std/syscalls/fn.exit.html) | Immediately terminate the execution of the currently running Script and exit with the specified return code. | +| 1 | 2061 | [ckb_load_tx_hash](https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0009-vm-syscalls/0009-vm-syscalls.md#load-transaction-hash) | [load_tx_hash](https://docs.rs/ckb-std/latest/ckb_std/high_level/fn.load_tx_hash.html) | Calculate the hash of the current transaction and copy it using partial loading. | +| 1 | 2051 | [ckb_load_transaction](https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0009-vm-syscalls/0009-vm-syscalls.md#load-transaction) | [load_transaction](https://docs.rs/ckb-std/latest/ckb_std/high_level/fn.load_transaction.html) | Serialize the full transaction of the running Script using the Molecule Encoding 1 format and copy it using partial loading. | +| 1 | 2062 | [ckb_load_script_hash](https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0009-vm-syscalls/0009-vm-syscalls.md#load-script-hash) | [load_script_hash](https://docs.rs/ckb-std/latest/ckb_std/high_level/fn.load_script_hash.html) | Calculate the hash of currently running Script and copy it using partial loading. | +| 1 | 2052 | [ckb_load_script](https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0009-vm-syscalls/0009-vm-syscalls.md#load-script) | [load_script](https://docs.rs/ckb-std/latest/ckb_std/high_level/fn.load_script.html) | Serialize the currently running Script using the Molecule Encoding 1 format and copy it using partial loading. | +| 1 | 2071 | [ckb_load_cell](https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0009-vm-syscalls/0009-vm-syscalls.md#load-cell) | [load_cell](https://docs.rs/ckb-std/latest/ckb_std/high_level/fn.load_cell.html) | Serialize the specified Cell in the current transaction using the Molecule Encoding 1 format and copy it using partial loading. | +| 1 | 2081 | [ckb_load_cell_by_field](https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0009-vm-syscalls/0009-vm-syscalls.md#load-cell-by-field) | [load_cell_by_field](https://docs.rs/ckb-std/latest/ckb_std/syscalls/fn.load_cell_by_field.html) | Load a single field from the specified Cell in the current transaction and copy it using partial loading. | +| 1 | 2092 | [ckb_load_cell_data](https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0009-vm-syscalls/0009-vm-syscalls.md#load-cell-data) | [load_cell_data](https://docs.rs/ckb-std/latest/ckb_std/high_level/fn.load_cell_data.html) | Load the data from the Cell data field in the specified Cell from the current transaction and copy it using partial loading. | +| 1 | 2091 | [ckb_load_cell_data_as_code](https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0009-vm-syscalls/0009-vm-syscalls.md#load-cell-data-as-code) | [load_cell_code](https://docs.rs/ckb-std/latest/ckb_std/syscalls/fn.load_cell_code.html) | Load the data from the Cell data field in the specified Cell from the current transaction, mark the loaded memory page as executable, and copy it using partial loading. The loaded code can then be executed by CKB-VM at a later time. | +| 1 | 2073 | [ckb_load_input](https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0009-vm-syscalls/0009-vm-syscalls.md#load-input) | [load_input](https://docs.rs/ckb-std/latest/ckb_std/high_level/fn.load_input.html) | Serialize the specified input Cell in the current transaction using the Molecule Encoding 1 format and copy it using partial loading. | +| 1 | 2083 | [ckb_load_input_by_field](https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0009-vm-syscalls/0009-vm-syscalls.md#load-input-by-field) | [load_input_by_field](https://docs.rs/ckb-std/latest/ckb_std/syscalls/fn.load_input_by_field.html) | Load a single field from the specified input Cell in the current transaction and copy it using partial loading. | +| 1 | 2072 | [ckb_load_header](https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0009-vm-syscalls/0009-vm-syscalls.md#load-header) | [load_header](https://docs.rs/ckb-std/latest/ckb_std/high_level/fn.load_header.html) | Serialize the specified header associated with an input Cell, dep Cell, or header dep using the Molecule Encoding 1 format and copy it using partial loading. | +| 1 | 2082 | [ckb_load_header_by_field](https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0009-vm-syscalls/0009-vm-syscalls.md#load-header-by-field) | [load_header_by_field](https://docs.rs/ckb-std/latest/ckb_std/syscalls/fn.load_header_by_field.html) | Load a single field from the specified header associated with an input Cell, dep Cell, or header dep and copy it using partial loading. | +| 1 | 2074 | [ckb_load_witness](https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0009-vm-syscalls/0009-vm-syscalls.md#load-witness) | [load_witness](https://docs.rs/ckb-std/latest/ckb_std/high_level/fn.load_witness.html) | Load the specified witness in the current transaction and copy it using partial loading. | +| 1 | 2177 | [ckb_debug](https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0009-vm-syscalls/0009-vm-syscalls.md#debug) | [debug](https://docs.rs/ckb-std/latest/ckb_std/syscalls/fn.debug.html) | Print the specified message in CKB's terminal output for the purposes of debugging. | +| 2 | 2041 | [ckb_vm_version](https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0034-vm-syscalls-2/0034-vm-syscalls-2.md#vm-version) | [vm_version](https://docs.rs/ckb-std/latest/ckb_std/syscalls/fn.vm_version.html) | Return the version of CKB-VM being used to execute the current Script. | +| 2 | 2042 | [ckb_current_cycles](https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0034-vm-syscalls-2/0034-vm-syscalls-2.md#current-cycles) | [current_cycles](https://docs.rs/ckb-std/latest/ckb_std/syscalls/fn.current_cycles.html) | Return the number of cycles consumed by the currently running Script _immediately before_ executing this syscall. This syscall will consume an additional 500 cycles. | +| 2 | 2043 | [ckb_exec](https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0034-vm-syscalls-2/0034-vm-syscalls-2.md#exec) | [exec](https://docs.rs/ckb-std/latest/ckb_std/syscalls/fn.exec.html) | Run a Script executable from the specified Cell using the current VM context. This replaces the original calling running Script executable with the new specified Script executable. This is similar to the [exec call]() found in several operating systems. | +| 2 | 2101 | [ckb_spawn](https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0050-vm-syscalls-3/0050-vm-syscalls-3.md#spawn) | [spawn](https://docs.rs/ckb-std/latest/ckb_std/syscalls/fn.spawn.html) | Run a Script executable from the specified Cell using the current VM context, but return to the original calling Script executable upon termination. This is similar to the [spawn function]() found in several operating systems and programming languages. | +| 2 | 2104 | [ckb_load_extension](https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0050-vm-syscalls-3/0050-vm-syscalls-3.md#load-block-extension) | [load_block_extension](https://docs.rs/ckb-std/latest/ckb_std/syscalls/fn.load_block_extension.html) | Load the extension field data and copy it using partial loading. | +| 2 | 2602 | [ckb_wait](https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0050-vm-syscalls-3/0050-vm-syscalls-3.md#wait) | | Pause until the execution of a process specified by `pid` has ended. | +| 2 | 2603 | [ckb_process_id](https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0050-vm-syscalls-3/0050-vm-syscalls-3.md#process-id) | | Get the current process id. | +| 2 | 2604 | [ckb_pipe](https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0050-vm-syscalls-3/0050-vm-syscalls-3.md#pipe) | | Create a pipe with read-write pair of file descriptions. | +| 2 | 2605 | [ckb_write](https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0050-vm-syscalls-3/0050-vm-syscalls-3.md#write) | | Write data to a pipe via a file descriptor. | +| 2 | 2606 | [ckb_read](https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0050-vm-syscalls-3/0050-vm-syscalls-3.md#read) | | Read data from a pipe via a file descriptor. | +| 2 | 2607 | [ckb_inherited_file_descriptors](https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0050-vm-syscalls-3/0050-vm-syscalls-3.md#inherited-file-descriptors) | | Retrieve the file descriptors available to the current process, which are passed in from the parent process. | +| 2 | 2608 | [ckb_close](https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0050-vm-syscalls-3/0050-vm-syscalls-3.md#close) | | Manually close a file descriptor. | ## Constants @@ -94,3 +101,214 @@ These are the field specifiers for syscalls that request a specific field of an | --------- | ------------------------- | -------------------------------------------- | --- | | 0 | CKB_INPUT_FIELD_OUT_POINT | The out point of the specified input Cell. | | | 1 | CKB_INPUT_FIELD_SINCE | The since value of the specified input Cell. | | + +## Spawn Example + +Consider the creation of a dependency library with a straightforward function that receives strings, concatenates them, and subsequently returns the resulting string to the caller (a.k.a, echo). + +```mdx-code-block + + +``` + +```C +#include +#include + +#include "ckb_syscalls.h" + +#define CKB_STDIN (0) +#define CKB_STDOUT (1) + +// Function read_all reads from fd until an error or EOF and returns the data it read. +int ckb_read_all(uint64_t fd, void* buffer, size_t* length) { + int err = 0; + size_t read_length = 0; + size_t full_length = *length; + uint8_t* b = buffer; + while (true) { + size_t n = full_length - read_length; + err = ckb_read(fd, b, &n); + if (err == CKB_OTHER_END_CLOSED) { + err = 0; + *length = read_length; + break; + } else { + if (err != 0) { + goto exit; + } + } + if (full_length - read_length == 0) { + err = CKB_LENGTH_NOT_ENOUGH; + if (err != 0) { + goto exit; + } + } + b += n; + read_length += n; + *length = read_length; + } + +exit: + return err; +} + +// Mimic stdio fds on linux +int create_std_fds(uint64_t* fds, uint64_t* inherited_fds) { + int err = 0; + + uint64_t to_child[2] = {0}; + uint64_t to_parent[2] = {0}; + err = ckb_pipe(to_child); + if (err != 0) { + goto exit; + } + err = ckb_pipe(to_parent); + if (err != 0) { + goto exit; + } + + inherited_fds[0] = to_child[0]; + inherited_fds[1] = to_parent[1]; + inherited_fds[2] = 0; + + fds[CKB_STDIN] = to_parent[0]; + fds[CKB_STDOUT] = to_child[1]; + +exit: + return err; +} + +int main() { + int err = 0; + + const char* argv[] = {}; + uint64_t pid = 0; + uint64_t fds[2] = {0}; + // it must be end with zero + uint64_t inherited_fds[3] = {0}; + err = create_std_fds(fds, inherited_fds); + if (err != 0) { + goto exit; + } + + spawn_args_t spgs = { + .argc = 0, + .argv = argv, + .process_id = &pid, + .inherited_fds = inherited_fds, + }; + err = ckb_spawn(0, 3, 0, 0, &spgs); + if (err != 0) { + goto exit; + } + + size_t length = 0; + length = 12; + err = ckb_write(fds[CKB_STDOUT], "Hello World!", &length); + if (err != 0) { + goto exit; + } + err = ckb_close(fds[CKB_STDOUT]); + if (err != 0) { + goto exit; + } + + uint8_t buffer[1024] = {0}; + length = 1024; + err = ckb_read_all(fds[CKB_STDIN], buffer, &length); + if (err != 0) { + goto exit; + } + err = memcmp("Hello World!", buffer, length); + if (err != 0) { + goto exit; + } + +exit: + return err; +} +``` + +```mdx-code-block + + +``` + +```C +#include +#include + +#include "ckb_syscalls.h" + +#define CKB_STDIN (0) +#define CKB_STDOUT (1) + +// Function read_all reads from fd until an error or EOF and returns the data it read. +int ckb_read_all(uint64_t fd, void* buffer, size_t* length) { + int err = 0; + size_t read_length = 0; + size_t full_length = *length; + uint8_t* b = buffer; + while (true) { + size_t n = full_length - read_length; + err = ckb_read(fd, b, &n); + if (err == CKB_OTHER_END_CLOSED) { + err = 0; + *length = read_length; + break; + } else { + if (err != 0) { + goto exit; + } + } + if (full_length - read_length == 0) { + err = CKB_LENGTH_NOT_ENOUGH; + if (err != 0) { + goto exit; + } + } + b += n; + read_length += n; + *length = read_length; + } + +exit: + return err; +} + +int main() { + int err = 0; + + uint64_t fds[2] = {0}; + uint64_t fds_len = 2; + err = ckb_inherited_file_descriptors(fds, &fds_len); + if (err != 0) { + goto exit; + } + + uint8_t buffer[1024] = {0}; + size_t length; + length = 1024; + err = ckb_read_all(fds[CKB_STDIN], buffer, &length); + if (err != 0) { + goto exit; + } + err = ckb_write(fds[CKB_STDOUT], buffer, &length); + if (err != 0) { + goto exit; + } + err = ckb_close(fds[CKB_STDOUT]); + if (err != 0) { + goto exit; + } + +exit: + return err; +} +``` + +```mdx-code-block + + +``` diff --git a/website/docs/script/vm-cycle-limits.mdx b/website/docs/script/vm-cycle-limits.mdx index 043ad0e0..1e4b18b8 100644 --- a/website/docs/script/vm-cycle-limits.mdx +++ b/website/docs/script/vm-cycle-limits.mdx @@ -168,4 +168,4 @@ The cycle consumption of each Spawn-related Syscall is as follows. The constants | process_id | 500 | | load block extension | 500 + BYTES_TRANSFERRED_CYCLES | -In addition, when a VM switches from instantiated to uninstantiated, or from uninstantiated to instantiated, each VM needs `SPAWN_EXTRA_CYCLES_BASE` cycles. +In addition, when a VM switches between instantiated and uninstantiated states, it requires `SPAWN_EXTRA_CYCLES_BASE` cycles for each transition. diff --git a/website/docs/serialization/encoding-specs.mdx b/website/docs/serialization/encoding-specs.mdx index 6e3c50ee..e302fcd6 100644 --- a/website/docs/serialization/encoding-specs.mdx +++ b/website/docs/serialization/encoding-specs.mdx @@ -17,15 +17,15 @@ Molecule categorizes data types into fixed and dynamic sizes: ## Memory Layout -| Type | Header | Body | +| Type | Header | Body | | | | | | | | | ------ | ------------ | ------------------------- | -------- | --- | -------- | ------- | ------- | --- | ------- | -| array | | item-0 | item-1 | ... | item-N | -| struct | | field-0 | field-1 | ... | field-N | -| fixvec | items-count | item-0 | item-1 | ... | item-N | +| array | | item-0 | item-1 | ... | item-N | | | | | +| struct | | field-0 | field-1 | ... | field-N | | | | | +| fixvec | items-count | item-0 | item-1 | ... | item-N | | | | | | dynvec | full-size | offset-0 | offset-1 | ... | offset-N | item-0 | item-1 | ... | item-N | | table | full-size | offset-0 | offset-1 | ... | offset-N | filed-0 | field-1 | ... | field-N | -| option | | item or none (zero bytes) | -| union | item-type-id | item | +| option | | item or none (zero bytes) | | | | | | | | +| union | item-type-id | item | | | | | | | | :::note