From 583ccaae94edde1dcc4d0526fd8c14b02c50fc3d Mon Sep 17 00:00:00 2001 From: JES Date: Wed, 5 Mar 2025 14:15:48 -0800 Subject: [PATCH 1/5] docs: update BlsApkRegistry --- docs/registries/BLSApkRegistry.md | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/docs/registries/BLSApkRegistry.md b/docs/registries/BLSApkRegistry.md index 031936b8b..59a1d687e 100644 --- a/docs/registries/BLSApkRegistry.md +++ b/docs/registries/BLSApkRegistry.md @@ -54,6 +54,7 @@ This method validates a BLS signature over the `pubkeyRegistrationMessageHash`, * Registers the Operator's BLS pubkey for the first time, updating the following mappings: * `operatorToPubkey[operator]` * `operatorToPubkeyHash[operator]` + * `operatorToPubKeyG2[operator]` * `pubkeyHashToOperator[pubkeyHash]` *Requirements*: @@ -129,6 +130,27 @@ This method is ONLY callable by the `RegistryCoordinator`, and is called when an * `operator` MUST already have a registered BLS pubkey (see `registerBLSPublicKey` above) * Each quorum in `quorumNumbers` MUST be initialized (see `initializeQuorum` below) +#### `verifyAndRegisterG2PubkeyForOperator` + +```solidity +function verifyAndRegisterG2PubkeyForOperator( + address operator, + BN254.G2Point calldata pubkeyG2 +) + external + onlyRegistryCoordinatorOwner +``` +`verifyAndRegisterG2PubkeyForOperator` verifies and registers a G2 public key for an operator that already has a G1 key. This method is used to retrieve all information for the `checkSignatures` entry point from a view function, avoiding the need to index this information offchain. The method ensures that the BLS key pair is derived from the same secret key and stores the G2 key for the operator. + +This method is only callable by the `RegistryCoordinatorOwner`, which is the account that has the `owner` role inside the `RegistryCoordinator`. + +*Effects* +* Stores the corresponding G2 public key of an operator's BLS keypair, based on their G1 public key. + +*Requirements* +* Caller MUST be the `RegistryCoordinatorOwner` +* Operator must not have a G2 public key set +* The G2 pubic key must form a valid BN254 pairing with the stored G1 key, in effect verifying that the keypair is derived from the same secret key --- ### System Configuration From f759ba5b3442559a93650646e71c4f45a791a284 Mon Sep 17 00:00:00 2001 From: JES Date: Wed, 5 Mar 2025 15:22:25 -0800 Subject: [PATCH 2/5] docs: update stake registry --- docs/registries/BLSApkRegistry.md | 2 +- docs/registries/StakeRegistry.md | 81 ++++++++++++++++++++++++++++--- 2 files changed, 75 insertions(+), 8 deletions(-) diff --git a/docs/registries/BLSApkRegistry.md b/docs/registries/BLSApkRegistry.md index 59a1d687e..5b7d9ecee 100644 --- a/docs/registries/BLSApkRegistry.md +++ b/docs/registries/BLSApkRegistry.md @@ -145,7 +145,7 @@ function verifyAndRegisterG2PubkeyForOperator( This method is only callable by the `RegistryCoordinatorOwner`, which is the account that has the `owner` role inside the `RegistryCoordinator`. *Effects* -* Stores the corresponding G2 public key of an operator's BLS keypair, based on their G1 public key. +* Stores the corresponding G2 public key of an operator's BLS keypair, based on their G1 public key, updating `operatorToPubkeyG2[operator]`. *Requirements* * Caller MUST be the `RegistryCoordinatorOwner` diff --git a/docs/registries/StakeRegistry.md b/docs/registries/StakeRegistry.md index 13a19334b..f43404b1b 100644 --- a/docs/registries/StakeRegistry.md +++ b/docs/registries/StakeRegistry.md @@ -172,19 +172,22 @@ These properties are enforced by the `RegistryCoordinator`. ### System Configuration -This method is used by the `RegistryCoordinator` to initialize new quorums in the `StakeRegistry`: -* [`initializeQuorum`](#initializequorum) +Two methods are used by the `RegistryCoordinator` to initialize new quorums in the `StakeRegistry`: +* [`initializeDelegatedStakeQuorum`](#initializedelegatedstakequorum) +* [`initializeSlashableStakeQuorum`](#initializeslashablestakequorum) + These methods are used by the `RegistryCoordinator's` Owner to configure initialized quorums in the `StakeRegistry`. They are not expected to be called very often, and will require updating Operator stakes via `RegistryCoordinator.updateOperatorsForQuorum` to maintain up-to-date views on Operator stake weights. Methods follow: * [`setMinimumStakeForQuorum`](#setminimumstakeforquorum) * [`addStrategies`](#addstrategies) +* [`setSlashableLookAhead`](#setslashablelookahead) * [`removeStrategies`](#removestrategies) * [`modifyStrategyParams`](#modifystrategyparams) -#### `initializeQuorum` +#### `initializeDelegatedStakeQuorum` ```solidity -function initializeQuorum( +function initializeDelegatedStakeQuorum( uint8 quorumNumber, uint96 minimumStake, StrategyParams[] memory _strategyParams @@ -199,20 +202,61 @@ struct StrategyParams { } ``` -This method is ONLY callable by the `RegistryCoordinator`, and is called when the `RegistryCoordinator` Owner creates a new quorum. +This method is ONLY callable by the `RegistryCoordinator`, and is called when the `RegistryCoordinator` Owner creates a new delegated stake quorum. -`initializeQuorum` initializes a new quorum by pushing an initial `StakeUpdate` to `_totalStakeHistory[quorumNumber]`, with an initial stake of 0. Other methods can validate that a quorum exists by checking whether `_totalStakeHistory[quorumNumber]` has a nonzero length. +`initializeDelegatedStakeQuorum` initializes a new delegated stake quorum by pushing an initial `StakeUpdate` to `_totalStakeHistory[quorumNumber]`, with an initial stake of 0. Other methods can validate that a quorum exists by checking whether `_totalStakeHistory[quorumNumber]` has a nonzero length. Additionally, this method configures a `minimumStake` for the quorum, as well as the `StrategyParams` it considers when calculating stake weight. *Entry Points*: -* `RegistryCoordinator.createQuorum` +* `RegistryCoordinator.createDelegatedStakeQuorum` + +*Effects*: +* See `addStrategies` below +* See `setMinimumStakeForQuorum` below +* Pushes a `StakeUpdate` to `_totalStakeHistory[quorumNumber]`. The update's `updateBlockNumber` is set to the current block, and `stake` is set to 0. + +*Requirements*: +* Caller MUST be the `RegistryCoordinator` +* `quorumNumber` MUST NOT belong to an existing, initialized quorum +* See `addStrategies` below +* See `setMinimumStakeForQuorum` below + +#### `initializeSlashableStakeQuorum` + +```solidity +function initializeSlashableStakeQuorum( + uint8 quorumNumber, + uint96 minimumStake, + uint32 lookAheadPeriod, + StrategyParams[] memory _strategyParams +) + public + virtual + onlyRegistryCoordinator + +struct StrategyParams { + IStrategy strategy; + uint96 multiplier; +} +``` + +This method is ONLY callable by the `RegistryCoordinator`, and is called when the `RegistryCoordinator` Owner creates a new slashable stake quorum. + +`initializeSlashableStakeQuorum` initializes a new quorum by pushing an initial `StakeUpdate` to `_totalStakeHistory[quorumNumber]`, with an initial stake of 0. Other methods can validate that a quorum exists by checking whether `_totalStakeHistory[quorumNumber]` has a nonzero length. + +This method configures a `minimumStake` for the quorum, defines the `StrategyParams` used when calculating stake weight and sets the `lookAheadPeriod` which defines how many blocks ahead to when considering the minimum amount of slahable stake. Note that `lookAheadPeriod` should be less than the `DEALLOCATION_DELAY` (14 days within the `AllocationManager`) blocks in the future, or the values returned from this method may inaccurate due to deallocations. + +*Entry Points*: +* `RegistryCoordinator.createSlashableStakeQuorum` *Effects*: * See `addStrategies` below * See `setMinimumStakeForQuorum` below +* See `setSlashableLookAhead` below * Pushes a `StakeUpdate` to `_totalStakeHistory[quorumNumber]`. The update's `updateBlockNumber` is set to the current block, and `stake` is set to 0. + *Requirements*: * Caller MUST be the `RegistryCoordinator` * `quorumNumber` MUST NOT belong to an existing, initialized quorum @@ -336,4 +380,27 @@ Allows the `RegistryCoordinator` Owner to modify the multipliers specified in a * `strategyIndices` MUST NOT be empty * `strategyIndices` and `newMultipliers` MUST have equal lengths + +#### `setSlashableLookAhead` + +```solidity +function setSlashableStakeLookahead( + uint8 quorumNumber, + uint32 _lookAheadBlocks +) + external + onlyCoordinatorOwner + quorumExists(quorumNumber) +``` + +Allows the `RegistryCoordinator` Owner to modify the slashable lookahead for a slashable stake quorum. + +*Effects* +* The quorum's `SlashablableStakeLookAhead` is updated to `_lookAheadBlocks` + +*Requirements* +* Caller MUST be `RegistryCoordinator.owner()` +* `quorumNumber` MUST belong to an existing initialized quorum +* `quorumNumber` MUST map to a slashable stake quorum + --- \ No newline at end of file From 09eda05d0c4093585a35c85939540cb4af705292 Mon Sep 17 00:00:00 2001 From: JES Date: Wed, 5 Mar 2025 16:52:28 -0800 Subject: [PATCH 3/5] docs: add socket registry --- docs/registries/SocketRegistry.md | 44 +++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 docs/registries/SocketRegistry.md diff --git a/docs/registries/SocketRegistry.md b/docs/registries/SocketRegistry.md new file mode 100644 index 000000000..7e1a11e9f --- /dev/null +++ b/docs/registries/SocketRegistry.md @@ -0,0 +1,44 @@ +## SocketRegistry + +| File | Type | Proxy | +| -------- | -------- | -------- | +| [`SocketRegistry.sol`](../src/SocketRegistry.sol) | Singleton | Transparent proxy | + +The `SocketRegistry` is a simple registry contract that keeps track of operator sockets (arbitrary strings). This socket could represent network connection information such as IP addresses, ports, or other connectivity details. + +#### High-level Concepts + +This registry maintains a mapping between operator IDs (represented as bytes32 values) and their corresponding socket information. The contract is designed to work in conjunction with the `SlashingRegistryCoordinator`, which is the only entity authorized to update socket information for operators. + +This document organizes methods according to the following themes: +* [Socket Management](#socket-management) + +--- + +### Socket Management + +These methods allow for managing operator socket information: +* [`setOperatorSocket`](#setoperatorsocket) +* [`getOperatorSocket`](#getoperatorsocket) + +#### `setOperatorSocket` + +```solidity +function setOperatorSocket( + bytes32 _operatorId, + string memory _socket +) + external + onlySlashingRegistryCoordinator +``` + +Sets a socket string with an operator ID (hash of the G1 BLS public key) in the registry. This function is called by the `SlashingRegistryCoordinator`. + +*Entry Points:* +Called by the `SlashingRegistryCoordinator` when an operator is registered or needs to update their socket information + +*Effects:* +* Sets operatorIdToSocket[_operatorId] to the provided `_socket` string + +*Requirements:* +* Caller MUST be the `SlashingRegistryCoordinator` \ No newline at end of file From f122460524b9df82d430a93d3dc42056eb242f0a Mon Sep 17 00:00:00 2001 From: JES Date: Thu, 6 Mar 2025 08:08:34 -0800 Subject: [PATCH 4/5] chore: touch up socket registry --- docs/registries/SocketRegistry.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/registries/SocketRegistry.md b/docs/registries/SocketRegistry.md index 7e1a11e9f..d15ddfd71 100644 --- a/docs/registries/SocketRegistry.md +++ b/docs/registries/SocketRegistry.md @@ -8,7 +8,7 @@ The `SocketRegistry` is a simple registry contract that keeps track of operator #### High-level Concepts -This registry maintains a mapping between operator IDs (represented as bytes32 values) and their corresponding socket information. The contract is designed to work in conjunction with the `SlashingRegistryCoordinator`, which is the only entity authorized to update socket information for operators. +This registry maintains a mapping between operator IDs (represented as bytes32 values) and their corresponding socket information. The contract is designed to work in conjunction with the `SlashingRegistryCoordinator`, which is the only contract authorized to update socket information for operators. This document organizes methods according to the following themes: * [Socket Management](#socket-management) @@ -19,7 +19,6 @@ This document organizes methods according to the following themes: These methods allow for managing operator socket information: * [`setOperatorSocket`](#setoperatorsocket) -* [`getOperatorSocket`](#getoperatorsocket) #### `setOperatorSocket` From baeafa9bec0f01b3ee6ecfd3a15cafd6e12281be Mon Sep 17 00:00:00 2001 From: JES Date: Fri, 7 Mar 2025 09:00:43 -0800 Subject: [PATCH 5/5] chore: fix up small logic errors in stakeregistry --- docs/registries/StakeRegistry.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/registries/StakeRegistry.md b/docs/registries/StakeRegistry.md index f43404b1b..b83ea47c5 100644 --- a/docs/registries/StakeRegistry.md +++ b/docs/registries/StakeRegistry.md @@ -245,7 +245,7 @@ This method is ONLY callable by the `RegistryCoordinator`, and is called when th `initializeSlashableStakeQuorum` initializes a new quorum by pushing an initial `StakeUpdate` to `_totalStakeHistory[quorumNumber]`, with an initial stake of 0. Other methods can validate that a quorum exists by checking whether `_totalStakeHistory[quorumNumber]` has a nonzero length. -This method configures a `minimumStake` for the quorum, defines the `StrategyParams` used when calculating stake weight and sets the `lookAheadPeriod` which defines how many blocks ahead to when considering the minimum amount of slahable stake. Note that `lookAheadPeriod` should be less than the `DEALLOCATION_DELAY` (14 days within the `AllocationManager`) blocks in the future, or the values returned from this method may inaccurate due to deallocations. +This method configures a `minimumStake` for the quorum, defines the `StrategyParams` used when calculating stake weight and sets the `lookAheadPeriod` which defines how many blocks ahead to when considering the minimum amount of slahable stake. Note that `lookAheadPeriod` should be less than the `DEALLOCATION_DELAY` (14 days within the `AllocationManager`) blocks in the future, to avoid calculating stake values that may not reflect the operators true allocated stake. *Entry Points*: * `RegistryCoordinator.createSlashableStakeQuorum`