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        (fuel_consumed, fuel_refunded, exit_code)
93    }
94
95    fn forward_output(&self, offset: u32, len: u32) {
96        syscall_forward_output_impl(&mut self.ctx.borrow_mut(), offset, len).unwrap_exit_code()
97    }
98
99    #[inline(always)]
100    fn fuel(&self) -> u64 {
101        syscall_fuel_impl(&self.ctx.borrow())
102    }
103
104    fn debug_log(message: &str) {
105        syscall_debug_log_impl(message.as_bytes())
106    }
107
108    fn charge_fuel(&self, fuel_consumed: u64) {
109        syscall_charge_fuel_impl(&mut self.ctx.borrow_mut(), fuel_consumed).unwrap();
110    }
111
112    fn enter_unconstrained(&self) {
113        syscall_enter_leave_unconstrained_impl(&mut self.ctx.borrow_mut());
114    }
115
116    fn exit_unconstrained(&self) {
117        syscall_enter_leave_unconstrained_impl(&mut self.ctx.borrow_mut());
118    }
119
120    fn write_fd(&self, fd: u32, slice: &[u8]) {
121        syscall_write_fd_impl(&mut self.ctx.borrow_mut(), fd, slice).unwrap_exit_code();
122    }
123}