This document is a continuation in the series of articles explaining the transaction life cycle inside Polygon zkEVM.
PolygonZkEVM.sol contract’s sequencedBatches mapping, which is basically a storage structure that holds the queue of sequences defining the virtual state.
PolygonZkEVM.sol contract, which employs its sequenceBatches mapping, which accepts an array of batches to be sequenced as an argument. Please see the code snippet provided below.

Max & min batch size bounds
The contract’s public constant,MAX_TRANSACTIONS_BYTE_LENGTH, determines the maximum number of transactions that can be included in a batch (120000).
Similarly, the number of batches in a sequence is limited by the contract’s public constant MAX_VERIFY_BATCHES (1000). The batches array must contain at least one batch and no more than the value of the constant MAX_VERIFY_BATCHES.
Only the trusted sequencer’s Ethereum account can access the sequencedBatches mapping. The contract must not be in an emergency state.
The function call reverts if the above conditions are not met.
Batch validity & L2 state integrity
ThesequencedBatches function iterates over every batch of the sequence, checking its validity. A valid batch must meet the following criteria:
- It must include a
globalExitRootvalue that is present in theGlobalExitRootMapof the bridge’s L1PolygonZkEVMGlobalExitRoot.solcontract. A batch is valid only if it includes a validglobalExitRoot. - The length of the transactions byte array must be less than the value of
MAX_TRANSACTIONS_BYTE_LENGTHconstant. - The timestamp of the block must be greater or equal to that of the last block (of a sequenced batch), but less than or equal to the timestamp of the block where the sequencing L1 transaction is executed. All blocks must be ordered by time.
lastBatchSequenced is used as a batch counter, and it is thus incremented each time a batch is sequenced. It gives a specific index number to each batch that is used as a position value in the batch chain.
The same hashing mechanism used in blockchains to link one block to the next is used in batches to ensure the cryptographic integrity of the batch chain. That is, including the previous batch’s digest among the data used to compute the next batch’s digest.
As a result, the digest of a given batch is an accumulated hash of all previously sequenced batches, hence the name accumulated hash of a batch, denoted by oldAccInputHash for the old and newAccInputHash for the new.
An accumulated hash of a specific batch has the following structure:
oldAccInputHashis the accumulated hash of the previous sequenced batch.keccack256(transactions)is the Keccak digest of the transactions byte array.globalExitRootis the root of the bridge’s global exit Merkle tree.timestampis the batch timestamp.seqAddressis the address of the batch sequencer.

transactions, timestamp, and globalExitRoot, as well as the order in which they were sequenced.
It is important to note that any change in the batch chain causes all future accumulated input hashes to be incorrect, demonstrating a lack of integrity in the resulting L2 state.
The batch sequence is added to the sequencedBatches mapping using the following SequencedBatchData struct only after the validity of all batches in a sequence has been verified and the accumulated hash of each batch has been computed.
accInputHashis the batch’s a unique cryptographic finger-print of the last batch in the sequence.sequencedTimestampis the timestamp of the block where the sequencing L1 transaction is executed.previousLastBatchSequencedis the index of the last sequenced batch before the first batch of the current sequence (i.e., the last batch of the previous sequence).
SequencedBatchData struct is the value, in the sequencedBatches mapping.
Batch data minimal storage
Since storage operations on L1 are very costly in terms of gas consumption, it is essential to use them as sparingly as possible. To accomplish this, storage slots (or mapping entries) are used solely to store a sequence commitment. Each mapping entry commits two batch indices,- Last batch of the previous sequence as value of
SequencedBatchDatastruct, - Last batch of the current sequence as mapping key,
SequenceBatches event emits.
PolygonZkEVM.sol contract, without having to rely on the trusted sequencer alone. This is how the L2 virtual state is reached.