Skip to content

docs(v2): operator #508

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 12 commits into from
May 21, 2025
113 changes: 111 additions & 2 deletions crates/operator/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,113 @@
//! Operator common functions.
//! # Operator
//!
//! ## What is an Operator
//!
//! Operators are off-chain nodes that perform, sign, and submit verifiable computations for
//! Autonomous Verifiable Services (AVSs) using Ethereum restaking for security. They first register on
//! EigenLayer’s core contracts, then opt-in to provide a range of services to AVSs.
//! Operators listen for new task events, execute the supplied computation logic,
//! cryptographically sign the results with `BLS/ECDSA` keys, and finally send the proofs
//! to an aggregator for final consolidation.
//!
//! ## How the Logic Works
//!
//! The Operator functions through the following flow:
//!
//! 1. **Task Subscription**:
//! - The operator subscribes to specific event signatures emitted by task processors
//! - Uses WebSocket connection to listen to blockchain events
//! - Filters only for the specific task type it's designed to handle
//!
//! 2. **Task Processing**:
//! - When a new task is detected, it extracts the task index and input data
//! - Applies a computation function to the input data. This computation function is provided when starting the operator.
//!
//! 3. **Response Signing**:
//! - Signs the computed result using the operator's BLS Key Pair.
//! - Creates a `SignedTaskResponse` containing the result, signature, and operator ID
//!
//! 4. **Response Submission**:
//! - Sends the signed response to an Aggregator service through a RPC request.
//!
//! ## How to Set Up an Operator
//!
//! 1. **Task Manager Definition**: Create a struct implementing the `TaskManagerDefs` trait:
//! - `Input` and `Output` types for your tasks. This should come from your bindings.
//! - `NEW_TASK_EVENT_SELECTOR` - the event signature for new task events
//! - Use the `impl_task_manager_from_defs_and_contract` macro to build your `TaskManager`.
//!
//! ```ignore
//! impl TaskManagerDefs for ISTaskManager {
//! type Input = U256;
//! type Output = U256;
//! const NEW_TASK_EVENT_SELECTOR: B256 = NewTaskCreated::SIGNATURE_HASH;
//! const TASK_RESPONDED_EVENT_SELECTOR: B256 = TaskResponded::SIGNATURE_HASH;
//! }
//!
//! impl_task_manager_from_defs_and_contract!(ISTaskManager => YOUR_BINDING_CONTRACT_INSTANCE);
//! ```
//!
//! 2. **Processing Logic**: Implement the computation function that processes task inputs and produces outputs
//! - This function will be called when the operator receives a `NEW_TASK_EVENT_SELECTOR` event.
//!
//! ```ignore
//! // Your custom logic to process the input and generate a response.
//! // Example: square the input.
//! pub async fn square(
//! task_index: u32,
//! number_to_be_squared: U256
//! ) -> Result<U256, TaskManagerError> {
//! Ok(number_to_be_squared * number_to_be_squared)
//! }
//! ```
//!
//! 3. **Response Calculator**: To abstract your computation into the operator, we provide a `ResponseCalculator`
//! trait with a standar `FunctionResponseCalculator` struct. This struct implements the trait and helpers
//! for turning your functions into implementations:
//! - `response_calculator_from_fn`: Create a response calculator from your computation function.
//! - `response_calculator_from_async_fn`: Create a response calculator from your async computation function.
//!
//! ```ignore
//! let response_calculator = response_calculator_from_fn(square);
//! ```
//!
//! - In case you need to save state in the operator, you can use your own struct implementing the `ResponseCalculator` trait.
//!
//! 4. **Failing Response Calculator**: If you want to test what happens when the operator responds incorrectly
//! to a task and see how slashing works, you can wrap your logic with `failing_response_calculator` (from
//! `eigen-testing-utils`), to inject failures and a given failure rate. **Use this for testing purposes only.**
//!
//! ```ignore
//! let logic = failing_response_calculator(response_calculator, || U256::from(42), 60);
//! ```
//!
//! 5. **Create the operator configuration**: Create a [`OperatorConfig`](crate::config::OperatorConfig) struct.
//! This structs implements `Serialize` and `Deserialize` so you can load from a file.
//! - Attributes:
//! - `bls_private_key`: The BLS private key for
//! - `operator_address`: The address of the operator
//! - `operator_name`: The name of the operator
//! - `ws_rpc_url`: The WebSocket RPC URL of the Ethereum node
//! - `http_rpc_url`: The HTTP RPC URL of the Ethereum node
//! - `registry_coordinator_address`: The address of the registry coordinator
//! - `operator_state_retriever_address`: The address of the operator state retriever
//! - `aggregator_ip_port`: The IP and port of the aggregator
//! - `registration`: The registration of the operator. If you don't want to register the operator, you can set this to `None`.
//!
//! 6. **Run the operator**: Initialize the [`Operator`] with the configuration and start it with the processing logic
//!
//! ```ignore
//! let operator = Operator::new(logger, config).await.unwrap();
//! operator.start::<ISTaskManager>(logic).await.unwrap();
//! ```
//!
//! ## Examples
//!
//! Here are some examples of operators that are already implemented:
//!
//! - [Incredible Squaring](https://github.com/Layr-Labs/eigensdk-rs/blob/v2-dev-1/examples/incredible-squaring/src/bin/operator.rs)
//! - [Incredible Dot Product](https://github.com/Layr-Labs/eigensdk-rs/blob/v2-dev-1/examples/incredible-dot-product/src/bin/operator.rs)
//! - [Awesome Vault Service](https://github.com/Layr-Labs/eigensdk-rs/blob/v2-dev-1/examples/awesome-vault-service/src/bin/operator.rs)

use alloy::{
dyn_abi::SolType,
Expand All @@ -24,7 +133,7 @@ use tracing::{error, info};
pub mod client;
/// Operator config
pub mod config;
/// Error
/// Operator error
pub mod error;
/// Operator registration config
pub mod register_config;
Expand Down
Loading