Virtual Machine
The Virtual Machine (VM) is a core component of the EigenLayer-AVS task engine responsible for loading, compiling, and executing user-defined task workflows.
The Virtual Machine (VM) is a core component of the EigenLayer-AVS task engine responsible for loading, compiling, and executing user-defined task workflows. It serves as the execution environment for all task nodes, managing state between steps and orchestrating the flow of data through the task graph.
This document explains the design, architecture, and functionality of the VM, including how it compiles task graphs, executes different node types, and manages execution state. For information about the specific node processors the VM uses, refer to REST API Processor, Contract Interaction Processors, JavaScript Processor, and Branch and Flow Control.
Architecture#
The VM is designed as a stateful executor that processes a directed acyclic graph (DAG) of task nodes. It maintains an internal state during execution, manages variables that can be used between nodes, and applies a compilation step to create an execution plan before running.
Sources:
VM Lifecycle#
The VM follows a well-defined lifecycle as it processes a task:
Sources:
Task Compilation#
Before executing a task, the VM compiles it into an execution plan. This process:
- Analyzes all task edges (connections between nodes)
- Creates a map of execution steps
- Identifies the entrypoint node (connected to the trigger)
- Sets up the execution flow based on edge connections
Sources:
The compilation process handles special cases such as branch conditions (e.g., branch1.a1
) and ensures that the execution flow is properly established before running. If compilation fails (for example, if no valid entrypoint is found), the VM will not proceed to execution.
Task Execution#
Once compiled, the VM executes the task by following these steps:
- Start from the entrypoint
- Execute each node using the appropriate processor
- Follow the execution plan to determine the next node
- Collect execution logs and manage variables between steps
- Handle any errors that occur during execution
Sources:
Node Processors#
The VM uses specialized processors to handle different types of task nodes:
Processor Type | Function | Purpose |
---|---|---|
REST API | runRestApi | Executes HTTP requests to external APIs |
GraphQL | runGraphQL | Performs GraphQL queries to external services |
Contract Read | runContractRead | Reads data from Ethereum smart contracts |
Contract Write | runContractWrite | Writes data to Ethereum smart contracts |
Custom Code | runCustomCode | Executes custom JavaScript code |
Branch | runBranch | Evaluates conditions and directs flow |
Each processor:
- Takes the node configuration as input
- Performs its specific operation
- Collects input variables used
- Generates an execution log
- Sets output variables for use by subsequent nodes
Sources:
Variable Management#
The VM manages a variables context that enables data to flow between nodes. There are three primary sources of variables:
- Trigger data (event information that triggered the task)
- Node output variables (results from executed nodes)
- Configuration variables (secrets and user-defined constants)
A key feature is the preprocessText
method, which allows dynamic text substitution using JavaScript expressions within {{ }}
delimiters.
Sources:
The preprocessor allows for powerful templating capabilities, enabling tasks to dynamically reference data from previous steps, trigger information, or configuration variables.
Integration with Task Executor#
The VM is used by the TaskExecutor
component, which:
- Retrieves task definitions from storage
- Creates a VM instance for the task
- Initializes the VM with trigger data
- Compiles and runs the task
- Stores execution results
Sources:
Example Virtual Machine Execution#
To illustrate the VM in action, let's examine a simplified task execution:
The VM plays a critical role in this execution by:
- Parsing the trigger data (contract event)
- Making it available to the branch node for condition evaluation
- Determining the correct execution path
- Executing each node in sequence
- Managing data between nodes (e.g., passing REST API response to contract write)
- Recording the execution for auditing purposes
Sources:
Preprocessing and Template Functions#
The VM includes a powerful text preprocessing system that allows dynamic content generation in node configurations. This system:
- Parses templates with
{{ expression }}
syntax - Evaluates JavaScript expressions within templates
- Substitutes the results into the text
- Provides access to variables, mathematical operations, and string manipulation
This preprocessor is used extensively throughout the task system to allow dynamic configuration, such as:
- Including authentication keys in API requests
- Adding dynamic data to notification messages
- Building parameterized contract calls
Sources:
Error Handling#
The VM includes robust error handling that:
- Captures errors during node execution
- Records them in execution logs
- Terminates execution when necessary
- Returns detailed error information to callers
- Handles compilation errors separately from runtime errors
This error handling ensures that issues are properly reported and that task execution is reliable, even with external dependencies.
Sources:
Conclusion#
The Virtual Machine is a central component of the EigenLayer-AVS task execution system, providing a flexible and powerful framework for running complex task workflows. By managing state, handling different node types, and providing variable context between steps, the VM enables the creation of sophisticated automation workflows that can interact with both on-chain and off-chain systems.
Feature this wiki to auto refresh weekly
Try DeepWiki on your private codebase with Devin