Skip to content

Commit 4286bdb

Browse files
committed
Validate final blob was submitted on finalization
1 parent cd58916 commit 4286bdb

File tree

3 files changed

+60
-0
lines changed

3 files changed

+60
-0
lines changed

contracts/contracts/LineaRollup.sol

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -441,6 +441,7 @@ contract LineaRollup is
441441

442442
/// @dev currentFinalizedShnarf is updated in _finalizeBlocks and lastFinalizedShnarf MUST be set beforehand for the transition.
443443
bytes32 lastFinalizedShnarf = currentFinalizedShnarf;
444+
444445
bytes32 finalShnarf = _finalizeBlocks(_finalizationData, lastFinalizedBlockNumber);
445446

446447
uint256 publicInput = _computePublicInput(
@@ -503,6 +504,10 @@ contract LineaRollup is
503504
_finalizationData.shnarfData.dataEvaluationClaim
504505
);
505506

507+
if (blobShnarfExists[finalShnarf] == 0) {
508+
revert FinalBlobNotSubmitted(finalShnarf);
509+
}
510+
506511
_addL2MerkleRoots(_finalizationData.l2MerkleRoots, _finalizationData.l2MerkleTreesDepth);
507512
_anchorL2MessagingBlocks(_finalizationData.l2MessagingBlocksOffsets, _lastFinalizedBlock);
508513

contracts/contracts/interfaces/l1/ILineaRollup.sol

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,11 @@ interface ILineaRollup {
278278
*/
279279
error ParentBlobNotSubmitted(bytes32 shnarf);
280280

281+
/**
282+
* @dev Thrown when a shnarf does not exist for the final blob being finalized.
283+
*/
284+
error FinalBlobNotSubmitted(bytes32 shnarf);
285+
281286
/**
282287
* @notice Adds or updates the verifier contract address for a proof type.
283288
* @dev VERIFIER_SETTER_ROLE is required to execute.

contracts/test/LineaRollup.ts

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1332,6 +1332,56 @@ describe("Linea Rollup contract", () => {
13321332
]);
13331333
});
13341334

1335+
it("Should revert if the final shnarf does not exist", async () => {
1336+
const submissionDataBeforeFinalization = generateCallDataSubmission(0, 4);
1337+
let index = 0;
1338+
for (const data of submissionDataBeforeFinalization) {
1339+
const parentAndExpectedShnarf = generateParentAndExpectedShnarfForIndex(index);
1340+
await lineaRollup
1341+
.connect(operator)
1342+
.submitDataAsCalldata(data, parentAndExpectedShnarf.parentShnarf, parentAndExpectedShnarf.expectedShnarf, {
1343+
gasLimit: 30_000_000,
1344+
});
1345+
index++;
1346+
}
1347+
1348+
const finalizationData = await generateFinalizationData({
1349+
l1RollingHash: calculateRollingHash(HASH_ZERO, messageHash),
1350+
l1RollingHashMessageNumber: 10n,
1351+
lastFinalizedTimestamp: DEFAULT_LAST_FINALIZED_TIMESTAMP,
1352+
endBlockNumber: BigInt(calldataAggregatedProof1To155.finalBlockNumber),
1353+
parentStateRootHash: calldataAggregatedProof1To155.parentStateRootHash,
1354+
finalTimestamp: BigInt(calldataAggregatedProof1To155.finalTimestamp),
1355+
l2MerkleRoots: calldataAggregatedProof1To155.l2MerkleRoots,
1356+
l2MerkleTreesDepth: BigInt(calldataAggregatedProof1To155.l2MerkleTreesDepth),
1357+
l2MessagingBlocksOffsets: calldataAggregatedProof1To155.l2MessagingBlocksOffsets,
1358+
aggregatedProof: calldataAggregatedProof1To155.aggregatedProof,
1359+
shnarfData: generateParentShnarfData(index),
1360+
});
1361+
1362+
await lineaRollup.setRollingHash(
1363+
calldataAggregatedProof1To155.l1RollingHashMessageNumber,
1364+
calldataAggregatedProof1To155.l1RollingHash,
1365+
);
1366+
1367+
finalizationData.shnarfData.snarkHash = generateRandomBytes(32);
1368+
1369+
const { dataEvaluationClaim, dataEvaluationPoint, finalStateRootHash, parentShnarf, snarkHash } =
1370+
finalizationData.shnarfData;
1371+
const expectedMissingBlobShnarf = generateKeccak256(
1372+
["bytes32", "bytes32", "bytes32", "bytes32", "bytes32"],
1373+
[parentShnarf, snarkHash, finalStateRootHash, dataEvaluationPoint, dataEvaluationClaim],
1374+
);
1375+
1376+
const finalizeCompressedCall = lineaRollup
1377+
.connect(operator)
1378+
.finalizeBlocks(calldataAggregatedProof1To155.aggregatedProof, TEST_PUBLIC_VERIFIER_INDEX, finalizationData);
1379+
1380+
await expectRevertWithCustomError(lineaRollup, finalizeCompressedCall, "FinalBlobNotSubmitted", [
1381+
expectedMissingBlobShnarf,
1382+
]);
1383+
});
1384+
13351385
it("Should revert if finalizationData.finalTimestamp is greater than the block.timestamp", async () => {
13361386
const submissionDataBeforeFinalization = generateCallDataSubmission(0, 4);
13371387
let index = 0;

0 commit comments

Comments
 (0)