|
| 1 | +# Indexer Agent Operation Modes |
| 2 | + |
| 3 | +This document explains the internal workings of the indexer agent, focusing on allocation management, the reconciliation loop, and how indexing rules interact with allocation actions. |
| 4 | + |
| 5 | +## Allocation Management Modes |
| 6 | + |
| 7 | +The agent supports three allocation management modes, configured via `--allocation-management`: |
| 8 | + |
| 9 | +| Mode | Behavior | |
| 10 | +|------|----------| |
| 11 | +| **AUTO** (default) | Allocation decisions are automatically approved and executed | |
| 12 | +| **MANUAL** | Reconciliation is completely skipped; all actions must be manually created via CLI | |
| 13 | +| **OVERSIGHT** | Actions are queued but require manual approval before execution | |
| 14 | + |
| 15 | +## The Reconciliation Loop |
| 16 | + |
| 17 | +The reconciliation loop runs continuously with two polling intervals: |
| 18 | + |
| 19 | +- **Small interval**: `pollingInterval` - for frequently changing data |
| 20 | +- **Large interval**: `pollingInterval * 5` - for stable data |
| 21 | + |
| 22 | +### Data Streams |
| 23 | + |
| 24 | +The loop fetches and maintains: |
| 25 | + |
| 26 | +1. **Current epoch number** (large interval) |
| 27 | +2. **Max allocation duration** (large interval) |
| 28 | +3. **Indexing rules** (small interval) |
| 29 | +4. **Active deployments on Graph Node** (large interval, AUTO mode only) |
| 30 | +5. **Network deployments** (small interval) |
| 31 | +6. **Active allocations** (small interval) |
| 32 | +7. **Recently closed allocations** (small interval) |
| 33 | + |
| 34 | +### Two-Phase Process |
| 35 | + |
| 36 | +The reconciliation consists of two distinct phases: |
| 37 | + |
| 38 | +#### Phase 1: Deployment Evaluation |
| 39 | + |
| 40 | +**What it does**: Determines which deployments the indexer *should* be allocated to based on indexing rules. |
| 41 | + |
| 42 | +- Takes all network deployments from the network subgraph |
| 43 | +- Matches each deployment against indexing rules (deployment-specific or global) |
| 44 | +- Outputs allocation decisions with `toAllocate: true/false` for each deployment |
| 45 | + |
| 46 | +**When it runs**: Every `pollingInterval * 5`, but **only in AUTO/OVERSIGHT mode**. Skipped entirely in MANUAL mode. |
| 47 | + |
| 48 | +**Decision basis options**: |
| 49 | +- `always` - allocate |
| 50 | +- `never` - don't allocate |
| 51 | +- `offchain` - index but don't allocate |
| 52 | +- `rules` - evaluate against thresholds (`minStake`, `minSignal`, `minAverageQueryFees`) |
| 53 | + |
| 54 | +#### Phase 2: Allocation Reconciliation |
| 55 | + |
| 56 | +**What it does**: Compares desired state (from deployment evaluation) against actual on-chain state and queues actions to resolve differences. |
| 57 | + |
| 58 | +| Condition | Action Queued | |
| 59 | +|-----------|---------------| |
| 60 | +| `toAllocate=true` + no active allocation | ALLOCATE | |
| 61 | +| `toAllocate=false` + active allocation exists | UNALLOCATE | |
| 62 | +| `toAllocate=true` + allocation expiring | REALLOCATE | |
| 63 | + |
| 64 | +**Expiration check**: `currentEpoch >= createdAtEpoch + allocationLifetime` |
| 65 | + |
| 66 | +**When it runs**: After deployment evaluation, **only in AUTO/OVERSIGHT mode**. Skipped in MANUAL mode. |
| 67 | + |
| 68 | +### Visual Flow |
| 69 | + |
| 70 | +``` |
| 71 | +AUTO/OVERSIGHT MODE: |
| 72 | +┌─────────────────────┐ ┌──────────────────────────┐ ┌─────────────┐ |
| 73 | +│ Deployment │ --> │ Allocation │ --> │ Action │ |
| 74 | +│ Evaluation │ │ Reconciliation │ │ Executor │ |
| 75 | +│ │ │ │ │ │ |
| 76 | +│ "What SHOULD we │ │ "What do we need to DO │ │ Execute │ |
| 77 | +│ allocate to?" │ │ to match desired state?"│ │ on-chain │ |
| 78 | +└─────────────────────┘ └──────────────────────────┘ └─────────────┘ |
| 79 | +
|
| 80 | +MANUAL MODE: |
| 81 | +┌─────────────────────┐ ┌──────────────────────────┐ ┌─────────────┐ |
| 82 | +│ Deployment │ │ Allocation │ │ Action │ |
| 83 | +│ Evaluation │ │ Reconciliation │ │ Executor │ |
| 84 | +│ │ │ │ │ │ |
| 85 | +│ SKIPPED │ │ SKIPPED │ │ Still runs! │ |
| 86 | +└─────────────────────┘ └──────────────────────────┘ └─────────────┘ |
| 87 | + ^ |
| 88 | + | |
| 89 | + Manual CLI actions |
| 90 | + (graph indexer actions queue) |
| 91 | +``` |
| 92 | + |
| 93 | +## Indexing Rules |
| 94 | + |
| 95 | +### Purpose |
| 96 | + |
| 97 | +Rules serve two purposes: |
| 98 | + |
| 99 | +1. **Allocation decisions** (AUTO/OVERSIGHT only): Determine whether to allocate via `decisionBasis` and threshold fields |
| 100 | +2. **Deployment management** (ALL modes): Control what to index on Graph Node, provide defaults for manual actions |
| 101 | + |
| 102 | +### Management |
| 103 | + |
| 104 | +Rules are primarily managed through: |
| 105 | + |
| 106 | +- **CLI**: `graph indexer rules set/delete/clear/get` |
| 107 | +- **GraphQL API**: Direct mutations to the indexer management server |
| 108 | + |
| 109 | +### Automatic Rule Modifications |
| 110 | + |
| 111 | +**Important**: Allocation actions automatically modify rules to maintain consistency: |
| 112 | + |
| 113 | +| Action | Rule Modification | |
| 114 | +|--------|------------------| |
| 115 | +| **ALLOCATE** | Creates rule with `decisionBasis: ALWAYS` if no matching rule exists | |
| 116 | +| **UNALLOCATE** | **Always** sets rule to `decisionBasis: NEVER` | |
| 117 | +| **REALLOCATE** | Creates rule with `decisionBasis: ALWAYS` if no matching rule exists | |
| 118 | + |
| 119 | +This means: |
| 120 | +- After unallocating, you must manually change the rule back to `ALWAYS` or `RULES` if you want to allocate again |
| 121 | +- The agent won't fight against manual allocation actions (it creates rules to match) |
| 122 | + |
| 123 | +## Safety Mechanisms |
| 124 | + |
| 125 | +The agent includes several safety features: |
| 126 | + |
| 127 | +1. **Health check**: Won't allocate to deployments with "failed" health status if rule has `safety=true` |
| 128 | +2. **Zero POI safety**: Won't reallocate if previous allocation closed with zero POI and safety is enabled |
| 129 | +3. **Approved actions check**: Skips reconciliation if there are already pending approved actions (prevents conflicts) |
| 130 | +4. **Network subgraph protection**: Never auto-allocated unless explicitly enabled via `--allocate-on-network-subgraph` |
| 131 | + |
| 132 | +## Action Execution |
| 133 | + |
| 134 | +Actions flow through the action queue regardless of mode: |
| 135 | + |
| 136 | +1. **AUTO mode**: Actions are queued with `APPROVED` status and executed automatically |
| 137 | +2. **OVERSIGHT mode**: Actions are queued with `QUEUED` status, require manual approval |
| 138 | +3. **MANUAL mode**: No automatic actions; user queues actions via CLI with desired status |
| 139 | + |
| 140 | +The action executor runs in all modes - in MANUAL mode it simply has no auto-generated actions to process. |
0 commit comments