Unified AVS registration extension for EigenLayer CLI #298
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Unified AVS Registration
This package contains an extension to the EigenLayer CLI that allows it to support managing registration of operators with different Actively Validated Services (AVS) in a unified manner. It is intended to replace the practice of AVS developers providing an AVS specific tool for the management of operator registration for each AVS.
Design Objectives
Architecture
The extension design includes the following components.
Command Package
The
pkg/avs
command package contains multiple sub commands that perform different functions including management of specifications, generating AVS specific configuration files, and the actual registration workflows (register, opt-in, opt-out, deregister and status check).These commands are summarized below.
avs specs list
avs specs reset
avs specs update
avs config create <avs-id> <avs-config-file>
avs register <operator-config-file> <avs-config-file>
avs opt-in <operator-config-file> <avs-config-file>
avs opt-out <operator-config-file> <avs-config-file>
avs deregister <operator-config-file> <avs-config-file>
avs status <operator-config-file> <avs-config-file>
Parameters for above command are as follows.
avs-id
refers to a unique identifier for an AVS (see Specifications for more details).operator-config-file
refers to a YALM file that contains operator specific configuration details (also used for operator registration with EigenLayer).avs-config-file
refers to a YAML file that contains AVS specific configuration details.Specifications
One of the objectives of the extension design is to be able to support registration workflows on new AVS implementations without changes to the CLI code. This is achieved by describing details about each AVS using a specification, which is a set of JSON (and possibly other) files.
Each specification has a unique identifier for naming it. For example, the identifier for EigenDA specification is
mainnet/eigenda
for the main-net andholesky/eigenda
for the Holesky test-net. This identifier is used for organizing the specifications as well as in CLI commands when referring to a specification.Each specification consists of the following.
avs.json
file which describes the details about the AVS and the registration flows.config.yaml
file which describes the configuration template to be used during registration workflows with the AVS. The operator must fill-up this template to specify AVS specific configuration parameters.In addition the specification may also include other files as required.
Managing Specifications
Specification management includes the following functionality.
master
branch of the GitHub repository for EigenLayer CLI).Local Storage of Specifications
All AVS specifications are stored under the user’s home directory, inside the
.eigenlayer/avs/specs
directory. Each specification is stored under a sub-directory that match its unique identifier. CLI commands work off of AVS specifications in this storage.The CLI extension includes an embedded set of specifications at compile time. On first use of the CLI the local storage would be initialized with this embedded set of specifications if it is empty.
Listing Specifications
A CLI user will be able to list the available set of AVS specifications by running the
avs specs list
command.Resetting Specifications
The local specification storage can be reset to reflect the embedded set of specifications by running the
avs specs reset
command.Updating Specifications
New specification releases done by adding them to the master branch of the GitHub repository of the EigenLayer CLI project can be used as a remote specification repository. A user may update the local specification storage by downloading from this remote repository using the
avs specs update
command.Specification Schema
Each AVS specification includes an
avs.json
file that describes the details about the AVS.The following attributes are available at the top level of the AVS schema.
Coordinators
Each specification indicates how the registration workflows are to be managed in the form of a coordinator. Each coordinator implements a different way of managing registration workflows.
The following coordinators are supported.
eigenlayer-contracts
andeigenlayer-middleware
libraries.Contract Coordinator
The contract coordinator can be used when registration flows involve direct or delegated contract invocation. Details of the contract functions must be included in the AVS specification.
The following is an example specification for Lagrange State Committees that makes use of the contract coordinator.
The following describes the additional attributes available at the top level of the AVS schema.
Functions
Functions can be defined under the
functions
attribute for the following workflows. If one is not defined the workflow is assumed to be unavailable.register
opt_in
opt_out
deregister
status
Each function specification under the
functions
attribute describe details about a contract function for an AVS registration workflow, as described below.Function parameters can be specified in the following expression formats.
Configuration Lookup
An expression in the form of
config:key
is evaluated to the configuration value (specified in the operator configuration file, or the AVS configuration file, or on the command line) withkey
.If the configuration value cannot be found, then the user is prompted to enter the value.
For example,
config:operator.address
evaluates to the operator address specified in the operator yaml file underoperator:
and thenaddress:
.Constants
An expression in the form of
const:value
is evaluated tovalue
.For example,
const:lagrage-avs
evaluates to the stringlagrange-avs
andconst:300
evaluates to300
.Specification Lookup
An expression in the form of
spec:key
is evaluated to the specification value withkey
.For example,
spec:contract_address
evaluates to thecontract_address:
defined in the corresponding specification, i.e.0x18A74E66cc90F0B1744Da27E72Df338cEa0A542b
in the above example.Built-in Functions
An expression in the form of
func:name(params)
is evaluated to the value returned by executing the corresponding built-in function withname
and parameters.Parameters to a built-in function invocation is a list of named parameter values. These values may in turn be an expression (but not a nested built-in function invocation).
For example,
func:salt(seed=const:lagrange-sc)
is evaluated by invoking the built-insalt
function with the parameterseed
set to the constant valuelagrange-sc
.See
pkg/avs/adapters/contract/functions.go
for the full list of available built-in functions.Contract Functions
An expression in the form of
call:name
is evaluated to the value returned by invoking the corresponding contract function (or contract function chain) withname
.For example,
call:avsDirectory.calculateOperatorAVSRegistrationDigestHash
is evaluated by calling theavsDirectory
function on the main contract (with the address defined in the specification usingcontract_address
), and then invoking thecalculateOperatorAVSRegistrationDigestHash
function on the contract with the resulting address.Cached Last Values
An expression int he form of
last:name
is evaluated to the result of the previous invocation of the functionname
. This is useful when multiple function calls require the same salt and expiry values.Transformations
The result of a function can be transformed using a transformation expression, which can be specified at the function using the
transform
attribute, or at parameter level by adding the delimiter->
at the end of the parameter expression followed by the transformation expression.The following example shows how the value returned from a contract invocation can be transformed in to a byte array using a function level transform.
The following example shows how the results of a BLS signing can be transformed in to a custom anonymous structure using a parameter level transform.
Delegates
AVS implementations that delegate operator registration functionality to other contracts can be defined using the
delegates
attribute.For example, the following defined two delegates.
Each delegate specification is described with the following attributes.
Functions specified at delegate level have the same format as regular contract functions.
Middleware Coordinator
The middleware coordinator can be used for managing registration processes for an AVS that implements
IServiceManager
which encapsulatesIRegistryCoordinator
for managing operator registrations (as defined ineigenlayer-contracts
andeigenlayer-middleware
). EigenDA and Ava Protocol are examples of AVS implementations that follow this pattern.This specific coordinator includes support for registration (with and without churning as required), deregistration and status checks (with opt-in and opt-out being implied).
The following is an example specification for EigenDA that uses the middleware coordinator.
The following describes the additional attributes available at the top level of the AVS schema.
Plugin Coordinator
AVS registration flows that require custom off-chain code execution can include that behavior in to the EigenLayer CLI in the form of a custom coordinator. This can be specified as follows.
The following describes the additional attributes available at the top level of the AVS schema.
The
library_url
can have the following variables that would be substituted to allow derivation of platform specific shared libraries.${ARCH}
represents the architecture as defined inruntime.GOARCH
${OS}
represents the operating system as defined inruntime.GOOS
${EXT}
represents the shared library extension based on the operating system (dll
on Windows,so
on other operating systems).For example, the
library_url
may be defined ashttps://github.com/avs-x/cli-plugin/releases/download/cli-plugin-1.5/avs-x-cli-plugin-${ARCH}-${OS}.${EXT}
.More details on building a plugin is available in a later section.
ABI Schema
Each specification includes a set of files that describes the interface of the contracts that the CLI should interact with for that AVS. These are standard ABI descriptions in JSON format and correspond to the Service Manager contract and other delegated contracts for that AVS.
Configuration Schema
Commands related to AVS registration makes use of 2 configuration files.
Operator Configuration
This is a YAML file that contains operator related details. This is the same file that would have been used to register the operator with EigenLayer.
The following values among others are picked up from this file during AVS registration workflows.
operator.address
which specifies the address of the operator.eth_rpc_url
which specifies the RPC URL for the Ethereum node for interaction with the network. The same RPC URL is used for all contract invocations during AVS registration processes.signer_type
which specifies how signing should work (local or remote).private_key_store_path
which specifies the location of the ECDSA private keystore file.fireblocks.*
which specifies details related to Fireblocks based remote signing.web3.*
which specifies details related to Web3 based remote signing.AVS Configuration
This is a YAML file that contains AVS specific details. Each specification includes a template for this as
config.yaml
. A user may copy out this template via theavs config create
CLI command, edit the resulting file and fill in the details before using it in subsequent CLI commands.AVS configuration file may only contain a predefined set of parameters required for AVS registration flows, which would be referred to by the CLI to build parameter values for contract function invocation.
All AVS specific configuration values required for the CLI to function can be specified in this configuration file. In addition, values that have been specified in the operator configuration can be overridden by specifying them again in the AVS configuration file.
Any required but unspecified parameters would result in the CLI prompting the user for entry of the missing parameter values as and when they are required before proceeding.
Command Line Overrides
Configuration values can be specified and existing values can be overridden on the command line passing
--arg key=value
. Multiple such arguments can be passed.Registration Workflows
Prerequisite - Register with EigenLayer
An operator would first register with EigenLayer by doing the following.
The above can be done by using
keys
andoperator
commands available in the CLI.Prepare AVS Configuration
The operator must then prepare a configuration file for registration with required AVS. A template configuration file can be created as follows.
The following example creates a configuration file for the
holesky/eigenda
AVS calledholesky-eigenda-config.yaml
.The operator must then edit this file and populate it with the required configuration values. The file would already have content to name the configuration keys as well as documentation for configuration parameters in the form of comments.
Register
The operator can register with the AVS as follows.
For example, assuming the operator used
operator-config.yaml
for registering the operator with EigenLayer, registration withholesky/eigenda
can be initiated as;Opt-In
The operator can opt-in to the AVS as follows.
Note that the opt-in process may be implied on some AVS implementations at registration. If so this would be indicated to the operator.
Opt-Out
The operator can opt-out from the AVS as follows.
Note that the opt-out process may be implied on some AVS implementations at deregistration. If so this would be indicated to the operator.
Deregister
The operator can deregister with the AVS as follows.
For example, assuming the operator used
operator-config.yaml
for registering the operator with EigenLayer, deregistration withholesky/eigenda
can be initiated as;Check Registration Status
The operator can check the registration status with an AVS as follows.
Dry Runs
Registration workflows that issue transactions (register, opt-in, opt-out, deregister) can be invoked in a dry-run mode using the
--dry-run
command line argument.In dry-run mode, the actual transactions are not sent out. Instead, the raw transactions are displayed on the console in RLP encoding.
Remote Signing
All operations that require signing may be done using one of the following methods.
Remote signing follows the configuration in the operator configuration file.
Building Plugins
A minimal plugin for EigenLayer CLI requires a shared library to be built that includes a symbol named
PluginCoordinator
that implement the following interface.The
Register()
,OptIn()
,OptOut()
andDeregister()
functions are invoked when the plugin is to execute the logic for the corresponding AVS registration workflows.The
Status()
function is called to query the registration status of an operator for an AVS.Create the Project
Create a new directory to hold the project (following example uses
eigenlayer-cli-plugin-demo
).$ mkdir eigenlayer-plugin-demo $ cd eigenlayer-plugin-demo
Initialize the project as a module (following example uses
github.com/eigenlayer/eigenlayer-cli-demo
).Add a Coordinator
Create the plugin coordinator implementation (following is added as
main/coordinator.go
).Build the Plugin
Build the project as a plugin (following example build
eigenlayer-cli-demo.so
).Host the Plugin
Host the plugin shared library so that it can be accessible from a public URL.
Use it in a Specification
The plugin can be used in a specification by setting the specification's
coordinator
andlibrary_url
attributes.The following example shows an
avs.json
of a specification that uses a plugin hosted athttps://download.eigenlayer.xys/cli/eigenlayer-cli-demo.so
.Accessing the Specification
The plugin can access the specification used for launching the coordinator by including a symbol named
PluginSpecification
that implements the following interface.The
Validate()
function is called after loading the specification in order to check its validity.Note that this plugin specification can also include custom properties included in the corresponding
avs.json
file.For example, consider the following
avs.json
.The plugin can access the specification as follows.
Accessing Configuration Parameters
The plugin can access the configuration parameters used when workflows are invoked by including a symbol named
PluginConfiguration
that implements the following interface.The following is a full example.