Skip to content

Commit 161ea83

Browse files
committed
fix
1 parent 6e30575 commit 161ea83

File tree

2 files changed

+183
-4
lines changed

2 files changed

+183
-4
lines changed

contracts/contracts/test/Rollup.t.sol

Lines changed: 179 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1262,3 +1262,182 @@ contract RollupTest is L1MessageBaseTest {
12621262
rollup.importGenesisBatch(batchHeader);
12631263
}
12641264
}
1265+
1266+
/// @dev Tests for commitState: recommit after revert using stored blob hash, no blob in tx.
1267+
contract RollupCommitStateTest is L1MessageBaseTest {
1268+
bytes32 public stateRoot = bytes32(uint256(1));
1269+
IRollup.BatchDataInput public batchDataInput;
1270+
IRollup.BatchSignatureInput public batchSignatureInput;
1271+
1272+
function setUp() public virtual override {
1273+
super.setUp();
1274+
batchSignatureInput = IRollup.BatchSignatureInput(
1275+
uint256(0),
1276+
abi.encode(uint256(0), new address[](0), uint256(0), new address[](0), uint256(0), new address[](0)),
1277+
bytes("0x")
1278+
);
1279+
hevm.deal(alice, 5 * STAKING_VALUE);
1280+
Types.StakerInfo memory stakerInfo = ffi.generateStakerInfo(alice);
1281+
address[] memory add = new address[](1);
1282+
add[0] = alice;
1283+
hevm.prank(multisig);
1284+
l1Staking.updateWhitelist(add, new address[](0));
1285+
hevm.prank(alice);
1286+
l1Staking.register{value: STAKING_VALUE}(stakerInfo.tmKey, stakerInfo.blsKey);
1287+
}
1288+
1289+
function _genesisBatchHeader() internal pure returns (bytes memory batchHeader0) {
1290+
batchHeader0 = new bytes(249);
1291+
bytes32 bytesData1 = bytes32(uint256(1));
1292+
bytes32 bytesData0 = bytes32(uint256(0));
1293+
assembly {
1294+
mstore(add(batchHeader0, add(0x20, 25)), 1)
1295+
mstore(add(batchHeader0, add(0x20, 57)), 0x010657f37554c781402a22917dee2f75def7ab966d7b770905398eba3c444014)
1296+
mstore(add(batchHeader0, add(0x20, 121)), bytesData1)
1297+
mstore(add(batchHeader0, add(0x20, 217)), bytesData0)
1298+
}
1299+
}
1300+
1301+
function _buildBatchHeader1ForProof(bytes32 parentBatchHash) internal view returns (bytes memory) {
1302+
return _createBatchHeaderV0ForProof(
1303+
1,
1304+
0,
1305+
0,
1306+
_computeDataHash(1, 0),
1307+
stateRoot,
1308+
stateRoot,
1309+
bytes32(uint256(4)),
1310+
keccak256(batchSignatureInput.sequencerSets),
1311+
parentBatchHash
1312+
);
1313+
}
1314+
1315+
function _batchHeader1Bytes(bytes32 parentBatchHash) internal pure returns (bytes memory batchHeader1) {
1316+
bytes32 bytesData1 = bytes32(uint256(1));
1317+
bytes32 bytesData4 = bytes32(uint256(4));
1318+
batchHeader1 = new bytes(249);
1319+
assembly {
1320+
mstore(add(batchHeader1, 0x20), 0)
1321+
mstore(add(batchHeader1, add(0x20, 1)), shl(192, 1))
1322+
mstore(add(batchHeader1, add(0x20, 9)), 0)
1323+
mstore(add(batchHeader1, add(0x20, 17)), 0)
1324+
mstore(add(batchHeader1, add(0x20, 25)), 0xe979da4b80d60a17ce56fa19278c6f3a7e1b43359fb8a8ea46d0264de7d653ab)
1325+
mstore(add(batchHeader1, add(0x20, 57)), 0x010657f37554c781402a22917dee2f75def7ab966d7b770905398eba3c444014)
1326+
mstore(add(batchHeader1, add(0x20, 89)), bytesData1)
1327+
mstore(add(batchHeader1, add(0x20, 121)), bytesData1)
1328+
mstore(add(batchHeader1, add(0x20, 153)), bytesData4)
1329+
mstore(add(batchHeader1, add(0x20, 185)), 0xf1f58308e98844ec99e2990d88bfb36e1a30f0e6591e62af90ae6f8498a1b067)
1330+
mstore(add(batchHeader1, add(0x20, 217)), parentBatchHash)
1331+
mstore(add(batchHeader1, add(0x20, 249)), 0)
1332+
}
1333+
}
1334+
1335+
/// @dev Setup: genesis + batch 1 committed (via commitBatchWithProof) so batch 1 has stored blob hash.
1336+
function _setupCommitStatePrecondition() internal {
1337+
bytes memory batchHeader0 = _genesisBatchHeader();
1338+
hevm.prank(multisig);
1339+
rollup.importGenesisBatch(batchHeader0);
1340+
bytes32 batchHash0 = rollup.committedBatches(0);
1341+
_setupDelayAndWarpForProof();
1342+
_mockMessageQueueNotDelayedForProof();
1343+
_mockVerifierForProof();
1344+
bytes memory batchHeader1ForProof = _buildBatchHeader1ForProof(batchHash0);
1345+
batchDataInput = IRollup.BatchDataInput(0, batchHeader0, 1, 0, stateRoot, stateRoot, bytes32(uint256(4)));
1346+
hevm.prank(alice);
1347+
rollup.commitBatchWithProof(
1348+
batchDataInput,
1349+
batchSignatureInput,
1350+
batchHeader1ForProof,
1351+
hex"deadbeef"
1352+
);
1353+
hevm.prank(multisig);
1354+
rollup.revertBatch(_batchHeader1Bytes(batchHash0), 1);
1355+
}
1356+
1357+
/// @dev commitState succeeds when recommitting after revertBatch (uses stored blob hash).
1358+
function test_commitState_succeeds_after_revertBatch() public {
1359+
bytes memory batchHeader0 = _genesisBatchHeader();
1360+
hevm.prank(multisig);
1361+
rollup.importGenesisBatch(batchHeader0);
1362+
bytes32 batchHash0 = rollup.committedBatches(0);
1363+
1364+
// Commit batch 1 via commitBatchWithProof so we have stored blob hash
1365+
_setupDelayAndWarpForProof();
1366+
_mockMessageQueueNotDelayedForProof();
1367+
_mockVerifierForProof();
1368+
bytes memory batchHeader1ForProof = _buildBatchHeader1ForProof(batchHash0);
1369+
batchDataInput = IRollup.BatchDataInput(0, batchHeader0, 1, 0, stateRoot, stateRoot, bytes32(uint256(4)));
1370+
hevm.prank(alice);
1371+
rollup.commitBatchWithProof(
1372+
batchDataInput,
1373+
batchSignatureInput,
1374+
batchHeader1ForProof,
1375+
hex"deadbeef"
1376+
);
1377+
assertEq(rollup.committedBatches(1), 0x25c3e4fee90e53de960c1092746c431ab570eacf8513011902fa65f10c814541);
1378+
assertGt(uint256(rollup.batchBlobVersionedHashes(1)), 0);
1379+
1380+
// Revert batch 1 (blob hash is preserved)
1381+
bytes memory batchHeader1 = _batchHeader1Bytes(batchHash0);
1382+
hevm.prank(multisig);
1383+
rollup.revertBatch(batchHeader1, 1);
1384+
assertEq(uint256(rollup.committedBatches(1)), 0);
1385+
assertEq(uint256(rollup.lastCommittedBatchIndex()), 0);
1386+
assertGt(uint256(rollup.batchBlobVersionedHashes(1)), 0);
1387+
1388+
// Recommit with commitState (no blob in tx; uses stored blob hash)
1389+
batchDataInput = IRollup.BatchDataInput(0, batchHeader0, 1, 0, stateRoot, stateRoot, bytes32(uint256(4)));
1390+
hevm.prank(alice);
1391+
rollup.commitState(batchDataInput, batchSignatureInput);
1392+
assertEq(rollup.committedBatches(1), 0x25c3e4fee90e53de960c1092746c431ab570eacf8513011902fa65f10c814541);
1393+
assertEq(uint256(rollup.lastCommittedBatchIndex()), 1);
1394+
}
1395+
1396+
/// @dev commitState must be rejected when tx carries blob (blobhash(0) != 0).
1397+
/// Contract: require(blobhash(0) == bytes32(0), "commitState must not carry blob").
1398+
/// In test env we cannot send a blob tx (blobhash(0) is always 0), so we only assert that without blob commitState succeeds.
1399+
/// Full revert test requires a blob transaction.
1400+
function test_commitState_reverts_when_carrying_blob() public {
1401+
_setupCommitStatePrecondition();
1402+
batchDataInput = IRollup.BatchDataInput(0, _genesisBatchHeader(), 1, 0, stateRoot, stateRoot, bytes32(uint256(4)));
1403+
hevm.prank(alice);
1404+
rollup.commitState(batchDataInput, batchSignatureInput);
1405+
// Without blob in tx, commitState succeeds. Revert "commitState must not carry blob" is hit only when blobhash(0) != 0 (blob tx).
1406+
assertEq(rollup.lastCommittedBatchIndex(), 1);
1407+
}
1408+
1409+
/// @dev commitState reverts when there is no stored blob hash for the batch.
1410+
function test_commitState_reverts_when_no_stored_blob_hash() public {
1411+
bytes memory batchHeader0 = _genesisBatchHeader();
1412+
hevm.prank(multisig);
1413+
rollup.importGenesisBatch(batchHeader0);
1414+
// Do NOT set stored blob hash for batch 1
1415+
batchDataInput = IRollup.BatchDataInput(0, batchHeader0, 1, 0, stateRoot, stateRoot, bytes32(uint256(4)));
1416+
hevm.prank(alice);
1417+
hevm.expectRevert("no stored blob hash for this batch");
1418+
rollup.commitState(batchDataInput, batchSignatureInput);
1419+
}
1420+
1421+
/// @dev commitState can only be called by an active staker.
1422+
function test_commitState_only_active_staker() public {
1423+
_setupCommitStatePrecondition();
1424+
batchDataInput = IRollup.BatchDataInput(0, _genesisBatchHeader(), 1, 0, stateRoot, stateRoot, bytes32(uint256(4)));
1425+
hevm.prank(address(1));
1426+
hevm.expectRevert("only active staker allowed");
1427+
rollup.commitState(batchDataInput, batchSignatureInput);
1428+
}
1429+
1430+
/// @dev Mutual exclusion: (1) commitBatch reverts when stored blob hash exists; (2) commitState reverts when no stored hash (see test_commitState_reverts_when_no_stored_blob_hash).
1431+
function test_commitState_commitBatch_mutual_exclusion() public {
1432+
bytes memory batchHeader0 = _genesisBatchHeader();
1433+
hevm.prank(multisig);
1434+
rollup.importGenesisBatch(batchHeader0);
1435+
1436+
// When there IS stored blob hash for batch 1, commitBatch must revert
1437+
_setStoredBlobHash(1);
1438+
batchDataInput = IRollup.BatchDataInput(0, batchHeader0, 1, 0, stateRoot, stateRoot, bytes32(uint256(4)));
1439+
hevm.prank(alice);
1440+
hevm.expectRevert("commitBatch requires no stored blob hash");
1441+
rollup.commitBatch(batchDataInput, batchSignatureInput);
1442+
}
1443+
}

tx-submitter/batch/batch_restart_test.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,7 @@ func compareBatchHeaderWithCommitData(t *testing.T, assembledBatchHeader *BatchH
210210
t.Logf("✓ NumL1Messages: %d (match)", l1MsgPopped)
211211
}
212212

213-
// 比较 PrevStateRoot
213+
// Compare PrevStateRoot
214214
prevStateRoot, err := assembledBatchHeader.PrevStateRoot()
215215
require.NoError(t, err)
216216
prevStateRootFromCommit := common.BytesToHash(batchDataInput.PrevStateRoot[:])
@@ -220,7 +220,7 @@ func compareBatchHeaderWithCommitData(t *testing.T, assembledBatchHeader *BatchH
220220
t.Logf("✓ PrevStateRoot: %x (match)", prevStateRoot)
221221
}
222222

223-
// 比较 PostStateRoot
223+
// Compare PostStateRoot
224224
postStateRoot, err := assembledBatchHeader.PostStateRoot()
225225
require.NoError(t, err)
226226
postStateRootFromCommit := common.BytesToHash(batchDataInput.PostStateRoot[:])
@@ -230,7 +230,7 @@ func compareBatchHeaderWithCommitData(t *testing.T, assembledBatchHeader *BatchH
230230
t.Logf("✓ PostStateRoot: %x (match)", postStateRoot)
231231
}
232232

233-
// 比较 WithdrawalRoot
233+
// Compare WithdrawalRoot
234234
withdrawRoot, err := assembledBatchHeader.WithdrawalRoot()
235235
require.NoError(t, err)
236236
withdrawRootFromCommit := common.BytesToHash(batchDataInput.WithdrawalRoot[:])
@@ -240,7 +240,7 @@ func compareBatchHeaderWithCommitData(t *testing.T, assembledBatchHeader *BatchH
240240
t.Logf("✓ WithdrawalRoot: %x (match)", withdrawRoot)
241241
}
242242

243-
// 比较 SequencerSetVerifyHash
243+
// Compare SequencerSetVerifyHash
244244
sequencerSetsHash := crypto.Keccak256Hash(batchSignatureInput.SequencerSets)
245245
seqHash, err := assembledBatchHeader.SequencerSetVerifyHash()
246246
require.NoError(t, err)

0 commit comments

Comments
 (0)