From 11c51e1007e9e5c4159fa9064e47ef9d0df5fab1 Mon Sep 17 00:00:00 2001 From: ChaoticWalrus <93558947+ChaoticWalrus@users.noreply.github.com> Date: Mon, 11 Dec 2023 17:04:31 -0800 Subject: [PATCH] feat: create struct for pubkey registration params note: code is currently not compiling due to a stack-too-deep error error here: src/RegistryCoordinator.sol:254:69: | 254 | _deregisterOperator(operatorKickParams[i].operator, quorumNumbers[i:i+1]); --- src/BLSApkRegistry.sol | 30 +++--- src/RegistryCoordinator.sol | 20 +++- src/interfaces/IBLSApkRegistry.sol | 41 +++++---- test/ffi/BLSPubKeyCompendiumFFI.t.sol | 19 ++-- test/unit/BLSApkRegistryUnit.t.sol | 42 +++++---- test/unit/RegistryCoordinatorUnit.t.sol | 117 ++++++++++-------------- test/utils/MockAVSDeployer.sol | 14 +-- 7 files changed, 139 insertions(+), 144 deletions(-) diff --git a/src/BLSApkRegistry.sol b/src/BLSApkRegistry.sol index 880ef9c2..03abe2b5 100644 --- a/src/BLSApkRegistry.sol +++ b/src/BLSApkRegistry.sol @@ -96,17 +96,13 @@ contract BLSApkRegistry is BLSApkRegistryStorage { /** * @notice Called by the RegistryCoordinator register an operator as the owner of a BLS public key. * @param operator is the operator for whom the key is being registered - * @param signedMessageHash is the registration message hash signed by the private key of the operator - * @param pubkeyG1 is the corresponding G1 public key of the operator - * @param pubkeyG2 is the corresponding G2 public key of the operator + * @param pubkeyRegistrationParams contains the G1 & G2 public keys of the operator, and a signature proving their ownership */ function registerBLSPublicKey( address operator, - BN254.G1Point memory signedMessageHash, - BN254.G1Point memory pubkeyG1, - BN254.G2Point memory pubkeyG2 + PubkeyRegistrationParams calldata pubkeyRegistrationParams ) external onlyRegistryCoordinator { - bytes32 pubkeyHash = BN254.hashG1Point(pubkeyG1); + bytes32 pubkeyHash = BN254.hashG1Point(pubkeyRegistrationParams.pubkeyG1); require( pubkeyHash != ZERO_PK_HASH, "BLSApkRegistry.registerBLSPublicKey: cannot register zero pubkey" ); @@ -124,29 +120,29 @@ contract BLSApkRegistry is BLSApkRegistryStorage { // gamma = h(sigma, P, P', H(m)) uint256 gamma = uint256(keccak256(abi.encodePacked( - signedMessageHash.X, - signedMessageHash.Y, - pubkeyG1.X, - pubkeyG1.Y, - pubkeyG2.X, - pubkeyG2.Y, + pubkeyRegistrationParams.pubkeyRegistrationSignature.X, + pubkeyRegistrationParams.pubkeyRegistrationSignature.Y, + pubkeyRegistrationParams.pubkeyG1.X, + pubkeyRegistrationParams.pubkeyG1.Y, + pubkeyRegistrationParams.pubkeyG2.X, + pubkeyRegistrationParams.pubkeyG2.Y, messageHash.X, messageHash.Y ))) % BN254.FR_MODULUS; // e(sigma + P * gamma, [-1]_2) = e(H(m) + [1]_1 * gamma, P') require(BN254.pairing( - signedMessageHash.plus(pubkeyG1.scalar_mul(gamma)), + pubkeyRegistrationParams.pubkeyRegistrationSignature.plus(pubkeyRegistrationParams.pubkeyG1.scalar_mul(gamma)), BN254.negGeneratorG2(), messageHash.plus(BN254.generatorG1().scalar_mul(gamma)), - pubkeyG2 + pubkeyRegistrationParams.pubkeyG2 ), "BLSApkRegistry.registerBLSPublicKey: either the G1 signature is wrong, or G1 and G2 private key do not match"); - operatorToPubkey[operator] = pubkeyG1; + operatorToPubkey[operator] = pubkeyRegistrationParams.pubkeyG1; operatorToPubkeyHash[operator] = pubkeyHash; pubkeyHashToOperator[pubkeyHash] = operator; - emit NewPubkeyRegistration(operator, pubkeyG1, pubkeyG2); + emit NewPubkeyRegistration(operator, pubkeyRegistrationParams.pubkeyG1, pubkeyRegistrationParams.pubkeyG2); } /******************************************************************************* diff --git a/src/RegistryCoordinator.sol b/src/RegistryCoordinator.sol index 31398cae..68b5d4bd 100644 --- a/src/RegistryCoordinator.sol +++ b/src/RegistryCoordinator.sol @@ -147,20 +147,20 @@ contract RegistryCoordinator is EIP712, Initializable, IRegistryCoordinator, ISo * @notice Registers msg.sender as an operator for one or more quorums. If any quorum reaches its maximum * operator capacity, this method will fail. * @param quorumNumbers is an ordered byte array containing the quorum numbers being registered for + * @param pubkeyRegistrationParams contains the G1 & G2 public keys of the operator, and a signature proving their ownership + * @dev the `pubkeyRegistrationParams` input param is ignored if the caller has previously registered a public key */ function registerOperator( bytes calldata quorumNumbers, string calldata socket, - BN254.G1Point memory pubkeyRegistrationSignature, - BN254.G1Point memory pubkeyG1, - BN254.G2Point memory pubkeyG2 + IBLSApkRegistry.PubkeyRegistrationParams calldata pubkeyRegistrationParams ) external onlyWhenNotPaused(PAUSED_REGISTER_OPERATOR) { /** * IF the operator has never registered a pubkey before, THEN register their pubkey - * OTHERWISE, simply ignore the `pubkeyRegistrationSignature`, `pubkeyG1`, and `pubkeyG2` inputs + * OTHERWISE, simply ignore the provided `pubkeyRegistrationParams` */ if (blsApkRegistry.operatorToPubkeyHash(msg.sender) == 0) { - blsApkRegistry.registerBLSPublicKey(msg.sender, pubkeyRegistrationSignature, pubkeyG1, pubkeyG2); + blsApkRegistry.registerBLSPublicKey(msg.sender, pubkeyRegistrationParams); } bytes32 operatorId = blsApkRegistry.getOperatorId(msg.sender); @@ -192,18 +192,28 @@ contract RegistryCoordinator is EIP712, Initializable, IRegistryCoordinator, ISo * @notice Registers msg.sender as an operator for one or more quorums. If any quorum reaches its maximum operator * capacity, `operatorKickParams` is used to replace an old operator with the new one. * @param quorumNumbers is an ordered byte array containing the quorum numbers being registered for + * @param pubkeyRegistrationParams contains the G1 & G2 public keys of the operator, and a signature proving their ownership * @param operatorKickParams are used to determine which operator is removed to maintain quorum capacity as the * operator registers for quorums. * @param churnApproverSignature is the signature of the churnApprover on the operator kick params + * @dev the `pubkeyRegistrationParams` input param is ignored if the caller has previously registered a public key */ function registerOperatorWithChurn( bytes calldata quorumNumbers, string calldata socket, + IBLSApkRegistry.PubkeyRegistrationParams calldata pubkeyRegistrationParams, OperatorKickParam[] calldata operatorKickParams, SignatureWithSaltAndExpiry memory churnApproverSignature ) external onlyWhenNotPaused(PAUSED_REGISTER_OPERATOR) { require(operatorKickParams.length == quorumNumbers.length, "RegistryCoordinator.registerOperatorWithChurn: input length mismatch"); + /** + * IF the operator has never registered a pubkey before, THEN register their pubkey + * OTHERWISE, simply ignore the `pubkeyRegistrationSignature`, `pubkeyG1`, and `pubkeyG2` inputs + */ + if (blsApkRegistry.operatorToPubkeyHash(msg.sender) == 0) { + blsApkRegistry.registerBLSPublicKey(msg.sender, pubkeyRegistrationParams); + } bytes32 operatorId = blsApkRegistry.getOperatorId(msg.sender); // Verify the churn approver's signature for the registering operator and kick params diff --git a/src/interfaces/IBLSApkRegistry.sol b/src/interfaces/IBLSApkRegistry.sol index af241658..3c5a0c27 100644 --- a/src/interfaces/IBLSApkRegistry.sol +++ b/src/interfaces/IBLSApkRegistry.sol @@ -10,6 +10,29 @@ import {BN254} from "src/libraries/BN254.sol"; * @author Layr Labs, Inc. */ interface IBLSApkRegistry is IRegistry { + // STRUCTS + /// @notice Data structure used to track the history of the Aggregate Public Key of all operators + struct ApkUpdate { + // first 24 bytes of keccak256(apk_x0, apk_x1, apk_y0, apk_y1) + bytes24 apkHash; + // block number at which the update occurred + uint32 updateBlockNumber; + // block number at which the next update occurred + uint32 nextUpdateBlockNumber; + } + + /** + * @notice Struct used when registering a new public key + * @param signedMessageHash is the registration message hash signed by the private key of the operator + * @param pubkeyG1 is the corresponding G1 public key of the operator + * @param pubkeyG2 is the corresponding G2 public key of the operator + */ + struct PubkeyRegistrationParams { + BN254.G1Point pubkeyRegistrationSignature; + BN254.G1Point pubkeyG1; + BN254.G2Point pubkeyG2; + } + // EVENTS /// @notice Emitted when `operator` registers with the public keys `pubkeyG1` and `pubkeyG2`. event NewPubkeyRegistration(address indexed operator, BN254.G1Point pubkeyG1, BN254.G2Point pubkeyG2); @@ -26,16 +49,6 @@ interface IBLSApkRegistry is IRegistry { bytes quorumNumbers ); - /// @notice Data structure used to track the history of the Aggregate Public Key of all operators - struct ApkUpdate { - // first 24 bytes of keccak256(apk_x0, apk_x1, apk_y0, apk_y1) - bytes24 apkHash; - // block number at which the update occurred - uint32 updateBlockNumber; - // block number at which the next update occurred - uint32 nextUpdateBlockNumber; - } - /** * @notice Registers the `operator`'s pubkey for the specified `quorumNumbers`. * @param operator The address of the operator to register. @@ -85,15 +98,11 @@ interface IBLSApkRegistry is IRegistry { /** * @notice Called by the RegistryCoordinator register an operator as the owner of a BLS public key. * @param operator is the operator for whom the key is being registered - * @param signedMessageHash is the registration message hash signed by the private key of the operator - * @param pubkeyG1 is the corresponding G1 public key of the operator - * @param pubkeyG2 is the corresponding G2 public key of the operator + * @param pubkeyRegistrationParams contains the G1 & G2 public keys of the operator, and a signature proving their ownership */ function registerBLSPublicKey( address operator, - BN254.G1Point memory signedMessageHash, - BN254.G1Point memory pubkeyG1, - BN254.G2Point memory pubkeyG2 + PubkeyRegistrationParams calldata pubkeyRegistrationParams ) external; /** diff --git a/test/ffi/BLSPubKeyCompendiumFFI.t.sol b/test/ffi/BLSPubKeyCompendiumFFI.t.sol index 39121a96..0910ab5d 100644 --- a/test/ffi/BLSPubKeyCompendiumFFI.t.sol +++ b/test/ffi/BLSPubKeyCompendiumFFI.t.sol @@ -3,6 +3,7 @@ pragma solidity =0.8.12; import "src/BLSApkRegistry.sol"; import "test/ffi/util/G2Operations.sol"; +import {IBLSApkRegistry} from "src/interfaces/IBLSApkRegistry.sol"; contract BLSApkRegistryFFITests is G2Operations { using BN254 for BN254.G1Point; @@ -14,9 +15,7 @@ contract BLSApkRegistryFFITests is G2Operations { IRegistryCoordinator registryCoordinator; uint256 privKey; - BN254.G1Point pubKeyG1; - BN254.G2Point pubKeyG2; - BN254.G1Point signedMessageHash; + IBLSApkRegistry.PubkeyRegistrationParams pubkeyRegistrationParams; address alice = address(0x69); @@ -28,19 +27,21 @@ contract BLSApkRegistryFFITests is G2Operations { cheats.assume(_privKey != 0); _setKeys(_privKey); - signedMessageHash = _signMessage(alice); + pubkeyRegistrationParams.pubkeyRegistrationSignature = _signMessage(alice); vm.prank(address(registryCoordinator)); - blsApkRegistry.registerBLSPublicKey(alice, signedMessageHash, pubKeyG1, pubKeyG2); + blsApkRegistry.registerBLSPublicKey(alice, pubkeyRegistrationParams); - assertEq(blsApkRegistry.operatorToPubkeyHash(alice), BN254.hashG1Point(pubKeyG1), "pubkey hash not stored correctly"); - assertEq(blsApkRegistry.pubkeyHashToOperator(BN254.hashG1Point(pubKeyG1)), alice, "operator address not stored correctly"); + assertEq(blsApkRegistry.operatorToPubkeyHash(alice), BN254.hashG1Point(pubkeyRegistrationParams.pubkeyG1), + "pubkey hash not stored correctly"); + assertEq(blsApkRegistry.pubkeyHashToOperator(BN254.hashG1Point(pubkeyRegistrationParams.pubkeyG1)), alice, + "operator address not stored correctly"); } function _setKeys(uint256 _privKey) internal { privKey = _privKey; - pubKeyG1 = BN254.generatorG1().scalar_mul(_privKey); - pubKeyG2 = G2Operations.mul(_privKey); + pubkeyRegistrationParams.pubkeyG1 = BN254.generatorG1().scalar_mul(_privKey); + pubkeyRegistrationParams.pubkeyG2 = G2Operations.mul(_privKey); } function _signMessage(address signer) internal view returns(BN254.G1Point memory) { diff --git a/test/unit/BLSApkRegistryUnit.t.sol b/test/unit/BLSApkRegistryUnit.t.sol index 493a44d4..683d59ff 100644 --- a/test/unit/BLSApkRegistryUnit.t.sol +++ b/test/unit/BLSApkRegistryUnit.t.sol @@ -21,9 +21,7 @@ contract BLSApkRegistryUnitTests is Test { BN254.G1Point internal defaultPubKey = BN254.G1Point(18260007818883133054078754218619977578772505796600400998181738095793040006897,3432351341799135763167709827653955074218841517684851694584291831827675065899); - BN254.G1Point pubKeyG1; - BN254.G2Point pubKeyG2; - BN254.G1Point signedMessageHash; + IBLSApkRegistry.PubkeyRegistrationParams pubkeyRegistrationParams; address alice = address(1); address bob = address(2); @@ -39,13 +37,13 @@ contract BLSApkRegistryUnitTests is Test { registryCoordinator = new RegistryCoordinatorMock(); blsApkRegistry = new BLSApkRegistryHarness(registryCoordinator); - pubKeyG1 = BN254.generatorG1().scalar_mul(privKey); + pubkeyRegistrationParams.pubkeyG1 = BN254.generatorG1().scalar_mul(privKey); //privKey*G2 - pubKeyG2.X[1] = 19101821850089705274637533855249918363070101489527618151493230256975900223847; - pubKeyG2.X[0] = 5334410886741819556325359147377682006012228123419628681352847439302316235957; - pubKeyG2.Y[1] = 354176189041917478648604979334478067325821134838555150300539079146482658331; - pubKeyG2.Y[0] = 4185483097059047421902184823581361466320657066600218863748375739772335928910; + pubkeyRegistrationParams.pubkeyG2.X[1] = 19101821850089705274637533855249918363070101489527618151493230256975900223847; + pubkeyRegistrationParams.pubkeyG2.X[0] = 5334410886741819556325359147377682006012228123419628681352847439302316235957; + pubkeyRegistrationParams.pubkeyG2.Y[1] = 354176189041917478648604979334478067325821134838555150300539079146482658331; + pubkeyRegistrationParams.pubkeyG2.Y[0] = 4185483097059047421902184823581361466320657066600218863748375739772335928910; // Initialize a quorum @@ -293,29 +291,33 @@ contract BLSApkRegistryUnitTests is Test { // TODO: better organize / integrate tests migrated from `BLSPublicKeyCompendium` unit tests function testRegisterBLSPublicKey() public { - signedMessageHash = _signMessage(alice); + pubkeyRegistrationParams.pubkeyRegistrationSignature = _signMessage(alice); vm.prank(address(registryCoordinator)); - blsApkRegistry.registerBLSPublicKey(alice, signedMessageHash, pubKeyG1, pubKeyG2); + blsApkRegistry.registerBLSPublicKey(alice, pubkeyRegistrationParams); - assertEq(blsApkRegistry.operatorToPubkeyHash(alice), BN254.hashG1Point(pubKeyG1), "pubkey hash not stored correctly"); - assertEq(blsApkRegistry.pubkeyHashToOperator(BN254.hashG1Point(pubKeyG1)), alice, "operator address not stored correctly"); + assertEq(blsApkRegistry.operatorToPubkeyHash(alice), BN254.hashG1Point(pubkeyRegistrationParams.pubkeyG1), + "pubkey hash not stored correctly"); + assertEq(blsApkRegistry.pubkeyHashToOperator(BN254.hashG1Point(pubkeyRegistrationParams.pubkeyG1)), alice, + "operator address not stored correctly"); } function testRegisterBLSPublicKey_NoMatch_Reverts() public { - signedMessageHash = _signMessage(alice); - BN254.G1Point memory badPubKeyG1 = BN254.generatorG1().scalar_mul(420); // mismatch public keys + pubkeyRegistrationParams.pubkeyRegistrationSignature = _signMessage(alice); + BN254.G1Point memory badPubkeyG1 = BN254.generatorG1().scalar_mul(420); // mismatch public keys + + pubkeyRegistrationParams.pubkeyG1 = badPubkeyG1; vm.prank(address(registryCoordinator)); vm.expectRevert(bytes("BLSApkRegistry.registerBLSPublicKey: either the G1 signature is wrong, or G1 and G2 private key do not match")); - blsApkRegistry.registerBLSPublicKey(alice, signedMessageHash, badPubKeyG1, pubKeyG2); + blsApkRegistry.registerBLSPublicKey(alice, pubkeyRegistrationParams); } function testRegisterBLSPublicKey_BadSig_Reverts() public { - signedMessageHash = _signMessage(bob); // sign with wrong private key + pubkeyRegistrationParams.pubkeyRegistrationSignature = _signMessage(bob); // sign with wrong private key vm.prank(address(registryCoordinator)); vm.expectRevert(bytes("BLSApkRegistry.registerBLSPublicKey: either the G1 signature is wrong, or G1 and G2 private key do not match")); - blsApkRegistry.registerBLSPublicKey(alice, signedMessageHash, pubKeyG1, pubKeyG2); + blsApkRegistry.registerBLSPublicKey(alice, pubkeyRegistrationParams); } function testRegisterBLSPublicKey_OpRegistered_Reverts() public { @@ -323,16 +325,16 @@ contract BLSApkRegistryUnitTests is Test { vm.prank(address(registryCoordinator)); vm.expectRevert(bytes("BLSApkRegistry.registerBLSPublicKey: operator already registered pubkey")); - blsApkRegistry.registerBLSPublicKey(alice, signedMessageHash, pubKeyG1, pubKeyG2); + blsApkRegistry.registerBLSPublicKey(alice, pubkeyRegistrationParams); } function testRegisterBLSPublicKey_PkRegistered_Reverts() public { testRegisterBLSPublicKey(); - signedMessageHash = _signMessage(bob); // same private key different operator + pubkeyRegistrationParams.pubkeyRegistrationSignature = _signMessage(bob); // same private key different operator vm.prank(address(registryCoordinator)); vm.expectRevert(bytes("BLSApkRegistry.registerBLSPublicKey: public key already registered")); - blsApkRegistry.registerBLSPublicKey(bob, signedMessageHash, pubKeyG1, pubKeyG2); + blsApkRegistry.registerBLSPublicKey(bob, pubkeyRegistrationParams); } function _signMessage(address signer) internal view returns(BN254.G1Point memory) { diff --git a/test/unit/RegistryCoordinatorUnit.t.sol b/test/unit/RegistryCoordinatorUnit.t.sol index a577df7a..2e88a222 100644 --- a/test/unit/RegistryCoordinatorUnit.t.sol +++ b/test/unit/RegistryCoordinatorUnit.t.sol @@ -115,9 +115,6 @@ contract RegistryCoordinatorUnit is MockAVSDeployer { function testRegisterOperatorWithCoordinator_WhenPaused_Reverts() public { bytes memory emptyQuorumNumbers = new bytes(0); - BN254.G1Point memory pubkeyRegistrationSignature; - BN254.G1Point memory pubkeyG1; - BN254.G2Point memory pubkeyG2; // pause registerOperator cheats.prank(pauser); @@ -125,51 +122,39 @@ contract RegistryCoordinatorUnit is MockAVSDeployer { cheats.startPrank(defaultOperator); cheats.expectRevert(bytes("Pausable: index is paused")); - registryCoordinator.registerOperator(emptyQuorumNumbers, defaultSocket, pubkeyRegistrationSignature, pubkeyG1, pubkeyG2); + registryCoordinator.registerOperator(emptyQuorumNumbers, defaultSocket, pubkeyRegistrationParams); } function testRegisterOperatorWithCoordinator_EmptyQuorumNumbers_Reverts() public { bytes memory emptyQuorumNumbers = new bytes(0); - BN254.G1Point memory pubkeyRegistrationSignature; - BN254.G1Point memory pubkeyG1; - BN254.G2Point memory pubkeyG2; cheats.expectRevert("RegistryCoordinator._registerOperator: bitmap cannot be 0"); cheats.prank(defaultOperator); - registryCoordinator.registerOperator(emptyQuorumNumbers, defaultSocket, pubkeyRegistrationSignature, pubkeyG1, pubkeyG2); + registryCoordinator.registerOperator(emptyQuorumNumbers, defaultSocket, pubkeyRegistrationParams); } function testRegisterOperatorWithCoordinator_QuorumNumbersTooLarge_Reverts() public { bytes memory quorumNumbersTooLarge = new bytes(1); quorumNumbersTooLarge[0] = 0xC0; - BN254.G1Point memory pubkeyRegistrationSignature; - BN254.G1Point memory pubkeyG1; - BN254.G2Point memory pubkeyG2; cheats.expectRevert("BitmapUtils.orderedBytesArrayToBitmap: bitmap exceeds max value"); cheats.prank(defaultOperator); - registryCoordinator.registerOperator(quorumNumbersTooLarge, defaultSocket, pubkeyRegistrationSignature, pubkeyG1, pubkeyG2); + registryCoordinator.registerOperator(quorumNumbersTooLarge, defaultSocket, pubkeyRegistrationParams); } function testRegisterOperatorWithCoordinator_QuorumNotCreated_Reverts() public { _deployMockEigenLayerAndAVS(10); bytes memory quorumNumbersNotCreated = new bytes(1); quorumNumbersNotCreated[0] = 0x0B; - BN254.G1Point memory pubkeyRegistrationSignature; - BN254.G1Point memory pubkeyG1; - BN254.G2Point memory pubkeyG2; cheats.prank(defaultOperator); cheats.expectRevert("BitmapUtils.orderedBytesArrayToBitmap: bitmap exceeds max value"); - registryCoordinator.registerOperator(quorumNumbersNotCreated, defaultSocket, pubkeyRegistrationSignature, pubkeyG1, pubkeyG2); + registryCoordinator.registerOperator(quorumNumbersNotCreated, defaultSocket, pubkeyRegistrationParams); } function testRegisterOperatorWithCoordinatorForSingleQuorum_Valid() public { bytes memory quorumNumbers = new bytes(1); quorumNumbers[0] = bytes1(defaultQuorumNumber); - BN254.G1Point memory pubkeyRegistrationSignature; - BN254.G1Point memory pubkeyG1; - BN254.G2Point memory pubkeyG2; stakeRegistry.setOperatorWeight(uint8(quorumNumbers[0]), defaultOperator, defaultStake); @@ -184,7 +169,7 @@ contract RegistryCoordinatorUnit is MockAVSDeployer { uint256 gasBefore = gasleft(); cheats.prank(defaultOperator); - registryCoordinator.registerOperator(quorumNumbers, defaultSocket, pubkeyRegistrationSignature, pubkeyG1, pubkeyG2); + registryCoordinator.registerOperator(quorumNumbers, defaultSocket, pubkeyRegistrationParams); uint256 gasAfter = gasleft(); emit log_named_uint("gasUsed", gasBefore - gasAfter); @@ -213,9 +198,6 @@ contract RegistryCoordinatorUnit is MockAVSDeployer { quorumBitmap = quorumBitmap & MAX_QUORUM_BITMAP; cheats.assume(quorumBitmap != 0); bytes memory quorumNumbers = BitmapUtils.bitmapToBytesArray(quorumBitmap); - BN254.G1Point memory pubkeyRegistrationSignature; - BN254.G1Point memory pubkeyG1; - BN254.G2Point memory pubkeyG2; for (uint i = 0; i < quorumNumbers.length; i++) { stakeRegistry.setOperatorWeight(uint8(quorumNumbers[i]), defaultOperator, defaultStake); @@ -239,7 +221,7 @@ contract RegistryCoordinatorUnit is MockAVSDeployer { uint256 gasBefore = gasleft(); cheats.prank(defaultOperator); - registryCoordinator.registerOperator(quorumNumbers, defaultSocket, pubkeyRegistrationSignature, pubkeyG1, pubkeyG2); + registryCoordinator.registerOperator(quorumNumbers, defaultSocket, pubkeyRegistrationParams); uint256 gasAfter = gasleft(); emit log_named_uint("gasUsed", gasBefore - gasAfter); emit log_named_uint("numQuorums", quorumNumbers.length); @@ -269,14 +251,11 @@ contract RegistryCoordinatorUnit is MockAVSDeployer { bytes memory quorumNumbers = new bytes(1); quorumNumbers[0] = bytes1(defaultQuorumNumber); - BN254.G1Point memory pubkeyRegistrationSignature; - BN254.G1Point memory pubkeyG1; - BN254.G2Point memory pubkeyG2; stakeRegistry.setOperatorWeight(uint8(quorumNumbers[0]), defaultOperator, defaultStake); cheats.prank(defaultOperator); cheats.roll(registrationBlockNumber); - registryCoordinator.registerOperator(quorumNumbers, defaultSocket, pubkeyRegistrationSignature, pubkeyG1, pubkeyG2); + registryCoordinator.registerOperator(quorumNumbers, defaultSocket, pubkeyRegistrationParams); bytes memory newQuorumNumbers = new bytes(1); newQuorumNumbers[0] = bytes1(defaultQuorumNumber+1); @@ -292,7 +271,7 @@ contract RegistryCoordinatorUnit is MockAVSDeployer { emit QuorumIndexUpdate(defaultOperatorId, uint8(newQuorumNumbers[0]), 0); cheats.roll(nextRegistrationBlockNumber); cheats.prank(defaultOperator); - registryCoordinator.registerOperator(newQuorumNumbers, defaultSocket, pubkeyRegistrationSignature, pubkeyG1, pubkeyG2); + registryCoordinator.registerOperator(newQuorumNumbers, defaultSocket, pubkeyRegistrationParams); uint256 quorumBitmap = BitmapUtils.orderedBytesArrayToBitmap(quorumNumbers) | BitmapUtils.orderedBytesArrayToBitmap(newQuorumNumbers); @@ -329,9 +308,6 @@ contract RegistryCoordinatorUnit is MockAVSDeployer { bytes memory quorumNumbers = new bytes(1); quorumNumbers[0] = bytes1(defaultQuorumNumber); - BN254.G1Point memory pubkeyRegistrationSignature; - BN254.G1Point memory pubkeyG1; - BN254.G2Point memory pubkeyG2; uint256 quorumBitmap = BitmapUtils.orderedBytesArrayToBitmap(quorumNumbers); @@ -353,7 +329,7 @@ contract RegistryCoordinatorUnit is MockAVSDeployer { cheats.prank(operatorToRegister); cheats.expectRevert("RegistryCoordinator.registerOperator: operator count exceeds maximum"); - registryCoordinator.registerOperator(quorumNumbers, defaultSocket, pubkeyRegistrationSignature, pubkeyG1, pubkeyG2); + registryCoordinator.registerOperator(quorumNumbers, defaultSocket, pubkeyRegistrationParams); } function testRegisterOperatorWithCoordinator_RegisteredOperatorForSameQuorums_Reverts() public { @@ -362,19 +338,16 @@ contract RegistryCoordinatorUnit is MockAVSDeployer { bytes memory quorumNumbers = new bytes(1); quorumNumbers[0] = bytes1(defaultQuorumNumber); - BN254.G1Point memory pubkeyRegistrationSignature; - BN254.G1Point memory pubkeyG1; - BN254.G2Point memory pubkeyG2; stakeRegistry.setOperatorWeight(uint8(quorumNumbers[0]), defaultOperator, defaultStake); cheats.prank(defaultOperator); cheats.roll(registrationBlockNumber); - registryCoordinator.registerOperator(quorumNumbers, defaultSocket, pubkeyRegistrationSignature, pubkeyG1, pubkeyG2); + registryCoordinator.registerOperator(quorumNumbers, defaultSocket, pubkeyRegistrationParams); cheats.prank(defaultOperator); cheats.roll(nextRegistrationBlockNumber); cheats.expectRevert("RegistryCoordinator._registerOperator: operator already registered for some quorums being registered for"); - registryCoordinator.registerOperator(quorumNumbers, defaultSocket, pubkeyRegistrationSignature, pubkeyG1, pubkeyG2); + registryCoordinator.registerOperator(quorumNumbers, defaultSocket, pubkeyRegistrationParams); } function testDeregisterOperatorWithCoordinator_WhenPaused_Reverts() public { @@ -424,9 +397,6 @@ contract RegistryCoordinatorUnit is MockAVSDeployer { bytes memory quorumNumbers = new bytes(1); quorumNumbers[0] = bytes1(defaultQuorumNumber); - BN254.G1Point memory pubkeyRegistrationSignature; - BN254.G1Point memory pubkeyG1; - BN254.G2Point memory pubkeyG2; stakeRegistry.setOperatorWeight(uint8(quorumNumbers[0]), defaultOperator, defaultStake); @@ -434,7 +404,7 @@ contract RegistryCoordinatorUnit is MockAVSDeployer { cheats.roll(registrationBlockNumber); - registryCoordinator.registerOperator(quorumNumbers, defaultSocket, pubkeyRegistrationSignature, pubkeyG1, pubkeyG2); + registryCoordinator.registerOperator(quorumNumbers, defaultSocket, pubkeyRegistrationParams); uint256 quorumBitmap = BitmapUtils.orderedBytesArrayToBitmap(quorumNumbers); @@ -471,9 +441,6 @@ contract RegistryCoordinatorUnit is MockAVSDeployer { function testDeregisterOperatorWithCoordinatorForFuzzedQuorumAndSingleOperator_Valid(uint256 quorumBitmap) public { uint32 registrationBlockNumber = 100; uint32 deregistrationBlockNumber = 200; - BN254.G1Point memory pubkeyRegistrationSignature; - BN254.G1Point memory pubkeyG1; - BN254.G2Point memory pubkeyG2; quorumBitmap = quorumBitmap & MAX_QUORUM_BITMAP; cheats.assume(quorumBitmap != 0); @@ -487,7 +454,7 @@ contract RegistryCoordinatorUnit is MockAVSDeployer { cheats.roll(registrationBlockNumber); - registryCoordinator.registerOperator(quorumNumbers, defaultSocket, pubkeyRegistrationSignature, pubkeyG1, pubkeyG2); + registryCoordinator.registerOperator(quorumNumbers, defaultSocket, pubkeyRegistrationParams); cheats.expectEmit(true, true, true, true, address(blsApkRegistry)); emit OperatorRemovedFromQuorums(defaultOperator, quorumNumbers); @@ -604,9 +571,6 @@ contract RegistryCoordinatorUnit is MockAVSDeployer { bytes memory quorumNumbers = new bytes(1); quorumNumbers[0] = bytes1(defaultQuorumNumber); - BN254.G1Point memory pubkeyRegistrationSignature; - BN254.G1Point memory pubkeyG1; - BN254.G2Point memory pubkeyG2; cheats.startPrank(defaultOperator); @@ -617,7 +581,7 @@ contract RegistryCoordinatorUnit is MockAVSDeployer { registryCoordinator.getQuorumBitmapUpdateByIndex(defaultOperatorId, 0); // re-register the operator - registryCoordinator.registerOperator(quorumNumbers, defaultSocket, pubkeyRegistrationSignature, pubkeyG1, pubkeyG2); + registryCoordinator.registerOperator(quorumNumbers, defaultSocket, pubkeyRegistrationParams); // check success of registration uint256 quorumBitmap = BitmapUtils.orderedBytesArrayToBitmap(quorumNumbers); @@ -715,12 +679,16 @@ contract RegistryCoordinatorUnit is MockAVSDeployer { emit QuorumIndexUpdate(operatorToRegisterId, defaultQuorumNumber, numOperators - 1); { + BN254.G1Point memory pubkeyRegistrationSignature; + BN254.G1Point memory pubkeyG1; + BN254.G2Point memory pubkeyG2; ISignatureUtils.SignatureWithSaltAndExpiry memory signatureWithExpiry = _signOperatorChurnApproval(operatorToRegisterId, operatorKickParams, defaultSalt, block.timestamp + 10); cheats.prank(operatorToRegister); uint256 gasBefore = gasleft(); registryCoordinator.registerOperatorWithChurn( quorumNumbers, - defaultSocket, + defaultSocket, + pubkeyRegistrationParams, operatorKickParams, signatureWithExpiry ); @@ -769,7 +737,13 @@ contract RegistryCoordinatorUnit is MockAVSDeployer { ISignatureUtils.SignatureWithSaltAndExpiry memory signatureWithExpiry = _signOperatorChurnApproval(operatorToRegisterId, operatorKickParams, defaultSalt, block.timestamp + 10); cheats.prank(operatorToRegister); cheats.expectRevert("RegistryCoordinator._validateChurn: incoming operator has insufficient stake for churn"); - registryCoordinator.registerOperatorWithChurn(quorumNumbers, defaultSocket, operatorKickParams, signatureWithExpiry); + registryCoordinator.registerOperatorWithChurn( + quorumNumbers, + defaultSocket, + pubkeyRegistrationParams, + operatorKickParams, + signatureWithExpiry + ); } function testRegisterOperatorWithCoordinatorWithKicks_LessThanKickBIPsOfTotalStake_Reverts(uint256 pseudoRandomNumber) public { @@ -792,7 +766,13 @@ contract RegistryCoordinatorUnit is MockAVSDeployer { ISignatureUtils.SignatureWithSaltAndExpiry memory signatureWithExpiry = _signOperatorChurnApproval(operatorToRegisterId, operatorKickParams, defaultSalt, block.timestamp + 10); cheats.prank(operatorToRegister); cheats.expectRevert("RegistryCoordinator._validateChurn: cannot kick operator with more than kickBIPsOfTotalStake"); - registryCoordinator.registerOperatorWithChurn(quorumNumbers, defaultSocket, operatorKickParams, signatureWithExpiry); + registryCoordinator.registerOperatorWithChurn( + quorumNumbers, + defaultSocket, + pubkeyRegistrationParams, + operatorKickParams, + signatureWithExpiry + ); } function testRegisterOperatorWithCoordinatorWithKicks_InvalidSignatures_Reverts(uint256 pseudoRandomNumber) public { @@ -815,7 +795,13 @@ contract RegistryCoordinatorUnit is MockAVSDeployer { signatureWithSaltAndExpiry.salt = defaultSalt; cheats.prank(operatorToRegister); cheats.expectRevert("ECDSA: invalid signature"); - registryCoordinator.registerOperatorWithChurn(quorumNumbers, defaultSocket, operatorKickParams, signatureWithSaltAndExpiry); + registryCoordinator.registerOperatorWithChurn( + quorumNumbers, + defaultSocket, + pubkeyRegistrationParams, + operatorKickParams, + signatureWithSaltAndExpiry + ); } function testRegisterOperatorWithCoordinatorWithKicks_ExpiredSignatures_Reverts(uint256 pseudoRandomNumber) public { @@ -836,21 +822,24 @@ contract RegistryCoordinatorUnit is MockAVSDeployer { ISignatureUtils.SignatureWithSaltAndExpiry memory signatureWithSaltAndExpiry = _signOperatorChurnApproval(operatorToRegisterId, operatorKickParams, defaultSalt, block.timestamp - 1); cheats.prank(operatorToRegister); cheats.expectRevert("RegistryCoordinator._verifyChurnApproverSignature: churnApprover signature expired"); - registryCoordinator.registerOperatorWithChurn(quorumNumbers, defaultSocket, operatorKickParams, signatureWithSaltAndExpiry); + registryCoordinator.registerOperatorWithChurn( + quorumNumbers, + defaultSocket, + pubkeyRegistrationParams, + operatorKickParams, + signatureWithSaltAndExpiry + ); } function testEjectOperatorFromCoordinator_AllQuorums_Valid() public { // register operator with default stake with default quorum number bytes memory quorumNumbers = new bytes(1); quorumNumbers[0] = bytes1(defaultQuorumNumber); - BN254.G1Point memory pubkeyRegistrationSignature; - BN254.G1Point memory pubkeyG1; - BN254.G2Point memory pubkeyG2; stakeRegistry.setOperatorWeight(uint8(quorumNumbers[0]), defaultOperator, defaultStake); cheats.prank(defaultOperator); - registryCoordinator.registerOperator(quorumNumbers, defaultSocket, pubkeyRegistrationSignature, pubkeyG1, pubkeyG2); + registryCoordinator.registerOperator(quorumNumbers, defaultSocket, pubkeyRegistrationParams); cheats.expectEmit(true, true, true, true, address(blsApkRegistry)); emit OperatorRemovedFromQuorums(defaultOperator, quorumNumbers); @@ -879,16 +868,13 @@ contract RegistryCoordinatorUnit is MockAVSDeployer { bytes memory quorumNumbers = new bytes(2); quorumNumbers[0] = bytes1(defaultQuorumNumber); quorumNumbers[1] = bytes1(defaultQuorumNumber + 1); - BN254.G1Point memory pubkeyRegistrationSignature; - BN254.G1Point memory pubkeyG1; - BN254.G2Point memory pubkeyG2; for (uint i = 0; i < quorumNumbers.length; i++) { stakeRegistry.setOperatorWeight(uint8(quorumNumbers[i]), defaultOperator, defaultStake); } cheats.prank(defaultOperator); - registryCoordinator.registerOperator(quorumNumbers, defaultSocket, pubkeyRegistrationSignature, pubkeyG1, pubkeyG2); + registryCoordinator.registerOperator(quorumNumbers, defaultSocket, pubkeyRegistrationParams); // eject from only first quorum bytes memory quorumNumbersToEject = new bytes(1); @@ -921,14 +907,11 @@ contract RegistryCoordinatorUnit is MockAVSDeployer { function testEjectOperatorFromCoordinator_NotEjector_Reverts() public { bytes memory quorumNumbers = new bytes(1); quorumNumbers[0] = bytes1(defaultQuorumNumber); - BN254.G1Point memory pubkeyRegistrationSignature; - BN254.G1Point memory pubkeyG1; - BN254.G2Point memory pubkeyG2; stakeRegistry.setOperatorWeight(uint8(quorumNumbers[0]), defaultOperator, defaultStake); cheats.prank(defaultOperator); - registryCoordinator.registerOperator(quorumNumbers, defaultSocket, pubkeyRegistrationSignature, pubkeyG1, pubkeyG2); + registryCoordinator.registerOperator(quorumNumbers, defaultSocket, pubkeyRegistrationParams); cheats.expectRevert("RegistryCoordinator.onlyEjector: caller is not the ejector"); cheats.prank(defaultOperator); diff --git a/test/utils/MockAVSDeployer.sol b/test/utils/MockAVSDeployer.sol index 5112746d..89fac517 100644 --- a/test/utils/MockAVSDeployer.sol +++ b/test/utils/MockAVSDeployer.sol @@ -95,6 +95,8 @@ contract MockAVSDeployer is Test { uint32 registrationBlockNumber = 100; uint32 blocksBetweenRegistrations = 10; + IBLSApkRegistry.PubkeyRegistrationParams pubkeyRegistrationParams; + struct OperatorMetadata { uint256 quorumBitmap; address operator; @@ -291,17 +293,13 @@ contract MockAVSDeployer is Test { blsApkRegistry.setBLSPublicKey(operator, pubKey); - BN254.G1Point memory pubkeyRegistrationSignature; - BN254.G1Point memory pubkeyG1; - BN254.G2Point memory pubkeyG2; - bytes memory quorumNumbers = BitmapUtils.bitmapToBytesArray(quorumBitmap); for (uint i = 0; i < quorumNumbers.length; i++) { stakeRegistry.setOperatorWeight(uint8(quorumNumbers[i]), operator, stake); } cheats.prank(operator); - registryCoordinator.registerOperator(quorumNumbers, defaultSocket, pubkeyRegistrationSignature, pubkeyG1, pubkeyG2); + registryCoordinator.registerOperator(quorumNumbers, defaultSocket, pubkeyRegistrationParams); } /** @@ -313,17 +311,13 @@ contract MockAVSDeployer is Test { blsApkRegistry.setBLSPublicKey(operator, pubKey); - BN254.G1Point memory pubkeyRegistrationSignature; - BN254.G1Point memory pubkeyG1; - BN254.G2Point memory pubkeyG2; - bytes memory quorumNumbers = BitmapUtils.bitmapToBytesArray(quorumBitmap); for (uint i = 0; i < quorumNumbers.length; i++) { stakeRegistry.setOperatorWeight(uint8(quorumNumbers[i]), operator, stakes[uint8(quorumNumbers[i])]); } cheats.prank(operator); - registryCoordinator.registerOperator(quorumNumbers, defaultSocket, pubkeyRegistrationSignature, pubkeyG1, pubkeyG2); + registryCoordinator.registerOperator(quorumNumbers, defaultSocket, pubkeyRegistrationParams); } function _registerRandomOperators(uint256 pseudoRandomNumber) internal returns(OperatorMetadata[] memory, uint256[][] memory) {