eigen_services_avsregistry/lib.rs
1//! AVS Registry Service
2//!
3//! This service is used to get the AVS state of the operators and the quorums.
4//!
5//! ## Introduction
6//!
7//! The [`AvsRegistryServiceChainCaller`] allows to get the AVS state of the operators and the quorums at any block.
8//! This service is used by the `BLS Aggregator service` and use under the hood the `OperatorInfoService` to get the operator info.
9//!
10//! ## Main Components
11//!
12//! ### OperatorAvsState
13//!
14//! Represents the AVS state of an operator.
15//!
16//! - `operator_id`: Operator ID
17//! - `operator_info`: Operator info public key
18//! - `stake_per_quorum`: Stake per quorum
19//! - `block_num`: Block number
20//!
21//! ### QuorumAvsState
22//!
23//! Represents the AVS state of a quorum.
24//!
25//! - `quorum_num`: Quorum number
26//! - `total_stake`: Total stake
27//! - `agg_pub_key_g1`: Aggregated G1 public key
28//! - `block_num`: Block number
29//!
30//! ## Usage
31//!
32//! ### Initialize the service
33//!
34//! To initialize the service, you need to provide an `AvsRegistryReader` and an `OperatorInfoService` and call the [`new`] method.
35//!
36//! ```rust,no_run
37//!# use eigen_testing_utils::anvil_constants::{FIRST_ADDRESS, OPERATOR_BLS_KEY};
38//!# use eigen_services_operatorsinfo::operatorsinfo_inmemory::OperatorInfoServiceInMemory;
39//!# use eigen_client_avsregistry::fake_reader::FakeAvsRegistryReader;
40//!# use eigen_services_operatorsinfo::fake_operator_info::FakeOperatorInfoService;
41//!# use eigen_types::test::TestOperator;
42//!# use eigen_crypto_bls::BlsKeyPair;
43//!# use eigen_types::avs_state::{OperatorAvsState, QuorumAvsState};
44//!# use eigen_types::operator::{OperatorInfo, OperatorPubKeys, QuorumNum};
45//!# use std::collections::HashMap;
46//!# use eigen_services_avsregistry::chaincaller::AvsRegistryServiceChainCaller;
47//!# use alloy::primitives::{FixedBytes, U256, Address};
48//!# fn example () {
49//!# let operator_id = FixedBytes::from_slice(&[1]);
50//!# let test_operator = TestOperator {
51//!# operator_id,
52//!# bls_keypair: BlsKeyPair::new(OPERATOR_BLS_KEY.to_string()).unwrap(),
53//!# stake_per_quorum: HashMap::from([(1u8, U256::from(123))]),
54//!# };
55//!# let operator_address = Address::from(FIRST_ADDRESS);
56//!# let avs_registry = FakeAvsRegistryReader::new(test_operator.clone(), operator_address);
57//!# let operator_info_service = FakeOperatorInfoService::new(test_operator.bls_keypair.clone());
58//!#
59//! let avs_registry_service =
60//! AvsRegistryServiceChainCaller::new(avs_registry, operator_info_service);
61//!# }
62//! ```
63//!
64//! ### Get the AVS state of the operators and the quorums at a specific block
65//!
66//! To get the state of the operator in a specific quorum at a specific block, you can use the [`get_operators_avs_state_at_block`] method.
67//! The list of quorum nums and the list of operators stakes in quorums should have the same length.
68//! The method returns a hashmap with the operator ID as the key and the `OperatorAvsState` as the value.
69//!
70//! ```rust,no_run
71//!# use eigen_testing_utils::anvil_constants::{FIRST_ADDRESS, OPERATOR_BLS_KEY};
72//!# use eigen_services_operatorsinfo::operatorsinfo_inmemory::OperatorInfoServiceInMemory;
73//!# use eigen_client_avsregistry::fake_reader::FakeAvsRegistryReader;
74//!# use eigen_services_operatorsinfo::fake_operator_info::FakeOperatorInfoService;
75//!# use eigen_types::test::TestOperator;
76//!# use eigen_crypto_bls::BlsKeyPair;
77//!# use eigen_types::avs_state::{OperatorAvsState, QuorumAvsState};
78//!# use eigen_types::operator::{OperatorInfo, OperatorPubKeys, QuorumNum};
79//!# use std::collections::HashMap;
80//!# use eigen_services_avsregistry::chaincaller::AvsRegistryServiceChainCaller;
81//!# use alloy::primitives::{FixedBytes, U256, Address};
82//!# use eigen_services_avsregistry::AvsRegistryService;
83//!# async fn example () {
84//!# let operator_id = FixedBytes::from_slice(&[1]);
85//!# let test_operator = TestOperator {
86//!# operator_id,
87//!# bls_keypair: BlsKeyPair::new(OPERATOR_BLS_KEY.to_string()).unwrap(),
88//!# stake_per_quorum: HashMap::from([(1u8, U256::from(123))]),
89//!# };
90//!# let operator_address = Address::from(FIRST_ADDRESS);
91//!# let avs_registry = FakeAvsRegistryReader::new(test_operator.clone(), operator_address);
92//!# let operator_info_service = FakeOperatorInfoService::new(test_operator.bls_keypair.clone());
93//!#
94//!# let avs_registry_service =
95//!# AvsRegistryServiceChainCaller::new(avs_registry, operator_info_service);
96//!#
97//!# let block_num = 1;
98//!# let quorum_nums = vec![1];
99//! let operator_avs_state = avs_registry_service
100//! .get_operators_avs_state_at_block(block_num, &quorum_nums)
101//! .await
102//! .unwrap();
103//!# }
104//! ```
105//!
106//! To get the state of the quorum at a specific block, you can use the [`get_quorums_avs_state_at_block`] method.
107//! The method returns a hashmap with the quorum number as the key and the `QuorumAvsState` as the value.
108//!
109//! ```rust,no_run
110//!# use eigen_testing_utils::anvil_constants::{FIRST_ADDRESS, OPERATOR_BLS_KEY};
111//!# use eigen_services_operatorsinfo::operatorsinfo_inmemory::OperatorInfoServiceInMemory;
112//!# use eigen_client_avsregistry::fake_reader::FakeAvsRegistryReader;
113//!# use eigen_services_operatorsinfo::fake_operator_info::FakeOperatorInfoService;
114//!# use eigen_types::test::TestOperator;
115//!# use eigen_crypto_bls::BlsKeyPair;
116//!# use eigen_types::avs_state::{OperatorAvsState, QuorumAvsState};
117//!# use eigen_types::operator::{OperatorInfo, OperatorPubKeys, QuorumNum};
118//!# use std::collections::HashMap;
119//!# use eigen_services_avsregistry::chaincaller::AvsRegistryServiceChainCaller;
120//!# use alloy::primitives::{FixedBytes, U256, Address};
121//!# use eigen_services_avsregistry::AvsRegistryService;
122//!# async fn example () {
123//!# let operator_id = FixedBytes::from_slice(&[1]);
124//!# let test_operator = TestOperator {
125//!# operator_id,
126//!# bls_keypair: BlsKeyPair::new(OPERATOR_BLS_KEY.to_string()).unwrap(),
127//!# stake_per_quorum: HashMap::from([(1u8, U256::from(123))]),
128//!# };
129//!# let operator_address = Address::from(FIRST_ADDRESS);
130//!# let avs_registry = FakeAvsRegistryReader::new(test_operator.clone(), operator_address);
131//!# let operator_info_service = FakeOperatorInfoService::new(test_operator.bls_keypair.clone());
132//!#
133//!# let avs_registry_service =
134//!# AvsRegistryServiceChainCaller::new(avs_registry, operator_info_service);
135//!#
136//!# let block_num = 1;
137//!# let quorum_nums = vec![1];
138//! let quorum_state_per_number = avs_registry_service
139//! .get_quorums_avs_state_at_block(&quorum_nums, block_num)
140//! .await
141//! .unwrap();
142//!# }
143//! ```
144//!
145//! ### Get the signatures indices of quorum members for a specific block
146//!
147//! To get the signatures indices of quorum members for a specific block, you can use the [`get_check_signatures_indices`] method.
148//!
149//! ```rust,no_run
150//!# use eigen_testing_utils::anvil_constants::{FIRST_ADDRESS, OPERATOR_BLS_KEY};
151//!# use eigen_services_operatorsinfo::operatorsinfo_inmemory::OperatorInfoServiceInMemory;
152//!# use eigen_client_avsregistry::fake_reader::FakeAvsRegistryReader;
153//!# use eigen_services_operatorsinfo::fake_operator_info::FakeOperatorInfoService;
154//!# use eigen_types::test::TestOperator;
155//!# use eigen_crypto_bls::BlsKeyPair;
156//!# use eigen_types::avs_state::{OperatorAvsState, QuorumAvsState};
157//!# use eigen_types::operator::{OperatorInfo, OperatorPubKeys, QuorumNum};
158//!# use std::collections::HashMap;
159//!# use eigen_services_avsregistry::chaincaller::AvsRegistryServiceChainCaller;
160//!# use alloy::primitives::{FixedBytes, U256, Address};
161//!# use eigen_services_avsregistry::AvsRegistryService;
162//!# async fn example () {
163//!# let operator_id = FixedBytes::from_slice(&[1]);
164//!# let test_operator = TestOperator {
165//!# operator_id,
166//!# bls_keypair: BlsKeyPair::new(OPERATOR_BLS_KEY.to_string()).unwrap(),
167//!# stake_per_quorum: HashMap::from([(1u8, U256::from(123))]),
168//!# };
169//!# let operator_address = Address::from(FIRST_ADDRESS);
170//!# let avs_registry = FakeAvsRegistryReader::new(test_operator.clone(), operator_address);
171//!# let operator_info_service = FakeOperatorInfoService::new(test_operator.bls_keypair.clone());
172//!#
173//!# let avs_registry_service =
174//!# AvsRegistryServiceChainCaller::new(avs_registry, operator_info_service);
175//!#
176//!# let block_num = 1;
177//!# let quorum_nums = vec![1];
178//!# let non_signer_operator_ids = vec![];
179//! let check_signatures_indices = avs_registry_service
180//! .get_check_signatures_indices(block_num, quorum_nums, non_signer_operator_ids)
181//! .await
182//! .unwrap();
183//!# }
184//! ```
185//!
186//! [`AvsRegistryServiceChainCaller`]: chaincaller::AvsRegistryServiceChainCaller
187//! [`new`]: chaincaller::AvsRegistryServiceChainCaller::new()
188//! [`get_operators_avs_state_at_block`]: chaincaller::AvsRegistryServiceChainCaller::get_operators_avs_state_at_block()
189//! [`get_quorums_avs_state_at_block`]: chaincaller::AvsRegistryServiceChainCaller::get_quorums_avs_state_at_block()
190//! [`get_check_signatures_indices`]: chaincaller::AvsRegistryServiceChainCaller::get_check_signatures_indices()
191//!
192
193#![doc(
194 html_logo_url = "https://github.com/Layr-Labs/eigensdk-rs/assets/91280922/bd13caec-3c00-4afc-839a-b83d2890beb5",
195 issue_tracker_base_url = "https://github.com/Layr-Labs/eigensdk-rs/issues/"
196)]
197#![cfg_attr(not(test), warn(unused_crate_dependencies))]
198
199use std::collections::HashMap;
200
201use alloy::primitives::FixedBytes;
202use async_trait::async_trait;
203use eigen_client_avsregistry::error::AvsRegistryError;
204use eigen_types::avs_state::{OperatorAvsState, QuorumAvsState};
205use eigen_utils::slashing::middleware::operatorstateretriever::OperatorStateRetriever::CheckSignaturesIndices;
206
207pub mod chaincaller;
208#[doc(hidden)]
209pub mod fake_avs_registry_service;
210
211#[async_trait]
212pub trait AvsRegistryService {
213 /// Get the operators AVS state at a specific block number
214 ///
215 /// # Arguments
216 ///
217 /// * `block_num` - The block number to get the AVS state at
218 /// * `quorum_nums` - The list of quorum numbers
219 ///
220 /// # Returns
221 ///
222 /// A hashmap containing the operator ID and the operator AVS state
223 async fn get_operators_avs_state_at_block(
224 &self,
225 block_num: u64,
226 quorum_nums: &[u8],
227 ) -> Result<HashMap<FixedBytes<32>, OperatorAvsState>, AvsRegistryError>;
228
229 /// Get the quorum AVS state at a specific block
230 ///
231 /// # Arguments
232 ///
233 /// * `quorum_nums` - The list of quorum numbers
234 /// * `block_num` - The block number
235 ///
236 /// # Returns
237 ///
238 /// A hashmap containing the quorum number and the quorum AVS state.
239 async fn get_quorums_avs_state_at_block(
240 &self,
241 quorum_nums: &[u8],
242 block_num: u64,
243 ) -> Result<HashMap<u8, QuorumAvsState>, AvsRegistryError>;
244
245 /// Get the signatures indices of quorum members for a specific block and checks
246 /// if the indices are valid
247 ///
248 /// # Arguments
249 ///
250 /// * `reference_block_number` - The reference block number
251 /// * `quorum_numbers` - The list of quorum numbers
252 /// * `non_signer_operator_ids` - The list of non-signer operator ids
253 ///
254 /// # Returns
255 ///
256 /// A struct containing the indices of the quorum members that signed,
257 /// and the ones that didn't
258 async fn get_check_signatures_indices(
259 &self,
260 reference_block_number: u64,
261 quorum_numbers: Vec<u8>,
262 non_signer_operator_ids: Vec<FixedBytes<32>>,
263 ) -> Result<CheckSignaturesIndices, AvsRegistryError>;
264}