[Fix] M-01 Validate final blob was submitted on finalization (#226)

* Validate final blob was submitted on finalization

* Use new error code in Coordinator

* Use correct name for error
This commit is contained in:
The Dark Jester
2024-10-31 09:38:52 -07:00
committed by GitHub
parent 31f946ede7
commit 7b99e5ff20
5 changed files with 63 additions and 1 deletions

View File

@@ -41,9 +41,10 @@
"b015579f" = "IsNotPaused"
"3b174434" = "MessageHashesListLengthHigherThanOneHundred"
"ca389c44" = "InvalidProofOrProofVerificationRanOutOfGas"
"42ab979d" = "ParentBlobNotSubmitted"
"edeae83c" = "FinalBlobNotSubmitted"
# L2 Message Service
"6446cc9c" = "MessageHashesListLengthIsZero"
"d39e75f9" = "L1MessageNumberSynchronizationWrong"
"7557a60a" = "L1RollingHashSynchronizationWrong"
"36a4bb94" = "FinalRollingHashIsZero"
"42ab979d" = "ParentBlobNotSubmitted"

View File

@@ -445,6 +445,7 @@ contract LineaRollup is
/// @dev currentFinalizedShnarf is updated in _finalizeBlocks and lastFinalizedShnarf MUST be set beforehand for the transition.
bytes32 lastFinalizedShnarf = currentFinalizedShnarf;
bytes32 finalShnarf = _finalizeBlocks(_finalizationData, lastFinalizedBlockNumber);
uint256 publicInput = _computePublicInput(
@@ -507,6 +508,10 @@ contract LineaRollup is
_finalizationData.shnarfData.dataEvaluationClaim
);
if (blobShnarfExists[finalShnarf] == 0) {
revert FinalBlobNotSubmitted(finalShnarf);
}
_addL2MerkleRoots(_finalizationData.l2MerkleRoots, _finalizationData.l2MerkleTreesDepth);
_anchorL2MessagingBlocks(_finalizationData.l2MessagingBlocksOffsets, _lastFinalizedBlock);

View File

@@ -278,6 +278,11 @@ interface ILineaRollup {
*/
error ParentBlobNotSubmitted(bytes32 shnarf);
/**
* @dev Thrown when a shnarf does not exist for the final blob being finalized.
*/
error FinalBlobNotSubmitted(bytes32 shnarf);
/**
* @notice Adds or updates the verifier contract address for a proof type.
* @dev VERIFIER_SETTER_ROLE is required to execute.

View File

@@ -1342,6 +1342,56 @@ describe("Linea Rollup contract", () => {
]);
});
it("Should revert if the final shnarf does not exist", async () => {
const submissionDataBeforeFinalization = generateCallDataSubmission(0, 4);
let index = 0;
for (const data of submissionDataBeforeFinalization) {
const parentAndExpectedShnarf = generateParentAndExpectedShnarfForIndex(index);
await lineaRollup
.connect(operator)
.submitDataAsCalldata(data, parentAndExpectedShnarf.parentShnarf, parentAndExpectedShnarf.expectedShnarf, {
gasLimit: 30_000_000,
});
index++;
}
const finalizationData = await generateFinalizationData({
l1RollingHash: calculateRollingHash(HASH_ZERO, messageHash),
l1RollingHashMessageNumber: 10n,
lastFinalizedTimestamp: DEFAULT_LAST_FINALIZED_TIMESTAMP,
endBlockNumber: BigInt(calldataAggregatedProof1To155.finalBlockNumber),
parentStateRootHash: calldataAggregatedProof1To155.parentStateRootHash,
finalTimestamp: BigInt(calldataAggregatedProof1To155.finalTimestamp),
l2MerkleRoots: calldataAggregatedProof1To155.l2MerkleRoots,
l2MerkleTreesDepth: BigInt(calldataAggregatedProof1To155.l2MerkleTreesDepth),
l2MessagingBlocksOffsets: calldataAggregatedProof1To155.l2MessagingBlocksOffsets,
aggregatedProof: calldataAggregatedProof1To155.aggregatedProof,
shnarfData: generateParentShnarfData(index),
});
await lineaRollup.setRollingHash(
calldataAggregatedProof1To155.l1RollingHashMessageNumber,
calldataAggregatedProof1To155.l1RollingHash,
);
finalizationData.shnarfData.snarkHash = generateRandomBytes(32);
const { dataEvaluationClaim, dataEvaluationPoint, finalStateRootHash, parentShnarf, snarkHash } =
finalizationData.shnarfData;
const expectedMissingBlobShnarf = generateKeccak256(
["bytes32", "bytes32", "bytes32", "bytes32", "bytes32"],
[parentShnarf, snarkHash, finalStateRootHash, dataEvaluationPoint, dataEvaluationClaim],
);
const finalizeCompressedCall = lineaRollup
.connect(operator)
.finalizeBlocks(calldataAggregatedProof1To155.aggregatedProof, TEST_PUBLIC_VERIFIER_INDEX, finalizationData);
await expectRevertWithCustomError(lineaRollup, finalizeCompressedCall, "FinalBlobNotSubmitted", [
expectedMissingBlobShnarf,
]);
});
it("Should revert if finalizationData.finalTimestamp is greater than the block.timestamp", async () => {
const submissionDataBeforeFinalization = generateCallDataSubmission(0, 4);
let index = 0;

View File

@@ -181,6 +181,7 @@ class CoordinatorConfigTest {
"3b174434" to "MessageHashesListLengthHigherThanOneHundred",
"ca389c44" to "InvalidProofOrProofVerificationRanOutOfGas",
"42ab979d" to "ParentBlobNotSubmitted",
"edeae83c" to "FinalBlobNotSubmitted",
// L2 Message Service
"6446cc9c" to "MessageHashesListLengthIsZero",
"d39e75f9" to "L1MessageNumberSynchronizationWrong",