diff --git a/l1-contracts/contracts/state-transition/chain-deps/facets/Executor.sol b/l1-contracts/contracts/state-transition/chain-deps/facets/Executor.sol index 6639a7af8..c04c78fc8 100644 --- a/l1-contracts/contracts/state-transition/chain-deps/facets/Executor.sol +++ b/l1-contracts/contracts/state-transition/chain-deps/facets/Executor.sol @@ -78,7 +78,7 @@ contract ExecutorFacet is ZkSyncHyperchainBase, IExecutor { // Add batch to BatchAggregator IBatchAggregator(BATCH_AGGREGATOR_ADDRESS).commitBatch( _newBatch.pubdataCommitments, - 0, + s.chainId, _newBatch.batchNumber ); } diff --git a/system-contracts/contracts/BatchAggregator.sol b/system-contracts/contracts/BatchAggregator.sol index b68264e7d..73b33e9a9 100644 --- a/system-contracts/contracts/BatchAggregator.sol +++ b/system-contracts/contracts/BatchAggregator.sol @@ -5,7 +5,7 @@ pragma solidity 0.8.20; import {IBatchAggregator} from "./interfaces/IBatchAggregator.sol"; import {ISystemContract} from "./interfaces/ISystemContract.sol"; import {L2_L1_LOGS_TREE_DEFAULT_LEAF_HASH, L2_TO_L1_LOG_SERIALIZE_SIZE, STATE_DIFF_COMPRESSION_VERSION_NUMBER} from "./interfaces/IL1Messenger.sol"; -import {SystemLogKey, SYSTEM_CONTEXT_CONTRACT, KNOWN_CODE_STORAGE_CONTRACT, COMPRESSOR_CONTRACT, BATCH_AGGREGATOR, STATE_DIFF_ENTRY_SIZE, L2_TO_L1_LOGS_MERKLE_TREE_LEAVES, PUBDATA_CHUNK_PUBLISHER, COMPUTATIONAL_PRICE_FOR_PUBDATA} from "./Constants.sol"; +import {SystemLogKey, SYSTEM_CONTEXT_CONTRACT, KNOWN_CODE_STORAGE_CONTRACT, COMPRESSOR_CONTRACT, BATCH_AGGREGATOR, STATE_DIFF_ENTRY_SIZE, STATE_DIFF_AGGREGATION_INFO_SIZE, L2_TO_L1_LOGS_MERKLE_TREE_LEAVES, PUBDATA_CHUNK_PUBLISHER, COMPUTATIONAL_PRICE_FOR_PUBDATA} from "./Constants.sol"; import {UnsafeBytesCalldata} from "./libraries/UnsafeBytesCalldata.sol"; import {ICompressor, OPERATION_BITMASK, LENGTH_BITS_OFFSET, MAX_ENUMERATION_INDEX_SIZE} from "./interfaces/ICompressor.sol"; @@ -23,9 +23,10 @@ contract BatchAggregator is IBatchAggregator, ISystemContract { // state diff data mapping(uint256 => bytes[]) initialWrites; mapping(uint256 => bytes32[]) initialWritesSlots; + /// @dev state diff: [32bytes derived key][8bytes enum index][32bytes initial value][32bytes final value] mapping(uint256 => mapping(uint64 => bytes)) uncompressedWrites; - mapping(uint256 => mapping(uint64 => bool)) slotStatus; - mapping(uint256 => uint64[]) accesedSlots; + mapping(uint256 => mapping(uint64 => bool)) isKeyTouched; + mapping(uint256 => uint64[]) touchedSlots; // chain data mapping(uint256 => bool) chainSet; @@ -40,26 +41,37 @@ contract BatchAggregator is IBatchAggregator, ISystemContract { function _sliceToUint256(bytes calldata _calldataSlice) internal pure returns (uint256 number) { number = uint256(bytes32(_calldataSlice)); number >>= (256 - (_calldataSlice.length * 8)); + } - function addInitialWrite(uint256 chainId, bytes calldata stateDiff, bytes calldata compressedStateDiff) internal{ - bytes32 derivedKey = stateDiff.readBytes32(52); - initialWrites[chainId].push(stateDiff); + function addInitialWrite(uint256 chainId, bytes32 derivedKey, uint64 enumIndex, uint256 initialValue, uint256 finalValue) internal{ + bytes memory slotData = new bytes(STATE_DIFF_AGGREGATION_INFO_SIZE); + assembly{ + mstore(add(slotData,0),derivedKey) + mstore(add(slotData,32),enumIndex) + mstore(add(slotData,40),initialValue) + mstore(add(slotData,72),finalValue) + } + initialWrites[chainId].push(slotData); initialWritesSlots[chainId].push(derivedKey); } - function addRepeatedWrite(uint256 chainId, bytes calldata stateDiff, bytes calldata compressedStateDiff) internal{ - uint64 enumIndex = stateDiff.readUint64(84); - if (slotStatus[chainId][enumIndex]==false){ - uncompressedWrites[chainId][enumIndex] = stateDiff; - slotStatus[chainId][enumIndex] = true; - accesedSlots[chainId].push(enumIndex); + function addRepeatedWrite(uint256 chainId, bytes32 derivedKey, uint64 enumIndex, uint256 initialValue, uint256 finalValue) internal{ + if (isKeyTouched[chainId][enumIndex]==false){ + bytes memory slotData = new bytes(STATE_DIFF_AGGREGATION_INFO_SIZE); + assembly{ + mstore(add(slotData,0),derivedKey) + mstore(add(slotData,32),enumIndex) + mstore(add(slotData,40),initialValue) + mstore(add(slotData,72),finalValue) + } + uncompressedWrites[chainId][enumIndex] = slotData; + isKeyTouched[chainId][enumIndex] = true; + touchedSlots[chainId].push(enumIndex); } else{ bytes memory slotData = uncompressedWrites[chainId][enumIndex]; - bytes32 finalValue = stateDiff.readBytes32(124); assembly { - let start := add(slotData, 0x20) - mstore(add(start,124),finalValue) + mstore(add(slotData,72),finalValue) } uncompressedWrites[chainId][enumIndex] = slotData; } @@ -93,7 +105,7 @@ contract BatchAggregator is IBatchAggregator, ISystemContract { numInitialWritesProcessed++; bytes32 derivedKey = stateDiff.readBytes32(52); - uint256 initValue = stateDiff.readUint256(92); + uint256 initialValue = stateDiff.readUint256(92); uint256 finalValue = stateDiff.readUint256(124); uint256 sliceStart = stateDiffPtr; @@ -105,7 +117,7 @@ contract BatchAggregator is IBatchAggregator, ISystemContract { uint8 len = operation == 0 ? 32 : metadata >> LENGTH_BITS_OFFSET; stateDiffPtr += len; - addInitialWrite(chainId, stateDiff, _compressedStateDiffs[sliceStart:stateDiffPtr]); + addInitialWrite(chainId, derivedKey, enumIndex, initialValue, finalValue); } require(numInitialWritesProcessed == numberOfInitialWrites, "Incorrect number of initial storage diffs"); @@ -117,8 +129,9 @@ contract BatchAggregator is IBatchAggregator, ISystemContract { if (enumIndex == 0) { continue; } - - uint256 initValue = stateDiff.readUint256(92); + + bytes32 derivedKey = stateDiff.readBytes32(52); + uint256 initialValue = stateDiff.readUint256(92); uint256 finalValue = stateDiff.readUint256(124); uint256 sliceStart = stateDiffPtr; uint256 compressedEnumIndex = _sliceToUint256( @@ -131,9 +144,9 @@ contract BatchAggregator is IBatchAggregator, ISystemContract { stateDiffPtr += 1; uint8 operation = metadata & OPERATION_BITMASK; uint8 len = operation == 0 ? 32 : metadata >> LENGTH_BITS_OFFSET; - stateDiffPtr += len; - addRepeatedWrite(chainId, stateDiff, _compressedStateDiffs[sliceStart:stateDiffPtr]); + + addRepeatedWrite(chainId, derivedKey, enumIndex, initialValue, finalValue); } @@ -226,28 +239,28 @@ contract BatchAggregator is IBatchAggregator, ISystemContract { uint8 transform = bytesLength(finalValue); uint8 add = bytesLength(finalValue-initialValue); uint8 sub = bytesLength(initialValue-finalValue); - uint8 opt = (transform enumIndex?maxEnumIndex:enumIndex); - stateDiffPtr += STATE_DIFF_ENTRY_SIZE; + stateDiffPtr += STATE_DIFF_AGGREGATION_INFO_SIZE; } uint256 enumIndexSize = bytesLength(maxEnumIndex); - bytes memory compressedStateDiffs = new bytes((numberOfRepeatedWrites+numberOfInitialWrites)*LOOSE_COMPRESION+numberOfRepeatedWrites*enumIndexSize+numberOfInitialWrites*DERIVED_KEY_SIZE); + + bytes memory compressedStateDiffs = new bytes( + (numberOfRepeatedWrites+numberOfInitialWrites)*LOOSE_COMPRESION // maximal size of metadata + compressed value + +numberOfRepeatedWrites*enumIndexSize // enumIndexSize for repeated writes + +numberOfInitialWrites*DERIVED_KEY_SIZE); // derived key for initial writes uint256 compressionPtr = 0; // compress initial writes uint256 compressedStateDiffSize = 0; - initialWritesPtr = 0; - for(uint256 i = 0;i