@@ -11,9 +11,13 @@ import {
1111import {IPredepositGuarantee} from "contracts/0.8.25/vaults/interfaces/IPredepositGuarantee.sol " ;
1212
1313interface IConsolidationGateway {
14+ struct ConsolidationWitnessGroup {
15+ bytes [] sourcePubkeys;
16+ IPredepositGuarantee.ValidatorWitness targetWitness;
17+ }
18+
1419 function addConsolidationRequests (
15- bytes [][] calldata sourcePubkeysGroups ,
16- IPredepositGuarantee.ValidatorWitness[] calldata targetWitnesses ,
20+ ConsolidationWitnessGroup[] calldata groups ,
1721 address refundRecipient
1822 ) external payable ;
1923}
@@ -43,13 +47,6 @@ contract ConsolidationBus is AccessControlEnumerableUpgradeable {
4347 */
4448 error AdminCannotBeZero ();
4549
46- /**
47- * @notice Thrown when source groups and target arrays have different lengths
48- * @param sourceGroupsLength Length of source pubkeys groups array
49- * @param targetLength Length of target pubkeys array
50- */
51- error ArraysLengthMismatch (uint256 sourceGroupsLength , uint256 targetLength );
52-
5350 /**
5451 * @notice Thrown when batch is empty
5552 */
@@ -142,7 +139,7 @@ contract ConsolidationBus is AccessControlEnumerableUpgradeable {
142139 /**
143140 * @notice Emitted when consolidation requests are added
144141 * @param publisher Address of the publisher who added the requests
145- * @param batchData Encoded batch data (abi.encode(sourcePubkeysGroups, targetPubkeys ))
142+ * @param batchData Encoded batch data (abi.encode(groups ))
146143 */
147144 event RequestsAdded (address indexed publisher , bytes batchData );
148145
@@ -169,6 +166,11 @@ contract ConsolidationBus is AccessControlEnumerableUpgradeable {
169166 bytes32 public constant PUBLISH_ROLE = keccak256 ("PUBLISH_ROLE " );
170167 bytes32 public constant REMOVE_ROLE = keccak256 ("REMOVE_ROLE " );
171168
169+ struct ConsolidationGroup {
170+ bytes [] sourcePubkeys;
171+ bytes targetPubkey;
172+ }
173+
172174 struct BatchInfo {
173175 address publisher;
174176 uint64 addedAt;
@@ -310,34 +312,27 @@ contract ConsolidationBus is AccessControlEnumerableUpgradeable {
310312
311313 /**
312314 * @notice Adds grouped consolidation requests to the queue
313- * @param sourcePubkeysGroups Array of groups, where each group is an array of 48-byte source validator public keys
314- * consolidating to the corresponding target
315- * @param targetPubkeys Array of 48-byte target validator public keys, one per group
315+ * @param groups Array of consolidation groups, where each group contains source pubkeys and a target pubkey
316316 * @dev The same batch can be submitted again after it has been executed.
317317 * @dev Reverts if:
318318 * - Caller does not have PUBLISH_ROLE
319- * - Arrays have different lengths
320319 * - Batch is empty
321320 * - Any group is empty
322321 * - Total batch size exceeds limit
323322 * - Any source or target pubkey length is not 48 bytes
324323 * - Any source pubkey equals its corresponding target pubkey
325324 * - Batch already exists
326325 */
327- function addConsolidationRequests (
328- bytes [][] calldata sourcePubkeysGroups ,
329- bytes [] calldata targetPubkeys
330- ) external onlyRole (PUBLISH_ROLE) {
331- uint256 groupsCount = sourcePubkeysGroups.length ;
326+ function addConsolidationRequests (ConsolidationGroup[] calldata groups ) external onlyRole (PUBLISH_ROLE) {
327+ uint256 groupsCount = groups.length ;
332328 if (groupsCount == 0 ) revert EmptyBatch ();
333- if (groupsCount != targetPubkeys.length ) revert ArraysLengthMismatch (groupsCount, targetPubkeys.length );
334329
335330 uint256 maxGroups = _maxGroupsInBatch;
336331 if (groupsCount > maxGroups) revert TooManyGroups (groupsCount, maxGroups);
337332
338333 uint256 totalCount = 0 ;
339334 for (uint256 i = 0 ; i < groupsCount; ++ i) {
340- uint256 groupSize = sourcePubkeysGroups [i].length ;
335+ uint256 groupSize = groups [i].sourcePubkeys .length ;
341336 if (groupSize == 0 ) revert EmptyGroup (i);
342337 totalCount += groupSize;
343338 }
@@ -346,13 +341,13 @@ contract ConsolidationBus is AccessControlEnumerableUpgradeable {
346341 if (totalCount > limit) revert BatchTooLarge (totalCount, limit);
347342
348343 for (uint256 i = 0 ; i < groupsCount; ++ i) {
349- bytes calldata targetPubkey = targetPubkeys [i];
344+ bytes calldata targetPubkey = groups [i].targetPubkey ;
350345 if (targetPubkey.length != PUBKEY_LENGTH) {
351346 revert InvalidTargetPubkeyLength (i, targetPubkey.length );
352347 }
353348
354349 bytes32 targetHash = keccak256 (targetPubkey);
355- bytes [] calldata group = sourcePubkeysGroups [i];
350+ bytes [] calldata group = groups [i].sourcePubkeys ;
356351 for (uint256 j = 0 ; j < group.length ; ++ j) {
357352 bytes calldata sourcePubkey = group[j];
358353 if (sourcePubkey.length != PUBKEY_LENGTH) {
@@ -365,7 +360,7 @@ contract ConsolidationBus is AccessControlEnumerableUpgradeable {
365360 }
366361 }
367362
368- bytes memory encodedBatch = abi.encode (sourcePubkeysGroups, targetPubkeys );
363+ bytes memory encodedBatch = abi.encode (groups );
369364
370365 bytes32 batchHash = keccak256 (encodedBatch);
371366
@@ -382,22 +377,22 @@ contract ConsolidationBus is AccessControlEnumerableUpgradeable {
382377
383378 /**
384379 * @notice Executes a batch of grouped consolidation requests
385- * @param sourcePubkeysGroups Array of groups of 48-byte source validator public keys
386- * @param targetWitnesses Array of ValidatorWitness structs, one per group; each witness.pubkey is the target pubkey
380+ * @param groups Array of consolidation witness groups, each containing source pubkeys and a target validator witness
387381 * @dev Forwards the batch to ConsolidationGateway with msg.value as fee
388382 * @dev Reverts if:
389383 * - Batch was not added or was already executed/removed
390384 */
391- function executeConsolidation (
392- bytes [][] calldata sourcePubkeysGroups ,
393- IPredepositGuarantee.ValidatorWitness[] calldata targetWitnesses
394- ) external payable {
395- bytes [] memory targetPubkeys = new bytes [](targetWitnesses.length );
396- for (uint256 i = 0 ; i < targetWitnesses.length ; ++ i) {
397- targetPubkeys[i] = targetWitnesses[i].pubkey;
385+ function executeConsolidation (IConsolidationGateway.ConsolidationWitnessGroup[] calldata groups ) external payable {
386+ // Reconstruct ConsolidationGroup[] to compute the batch hash that matches the publisher's submission
387+ ConsolidationGroup[] memory publisherGroups = new ConsolidationGroup [](groups.length );
388+ for (uint256 i = 0 ; i < groups.length ; ++ i) {
389+ publisherGroups[i] = ConsolidationGroup ({
390+ sourcePubkeys: groups[i].sourcePubkeys,
391+ targetPubkey: groups[i].targetWitness.pubkey
392+ });
398393 }
399394
400- bytes32 batchHash = keccak256 (abi.encode (sourcePubkeysGroups, targetPubkeys ));
395+ bytes32 batchHash = keccak256 (abi.encode (publisherGroups ));
401396
402397 BatchInfo memory batch = _pendingBatches[batchHash];
403398 if (batch.publisher == address (0 )) revert BatchNotFound (batchHash);
@@ -407,11 +402,7 @@ contract ConsolidationBus is AccessControlEnumerableUpgradeable {
407402
408403 delete _pendingBatches[batchHash];
409404
410- CONSOLIDATION_GATEWAY.addConsolidationRequests {value: msg .value }(
411- sourcePubkeysGroups,
412- targetWitnesses,
413- msg .sender
414- );
405+ CONSOLIDATION_GATEWAY.addConsolidationRequests {value: msg .value }(groups, msg .sender );
415406
416407 emit RequestsExecuted (batchHash, msg .value );
417408 }
0 commit comments