fvm_sdk/
lib.rs

1// Copyright 2021-2023 Protocol Labs
2// SPDX-License-Identifier: Apache-2.0, MIT
3pub mod actor;
4pub mod crypto;
5pub mod debug;
6pub mod error;
7pub mod event;
8pub mod gas;
9pub mod ipld;
10pub mod message;
11pub mod network;
12pub mod rand;
13pub mod send;
14pub mod sself;
15pub mod sys;
16pub mod vm;
17
18/// BlockID representing nil parameters or return data.
19pub const NO_DATA_BLOCK_ID: u32 = 0;
20
21// TODO: provide a custom panic handler?
22
23#[inline]
24pub(crate) fn status_code_to_bool(code: i32) -> bool {
25    code == 0
26}
27
28/// SDK functions performing a syscall return a SyscallResult type, where the
29/// Error type is an ExitCode. ExitCode::Ok is translated to an Ok result, while
30/// error codes are propagated as Err(ExitCode).
31///
32/// Error messages don't make it across the boundary, but are logged at the FVM
33/// level for debugging and informational purposes.
34pub type SyscallResult<T> = core::result::Result<T, fvm_shared::error::ErrorNumber>;
35
36/// Initialize the FVM SDK. Calling this function optional but encouraged.
37///
38/// At the moment, this will:
39///
40/// 1. Initialize logging (if "debug mode" is enabled).
41/// 2. Setup a panic handler for easier debugging.
42///
43/// In the future, this may perform additional setup operations, but will never incure more than a
44/// minimal runtime cost.
45pub fn initialize() {
46    debug::init_logging();
47    vm::set_panic_handler();
48}
49
50fn build_response(send: fvm_shared::sys::out::send::Send) -> SyscallResult<fvm_shared::Response> {
51    let exit_code = fvm_shared::error::ExitCode::new(send.exit_code);
52    let return_data = if send.return_id == NO_DATA_BLOCK_ID {
53        None
54    } else {
55        // Allocate a buffer to read the return data.
56        let mut bytes = vec![0; send.return_size as usize];
57
58        unsafe {
59            // Now read the return data.
60            let unread =
61                sys::ipld::block_read(send.return_id, 0, bytes.as_mut_ptr(), send.return_size)?;
62            assert_eq!(0, unread);
63        }
64
65        Some(fvm_ipld_encoding::ipld_block::IpldBlock {
66            codec: send.return_codec,
67            data: bytes.to_vec(),
68        })
69    };
70
71    Ok(fvm_shared::Response {
72        exit_code,
73        return_data,
74    })
75}