Skip to main content

fluentbase_runtime/
context_wrapper.rs

1use crate::{syscall_handler::*, RuntimeContext};
2use alloc::borrow::Cow;
3use fluentbase_types::{BytecodeOrHash, ExitCode, NativeAPI, UnwrapExitCode};
4use std::cell::RefCell;
5
6#[derive(Default)]
7pub struct RuntimeContextWrapper {
8    pub ctx: RefCell<RuntimeContext>,
9}
10
11impl RuntimeContextWrapper {
12    pub fn new(ctx: RuntimeContext) -> Self {
13        Self {
14            ctx: RefCell::new(ctx),
15        }
16    }
17    pub fn into_inner(self) -> RuntimeContext {
18        self.ctx.into_inner()
19    }
20}
21
22impl NativeAPI for RuntimeContextWrapper {
23    fn exit(&self, exit_code: ExitCode) -> ! {
24        syscall_exit_impl(&mut self.ctx.borrow_mut(), exit_code).unwrap_exit_code();
25        unreachable!("exit code: {}", exit_code)
26    }
27
28    fn state(&self) -> u32 {
29        syscall_state_impl(&self.ctx.borrow())
30    }
31
32    fn read(&self, target: &mut [u8], offset: u32) {
33        let result =
34            syscall_read_input_impl(&mut self.ctx.borrow_mut(), offset, target.len() as u32)
35                .unwrap();
36        target.copy_from_slice(&result);
37    }
38
39    fn input_size(&self) -> u32 {
40        syscall_input_size_impl(&self.ctx.borrow())
41    }
42
43    fn write(&self, value: &[u8]) {
44        syscall_write_output_impl(&mut self.ctx.borrow_mut(), value)
45    }
46
47    fn output_size(&self) -> u32 {
48        syscall_output_size_impl(&self.ctx.borrow())
49    }
50
51    fn read_output(&self, target: &mut [u8], offset: u32) {
52        let result =
53            syscall_read_output_impl(&mut self.ctx.borrow_mut(), offset, target.len() as u32)
54                .unwrap();
55        target.copy_from_slice(&result);
56    }
57
58    fn exec(
59        &self,
60        code_hash: BytecodeOrHash,
61        input: Cow<'_, [u8]>,
62        fuel_limit: Option<u64>,
63        state: u32,
64    ) -> (u64, i64, i32) {
65        let (fuel_consumed, fuel_refunded, exit_code) = syscall_exec_impl(
66            &mut self.ctx.borrow_mut(),
67            code_hash,
68            input,
69            fuel_limit.unwrap_or(u64::MAX),
70            state,
71        );
72        (fuel_consumed, fuel_refunded, exit_code)
73    }
74
75    fn resume(
76        &self,
77        call_id: u32,
78        return_data: &[u8],
79        exit_code: i32,
80        fuel_consumed: u64,
81        fuel_refunded: i64,
82    ) -> (u64, i64, i32) {
83        let (fuel_consumed, fuel_refunded, exit_code) = syscall_resume_impl(
84            &mut self.ctx.borrow_mut(),
85            call_id,
86            return_data,
87            exit_code,
88            fuel_consumed,
89            fuel_refunded,
90            0,
91        )
92        .unwrap_exit_code();
93        (fuel_consumed, fuel_refunded, exit_code)
94    }
95
96    fn forward_output(&self, offset: u32, len: u32) {
97        syscall_forward_output_impl(&mut self.ctx.borrow_mut(), offset, len).unwrap_exit_code()
98    }
99
100    #[inline(always)]
101    fn fuel(&self) -> u64 {
102        syscall_fuel_impl(&self.ctx.borrow())
103    }
104
105    fn debug_log(message: &str) {
106        syscall_debug_log_impl(message.as_bytes())
107    }
108
109    fn charge_fuel(&self, fuel_consumed: u64) {
110        syscall_charge_fuel_impl(&mut self.ctx.borrow_mut(), fuel_consumed).unwrap();
111    }
112
113    fn enter_unconstrained(&self) {
114        syscall_enter_leave_unconstrained_impl(&mut self.ctx.borrow_mut());
115    }
116
117    fn exit_unconstrained(&self) {
118        syscall_enter_leave_unconstrained_impl(&mut self.ctx.borrow_mut());
119    }
120
121    fn write_fd(&self, fd: u32, slice: &[u8]) {
122        syscall_write_fd_impl(&mut self.ctx.borrow_mut(), fd, slice).unwrap_exit_code();
123    }
124}