Skip to main content

fluentbase_runtime/
context.rs

1use crate::{executor::ExecutionResult, syscall_handler::InterruptionHolder};
2use fluentbase_types::{Bytes, CALL_DEPTH_ROOT, STATE_MAIN};
3
4/// Per-invocation execution context carried inside the VM store.
5#[derive(Debug, Clone)]
6pub struct RuntimeContext {
7    /// Maximum fuel available to this invocation.
8    pub fuel_limit: u64,
9    /// Entry selector for the module (e.g., STATE_MAIN or STATE_DEPLOY).
10    pub state: u32,
11    /// Current call depth; root is zero.
12    pub call_depth: u32,
13    /// Calldata for the invocation.
14    pub input: Bytes,
15    /// Mutable execution artifacts collected during the run.
16    pub execution_result: ExecutionResult,
17    /// Deferred invocation metadata used to resume an interrupted call.
18    pub resumable_context: Option<InterruptionHolder>,
19}
20
21impl Default for RuntimeContext {
22    fn default() -> Self {
23        Self {
24            fuel_limit: 0,
25            state: STATE_MAIN,
26            call_depth: CALL_DEPTH_ROOT,
27            input: Bytes::default(),
28            execution_result: ExecutionResult::default(),
29            resumable_context: None,
30        }
31    }
32}
33
34impl RuntimeContext {
35    /// Sets the fuel limit for this context.
36    pub fn with_fuel_limit(mut self, fuel_limit: u64) -> Self {
37        self.fuel_limit = fuel_limit;
38        self
39    }
40
41    /// Replaces the calldata for this invocation.
42    pub fn with_input<I: Into<Bytes>>(mut self, input_data: I) -> Self {
43        self.input = input_data.into();
44        self
45    }
46
47    /// Updates the entry selector (state) for this invocation.
48    pub fn with_state(mut self, state: u32) -> Self {
49        self.state = state;
50        self
51    }
52
53    /// Sets the call depth for this context.
54    pub fn with_call_depth(mut self, depth: u32) -> Self {
55        self.call_depth = depth;
56        self
57    }
58
59    /// Extract serialized resumable context
60    pub fn take_resumable_context_serialized(&mut self) -> Option<Vec<u8>> {
61        // Take resumable context from execution context
62        let resumable_context = self.resumable_context.take()?;
63        if resumable_context.is_root {
64            unimplemented!("validate this logic, might not be ok in STF mode");
65        }
66        // serialize the delegated execution state,
67        // but we don't serialize registers and stack state,
68        // instead we remember it inside the internal structure
69        // and assign a special identifier for recovery
70        let result = resumable_context.params.encode();
71        Some(result)
72    }
73
74    /// Clears the accumulated output buffer.
75    pub fn clear_output(&mut self) {
76        self.execution_result.output.clear();
77    }
78}