pub struct VmContext {
pub instructions_executed: u64,
pub cache_hits: u64,
pub pda_cache_hits: u64,
pub pda_cache_misses: u64,
pub pending_queue_size: u64,
/* private fields */
}Fields§
§instructions_executed: u64§cache_hits: u64§pda_cache_hits: u64§pda_cache_misses: u64§pending_queue_size: u64Implementations§
Source§impl VmContext
impl VmContext
pub fn new() -> Self
Sourcepub fn get_state_table_mut(&mut self, state_id: u32) -> Option<&mut StateTable>
pub fn get_state_table_mut(&mut self, state_id: u32) -> Option<&mut StateTable>
Get a mutable reference to a state table by ID Returns None if the state ID doesn’t exist
Sourcepub fn registers_mut(&mut self) -> &mut Vec<RegisterValue> ⓘ
pub fn registers_mut(&mut self) -> &mut Vec<RegisterValue> ⓘ
Get public access to registers (for metrics context)
Sourcepub fn path_cache(&self) -> &HashMap<String, CompiledPath>
pub fn path_cache(&self) -> &HashMap<String, CompiledPath>
Get public access to path cache (for metrics context)
Sourcepub fn current_context(&self) -> Option<&UpdateContext>
pub fn current_context(&self) -> Option<&UpdateContext>
Get the current update context
Sourcepub fn update_state_from_register(
&mut self,
state_id: u32,
key: Value,
register: Register,
) -> Result<()>
pub fn update_state_from_register( &mut self, state_id: u32, key: Value, register: Register, ) -> Result<()>
Update the state table with the current value in a register This allows imperative hooks to persist their changes to the state table
Sourcepub fn extract_partial_state(
&self,
state_reg: Register,
dirty_fields: &HashSet<String>,
) -> Result<Value>
pub fn extract_partial_state( &self, state_reg: Register, dirty_fields: &HashSet<String>, ) -> Result<Value>
Extract only the dirty fields from state (public for use by instruction hooks)
Sourcepub fn process_event_with_context(
&mut self,
bytecode: &MultiEntityBytecode,
event_value: Value,
event_type: &str,
context: Option<&UpdateContext>,
) -> Result<Vec<Mutation>>
pub fn process_event_with_context( &mut self, bytecode: &MultiEntityBytecode, event_value: Value, event_type: &str, context: Option<&UpdateContext>, ) -> Result<Vec<Mutation>>
Process an event with optional context metadata
Sourcepub fn process_event(
&mut self,
bytecode: &MultiEntityBytecode,
event_value: Value,
event_type: &str,
) -> Result<Vec<Mutation>>
pub fn process_event( &mut self, bytecode: &MultiEntityBytecode, event_value: Value, event_type: &str, ) -> Result<Vec<Mutation>>
Process an event without context (backward compatibility)
pub fn process_any( &mut self, bytecode: &MultiEntityBytecode, any: Any, ) -> Result<Vec<Mutation>>
Sourcepub fn update_pda_reverse_lookup(
&mut self,
state_id: u32,
lookup_name: &str,
pda_address: String,
seed_value: String,
) -> Result<Vec<PendingAccountUpdate>>
pub fn update_pda_reverse_lookup( &mut self, state_id: u32, lookup_name: &str, pda_address: String, seed_value: String, ) -> Result<Vec<PendingAccountUpdate>>
Update a PDA reverse lookup and return pending updates for reprocessing
After registering the PDA reverse lookup, this returns any pending account updates that were queued for this PDA. The caller should reprocess these through the VM by calling process_event() for each update.
§Example
let pending = vm.update_pda_reverse_lookup(state_id, lookup_name, pda_addr, seed)?;
for update in pending {
vm.process_event(&bytecode, update.account_data, &update.account_type)?;
}Sourcepub fn cleanup_expired_pending_updates(&mut self, state_id: u32) -> usize
pub fn cleanup_expired_pending_updates(&mut self, state_id: u32) -> usize
Clean up expired pending updates that are older than the TTL
Returns the number of updates that were removed. This should be called periodically to prevent memory leaks from orphaned updates.
Sourcepub fn queue_account_update(
&mut self,
state_id: u32,
pda_address: String,
account_type: String,
account_data: Value,
slot: u64,
signature: String,
) -> Result<()>
pub fn queue_account_update( &mut self, state_id: u32, pda_address: String, account_type: String, account_data: Value, slot: u64, signature: String, ) -> Result<()>
Queue an account update for later processing when PDA reverse lookup is not yet available
§Workflow
This implements a deferred processing pattern for account updates when the PDA reverse lookup needed to resolve the primary key is not yet available:
-
Initial Account Update: When an account update arrives but the PDA reverse lookup is not available, call
queue_account_update()to queue it for later. -
Register PDA Mapping: When the instruction that establishes the PDA mapping is processed, call
update_pda_reverse_lookup()which returns pending updates. -
Reprocess Pending Updates: Process the returned pending updates through the VM:
ⓘlet pending = vm.update_pda_reverse_lookup(state_id, lookup_name, pda_addr, seed)?; for update in pending { let mutations = vm.process_event( &bytecode, update.account_data, &update.account_type )?; // Handle mutations... }
§Arguments
state_id- The state table IDpda_address- The PDA address that needs reverse lookupaccount_type- The event type name for reprocessingaccount_data- The account data (event value) for reprocessingslot- The slot number when this update occurredsignature- The transaction signature
Sourcepub fn get_pending_queue_stats(
&self,
state_id: u32,
) -> Option<PendingQueueStats>
pub fn get_pending_queue_stats( &self, state_id: u32, ) -> Option<PendingQueueStats>
Get statistics about the pending queue for monitoring
Sourcepub fn try_pda_reverse_lookup(
&mut self,
state_id: u32,
lookup_name: &str,
pda_address: &str,
) -> Option<String>
pub fn try_pda_reverse_lookup( &mut self, state_id: u32, lookup_name: &str, pda_address: &str, ) -> Option<String>
Try to resolve a primary key via PDA reverse lookup
Sourcepub fn evaluate_computed_expr(
&self,
expr: &ComputedExpr,
state: &Value,
) -> Result<Value>
pub fn evaluate_computed_expr( &self, expr: &ComputedExpr, state: &Value, ) -> Result<Value>
Evaluate a computed expression AST against the current state This is the core runtime evaluator for computed fields from the AST
Sourcepub fn evaluate_computed_fields_from_ast(
&self,
state: &mut Value,
computed_field_specs: &[ComputedFieldSpec],
) -> Result<Vec<String>>
pub fn evaluate_computed_fields_from_ast( &self, state: &mut Value, computed_field_specs: &[ComputedFieldSpec], ) -> Result<Vec<String>>
Evaluate all computed fields for an entity and update the state This takes a list of ComputedFieldSpec from the AST and applies them
Sourcepub fn create_evaluator_from_specs(
specs: Vec<ComputedFieldSpec>,
) -> impl Fn(&mut Value) -> Result<()> + Send + Sync + 'static
pub fn create_evaluator_from_specs( specs: Vec<ComputedFieldSpec>, ) -> impl Fn(&mut Value) -> Result<()> + Send + Sync + 'static
Create a computed fields evaluator closure from AST specs This returns a function that can be passed to the bytecode builder