Skip to content

Commit 06b33df

Browse files
docs: add OperatorStateRetriever (#421)
**Motivation:** `OperatorStateRetriever` had no documentation **Modifications:** Added `OperatorStateRetriever.md` **Result:** Increase documentation coverage --------- Co-authored-by: steven <[email protected]>
1 parent 2afed9d commit 06b33df

File tree

1 file changed

+168
-0
lines changed

1 file changed

+168
-0
lines changed

docs/OperatorStateRetriever.md

+168
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
# OperatorStateRetriever
2+
3+
| File | Type | Proxy |
4+
| -------- | -------- | -------- |
5+
| [`OperatorStateRetriever.sol`](../src/OperatorStateRetriever.sol) | Singleton | None |
6+
7+
The `OperatorStateRetriever` contract provides view methods that compose view calls from the registry contracts to surface enriched state information. These methods are intended to be called offchain to prepare calldata for BLS signature validation through the `BLSSignatureChecker.checkSignatures` method.
8+
9+
The contract traverses historical state records in the registry contracts ([`IndexRegistry`](./registries/IndexRegistry.md), [`StakeRegistry`](./registries/StakeRegistry.md), and [`BLSApkRegistry`](./registries/BLSApkRegistry.md)) to retrieve information about operators and quorums at specific block numbers. This historical data is essential for validating signatures against a fixed point in time, as operators may register for or deregister from quorums after signing data.
10+
11+
#### High-level Concepts
12+
13+
This document organizes methods according to the following themes:
14+
* [Offchain Methods](#offchain-methods)
15+
* [Utility Functions](#utility-functions)
16+
17+
---
18+
19+
### Offchain Methods
20+
21+
These methods traverse various registry histories to retrieve information needed for BLS signature validation:
22+
* [`getOperatorState (operatorId)`](#getoperatorstate-operatorid)
23+
* [`getOperatorState (quorumNumbers)`](#getoperatorstate-quorumnumbers)
24+
* [`getCheckSignaturesIndices`](#getchecksignaturesindices)
25+
26+
#### `getOperatorState (operatorId)`
27+
28+
```solidity
29+
function getOperatorState(
30+
ISlashingRegistryCoordinator registryCoordinator,
31+
bytes32 operatorId,
32+
uint32 blockNumber
33+
) external view returns (uint256, Operator[][] memory)
34+
35+
struct Operator {
36+
address operator;
37+
bytes32 operatorId;
38+
uint96 stake;
39+
}
40+
```
41+
42+
This method is designed for AVS operators to retrieve their state and responsibilities when a new task is created by the AVS coordinator. It returns information about an Operator and the quorums they were registered for at a specific block number.
43+
44+
The method performs the following operations:
45+
1. Retrieves the quorum bitmap for the Operator at the specified block number
46+
2. Converts the bitmap to an array of quorum numbers
47+
3. For each quorum the Operator was registered for, retrieves the complete list of registered Operators in that quorum
48+
49+
This eliminates the need for operators to run indexers to fetch on-chain data.
50+
51+
*Returns*:
52+
* `uint256`: A bitmap representation of the quorums the Operator was registered for at the given block number
53+
* `Operator[][]`: For each quorum the Operator was registered for, an ordered list of all Operators in that quorum, including their addresses, IDs, and stakes
54+
55+
#### `getOperatorState (quorumNumbers)`
56+
57+
```solidity
58+
function getOperatorState(
59+
ISlashingRegistryCoordinator registryCoordinator,
60+
bytes memory quorumNumbers,
61+
uint32 blockNumber
62+
) public view returns (Operator[][] memory)
63+
```
64+
65+
This method returns comprehensive information about all Operators registered for specified quorums at a given block number. It traverses multiple registry contracts to compile complete operator data.
66+
67+
The method performs the following operations for each quorum:
68+
1. Retrieves the list of operator IDs from the `IndexRegistry`
69+
2. Fetches each operator's address from the `BLSApkRegistry`
70+
3. Obtains stake amounts from the `StakeRegistry`
71+
4. Compiles this information into an ordered list of Operators for each quorum
72+
73+
*Returns*:
74+
* `Operator[][]`: For each quorum in `quorumNumbers`, an ordered list of all Operators registered for that quorum at the specified block number, including their addresses, IDs, and stakes
75+
76+
#### `getCheckSignaturesIndices`
77+
78+
```solidity
79+
function getCheckSignaturesIndices(
80+
ISlashingRegistryCoordinator registryCoordinator,
81+
uint32 referenceBlockNumber,
82+
bytes calldata quorumNumbers,
83+
bytes32[] calldata nonSignerOperatorIds
84+
) external view returns (CheckSignaturesIndices memory)
85+
86+
struct CheckSignaturesIndices {
87+
uint32[] nonSignerQuorumBitmapIndices;
88+
uint32[] quorumApkIndices;
89+
uint32[] totalStakeIndices;
90+
uint32[][] nonSignerStakeIndices; // nonSignerStakeIndices[quorumNumberIndex][nonSignerIndex]
91+
}
92+
```
93+
94+
This method is critical for BLS signature validation, as it retrieves indices into historical state that can be used for efficient lookups in `BLSSignatureChecker.checkSignatures`. The non-signer operator IDs are required here as signature verification is done against negation of the BLS aggregate public key. That is, negate the aggregate key then add the weight of each signer.
95+
96+
The method generates the following indices:
97+
1. Indices of quorum bitmap updates for each non-signing operator
98+
2. Indices of total stake updates for each quorum
99+
3. For each quorum, indices of stake updates for non-signing operators registered for that quorum
100+
4. Indices of aggregate public key (APK) updates for each quorum
101+
102+
By pre-computing these indices offchain, the `BLSSignatureChecker.checkSignatures` method can perform cheap lookups rather than traversing over historical state during an expensive onchain operation.
103+
104+
*Returns*:
105+
* `CheckSignaturesIndices`: A struct containing all indices needed for signature validation:
106+
* `nonSignerQuorumBitmapIndices`: For each non-signer, the index in `RegistryCoordinator._operatorBitmapHistory` where their quorum bitmap can be found
107+
* `quorumApkIndices`: For each quorum, the index in `BLSApkRegistry.apkHistory` where the quorum's APK can be found
108+
* `totalStakeIndices`: For each quorum, the index in `StakeRegistry._totalStakeHistory` where the quorum's total stake can be found
109+
* `nonSignerStakeIndices`: For each quorum, indices in `StakeRegistry.operatorStakeHistory` for each non-signer registered for that quorum
110+
111+
*Requirements*:
112+
* Non-signer operator IDs must be registered (have non-zero quorum bitmaps)
113+
114+
---
115+
116+
### Utility Functions
117+
118+
These methods provide additional utilities for retrieving historical state and operator information:
119+
* [`getQuorumBitmapsAtBlockNumber`](#getquorumbitmapsatblocknumber)
120+
* [`getBatchOperatorId`](#getbatchoperatorid)
121+
* [`getBatchOperatorFromId`](#getbatchoperatorfromid)
122+
123+
#### `getQuorumBitmapsAtBlockNumber`
124+
125+
```solidity
126+
function getQuorumBitmapsAtBlockNumber(
127+
ISlashingRegistryCoordinator registryCoordinator,
128+
bytes32[] memory operatorIds,
129+
uint32 blockNumber
130+
) external view returns (uint256[] memory)
131+
```
132+
133+
This method retrieves quorum bitmaps for multiple operators at a specific block number, providing an efficient way to determine which quorums each operator was registered for at that point in time.
134+
135+
*Returns*:
136+
* `uint256[]`: An array of quorum bitmaps, one for each operator ID provided, representing the quorums each operator was registered for at the given block number
137+
138+
#### `getBatchOperatorId`
139+
140+
```solidity
141+
function getBatchOperatorId(
142+
ISlashingRegistryCoordinator registryCoordinator,
143+
address[] memory operators
144+
) external view returns (bytes32[] memory operatorIds)
145+
```
146+
147+
This utility function converts multiple operator addresses to their corresponding operator IDs in a single call, improving gas efficiency for batch operations.
148+
149+
*Returns*:
150+
* `bytes32[]`: An array of operator IDs corresponding to the provided addresses
151+
* If an operator is not registered, its ID will be 0
152+
153+
#### `getBatchOperatorFromId`
154+
155+
```solidity
156+
function getBatchOperatorFromId(
157+
ISlashingRegistryCoordinator registryCoordinator,
158+
bytes32[] memory operatorIds
159+
) external view returns (address[] memory operators)
160+
```
161+
162+
This utility function converts multiple operator IDs to their corresponding operator addresses in a single call, improving gas efficiency for batch operations.
163+
164+
*Returns*:
165+
* `address[]`: An array of operator addresses corresponding to the provided IDs
166+
* If an operator ID is not registered, its address will be 0x0
167+
168+
---

0 commit comments

Comments
 (0)