|
| 1 | +# ReleaseManager |
| 2 | + |
| 3 | +| File | Notes | |
| 4 | +| -------- | -------- | |
| 5 | +| [`ReleaseManager.sol`](../../src/contracts/core/ReleaseManager.sol) | | |
| 6 | +| [`ReleaseManagerStorage.sol`](../../src/contracts/core/ReleaseManagerStorage.sol) | state variables | |
| 7 | +| [`IReleaseManager.sol`](../../src/contracts/interfaces/IReleaseManager.sol) | interface | |
| 8 | + |
| 9 | +Libraries and Mixins: |
| 10 | + |
| 11 | +| File | Notes | |
| 12 | +| -------- | -------- | |
| 13 | +| [`PermissionControllerMixin.sol`](../../src/contracts/mixins/PermissionControllerMixin.sol) | account delegation | |
| 14 | +| [`SemVerMixin.sol`](../../src/contracts/mixins/SemVerMixin.sol) | semantic versioning | |
| 15 | +| [`OperatorSetLib.sol`](../../src/contracts/libraries/OperatorSetLib.sol) | encode/decode operator sets | |
| 16 | + |
| 17 | +## Overview |
| 18 | + |
| 19 | +The `ReleaseManager` manages software releases for AVS operator sets. It provides a standardized way for AVSs to publish software artifacts (binaries, docker images, etc.) that operators in their operator sets should upgrade to by specified deadlines. This ensures operators run compatible and up-to-date software versions required by the AVS. |
| 20 | + |
| 21 | +The `ReleaseManager's` responsibilities include: |
| 22 | + |
| 23 | +* **Release Publishing**: AVSs can publish new releases containing one or more software artifacts for their operator sets. |
| 24 | +* **Upgrade Deadlines**: Each release specifies a deadline by which operators must upgrade. |
| 25 | +* **Release Tracking**: Maintains a history of all releases for each operator set. |
| 26 | +* **Release Queries**: Provides view functions to query release information. |
| 27 | + |
| 28 | +An AVS in the context of `ReleaseManager` is defined as the `address` of the contract that implements the AVS logic. For `PermissionController` purposes, this AVS address is also the AVS [account](https://github.com/Layr-Labs/eigenlayer-contracts/blob/dev/docs/permissions/PermissionController.md#accounts). |
| 29 | + |
| 30 | +### Important Notes on Release Management |
| 31 | + |
| 32 | +* **Latest Release Validity**: Only the latest release for an operator set is considered valid. Previous releases become obsolete as soon as a new release is published. |
| 33 | +* **Upgrade Deadlines**: The `upgradeByTime` timestamp (in Unix time) is a suggested deadline and is not enforced on-chain or off-chain. It serves as a communication mechanism for AVSs to indicate when operators should complete their upgrades. |
| 34 | +* **Multiple Releases in Same Block**: If multiple releases are published in the same block with the same `upgradeByTime`, the last transaction processed in that block will determine the latest valid release. |
| 35 | + |
| 36 | +--- |
| 37 | + |
| 38 | +## Releases |
| 39 | + |
| 40 | +A release represents a collection of software artifacts that operators in an operator set must run. Each release is associated with a specific operator set and contains: |
| 41 | + |
| 42 | +* **Artifacts**: An array of software artifacts, each with a digest (hash) and registry URL |
| 43 | +* **Upgrade By Time**: A Unix timestamp by which operators should complete the upgrade |
| 44 | + |
| 45 | +The release structure is defined as: |
| 46 | + |
| 47 | +```solidity |
| 48 | +/** |
| 49 | + * @notice Represents a software artifact with its digest and registry URL. |
| 50 | + * @param digest The hash digest of the artifact. |
| 51 | + * @param registryUrl The URL where the artifact can be found. |
| 52 | + */ |
| 53 | +struct Artifact { |
| 54 | + bytes32 digest; |
| 55 | + string registryUrl; |
| 56 | +} |
| 57 | +
|
| 58 | +/** |
| 59 | + * @notice Represents a release containing multiple artifacts and an upgrade deadline. |
| 60 | + * @param artifacts Array of artifacts included in this release. |
| 61 | + * @param upgradeByTime Timestamp by which operators must upgrade to this release. |
| 62 | + */ |
| 63 | +struct Release { |
| 64 | + Artifact[] artifacts; |
| 65 | + uint32 upgradeByTime; |
| 66 | +} |
| 67 | +``` |
| 68 | + |
| 69 | +**State Management:** |
| 70 | + |
| 71 | +```solidity |
| 72 | +/// @dev Mapping from operator set key to array of releases for that operator set |
| 73 | +mapping(bytes32 operatorSetKey => Release[]) internal _operatorSetReleases; |
| 74 | +``` |
| 75 | + |
| 76 | +**Methods:** |
| 77 | +* [`publishRelease`](#publishrelease) |
| 78 | +* [`getTotalReleases`](#gettotalreleases) |
| 79 | +* [`getRelease`](#getrelease) |
| 80 | +* [`getLatestRelease`](#getlatestrelease) |
| 81 | +* [`getLatestUpgradeByTime`](#getlatestupgradebytime) |
| 82 | +* [`isValidRelease`](#isValidRelease) |
| 83 | + |
| 84 | +--- |
| 85 | + |
| 86 | +### Write Functions |
| 87 | + |
| 88 | +#### `publishRelease` |
| 89 | + |
| 90 | +```solidity |
| 91 | +/** |
| 92 | + * @notice Publishes a new release for an operator set. |
| 93 | + * @param operatorSet The operator set this release is for. |
| 94 | + * @param release The release that was published. |
| 95 | + * @return releaseId The index of the newly published release. |
| 96 | + */ |
| 97 | +function publishRelease( |
| 98 | + OperatorSet calldata operatorSet, |
| 99 | + Release calldata release |
| 100 | +) |
| 101 | + external |
| 102 | + checkCanCall(operatorSet.avs) |
| 103 | + returns (uint256 releaseId) |
| 104 | +``` |
| 105 | + |
| 106 | +_Note: this method can be called directly by an AVS, or by a caller authorized by the AVS. See [`PermissionController.md`](../permissions/PermissionController.md) for details._ |
| 107 | + |
| 108 | +AVSs use this method to publish new software releases for their operator sets. Each release contains one or more artifacts that represent the software components operators must run (e.g., validator clients, network monitors, etc.). The AVS specifies a deadline (`upgradeByTime`) by which all operators in the operator set must upgrade to the new release. |
| 109 | + |
| 110 | +The `releaseId` returned is the zero-based index of the release in the operator set's release array. This ID can be used to query the release later using [`getRelease`](#getrelease). |
| 111 | + |
| 112 | +*Effects*: |
| 113 | +* Appends the release to `_operatorSetReleases[operatorSet.key()]` |
| 114 | +* The new release is assigned a `releaseId` equal to the previous array length |
| 115 | +* All artifact information (digest and registryUrl) is copied to storage |
| 116 | +* Emits a `ReleasePublished` event with the operator set, release ID, and release details |
| 117 | + |
| 118 | +*Requirements*: |
| 119 | +* Caller MUST be authorized, either as the AVS itself or an admin/appointee (see [`PermissionController.md`](../permissions/PermissionController.md)) |
| 120 | +* `release.upgradeByTime` MUST be greater than or equal to the current block timestamp |
| 121 | +--- |
| 122 | + |
| 123 | +### View Functions |
| 124 | + |
| 125 | +#### `getTotalReleases` |
| 126 | + |
| 127 | +```solidity |
| 128 | +/** |
| 129 | + * @notice Returns the total number of releases for an operator set. |
| 130 | + * @param operatorSet The operator set to query. |
| 131 | + * @return The number of releases. |
| 132 | + */ |
| 133 | +function getTotalReleases( |
| 134 | + OperatorSet memory operatorSet |
| 135 | +) |
| 136 | + public |
| 137 | + view |
| 138 | + returns (uint256) |
| 139 | +``` |
| 140 | + |
| 141 | +Returns the total number of releases that have been published for the specified operator set. This can be used to iterate through all releases or to determine if any releases exist. |
| 142 | + |
| 143 | +*Returns*: |
| 144 | +* The length of the releases array for the given operator set |
| 145 | +* Returns 0 if no releases have been published |
| 146 | + |
| 147 | +#### `getRelease` |
| 148 | + |
| 149 | +```solidity |
| 150 | +/** |
| 151 | + * @notice Returns a specific release by index. |
| 152 | + * @param operatorSet The operator set to query. |
| 153 | + * @param releaseId The id of the release to get. |
| 154 | + * @return The release at the specified index. |
| 155 | + */ |
| 156 | +function getRelease( |
| 157 | + OperatorSet memory operatorSet, |
| 158 | + uint256 releaseId |
| 159 | +) |
| 160 | + external |
| 161 | + view |
| 162 | + returns (Release memory) |
| 163 | +``` |
| 164 | + |
| 165 | +Retrieves a specific release by its ID for a given operator set. The `releaseId` is the zero-based index of the release in the operator set's release history. |
| 166 | + |
| 167 | +*Returns*: |
| 168 | +* The complete `Release` struct including all artifacts and the upgrade deadline |
| 169 | +* Reverts if `releaseId` is out of bounds |
| 170 | + |
| 171 | +#### `getLatestRelease` |
| 172 | + |
| 173 | +```solidity |
| 174 | +/** |
| 175 | + * @notice Returns the latest release for an operator set. |
| 176 | + * @param operatorSet The operator set to query. |
| 177 | + * @return The id of the latest release. |
| 178 | + * @return The latest release. |
| 179 | + */ |
| 180 | +function getLatestRelease( |
| 181 | + OperatorSet memory operatorSet |
| 182 | +) |
| 183 | + public |
| 184 | + view |
| 185 | + returns (uint256, Release memory) |
| 186 | +``` |
| 187 | + |
| 188 | +Retrieves the most recently published release for an operator set. This is typically the release that operators should be running or upgrading to. |
| 189 | + |
| 190 | +*Returns*: |
| 191 | +* The latest `Release` struct from the operator set's release array |
| 192 | +* Reverts if no releases have been published for the operator set |
| 193 | + |
| 194 | +#### `getLatestUpgradeByTime` |
| 195 | + |
| 196 | +```solidity |
| 197 | +/** |
| 198 | + * @notice Returns the upgrade by time for the latest release. |
| 199 | + * @param operatorSet The operator set to query. |
| 200 | + * @return The upgrade by time for the latest release. |
| 201 | + */ |
| 202 | +function getLatestUpgradeByTime( |
| 203 | + OperatorSet memory operatorSet |
| 204 | +) |
| 205 | + external |
| 206 | + view |
| 207 | + returns (uint256) |
| 208 | +``` |
| 209 | + |
| 210 | +A convenience function that returns just the upgrade deadline from the latest release. This can be useful for quickly checking when operators must complete their upgrades. |
| 211 | + |
| 212 | +*Returns*: |
| 213 | +* The `upgradeByTime` timestamp from the latest release |
| 214 | +* Reverts if no releases have been published for the operator set |
| 215 | + |
| 216 | +#### `isValidRelease` |
| 217 | + |
| 218 | +```solidity |
| 219 | +/** |
| 220 | + * @notice Returns true if the release is the latest release, false otherwise. |
| 221 | + * @param operatorSet The operator set to query. |
| 222 | + * @param releaseId The id of the release to check. |
| 223 | + * @return True if the release is the latest release, false otherwise. |
| 224 | + */ |
| 225 | +function isValidRelease( |
| 226 | + OperatorSet memory operatorSet, |
| 227 | + uint256 releaseId |
| 228 | +) |
| 229 | + external |
| 230 | + view |
| 231 | + returns (bool) |
| 232 | +``` |
| 233 | + |
| 234 | +Checks whether a given release ID corresponds to the latest release for an operator set. This can be useful for operators to verify they are running the most current software version. |
| 235 | + |
| 236 | +**Note**: Only the latest release is considered valid. All previous releases are considered obsolete and should not be used by operators. |
| 237 | + |
| 238 | +*Returns*: |
| 239 | +* `true` if the `releaseId` matches the latest release index |
| 240 | +* `false` if the `releaseId` refers to an older release |
| 241 | +* Reverts if the operator set has no releases |
| 242 | + |
| 243 | +--- |
0 commit comments