Skip to main content

fluentbase_runtime/
syscall_handler.rs

1use crate::RuntimeContext;
2use fluentbase_types::{ExitCode, SysFuncIdx};
3use rwasm::{StoreTr, TrapCode, TypedCaller, Value};
4
5mod edwards;
6pub use edwards::*;
7mod host;
8pub use host::*;
9mod hashing;
10pub use hashing::*;
11mod uint256;
12pub use uint256::*;
13mod weierstrass;
14pub use weierstrass::*;
15mod tower;
16pub use tower::*;
17
18/// Routes a syscall identified by func_idx to the corresponding runtime instruction handler.
19pub(crate) fn runtime_syscall_handler(
20    caller: &mut TypedCaller<RuntimeContext>,
21    func_idx: u32,
22    params: &[Value],
23    result: &mut [Value],
24) -> Result<(), TrapCode> {
25    let sys_func_idx = SysFuncIdx::from_repr(func_idx).ok_or(TrapCode::UnknownExternalFunction)?;
26    invoke_runtime_handler(caller, sys_func_idx, params, result)
27}
28
29#[rustfmt::skip]
30/// Dispatches a system function index to its corresponding syscall handler.
31///
32/// This is the central runtime syscall dispatcher used by runtime_syscall_handler.
33/// It routes the call based on SysFuncIdx without performing additional validation.
34pub fn invoke_runtime_handler(
35    caller: &mut impl StoreTr<RuntimeContext>,
36    sys_func_idx: SysFuncIdx,
37    params: &[Value],
38    result: &mut [Value],
39) -> Result<(), TrapCode> {
40    match sys_func_idx {
41        // input/output & state control (0x00)
42        SysFuncIdx::EXIT => syscall_exit_handler(caller, params, result),
43        SysFuncIdx::STATE => syscall_state_handler(caller, params, result),
44        SysFuncIdx::READ_INPUT => syscall_read_input_handler(caller, params, result),
45        SysFuncIdx::INPUT_SIZE => syscall_input_size_handler(caller, params, result),
46        SysFuncIdx::WRITE_OUTPUT => syscall_write_output_handler(caller, params, result),
47        SysFuncIdx::OUTPUT_SIZE => syscall_output_size_handler(caller, params, result),
48        SysFuncIdx::READ_OUTPUT => syscall_read_output_handler(caller, params, result),
49        SysFuncIdx::EXEC => syscall_exec_handler(caller, params, result),
50        SysFuncIdx::RESUME => syscall_resume_handler(caller, params, result),
51        SysFuncIdx::FORWARD_OUTPUT => syscall_forward_output_handler(caller, params, result),
52        SysFuncIdx::CHARGE_FUEL_MANUALLY => syscall_charge_fuel_manually_handler(caller, params, result),
53        SysFuncIdx::FUEL => syscall_fuel_handler(caller, params, result),
54        SysFuncIdx::DEBUG_LOG => syscall_debug_log_handler(caller, params, result),
55        SysFuncIdx::CHARGE_FUEL => syscall_charge_fuel_handler(caller, params, result),
56        SysFuncIdx::ENTER_UNCONSTRAINED => syscall_enter_leave_unconstrained_handler(caller, params, result),
57        SysFuncIdx::EXIT_UNCONSTRAINED => syscall_enter_leave_unconstrained_handler(caller, params, result),
58        // TODO(dmitry123): This syscall is disabled since it can cause panic, we should refine it
59        //  by introducing new system contracts where the same functionality is achieved.
60        SysFuncIdx::WRITE_FD => Err(TrapCode::UnreachableCodeReached),
61
62        // hashing functions (0x01)
63        SysFuncIdx::KECCAK256 => syscall_hashing_keccak256_handler(caller, params, result),
64        SysFuncIdx::KECCAK256_PERMUTE => syscall_hashing_keccak256_permute_handler(caller, params, result),
65        // TODO(dmitry123): This syscall is disabled since we don't support SVM yet.
66        SysFuncIdx::POSEIDON => Err(TrapCode::UnreachableCodeReached),
67        SysFuncIdx::SHA256_EXTEND => syscall_hashing_sha256_extend_handler(caller, params, result),
68        SysFuncIdx::SHA256_COMPRESS => syscall_hashing_sha256_compress_handler(caller, params, result),
69        SysFuncIdx::SHA256 => syscall_hashing_sha256_handler(caller, params, result),
70        SysFuncIdx::BLAKE3 => syscall_hashing_blake3_handler(caller, params, result),
71
72        // ed25519 (0x02)
73        SysFuncIdx::ED25519_DECOMPRESS => syscall_ed25519_decompress_handler(caller, params, result),
74        SysFuncIdx::ED25519_ADD => syscall_edwards_add_handler(caller, params, result),
75
76        // fp1/fp2 tower field (0x03)
77        SysFuncIdx::TOWER_FP1_BN254_ADD => syscall_tower_fp1_bn254_add_handler(caller, params, result),
78        SysFuncIdx::TOWER_FP1_BN254_SUB => syscall_tower_fp1_bn254_sub_handler(caller, params, result),
79        SysFuncIdx::TOWER_FP1_BN254_MUL => syscall_tower_fp1_bn254_mul_handler(caller, params, result),
80        SysFuncIdx::TOWER_FP1_BLS12381_ADD => syscall_tower_fp1_bls12381_add_handler(caller, params, result),
81        SysFuncIdx::TOWER_FP1_BLS12381_SUB => syscall_tower_fp1_bls12381_sub_handler(caller, params, result),
82        SysFuncIdx::TOWER_FP1_BLS12381_MUL => syscall_tower_fp1_bls12381_mul_handler(caller, params, result),
83        SysFuncIdx::TOWER_FP2_BN254_ADD => syscall_tower_fp2_bn254_add_handler(caller, params, result),
84        SysFuncIdx::TOWER_FP2_BN254_SUB => syscall_tower_fp2_bn254_sub_handler(caller, params, result),
85        SysFuncIdx::TOWER_FP2_BN254_MUL => syscall_tower_fp2_bn254_mul_handler(caller, params, result),
86        SysFuncIdx::TOWER_FP2_BLS12381_ADD => syscall_tower_fp2_bls12381_add_handler(caller, params, result),
87        SysFuncIdx::TOWER_FP2_BLS12381_SUB => syscall_tower_fp2_bls12381_sub_handler(caller, params, result),
88        SysFuncIdx::TOWER_FP2_BLS12381_MUL => syscall_tower_fp2_bls12381_mul_handler(caller, params, result),
89
90        // secp256k1 (0x04)
91        SysFuncIdx::SECP256K1_ADD => syscall_secp256k1_add_handler(caller, params, result),
92        SysFuncIdx::SECP256K1_DECOMPRESS => syscall_secp256k1_decompress_handler(caller, params, result),
93        SysFuncIdx::SECP256K1_DOUBLE => syscall_secp256k1_double_handler(caller, params, result),
94
95        // secp256r1 (0x05)
96        SysFuncIdx::SECP256R1_ADD => syscall_secp256r1_add_handler(caller, params, result),
97        SysFuncIdx::SECP256R1_DECOMPRESS => syscall_secp256r1_decompress_handler(caller, params, result),
98        SysFuncIdx::SECP256R1_DOUBLE => syscall_secp256r1_double_handler(caller, params, result),
99
100        // bls12381 (0x06)
101        SysFuncIdx::BLS12381_ADD => syscall_bls12381_add_handler(caller, params, result),
102        SysFuncIdx::BLS12381_DECOMPRESS => syscall_bls12381_decompress_handler(caller, params, result),
103        SysFuncIdx::BLS12381_DOUBLE => syscall_bls12381_double_handler(caller, params, result),
104
105        // bn254 (0x07)
106        SysFuncIdx::BN254_ADD => syscall_bn254_add_handler(caller, params, result),
107        SysFuncIdx::BN254_DOUBLE => syscall_bn254_double_handler(caller, params, result),
108
109        // uint256 (0x08)
110        SysFuncIdx::UINT256_MUL_MOD => syscall_uint256_mul_mod_handler(caller, params, result),
111        SysFuncIdx::UINT256_X2048_MUL => syscall_uint256_x2048_mul_handler(caller, params, result),
112
113        // sp1 (0x51)
114    }
115}
116
117/// Stores the exit code in the context and converts it into a halting TrapCode.
118pub(crate) fn syscall_process_exit_code(
119    ctx: &mut impl StoreTr<RuntimeContext>,
120    exit_code: ExitCode,
121) -> TrapCode {
122    ctx.data_mut().execution_result.exit_code = exit_code.into();
123    TrapCode::ExecutionHalted
124}