Branch and Flow Control

This document details the Branch and Flow Control mechanism within the EigenLayer-AVS Task Engine.

This document details the Branch and Flow Control mechanism within the EigenLayer-AVS Task Engine. This system enables conditional execution paths in task graphs, allowing for dynamic behavior based on runtime data evaluation.

For information about the overall Task Engine architecture, see Task Engine, and for the general Task Model, see Task Model.

1. Branch Processor Overview#

The Branch Processor is a core component of the Task Engine's Virtual Machine that enables conditional flow control within task graphs. It evaluates JavaScript expressions against runtime data to determine which execution path to follow.

Sources:

The Branch Processor evaluates conditions sequentially until one evaluates to true or until it reaches an 'else' condition. The execution then follows the path associated with the matched condition.

2. Branch Node Structure#

A Branch Node contains a list of conditions, where each condition has an ID, type ('if' or 'else'), and an expression to evaluate.

Sources:

The Branch Node must have at least one condition, and the first condition must be of type 'if'. The 'else' condition, if present, must be the last condition in the list as any conditions after 'else' are ignored during execution.

3. Condition Types and Behavior#

Branch nodes support two types of conditions:

Condition TypeDescriptionExpression RequiredBehavior
ifPrimary conditionYesEvaluates expression, executes path if true
elseFallback conditionNoAlways executes when reached, no evaluation needed

Sources:

Valid Condition Structures#

Sources:

4. Expression Evaluation#

The Branch Processor uses the Goja JavaScript runtime to evaluate expressions in conditions. These expressions are evaluated in the context of variables that are available in the VM, which can include task inputs, previous node outputs, and other runtime data.

Sources:

Expressions are evaluated as JavaScript code and must resolve to a boolean value. The expression is wrapped in a function to prevent variable leakage across evaluations.

Expression Examples#

The Branch Processor supports a wide range of JavaScript expressions:

Expression TypeExampleDescription
Numeric comparisonNumber(data) > 10Compare numeric values
Logical operatorsvalue >= 2 && value <= 3Combine multiple conditions
String comparisondata == 'alice'Compare string values
Type checkingtypeof trigger.data == "undefined"Check variable types
Object property accessresponse.status === 200Check nested properties
Function callsString(value).startsWith("0x")Use JavaScript functions

Sources:

5. Branch Node in Task Execution#

When a Branch Node is executed as part of a task, the Virtual Machine follows a specific process to determine the next execution path.

Sources:

The output of a Branch Node includes a conditionId that identifies which condition was matched. This ID is constructed by combining the node ID and the condition ID (e.g., branchNode1.condition1). The Virtual Machine uses this ID to determine which edge to follow next in the task graph.

6. Implementation Details#

The Branch Processor is implemented in the BranchProcessor struct which contains the following methods:

  1. NewBranchProcessor - Creates a new instance of the Branch Processor
  2. Validate - Validates that the branch node structure is correct
  3. Execute - Executes the branch node, evaluating conditions and returning the matched path

The Branch Processor uses Goja for JavaScript evaluation, which is initialized with a set of utility functions that extend its capabilities.

Sources:

Branch Node Execution Process#

  1. Create a new execution step record

  2. Initialize the JavaScript runtime and set variables

  3. Validate the branch node structure

  4. Iterate through each condition:

    • If the condition is 'else', return its path immediately
    • If the condition is 'if', evaluate its expression
    • If the expression is true, return its path
  5. If no condition matches, halt execution

Sources:

7. Branch Node in Task Graphs#

Branch nodes enable complex task flows by allowing for conditional paths based on runtime data. Here's an example of how a branch node might be used in a task graph:

Sources:

In this example, after receiving data from an API, the branch node evaluates the value and directs the flow to the appropriate action based on conditions.

8. Best Practices#

When working with Branch Nodes in the EigenLayer-AVS system, consider the following best practices:

  1. Always ensure the first condition is of type 'if'
  2. Include an 'else' condition as a fallback to prevent execution halting
  3. Use descriptive condition IDs to make task graphs more readable
  4. Ensure expressions evaluate to boolean values
  5. Keep expressions simple and focused on a single condition
  6. Test branch conditions with different inputs to ensure correct behavior

Sources:

9. Empty and Invalid Expressions#

The Branch Processor has specific behaviors for handling empty or invalid expressions:

  • Empty expressions (or those containing only whitespace) evaluate to false
  • Expressions that don't evaluate to a boolean value will cause an error
  • Syntax errors in expressions will cause execution to fail with an error message

Sources:

10. Integration with Task Engine#

The Branch Processor integrates with the Task Engine's Virtual Machine, which compiles and executes task graphs. When a Branch Node is encountered during execution, the VM passes control to the Branch Processor, which evaluates conditions and returns the appropriate path to follow.

The connection between nodes is established through Task Edges, where the source can be a standard node ID or a condition-specific ID formed by combining the node ID and condition ID (e.g., branchNode1.condition1).

Sources:

Feature this wiki to auto refresh weekly

Try DeepWiki on your private codebase with Devin