Skip to main content

rns_hooks/
runtime.rs

1use crate::engine_access::EngineAccess;
2use crate::wire::ActionWire;
3
4#[derive(Debug, Clone)]
5pub struct RawProviderEvent {
6    pub payload_type: String,
7    pub payload: Vec<u8>,
8}
9
10/// Default fuel budget per WASM invocation.
11pub const DEFAULT_FUEL: u64 = 10_000_000;
12/// Default maximum memory for WASM modules (16 MB).
13pub const DEFAULT_MAX_MEMORY: usize = 16 * 1024 * 1024;
14
15/// Data stored in each wasmtime `Store`.
16///
17/// Uses a raw pointer for `EngineAccess` because `Linker<T>` requires `T`
18/// without lifetime parameters. The Store is cached across calls for instance
19/// persistence, but `engine_access` is refreshed each call via `reset_per_call`
20/// and must only be dereferenced during the active call.
21pub struct StoreData {
22    pub engine_access: *const dyn EngineAccess,
23    pub now: f64,
24    pub injected_actions: Vec<ActionWire>,
25    pub log_messages: Vec<String>,
26    pub provider_events: Vec<RawProviderEvent>,
27    pub provider_events_enabled: bool,
28}
29
30// Safety: StoreData is only used within a single-threaded driver loop.
31// The `engine_access` raw pointer is refreshed each call and only dereferenced
32// during that call while the borrow is live.
33unsafe impl Send for StoreData {}
34unsafe impl Sync for StoreData {}
35
36impl StoreData {
37    /// Access the engine through the raw pointer.
38    ///
39    /// # Safety
40    /// The caller must ensure the pointer is still valid.
41    pub unsafe fn engine(&self) -> &dyn EngineAccess {
42        &*self.engine_access
43    }
44
45    /// Reset per-call fields while preserving the store (and WASM linear memory).
46    pub fn reset_per_call(
47        &mut self,
48        engine_access: *const dyn EngineAccess,
49        now: f64,
50        provider_events_enabled: bool,
51    ) {
52        self.engine_access = engine_access;
53        self.now = now;
54        self.injected_actions.clear();
55        self.log_messages.clear();
56        self.provider_events.clear();
57        self.provider_events_enabled = provider_events_enabled;
58    }
59}
60
61/// Wrapper around `wasmtime::Engine` with fuel-metering enabled.
62pub struct WasmRuntime {
63    engine: wasmtime::Engine,
64    fuel: u64,
65}
66
67impl WasmRuntime {
68    pub fn new() -> Result<Self, wasmtime::Error> {
69        let mut config = wasmtime::Config::new();
70        config.consume_fuel(true);
71        let engine = wasmtime::Engine::new(&config)?;
72        Ok(WasmRuntime {
73            engine,
74            fuel: DEFAULT_FUEL,
75        })
76    }
77
78    pub fn compile(&self, bytes: &[u8]) -> Result<wasmtime::Module, wasmtime::Error> {
79        wasmtime::Module::new(&self.engine, bytes)
80    }
81
82    pub fn engine(&self) -> &wasmtime::Engine {
83        &self.engine
84    }
85
86    pub fn fuel(&self) -> u64 {
87        self.fuel
88    }
89}