This document describes the storage subsystem of the EigenLayer-AVS platform.
This document describes the storage subsystem of the EigenLayer-AVS platform. The storage layer provides persistent data storage capabilities to all components in the system, particularly the Task Engine and Aggregator. It manages task definitions, execution histories, user data, smart wallet information, and sensitive secret values using a key-value database approach.
The EigenLayer-AVS system uses BadgerDB, a high-performance embedded key-value database written in pure Go, as its primary storage engine. This choice enables cross-platform compatibility while providing efficient data access patterns optimized for the system's operational needs.
Sources:
The storage system is built around a well-defined interface that abstracts the underlying implementation. This design allows for potential replacement of the storage backend while maintaining compatibility with the rest of the system.
Sources:
The storage interface provides a comprehensive set of key-value operations for data management:
| Category | Operations | Description |
|---|---|---|
| Basic Operations | Set, Delete, GetKey, Exist | Core operations for manipulating individual key-value pairs |
| Prefix Operations | GetByPrefix, GetKeyHasPrefix, FirstKVHasPrefix | Functions for working with key prefixes to support hierarchical data structures and range queries |
| Batch Operations | BatchWrite, Move | Utilities for atomic operations on multiple keys or moving data between keys |
| Listing Operations | ListKeys, ListKeysMulti | Methods for retrieving lists of keys matching certain patterns |
| Counting Operations | CountKeysByPrefix, CountKeysByPrefixes | Efficient counting of keys with specific prefixes without retrieving values |
| Counter Operations | GetCounter, IncCounter, SetCounter | Special utilities for managing counter values |
| Sequence Operations | GetSequence | Support for generating sequential IDs |
| Maintenance | Vacuum, Backup, Load | Database maintenance and backup functionality |
Sources:
The BadgerDB implementation (BadgerStorage) provides the concrete implementation of the Storage interface using BadgerDB as the underlying data store. The implementation configures BadgerDB with sync writes enabled to ensure durability of data.
Key characteristics of the BadgerDB implementation include:
CountKeysByPrefix only scan keys, not valuesSources:
The storage system uses a hierarchical key structure with prefixes to organize different types of data. This enables efficient access patterns based on the type of data and relationships between entities.
Sources:
Tasks are managed using several key patterns:
t:<status>:<task-id> - Stores the full task definition with its current statusu:<eoa>:<smart-wallet>:<task-id> - Maps user accounts to their taskshistory:<task-id>:<execution-id> - Stores execution history for each tasktrigger:<task-id>:<execution-id> - Records trigger information for task executionsTask status is encoded in the key prefix using single characters:
a - Active tasks that can be triggeredc - Completed tasksf - Failed tasksl - Cancelled (cancelled) tasksx - Currently executing tasksSources:
Secrets are stored with a flexible permission model that can scope secrets to different levels:
secret:_:<eoa>:_:<name> - User-level secrets available to all workflowssecret:_:<eoa>:<workflow-id>:<name> - Workflow-specific secretssecret:<org-id>:<eoa>:_:<name> - Organization-level secretsThis structure allows for precise control over secret visibility while maintaining efficient lookup.
Sources:
The system uses counters for tracking various metrics, such as contract write operations:
ct:cw:<eoa> - Tracks contract writes initiated by a particular userCounters are implemented as string-encoded integer values for easy inspection and debugging.
Sources:
The storage layer integrates with several key components of the EigenLayer-AVS system:
Sources:
The RPC Server uses the storage layer for all persistent data needs, including:
The storage instance is injected into the RPC Server during initialization and is accessible via the db field.
Sources:
The Task Engine uses storage to:
The engine accesses storage directly through the storage interface, enabling efficient operations like listing tasks by status or retrieving execution histories.
Sources:
The storage system provides built-in capabilities for backup, restoration, and maintenance:
BadgerDB supports incremental backups, allowing efficient capture of changes since the last backup:
Sources:
The Vacuum operation performs garbage collection on the database to reclaim space from deleted entries:
This is particularly important for long-running systems where task and execution data may accumulate over time.
Sources:
The storage system supports direct inspection through a telnet interface, allowing administrators to examine keys and values directly:
telnet /tmp/ap.sock
> list * # List all keys
> get <key> # Retrieve a specific value
> list <prefix> # List keys with a specific prefix
This feature aids in troubleshooting and verifying system state.
Sources:
Several design choices in the storage implementation aim to optimize performance:
CountKeysByPrefix avoid loading values when only key information is neededSources:
The storage subsystem provides a reliable, efficient persistence layer for the EigenLayer-AVS platform. Its flexible key structure and comprehensive interface enable the various components to store and retrieve data with appropriate access patterns. The BadgerDB implementation offers good performance characteristics while maintaining simplicity and cross-platform compatibility.
Feature this wiki to auto refresh weekly