Skip to content
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

Impl registry coordinator #76

Merged
merged 118 commits into from
Jun 27, 2023
Merged
Show file tree
Hide file tree
Changes from 113 commits
Commits
Show all changes
118 commits
Select commit Hold shift + click to select a range
8d6737d
add initial stake registry
gpsanant May 25, 2023
0798ffa
Merge branch 'multiquorums' into add-stake-registry
gpsanant May 25, 2023
98c5e77
everything but quorumNumbers
gpsanant May 25, 2023
5161eab
added indexregistry
Sidu28 May 26, 2023
518ef4e
fixed error
Sidu28 May 26, 2023
eac96b1
fixed error
Sidu28 May 26, 2023
bfae892
fixed error
Sidu28 May 26, 2023
dedc642
fixed error
Sidu28 May 26, 2023
2f8df64
fixed error
Sidu28 May 26, 2023
e0e17a0
Merge branch 'multiquorums' of https://github.com/Layr-Labs/eigenlaye…
Sidu28 May 26, 2023
4d80a7e
modified interface
Sidu28 May 26, 2023
9ae1af4
modified interface
Sidu28 May 26, 2023
3abc044
fixed incorrect checl
Sidu28 May 26, 2023
de579ec
added additional lower bound check to getters
Sidu28 May 26, 2023
6b760fb
added additional lower bound check to getters
Sidu28 May 26, 2023
235b8ec
fixed _updateTotalOperatorHistory
Sidu28 May 26, 2023
ae519e7
fixed index update in _updateOperatorIdToIndexHistory
Sidu28 May 26, 2023
eee0936
added blockNumber update for deregistering operator
Sidu28 May 26, 2023
58ead13
added blockNumber update for deregistering operator
Sidu28 May 26, 2023
bf3a740
added comments
Sidu28 May 26, 2023
5286912
added comments
Sidu28 May 26, 2023
47c7506
fix conflicts
gpsanant May 26, 2023
7e15efb
Merge branch 'master' into add-stake-registry
gpsanant May 26, 2023
69f04fb
more work on stakeregistry
gpsanant May 26, 2023
cef971f
further reuse of internal functions
gpsanant May 26, 2023
500b41f
fix total stake update logic
gpsanant May 26, 2023
1fb084c
fix voteweigher interface
gpsanant May 27, 2023
ba56be4
removed random inut
Sidu28 May 28, 2023
b0ac3b1
fixed error
Sidu28 May 28, 2023
8f8c912
fixed error
Sidu28 May 28, 2023
5529568
added comment
Sidu28 May 28, 2023
abfa22c
added blackbox unit tests
Sidu28 May 28, 2023
2dd2c72
added blackbox unit tests
Sidu28 May 28, 2023
a0381d0
added tests
May 30, 2023
0d5b0bc
almost all tests working for vote weigher
gpsanant May 30, 2023
3a8ff37
add valid modification test
gpsanant May 30, 2023
a0d802e
add weight of operator test
gpsanant May 30, 2023
d4be2b7
reformats, remove some unnecessary fuzzing
gpsanant May 31, 2023
7b14be2
revert instead on empty arrays for removal/modification
gpsanant May 31, 2023
2c3df9a
heavy speedup
gpsanant May 31, 2023
7992f65
added comment to testRemoveStrategiesConsideredAndMultipliers_Valid
gpsanant May 31, 2023
501291b
merged BLSPubkeyRegistry and StakeRegistry
gpsanant May 31, 2023
a768731
initial write of BLSIndexRegistryCoordinator
gpsanant May 31, 2023
e57eb8b
add deregistration logic and silence warnings
gpsanant May 31, 2023
d69f30e
add comments to BLSIndexRegistryCoordinator
gpsanant May 31, 2023
42234da
fixed the tests
Jun 2, 2023
e753296
added test
Jun 2, 2023
515d631
added test
Jun 2, 2023
ba2185e
removed quorum To Operator list
Jun 2, 2023
5b1d971
removed quorum To Operator list
Jun 2, 2023
13cf421
removed quorum To Operator list
Jun 2, 2023
f343682
replaced length with variable
Jun 2, 2023
7f8a752
minor improvements
Jun 2, 2023
27ae581
fixed tests expecept for deregistry one
Jun 4, 2023
ba2a270
fixed error in code
Jun 4, 2023
a85e26a
fixed error in code
Jun 4, 2023
f418291
add index update events
gpsanant Jun 8, 2023
149b31e
removed quorumToTotalOperatorCount
Jun 20, 2023
7938853
merged multiquorums, registry coordinator mock doesn't work
gpsanant Jun 21, 2023
b3adbdd
made two sloads into 1
Jun 21, 2023
71dd923
Merge remote-tracking branch 'origin/multiquorums' into impl-registry…
gpsanant Jun 21, 2023
d34b1bc
make registry coordinator mock work
gpsanant Jun 21, 2023
1b8148a
merged indexRegistry
gpsanant Jun 21, 2023
8e82986
removed merge ugliness
gpsanant Jun 22, 2023
3fc195b
made IndexRegistry comment changes and propagated them
gpsanant Jun 22, 2023
3304f12
update operator status and add not registered check
gpsanant Jun 22, 2023
5b85ce5
updated IVoteWeigher to allow constants
gpsanant Jun 22, 2023
f616be4
remove max length from IVoteWeigher
gpsanant Jun 22, 2023
8c37e88
update IVoteWeigher.modifyStrategyWeights comment
gpsanant Jun 22, 2023
fa1d1cf
index operatorId in StakeRegistry
gpsanant Jun 22, 2023
8673c23
make registry coordinator immutable, and set in stake registry initia…
gpsanant Jun 22, 2023
ad65b84
remove test import
gpsanant Jun 22, 2023
3d5bfdf
hyphenate
gpsanant Jun 22, 2023
e2108d6
remove revert on strategiesConsideredAndMultipliersLength
gpsanant Jun 22, 2023
e9b8781
comment disabled function
gpsanant Jun 22, 2023
4f13cb5
add more to registry coordinator interface
gpsanant Jun 22, 2023
a5ec4e8
rename totalStakeHistory
gpsanant Jun 22, 2023
2ca877a
update stake registry comment
gpsanant Jun 22, 2023
c88b68b
fix iindexregistry comments
gpsanant Jun 22, 2023
34e2362
fix iindexregistry comments
gpsanant Jun 22, 2023
b6abc46
top level BLSIndexRegistryCoordinator comment
gpsanant Jun 22, 2023
0c907f4
modified register/deregister function names in registrycoordinator
gpsanant Jun 22, 2023
4b8f0ed
preconditions comment
gpsanant Jun 22, 2023
dd761a6
clarify register/deregister comments
gpsanant Jun 22, 2023
b644479
clarify register/deregister data structure
gpsanant Jun 22, 2023
9674a65
add quorumNumbers to registry coordinator
gpsanant Jun 22, 2023
c7d5d84
add complete deregistration functionality
gpsanant Jun 23, 2023
f9b3012
change to uin192 quorum numbers
gpsanant Jun 23, 2023
c9d36fc
edit voteweigher to have 192 quorums
gpsanant Jun 23, 2023
c938c14
add operator churn mechanism
gpsanant Jun 24, 2023
fb347a5
separated stakeregistry and coordinator
gpsanant Jun 24, 2023
f2c66a0
propagate bls sig edit updates
gpsanant Jun 24, 2023
0eff795
update stakeHistoryIndex comment
gpsanant Jun 27, 2023
926aabd
update voteweigher protocol contract pointer comments
gpsanant Jun 27, 2023
49a9ef1
make operator set params internal
gpsanant Jun 27, 2023
f38b7c8
make index registry mapping internal
gpsanant Jun 27, 2023
d3f5a94
address abuse of OperatorIndexUpdate
gpsanant Jun 27, 2023
d6e5a76
change kick percentages with kick BIPs
gpsanant Jun 27, 2023
598d8c6
add struct comments
gpsanant Jun 27, 2023
481daab
update index update event comment
gpsanant Jun 27, 2023
4f862c5
abstract setOperatorSetParams and add events
gpsanant Jun 27, 2023
ba096da
improve quorumBitmapUpdate comment and fix check
gpsanant Jun 27, 2023
b20e598
improve quorumBitmapUpdate struct comment
gpsanant Jun 27, 2023
88d0c50
add revert for lack of quorumBitmap history
gpsanant Jun 27, 2023
3874818
add to registerOperatorWithCoordinator (kick version) comment
gpsanant Jun 27, 2023
61db480
kick logic updates
gpsanant Jun 27, 2023
2631769
address various stakereg comments
gpsanant Jun 27, 2023
b03c92c
address various indexreg comments
gpsanant Jun 27, 2023
b3dbc9b
quorum mispellings"
gpsanant Jun 27, 2023
0aa1b58
various stakereg updates
gpsanant Jun 27, 2023
1a690fa
add internal setter and event for minimum stake and other updates
gpsanant Jun 27, 2023
2d4a033
fix lack of quorumNumbers check
gpsanant Jun 27, 2023
fc499a5
fix quorumBitmap lookup bug
gpsanant Jun 27, 2023
8280cc5
add permissions to stake registry register/deregister
gpsanant Jun 27, 2023
4262ada
update operator stake to 1 when below min
gpsanant Jun 27, 2023
932d5cb
add comment to remove fromTaskNumber
gpsanant Jun 27, 2023
f97ac40
update deregistration comments
gpsanant Jun 27, 2023
caab3f3
remove check(In)Active functions and revert 0/1 min stake update change
gpsanant Jun 27, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 14 additions & 8 deletions src/contracts/interfaces/IBLSPubkeyRegistry.sol
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,13 @@ interface IBLSPubkeyRegistry is IRegistry {
event PubkeyRemoved(
address operator,
BN254.G1Point pubkey
);
);

// Emitted when an operator pubkey is removed from a set of quorums
event PubkeyRemoveFromQuorums(
address operator,
bytes quorumNumbers
);


/// @notice Data structure used to track the history of the Aggregate Public Key of all operators
Expand All @@ -34,36 +40,36 @@ interface IBLSPubkeyRegistry is IRegistry {
}

/**

* @notice Registers the `operator`'s pubkey for the specified `quorumNumbers`.
* @param operator The address of the operator to register.
* @param quorumNumbers The quorum numbers the operator is registering for, where each byte is an 8 bit integer quorumNumber.
* @param pubkey The operator's BLS public key.
* @dev access restricted to the RegistryCoordinator
* @dev Preconditions:
* @dev Preconditions (these are assumed, not validated in this contract):
* 1) `quorumNumbers` has no duplicates
* 2) `quorumNumbers.length` != 0
* 3) `quorumNumbers` is ordered in ascending order
* 4) the operator is not already registered
*/
function registerOperator(address operator, bytes memory quorumNumbers, BN254.G1Point memory pubkey) external returns(bytes32);
function registerOperator(address operator, bytes calldata quorumNumbers, BN254.G1Point memory pubkey) external returns(bytes32);

/**
* @notice Deregisters the `operator`'s pubkey for the specified `quorumNumbers`.
* @param operator The address of the operator to deregister.
* @param quorumNumbers The quourm numbers the operator is deregistering from, where each byte is an 8 bit integer quorumNumber.
* @param completeDeregistration Whether the operator is deregistering from all quorums or just some.
* @param quorumNumbers The quorum numbers the operator is deregistering from, where each byte is an 8 bit integer quorumNumber.
* @param pubkey The public key of the operator.
* @dev access restricted to the RegistryCoordinator
* @dev Preconditions:
* @dev Preconditions (these are assumed, not validated in this contract):
* 1) `quorumNumbers` has no duplicates
* 2) `quorumNumbers.length` != 0
* 3) `quorumNumbers` is ordered in ascending order
* 4) the operator is not already deregistered
* 5) `quorumNumbers` is the same as the parameter use when registering
* 6) `pubkey` is the same as the parameter used when registering
*/
function deregisterOperator(address operator, bytes memory quorumNumbers, BN254.G1Point memory pubkey) external returns(bytes32);

function deregisterOperator(address operator, bool completeDeregistration, bytes calldata quorumNumbers, BN254.G1Point memory pubkey) external returns(bytes32);
/// @notice Returns the current APK for the provided `quorumNumber `
function getApkForQuorum(uint8 quorumNumber) external view returns (BN254.G1Point memory);

Expand Down
55 changes: 55 additions & 0 deletions src/contracts/interfaces/IBLSRegistryCoordinatorWithIndices.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
// SPDX-License-Identifier: BUSL-1.1
pragma solidity =0.8.12;

import "./IRegistryCoordinator.sol";
import "./IStakeRegistry.sol";
import "./IBLSPubkeyRegistry.sol";
import "./IIndexRegistry.sol";

/**
* @title Minimal interface for the `IBLSStakeRegistryCoordinator` contract.
* @author Layr Labs, Inc.
*/
interface IBLSRegistryCoordinatorWithIndices is IRegistryCoordinator {
// STRUCT

/**
* @notice Data structure for storing operator set params for a given quorum. Specifically the
* `maxOperatorCount` is the maximum number of operators that can be registered for the quorum,
* `kickBIPsOfOperatorStake` is the basis points of a new operator needs to have of an operator they are trying to kick from the quorum,
* `kickBIPsOfAverageStake` is the basis points of the average stake of the quorum that an operator needs to be below to be kicked,
* and `kickBIPsOfTotalStake` is the basis points of the total stake of the quorum that an operator needs to be below to be kicked.
*/
struct OperatorSetParam {
uint32 maxOperatorCount;
uint8 kickBIPsOfOperatorStake;
uint8 kickBIPsOfAverageStake;
uint8 kickBIPsOfTotalStake;
}

/**
* @notice Data structure for the parameters needed to kick an operator from a quorum, used during registration churn.
* Specifically the `operator` is the address of the operator to kick, `pubkey` is the BLS public key of the operator,
* `operatorIdsToSwap` is the list of operatorIds to swap with the operator being kicked in the indexRegistry,
* and `globalOperatorListIndex` is the index of the operator in the global operator list in the indexRegistry.
*/
struct OperatorKickParam {
gpsanant marked this conversation as resolved.
Show resolved Hide resolved
address operator;
BN254.G1Point pubkey;
bytes32[] operatorIdsToSwap; // should be a single length array when kicking
uint32 globalOperatorListIndex;
}

// EVENTS

event OperatorSetParamsUpdated(uint8 indexed quorumNumber, OperatorSetParam operatorSetParams);

/// @notice Returns the operator set params for the given `quorumNumber`
function getOperatorSetParams(uint8 quorumNumber) external view returns (OperatorSetParam memory);
/// @notice the stake registry for this corrdinator is the contract itself
function stakeRegistry() external view returns (IStakeRegistry);
/// @notice the BLS Pubkey Registry contract that will keep track of operators' BLS public keys
function blsPubkeyRegistry() external view returns (IBLSPubkeyRegistry);
/// @notice the Index Registry contract that will keep track of operators' indexes
function indexRegistry() external view returns (IIndexRegistry);
}
50 changes: 35 additions & 15 deletions src/contracts/interfaces/IIndexRegistry.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,21 @@ pragma solidity =0.8.12;
import "./IRegistry.sol";

/**
* @title Interface for a `Registry`-type contract that keeps track of an ordered list of operators for up to 256 quroums.
* @title Interface for a `Registry`-type contract that keeps track of an ordered list of operators for up to 256 quorums.
* @author Layr Labs, Inc.
*/
interface IIndexRegistry is IRegistry {
// EVENTS
// emitted when an operator's index in the orderd operator list for the quorum with number `quorumNumber` is updated
event QuorumIndexUpdate(bytes32 indexed operatorId, uint8 quorumNumber, uint32 newIndex);
// emitted when an operator's index in the global operator list is updated
event GlobalIndexUpdate(bytes32 indexed operatorId, uint32 newIndex);

// DATA STRUCTURES

// struct used to give definitive ordering to operators at each blockNumber
struct OperatorIndex {
// struct used to give definitive ordering to operators at each blockNumber.
// NOTE: this struct is slightly abused for also storing the total number of operators for each quorum over time
struct OperatorIndexUpdate {
// blockNumber number at which operator index changed
// note that the operator's index is different *for this block number*, i.e. the *new* index is *inclusive* of this value
uint32 toBlockNumber;
Expand All @@ -20,28 +27,41 @@ interface IIndexRegistry is IRegistry {
}

/**
* @notice Registers the operator with the specified `operatorId` for the quorums specified by `quorumBitmap`.
* @notice Registers the operator with the specified `operatorId` for the quorums specified by `quorumNumbers`.
* @param operatorId is the id of the operator that is being registered
* @param quorumNumbers is the quorum numbers the operator is registered for
* @dev access restricted to the RegistryCoordinator
* @dev Preconditions (these are assumed, not validated in this contract):
* 1) `quorumNumbers` has no duplicates
* 2) `quorumNumbers.length` != 0
* 3) `quorumNumbers` is ordered in ascending order
* 4) the operator is not already registered
*/
function registerOperator(bytes32 operatorId, uint8[] memory quorumNumbers) external;
function registerOperator(bytes32 operatorId, bytes calldata quorumNumbers) external;

/**
* @notice Deregisters the operator with the specified `operatorId` for the quorums specified by `quorumBitmap`.
* @notice Deregisters the operator with the specified `operatorId` for the quorums specified by `quorumNumbers`.
* @param operatorId is the id of the operator that is being deregistered
* @param completeDeregistration Whether the operator is deregistering from all quorums or just some.
gpsanant marked this conversation as resolved.
Show resolved Hide resolved
* @param quorumNumbers is the quorum numbers the operator is deregistered for
* @param quorumToOperatorListIndexes is an array of indexes for each quorum being removed from the quorumToOperatorList mapping
* @param globalOperatorListIndex is the index of the operator in the global operator list to be removed
* @dev Permissioned by RegistryCoordinator
* @param operatorIdsToSwap is the list of operatorIds that have the largest indexes in each of the `quorumNumbers`
* they will be swapped with the operator's current index when the operator is removed from the list
* @param globalOperatorListIndex is the index of the operator that is to be removed from the list
* @dev access restricted to the RegistryCoordinator
* @dev Preconditions (these are assumed, not validated in this contract):
* 1) `quorumNumbers` has no duplicates
* 2) `quorumNumbers.length` != 0
* 3) `quorumNumbers` is ordered in ascending order
* 4) the operator is not already deregistered
* 5) `quorumNumbers` is the same as the parameter use when registering
*/
function deregisterOperator(bytes32 operatorId, uint8[] memory quorumNumbers, uint32[] memory quorumToOperatorListIndexes, uint32 globalOperatorListIndex) external;
function deregisterOperator(bytes32 operatorId, bool completeDeregistration, bytes calldata quorumNumbers, bytes32[] memory operatorIdsToSwap, uint32 globalOperatorListIndex) external;

/**
* @notice Returns the operator id at the index in the list of all operators for all quorums
* @param index is the index of the operator in the array of operators
*/
function totalOperatorList(uint256 index) external view returns (bytes32);
/// @notice Returns the _operatorIdToIndexHistory entry for the specified `operatorId` and `quorumNumber` at the specified `index`
function getOperatorIndexUpdateOfOperatorIdForQuorumAtIndex(bytes32 operatorId, uint8 quorumNumber, uint32 index) external view returns (OperatorIndexUpdate memory);

/// @notice Returns the _totalOperatorsHistory entry for the specified `quorumNumber` at the specified `index`
function getTotalOperatorsUpdateForQuorumAtIndex(uint8 quorumNumber, uint32 index) external view returns (OperatorIndexUpdate memory);

/**
* @notice Looks up the `operator`'s index for `quorumNumber` at the specified `blockNumber` using the `index`.
Expand Down
2 changes: 1 addition & 1 deletion src/contracts/interfaces/IQuorumRegistry.sol
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ interface IQuorumRegistry {
uint96 stake;
}

function pubkeyHashToQuorumBitmap(bytes32 pubkeyHash) external view returns (uint256);
function pubkeyHashToQuorumBitmap(bytes32 pubkeyHash) external view returns (uint192);

function getLengthOfTotalStakeHistoryForQuorum(uint8 quorumNumber) external view returns (uint256);

Expand Down
64 changes: 51 additions & 13 deletions src/contracts/interfaces/IRegistryCoordinator.sol
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,24 @@ pragma solidity =0.8.12;
* @author Layr Labs, Inc.
*/
interface IRegistryCoordinator {
// EVENTS
/// Emits when an operator is registered
event OperatorRegistered(address indexed operator, bytes32 indexed operatorId);

/// Emits when an operator is deregistered
event OperatorDeregistered(address indexed operator, bytes32 indexed operatorId);

// DATA STRUCTURES
enum Status
enum OperatorStatus
{
// default is inactive
INACTIVE,
ACTIVE
// default is NEVER_REGISTERED
NEVER_REGISTERED,
REGISTERED,
DEREGISTERED
}

// STRUCTS

/**
* @notice Data structure for storing info on operators
*/
Expand All @@ -23,15 +33,35 @@ interface IRegistryCoordinator {
// start taskNumber from which the operator has been registered
uint32 fromTaskNumber;
// indicates whether the operator is actively registered for serving the middleware or not
Status status;
OperatorStatus status;
gpsanant marked this conversation as resolved.
Show resolved Hide resolved
}

/// @notice Returns the bitmap of the quroums the operator is registered for.
function operatorIdToQuorumBitmap(bytes32 pubkeyHash) external view returns (uint256);
/**
* @notice Data structure for storing info on quorum bitmap updates where the `quorumBitmap` is the bitmap of the
* quorums the operator is registered for starting at (inclusive)`updateBlockNumber` and ending at (exclusive) `nextUpdateBlockNumber`
* @dev nextUpdateBlockNumber is initialized to 0 for the latest update
*/
struct QuorumBitmapUpdate {
uint32 updateBlockNumber;
uint32 nextUpdateBlockNumber;
uint192 quorumBitmap;
}

/// @notice Returns the operator struct for the given `operator`
function getOperator(address operator) external view returns (Operator memory);

/// @notice Returns the stored id for the specified `operator`.
/// @notice Returns the operatorId for the given `operator`
function getOperatorId(address operator) external view returns (bytes32);

/**
* @notice Returns the quorum bitmap for the given `operatorId` at the given `blockNumber` via the `index`
* @dev reverts if `index` is incorrect
*/
function getQuorumBitmapByOperatorIdAtBlockNumberByIndex(bytes32 operatorId, uint32 blockNumber, uint256 index) external view returns (uint192);

/// @notice Returns the current quorum bitmap for the given `operatorId`
function getCurrentQuorumBitmapByOperatorId(bytes32 operatorId) external view returns (uint192);

/// @notice Returns task number from when `operator` has been registered.
function getFromTaskNumberForOperator(address operator) external view returns (uint32);

Expand All @@ -41,9 +71,17 @@ interface IRegistryCoordinator {
/// @notice Returns the number of registries
function numRegistries() external view returns (uint256);

/// @notice registers the sender as an operator for the `quorumNumbers` with additional bytes for registry interaction data
function registerOperator(uint8[] memory quorumNumbers, bytes calldata) external returns (bytes32);
/**
* @notice Registers msg.sender as an operator with the middleware
* @param quorumNumbers are the bytes representing the quorum numbers that the operator is registering for
* @param registrationData is the data that is decoded to get the operator's registration information
*/
function registerOperatorWithCoordinator(bytes memory quorumNumbers, bytes calldata registrationData) external;

/// @notice deregisters the sender with additional bytes for registry interaction data
function deregisterOperator(bytes calldata) external returns (bytes32);
}
/**
* @notice Deregisters the msg.sender as an operator from the middleware
* @param quorumNumbers are the bytes representing the quorum numbers that the operator is registered for
* @param deregistrationData is the the data that is decoded to get the operator's deregistration information
*/
function deregisterOperatorWithCoordinator(bytes calldata quorumNumbers, bytes calldata deregistrationData) external;
}
Loading