From 61124531ef8a903a8fd8df25c62fb427f88cbb1f Mon Sep 17 00:00:00 2001 From: Daniel Wang Date: Thu, 9 Jan 2025 15:16:01 +0800 Subject: [PATCH 01/41] disable all TaikoInbox tests --- .../protocol/snapshots/InboxTest_Suite1.json | 4 - .../layer1/based/InBoxTest_BlockParams.t.sol | 340 +++---- .../test/layer1/based/InboxTestBase.sol | 480 +++++----- .../based/InboxTest_BondMechanics.t.sol | 244 ++--- .../test/layer1/based/InboxTest_BondToken.sol | 354 +++---- .../based/InboxTest_CalldataForTxList.t.sol | 322 +++---- .../layer1/based/InboxTest_EtherAsBond.t.sol | 294 +++--- .../test/layer1/based/InboxTest_Suite1.t.sol | 896 +++++++++--------- .../tokenunlock/TokenUnlock_ProverSet.t.sol | 348 +++---- 9 files changed, 1639 insertions(+), 1643 deletions(-) delete mode 100644 packages/protocol/snapshots/InboxTest_Suite1.json diff --git a/packages/protocol/snapshots/InboxTest_Suite1.json b/packages/protocol/snapshots/InboxTest_Suite1.json deleted file mode 100644 index 84341681d44..00000000000 --- a/packages/protocol/snapshots/InboxTest_Suite1.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "proposeBlocksV3": "88734", - "proveBlocksV3": "134458" -} \ No newline at end of file diff --git a/packages/protocol/test/layer1/based/InBoxTest_BlockParams.t.sol b/packages/protocol/test/layer1/based/InBoxTest_BlockParams.t.sol index 418450b5248..f51c576dedb 100644 --- a/packages/protocol/test/layer1/based/InBoxTest_BlockParams.t.sol +++ b/packages/protocol/test/layer1/based/InBoxTest_BlockParams.t.sol @@ -1,173 +1,173 @@ // SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.24; -import "./InboxTestBase.sol"; - -contract InBoxTest_BlockParams is InboxTestBase { - function getConfig() internal pure override returns (ITaikoInbox.ConfigV3 memory) { - return ITaikoInbox.ConfigV3({ - chainId: LibNetwork.TAIKO_MAINNET, - blockMaxProposals: 10, - blockRingBufferSize: 15, - maxBlocksToVerify: 5, - blockMaxGasLimit: 240_000_000, - livenessBond: 125e18, // 125 Taiko token - stateRootSyncInternal: 5, - maxAnchorHeightOffset: 64, - baseFeeConfig: LibSharedData.BaseFeeConfig({ - adjustmentQuotient: 8, - sharingPctg: 75, - gasIssuancePerSecond: 5_000_000, - minGasExcess: 1_340_000_000, // correspond to 0.008847185 gwei basefee - maxGasIssuancePerBlock: 600_000_000 // two minutes: 5_000_000 * 120 - }), - provingWindow: 1 hours, - maxSignalsToReceive: 16, - forkHeights: ITaikoInbox.ForkHeights({ ontake: 0, pacaya: 0 }) - }); - } - - function setUpOnEthereum() internal override { - super.setUpOnEthereum(); - bondToken = deployBondToken(); - } - - function test_validateBlockParams_defaults_when_anchorBlockId_is_zero() - external - transactBy(Alice) - { - ITaikoInbox.BlockParamsV3[] memory paramsArray = new ITaikoInbox.BlockParamsV3[](1); - paramsArray[0] = ITaikoInbox.BlockParamsV3({ - anchorBlockId: 0, // Simulate missing anchor block ID - timestamp: 0, - parentMetaHash: 0, - signalSlots: new bytes32[](0), - blobIndex: 0, - txListOffset: 0, - txListSize: 0, - anchorInput: bytes32(0) - }); - - ITaikoInbox.BlockMetadataV3[] memory metas = - inbox.proposeBlocksV3(address(0), address(0), paramsArray, "txList"); - - // Assert that the default anchorBlockId was set correctly - uint64 expectedAnchorBlockId = uint64(block.number - 1); - assertEq(metas[0].anchorBlockId, expectedAnchorBlockId, "AnchorBlockId mismatch"); - } - - function test_validateBlockParams_reverts_when_anchorBlockId_too_small() - external - transactBy(Alice) - { - ITaikoInbox.ConfigV3 memory config = inbox.getConfigV3(); - - // Advance the block number to create the appropriate test scenario - vm.roll(config.maxAnchorHeightOffset + 2); - - // Calculate an invalid anchorBlockId (too small) - uint64 anchorBlockId = uint64(block.number - config.maxAnchorHeightOffset - 1); - - ITaikoInbox.BlockParamsV3[] memory paramsArray = new ITaikoInbox.BlockParamsV3[](1); - paramsArray[0] = ITaikoInbox.BlockParamsV3({ - anchorBlockId: anchorBlockId, - timestamp: 0, - parentMetaHash: 0, - signalSlots: new bytes32[](0), - blobIndex: 0, - txListOffset: 0, - txListSize: 0, - anchorInput: bytes32(0) - }); - - vm.expectRevert(ITaikoInbox.AnchorBlockIdTooSmall.selector); - inbox.proposeBlocksV3(address(0), address(0), paramsArray, "txList"); - } - - function test_validateBlockParams_reverts_when_anchorBlockId_too_large() - external - transactBy(Alice) - { - // Calculate an invalid anchorBlockId (too large) - uint64 anchorBlockId = uint64(block.number); - - ITaikoInbox.BlockParamsV3[] memory paramsArray = new ITaikoInbox.BlockParamsV3[](1); - paramsArray[0] = ITaikoInbox.BlockParamsV3({ - anchorBlockId: anchorBlockId, - timestamp: 0, - parentMetaHash: 0, - signalSlots: new bytes32[](0), - blobIndex: 0, - txListOffset: 0, - txListSize: 0, - anchorInput: bytes32(0) - }); - - vm.expectRevert(ITaikoInbox.AnchorBlockIdTooLarge.selector); - inbox.proposeBlocksV3(address(0), address(0), paramsArray, "txList"); - } - - function test_validateBlockParams_reverts_when_anchorBlockId_smaller_than_parent() - external - transactBy(Alice) - { - vm.roll(10); - _proposeBlocksWithDefaultParameters(1); - ITaikoInbox.BlockV3 memory parent = inbox.getBlockV3(1); - - ITaikoInbox.BlockParamsV3[] memory paramsArray = new ITaikoInbox.BlockParamsV3[](1); - paramsArray[0] = ITaikoInbox.BlockParamsV3({ - anchorBlockId: parent.anchorBlockId - 1, - timestamp: 0, - parentMetaHash: 0, - signalSlots: new bytes32[](0), - blobIndex: 0, - txListOffset: 0, - txListSize: 0, - anchorInput: bytes32(0) - }); - - vm.expectRevert(ITaikoInbox.AnchorBlockIdSmallerThanParent.selector); - inbox.proposeBlocksV3(address(0), address(0), paramsArray, "txList"); - } - - function test_validateBlockParams_when_anchorBlockId_is_not_zero() external transactBy(Alice) { - ITaikoInbox.BlockParamsV3[] memory paramsArray = new ITaikoInbox.BlockParamsV3[](1); - paramsArray[0] = ITaikoInbox.BlockParamsV3({ - anchorBlockId: uint64(block.number - 1), - timestamp: 0, - parentMetaHash: 0, - signalSlots: new bytes32[](0), - blobIndex: 0, - txListOffset: 0, - txListSize: 0, - anchorInput: bytes32(0) - }); - - ITaikoInbox.BlockMetadataV3[] memory metas = - inbox.proposeBlocksV3(address(0), address(0), paramsArray, "txList"); - - uint64 expectedAnchorBlockId = uint64(block.number - 1); - assertEq(metas[0].anchorBlockId, expectedAnchorBlockId, "AnchorBlockId mismatch"); - } - - function test_validateBlockParams_reverts_when_timestamp_too_large() - external - transactBy(Alice) - { - ITaikoInbox.BlockParamsV3[] memory paramsArray = new ITaikoInbox.BlockParamsV3[](1); - paramsArray[0] = ITaikoInbox.BlockParamsV3({ - anchorBlockId: 0, - timestamp: uint64(block.timestamp + 1), - parentMetaHash: 0, - signalSlots: new bytes32[](0), - blobIndex: 0, - txListOffset: 0, - txListSize: 0, - anchorInput: bytes32(0) - }); - - vm.expectRevert(ITaikoInbox.TimestampTooLarge.selector); - inbox.proposeBlocksV3(address(0), address(0), paramsArray, "txList"); - } -} +// import "./InboxTestBase.sol"; + +// contract InBoxTest_BlockParams is InboxTestBase { +// function getConfig() internal pure override returns (ITaikoInbox.ConfigV3 memory) { +// return ITaikoInbox.ConfigV3({ +// chainId: LibNetwork.TAIKO_MAINNET, +// blockMaxProposals: 10, +// blockRingBufferSize: 15, +// maxBlocksToVerify: 5, +// blockMaxGasLimit: 240_000_000, +// livenessBond: 125e18, // 125 Taiko token +// stateRootSyncInternal: 5, +// maxAnchorHeightOffset: 64, +// baseFeeConfig: LibSharedData.BaseFeeConfig({ +// adjustmentQuotient: 8, +// sharingPctg: 75, +// gasIssuancePerSecond: 5_000_000, +// minGasExcess: 1_340_000_000, // correspond to 0.008847185 gwei basefee +// maxGasIssuancePerBlock: 600_000_000 // two minutes: 5_000_000 * 120 +// }), +// provingWindow: 1 hours, +// maxSignalsToReceive: 16, +// forkHeights: ITaikoInbox.ForkHeights({ ontake: 0, pacaya: 0 }) +// }); +// } + +// function setUpOnEthereum() internal override { +// super.setUpOnEthereum(); +// bondToken = deployBondToken(); +// } + +// function test_validateBlockParams_defaults_when_anchorBlockId_is_zero() +// external +// transactBy(Alice) +// { +// ITaikoInbox.BlockParamsV3[] memory paramsArray = new ITaikoInbox.BlockParamsV3[](1); +// paramsArray[0] = ITaikoInbox.BlockParamsV3({ +// anchorBlockId: 0, // Simulate missing anchor block ID +// timestamp: 0, +// parentMetaHash: 0, +// signalSlots: new bytes32[](0), +// blobIndex: 0, +// txListOffset: 0, +// txListSize: 0, +// anchorInput: bytes32(0) +// }); + +// ITaikoInbox.BlockMetadataV3[] memory metas = +// inbox.proposeBlocksV3(address(0), address(0), paramsArray, "txList"); + +// // Assert that the default anchorBlockId was set correctly +// uint64 expectedAnchorBlockId = uint64(block.number - 1); +// assertEq(metas[0].anchorBlockId, expectedAnchorBlockId, "AnchorBlockId mismatch"); +// } + +// function test_validateBlockParams_reverts_when_anchorBlockId_too_small() +// external +// transactBy(Alice) +// { +// ITaikoInbox.ConfigV3 memory config = inbox.getConfigV3(); + +// // Advance the block number to create the appropriate test scenario +// vm.roll(config.maxAnchorHeightOffset + 2); + +// // Calculate an invalid anchorBlockId (too small) +// uint64 anchorBlockId = uint64(block.number - config.maxAnchorHeightOffset - 1); + +// ITaikoInbox.BlockParamsV3[] memory paramsArray = new ITaikoInbox.BlockParamsV3[](1); +// paramsArray[0] = ITaikoInbox.BlockParamsV3({ +// anchorBlockId: anchorBlockId, +// timestamp: 0, +// parentMetaHash: 0, +// signalSlots: new bytes32[](0), +// blobIndex: 0, +// txListOffset: 0, +// txListSize: 0, +// anchorInput: bytes32(0) +// }); + +// vm.expectRevert(ITaikoInbox.AnchorBlockIdTooSmall.selector); +// inbox.proposeBlocksV3(address(0), address(0), paramsArray, "txList"); +// } + +// function test_validateBlockParams_reverts_when_anchorBlockId_too_large() +// external +// transactBy(Alice) +// { +// // Calculate an invalid anchorBlockId (too large) +// uint64 anchorBlockId = uint64(block.number); + +// ITaikoInbox.BlockParamsV3[] memory paramsArray = new ITaikoInbox.BlockParamsV3[](1); +// paramsArray[0] = ITaikoInbox.BlockParamsV3({ +// anchorBlockId: anchorBlockId, +// timestamp: 0, +// parentMetaHash: 0, +// signalSlots: new bytes32[](0), +// blobIndex: 0, +// txListOffset: 0, +// txListSize: 0, +// anchorInput: bytes32(0) +// }); + +// vm.expectRevert(ITaikoInbox.AnchorBlockIdTooLarge.selector); +// inbox.proposeBlocksV3(address(0), address(0), paramsArray, "txList"); +// } + +// function test_validateBlockParams_reverts_when_anchorBlockId_smaller_than_parent() +// external +// transactBy(Alice) +// { +// vm.roll(10); +// _proposeBlocksWithDefaultParameters(1); +// ITaikoInbox.BlockV3 memory parent = inbox.getBlockV3(1); + +// ITaikoInbox.BlockParamsV3[] memory paramsArray = new ITaikoInbox.BlockParamsV3[](1); +// paramsArray[0] = ITaikoInbox.BlockParamsV3({ +// anchorBlockId: parent.anchorBlockId - 1, +// timestamp: 0, +// parentMetaHash: 0, +// signalSlots: new bytes32[](0), +// blobIndex: 0, +// txListOffset: 0, +// txListSize: 0, +// anchorInput: bytes32(0) +// }); + +// vm.expectRevert(ITaikoInbox.AnchorBlockIdSmallerThanParent.selector); +// inbox.proposeBlocksV3(address(0), address(0), paramsArray, "txList"); +// } + +// function test_validateBlockParams_when_anchorBlockId_is_not_zero() external transactBy(Alice) { +// ITaikoInbox.BlockParamsV3[] memory paramsArray = new ITaikoInbox.BlockParamsV3[](1); +// paramsArray[0] = ITaikoInbox.BlockParamsV3({ +// anchorBlockId: uint64(block.number - 1), +// timestamp: 0, +// parentMetaHash: 0, +// signalSlots: new bytes32[](0), +// blobIndex: 0, +// txListOffset: 0, +// txListSize: 0, +// anchorInput: bytes32(0) +// }); + +// ITaikoInbox.BlockMetadataV3[] memory metas = +// inbox.proposeBlocksV3(address(0), address(0), paramsArray, "txList"); + +// uint64 expectedAnchorBlockId = uint64(block.number - 1); +// assertEq(metas[0].anchorBlockId, expectedAnchorBlockId, "AnchorBlockId mismatch"); +// } + +// function test_validateBlockParams_reverts_when_timestamp_too_large() +// external +// transactBy(Alice) +// { +// ITaikoInbox.BlockParamsV3[] memory paramsArray = new ITaikoInbox.BlockParamsV3[](1); +// paramsArray[0] = ITaikoInbox.BlockParamsV3({ +// anchorBlockId: 0, +// timestamp: uint64(block.timestamp + 1), +// parentMetaHash: 0, +// signalSlots: new bytes32[](0), +// blobIndex: 0, +// txListOffset: 0, +// txListSize: 0, +// anchorInput: bytes32(0) +// }); + +// vm.expectRevert(ITaikoInbox.TimestampTooLarge.selector); +// inbox.proposeBlocksV3(address(0), address(0), paramsArray, "txList"); +// } +// } diff --git a/packages/protocol/test/layer1/based/InboxTestBase.sol b/packages/protocol/test/layer1/based/InboxTestBase.sol index 2551a3da262..62b8dc24948 100644 --- a/packages/protocol/test/layer1/based/InboxTestBase.sol +++ b/packages/protocol/test/layer1/based/InboxTestBase.sol @@ -1,243 +1,243 @@ // SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.24; -import "../Layer1Test.sol"; -import "test/layer1/based/helpers/Verifier_ToggleStub.sol"; - -abstract contract InboxTestBase is Layer1Test { - mapping(uint256 => ITaikoInbox.BlockMetadataV3) internal blockMetadatas; - ITaikoInbox internal inbox; - TaikoToken internal bondToken; - SignalService internal signalService; - uint256 genesisBlockProposedAt; - uint256 genesisBlockProposedIn; - - function getConfig() internal view virtual returns (ITaikoInbox.ConfigV3 memory); - - modifier transactBy(address transactor) override { - vm.deal(transactor, 100 ether); - if (bondToken != TaikoToken(address(0))) { - bondToken.transfer(transactor, 10_000 ether); - vm.startPrank(transactor); - bondToken.approve(address(inbox), type(uint256).max); - } else { - vm.startPrank(transactor); - } - - _; - vm.stopPrank(); - } - - function setUpOnEthereum() internal virtual override { - genesisBlockProposedAt = block.timestamp; - genesisBlockProposedIn = block.number; - - inbox = deployInbox(correctBlockhash(0), getConfig()); - - signalService = deploySignalService(address(new SignalService())); - signalService.authorize(address(inbox), true); - - resolver.registerAddress( - block.chainid, "proof_verifier", address(new Verifier_ToggleStub()) - ); - - mineOneBlockAndWrap(12 seconds); - } - - modifier WhenLogAllBlocksAndTransitions() { - _logAllBlocksAndTransitions(); - _; - } - - modifier WhenMultipleBlocksAreProposedWithDefaultParameters(uint256 numBlocksToPropose) { - _proposeBlocksWithDefaultParameters(numBlocksToPropose); - _; - } - - modifier WhenMultipleBlocksAreProvedWithWrongTransitions( - uint64 startBlockId, - uint64 endBlockId - ) { - _proveBlocksWithWrongTransitions(range(startBlockId, endBlockId)); - _; - } - - modifier WhenMultipleBlocksAreProvedWithCorrectTransitions( - uint64 startBlockId, - uint64 endBlockId - ) { - _proveBlocksWithCorrectTransitions(range(startBlockId, endBlockId)); - _; - } - - // internal helper functions ------------------------------------------------------------------- - - function _proposeBlocksWithDefaultParameters(uint256 numBlocksToPropose) - internal - returns (uint64[] memory blockIds) - { - // Provide a default value for txList - bytes memory defaultTxList = abi.encodePacked("txList"); - return _proposeBlocksWithDefaultParameters(numBlocksToPropose, defaultTxList); - } - - function _proposeBlocksWithDefaultParameters( - uint256 numBlocksToPropose, - bytes memory txList - ) - internal - returns (uint64[] memory blockIds) - { - ITaikoInbox.BlockParamsV3[] memory blockParams = - new ITaikoInbox.BlockParamsV3[](numBlocksToPropose); - - ITaikoInbox.BlockMetadataV3[] memory metas = - inbox.proposeBlocksV3(address(0), address(0), blockParams, txList); - - // Initialize blockIds array - blockIds = new uint64[](metas.length); - for (uint256 i; i < metas.length; ++i) { - blockMetadatas[metas[i].blockId] = metas[i]; - blockIds[i] = metas[i].blockId; - } - } - - function _proveBlocksWithCorrectTransitions(uint64[] memory blockIds) internal { - ITaikoInbox.BlockMetadataV3[] memory metas = - new ITaikoInbox.BlockMetadataV3[](blockIds.length); - ITaikoInbox.TransitionV3[] memory transitions = - new ITaikoInbox.TransitionV3[](blockIds.length); - - for (uint256 i; i < metas.length; ++i) { - metas[i] = blockMetadatas[blockIds[i]]; - transitions[i].parentHash = correctBlockhash(blockIds[i] - 1); - transitions[i].blockHash = correctBlockhash(blockIds[i]); - transitions[i].stateRoot = correctStateRoot(blockIds[i]); - } - - inbox.proveBlocksV3(metas, transitions, "proof"); - } - - function _proveBlocksWithWrongTransitions(uint64[] memory blockIds) internal { - ITaikoInbox.BlockMetadataV3[] memory metas = - new ITaikoInbox.BlockMetadataV3[](blockIds.length); - ITaikoInbox.TransitionV3[] memory transitions = - new ITaikoInbox.TransitionV3[](blockIds.length); - - for (uint256 i; i < metas.length; ++i) { - metas[i] = blockMetadatas[blockIds[i]]; - transitions[i].parentHash = randBytes32(); - transitions[i].blockHash = randBytes32(); - transitions[i].stateRoot = randBytes32(); - } - - inbox.proveBlocksV3(metas, transitions, "proof"); - } - - function _logAllBlocksAndTransitions() internal view { - console2.log(unicode"|───────────────────────────────────────────────────────────────"); - ITaikoInbox.Stats1 memory stats1 = inbox.getStats1(); - console2.log("Stats1 - lastSyncedBlockId:", stats1.lastSyncedBlockId); - console2.log("Stats1 - lastSyncedAt:", stats1.lastSyncedAt); - - ITaikoInbox.Stats2 memory stats2 = inbox.getStats2(); - console2.log("Stats2 - numBlocks:", stats2.numBlocks); - console2.log("Stats2 - lastVerifiedBlockId:", stats2.lastVerifiedBlockId); - console2.log("Stats2 - paused:", stats2.paused); - console2.log("Stats2 - lastProposedIn:", stats2.lastProposedIn); - console2.log("Stats2 - lastUnpausedAt:", stats2.lastUnpausedAt); - - // console2.log("stats2.numBlocks:", stats2.numBlocks); - // console2.log("getConfig().blockRingBufferSize:", getConfig().blockRingBufferSize); - - uint64 firstBlockId = stats2.numBlocks > getConfig().blockRingBufferSize - ? stats2.numBlocks - getConfig().blockRingBufferSize - : 0; - - for (uint64 i = firstBlockId; i < stats2.numBlocks; ++i) { - ITaikoInbox.BlockV3 memory blk = inbox.getBlockV3(i); - if (blk.blockId <= stats2.lastVerifiedBlockId) { - console2.log(unicode"|─ ✔ block#", blk.blockId); - } else { - console2.log(unicode"|─── block#", blk.blockId); - } - console2.log(unicode"│ |── metahash:", Strings.toHexString(uint256(blk.metaHash))); - console2.log(unicode"│ |── timestamp:", blk.timestamp); - console2.log(unicode"│ |── anchorBlockId:", blk.anchorBlockId); - console2.log(unicode"│ |── nextTransitionId:", blk.nextTransitionId); - console2.log(unicode"│ |── verifiedTransitionId:", blk.verifiedTransitionId); - - for (uint24 j = 1; j < blk.nextTransitionId; ++j) { - ITaikoInbox.TransitionV3 memory tran = inbox.getTransitionV3(blk.blockId, j); - console2.log(unicode"│ |── transition#", j); - console2.log( - unicode"│ │ |── parentHash:", - Strings.toHexString(uint256(tran.parentHash)) - ); - console2.log( - unicode"│ │ |── blockHash:", - Strings.toHexString(uint256(tran.blockHash)) - ); - console2.log( - unicode"│ │ └── stateRoot:", - Strings.toHexString(uint256(tran.stateRoot)) - ); - } - } - console2.log(""); - } - - function correctBlockhash(uint256 blockId) internal pure returns (bytes32) { - return bytes32(0x1000000 + blockId); - } - - function correctStateRoot(uint256 blockId) internal pure returns (bytes32) { - return bytes32(0x2000000 + blockId); - } - - function range(uint64 start, uint64 end) internal pure returns (uint64[] memory arr) { - arr = new uint64[](end - start); - for (uint64 i; i < arr.length; ++i) { - arr[i] = start + i; - } - } - - function mintEther(address to, uint256 amountEth) internal { - vm.deal(to, amountEth); - console2.log("Ether balance:", to, to.balance); - } - - function mintTaikoToken(address to, uint256 amountTko) internal { - bondToken.transfer(to, amountTko); - - vm.prank(to); - bondToken.approve(address(inbox), amountTko); - - console2.log("Bond balance :", to, bondToken.balanceOf(to)); - } - - function setupBondTokenState( - address user, - uint256 initialBondBalance, - uint256 bondAmount - ) - internal - { - vm.deal(user, 1000 ether); - bondToken.transfer(user, initialBondBalance); - - vm.prank(user); - bondToken.approve(address(inbox), bondAmount); - - vm.prank(user); - inbox.depositBond(bondAmount); - } - - function simulateBlockDelay(uint256 secondsPerBlock, uint256 blocksToWait) internal { - uint256 targetBlock = block.number + blocksToWait; - uint256 targetTime = block.timestamp + (blocksToWait * secondsPerBlock); - - vm.roll(targetBlock); - vm.warp(targetTime); - } -} +// import "../Layer1Test.sol"; +// import "test/layer1/based/helpers/Verifier_ToggleStub.sol"; + +// abstract contract InboxTestBase is Layer1Test { +// mapping(uint256 => ITaikoInbox.BlockMetadataV3) internal blockMetadatas; +// ITaikoInbox internal inbox; +// TaikoToken internal bondToken; +// SignalService internal signalService; +// uint256 genesisBlockProposedAt; +// uint256 genesisBlockProposedIn; + +// function getConfig() internal view virtual returns (ITaikoInbox.ConfigV3 memory); + +// modifier transactBy(address transactor) override { +// vm.deal(transactor, 100 ether); +// if (bondToken != TaikoToken(address(0))) { +// bondToken.transfer(transactor, 10_000 ether); +// vm.startPrank(transactor); +// bondToken.approve(address(inbox), type(uint256).max); +// } else { +// vm.startPrank(transactor); +// } + +// _; +// vm.stopPrank(); +// } + +// function setUpOnEthereum() internal virtual override { +// genesisBlockProposedAt = block.timestamp; +// genesisBlockProposedIn = block.number; + +// inbox = deployInbox(correctBlockhash(0), getConfig()); + +// signalService = deploySignalService(address(new SignalService())); +// signalService.authorize(address(inbox), true); + +// resolver.registerAddress( +// block.chainid, "proof_verifier", address(new Verifier_ToggleStub()) +// ); + +// mineOneBlockAndWrap(12 seconds); +// } + +// modifier WhenLogAllBlocksAndTransitions() { +// _logAllBlocksAndTransitions(); +// _; +// } + +// modifier WhenMultipleBlocksAreProposedWithDefaultParameters(uint256 numBlocksToPropose) { +// _proposeBlocksWithDefaultParameters(numBlocksToPropose); +// _; +// } + +// modifier WhenMultipleBlocksAreProvedWithWrongTransitions( +// uint64 startBlockId, +// uint64 endBlockId +// ) { +// _proveBlocksWithWrongTransitions(range(startBlockId, endBlockId)); +// _; +// } + +// modifier WhenMultipleBlocksAreProvedWithCorrectTransitions( +// uint64 startBlockId, +// uint64 endBlockId +// ) { +// _proveBlocksWithCorrectTransitions(range(startBlockId, endBlockId)); +// _; +// } + +// // internal helper functions ------------------------------------------------------------------- + +// function _proposeBlocksWithDefaultParameters(uint256 numBlocksToPropose) +// internal +// returns (uint64[] memory blockIds) +// { +// // Provide a default value for txList +// bytes memory defaultTxList = abi.encodePacked("txList"); +// return _proposeBlocksWithDefaultParameters(numBlocksToPropose, defaultTxList); +// } + +// function _proposeBlocksWithDefaultParameters( +// uint256 numBlocksToPropose, +// bytes memory txList +// ) +// internal +// returns (uint64[] memory blockIds) +// { +// ITaikoInbox.BlockParamsV3[] memory blockParams = +// new ITaikoInbox.BlockParamsV3[](numBlocksToPropose); + +// ITaikoInbox.BlockMetadataV3[] memory metas = +// inbox.proposeBlocksV3(address(0), address(0), blockParams, txList); + +// // Initialize blockIds array +// blockIds = new uint64[](metas.length); +// for (uint256 i; i < metas.length; ++i) { +// blockMetadatas[metas[i].blockId] = metas[i]; +// blockIds[i] = metas[i].blockId; +// } +// } + +// function _proveBlocksWithCorrectTransitions(uint64[] memory blockIds) internal { +// ITaikoInbox.BlockMetadataV3[] memory metas = +// new ITaikoInbox.BlockMetadataV3[](blockIds.length); +// ITaikoInbox.TransitionV3[] memory transitions = +// new ITaikoInbox.TransitionV3[](blockIds.length); + +// for (uint256 i; i < metas.length; ++i) { +// metas[i] = blockMetadatas[blockIds[i]]; +// transitions[i].parentHash = correctBlockhash(blockIds[i] - 1); +// transitions[i].blockHash = correctBlockhash(blockIds[i]); +// transitions[i].stateRoot = correctStateRoot(blockIds[i]); +// } + +// inbox.proveBlocksV3(metas, transitions, "proof"); +// } + +// function _proveBlocksWithWrongTransitions(uint64[] memory blockIds) internal { +// ITaikoInbox.BlockMetadataV3[] memory metas = +// new ITaikoInbox.BlockMetadataV3[](blockIds.length); +// ITaikoInbox.TransitionV3[] memory transitions = +// new ITaikoInbox.TransitionV3[](blockIds.length); + +// for (uint256 i; i < metas.length; ++i) { +// metas[i] = blockMetadatas[blockIds[i]]; +// transitions[i].parentHash = randBytes32(); +// transitions[i].blockHash = randBytes32(); +// transitions[i].stateRoot = randBytes32(); +// } + +// inbox.proveBlocksV3(metas, transitions, "proof"); +// } + +// function _logAllBlocksAndTransitions() internal view { +// console2.log(unicode"|───────────────────────────────────────────────────────────────"); +// ITaikoInbox.Stats1 memory stats1 = inbox.getStats1(); +// console2.log("Stats1 - lastSyncedBlockId:", stats1.lastSyncedBlockId); +// console2.log("Stats1 - lastSyncedAt:", stats1.lastSyncedAt); + +// ITaikoInbox.Stats2 memory stats2 = inbox.getStats2(); +// console2.log("Stats2 - numBlocks:", stats2.numBlocks); +// console2.log("Stats2 - lastVerifiedBlockId:", stats2.lastVerifiedBlockId); +// console2.log("Stats2 - paused:", stats2.paused); +// console2.log("Stats2 - lastProposedIn:", stats2.lastProposedIn); +// console2.log("Stats2 - lastUnpausedAt:", stats2.lastUnpausedAt); + +// // console2.log("stats2.numBlocks:", stats2.numBlocks); +// // console2.log("getConfig().blockRingBufferSize:", getConfig().blockRingBufferSize); + +// uint64 firstBlockId = stats2.numBlocks > getConfig().blockRingBufferSize +// ? stats2.numBlocks - getConfig().blockRingBufferSize +// : 0; + +// for (uint64 i = firstBlockId; i < stats2.numBlocks; ++i) { +// ITaikoInbox.BlockV3 memory blk = inbox.getBlockV3(i); +// if (blk.blockId <= stats2.lastVerifiedBlockId) { +// console2.log(unicode"|─ ✔ block#", blk.blockId); +// } else { +// console2.log(unicode"|─── block#", blk.blockId); +// } +// console2.log(unicode"│ |── metahash:", Strings.toHexString(uint256(blk.metaHash))); +// console2.log(unicode"│ |── timestamp:", blk.timestamp); +// console2.log(unicode"│ |── anchorBlockId:", blk.anchorBlockId); +// console2.log(unicode"│ |── nextTransitionId:", blk.nextTransitionId); +// console2.log(unicode"│ |── verifiedTransitionId:", blk.verifiedTransitionId); + +// for (uint24 j = 1; j < blk.nextTransitionId; ++j) { +// ITaikoInbox.TransitionV3 memory tran = inbox.getTransitionV3(blk.blockId, j); +// console2.log(unicode"│ |── transition#", j); +// console2.log( +// unicode"│ │ |── parentHash:", +// Strings.toHexString(uint256(tran.parentHash)) +// ); +// console2.log( +// unicode"│ │ |── blockHash:", +// Strings.toHexString(uint256(tran.blockHash)) +// ); +// console2.log( +// unicode"│ │ └── stateRoot:", +// Strings.toHexString(uint256(tran.stateRoot)) +// ); +// } +// } +// console2.log(""); +// } + +// function correctBlockhash(uint256 blockId) internal pure returns (bytes32) { +// return bytes32(0x1000000 + blockId); +// } + +// function correctStateRoot(uint256 blockId) internal pure returns (bytes32) { +// return bytes32(0x2000000 + blockId); +// } + +// function range(uint64 start, uint64 end) internal pure returns (uint64[] memory arr) { +// arr = new uint64[](end - start); +// for (uint64 i; i < arr.length; ++i) { +// arr[i] = start + i; +// } +// } + +// function mintEther(address to, uint256 amountEth) internal { +// vm.deal(to, amountEth); +// console2.log("Ether balance:", to, to.balance); +// } + +// function mintTaikoToken(address to, uint256 amountTko) internal { +// bondToken.transfer(to, amountTko); + +// vm.prank(to); +// bondToken.approve(address(inbox), amountTko); + +// console2.log("Bond balance :", to, bondToken.balanceOf(to)); +// } + +// function setupBondTokenState( +// address user, +// uint256 initialBondBalance, +// uint256 bondAmount +// ) +// internal +// { +// vm.deal(user, 1000 ether); +// bondToken.transfer(user, initialBondBalance); + +// vm.prank(user); +// bondToken.approve(address(inbox), bondAmount); + +// vm.prank(user); +// inbox.depositBond(bondAmount); +// } + +// function simulateBlockDelay(uint256 secondsPerBlock, uint256 blocksToWait) internal { +// uint256 targetBlock = block.number + blocksToWait; +// uint256 targetTime = block.timestamp + (blocksToWait * secondsPerBlock); + +// vm.roll(targetBlock); +// vm.warp(targetTime); +// } +// } diff --git a/packages/protocol/test/layer1/based/InboxTest_BondMechanics.t.sol b/packages/protocol/test/layer1/based/InboxTest_BondMechanics.t.sol index 0bd0f97a68e..50fdcfda70b 100644 --- a/packages/protocol/test/layer1/based/InboxTest_BondMechanics.t.sol +++ b/packages/protocol/test/layer1/based/InboxTest_BondMechanics.t.sol @@ -1,131 +1,131 @@ // SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.24; -import "contracts/layer1/based/ITaikoInbox.sol"; -import "./InboxTestBase.sol"; - -contract InboxTest_BondMechanics is InboxTestBase { - uint16 constant provingWindow = 1 hours; - - function getConfig() internal pure override returns (ITaikoInbox.ConfigV3 memory) { - return ITaikoInbox.ConfigV3({ - chainId: LibNetwork.TAIKO_MAINNET, - blockMaxProposals: 10, - blockRingBufferSize: 15, - maxBlocksToVerify: 5, - blockMaxGasLimit: 240_000_000, - livenessBond: 125e18, // 125 Taiko token - stateRootSyncInternal: 5, - maxAnchorHeightOffset: 64, - baseFeeConfig: LibSharedData.BaseFeeConfig({ - adjustmentQuotient: 8, - sharingPctg: 75, - gasIssuancePerSecond: 5_000_000, - minGasExcess: 1_340_000_000, // correspond to 0.008847185 gwei basefee - maxGasIssuancePerBlock: 600_000_000 // two minutes: 5_000_000 * 120 - }), - provingWindow: provingWindow, - maxSignalsToReceive: 16, - forkHeights: ITaikoInbox.ForkHeights({ ontake: 0, pacaya: 0 }) - }); - } - - function setUpOnEthereum() internal override { - super.setUpOnEthereum(); - bondToken = deployBondToken(); - } - - function test_inbox_bonds_debit_and_credit_on_proposal_and_proof() external { - vm.warp(1_000_000); - - uint256 initialBondBalance = 100_000 ether; - uint256 bondAmount = 1000 ether; - - setupBondTokenState(Alice, initialBondBalance, bondAmount); - - vm.prank(Alice); - uint64[] memory blockIds = _proposeBlocksWithDefaultParameters({ numBlocksToPropose: 1 }); - assertEq(inbox.bondBalanceOf(Alice) < bondAmount, true); - - vm.prank(Alice); - _proveBlocksWithCorrectTransitions(blockIds); - - assertEq(inbox.bondBalanceOf(Alice), bondAmount); - } - - function test_only_proposer_can_prove_block_before_deadline() external { - vm.warp(1_000_000); - - uint256 initialBondBalance = 100_000 ether; - uint256 bondAmount = 1000 ether; - - setupBondTokenState(Alice, initialBondBalance, bondAmount); - setupBondTokenState(Bob, initialBondBalance, bondAmount); - - vm.prank(Alice); - uint64[] memory blockIds = _proposeBlocksWithDefaultParameters({ numBlocksToPropose: 1 }); - assertEq(inbox.bondBalanceOf(Alice) < bondAmount, true); - - vm.prank(Bob); - vm.expectRevert(ITaikoInbox.ProverNotPermitted.selector); - _proveBlocksWithCorrectTransitions(blockIds); - - assertEq(inbox.bondBalanceOf(Bob), bondAmount); - } - - function test_inbox_bonds_debited_on_proposal_not_credited_back_if_proved_after_deadline() - external - { - vm.warp(1_000_000); - - uint256 initialBondBalance = 100_000 ether; - uint256 bondAmount = 1000 ether; - - setupBondTokenState(Alice, initialBondBalance, bondAmount); - - vm.prank(Alice); - uint64[] memory blockIds = _proposeBlocksWithDefaultParameters({ numBlocksToPropose: 1 }); - - uint256 aliceBondBalanceAfterProposal = inbox.bondBalanceOf(Alice); - assertEq(aliceBondBalanceAfterProposal < bondAmount, true); - - // Simulate waiting for blocks after proving deadline - uint256 secondsPerBlock = 12; - uint256 blocksToWait = provingWindow / secondsPerBlock + 1; - simulateBlockDelay(secondsPerBlock, blocksToWait); - - vm.prank(Alice); - _proveBlocksWithCorrectTransitions(blockIds); - - uint256 aliceBondBalanceAfterProof = inbox.bondBalanceOf(Alice); - assertEq(aliceBondBalanceAfterProof, aliceBondBalanceAfterProposal); - assertEq(aliceBondBalanceAfterProof < bondAmount, true); - } - - function test_inbox_bonds_debit_and_credit_on_proposal_and_proof_with_exact_proving_window() - external - { - vm.warp(1_000_000); +// import "contracts/layer1/based/ITaikoInbox.sol"; +// import "./InboxTestBase.sol"; + +// contract InboxTest_BondMechanics is InboxTestBase { +// uint16 constant provingWindow = 1 hours; + +// function getConfig() internal pure override returns (ITaikoInbox.ConfigV3 memory) { +// return ITaikoInbox.ConfigV3({ +// chainId: LibNetwork.TAIKO_MAINNET, +// blockMaxProposals: 10, +// blockRingBufferSize: 15, +// maxBlocksToVerify: 5, +// blockMaxGasLimit: 240_000_000, +// livenessBond: 125e18, // 125 Taiko token +// stateRootSyncInternal: 5, +// maxAnchorHeightOffset: 64, +// baseFeeConfig: LibSharedData.BaseFeeConfig({ +// adjustmentQuotient: 8, +// sharingPctg: 75, +// gasIssuancePerSecond: 5_000_000, +// minGasExcess: 1_340_000_000, // correspond to 0.008847185 gwei basefee +// maxGasIssuancePerBlock: 600_000_000 // two minutes: 5_000_000 * 120 +// }), +// provingWindow: provingWindow, +// maxSignalsToReceive: 16, +// forkHeights: ITaikoInbox.ForkHeights({ ontake: 0, pacaya: 0 }) +// }); +// } + +// function setUpOnEthereum() internal override { +// super.setUpOnEthereum(); +// bondToken = deployBondToken(); +// } + +// function test_inbox_bonds_debit_and_credit_on_proposal_and_proof() external { +// vm.warp(1_000_000); + +// uint256 initialBondBalance = 100_000 ether; +// uint256 bondAmount = 1000 ether; + +// setupBondTokenState(Alice, initialBondBalance, bondAmount); + +// vm.prank(Alice); +// uint64[] memory blockIds = _proposeBlocksWithDefaultParameters({ numBlocksToPropose: 1 }); +// assertEq(inbox.bondBalanceOf(Alice) < bondAmount, true); + +// vm.prank(Alice); +// _proveBlocksWithCorrectTransitions(blockIds); + +// assertEq(inbox.bondBalanceOf(Alice), bondAmount); +// } + +// function test_only_proposer_can_prove_block_before_deadline() external { +// vm.warp(1_000_000); + +// uint256 initialBondBalance = 100_000 ether; +// uint256 bondAmount = 1000 ether; + +// setupBondTokenState(Alice, initialBondBalance, bondAmount); +// setupBondTokenState(Bob, initialBondBalance, bondAmount); + +// vm.prank(Alice); +// uint64[] memory blockIds = _proposeBlocksWithDefaultParameters({ numBlocksToPropose: 1 }); +// assertEq(inbox.bondBalanceOf(Alice) < bondAmount, true); + +// vm.prank(Bob); +// vm.expectRevert(ITaikoInbox.ProverNotPermitted.selector); +// _proveBlocksWithCorrectTransitions(blockIds); + +// assertEq(inbox.bondBalanceOf(Bob), bondAmount); +// } + +// function test_inbox_bonds_debited_on_proposal_not_credited_back_if_proved_after_deadline() +// external +// { +// vm.warp(1_000_000); + +// uint256 initialBondBalance = 100_000 ether; +// uint256 bondAmount = 1000 ether; + +// setupBondTokenState(Alice, initialBondBalance, bondAmount); + +// vm.prank(Alice); +// uint64[] memory blockIds = _proposeBlocksWithDefaultParameters({ numBlocksToPropose: 1 }); + +// uint256 aliceBondBalanceAfterProposal = inbox.bondBalanceOf(Alice); +// assertEq(aliceBondBalanceAfterProposal < bondAmount, true); + +// // Simulate waiting for blocks after proving deadline +// uint256 secondsPerBlock = 12; +// uint256 blocksToWait = provingWindow / secondsPerBlock + 1; +// simulateBlockDelay(secondsPerBlock, blocksToWait); + +// vm.prank(Alice); +// _proveBlocksWithCorrectTransitions(blockIds); + +// uint256 aliceBondBalanceAfterProof = inbox.bondBalanceOf(Alice); +// assertEq(aliceBondBalanceAfterProof, aliceBondBalanceAfterProposal); +// assertEq(aliceBondBalanceAfterProof < bondAmount, true); +// } + +// function test_inbox_bonds_debit_and_credit_on_proposal_and_proof_with_exact_proving_window() +// external +// { +// vm.warp(1_000_000); - uint256 initialBondBalance = 100_000 ether; - uint256 bondAmount = 1000 ether; - - setupBondTokenState(Alice, initialBondBalance, bondAmount); +// uint256 initialBondBalance = 100_000 ether; +// uint256 bondAmount = 1000 ether; + +// setupBondTokenState(Alice, initialBondBalance, bondAmount); - vm.prank(Alice); - uint64[] memory blockIds = _proposeBlocksWithDefaultParameters({ numBlocksToPropose: 1 }); +// vm.prank(Alice); +// uint64[] memory blockIds = _proposeBlocksWithDefaultParameters({ numBlocksToPropose: 1 }); - uint256 aliceBondBalanceAfterProposal = inbox.bondBalanceOf(Alice); - assertEq(aliceBondBalanceAfterProposal < bondAmount, true); +// uint256 aliceBondBalanceAfterProposal = inbox.bondBalanceOf(Alice); +// assertEq(aliceBondBalanceAfterProposal < bondAmount, true); - // Simulate waiting for exactly the proving window - uint256 secondsPerBlock = 12; - uint256 blocksToWait = provingWindow / secondsPerBlock; - simulateBlockDelay(secondsPerBlock, blocksToWait); +// // Simulate waiting for exactly the proving window +// uint256 secondsPerBlock = 12; +// uint256 blocksToWait = provingWindow / secondsPerBlock; +// simulateBlockDelay(secondsPerBlock, blocksToWait); - vm.prank(Alice); - _proveBlocksWithCorrectTransitions(blockIds); +// vm.prank(Alice); +// _proveBlocksWithCorrectTransitions(blockIds); - assertEq(inbox.bondBalanceOf(Alice), bondAmount); - } -} +// assertEq(inbox.bondBalanceOf(Alice), bondAmount); +// } +// } diff --git a/packages/protocol/test/layer1/based/InboxTest_BondToken.sol b/packages/protocol/test/layer1/based/InboxTest_BondToken.sol index 833cec2638c..4c222094abb 100644 --- a/packages/protocol/test/layer1/based/InboxTest_BondToken.sol +++ b/packages/protocol/test/layer1/based/InboxTest_BondToken.sol @@ -1,199 +1,199 @@ // SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.24; -import "contracts/layer1/based/ITaikoInbox.sol"; -import "./InboxTestBase.sol"; - -contract InboxTest_BondToken is InboxTestBase { - function getConfig() internal pure override returns (ITaikoInbox.ConfigV3 memory) { - return ITaikoInbox.ConfigV3({ - chainId: LibNetwork.TAIKO_MAINNET, - blockMaxProposals: 10, - blockRingBufferSize: 15, - maxBlocksToVerify: 5, - blockMaxGasLimit: 240_000_000, - livenessBond: 125e18, // 125 Taiko token - stateRootSyncInternal: 5, - maxAnchorHeightOffset: 64, - baseFeeConfig: LibSharedData.BaseFeeConfig({ - adjustmentQuotient: 8, - sharingPctg: 75, - gasIssuancePerSecond: 5_000_000, - minGasExcess: 1_340_000_000, // correspond to 0.008847185 gwei basefee - maxGasIssuancePerBlock: 600_000_000 // two minutes: 5_000_000 * 120 - }), - provingWindow: 1 hours, - maxSignalsToReceive: 16, - forkHeights: ITaikoInbox.ForkHeights({ ontake: 0, pacaya: 0 }) - }); - } - - function setUpOnEthereum() internal override { - super.setUpOnEthereum(); - bondToken = deployBondToken(); - } - - function test_inbox_deposit_withdraw() external { - vm.warp(1_000_000); - vm.deal(Alice, 1000 ether); - - uint256 transferAmount = 1234 ether; - bondToken.transfer(Alice, transferAmount); - assertEq(bondToken.balanceOf(Alice), transferAmount); - - uint256 depositAmount = 1 ether; - uint256 withdrawAmount = 0.5 ether; - - vm.prank(Alice); - bondToken.approve(address(inbox), depositAmount); - - vm.prank(Alice); - inbox.depositBond(depositAmount); - assertEq(inbox.bondBalanceOf(Alice), depositAmount); - - vm.prank(Alice); - inbox.withdrawBond(withdrawAmount); - assertEq(inbox.bondBalanceOf(Alice), depositAmount - withdrawAmount); - } - - function test_inbox_withdraw_more_than_bond_balance() external { - vm.warp(1_000_000); - vm.deal(Alice, 1000 ether); - - uint256 transferAmount = 10 ether; - uint256 depositAmount = 1 ether; - uint256 withdrawAmount = 2 ether; - - bondToken.transfer(Alice, transferAmount); - - vm.prank(Alice); - bondToken.approve(address(inbox), depositAmount); - - vm.prank(Alice); - inbox.depositBond(depositAmount); - - vm.prank(Alice); - vm.expectRevert(ITaikoInbox.InsufficientBond.selector); - inbox.withdrawBond(withdrawAmount); - } - - function test_inbox_insufficient_approval() external { - vm.warp(1_000_000); - vm.deal(Alice, 1000 ether); - - uint256 transferAmount = 10 ether; - uint256 insufficientApproval = 5 ether; - uint256 depositAmount = 10 ether; - - bondToken.transfer(Alice, transferAmount); - - vm.prank(Alice); - bondToken.approve(address(inbox), insufficientApproval); - - vm.prank(Alice); - vm.expectRevert("ERC20: insufficient allowance"); - inbox.depositBond(depositAmount); - } - - function test_inbox_exceeding_balance() external { - vm.warp(1_000_000); - vm.deal(Alice, 1000 ether); - - uint256 transferAmount = 10 ether; - uint256 depositAmount = 12 ether; - - bondToken.transfer(Alice, transferAmount); - - vm.prank(Alice); - bondToken.approve(address(inbox), depositAmount); - - vm.prank(Alice); - vm.expectRevert("ERC20: transfer amount exceeds balance"); - inbox.depositBond(depositAmount); - } - - function test_inbox_no_value_sent_on_deposit() external { - vm.warp(1_000_000); - vm.deal(Alice, 1000 ether); - - uint256 transferAmount = 10 ether; - uint256 depositAmount = 1 ether; +// import "contracts/layer1/based/ITaikoInbox.sol"; +// import "./InboxTestBase.sol"; + +// contract InboxTest_BondToken is InboxTestBase { +// function getConfig() internal pure override returns (ITaikoInbox.ConfigV3 memory) { +// return ITaikoInbox.ConfigV3({ +// chainId: LibNetwork.TAIKO_MAINNET, +// blockMaxProposals: 10, +// blockRingBufferSize: 15, +// maxBlocksToVerify: 5, +// blockMaxGasLimit: 240_000_000, +// livenessBond: 125e18, // 125 Taiko token +// stateRootSyncInternal: 5, +// maxAnchorHeightOffset: 64, +// baseFeeConfig: LibSharedData.BaseFeeConfig({ +// adjustmentQuotient: 8, +// sharingPctg: 75, +// gasIssuancePerSecond: 5_000_000, +// minGasExcess: 1_340_000_000, // correspond to 0.008847185 gwei basefee +// maxGasIssuancePerBlock: 600_000_000 // two minutes: 5_000_000 * 120 +// }), +// provingWindow: 1 hours, +// maxSignalsToReceive: 16, +// forkHeights: ITaikoInbox.ForkHeights({ ontake: 0, pacaya: 0 }) +// }); +// } + +// function setUpOnEthereum() internal override { +// super.setUpOnEthereum(); +// bondToken = deployBondToken(); +// } + +// function test_inbox_deposit_withdraw() external { +// vm.warp(1_000_000); +// vm.deal(Alice, 1000 ether); + +// uint256 transferAmount = 1234 ether; +// bondToken.transfer(Alice, transferAmount); +// assertEq(bondToken.balanceOf(Alice), transferAmount); + +// uint256 depositAmount = 1 ether; +// uint256 withdrawAmount = 0.5 ether; + +// vm.prank(Alice); +// bondToken.approve(address(inbox), depositAmount); + +// vm.prank(Alice); +// inbox.depositBond(depositAmount); +// assertEq(inbox.bondBalanceOf(Alice), depositAmount); + +// vm.prank(Alice); +// inbox.withdrawBond(withdrawAmount); +// assertEq(inbox.bondBalanceOf(Alice), depositAmount - withdrawAmount); +// } + +// function test_inbox_withdraw_more_than_bond_balance() external { +// vm.warp(1_000_000); +// vm.deal(Alice, 1000 ether); + +// uint256 transferAmount = 10 ether; +// uint256 depositAmount = 1 ether; +// uint256 withdrawAmount = 2 ether; + +// bondToken.transfer(Alice, transferAmount); + +// vm.prank(Alice); +// bondToken.approve(address(inbox), depositAmount); + +// vm.prank(Alice); +// inbox.depositBond(depositAmount); + +// vm.prank(Alice); +// vm.expectRevert(ITaikoInbox.InsufficientBond.selector); +// inbox.withdrawBond(withdrawAmount); +// } + +// function test_inbox_insufficient_approval() external { +// vm.warp(1_000_000); +// vm.deal(Alice, 1000 ether); + +// uint256 transferAmount = 10 ether; +// uint256 insufficientApproval = 5 ether; +// uint256 depositAmount = 10 ether; + +// bondToken.transfer(Alice, transferAmount); + +// vm.prank(Alice); +// bondToken.approve(address(inbox), insufficientApproval); + +// vm.prank(Alice); +// vm.expectRevert("ERC20: insufficient allowance"); +// inbox.depositBond(depositAmount); +// } + +// function test_inbox_exceeding_balance() external { +// vm.warp(1_000_000); +// vm.deal(Alice, 1000 ether); + +// uint256 transferAmount = 10 ether; +// uint256 depositAmount = 12 ether; + +// bondToken.transfer(Alice, transferAmount); + +// vm.prank(Alice); +// bondToken.approve(address(inbox), depositAmount); + +// vm.prank(Alice); +// vm.expectRevert("ERC20: transfer amount exceeds balance"); +// inbox.depositBond(depositAmount); +// } + +// function test_inbox_no_value_sent_on_deposit() external { +// vm.warp(1_000_000); +// vm.deal(Alice, 1000 ether); + +// uint256 transferAmount = 10 ether; +// uint256 depositAmount = 1 ether; - bondToken.transfer(Alice, transferAmount); +// bondToken.transfer(Alice, transferAmount); - vm.prank(Alice); - bondToken.approve(address(inbox), depositAmount); +// vm.prank(Alice); +// bondToken.approve(address(inbox), depositAmount); - vm.prank(Alice); - vm.expectRevert(ITaikoInbox.MsgValueNotZero.selector); - inbox.depositBond{ value: 1 }(depositAmount); - } +// vm.prank(Alice); +// vm.expectRevert(ITaikoInbox.MsgValueNotZero.selector); +// inbox.depositBond{ value: 1 }(depositAmount); +// } - function test_inbox_deposit_and_withdraw_from_multiple_users() external { - vm.warp(1_000_000); - vm.deal(Alice, 1000 ether); - vm.deal(Bob, 50 ether); +// function test_inbox_deposit_and_withdraw_from_multiple_users() external { +// vm.warp(1_000_000); +// vm.deal(Alice, 1000 ether); +// vm.deal(Bob, 50 ether); - uint256 transferAmountAlice = 20 ether; - uint256 transferAmountBob = 10 ether; +// uint256 transferAmountAlice = 20 ether; +// uint256 transferAmountBob = 10 ether; - // Transfer bond tokens to Alice and Bob - bondToken.transfer(Alice, transferAmountAlice); - assertEq(bondToken.balanceOf(Alice), transferAmountAlice); +// // Transfer bond tokens to Alice and Bob +// bondToken.transfer(Alice, transferAmountAlice); +// assertEq(bondToken.balanceOf(Alice), transferAmountAlice); - bondToken.transfer(Bob, transferAmountBob); - assertEq(bondToken.balanceOf(Bob), transferAmountBob); +// bondToken.transfer(Bob, transferAmountBob); +// assertEq(bondToken.balanceOf(Bob), transferAmountBob); - uint256 aliceFirstDeposit = 2 ether; - uint256 aliceSecondDeposit = 3 ether; - uint256 aliceFirstWithdraw = 1 ether; - uint256 aliceSecondWithdraw = 1.5 ether; +// uint256 aliceFirstDeposit = 2 ether; +// uint256 aliceSecondDeposit = 3 ether; +// uint256 aliceFirstWithdraw = 1 ether; +// uint256 aliceSecondWithdraw = 1.5 ether; - uint256 bobDeposit = 5 ether; - uint256 bobWithdraw = 2 ether; +// uint256 bobDeposit = 5 ether; +// uint256 bobWithdraw = 2 ether; - vm.prank(Alice); - bondToken.approve(address(inbox), aliceFirstDeposit); +// vm.prank(Alice); +// bondToken.approve(address(inbox), aliceFirstDeposit); - vm.prank(Alice); - inbox.depositBond(aliceFirstDeposit); - assertEq(inbox.bondBalanceOf(Alice), aliceFirstDeposit); +// vm.prank(Alice); +// inbox.depositBond(aliceFirstDeposit); +// assertEq(inbox.bondBalanceOf(Alice), aliceFirstDeposit); - vm.prank(Bob); - bondToken.approve(address(inbox), bobDeposit); +// vm.prank(Bob); +// bondToken.approve(address(inbox), bobDeposit); - vm.prank(Bob); - inbox.depositBond(bobDeposit); - assertEq(inbox.bondBalanceOf(Bob), bobDeposit); +// vm.prank(Bob); +// inbox.depositBond(bobDeposit); +// assertEq(inbox.bondBalanceOf(Bob), bobDeposit); - vm.prank(Alice); - bondToken.approve(address(inbox), aliceSecondDeposit); +// vm.prank(Alice); +// bondToken.approve(address(inbox), aliceSecondDeposit); - vm.prank(Alice); - inbox.depositBond(aliceSecondDeposit); - assertEq(inbox.bondBalanceOf(Alice), aliceFirstDeposit + aliceSecondDeposit); +// vm.prank(Alice); +// inbox.depositBond(aliceSecondDeposit); +// assertEq(inbox.bondBalanceOf(Alice), aliceFirstDeposit + aliceSecondDeposit); - vm.prank(Bob); - inbox.withdrawBond(bobWithdraw); - assertEq(inbox.bondBalanceOf(Bob), bobDeposit - bobWithdraw); +// vm.prank(Bob); +// inbox.withdrawBond(bobWithdraw); +// assertEq(inbox.bondBalanceOf(Bob), bobDeposit - bobWithdraw); - vm.prank(Alice); - inbox.withdrawBond(aliceFirstWithdraw); - assertEq( - inbox.bondBalanceOf(Alice), aliceFirstDeposit + aliceSecondDeposit - aliceFirstWithdraw - ); +// vm.prank(Alice); +// inbox.withdrawBond(aliceFirstWithdraw); +// assertEq( +// inbox.bondBalanceOf(Alice), aliceFirstDeposit + aliceSecondDeposit - aliceFirstWithdraw +// ); - vm.prank(Alice); - inbox.withdrawBond(aliceSecondWithdraw); - assertEq( - inbox.bondBalanceOf(Alice), - aliceFirstDeposit + aliceSecondDeposit - aliceFirstWithdraw - aliceSecondWithdraw - ); +// vm.prank(Alice); +// inbox.withdrawBond(aliceSecondWithdraw); +// assertEq( +// inbox.bondBalanceOf(Alice), +// aliceFirstDeposit + aliceSecondDeposit - aliceFirstWithdraw - aliceSecondWithdraw +// ); - assertEq( - inbox.bondBalanceOf(Alice), - aliceFirstDeposit + aliceSecondDeposit - aliceFirstWithdraw - aliceSecondWithdraw - ); - assertEq(inbox.bondBalanceOf(Bob), bobDeposit - bobWithdraw); - } -} +// assertEq( +// inbox.bondBalanceOf(Alice), +// aliceFirstDeposit + aliceSecondDeposit - aliceFirstWithdraw - aliceSecondWithdraw +// ); +// assertEq(inbox.bondBalanceOf(Bob), bobDeposit - bobWithdraw); +// } +// } diff --git a/packages/protocol/test/layer1/based/InboxTest_CalldataForTxList.t.sol b/packages/protocol/test/layer1/based/InboxTest_CalldataForTxList.t.sol index c2055c674ac..700ecb1eb65 100644 --- a/packages/protocol/test/layer1/based/InboxTest_CalldataForTxList.t.sol +++ b/packages/protocol/test/layer1/based/InboxTest_CalldataForTxList.t.sol @@ -1,175 +1,175 @@ // SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.24; -import "contracts/layer1/based/ITaikoInbox.sol"; -import "./InboxTestBase.sol"; - -contract InboxTest_CalldataForTxList is InboxTestBase { - function getConfig() internal pure override returns (ITaikoInbox.ConfigV3 memory) { - return ITaikoInbox.ConfigV3({ - chainId: LibNetwork.TAIKO_MAINNET, - blockMaxProposals: 10, - blockRingBufferSize: 15, - maxBlocksToVerify: 5, - blockMaxGasLimit: 240_000_000, - livenessBond: 125e18, // 125 Taiko token - stateRootSyncInternal: 5, - maxAnchorHeightOffset: 64, - baseFeeConfig: LibSharedData.BaseFeeConfig({ - adjustmentQuotient: 8, - sharingPctg: 75, - gasIssuancePerSecond: 5_000_000, - minGasExcess: 1_340_000_000, // correspond to 0.008847185 gwei basefee - maxGasIssuancePerBlock: 600_000_000 // two minutes: 5_000_000 * 120 - }), - provingWindow: 1 hours, - maxSignalsToReceive: 16, - forkHeights: ITaikoInbox.ForkHeights({ ontake: 0, pacaya: 0 }) - }); - } - - function setUpOnEthereum() internal override { - super.setUpOnEthereum(); - bondToken = deployBondToken(); - } - - function test_calldata_used_for_txlist_da() external { - vm.warp(1_000_000); - - uint256 initialBondBalance = 100_000 ether; - uint256 bondAmount = 1000 ether; - - setupBondTokenState(Alice, initialBondBalance, bondAmount); - - // Define the txList in calldata - bytes memory txList = abi.encodePacked("txList"); - bytes32 expectedHash = keccak256(txList); - - vm.prank(Alice); - uint64[] memory blockIds = - _proposeBlocksWithDefaultParameters({ numBlocksToPropose: 1, txList: txList }); - for (uint256 i; i < blockIds.length; ++i) { - ITaikoInbox.BlockMetadataV3 memory meta = blockMetadatas[blockIds[i]]; - assertEq(meta.txListHash, expectedHash); - } - - vm.prank(Alice); - _proveBlocksWithCorrectTransitions(blockIds); - } - - function test_block_rejection_due_to_missing_txlist_and_blobindex() external { - vm.warp(1_000_000); - - uint256 initialBondBalance = 100_000 ether; - uint256 bondAmount = 1000 ether; - - setupBondTokenState(Alice, initialBondBalance, bondAmount); - - // Define empty txList - bytes memory txList = ""; - ITaikoInbox.BlockParamsV3[] memory blockParams = new ITaikoInbox.BlockParamsV3[](1); - blockParams[0].blobIndex = 0; // Blob index not provided - - vm.prank(Alice); - vm.expectRevert(ITaikoInbox.BlobIndexZero.selector); - inbox.proposeBlocksV3(address(0), address(0), blockParams, txList); - } - - function test_propose_block_with_empty_txlist_and_valid_blobindex() external { - vm.warp(1_000_000); - - uint256 initialBondBalance = 100_000 ether; - uint256 bondAmount = 1000 ether; - - setupBondTokenState(Alice, initialBondBalance, bondAmount); - - // Define empty txList - bytes memory txList = ""; - ITaikoInbox.BlockParamsV3[] memory blockParams = new ITaikoInbox.BlockParamsV3[](1); - blockParams[0].blobIndex = 1; // Valid blob index - - vm.prank(Alice); - ITaikoInbox.BlockMetadataV3[] memory metas = - inbox.proposeBlocksV3(address(0), address(0), blockParams, txList); - - ITaikoInbox.BlockMetadataV3 memory meta = metas[0]; - assertTrue(meta.txListHash != 0, "txListHash should not be zero for valid blobIndex"); - - vm.prank(Alice); - uint64[] memory blockIds = new uint64[](metas.length); - for (uint256 i; i < metas.length; ++i) { - blockMetadatas[metas[i].blockId] = metas[i]; - blockIds[i] = metas[i].blockId; - } - _proveBlocksWithCorrectTransitions(blockIds); - } - - function test_multiple_blocks_with_different_txlist() external { - vm.warp(1_000_000); - - uint256 initialBondBalance = 100_000 ether; - uint256 bondAmount = 1000 ether; - - setupBondTokenState(Alice, initialBondBalance, bondAmount); - - bytes memory txList1 = abi.encodePacked("txList1"); - bytes memory txList2 = abi.encodePacked("txList2"); - bytes32 expectedHash1 = keccak256(txList1); - bytes32 expectedHash2 = keccak256(txList2); - - vm.prank(Alice); - uint64[] memory blockIds1 = _proposeBlocksWithDefaultParameters(1, txList1); - ITaikoInbox.BlockMetadataV3 memory meta1 = blockMetadatas[blockIds1[0]]; - assertEq(meta1.txListHash, expectedHash1, "txListHash mismatch for block 1"); - - vm.prank(Alice); - uint64[] memory blockIds2 = _proposeBlocksWithDefaultParameters(1, txList2); - ITaikoInbox.BlockMetadataV3 memory meta2 = blockMetadatas[blockIds2[0]]; - assertEq(meta2.txListHash, expectedHash2, "txListHash mismatch for block 2"); +// import "contracts/layer1/based/ITaikoInbox.sol"; +// import "./InboxTestBase.sol"; + +// contract InboxTest_CalldataForTxList is InboxTestBase { +// function getConfig() internal pure override returns (ITaikoInbox.ConfigV3 memory) { +// return ITaikoInbox.ConfigV3({ +// chainId: LibNetwork.TAIKO_MAINNET, +// blockMaxProposals: 10, +// blockRingBufferSize: 15, +// maxBlocksToVerify: 5, +// blockMaxGasLimit: 240_000_000, +// livenessBond: 125e18, // 125 Taiko token +// stateRootSyncInternal: 5, +// maxAnchorHeightOffset: 64, +// baseFeeConfig: LibSharedData.BaseFeeConfig({ +// adjustmentQuotient: 8, +// sharingPctg: 75, +// gasIssuancePerSecond: 5_000_000, +// minGasExcess: 1_340_000_000, // correspond to 0.008847185 gwei basefee +// maxGasIssuancePerBlock: 600_000_000 // two minutes: 5_000_000 * 120 +// }), +// provingWindow: 1 hours, +// maxSignalsToReceive: 16, +// forkHeights: ITaikoInbox.ForkHeights({ ontake: 0, pacaya: 0 }) +// }); +// } + +// function setUpOnEthereum() internal override { +// super.setUpOnEthereum(); +// bondToken = deployBondToken(); +// } + +// function test_calldata_used_for_txlist_da() external { +// vm.warp(1_000_000); + +// uint256 initialBondBalance = 100_000 ether; +// uint256 bondAmount = 1000 ether; + +// setupBondTokenState(Alice, initialBondBalance, bondAmount); + +// // Define the txList in calldata +// bytes memory txList = abi.encodePacked("txList"); +// bytes32 expectedHash = keccak256(txList); + +// vm.prank(Alice); +// uint64[] memory blockIds = +// _proposeBlocksWithDefaultParameters({ numBlocksToPropose: 1, txList: txList }); +// for (uint256 i; i < blockIds.length; ++i) { +// ITaikoInbox.BlockMetadataV3 memory meta = blockMetadatas[blockIds[i]]; +// assertEq(meta.txListHash, expectedHash); +// } + +// vm.prank(Alice); +// _proveBlocksWithCorrectTransitions(blockIds); +// } + +// function test_block_rejection_due_to_missing_txlist_and_blobindex() external { +// vm.warp(1_000_000); + +// uint256 initialBondBalance = 100_000 ether; +// uint256 bondAmount = 1000 ether; + +// setupBondTokenState(Alice, initialBondBalance, bondAmount); + +// // Define empty txList +// bytes memory txList = ""; +// ITaikoInbox.BlockParamsV3[] memory blockParams = new ITaikoInbox.BlockParamsV3[](1); +// blockParams[0].blobIndex = 0; // Blob index not provided + +// vm.prank(Alice); +// vm.expectRevert(ITaikoInbox.BlobIndexZero.selector); +// inbox.proposeBlocksV3(address(0), address(0), blockParams, txList); +// } + +// function test_propose_block_with_empty_txlist_and_valid_blobindex() external { +// vm.warp(1_000_000); + +// uint256 initialBondBalance = 100_000 ether; +// uint256 bondAmount = 1000 ether; + +// setupBondTokenState(Alice, initialBondBalance, bondAmount); + +// // Define empty txList +// bytes memory txList = ""; +// ITaikoInbox.BlockParamsV3[] memory blockParams = new ITaikoInbox.BlockParamsV3[](1); +// blockParams[0].blobIndex = 1; // Valid blob index + +// vm.prank(Alice); +// ITaikoInbox.BlockMetadataV3[] memory metas = +// inbox.proposeBlocksV3(address(0), address(0), blockParams, txList); + +// ITaikoInbox.BlockMetadataV3 memory meta = metas[0]; +// assertTrue(meta.txListHash != 0, "txListHash should not be zero for valid blobIndex"); + +// vm.prank(Alice); +// uint64[] memory blockIds = new uint64[](metas.length); +// for (uint256 i; i < metas.length; ++i) { +// blockMetadatas[metas[i].blockId] = metas[i]; +// blockIds[i] = metas[i].blockId; +// } +// _proveBlocksWithCorrectTransitions(blockIds); +// } + +// function test_multiple_blocks_with_different_txlist() external { +// vm.warp(1_000_000); + +// uint256 initialBondBalance = 100_000 ether; +// uint256 bondAmount = 1000 ether; + +// setupBondTokenState(Alice, initialBondBalance, bondAmount); + +// bytes memory txList1 = abi.encodePacked("txList1"); +// bytes memory txList2 = abi.encodePacked("txList2"); +// bytes32 expectedHash1 = keccak256(txList1); +// bytes32 expectedHash2 = keccak256(txList2); + +// vm.prank(Alice); +// uint64[] memory blockIds1 = _proposeBlocksWithDefaultParameters(1, txList1); +// ITaikoInbox.BlockMetadataV3 memory meta1 = blockMetadatas[blockIds1[0]]; +// assertEq(meta1.txListHash, expectedHash1, "txListHash mismatch for block 1"); + +// vm.prank(Alice); +// uint64[] memory blockIds2 = _proposeBlocksWithDefaultParameters(1, txList2); +// ITaikoInbox.BlockMetadataV3 memory meta2 = blockMetadatas[blockIds2[0]]; +// assertEq(meta2.txListHash, expectedHash2, "txListHash mismatch for block 2"); - vm.prank(Alice); - _proveBlocksWithCorrectTransitions(blockIds2); +// vm.prank(Alice); +// _proveBlocksWithCorrectTransitions(blockIds2); - vm.prank(Alice); - _proveBlocksWithCorrectTransitions(blockIds1); - } +// vm.prank(Alice); +// _proveBlocksWithCorrectTransitions(blockIds1); +// } - function test_prove_block_with_mismatched_txlist() external { - vm.warp(1_000_000); +// function test_prove_block_with_mismatched_txlist() external { +// vm.warp(1_000_000); - uint256 initialBondBalance = 100_000 ether; - uint256 bondAmount = 1000 ether; +// uint256 initialBondBalance = 100_000 ether; +// uint256 bondAmount = 1000 ether; - setupBondTokenState(Alice, initialBondBalance, bondAmount); - - // Define a correct txList for proposal - bytes memory txList = abi.encodePacked("correct txList"); +// setupBondTokenState(Alice, initialBondBalance, bondAmount); + +// // Define a correct txList for proposal +// bytes memory txList = abi.encodePacked("correct txList"); - vm.prank(Alice); - uint64[] memory blockIds = _proposeBlocksWithDefaultParameters(1, txList); +// vm.prank(Alice); +// uint64[] memory blockIds = _proposeBlocksWithDefaultParameters(1, txList); - // Define an incorrect txList for proof - bytes32 incorrectHash = keccak256(abi.encodePacked("incorrect txList")); +// // Define an incorrect txList for proof +// bytes32 incorrectHash = keccak256(abi.encodePacked("incorrect txList")); - // Attempt to prove the block with the incorrect txList - ITaikoInbox.BlockMetadataV3 memory meta = blockMetadatas[blockIds[0]]; - meta.txListHash = incorrectHash; +// // Attempt to prove the block with the incorrect txList +// ITaikoInbox.BlockMetadataV3 memory meta = blockMetadatas[blockIds[0]]; +// meta.txListHash = incorrectHash; - ITaikoInbox.BlockMetadataV3[] memory metas = - new ITaikoInbox.BlockMetadataV3[](blockIds.length); - ITaikoInbox.TransitionV3[] memory transitions = - new ITaikoInbox.TransitionV3[](blockIds.length); +// ITaikoInbox.BlockMetadataV3[] memory metas = +// new ITaikoInbox.BlockMetadataV3[](blockIds.length); +// ITaikoInbox.TransitionV3[] memory transitions = +// new ITaikoInbox.TransitionV3[](blockIds.length); - for (uint256 i; i < blockIds.length; ++i) { - metas[i] = blockMetadatas[blockIds[i]]; - metas[i].txListHash = incorrectHash; - transitions[i].parentHash = correctBlockhash(blockIds[i] - 1); - transitions[i].blockHash = correctBlockhash(blockIds[i]); - transitions[i].stateRoot = correctStateRoot(blockIds[i]); - } +// for (uint256 i; i < blockIds.length; ++i) { +// metas[i] = blockMetadatas[blockIds[i]]; +// metas[i].txListHash = incorrectHash; +// transitions[i].parentHash = correctBlockhash(blockIds[i] - 1); +// transitions[i].blockHash = correctBlockhash(blockIds[i]); +// transitions[i].stateRoot = correctStateRoot(blockIds[i]); +// } - vm.prank(Alice); - vm.expectRevert(ITaikoInbox.MetaHashMismatch.selector); - inbox.proveBlocksV3(metas, transitions, "proof"); - } -} +// vm.prank(Alice); +// vm.expectRevert(ITaikoInbox.MetaHashMismatch.selector); +// inbox.proveBlocksV3(metas, transitions, "proof"); +// } +// } diff --git a/packages/protocol/test/layer1/based/InboxTest_EtherAsBond.t.sol b/packages/protocol/test/layer1/based/InboxTest_EtherAsBond.t.sol index 91560b7a8ca..045585a90d1 100644 --- a/packages/protocol/test/layer1/based/InboxTest_EtherAsBond.t.sol +++ b/packages/protocol/test/layer1/based/InboxTest_EtherAsBond.t.sol @@ -1,150 +1,150 @@ // SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.24; -import "contracts/layer1/based/ITaikoInbox.sol"; -import "./InboxTestBase.sol"; - -contract InboxTest_EtherAsBond is InboxTestBase { - function getConfig() internal pure override returns (ITaikoInbox.ConfigV3 memory) { - return ITaikoInbox.ConfigV3({ - chainId: LibNetwork.TAIKO_MAINNET, - blockMaxProposals: 10, - blockRingBufferSize: 15, - maxBlocksToVerify: 5, - blockMaxGasLimit: 240_000_000, - livenessBond: 125e18, // 125 Taiko token - stateRootSyncInternal: 5, - maxAnchorHeightOffset: 64, - baseFeeConfig: LibSharedData.BaseFeeConfig({ - adjustmentQuotient: 8, - sharingPctg: 75, - gasIssuancePerSecond: 5_000_000, - minGasExcess: 1_340_000_000, // correspond to 0.008847185 gwei basefee - maxGasIssuancePerBlock: 600_000_000 // two minutes: 5_000_000 * 120 - }), - provingWindow: 1 hours, - maxSignalsToReceive: 16, - forkHeights: ITaikoInbox.ForkHeights({ ontake: 0, pacaya: 0 }) - }); - } - - function setUpOnEthereum() internal override { - super.setUpOnEthereum(); - - // Use Ether as bond token - bondToken = TaikoToken(address(0)); - } - - function test_inbox_deposit_withdraw() external { - vm.warp(1_000_000); - vm.deal(Alice, 1000 ether); - - uint256 depositAmount = 1 ether; - uint256 withdrawAmount = 0.5 ether; - - vm.prank(Alice); - inbox.depositBond{ value: depositAmount }(depositAmount); - assertEq(inbox.bondBalanceOf(Alice), depositAmount); - - vm.prank(Alice); - inbox.withdrawBond(withdrawAmount); - assertEq(inbox.bondBalanceOf(Alice), depositAmount - withdrawAmount); - } - - function test_inbox_withdraw_more_than_bond_balance() external { - vm.warp(1_000_000); - vm.deal(Alice, 1000 ether); - - uint256 depositAmount = 1 ether; - uint256 withdrawAmount = 2 ether; - - vm.prank(Alice); - inbox.depositBond{ value: depositAmount }(depositAmount); - - vm.prank(Alice); - vm.expectRevert(ITaikoInbox.InsufficientBond.selector); - inbox.withdrawBond(withdrawAmount); - } - - function test_inbox_exceeding_balance() external { - vm.warp(1_000_000); - vm.deal(Alice, 0.5 ether); - - uint256 depositAmount = 1 ether; - - vm.prank(Alice); - vm.expectRevert(); - inbox.depositBond{ value: depositAmount }(depositAmount); - } - - function test_inbox_overpayment_of_ether() external { - vm.warp(1_000_000); - vm.deal(Alice, 1000 ether); - - uint256 depositAmount = 1 ether; - - vm.prank(Alice); - vm.expectRevert(ITaikoInbox.EtherNotPaidAsBond.selector); - inbox.depositBond{ value: depositAmount + 1 }(depositAmount); - } - - function test_inbox_eth_not_paid_as_bond_on_deposit() external { - vm.warp(1_000_000); - vm.deal(Alice, 1000 ether); - - uint256 depositAmount = 1 ether; - - vm.prank(Alice); - vm.expectRevert(ITaikoInbox.EtherNotPaidAsBond.selector); - inbox.depositBond{ value: 0 }(depositAmount); - } - - function test_inbox_bond_balance_after_multiple_operations() external { - vm.warp(1_000_000); - vm.deal(Alice, 1000 ether); - vm.deal(Bob, 50 ether); - - uint256 aliceFirstDeposit = 2 ether; - uint256 aliceSecondDeposit = 3 ether; - uint256 aliceFirstWithdraw = 1 ether; - uint256 aliceSecondWithdraw = 1.5 ether; - - uint256 bobDeposit = 5 ether; - uint256 bobWithdraw = 2 ether; - - vm.prank(Alice); - inbox.depositBond{ value: aliceFirstDeposit }(aliceFirstDeposit); - assertEq(inbox.bondBalanceOf(Alice), aliceFirstDeposit); - - vm.prank(Bob); - inbox.depositBond{ value: bobDeposit }(bobDeposit); - assertEq(inbox.bondBalanceOf(Bob), bobDeposit); - - vm.prank(Alice); - inbox.depositBond{ value: aliceSecondDeposit }(aliceSecondDeposit); - assertEq(inbox.bondBalanceOf(Alice), aliceFirstDeposit + aliceSecondDeposit); - - vm.prank(Bob); - inbox.withdrawBond(bobWithdraw); - assertEq(inbox.bondBalanceOf(Bob), bobDeposit - bobWithdraw); - - vm.prank(Alice); - inbox.withdrawBond(aliceFirstWithdraw); - assertEq( - inbox.bondBalanceOf(Alice), aliceFirstDeposit + aliceSecondDeposit - aliceFirstWithdraw - ); - - vm.prank(Alice); - inbox.withdrawBond(aliceSecondWithdraw); - assertEq( - inbox.bondBalanceOf(Alice), - aliceFirstDeposit + aliceSecondDeposit - aliceFirstWithdraw - aliceSecondWithdraw - ); - - assertEq( - inbox.bondBalanceOf(Alice), - aliceFirstDeposit + aliceSecondDeposit - aliceFirstWithdraw - aliceSecondWithdraw - ); - assertEq(inbox.bondBalanceOf(Bob), bobDeposit - bobWithdraw); - } -} +// import "contracts/layer1/based/ITaikoInbox.sol"; +// import "./InboxTestBase.sol"; + +// contract InboxTest_EtherAsBond is InboxTestBase { +// function getConfig() internal pure override returns (ITaikoInbox.ConfigV3 memory) { +// return ITaikoInbox.ConfigV3({ +// chainId: LibNetwork.TAIKO_MAINNET, +// blockMaxProposals: 10, +// blockRingBufferSize: 15, +// maxBlocksToVerify: 5, +// blockMaxGasLimit: 240_000_000, +// livenessBond: 125e18, // 125 Taiko token +// stateRootSyncInternal: 5, +// maxAnchorHeightOffset: 64, +// baseFeeConfig: LibSharedData.BaseFeeConfig({ +// adjustmentQuotient: 8, +// sharingPctg: 75, +// gasIssuancePerSecond: 5_000_000, +// minGasExcess: 1_340_000_000, // correspond to 0.008847185 gwei basefee +// maxGasIssuancePerBlock: 600_000_000 // two minutes: 5_000_000 * 120 +// }), +// provingWindow: 1 hours, +// maxSignalsToReceive: 16, +// forkHeights: ITaikoInbox.ForkHeights({ ontake: 0, pacaya: 0 }) +// }); +// } + +// function setUpOnEthereum() internal override { +// super.setUpOnEthereum(); + +// // Use Ether as bond token +// bondToken = TaikoToken(address(0)); +// } + +// function test_inbox_deposit_withdraw() external { +// vm.warp(1_000_000); +// vm.deal(Alice, 1000 ether); + +// uint256 depositAmount = 1 ether; +// uint256 withdrawAmount = 0.5 ether; + +// vm.prank(Alice); +// inbox.depositBond{ value: depositAmount }(depositAmount); +// assertEq(inbox.bondBalanceOf(Alice), depositAmount); + +// vm.prank(Alice); +// inbox.withdrawBond(withdrawAmount); +// assertEq(inbox.bondBalanceOf(Alice), depositAmount - withdrawAmount); +// } + +// function test_inbox_withdraw_more_than_bond_balance() external { +// vm.warp(1_000_000); +// vm.deal(Alice, 1000 ether); + +// uint256 depositAmount = 1 ether; +// uint256 withdrawAmount = 2 ether; + +// vm.prank(Alice); +// inbox.depositBond{ value: depositAmount }(depositAmount); + +// vm.prank(Alice); +// vm.expectRevert(ITaikoInbox.InsufficientBond.selector); +// inbox.withdrawBond(withdrawAmount); +// } + +// function test_inbox_exceeding_balance() external { +// vm.warp(1_000_000); +// vm.deal(Alice, 0.5 ether); + +// uint256 depositAmount = 1 ether; + +// vm.prank(Alice); +// vm.expectRevert(); +// inbox.depositBond{ value: depositAmount }(depositAmount); +// } + +// function test_inbox_overpayment_of_ether() external { +// vm.warp(1_000_000); +// vm.deal(Alice, 1000 ether); + +// uint256 depositAmount = 1 ether; + +// vm.prank(Alice); +// vm.expectRevert(ITaikoInbox.EtherNotPaidAsBond.selector); +// inbox.depositBond{ value: depositAmount + 1 }(depositAmount); +// } + +// function test_inbox_eth_not_paid_as_bond_on_deposit() external { +// vm.warp(1_000_000); +// vm.deal(Alice, 1000 ether); + +// uint256 depositAmount = 1 ether; + +// vm.prank(Alice); +// vm.expectRevert(ITaikoInbox.EtherNotPaidAsBond.selector); +// inbox.depositBond{ value: 0 }(depositAmount); +// } + +// function test_inbox_bond_balance_after_multiple_operations() external { +// vm.warp(1_000_000); +// vm.deal(Alice, 1000 ether); +// vm.deal(Bob, 50 ether); + +// uint256 aliceFirstDeposit = 2 ether; +// uint256 aliceSecondDeposit = 3 ether; +// uint256 aliceFirstWithdraw = 1 ether; +// uint256 aliceSecondWithdraw = 1.5 ether; + +// uint256 bobDeposit = 5 ether; +// uint256 bobWithdraw = 2 ether; + +// vm.prank(Alice); +// inbox.depositBond{ value: aliceFirstDeposit }(aliceFirstDeposit); +// assertEq(inbox.bondBalanceOf(Alice), aliceFirstDeposit); + +// vm.prank(Bob); +// inbox.depositBond{ value: bobDeposit }(bobDeposit); +// assertEq(inbox.bondBalanceOf(Bob), bobDeposit); + +// vm.prank(Alice); +// inbox.depositBond{ value: aliceSecondDeposit }(aliceSecondDeposit); +// assertEq(inbox.bondBalanceOf(Alice), aliceFirstDeposit + aliceSecondDeposit); + +// vm.prank(Bob); +// inbox.withdrawBond(bobWithdraw); +// assertEq(inbox.bondBalanceOf(Bob), bobDeposit - bobWithdraw); + +// vm.prank(Alice); +// inbox.withdrawBond(aliceFirstWithdraw); +// assertEq( +// inbox.bondBalanceOf(Alice), aliceFirstDeposit + aliceSecondDeposit - aliceFirstWithdraw +// ); + +// vm.prank(Alice); +// inbox.withdrawBond(aliceSecondWithdraw); +// assertEq( +// inbox.bondBalanceOf(Alice), +// aliceFirstDeposit + aliceSecondDeposit - aliceFirstWithdraw - aliceSecondWithdraw +// ); + +// assertEq( +// inbox.bondBalanceOf(Alice), +// aliceFirstDeposit + aliceSecondDeposit - aliceFirstWithdraw - aliceSecondWithdraw +// ); +// assertEq(inbox.bondBalanceOf(Bob), bobDeposit - bobWithdraw); +// } +// } diff --git a/packages/protocol/test/layer1/based/InboxTest_Suite1.t.sol b/packages/protocol/test/layer1/based/InboxTest_Suite1.t.sol index 9cc9db26528..0739cd3e575 100644 --- a/packages/protocol/test/layer1/based/InboxTest_Suite1.t.sol +++ b/packages/protocol/test/layer1/based/InboxTest_Suite1.t.sol @@ -1,451 +1,451 @@ // SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.24; -import "./InboxTestBase.sol"; - -contract InboxTest_Suite1 is InboxTestBase { - function getConfig() internal pure override returns (ITaikoInbox.ConfigV3 memory) { - return ITaikoInbox.ConfigV3({ - chainId: LibNetwork.TAIKO_MAINNET, - blockMaxProposals: 10, - blockRingBufferSize: 15, - maxBlocksToVerify: 5, - blockMaxGasLimit: 240_000_000, - livenessBond: 125e18, // 125 Taiko token - stateRootSyncInternal: 5, - maxAnchorHeightOffset: 64, - baseFeeConfig: LibSharedData.BaseFeeConfig({ - adjustmentQuotient: 8, - sharingPctg: 75, - gasIssuancePerSecond: 5_000_000, - minGasExcess: 1_340_000_000, // correspond to 0.008847185 gwei basefee - maxGasIssuancePerBlock: 600_000_000 // two minutes: 5_000_000 * 120 - }), - provingWindow: 1 hours, - maxSignalsToReceive: 16, - forkHeights: ITaikoInbox.ForkHeights({ ontake: 0, pacaya: 0 }) - }); - } - - function setUpOnEthereum() internal override { - super.setUpOnEthereum(); - bondToken = deployBondToken(); - } - - function test_inbox_query_right_after_genesis_block() external view { - // - All stats are correct and expected - ITaikoInbox.Stats1 memory stats1 = inbox.getStats1(); - assertEq(stats1.lastSyncedBlockId, 0); - assertEq(stats1.lastSyncedAt, 0); - - ITaikoInbox.Stats2 memory stats2 = inbox.getStats2(); - assertEq(stats2.numBlocks, 1); - assertEq(stats2.lastVerifiedBlockId, 0); - assertEq(stats2.paused, false); - assertEq(stats2.lastProposedIn, genesisBlockProposedIn); - assertEq(stats2.lastUnpausedAt, 0); - - // - Verify genesis block - ITaikoInbox.BlockV3 memory blk = inbox.getBlockV3(0); - assertEq(blk.blockId, 0); - assertEq(blk.metaHash, bytes32(uint256(1))); - assertEq(blk.timestamp, genesisBlockProposedAt); - assertEq(blk.anchorBlockId, genesisBlockProposedIn); - assertEq(blk.nextTransitionId, 2); - assertEq(blk.verifiedTransitionId, 1); - - (uint64 blockId, ITaikoInbox.TransitionV3 memory tran) = inbox.getLastVerifiedTransitionV3(); - assertEq(blockId, 0); - assertEq(tran.blockHash, correctBlockhash(0)); - assertEq(tran.stateRoot, bytes32(uint256(0))); - - (blockId, tran) = inbox.getLastSyncedTransitionV3(); - assertEq(blockId, 0); - assertEq(tran.blockHash, correctBlockhash(0)); - assertEq(tran.stateRoot, bytes32(uint256(0))); - } - - function test_inbox_query_blocks_not_exist_will_revert() external { - vm.expectRevert(ITaikoInbox.BlockNotFound.selector); - inbox.getBlockV3(1); - } - - function test_inbox_max_block_proposal() - external - transactBy(Alice) - WhenMultipleBlocksAreProposedWithDefaultParameters(9) - WhenLogAllBlocksAndTransitions - { - // - All stats are correct and expected - - ITaikoInbox.Stats1 memory stats1 = inbox.getStats1(); - assertEq(stats1.lastSyncedBlockId, 0); - assertEq(stats1.lastSyncedAt, 0); - - ITaikoInbox.Stats2 memory stats2 = inbox.getStats2(); - assertEq(stats2.numBlocks, 10); - assertEq(stats2.lastVerifiedBlockId, 0); - assertEq(stats2.paused, false); - assertEq(stats2.lastProposedIn, block.number); - assertEq(stats2.lastUnpausedAt, 0); - - // - Verify genesis block - ITaikoInbox.BlockV3 memory blk = inbox.getBlockV3(0); - assertEq(blk.blockId, 0); - assertEq(blk.metaHash, bytes32(uint256(1))); - assertEq(blk.timestamp, genesisBlockProposedAt); - assertEq(blk.anchorBlockId, genesisBlockProposedIn); - assertEq(blk.nextTransitionId, 2); - assertEq(blk.verifiedTransitionId, 1); - - // Verify block data - for (uint64 i = 1; i < 10; ++i) { - blk = inbox.getBlockV3(i); - assertEq(blk.blockId, i); - assertEq(blk.metaHash, keccak256(abi.encode(blockMetadatas[i]))); - - assertEq(blk.timestamp, block.timestamp); - assertEq(blk.anchorBlockId, block.number - 1); - assertEq(blk.nextTransitionId, 1); - assertEq(blk.verifiedTransitionId, 0); - } - - // - Proposing one block block will revert - vm.expectRevert(ITaikoInbox.TooManyBlocks.selector); - _proposeBlocksWithDefaultParameters({ numBlocksToPropose: 1 }); - } - - function test_inbox_exceed_max_block_proposal_will_revert() - external - transactBy(Alice) - WhenMultipleBlocksAreProposedWithDefaultParameters(9) - WhenLogAllBlocksAndTransitions - { - // - Proposing one block block will revert - vm.expectRevert(ITaikoInbox.TooManyBlocks.selector); - _proposeBlocksWithDefaultParameters({ numBlocksToPropose: 1 }); - } - - function test_inbox_prove_with_wrong_transitions_will_not_finalize_blocks() - external - transactBy(Alice) - WhenMultipleBlocksAreProposedWithDefaultParameters(6) - WhenMultipleBlocksAreProvedWithWrongTransitions(1, 7) - WhenLogAllBlocksAndTransitions - { - // - All stats are correct and expected - - ITaikoInbox.Stats1 memory stats1 = inbox.getStats1(); - assertEq(stats1.lastSyncedBlockId, 0); - assertEq(stats1.lastSyncedAt, 0); - - ITaikoInbox.Stats2 memory stats2 = inbox.getStats2(); - assertEq(stats2.numBlocks, 7); - assertEq(stats2.lastVerifiedBlockId, 0); - assertEq(stats2.paused, false); - assertEq(stats2.lastProposedIn, block.number); - assertEq(stats2.lastUnpausedAt, 0); - - // - Verify genesis block - ITaikoInbox.BlockV3 memory blk = inbox.getBlockV3(0); - assertEq(blk.blockId, 0); - assertEq(blk.metaHash, bytes32(uint256(1))); - assertEq(blk.timestamp, genesisBlockProposedAt); - assertEq(blk.anchorBlockId, genesisBlockProposedIn); - assertEq(blk.nextTransitionId, 2); - assertEq(blk.verifiedTransitionId, 1); - - // Verify block data - for (uint64 i = 1; i < 7; ++i) { - blk = inbox.getBlockV3(i); - assertEq(blk.blockId, i); - assertEq(blk.metaHash, keccak256(abi.encode(blockMetadatas[i]))); - - assertEq(blk.timestamp, block.timestamp); - assertEq(blk.anchorBlockId, block.number - 1); - assertEq(blk.nextTransitionId, 2); - assertEq(blk.verifiedTransitionId, 0); - } - } - - function test_inbox_prove_block_not_exist_will_revert() external transactBy(Alice) { - uint64[] memory blockIds = new uint64[](1); - blockIds[0] = 1; - vm.expectRevert(ITaikoInbox.BlockNotFound.selector); - _proveBlocksWithCorrectTransitions(blockIds); - } - - function test_inbox_prove_verified_block_will_revert() - external - transactBy(Alice) - WhenMultipleBlocksAreProposedWithDefaultParameters(1) - WhenMultipleBlocksAreProvedWithCorrectTransitions(1, 2) - { - uint64[] memory blockIds = new uint64[](1); - blockIds[0] = 1; - vm.expectRevert(ITaikoInbox.BlockNotFound.selector); - _proveBlocksWithCorrectTransitions(blockIds); - } - - function test_inbox_propose_and_prove_many_blocks_with_first_transition_being_correct() - external - transactBy(Alice) - WhenMultipleBlocksAreProposedWithDefaultParameters(9) - WhenMultipleBlocksAreProvedWithCorrectTransitions(1, 10) - WhenLogAllBlocksAndTransitions - { - // - All stats are correct and expected - - ITaikoInbox.Stats1 memory stats1 = inbox.getStats1(); - assertEq(stats1.lastSyncedBlockId, 5); - assertEq(stats1.lastSyncedAt, block.timestamp); - - ITaikoInbox.Stats2 memory stats2 = inbox.getStats2(); - assertEq(stats2.numBlocks, 10); - assertEq(stats2.lastVerifiedBlockId, 9); - assertEq(stats2.paused, false); - assertEq(stats2.lastProposedIn, block.number); - assertEq(stats2.lastUnpausedAt, 0); - - (uint64 blockId, ITaikoInbox.TransitionV3 memory tran) = inbox.getLastVerifiedTransitionV3(); - assertEq(blockId, 9); - assertEq(tran.blockHash, correctBlockhash(9)); - assertEq(tran.stateRoot, bytes32(uint256(0))); - - (blockId, tran) = inbox.getLastSyncedTransitionV3(); - assertEq(blockId, 5); - assertEq(tran.blockHash, correctBlockhash(5)); - assertEq(tran.stateRoot, correctStateRoot(5)); - - // - Verify genesis block - ITaikoInbox.BlockV3 memory blk = inbox.getBlockV3(0); - assertEq(blk.blockId, 0); - assertEq(blk.metaHash, bytes32(uint256(1))); - assertEq(blk.timestamp, genesisBlockProposedAt); - assertEq(blk.anchorBlockId, genesisBlockProposedIn); - assertEq(blk.nextTransitionId, 2); - assertEq(blk.verifiedTransitionId, 1); - - // Verify block data - for (uint64 i = 1; i < 10; ++i) { - blk = inbox.getBlockV3(i); - assertEq(blk.blockId, i); - assertEq(blk.metaHash, keccak256(abi.encode(blockMetadatas[i]))); - - assertEq(blk.timestamp, block.timestamp); - assertEq(blk.anchorBlockId, block.number - 1); - assertEq(blk.nextTransitionId, 2); - if (i % getConfig().stateRootSyncInternal == 0 || i == stats2.lastVerifiedBlockId) { - assertEq(blk.verifiedTransitionId, 1); - } else { - assertEq(blk.verifiedTransitionId, 0); - } - } - } - - function test_inbox_propose_and_prove_many_blocks_with_second_transition_being_correct() - external - transactBy(Alice) - WhenMultipleBlocksAreProposedWithDefaultParameters(9) - WhenMultipleBlocksAreProvedWithWrongTransitions(1, 10) - WhenMultipleBlocksAreProvedWithCorrectTransitions(1, 10) - WhenLogAllBlocksAndTransitions - { - // - All stats are correct and expected - - ITaikoInbox.Stats1 memory stats1 = inbox.getStats1(); - assertEq(stats1.lastSyncedBlockId, 5); - assertEq(stats1.lastSyncedAt, block.timestamp); - - ITaikoInbox.Stats2 memory stats2 = inbox.getStats2(); - assertEq(stats2.numBlocks, 10); - assertEq(stats2.lastVerifiedBlockId, 9); - assertEq(stats2.paused, false); - assertEq(stats2.lastProposedIn, block.number); - assertEq(stats2.lastUnpausedAt, 0); - - // - Verify genesis block - ITaikoInbox.BlockV3 memory blk = inbox.getBlockV3(0); - assertEq(blk.blockId, 0); - assertEq(blk.metaHash, bytes32(uint256(1))); - assertEq(blk.timestamp, genesisBlockProposedAt); - assertEq(blk.anchorBlockId, genesisBlockProposedIn); - assertEq(blk.nextTransitionId, 2); - assertEq(blk.verifiedTransitionId, 1); - - // Verify block data - for (uint64 i = 1; i < 10; ++i) { - blk = inbox.getBlockV3(i); - assertEq(blk.blockId, i); - assertEq(blk.metaHash, keccak256(abi.encode(blockMetadatas[i]))); - - assertEq(blk.timestamp, block.timestamp); - assertEq(blk.anchorBlockId, block.number - 1); - assertEq(blk.nextTransitionId, 3); - if (i % getConfig().stateRootSyncInternal == 0 || i == stats2.lastVerifiedBlockId) { - assertEq(blk.verifiedTransitionId, 2); - } else { - assertEq(blk.verifiedTransitionId, 0); - } - } - } - - function test_inbox_ring_buffer_will_be_reused() - external - transactBy(Alice) - WhenMultipleBlocksAreProposedWithDefaultParameters(9) - WhenMultipleBlocksAreProvedWithCorrectTransitions(1, 10) - WhenMultipleBlocksAreProposedWithDefaultParameters(8) - WhenLogAllBlocksAndTransitions - WhenMultipleBlocksAreProvedWithCorrectTransitions(14, 16) - WhenLogAllBlocksAndTransitions - WhenMultipleBlocksAreProvedWithCorrectTransitions(10, 11) - WhenLogAllBlocksAndTransitions - { - // - All stats are correct and expected - - ITaikoInbox.Stats1 memory stats1 = inbox.getStats1(); - assertEq(stats1.lastSyncedBlockId, 10); - assertEq(stats1.lastSyncedAt, block.timestamp); - - ITaikoInbox.Stats2 memory stats2 = inbox.getStats2(); - assertEq(stats2.numBlocks, 18); - assertEq(stats2.lastVerifiedBlockId, 10); - assertEq(stats2.paused, false); - assertEq(stats2.lastProposedIn, block.number); - assertEq(stats2.lastUnpausedAt, 0); - - (uint64 blockId, ITaikoInbox.TransitionV3 memory tran) = inbox.getLastVerifiedTransitionV3(); - assertEq(blockId, 10); - assertEq(tran.blockHash, correctBlockhash(10)); - assertEq(tran.stateRoot, correctStateRoot(10)); - - (blockId, tran) = inbox.getLastSyncedTransitionV3(); - assertEq(blockId, 10); - assertEq(tran.blockHash, correctBlockhash(10)); - assertEq(tran.stateRoot, correctStateRoot(10)); - - // Verify block data - for (uint64 i = 8; i < 15; ++i) { - ITaikoInbox.BlockV3 memory blk = inbox.getBlockV3(i); - assertEq(blk.blockId, i); - assertEq(blk.metaHash, keccak256(abi.encode(blockMetadatas[i]))); - - assertEq(blk.timestamp, block.timestamp); - assertEq(blk.anchorBlockId, block.number - 1); - if (i == 8) { - assertEq(blk.verifiedTransitionId, 0); - assertEq(blk.nextTransitionId, 2); - } else if (i == 9) { - assertEq(blk.verifiedTransitionId, 1); - assertEq(blk.nextTransitionId, 2); - } else if (i == 10) { - assertEq(blk.verifiedTransitionId, 1); - assertEq(blk.nextTransitionId, 2); - } else if (i == 11 || i == 12 || i == 13 || i == 16 || i == 17) { - assertEq(blk.verifiedTransitionId, 0); - assertEq(blk.nextTransitionId, 1); - } else if (i == 14 || i == 15) { - assertEq(blk.verifiedTransitionId, 0); - assertEq(blk.nextTransitionId, 2); - } - } - } - - function test_inbox_reprove_the_same_block_is_ok() - external - transactBy(Alice) - WhenMultipleBlocksAreProposedWithDefaultParameters(1) - WhenLogAllBlocksAndTransitions - { - ITaikoInbox.BlockMetadataV3[] memory metas = new ITaikoInbox.BlockMetadataV3[](1); - ITaikoInbox.TransitionV3[] memory transitions = new ITaikoInbox.TransitionV3[](1); - - metas[0] = blockMetadatas[1]; - - transitions[0].parentHash = bytes32(uint256(0x100)); - transitions[0].blockHash = bytes32(uint256(0x101)); - transitions[0].stateRoot = bytes32(uint256(0x102)); - inbox.proveBlocksV3(metas, transitions, "proof"); - _logAllBlocksAndTransitions(); - - transitions[0].parentHash = bytes32(uint256(0x100)); - transitions[0].blockHash = bytes32(uint256(0x111)); - transitions[0].stateRoot = bytes32(uint256(0x112)); - inbox.proveBlocksV3(metas, transitions, "proof"); - _logAllBlocksAndTransitions(); - - transitions[0].parentHash = bytes32(uint256(0x200)); - transitions[0].blockHash = bytes32(uint256(0x201)); - transitions[0].stateRoot = bytes32(uint256(0x202)); - inbox.proveBlocksV3(metas, transitions, "proof"); - _logAllBlocksAndTransitions(); - - transitions[0].parentHash = bytes32(uint256(0x200)); - transitions[0].blockHash = bytes32(uint256(0x211)); - transitions[0].stateRoot = bytes32(uint256(0x212)); - inbox.proveBlocksV3(metas, transitions, "proof"); - _logAllBlocksAndTransitions(); - } - - function test_proposeBlocksV3_reverts_for_invalid_proposer_and_preconfRouter() - external - transactBy(Alice) - { - uint64 count = 1; - - vm.expectRevert(ITaikoInbox.CustomProposerNotAllowed.selector); - inbox.proposeBlocksV3(Alice, address(0), new ITaikoInbox.BlockParamsV3[](count), "txList"); - - vm.startPrank(deployer); - address preconfRouter = Bob; - resolver.registerAddress(block.chainid, "preconf_router", preconfRouter); - vm.stopPrank(); - - vm.startPrank(Alice); - vm.expectRevert(ITaikoInbox.NotPreconfRouter.selector); - inbox.proposeBlocksV3( - preconfRouter, address(0), new ITaikoInbox.BlockParamsV3[](count), "txList" - ); - vm.stopPrank(); - - vm.startPrank(preconfRouter); - vm.expectRevert(ITaikoInbox.CustomProposerMissing.selector); - inbox.proposeBlocksV3( - address(0), address(0), new ITaikoInbox.BlockParamsV3[](count), "txList" - ); - vm.stopPrank(); - } - - function test_inbox_measure_gas_used() - external - transactBy(Alice) - WhenMultipleBlocksAreProposedWithDefaultParameters(9) - WhenMultipleBlocksAreProvedWithCorrectTransitions(1, 10) - WhenLogAllBlocksAndTransitions - { - uint64 count = 1; - - vm.startSnapshotGas("proposeBlocksV3"); - ITaikoInbox.BlockMetadataV3[] memory metas = inbox.proposeBlocksV3( - address(0), address(0), new ITaikoInbox.BlockParamsV3[](count), "txList" - ); - uint256 gasProposeBlocksV3 = vm.stopSnapshotGas("proposeBlocksV3"); - console2.log("Gas per block - proposing:", gasProposeBlocksV3 / count); - - ITaikoInbox.TransitionV3[] memory transitions = new ITaikoInbox.TransitionV3[](count); - for (uint256 i; i < metas.length; ++i) { - transitions[i].parentHash = correctBlockhash(metas[i].blockId - 1); - transitions[i].blockHash = correctBlockhash(metas[i].blockId); - transitions[i].stateRoot = correctStateRoot(metas[i].blockId); - } - - vm.startSnapshotGas("proveBlocksV3"); - inbox.proveBlocksV3(metas, transitions, "proof"); - uint256 gasProveBlocksV3 = vm.stopSnapshotGas("proveBlocksV3"); - console2.log("Gas per block - proving:", gasProveBlocksV3 / count); - console2.log("Gas per block - total:", (gasProposeBlocksV3 + gasProveBlocksV3) / count); - - _logAllBlocksAndTransitions(); - } -} +// import "./InboxTestBase.sol"; + +// contract InboxTest_Suite1 is InboxTestBase { +// function getConfig() internal pure override returns (ITaikoInbox.ConfigV3 memory) { +// return ITaikoInbox.ConfigV3({ +// chainId: LibNetwork.TAIKO_MAINNET, +// blockMaxProposals: 10, +// blockRingBufferSize: 15, +// maxBlocksToVerify: 5, +// blockMaxGasLimit: 240_000_000, +// livenessBond: 125e18, // 125 Taiko token +// stateRootSyncInternal: 5, +// maxAnchorHeightOffset: 64, +// baseFeeConfig: LibSharedData.BaseFeeConfig({ +// adjustmentQuotient: 8, +// sharingPctg: 75, +// gasIssuancePerSecond: 5_000_000, +// minGasExcess: 1_340_000_000, // correspond to 0.008847185 gwei basefee +// maxGasIssuancePerBlock: 600_000_000 // two minutes: 5_000_000 * 120 +// }), +// provingWindow: 1 hours, +// maxSignalsToReceive: 16, +// forkHeights: ITaikoInbox.ForkHeights({ ontake: 0, pacaya: 0 }) +// }); +// } + +// function setUpOnEthereum() internal override { +// super.setUpOnEthereum(); +// bondToken = deployBondToken(); +// } + +// function test_inbox_query_right_after_genesis_block() external view { +// // - All stats are correct and expected +// ITaikoInbox.Stats1 memory stats1 = inbox.getStats1(); +// assertEq(stats1.lastSyncedBlockId, 0); +// assertEq(stats1.lastSyncedAt, 0); + +// ITaikoInbox.Stats2 memory stats2 = inbox.getStats2(); +// assertEq(stats2.numBlocks, 1); +// assertEq(stats2.lastVerifiedBlockId, 0); +// assertEq(stats2.paused, false); +// assertEq(stats2.lastProposedIn, genesisBlockProposedIn); +// assertEq(stats2.lastUnpausedAt, 0); + +// // - Verify genesis block +// ITaikoInbox.BlockV3 memory blk = inbox.getBlockV3(0); +// assertEq(blk.blockId, 0); +// assertEq(blk.metaHash, bytes32(uint256(1))); +// assertEq(blk.timestamp, genesisBlockProposedAt); +// assertEq(blk.anchorBlockId, genesisBlockProposedIn); +// assertEq(blk.nextTransitionId, 2); +// assertEq(blk.verifiedTransitionId, 1); + +// (uint64 blockId, ITaikoInbox.TransitionV3 memory tran) = inbox.getLastVerifiedTransitionV3(); +// assertEq(blockId, 0); +// assertEq(tran.blockHash, correctBlockhash(0)); +// assertEq(tran.stateRoot, bytes32(uint256(0))); + +// (blockId, tran) = inbox.getLastSyncedTransitionV3(); +// assertEq(blockId, 0); +// assertEq(tran.blockHash, correctBlockhash(0)); +// assertEq(tran.stateRoot, bytes32(uint256(0))); +// } + +// function test_inbox_query_blocks_not_exist_will_revert() external { +// vm.expectRevert(ITaikoInbox.BlockNotFound.selector); +// inbox.getBlockV3(1); +// } + +// function test_inbox_max_block_proposal() +// external +// transactBy(Alice) +// WhenMultipleBlocksAreProposedWithDefaultParameters(9) +// WhenLogAllBlocksAndTransitions +// { +// // - All stats are correct and expected + +// ITaikoInbox.Stats1 memory stats1 = inbox.getStats1(); +// assertEq(stats1.lastSyncedBlockId, 0); +// assertEq(stats1.lastSyncedAt, 0); + +// ITaikoInbox.Stats2 memory stats2 = inbox.getStats2(); +// assertEq(stats2.numBlocks, 10); +// assertEq(stats2.lastVerifiedBlockId, 0); +// assertEq(stats2.paused, false); +// assertEq(stats2.lastProposedIn, block.number); +// assertEq(stats2.lastUnpausedAt, 0); + +// // - Verify genesis block +// ITaikoInbox.BlockV3 memory blk = inbox.getBlockV3(0); +// assertEq(blk.blockId, 0); +// assertEq(blk.metaHash, bytes32(uint256(1))); +// assertEq(blk.timestamp, genesisBlockProposedAt); +// assertEq(blk.anchorBlockId, genesisBlockProposedIn); +// assertEq(blk.nextTransitionId, 2); +// assertEq(blk.verifiedTransitionId, 1); + +// // Verify block data +// for (uint64 i = 1; i < 10; ++i) { +// blk = inbox.getBlockV3(i); +// assertEq(blk.blockId, i); +// assertEq(blk.metaHash, keccak256(abi.encode(blockMetadatas[i]))); + +// assertEq(blk.timestamp, block.timestamp); +// assertEq(blk.anchorBlockId, block.number - 1); +// assertEq(blk.nextTransitionId, 1); +// assertEq(blk.verifiedTransitionId, 0); +// } + +// // - Proposing one block block will revert +// vm.expectRevert(ITaikoInbox.TooManyBlocks.selector); +// _proposeBlocksWithDefaultParameters({ numBlocksToPropose: 1 }); +// } + +// function test_inbox_exceed_max_block_proposal_will_revert() +// external +// transactBy(Alice) +// WhenMultipleBlocksAreProposedWithDefaultParameters(9) +// WhenLogAllBlocksAndTransitions +// { +// // - Proposing one block block will revert +// vm.expectRevert(ITaikoInbox.TooManyBlocks.selector); +// _proposeBlocksWithDefaultParameters({ numBlocksToPropose: 1 }); +// } + +// function test_inbox_prove_with_wrong_transitions_will_not_finalize_blocks() +// external +// transactBy(Alice) +// WhenMultipleBlocksAreProposedWithDefaultParameters(6) +// WhenMultipleBlocksAreProvedWithWrongTransitions(1, 7) +// WhenLogAllBlocksAndTransitions +// { +// // - All stats are correct and expected + +// ITaikoInbox.Stats1 memory stats1 = inbox.getStats1(); +// assertEq(stats1.lastSyncedBlockId, 0); +// assertEq(stats1.lastSyncedAt, 0); + +// ITaikoInbox.Stats2 memory stats2 = inbox.getStats2(); +// assertEq(stats2.numBlocks, 7); +// assertEq(stats2.lastVerifiedBlockId, 0); +// assertEq(stats2.paused, false); +// assertEq(stats2.lastProposedIn, block.number); +// assertEq(stats2.lastUnpausedAt, 0); + +// // - Verify genesis block +// ITaikoInbox.BlockV3 memory blk = inbox.getBlockV3(0); +// assertEq(blk.blockId, 0); +// assertEq(blk.metaHash, bytes32(uint256(1))); +// assertEq(blk.timestamp, genesisBlockProposedAt); +// assertEq(blk.anchorBlockId, genesisBlockProposedIn); +// assertEq(blk.nextTransitionId, 2); +// assertEq(blk.verifiedTransitionId, 1); + +// // Verify block data +// for (uint64 i = 1; i < 7; ++i) { +// blk = inbox.getBlockV3(i); +// assertEq(blk.blockId, i); +// assertEq(blk.metaHash, keccak256(abi.encode(blockMetadatas[i]))); + +// assertEq(blk.timestamp, block.timestamp); +// assertEq(blk.anchorBlockId, block.number - 1); +// assertEq(blk.nextTransitionId, 2); +// assertEq(blk.verifiedTransitionId, 0); +// } +// } + +// function test_inbox_prove_block_not_exist_will_revert() external transactBy(Alice) { +// uint64[] memory blockIds = new uint64[](1); +// blockIds[0] = 1; +// vm.expectRevert(ITaikoInbox.BlockNotFound.selector); +// _proveBlocksWithCorrectTransitions(blockIds); +// } + +// function test_inbox_prove_verified_block_will_revert() +// external +// transactBy(Alice) +// WhenMultipleBlocksAreProposedWithDefaultParameters(1) +// WhenMultipleBlocksAreProvedWithCorrectTransitions(1, 2) +// { +// uint64[] memory blockIds = new uint64[](1); +// blockIds[0] = 1; +// vm.expectRevert(ITaikoInbox.BlockNotFound.selector); +// _proveBlocksWithCorrectTransitions(blockIds); +// } + +// function test_inbox_propose_and_prove_many_blocks_with_first_transition_being_correct() +// external +// transactBy(Alice) +// WhenMultipleBlocksAreProposedWithDefaultParameters(9) +// WhenMultipleBlocksAreProvedWithCorrectTransitions(1, 10) +// WhenLogAllBlocksAndTransitions +// { +// // - All stats are correct and expected + +// ITaikoInbox.Stats1 memory stats1 = inbox.getStats1(); +// assertEq(stats1.lastSyncedBlockId, 5); +// assertEq(stats1.lastSyncedAt, block.timestamp); + +// ITaikoInbox.Stats2 memory stats2 = inbox.getStats2(); +// assertEq(stats2.numBlocks, 10); +// assertEq(stats2.lastVerifiedBlockId, 9); +// assertEq(stats2.paused, false); +// assertEq(stats2.lastProposedIn, block.number); +// assertEq(stats2.lastUnpausedAt, 0); + +// (uint64 blockId, ITaikoInbox.TransitionV3 memory tran) = inbox.getLastVerifiedTransitionV3(); +// assertEq(blockId, 9); +// assertEq(tran.blockHash, correctBlockhash(9)); +// assertEq(tran.stateRoot, bytes32(uint256(0))); + +// (blockId, tran) = inbox.getLastSyncedTransitionV3(); +// assertEq(blockId, 5); +// assertEq(tran.blockHash, correctBlockhash(5)); +// assertEq(tran.stateRoot, correctStateRoot(5)); + +// // - Verify genesis block +// ITaikoInbox.BlockV3 memory blk = inbox.getBlockV3(0); +// assertEq(blk.blockId, 0); +// assertEq(blk.metaHash, bytes32(uint256(1))); +// assertEq(blk.timestamp, genesisBlockProposedAt); +// assertEq(blk.anchorBlockId, genesisBlockProposedIn); +// assertEq(blk.nextTransitionId, 2); +// assertEq(blk.verifiedTransitionId, 1); + +// // Verify block data +// for (uint64 i = 1; i < 10; ++i) { +// blk = inbox.getBlockV3(i); +// assertEq(blk.blockId, i); +// assertEq(blk.metaHash, keccak256(abi.encode(blockMetadatas[i]))); + +// assertEq(blk.timestamp, block.timestamp); +// assertEq(blk.anchorBlockId, block.number - 1); +// assertEq(blk.nextTransitionId, 2); +// if (i % getConfig().stateRootSyncInternal == 0 || i == stats2.lastVerifiedBlockId) { +// assertEq(blk.verifiedTransitionId, 1); +// } else { +// assertEq(blk.verifiedTransitionId, 0); +// } +// } +// } + +// function test_inbox_propose_and_prove_many_blocks_with_second_transition_being_correct() +// external +// transactBy(Alice) +// WhenMultipleBlocksAreProposedWithDefaultParameters(9) +// WhenMultipleBlocksAreProvedWithWrongTransitions(1, 10) +// WhenMultipleBlocksAreProvedWithCorrectTransitions(1, 10) +// WhenLogAllBlocksAndTransitions +// { +// // - All stats are correct and expected + +// ITaikoInbox.Stats1 memory stats1 = inbox.getStats1(); +// assertEq(stats1.lastSyncedBlockId, 5); +// assertEq(stats1.lastSyncedAt, block.timestamp); + +// ITaikoInbox.Stats2 memory stats2 = inbox.getStats2(); +// assertEq(stats2.numBlocks, 10); +// assertEq(stats2.lastVerifiedBlockId, 9); +// assertEq(stats2.paused, false); +// assertEq(stats2.lastProposedIn, block.number); +// assertEq(stats2.lastUnpausedAt, 0); + +// // - Verify genesis block +// ITaikoInbox.BlockV3 memory blk = inbox.getBlockV3(0); +// assertEq(blk.blockId, 0); +// assertEq(blk.metaHash, bytes32(uint256(1))); +// assertEq(blk.timestamp, genesisBlockProposedAt); +// assertEq(blk.anchorBlockId, genesisBlockProposedIn); +// assertEq(blk.nextTransitionId, 2); +// assertEq(blk.verifiedTransitionId, 1); + +// // Verify block data +// for (uint64 i = 1; i < 10; ++i) { +// blk = inbox.getBlockV3(i); +// assertEq(blk.blockId, i); +// assertEq(blk.metaHash, keccak256(abi.encode(blockMetadatas[i]))); + +// assertEq(blk.timestamp, block.timestamp); +// assertEq(blk.anchorBlockId, block.number - 1); +// assertEq(blk.nextTransitionId, 3); +// if (i % getConfig().stateRootSyncInternal == 0 || i == stats2.lastVerifiedBlockId) { +// assertEq(blk.verifiedTransitionId, 2); +// } else { +// assertEq(blk.verifiedTransitionId, 0); +// } +// } +// } + +// function test_inbox_ring_buffer_will_be_reused() +// external +// transactBy(Alice) +// WhenMultipleBlocksAreProposedWithDefaultParameters(9) +// WhenMultipleBlocksAreProvedWithCorrectTransitions(1, 10) +// WhenMultipleBlocksAreProposedWithDefaultParameters(8) +// WhenLogAllBlocksAndTransitions +// WhenMultipleBlocksAreProvedWithCorrectTransitions(14, 16) +// WhenLogAllBlocksAndTransitions +// WhenMultipleBlocksAreProvedWithCorrectTransitions(10, 11) +// WhenLogAllBlocksAndTransitions +// { +// // - All stats are correct and expected + +// ITaikoInbox.Stats1 memory stats1 = inbox.getStats1(); +// assertEq(stats1.lastSyncedBlockId, 10); +// assertEq(stats1.lastSyncedAt, block.timestamp); + +// ITaikoInbox.Stats2 memory stats2 = inbox.getStats2(); +// assertEq(stats2.numBlocks, 18); +// assertEq(stats2.lastVerifiedBlockId, 10); +// assertEq(stats2.paused, false); +// assertEq(stats2.lastProposedIn, block.number); +// assertEq(stats2.lastUnpausedAt, 0); + +// (uint64 blockId, ITaikoInbox.TransitionV3 memory tran) = inbox.getLastVerifiedTransitionV3(); +// assertEq(blockId, 10); +// assertEq(tran.blockHash, correctBlockhash(10)); +// assertEq(tran.stateRoot, correctStateRoot(10)); + +// (blockId, tran) = inbox.getLastSyncedTransitionV3(); +// assertEq(blockId, 10); +// assertEq(tran.blockHash, correctBlockhash(10)); +// assertEq(tran.stateRoot, correctStateRoot(10)); + +// // Verify block data +// for (uint64 i = 8; i < 15; ++i) { +// ITaikoInbox.BlockV3 memory blk = inbox.getBlockV3(i); +// assertEq(blk.blockId, i); +// assertEq(blk.metaHash, keccak256(abi.encode(blockMetadatas[i]))); + +// assertEq(blk.timestamp, block.timestamp); +// assertEq(blk.anchorBlockId, block.number - 1); +// if (i == 8) { +// assertEq(blk.verifiedTransitionId, 0); +// assertEq(blk.nextTransitionId, 2); +// } else if (i == 9) { +// assertEq(blk.verifiedTransitionId, 1); +// assertEq(blk.nextTransitionId, 2); +// } else if (i == 10) { +// assertEq(blk.verifiedTransitionId, 1); +// assertEq(blk.nextTransitionId, 2); +// } else if (i == 11 || i == 12 || i == 13 || i == 16 || i == 17) { +// assertEq(blk.verifiedTransitionId, 0); +// assertEq(blk.nextTransitionId, 1); +// } else if (i == 14 || i == 15) { +// assertEq(blk.verifiedTransitionId, 0); +// assertEq(blk.nextTransitionId, 2); +// } +// } +// } + +// function test_inbox_reprove_the_same_block_is_ok() +// external +// transactBy(Alice) +// WhenMultipleBlocksAreProposedWithDefaultParameters(1) +// WhenLogAllBlocksAndTransitions +// { +// ITaikoInbox.BlockMetadataV3[] memory metas = new ITaikoInbox.BlockMetadataV3[](1); +// ITaikoInbox.TransitionV3[] memory transitions = new ITaikoInbox.TransitionV3[](1); + +// metas[0] = blockMetadatas[1]; + +// transitions[0].parentHash = bytes32(uint256(0x100)); +// transitions[0].blockHash = bytes32(uint256(0x101)); +// transitions[0].stateRoot = bytes32(uint256(0x102)); +// inbox.proveBlocksV3(metas, transitions, "proof"); +// _logAllBlocksAndTransitions(); + +// transitions[0].parentHash = bytes32(uint256(0x100)); +// transitions[0].blockHash = bytes32(uint256(0x111)); +// transitions[0].stateRoot = bytes32(uint256(0x112)); +// inbox.proveBlocksV3(metas, transitions, "proof"); +// _logAllBlocksAndTransitions(); + +// transitions[0].parentHash = bytes32(uint256(0x200)); +// transitions[0].blockHash = bytes32(uint256(0x201)); +// transitions[0].stateRoot = bytes32(uint256(0x202)); +// inbox.proveBlocksV3(metas, transitions, "proof"); +// _logAllBlocksAndTransitions(); + +// transitions[0].parentHash = bytes32(uint256(0x200)); +// transitions[0].blockHash = bytes32(uint256(0x211)); +// transitions[0].stateRoot = bytes32(uint256(0x212)); +// inbox.proveBlocksV3(metas, transitions, "proof"); +// _logAllBlocksAndTransitions(); +// } + +// function test_proposeBlocksV3_reverts_for_invalid_proposer_and_preconfRouter() +// external +// transactBy(Alice) +// { +// uint64 count = 1; + +// vm.expectRevert(ITaikoInbox.CustomProposerNotAllowed.selector); +// inbox.proposeBlocksV3(Alice, address(0), new ITaikoInbox.BlockParamsV3[](count), "txList"); + +// vm.startPrank(deployer); +// address preconfRouter = Bob; +// resolver.registerAddress(block.chainid, "preconf_router", preconfRouter); +// vm.stopPrank(); + +// vm.startPrank(Alice); +// vm.expectRevert(ITaikoInbox.NotPreconfRouter.selector); +// inbox.proposeBlocksV3( +// preconfRouter, address(0), new ITaikoInbox.BlockParamsV3[](count), "txList" +// ); +// vm.stopPrank(); + +// vm.startPrank(preconfRouter); +// vm.expectRevert(ITaikoInbox.CustomProposerMissing.selector); +// inbox.proposeBlocksV3( +// address(0), address(0), new ITaikoInbox.BlockParamsV3[](count), "txList" +// ); +// vm.stopPrank(); +// } + +// function test_inbox_measure_gas_used() +// external +// transactBy(Alice) +// WhenMultipleBlocksAreProposedWithDefaultParameters(9) +// WhenMultipleBlocksAreProvedWithCorrectTransitions(1, 10) +// WhenLogAllBlocksAndTransitions +// { +// uint64 count = 1; + +// vm.startSnapshotGas("proposeBlocksV3"); +// ITaikoInbox.BlockMetadataV3[] memory metas = inbox.proposeBlocksV3( +// address(0), address(0), new ITaikoInbox.BlockParamsV3[](count), "txList" +// ); +// uint256 gasProposeBlocksV3 = vm.stopSnapshotGas("proposeBlocksV3"); +// console2.log("Gas per block - proposing:", gasProposeBlocksV3 / count); + +// ITaikoInbox.TransitionV3[] memory transitions = new ITaikoInbox.TransitionV3[](count); +// for (uint256 i; i < metas.length; ++i) { +// transitions[i].parentHash = correctBlockhash(metas[i].blockId - 1); +// transitions[i].blockHash = correctBlockhash(metas[i].blockId); +// transitions[i].stateRoot = correctStateRoot(metas[i].blockId); +// } + +// vm.startSnapshotGas("proveBlocksV3"); +// inbox.proveBlocksV3(metas, transitions, "proof"); +// uint256 gasProveBlocksV3 = vm.stopSnapshotGas("proveBlocksV3"); +// console2.log("Gas per block - proving:", gasProveBlocksV3 / count); +// console2.log("Gas per block - total:", (gasProposeBlocksV3 + gasProveBlocksV3) / count); + +// _logAllBlocksAndTransitions(); +// } +// } diff --git a/packages/protocol/test/layer1/team/tokenunlock/TokenUnlock_ProverSet.t.sol b/packages/protocol/test/layer1/team/tokenunlock/TokenUnlock_ProverSet.t.sol index 5dc56b3adff..47c625fd532 100644 --- a/packages/protocol/test/layer1/team/tokenunlock/TokenUnlock_ProverSet.t.sol +++ b/packages/protocol/test/layer1/team/tokenunlock/TokenUnlock_ProverSet.t.sol @@ -1,185 +1,185 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.24; - -import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Votes.sol"; -import "src/layer1/team/TokenUnlock.sol"; -import "../../based/InboxTestBase.sol"; - -contract TokenUnlock_ProverSet is InboxTestBase { - uint64 private constant TGE = 1_000_000; - uint96 private constant livenessBond = 125 ether; - - address private taikoL1 = randAddress(); - - TokenUnlock private target; - TaikoToken private taikoToken; - - function getConfig() internal pure override returns (ITaikoInbox.ConfigV3 memory) { - return ITaikoInbox.ConfigV3({ - chainId: LibNetwork.TAIKO_MAINNET, - blockMaxProposals: 10, - blockRingBufferSize: 15, - maxBlocksToVerify: 5, - blockMaxGasLimit: 240_000_000, - livenessBond: livenessBond, // 125 Taiko token - stateRootSyncInternal: 5, - maxAnchorHeightOffset: 64, - baseFeeConfig: LibSharedData.BaseFeeConfig({ - adjustmentQuotient: 8, - sharingPctg: 75, - gasIssuancePerSecond: 5_000_000, - minGasExcess: 1_340_000_000, // correspond to 0.008847185 gwei basefee - maxGasIssuancePerBlock: 600_000_000 // two minutes: 5_000_000 * 120 - }), - provingWindow: 1 hours, - maxSignalsToReceive: 16, - forkHeights: ITaikoInbox.ForkHeights({ ontake: 0, pacaya: 0 }) - }); - } - - function setUpOnEthereum() internal override { - super.setUpOnEthereum(); - taikoToken = deployBondToken(); - - register("taiko_token", address(taikoToken)); - register("prover_set", address(new ProverSet())); - - target = TokenUnlock( - deploy({ - name: "token_unlock", - impl: address(new TokenUnlock()), - data: abi.encodeCall(TokenUnlock.init, (Alice, address(resolver), Bob, TGE)) - }) - ); - } - - function setUp() public override { - super.setUp(); - - vm.warp(TGE); - - vm.prank(Alice); - taikoToken.approve(address(target), 1_000_000_000 ether); - } - - function test_tokenunlock_proverset() public { - taikoToken.transfer(Alice, 1000 ether); - - vm.startPrank(Alice); - target.vest(100 ether); - taikoToken.transfer(address(target), 20 ether); - vm.warp(TGE + target.ONE_YEAR() * 2); - - vm.expectRevert(TokenUnlock.PERMISSION_DENIED.selector); - target.createProverSet(); - vm.stopPrank(); - - vm.startPrank(Bob); - vm.expectRevert(TokenUnlock.NOT_PROVER_SET.selector); - target.depositToProverSet(vm.addr(0x1234), 1 ether); - - ProverSet set1 = ProverSet(payable(target.createProverSet())); - assertEq(set1.owner(), target.owner()); - assertEq(set1.admin(), address(target)); - - assertTrue(target.isProverSet(address(set1))); - - vm.expectRevert(); // ERC20: transfer amount exceeds balance - target.depositToProverSet(address(set1), 121 ether); - - target.depositToProverSet(address(set1), 120 ether); - assertEq(taikoToken.balanceOf(address(set1)), 120 ether); - assertEq(taikoToken.balanceOf(address(target)), 0 ether); - assertEq(target.amountVested(), 100 ether); - assertEq(target.amountWithdrawable(), 0 ether); - - vm.expectRevert(); // ERC20: transfer amount exceeds balance - set1.withdrawToAdmin(121 ether); - - set1.withdrawToAdmin(120 ether); - assertEq(taikoToken.balanceOf(address(set1)), 0 ether); - assertEq(taikoToken.balanceOf(address(target)), 120 ether); - assertEq(target.amountVested(), 100 ether); - assertEq(target.amountWithdrawable(), 70 ether); - - set1.enableProver(Carol, true); - assertTrue(set1.isProver(Carol)); - - vm.expectRevert(ProverSet.INVALID_STATUS.selector); - set1.enableProver(Carol, true); - - set1.delegate(Carol); - assertEq(taikoToken.delegates(address(set1)), Carol); - - // create another one - target.createProverSet(); - - vm.stopPrank(); - - vm.prank(target.owner()); - vm.expectRevert(TokenUnlock.PERMISSION_DENIED.selector); - set1.enableProver(David, true); - - vm.prank(David); - vm.expectRevert(TokenUnlock.PERMISSION_DENIED.selector); - set1.enableProver(Carol, true); - } - - function test_tokenunlock_proverset_propose_and_prove_blocks() public { - uint256 initialBondBalance = 200 ether; - - taikoToken.transfer(Alice, 1000 ether); - - vm.startPrank(Alice); - target.vest(100 ether); - taikoToken.transfer(address(target), 100 ether); - vm.warp(TGE + target.ONE_YEAR() * 2); +// // SPDX-License-Identifier: MIT +// pragma solidity ^0.8.24; + +// import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Votes.sol"; +// import "src/layer1/team/TokenUnlock.sol"; +// import "../../based/InboxTestBase.sol"; + +// contract TokenUnlock_ProverSet is InboxTestBase { +// uint64 private constant TGE = 1_000_000; +// uint96 private constant livenessBond = 125 ether; + +// address private taikoL1 = randAddress(); + +// TokenUnlock private target; +// TaikoToken private taikoToken; + +// function getConfig() internal pure override returns (ITaikoInbox.ConfigV3 memory) { +// return ITaikoInbox.ConfigV3({ +// chainId: LibNetwork.TAIKO_MAINNET, +// blockMaxProposals: 10, +// blockRingBufferSize: 15, +// maxBlocksToVerify: 5, +// blockMaxGasLimit: 240_000_000, +// livenessBond: livenessBond, // 125 Taiko token +// stateRootSyncInternal: 5, +// maxAnchorHeightOffset: 64, +// baseFeeConfig: LibSharedData.BaseFeeConfig({ +// adjustmentQuotient: 8, +// sharingPctg: 75, +// gasIssuancePerSecond: 5_000_000, +// minGasExcess: 1_340_000_000, // correspond to 0.008847185 gwei basefee +// maxGasIssuancePerBlock: 600_000_000 // two minutes: 5_000_000 * 120 +// }), +// provingWindow: 1 hours, +// maxSignalsToReceive: 16, +// forkHeights: ITaikoInbox.ForkHeights({ ontake: 0, pacaya: 0 }) +// }); +// } + +// function setUpOnEthereum() internal override { +// super.setUpOnEthereum(); +// taikoToken = deployBondToken(); + +// register("taiko_token", address(taikoToken)); +// register("prover_set", address(new ProverSet())); + +// target = TokenUnlock( +// deploy({ +// name: "token_unlock", +// impl: address(new TokenUnlock()), +// data: abi.encodeCall(TokenUnlock.init, (Alice, address(resolver), Bob, TGE)) +// }) +// ); +// } + +// function setUp() public override { +// super.setUp(); + +// vm.warp(TGE); + +// vm.prank(Alice); +// taikoToken.approve(address(target), 1_000_000_000 ether); +// } + +// function test_tokenunlock_proverset() public { +// taikoToken.transfer(Alice, 1000 ether); + +// vm.startPrank(Alice); +// target.vest(100 ether); +// taikoToken.transfer(address(target), 20 ether); +// vm.warp(TGE + target.ONE_YEAR() * 2); + +// vm.expectRevert(TokenUnlock.PERMISSION_DENIED.selector); +// target.createProverSet(); +// vm.stopPrank(); + +// vm.startPrank(Bob); +// vm.expectRevert(TokenUnlock.NOT_PROVER_SET.selector); +// target.depositToProverSet(vm.addr(0x1234), 1 ether); + +// ProverSet set1 = ProverSet(payable(target.createProverSet())); +// assertEq(set1.owner(), target.owner()); +// assertEq(set1.admin(), address(target)); + +// assertTrue(target.isProverSet(address(set1))); + +// vm.expectRevert(); // ERC20: transfer amount exceeds balance +// target.depositToProverSet(address(set1), 121 ether); + +// target.depositToProverSet(address(set1), 120 ether); +// assertEq(taikoToken.balanceOf(address(set1)), 120 ether); +// assertEq(taikoToken.balanceOf(address(target)), 0 ether); +// assertEq(target.amountVested(), 100 ether); +// assertEq(target.amountWithdrawable(), 0 ether); + +// vm.expectRevert(); // ERC20: transfer amount exceeds balance +// set1.withdrawToAdmin(121 ether); + +// set1.withdrawToAdmin(120 ether); +// assertEq(taikoToken.balanceOf(address(set1)), 0 ether); +// assertEq(taikoToken.balanceOf(address(target)), 120 ether); +// assertEq(target.amountVested(), 100 ether); +// assertEq(target.amountWithdrawable(), 70 ether); + +// set1.enableProver(Carol, true); +// assertTrue(set1.isProver(Carol)); + +// vm.expectRevert(ProverSet.INVALID_STATUS.selector); +// set1.enableProver(Carol, true); + +// set1.delegate(Carol); +// assertEq(taikoToken.delegates(address(set1)), Carol); + +// // create another one +// target.createProverSet(); + +// vm.stopPrank(); + +// vm.prank(target.owner()); +// vm.expectRevert(TokenUnlock.PERMISSION_DENIED.selector); +// set1.enableProver(David, true); + +// vm.prank(David); +// vm.expectRevert(TokenUnlock.PERMISSION_DENIED.selector); +// set1.enableProver(Carol, true); +// } + +// function test_tokenunlock_proverset_propose_and_prove_blocks() public { +// uint256 initialBondBalance = 200 ether; + +// taikoToken.transfer(Alice, 1000 ether); + +// vm.startPrank(Alice); +// target.vest(100 ether); +// taikoToken.transfer(address(target), 100 ether); +// vm.warp(TGE + target.ONE_YEAR() * 2); - vm.startPrank(Bob); - ProverSet set = ProverSet(payable(target.createProverSet())); - target.depositToProverSet(address(set), initialBondBalance); +// vm.startPrank(Bob); +// ProverSet set = ProverSet(payable(target.createProverSet())); +// target.depositToProverSet(address(set), initialBondBalance); - vm.expectRevert(); // ERC20: transfer amount exceeds balance - set.depositBond(201 ether); +// vm.expectRevert(); // ERC20: transfer amount exceeds balance +// set.depositBond(201 ether); - set.depositBond(200 ether); +// set.depositBond(200 ether); - set.enableProver(Carol, true); - assertTrue(set.isProver(Carol)); - vm.stopPrank(); +// set.enableProver(Carol, true); +// assertTrue(set.isProver(Carol)); +// vm.stopPrank(); - // Only prover in ProverSet can propose taiko blocks - vm.prank(Alice); - vm.expectRevert(TokenUnlock.PERMISSION_DENIED.selector); - ITaikoInbox.BlockParamsV3[] memory paramsArray = new ITaikoInbox.BlockParamsV3[](1); - set.proposeBlocksV3(paramsArray, "txList", false); +// // Only prover in ProverSet can propose taiko blocks +// vm.prank(Alice); +// vm.expectRevert(TokenUnlock.PERMISSION_DENIED.selector); +// ITaikoInbox.BlockParamsV3[] memory paramsArray = new ITaikoInbox.BlockParamsV3[](1); +// set.proposeBlocksV3(paramsArray, "txList", false); - vm.prank(Carol); - ITaikoInbox.BlockMetadataV3[] memory metas = - set.proposeBlocksV3(paramsArray, "txList", false); +// vm.prank(Carol); +// ITaikoInbox.BlockMetadataV3[] memory metas = +// set.proposeBlocksV3(paramsArray, "txList", false); - vm.startPrank(Bob); - vm.expectRevert(); - set.withdrawBond(initialBondBalance); - set.withdrawBond(initialBondBalance - livenessBond); - vm.stopPrank(); +// vm.startPrank(Bob); +// vm.expectRevert(); +// set.withdrawBond(initialBondBalance); +// set.withdrawBond(initialBondBalance - livenessBond); +// vm.stopPrank(); - // Only prover in ProverSet can prove taiko blocks - ITaikoInbox.TransitionV3[] memory transitions = new ITaikoInbox.TransitionV3[](1); - for (uint256 i; i < metas.length; ++i) { - transitions[i].parentHash = correctBlockhash(metas[i].blockId - 1); - transitions[i].blockHash = correctBlockhash(metas[i].blockId); - transitions[i].stateRoot = correctStateRoot(metas[i].blockId); - } +// // Only prover in ProverSet can prove taiko blocks +// ITaikoInbox.TransitionV3[] memory transitions = new ITaikoInbox.TransitionV3[](1); +// for (uint256 i; i < metas.length; ++i) { +// transitions[i].parentHash = correctBlockhash(metas[i].blockId - 1); +// transitions[i].blockHash = correctBlockhash(metas[i].blockId); +// transitions[i].stateRoot = correctStateRoot(metas[i].blockId); +// } - vm.prank(Alice); - vm.expectRevert(TokenUnlock.PERMISSION_DENIED.selector); - set.proveBlocksV3(metas, transitions, "proof"); +// vm.prank(Alice); +// vm.expectRevert(TokenUnlock.PERMISSION_DENIED.selector); +// set.proveBlocksV3(metas, transitions, "proof"); - vm.prank(Carol); - set.proveBlocksV3(metas, transitions, "proof"); +// vm.prank(Carol); +// set.proveBlocksV3(metas, transitions, "proof"); - vm.startPrank(Bob); - set.withdrawBond(livenessBond); - } -} +// vm.startPrank(Bob); +// set.withdrawBond(livenessBond); +// } +// } From 73888cbf8527eed06542aa5263732c0671ddcfa4 Mon Sep 17 00:00:00 2001 From: Daniel Wang Date: Thu, 9 Jan 2025 15:31:56 +0800 Subject: [PATCH 02/41] add sub block configs --- .../protocol/contracts/layer1/based/ITaikoInbox.sol | 10 +++++++++- .../protocol/contracts/layer1/based/TaikoInbox.sol | 5 +++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/packages/protocol/contracts/layer1/based/ITaikoInbox.sol b/packages/protocol/contracts/layer1/based/ITaikoInbox.sol index a06304747a7..dd25e984aa4 100644 --- a/packages/protocol/contracts/layer1/based/ITaikoInbox.sol +++ b/packages/protocol/contracts/layer1/based/ITaikoInbox.sol @@ -17,6 +17,11 @@ import "src/shared/based/LibSharedData.sol"; /// @dev Registered in the address resolver as "taiko". /// @custom:security-contact security@taiko.xyz interface ITaikoInbox { + struct SubBlockV3{ + uint16 numTransactions; + uint8 timeThift; + } + struct BlockParamsV3 { bytes32 parentMetaHash; uint64 anchorBlockId; @@ -26,6 +31,7 @@ interface ITaikoInbox { uint32 txListSize; uint8 blobIndex; bytes32[] signalSlots; + SubBlockV3[] subBlocks; } struct BlockMetadataV3 { @@ -47,6 +53,7 @@ interface ITaikoInbox { uint64 anchorBlockId; bytes32 anchorBlockHash; bytes32[] signalSlots; + SubBlockV3[] subBlocks; bytes32 anchorInput; LibSharedData.BaseFeeConfig baseFeeConfig; } @@ -67,7 +74,7 @@ interface ITaikoInbox { uint64 timestamp; uint64 anchorBlockId; uint24 nextTransitionId; - bool _reserved1; + uint8 numSubBlocks; // The ID of the transaction that is used to verify this block. However, if this block is // not verified as the last block in a batch, verifiedTransitionId will remain zero. uint24 verifiedTransitionId; @@ -207,6 +214,7 @@ interface ITaikoInbox { error InsufficientBond(); error InvalidForkHeight(); error InvalidGenesisBlockHash(); + error InvalidSubBlocks(); error InvalidTransitionBlockHash(); error InvalidTransitionParentHash(); error InvalidTransitionStateRoot(); diff --git a/packages/protocol/contracts/layer1/based/TaikoInbox.sol b/packages/protocol/contracts/layer1/based/TaikoInbox.sol index 914e9e113cb..50d1e9ad408 100644 --- a/packages/protocol/contracts/layer1/based/TaikoInbox.sol +++ b/packages/protocol/contracts/layer1/based/TaikoInbox.sol @@ -136,6 +136,7 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { anchorBlockId: updatedParams.anchorBlockId, anchorBlockHash: blockhash(updatedParams.anchorBlockId), signalSlots: _paramsArray[i].signalSlots, + subBlocks: _paramsArray[i].subBlocks, anchorInput: _paramsArray[i].anchorInput, baseFeeConfig: config.baseFeeConfig }); @@ -153,6 +154,7 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { blk.timestamp = updatedParams.timestamp; blk.anchorBlockId = updatedParams.anchorBlockId; blk.nextTransitionId = 1; + blk.numSubBlocks =uint8(_paramsArray[i].subBlocks.length); blk.verifiedTransitionId = 0; // SSTORE }} @@ -621,6 +623,9 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { require(signalService.isSignalSent(_params.signalSlots[i]), SignalNotSent()); } } + + + require(_params.subBlocks.length != 0 && _params.subBlocks.length <= type(uint8).max, InvalidSubBlocks()); } // Memory-only structs ---------------------------------------------------------------------- From 1d55b38261c16c834c3a0803bf7ecdf7933fd53a Mon Sep 17 00:00:00 2001 From: Daniel Wang Date: Thu, 9 Jan 2025 23:22:02 +0800 Subject: [PATCH 03/41] support multiple blobs --- .../contracts/layer1/based/ITaikoInbox.sol | 6 ++-- .../contracts/layer1/based/TaikoInbox.sol | 31 +++++++++++++------ packages/protocol/test/layer1/Layer1Test.sol | 2 +- .../layer1/based/InBoxTest_BlockParams.t.sol | 3 +- .../test/layer1/based/InboxTestBase.sol | 6 ++-- .../based/InboxTest_BondMechanics.t.sol | 12 ++++--- .../test/layer1/based/InboxTest_BondToken.sol | 3 +- .../layer1/based/InboxTest_EtherAsBond.t.sol | 3 +- .../test/layer1/based/InboxTest_Suite1.t.sol | 12 ++++--- 9 files changed, 52 insertions(+), 26 deletions(-) diff --git a/packages/protocol/contracts/layer1/based/ITaikoInbox.sol b/packages/protocol/contracts/layer1/based/ITaikoInbox.sol index dd25e984aa4..c6ca546c980 100644 --- a/packages/protocol/contracts/layer1/based/ITaikoInbox.sol +++ b/packages/protocol/contracts/layer1/based/ITaikoInbox.sol @@ -17,7 +17,7 @@ import "src/shared/based/LibSharedData.sol"; /// @dev Registered in the address resolver as "taiko". /// @custom:security-contact security@taiko.xyz interface ITaikoInbox { - struct SubBlockV3{ + struct SubBlockV3 { uint16 numTransactions; uint8 timeThift; } @@ -29,7 +29,7 @@ interface ITaikoInbox { uint64 timestamp; uint32 txListOffset; uint32 txListSize; - uint8 blobIndex; + uint8[] blobIndices; bytes32[] signalSlots; SubBlockV3[] subBlocks; } @@ -49,7 +49,7 @@ interface ITaikoInbox { uint64 proposedIn; // Used by node/client post block proposal. uint32 txListOffset; uint32 txListSize; - uint8 blobIndex; + uint8[] blobIndices; uint64 anchorBlockId; bytes32 anchorBlockHash; bytes32[] signalSlots; diff --git a/packages/protocol/contracts/layer1/based/TaikoInbox.sol b/packages/protocol/contracts/layer1/based/TaikoInbox.sol index 50d1e9ad408..402d4c8166e 100644 --- a/packages/protocol/contracts/layer1/based/TaikoInbox.sol +++ b/packages/protocol/contracts/layer1/based/TaikoInbox.sol @@ -104,7 +104,13 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { UpdatedParams memory updatedParams; for (uint256 i; i < _paramsArray.length; ++i) { - require(calldataUsed || _paramsArray[i].blobIndex != 0, BlobIndexZero()); + if (!calldataUsed) { + require(_paramsArray[i].blobIndices.length != 0, BlobIndexZero()); + for (uint256 j; j < _paramsArray[i].blobIndices[j]; ++j) { + require(_paramsArray[i].blobIndices[j] != 0, BlobIndexZero()); + } + } + updatedParams = _validateBlockParams( _paramsArray[i], config.maxAnchorHeightOffset, config.maxSignalsToReceive, lastBlock ); @@ -119,7 +125,7 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { difficulty: keccak256(abi.encode("TAIKO_DIFFICULTY", stats2.numBlocks)), txListHash: calldataUsed ? keccak256(_txList) - : _blobhash(_paramsArray[i].blobIndex - 1), + : _calcTxListHash(_paramsArray[i].blobIndices), extraData: bytes32(uint256(config.baseFeeConfig.sharingPctg)), coinbase: _coinbase, blockId: stats2.numBlocks, @@ -132,11 +138,11 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { proposedIn: uint64(block.number), txListOffset: _paramsArray[i].txListOffset, txListSize: _paramsArray[i].txListSize, - blobIndex: calldataUsed ? 0 : _paramsArray[i].blobIndex, + blobIndices: calldataUsed ? new uint8[](0) : _paramsArray[i].blobIndices, anchorBlockId: updatedParams.anchorBlockId, anchorBlockHash: blockhash(updatedParams.anchorBlockId), signalSlots: _paramsArray[i].signalSlots, - subBlocks: _paramsArray[i].subBlocks, + subBlocks: _paramsArray[i].subBlocks, anchorInput: _paramsArray[i].anchorInput, baseFeeConfig: config.baseFeeConfig }); @@ -154,7 +160,7 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { blk.timestamp = updatedParams.timestamp; blk.anchorBlockId = updatedParams.anchorBlockId; blk.nextTransitionId = 1; - blk.numSubBlocks =uint8(_paramsArray[i].subBlocks.length); + blk.numSubBlocks = uint8(_paramsArray[i].subBlocks.length); blk.verifiedTransitionId = 0; // SSTORE }} @@ -441,8 +447,13 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { state.stats2.paused = true; } - function _blobhash(uint256 _blobIndex) internal view virtual returns (bytes32) { - return blobhash(_blobIndex); + function _calcTxListHash(uint8[] memory blobIndices) internal view virtual returns (bytes32) { + bytes32[] memory blobHashes = new bytes32[](blobIndices.length); + for (uint256 i; i < blobIndices.length; ++i) { + blobHashes[i] = blobhash(blobIndices[i]); + require(blobHashes[i] != 0, BlobNotFound()); + } + return keccak256(abi.encode(blobHashes)); } // Private functions ----------------------------------------------------------------------- @@ -624,8 +635,10 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { } } - - require(_params.subBlocks.length != 0 && _params.subBlocks.length <= type(uint8).max, InvalidSubBlocks()); + require( + _params.subBlocks.length != 0 && _params.subBlocks.length <= type(uint8).max, + InvalidSubBlocks() + ); } // Memory-only structs ---------------------------------------------------------------------- diff --git a/packages/protocol/test/layer1/Layer1Test.sol b/packages/protocol/test/layer1/Layer1Test.sol index a18cfc20d96..61bd331cdf3 100644 --- a/packages/protocol/test/layer1/Layer1Test.sol +++ b/packages/protocol/test/layer1/Layer1Test.sol @@ -31,7 +31,7 @@ contract ConfigurableInbox is TaikoInbox { return __config; } - function _blobhash(uint256) internal pure override returns (bytes32) { + function _calcTxListHash(uint8[] memory) internal pure override returns (bytes32) { return keccak256("BLOB"); } } diff --git a/packages/protocol/test/layer1/based/InBoxTest_BlockParams.t.sol b/packages/protocol/test/layer1/based/InBoxTest_BlockParams.t.sol index f51c576dedb..63773cc4bfa 100644 --- a/packages/protocol/test/layer1/based/InBoxTest_BlockParams.t.sol +++ b/packages/protocol/test/layer1/based/InBoxTest_BlockParams.t.sol @@ -131,7 +131,8 @@ pragma solidity ^0.8.24; // inbox.proposeBlocksV3(address(0), address(0), paramsArray, "txList"); // } -// function test_validateBlockParams_when_anchorBlockId_is_not_zero() external transactBy(Alice) { +// function test_validateBlockParams_when_anchorBlockId_is_not_zero() external transactBy(Alice) +// { // ITaikoInbox.BlockParamsV3[] memory paramsArray = new ITaikoInbox.BlockParamsV3[](1); // paramsArray[0] = ITaikoInbox.BlockParamsV3({ // anchorBlockId: uint64(block.number - 1), diff --git a/packages/protocol/test/layer1/based/InboxTestBase.sol b/packages/protocol/test/layer1/based/InboxTestBase.sol index 62b8dc24948..6629234a9d1 100644 --- a/packages/protocol/test/layer1/based/InboxTestBase.sol +++ b/packages/protocol/test/layer1/based/InboxTestBase.sol @@ -70,7 +70,8 @@ pragma solidity ^0.8.24; // _; // } -// // internal helper functions ------------------------------------------------------------------- +// // internal helper functions +// ------------------------------------------------------------------- // function _proposeBlocksWithDefaultParameters(uint256 numBlocksToPropose) // internal @@ -161,7 +162,8 @@ pragma solidity ^0.8.24; // } else { // console2.log(unicode"|─── block#", blk.blockId); // } -// console2.log(unicode"│ |── metahash:", Strings.toHexString(uint256(blk.metaHash))); +// console2.log(unicode"│ |── metahash:", +// Strings.toHexString(uint256(blk.metaHash))); // console2.log(unicode"│ |── timestamp:", blk.timestamp); // console2.log(unicode"│ |── anchorBlockId:", blk.anchorBlockId); // console2.log(unicode"│ |── nextTransitionId:", blk.nextTransitionId); diff --git a/packages/protocol/test/layer1/based/InboxTest_BondMechanics.t.sol b/packages/protocol/test/layer1/based/InboxTest_BondMechanics.t.sol index 50fdcfda70b..987e1083ab6 100644 --- a/packages/protocol/test/layer1/based/InboxTest_BondMechanics.t.sol +++ b/packages/protocol/test/layer1/based/InboxTest_BondMechanics.t.sol @@ -44,7 +44,8 @@ pragma solidity ^0.8.24; // setupBondTokenState(Alice, initialBondBalance, bondAmount); // vm.prank(Alice); -// uint64[] memory blockIds = _proposeBlocksWithDefaultParameters({ numBlocksToPropose: 1 }); +// uint64[] memory blockIds = _proposeBlocksWithDefaultParameters({ numBlocksToPropose: 1 +// }); // assertEq(inbox.bondBalanceOf(Alice) < bondAmount, true); // vm.prank(Alice); @@ -63,7 +64,8 @@ pragma solidity ^0.8.24; // setupBondTokenState(Bob, initialBondBalance, bondAmount); // vm.prank(Alice); -// uint64[] memory blockIds = _proposeBlocksWithDefaultParameters({ numBlocksToPropose: 1 }); +// uint64[] memory blockIds = _proposeBlocksWithDefaultParameters({ numBlocksToPropose: 1 +// }); // assertEq(inbox.bondBalanceOf(Alice) < bondAmount, true); // vm.prank(Bob); @@ -84,7 +86,8 @@ pragma solidity ^0.8.24; // setupBondTokenState(Alice, initialBondBalance, bondAmount); // vm.prank(Alice); -// uint64[] memory blockIds = _proposeBlocksWithDefaultParameters({ numBlocksToPropose: 1 }); +// uint64[] memory blockIds = _proposeBlocksWithDefaultParameters({ numBlocksToPropose: 1 +// }); // uint256 aliceBondBalanceAfterProposal = inbox.bondBalanceOf(Alice); // assertEq(aliceBondBalanceAfterProposal < bondAmount, true); @@ -113,7 +116,8 @@ pragma solidity ^0.8.24; // setupBondTokenState(Alice, initialBondBalance, bondAmount); // vm.prank(Alice); -// uint64[] memory blockIds = _proposeBlocksWithDefaultParameters({ numBlocksToPropose: 1 }); +// uint64[] memory blockIds = _proposeBlocksWithDefaultParameters({ numBlocksToPropose: 1 +// }); // uint256 aliceBondBalanceAfterProposal = inbox.bondBalanceOf(Alice); // assertEq(aliceBondBalanceAfterProposal < bondAmount, true); diff --git a/packages/protocol/test/layer1/based/InboxTest_BondToken.sol b/packages/protocol/test/layer1/based/InboxTest_BondToken.sol index 4c222094abb..aa7849a82b7 100644 --- a/packages/protocol/test/layer1/based/InboxTest_BondToken.sol +++ b/packages/protocol/test/layer1/based/InboxTest_BondToken.sol @@ -180,7 +180,8 @@ pragma solidity ^0.8.24; // vm.prank(Alice); // inbox.withdrawBond(aliceFirstWithdraw); // assertEq( -// inbox.bondBalanceOf(Alice), aliceFirstDeposit + aliceSecondDeposit - aliceFirstWithdraw +// inbox.bondBalanceOf(Alice), aliceFirstDeposit + aliceSecondDeposit - +// aliceFirstWithdraw // ); // vm.prank(Alice); diff --git a/packages/protocol/test/layer1/based/InboxTest_EtherAsBond.t.sol b/packages/protocol/test/layer1/based/InboxTest_EtherAsBond.t.sol index 045585a90d1..8484b965212 100644 --- a/packages/protocol/test/layer1/based/InboxTest_EtherAsBond.t.sol +++ b/packages/protocol/test/layer1/based/InboxTest_EtherAsBond.t.sol @@ -131,7 +131,8 @@ pragma solidity ^0.8.24; // vm.prank(Alice); // inbox.withdrawBond(aliceFirstWithdraw); // assertEq( -// inbox.bondBalanceOf(Alice), aliceFirstDeposit + aliceSecondDeposit - aliceFirstWithdraw +// inbox.bondBalanceOf(Alice), aliceFirstDeposit + aliceSecondDeposit - +// aliceFirstWithdraw // ); // vm.prank(Alice); diff --git a/packages/protocol/test/layer1/based/InboxTest_Suite1.t.sol b/packages/protocol/test/layer1/based/InboxTest_Suite1.t.sol index 0739cd3e575..26f99dda96b 100644 --- a/packages/protocol/test/layer1/based/InboxTest_Suite1.t.sol +++ b/packages/protocol/test/layer1/based/InboxTest_Suite1.t.sol @@ -54,7 +54,8 @@ pragma solidity ^0.8.24; // assertEq(blk.nextTransitionId, 2); // assertEq(blk.verifiedTransitionId, 1); -// (uint64 blockId, ITaikoInbox.TransitionV3 memory tran) = inbox.getLastVerifiedTransitionV3(); +// (uint64 blockId, ITaikoInbox.TransitionV3 memory tran) = +// inbox.getLastVerifiedTransitionV3(); // assertEq(blockId, 0); // assertEq(tran.blockHash, correctBlockhash(0)); // assertEq(tran.stateRoot, bytes32(uint256(0))); @@ -207,7 +208,8 @@ pragma solidity ^0.8.24; // assertEq(stats2.lastProposedIn, block.number); // assertEq(stats2.lastUnpausedAt, 0); -// (uint64 blockId, ITaikoInbox.TransitionV3 memory tran) = inbox.getLastVerifiedTransitionV3(); +// (uint64 blockId, ITaikoInbox.TransitionV3 memory tran) = +// inbox.getLastVerifiedTransitionV3(); // assertEq(blockId, 9); // assertEq(tran.blockHash, correctBlockhash(9)); // assertEq(tran.stateRoot, bytes32(uint256(0))); @@ -315,7 +317,8 @@ pragma solidity ^0.8.24; // assertEq(stats2.lastProposedIn, block.number); // assertEq(stats2.lastUnpausedAt, 0); -// (uint64 blockId, ITaikoInbox.TransitionV3 memory tran) = inbox.getLastVerifiedTransitionV3(); +// (uint64 blockId, ITaikoInbox.TransitionV3 memory tran) = +// inbox.getLastVerifiedTransitionV3(); // assertEq(blockId, 10); // assertEq(tran.blockHash, correctBlockhash(10)); // assertEq(tran.stateRoot, correctStateRoot(10)); @@ -395,7 +398,8 @@ pragma solidity ^0.8.24; // uint64 count = 1; // vm.expectRevert(ITaikoInbox.CustomProposerNotAllowed.selector); -// inbox.proposeBlocksV3(Alice, address(0), new ITaikoInbox.BlockParamsV3[](count), "txList"); +// inbox.proposeBlocksV3(Alice, address(0), new ITaikoInbox.BlockParamsV3[](count), +// "txList"); // vm.startPrank(deployer); // address preconfRouter = Bob; From 1f798006fd5ed52b15745ec46ffc21ded14b05c9 Mon Sep 17 00:00:00 2001 From: Daniel Wang Date: Fri, 10 Jan 2025 11:27:38 +0800 Subject: [PATCH 04/41] rename 1 --- .../contracts/layer1/based/ITaikoInbox.sol | 84 +++++----- .../contracts/layer1/based/TaikoInbox.sol | 148 +++++++++--------- .../preconf/iface/IPreconfTaskManager.sol | 2 +- .../preconf/impl/PreconfTaskManager.sol | 6 +- .../contracts/layer1/provers/ProverSet.sol | 8 +- .../contracts/layer1/verifiers/IVerifier.sol | 4 +- .../layer1/verifiers/LibPublicInput.sol | 2 +- .../shared/tokenvault/ERC20Vault.sol | 2 +- .../test/layer1/based/helpers/StubInbox.sol | 30 ++-- .../preconf/blocks/BlockProposing.t.sol | 4 +- .../tokenunlock/TokenUnlock_ProverSet.t.sol | 4 +- .../test/layer1/verifiers/SP1Verifier.t.sol | 12 +- 12 files changed, 153 insertions(+), 153 deletions(-) diff --git a/packages/protocol/contracts/layer1/based/ITaikoInbox.sol b/packages/protocol/contracts/layer1/based/ITaikoInbox.sol index c6ca546c980..6bbc5374356 100644 --- a/packages/protocol/contracts/layer1/based/ITaikoInbox.sol +++ b/packages/protocol/contracts/layer1/based/ITaikoInbox.sol @@ -17,12 +17,12 @@ import "src/shared/based/LibSharedData.sol"; /// @dev Registered in the address resolver as "taiko". /// @custom:security-contact security@taiko.xyz interface ITaikoInbox { - struct SubBlockV3 { + struct SubBatch { uint16 numTransactions; uint8 timeThift; } - struct BlockParamsV3 { + struct BatchParams { bytes32 parentMetaHash; uint64 anchorBlockId; bytes32 anchorInput; @@ -31,15 +31,15 @@ interface ITaikoInbox { uint32 txListSize; uint8[] blobIndices; bytes32[] signalSlots; - SubBlockV3[] subBlocks; + SubBatch[] subBlocks; } - struct BlockMetadataV3 { + struct BatchMetadata { bytes32 difficulty; bytes32 txListHash; bytes32 extraData; address coinbase; - uint64 blockId; + uint64 batchId; uint32 gasLimit; uint64 timestamp; bytes32 parentMetaHash; @@ -53,24 +53,24 @@ interface ITaikoInbox { uint64 anchorBlockId; bytes32 anchorBlockHash; bytes32[] signalSlots; - SubBlockV3[] subBlocks; + SubBatch[] subBlocks; bytes32 anchorInput; LibSharedData.BaseFeeConfig baseFeeConfig; } /// @notice Struct representing transition to be proven. - struct TransitionV3 { + struct Transition { bytes32 parentHash; bytes32 blockHash; bytes32 stateRoot; } /// @notice 3 slots used. - struct BlockV3 { + struct Batch { bytes32 metaHash; // slot 1 address _reserved2; uint96 _reserved3; - uint64 blockId; // slot 3 + uint64 batchId; // slot 3 uint64 timestamp; uint64 anchorBlockId; uint24 nextTransitionId; @@ -87,13 +87,13 @@ interface ITaikoInbox { struct Stats1 { uint64 __reserved1; uint64 __reserved2; - uint64 lastSyncedBlockId; + uint64 lastSyncedBatch; uint64 lastSyncedAt; } struct Stats2 { uint64 numBlocks; - uint64 lastVerifiedBlockId; + uint64 lastVerifiedBatch; bool paused; uint56 lastProposedIn; uint64 lastUnpausedAt; @@ -135,13 +135,13 @@ interface ITaikoInbox { /// @notice Struct holding the state variables for the {Taiko} contract. struct State { // Ring buffer for proposed blocks and a some recent verified blocks. - mapping(uint256 blockId_mod_blockRingBufferSize => BlockV3 blk) blocks; + mapping(uint256 batchId_mod_blockRingBufferSize => Batch blk) blocks; // Indexing to transition ids (ring buffer not possible) - mapping(uint256 blockId => mapping(bytes32 parentHash => uint24 transitionId)) transitionIds; + mapping(uint256 batchId => mapping(bytes32 parentHash => uint24 transitionId)) transitionIds; // Ring buffer for transitions mapping( - uint256 blockId_mod_blockRingBufferSize - => mapping(uint24 transitionId => TransitionV3 ts) + uint256 batchId_mod_blockRingBufferSize + => mapping(uint24 transitionId => Transition ts) ) transitions; bytes32 __reserve1; // Used as a ring buffer for Ether deposits Stats1 stats1; // slot 5 @@ -182,22 +182,22 @@ interface ITaikoInbox { /// @param metas The metadata of the proposed blocks. /// @param calldataUsed Whether calldata is used for txList DA. /// @param txListInCalldata The tx list in calldata. - event BlocksProposedV3(BlockMetadataV3[] metas, bool calldataUsed, bytes txListInCalldata); + event BlocksProposedV3(BatchMetadata[] metas, bool calldataUsed, bytes txListInCalldata); /// @notice Emitted when multiple transitions are proved. /// @param verifier The address of the verifier. /// @param transitions The transitions data. - event BlocksProvedV3(address verifier, uint64[] blockIds, TransitionV3[] transitions); + event BlocksProvedV3(address verifier, uint64[] batchIds, Transition[] transitions); /// @notice Emitted when a transition is overwritten by another one. - /// @param blockId The block ID. + /// @param batchId The block ID. /// @param tran The transition data that has been overwritten. - event TransitionOverwrittenV3(uint64 blockId, TransitionV3 tran); + event TransitionOverwrittenV3(uint64 batchId, Transition tran); /// @notice Emitted when a block is verified. - /// @param blockId The ID of the verified block. + /// @param batchId The ID of the verified block. /// @param blockHash The hash of the verified block. - event BlockVerifiedV3(uint64 blockId, bytes32 blockHash); + event BlockVerifiedV3(uint64 batchId, bytes32 blockHash); error AnchorBlockIdSmallerThanParent(); error AnchorBlockIdTooSmall(); @@ -245,19 +245,19 @@ interface ITaikoInbox { function proposeBlocksV3( address _proposer, address _coinbase, - BlockParamsV3[] calldata _blockParams, + BatchParams[] calldata _blockParams, bytes calldata _txList ) external - returns (BlockMetadataV3[] memory); + returns (BatchMetadata[] memory); /// @notice Proves state transitions for multiple blocks with a single aggregated proof. /// @param _metas Array of metadata for each block being proved. /// @param _transitions Array of block transitions to be proved. /// @param proof The aggregated cryptographic proof proving the blocks transitions. function proveBlocksV3( - BlockMetadataV3[] calldata _metas, - TransitionV3[] calldata _transitions, + BatchMetadata[] calldata _metas, + Transition[] calldata _transitions, bytes calldata proof ) external; @@ -289,46 +289,46 @@ interface ITaikoInbox { function getStats2() external view returns (Stats2 memory); /// @notice Retrieves data about a specific block. - /// @param _blockId The ID of the block to retrieve. - /// @return blk_ The block data. - function getBlockV3(uint64 _blockId) external view returns (BlockV3 memory blk_); + /// @param _batchId The ID of the block to retrieve. + /// @return batch_ The block data. + function getBatch(uint64 _batchId) external view returns (Batch memory batch_); - /// @notice Retrieves a specific transition by block ID and transition ID. This function may + /// @notice Retrieves a specific transition by batch ID and transition ID. This function may /// revert if the transition is not found. - /// @param _blockId The block ID. + /// @param _batchId The block ID. /// @param _tid The transition ID. /// @return The specified transition. - function getTransitionV3( - uint64 _blockId, + function getTransition( + uint64 _batchId, uint24 _tid ) external view - returns (ITaikoInbox.TransitionV3 memory); + returns (ITaikoInbox.Transition memory); /// @notice Retrieves the transition used for the last verified block. - /// @return blockId_ The block ID of the last verified transition. + /// @return batchId_ The block ID of the last verified transition. /// @return tran_ The last verified transition. - function getLastVerifiedTransitionV3() + function getLastVerifiedTransition() external view - returns (uint64 blockId_, TransitionV3 memory tran_); + returns (uint64 batchId_, Transition memory tran_); /// @notice Retrieves the transition used for the last synced block. - /// @return blockId_ The block ID of the last synced transition. + /// @return batchId_ The block ID of the last synced transition. /// @return tran_ The last synced transition. - function getLastSyncedTransitionV3() + function getLastSyncedTransition() external view - returns (uint64 blockId_, TransitionV3 memory tran_); + returns (uint64 batchId_, Transition memory tran_); /// @notice Retrieves the transition used for verifying a block. - /// @param _blockId The block ID. + /// @param _batchId The block ID. /// @return The transition used for verifying the block. - function getBlockVerifyingTransition(uint64 _blockId) + function getBatchVerifyingTransition(uint64 _batchId) external view - returns (TransitionV3 memory); + returns (Transition memory); /// @notice Retrieves the current protocol configuration. /// @return The current configuration. diff --git a/packages/protocol/contracts/layer1/based/TaikoInbox.sol b/packages/protocol/contracts/layer1/based/TaikoInbox.sol index 402d4c8166e..918d35416b4 100644 --- a/packages/protocol/contracts/layer1/based/TaikoInbox.sol +++ b/packages/protocol/contracts/layer1/based/TaikoInbox.sol @@ -54,12 +54,12 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { function proposeBlocksV3( address _proposer, address _coinbase, - BlockParamsV3[] calldata _paramsArray, + BatchParams[] calldata _paramsArray, bytes calldata _txList ) external nonReentrant - returns (BlockMetadataV3[] memory metas_) + returns (BatchMetadata[] memory metas_) { require(_paramsArray.length != 0, NoBlocksToPropose()); @@ -72,7 +72,7 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { unchecked { require( stats2.numBlocks + _paramsArray.length - <= stats2.lastVerifiedBlockId + config.blockMaxProposals, + <= stats2.lastVerifiedBatch + config.blockMaxProposals, TooManyBlocks() ); } @@ -93,13 +93,13 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { // Keep track of last block's information. BlockInfo memory lastBlock; unchecked { - BlockV3 storage lastBlk = + Batch storage lastBlk = state.blocks[(stats2.numBlocks - 1) % config.blockRingBufferSize]; lastBlock = BlockInfo(lastBlk.metaHash, lastBlk.timestamp, lastBlk.anchorBlockId); } - metas_ = new BlockMetadataV3[](_paramsArray.length); + metas_ = new BatchMetadata[](_paramsArray.length); bool calldataUsed = _txList.length != 0; UpdatedParams memory updatedParams; @@ -121,14 +121,14 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { // The metadata must be supplied as calldata prior to proving the block, enabling the // computation and verification of its integrity through the comparison of the metahash. unchecked { - metas_[i] = BlockMetadataV3({ + metas_[i] = BatchMetadata({ difficulty: keccak256(abi.encode("TAIKO_DIFFICULTY", stats2.numBlocks)), txListHash: calldataUsed ? keccak256(_txList) : _calcTxListHash(_paramsArray[i].blobIndices), extraData: bytes32(uint256(config.baseFeeConfig.sharingPctg)), coinbase: _coinbase, - blockId: stats2.numBlocks, + batchId: stats2.numBlocks, gasLimit: config.blockMaxGasLimit, timestamp: updatedParams.timestamp, parentMetaHash: lastBlock.metaHash, @@ -151,12 +151,12 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { require(metas_[i].txListHash != 0, BlobNotFound()); bytes32 metaHash = keccak256(abi.encode(metas_[i])); - BlockV3 storage blk = state.blocks[stats2.numBlocks % config.blockRingBufferSize]; + Batch storage blk = state.blocks[stats2.numBlocks % config.blockRingBufferSize]; // SSTORE #1 blk.metaHash = metaHash; // SSTORE #2 {{ - blk.blockId = stats2.numBlocks; + blk.batchId = stats2.numBlocks; blk.timestamp = updatedParams.timestamp; blk.anchorBlockId = updatedParams.anchorBlockId; blk.nextTransitionId = 1; @@ -184,8 +184,8 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { /// @param _transitions Array of transitions corresponding to the block metadata. /// @param _proof Cryptographic proof validating all the transitions. function proveBlocksV3( - BlockMetadataV3[] calldata _metas, - TransitionV3[] calldata _transitions, + BatchMetadata[] calldata _metas, + Transition[] calldata _transitions, bytes calldata _proof ) external @@ -198,30 +198,30 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { require(stats2.paused == false, ContractPaused()); ConfigV3 memory config = getConfigV3(); - uint64[] memory blockIds = new uint64[](_metas.length); + uint64[] memory batchIds = new uint64[](_metas.length); IVerifier.Context[] memory ctxs = new IVerifier.Context[](_metas.length); for (uint256 i; i < _metas.length; ++i) { - BlockMetadataV3 calldata meta = _metas[i]; + BatchMetadata calldata meta = _metas[i]; - blockIds[i] = meta.blockId; - require(meta.blockId >= config.forkHeights.pacaya, InvalidForkHeight()); - require(meta.blockId > stats2.lastVerifiedBlockId, BlockNotFound()); - require(meta.blockId < stats2.numBlocks, BlockNotFound()); + batchIds[i] = meta.batchId; + require(meta.batchId >= config.forkHeights.pacaya, InvalidForkHeight()); + require(meta.batchId > stats2.lastVerifiedBatch, BlockNotFound()); + require(meta.batchId < stats2.numBlocks, BlockNotFound()); - TransitionV3 calldata tran = _transitions[i]; + Transition calldata tran = _transitions[i]; require(tran.parentHash != 0, InvalidTransitionParentHash()); require(tran.blockHash != 0, InvalidTransitionBlockHash()); require(tran.stateRoot != 0, InvalidTransitionStateRoot()); - ctxs[i].blockId = meta.blockId; + ctxs[i].batchId = meta.batchId; ctxs[i].difficulty = meta.difficulty; ctxs[i].metaHash = keccak256(abi.encode(meta)); ctxs[i].transition = tran; // Verify the block's metadata. - uint256 slot = meta.blockId % config.blockRingBufferSize; - BlockV3 storage blk = state.blocks[slot]; + uint256 slot = meta.batchId % config.blockRingBufferSize; + Batch storage blk = state.blocks[slot]; require(ctxs[i].metaHash == blk.metaHash, MetaHashMismatch()); // Finds out if this transition is overwriting an existing one (with the same parent @@ -237,7 +237,7 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { // Retrieve the transition ID using the parent hash from the mapping. If the ID // is 0, it indicates a new transition; otherwise, it's an overwrite of an // existing transition. - tid = state.transitionIds[meta.blockId][tran.parentHash]; + tid = state.transitionIds[meta.batchId][tran.parentHash]; } } @@ -247,9 +247,9 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { tid = blk.nextTransitionId++; } - TransitionV3 storage ts = state.transitions[slot][tid]; + Transition storage ts = state.transitions[slot][tid]; if (isOverwrite) { - emit TransitionOverwrittenV3(meta.blockId, ts); + emit TransitionOverwrittenV3(meta.batchId, ts); } else if (tid == 1) { // Ensure that only the block proposer can prove the first transition before the // proving deadline. @@ -267,10 +267,10 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { // No need to write parent hash to storage for transitions with id != 1 as the // parent hash is not used at all, instead, we need to update the parent hash to ID // mapping. - state.transitionIds[meta.blockId][tran.parentHash] = tid; + state.transitionIds[meta.batchId][tran.parentHash] = tid; } - if (meta.blockId % config.stateRootSyncInternal == 0) { + if (meta.batchId % config.stateRootSyncInternal == 0) { // This block is a "sync block", we need to save the state root. ts.stateRoot = tran.stateRoot; } else { @@ -284,7 +284,7 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { address verifier = resolve(LibStrings.B_PROOF_VERIFIER, false); IVerifier(verifier).verifyProof(ctxs, _proof); - emit BlocksProvedV3(verifier, blockIds, _transitions); + emit BlocksProvedV3(verifier, batchIds, _transitions); _verifyBlocks(config, stats2, _metas.length); } @@ -323,40 +323,40 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { } /// @inheritdoc ITaikoInbox - function getTransitionV3( - uint64 _blockId, + function getTransition( + uint64 _batchId, uint24 _tid ) external view - returns (TransitionV3 memory tran_) + returns (Transition memory tran_) { ConfigV3 memory config = getConfigV3(); - uint256 slot = _blockId % config.blockRingBufferSize; - BlockV3 storage blk = state.blocks[slot]; - require(blk.blockId == _blockId, BlockNotFound()); + uint256 slot = _batchId % config.blockRingBufferSize; + Batch storage blk = state.blocks[slot]; + require(blk.batchId == _batchId, BlockNotFound()); require(_tid != 0 && _tid < blk.nextTransitionId, TransitionNotFound()); return state.transitions[slot][_tid]; } /// @inheritdoc ITaikoInbox - function getLastVerifiedTransitionV3() + function getLastVerifiedTransition() external view - returns (uint64 blockId_, TransitionV3 memory tran_) + returns (uint64 batchId_, Transition memory tran_) { - blockId_ = state.stats2.lastVerifiedBlockId; - tran_ = getBlockVerifyingTransition(blockId_); + batchId_ = state.stats2.lastVerifiedBatch; + tran_ = getBatchVerifyingTransition(batchId_); } /// @inheritdoc ITaikoInbox - function getLastSyncedTransitionV3() + function getLastSyncedTransition() external view - returns (uint64 blockId_, TransitionV3 memory tran_) + returns (uint64 batchId_, Transition memory tran_) { - blockId_ = state.stats1.lastSyncedBlockId; - tran_ = getBlockVerifyingTransition(blockId_); + batchId_ = state.stats1.lastSyncedBatch; + tran_ = getBatchVerifyingTransition(batchId_); } /// @inheritdoc ITaikoInbox @@ -365,12 +365,12 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { } /// @inheritdoc ITaikoInbox - function getBlockV3(uint64 _blockId) external view returns (BlockV3 memory blk_) { + function getBatch(uint64 _batchId) external view returns (Batch memory blk_) { ConfigV3 memory config = getConfigV3(); - require(_blockId >= config.forkHeights.pacaya, InvalidForkHeight()); + require(_batchId >= config.forkHeights.pacaya, InvalidForkHeight()); - blk_ = state.blocks[_blockId % config.blockRingBufferSize]; - require(blk_.blockId == _blockId, BlockNotFound()); + blk_ = state.blocks[_batchId % config.blockRingBufferSize]; + require(blk_.batchId == _batchId, BlockNotFound()); } /// @notice Determines the operational layer of the contract, whether it is on Layer 1 (L1) or @@ -393,16 +393,16 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { } /// @inheritdoc ITaikoInbox - function getBlockVerifyingTransition(uint64 _blockId) + function getBatchVerifyingTransition(uint64 _batchId) public view - returns (TransitionV3 memory tran_) + returns (Transition memory tran_) { ConfigV3 memory config = getConfigV3(); - uint64 slot = _blockId % config.blockRingBufferSize; - BlockV3 storage blk = state.blocks[slot]; - require(blk.blockId == _blockId, BlockNotFound()); + uint64 slot = _batchId % config.blockRingBufferSize; + Batch storage blk = state.blocks[slot]; + require(blk.batchId == _batchId, BlockNotFound()); if (blk.verifiedTransitionId != 0) { tran_ = state.transitions[slot][blk.verifiedTransitionId]; @@ -426,7 +426,7 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { require(_genesisBlockHash != 0, InvalidGenesisBlockHash()); state.transitions[0][1].blockHash = _genesisBlockHash; - BlockV3 storage blk = state.blocks[0]; + Batch storage blk = state.blocks[0]; blk.metaHash = bytes32(uint256(1)); blk.timestamp = uint64(block.timestamp); blk.anchorBlockId = uint64(block.number); @@ -465,27 +465,27 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { ) private { - uint64 blockId = _stats2.lastVerifiedBlockId; - uint256 slot = blockId % _config.blockRingBufferSize; - BlockV3 storage blk = state.blocks[slot]; + uint64 batchId = _stats2.lastVerifiedBatch; + uint256 slot = batchId % _config.blockRingBufferSize; + Batch storage blk = state.blocks[slot]; uint24 tid = blk.verifiedTransitionId; bytes32 blockHash = state.transitions[slot][tid].blockHash; SyncBlock memory synced; - uint256 stopBlockId = (_config.maxBlocksToVerify * _length + _stats2.lastVerifiedBlockId) + uint256 stopBlockId = (_config.maxBlocksToVerify * _length + _stats2.lastVerifiedBatch) .min(_stats2.numBlocks); - for (++blockId; blockId < stopBlockId; ++blockId) { - slot = blockId % _config.blockRingBufferSize; + for (++batchId; batchId < stopBlockId; ++batchId) { + slot = batchId % _config.blockRingBufferSize; blk = state.blocks[slot]; // FIX - TransitionV3 storage ts = state.transitions[slot][1]; + Transition storage ts = state.transitions[slot][1]; if (ts.parentHash == blockHash) { tid = 1; } else { - uint24 _tid = state.transitionIds[blockId][blockHash]; + uint24 _tid = state.transitionIds[batchId][blockHash]; if (_tid == 0) break; tid = _tid; ts = state.transitions[slot][tid]; @@ -493,38 +493,38 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { blockHash = ts.blockHash; - if (blockId % _config.stateRootSyncInternal == 0) { - synced.blockId = blockId; + if (batchId % _config.stateRootSyncInternal == 0) { + synced.batchId = batchId; synced.tid = tid; synced.stateRoot = ts.stateRoot; } for (uint24 i = 2; i < blk.nextTransitionId; ++i) { ts = state.transitions[slot][i]; - delete state.transitionIds[blockId][ts.parentHash]; + delete state.transitionIds[batchId][ts.parentHash]; } } unchecked { - --blockId; + --batchId; } - if (_stats2.lastVerifiedBlockId != blockId) { - _stats2.lastVerifiedBlockId = blockId; + if (_stats2.lastVerifiedBatch != batchId) { + _stats2.lastVerifiedBatch = batchId; - blk = state.blocks[_stats2.lastVerifiedBlockId % _config.blockRingBufferSize]; + blk = state.blocks[_stats2.lastVerifiedBatch % _config.blockRingBufferSize]; blk.verifiedTransitionId = tid; - emit BlockVerifiedV3(_stats2.lastVerifiedBlockId, blockHash); + emit BlockVerifiedV3(_stats2.lastVerifiedBatch, blockHash); - if (synced.blockId != 0) { - if (synced.blockId != _stats2.lastVerifiedBlockId) { + if (synced.batchId != 0) { + if (synced.batchId != _stats2.lastVerifiedBatch) { // We write the synced block's verifiedTransitionId to storage - blk = state.blocks[synced.blockId % _config.blockRingBufferSize]; + blk = state.blocks[synced.batchId % _config.blockRingBufferSize]; blk.verifiedTransitionId = synced.tid; } Stats1 memory stats1 = state.stats1; - stats1.lastSyncedBlockId = synced.blockId; + stats1.lastSyncedBatch = synced.batchId; stats1.lastSyncedAt = uint64(block.timestamp); state.stats1 = stats1; @@ -532,7 +532,7 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { // Ask signal service to write cross chain signal ISignalService(resolve(LibStrings.B_SIGNAL_SERVICE, false)).syncChainData( - _config.chainId, LibStrings.H_STATE_ROOT, synced.blockId, synced.stateRoot + _config.chainId, LibStrings.H_STATE_ROOT, synced.batchId, synced.stateRoot ); } } @@ -576,7 +576,7 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { } function _validateBlockParams( - BlockParamsV3 calldata _params, + BatchParams calldata _params, uint64 _maxAnchorHeightOffset, uint8 _maxSignalsToReceive, BlockInfo memory _parent @@ -655,7 +655,7 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { } struct SyncBlock { - uint64 blockId; + uint64 batchId; uint24 tid; bytes32 stateRoot; } diff --git a/packages/protocol/contracts/layer1/preconf/iface/IPreconfTaskManager.sol b/packages/protocol/contracts/layer1/preconf/iface/IPreconfTaskManager.sol index 4b43d2f054d..6827ab9ff17 100644 --- a/packages/protocol/contracts/layer1/preconf/iface/IPreconfTaskManager.sol +++ b/packages/protocol/contracts/layer1/preconf/iface/IPreconfTaskManager.sol @@ -62,7 +62,7 @@ interface IPreconfTaskManager { /// @dev Accepts block proposal by an operator and forwards it to Taiko contract function proposeBlocksV3( address coinbase, - ITaikoInbox.BlockParamsV3[] calldata blockParams, + ITaikoInbox.BatchParams[] calldata batchParams, bytes calldata txList, uint256 lookaheadPointer, LookaheadSetParam[] calldata lookaheadSetParams diff --git a/packages/protocol/contracts/layer1/preconf/impl/PreconfTaskManager.sol b/packages/protocol/contracts/layer1/preconf/impl/PreconfTaskManager.sol index 1a84372d87c..dbd01b42d4a 100644 --- a/packages/protocol/contracts/layer1/preconf/impl/PreconfTaskManager.sol +++ b/packages/protocol/contracts/layer1/preconf/impl/PreconfTaskManager.sol @@ -78,7 +78,7 @@ contract PreconfTaskManager is IPreconfTaskManager, Initializable { * In this case, `forcePushLookahead` must be called in order to update the lookahead for the * next epoch. * @param coinbase The address of the coinbase for the proposed block - * @param blockParams A list of block parameters expected by Taiko contract + * @param batchParams A list of block parameters expected by Taiko contract * @param lookaheadPointer A pointer to the lookahead entry that may prove that the sender is * the preconfer * for the slot. @@ -87,7 +87,7 @@ contract PreconfTaskManager is IPreconfTaskManager, Initializable { */ function proposeBlocksV3( address coinbase, - ITaikoInbox.BlockParamsV3[] calldata blockParams, + ITaikoInbox.BatchParams[] calldata batchParams, bytes calldata txList, uint256 lookaheadPointer, LookaheadSetParam[] calldata lookaheadSetParams @@ -126,7 +126,7 @@ contract PreconfTaskManager is IPreconfTaskManager, Initializable { ); // Forward the block to Taiko's L1 contract - inbox.proposeBlocksV3(msg.sender, coinbase, blockParams, txList); + inbox.proposeBlocksV3(msg.sender, coinbase, batchParams, txList); } /** diff --git a/packages/protocol/contracts/layer1/provers/ProverSet.sol b/packages/protocol/contracts/layer1/provers/ProverSet.sol index 8880215e10e..53a180a3add 100644 --- a/packages/protocol/contracts/layer1/provers/ProverSet.sol +++ b/packages/protocol/contracts/layer1/provers/ProverSet.sol @@ -96,13 +96,13 @@ contract ProverSet is EssentialContract, IERC1271 { /// @notice Propose multiple Taiko blocks. function proposeBlocksV3( - ITaikoInbox.BlockParamsV3[] calldata _paramsArray, + ITaikoInbox.BatchParams[] calldata _paramsArray, bytes calldata _txList, bool _revertIfNotFirstProposal ) external onlyProver - returns (ITaikoInbox.BlockMetadataV3[] memory metas_) + returns (ITaikoInbox.BatchMetadata[] memory metas_) { ITaikoInbox taiko = ITaikoInbox(inbox()); if (_revertIfNotFirstProposal) { @@ -114,8 +114,8 @@ contract ProverSet is EssentialContract, IERC1271 { /// @notice Batch proves or contests Taiko blocks. function proveBlocksV3( - ITaikoInbox.BlockMetadataV3[] calldata _metas, - ITaikoInbox.TransitionV3[] calldata _transitions, + ITaikoInbox.BatchMetadata[] calldata _metas, + ITaikoInbox.Transition[] calldata _transitions, bytes calldata _proof ) external diff --git a/packages/protocol/contracts/layer1/verifiers/IVerifier.sol b/packages/protocol/contracts/layer1/verifiers/IVerifier.sol index 59e59a41c35..74554a7eb8c 100644 --- a/packages/protocol/contracts/layer1/verifiers/IVerifier.sol +++ b/packages/protocol/contracts/layer1/verifiers/IVerifier.sol @@ -8,10 +8,10 @@ import "../based/ITaikoInbox.sol"; /// @custom:security-contact security@taiko.xyz interface IVerifier { struct Context { - uint64 blockId; + uint64 batchId; bytes32 difficulty; bytes32 metaHash; - ITaikoInbox.TransitionV3 transition; + ITaikoInbox.Transition transition; } /// @notice Verifies multiple proofs. This function must throw if the proof cannot be verified. diff --git a/packages/protocol/contracts/layer1/verifiers/LibPublicInput.sol b/packages/protocol/contracts/layer1/verifiers/LibPublicInput.sol index e402e3b50d2..f222792fd4e 100644 --- a/packages/protocol/contracts/layer1/verifiers/LibPublicInput.sol +++ b/packages/protocol/contracts/layer1/verifiers/LibPublicInput.sol @@ -17,7 +17,7 @@ library LibPublicInput { /// @param _chainId The chain id. /// @return The public input hash. function hashPublicInputs( - ITaikoInbox.TransitionV3 memory _transition, + ITaikoInbox.Transition memory _transition, address _verifierContract, address _newInstance, bytes32 _metaHash, diff --git a/packages/protocol/contracts/shared/tokenvault/ERC20Vault.sol b/packages/protocol/contracts/shared/tokenvault/ERC20Vault.sol index 2a23c3e3748..990087df7ed 100644 --- a/packages/protocol/contracts/shared/tokenvault/ERC20Vault.sol +++ b/packages/protocol/contracts/shared/tokenvault/ERC20Vault.sol @@ -410,7 +410,7 @@ contract ERC20Vault is BaseVault { address taiko = resolve(LibStrings.B_TAIKO, false); require(ITaiko(taiko).isOnL1(), VAULT_NOT_ON_L1()); - bytes32 l2BlockMetaHash = ITaikoInbox(taiko).getBlockV3(_op.l2BlockId).metaHash; + bytes32 l2BlockMetaHash = ITaikoInbox(taiko).getBatch(_op.l2BlockId).metaHash; require(l2BlockMetaHash == _op.l2BlockMetaHash, VAULT_METAHASH_MISMATCH()); } diff --git a/packages/protocol/test/layer1/based/helpers/StubInbox.sol b/packages/protocol/test/layer1/based/helpers/StubInbox.sol index ed68625d91f..e2c323a5673 100644 --- a/packages/protocol/test/layer1/based/helpers/StubInbox.sol +++ b/packages/protocol/test/layer1/based/helpers/StubInbox.sol @@ -9,16 +9,16 @@ contract StubInbox is ITaikoInbox { function proposeBlocksV3( address _proposer, address _coinbase, - BlockParamsV3[] calldata _blockParams, + BatchParams[] calldata _blockParams, bytes calldata _txList ) external - returns (ITaikoInbox.BlockMetadataV3[] memory) + returns (ITaikoInbox.BatchMetadata[] memory) { } function proveBlocksV3( - ITaikoInbox.BlockMetadataV3[] calldata _metas, - ITaikoInbox.TransitionV3[] calldata _transitions, + ITaikoInbox.BatchMetadata[] calldata _metas, + ITaikoInbox.Transition[] calldata _transitions, bytes calldata proof ) external @@ -34,39 +34,39 @@ contract StubInbox is ITaikoInbox { return address(0); } - function getBlockV3(uint64 _blockId) + function getBatch(uint64 _batchId) external view virtual - returns (ITaikoInbox.BlockV3 memory blk_) + returns (ITaikoInbox.Batch memory ) { } - function getTransitionV3( - uint64 _blockId, + function getTransition( + uint64 _batchId, uint24 _tid ) external view virtual - returns (ITaikoInbox.TransitionV3 memory) + returns (ITaikoInbox.Transition memory) { } - function getLastVerifiedTransitionV3() + function getLastVerifiedTransition() external view - returns (uint64 blockId_, TransitionV3 memory tran_) + returns (uint64 batchId_, Transition memory ) { } - function getLastSyncedTransitionV3() + function getLastSyncedTransition() external view - returns (uint64 blockId_, TransitionV3 memory tran_) + returns (uint64 batchId_, Transition memory ) { } - function getBlockVerifyingTransition(uint64 _blockId) + function getBatchVerifyingTransition(uint64 _batchId) external view - returns (TransitionV3 memory) + returns (Transition memory) { } function getStats1() external view returns (Stats1 memory) { } diff --git a/packages/protocol/test/layer1/preconf/blocks/BlockProposing.t.sol b/packages/protocol/test/layer1/preconf/blocks/BlockProposing.t.sol index a69271b6891..86efd1d30b9 100644 --- a/packages/protocol/test/layer1/preconf/blocks/BlockProposing.t.sol +++ b/packages/protocol/test/layer1/preconf/blocks/BlockProposing.t.sol @@ -216,8 +216,8 @@ contract BlockProposing is BlocksFixtures { ) internal { - ITaikoInbox.BlockParamsV3 memory defaultParams; - ITaikoInbox.BlockParamsV3[] memory paramsArr = new ITaikoInbox.BlockParamsV3[](1); + ITaikoInbox.BatchParams memory defaultParams; + ITaikoInbox.BatchParams[] memory paramsArr = new ITaikoInbox.BatchParams[](1); paramsArr[0] = defaultParams; preconfTaskManager.proposeBlocksV3( diff --git a/packages/protocol/test/layer1/team/tokenunlock/TokenUnlock_ProverSet.t.sol b/packages/protocol/test/layer1/team/tokenunlock/TokenUnlock_ProverSet.t.sol index 47c625fd532..ca9f8259a65 100644 --- a/packages/protocol/test/layer1/team/tokenunlock/TokenUnlock_ProverSet.t.sol +++ b/packages/protocol/test/layer1/team/tokenunlock/TokenUnlock_ProverSet.t.sol @@ -1,5 +1,5 @@ -// // SPDX-License-Identifier: MIT -// pragma solidity ^0.8.24; +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.24; // import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Votes.sol"; // import "src/layer1/team/TokenUnlock.sol"; diff --git a/packages/protocol/test/layer1/verifiers/SP1Verifier.t.sol b/packages/protocol/test/layer1/verifiers/SP1Verifier.t.sol index 25323fb743a..543ba84e888 100644 --- a/packages/protocol/test/layer1/verifiers/SP1Verifier.t.sol +++ b/packages/protocol/test/layer1/verifiers/SP1Verifier.t.sol @@ -73,20 +73,20 @@ contract TestSP1Verifier is Layer1Test { // Context IVerifier.Context[] memory ctxs = new IVerifier.Context[](2); ctxs[0] = IVerifier.Context({ - blockId: 393_333, + batchId: 393_333, difficulty: 0, // TODO, need a non-zero value. metaHash: 0x207b2833fb6d804612da24d8785b870a19c7a3f25fa4aaeb9799cd442d65b031, - transition: ITaikoInbox.TransitionV3({ + transition: ITaikoInbox.Transition({ parentHash: 0xce519622a374dc014c005d7857de26d952751a9067d3e23ffe14da247aa8a399, blockHash: 0x941d557653da2214cbf3d30af8d9cadbc7b5f77b6c3e48bca548eba04eb9cd79, stateRoot: 0x4203a2fd98d268d272acb24d91e25055a779b443ff3e732f2cee7abcf639b5e9 }) }); ctxs[1] = IVerifier.Context({ - blockId: 393_334, + batchId: 393_334, difficulty: 0, // TODO, need a non-zero value. metaHash: 0x946ba1a9c02fc2f01da49e31cb5be83c118193d0389987c6be616ce76426b44d, - transition: ITaikoInbox.TransitionV3({ + transition: ITaikoInbox.Transition({ parentHash: 0x941d557653da2214cbf3d30af8d9cadbc7b5f77b6c3e48bca548eba04eb9cd79, blockHash: 0xc0dad38646ab264be30995b7b7fd02db65e7115126fb52bfad94c0fc9572287c, stateRoot: 0x222061caab95b6bd0f8dd398088030979efbe56e282cd566f7abd77838558eb9 @@ -102,10 +102,10 @@ contract TestSP1Verifier is Layer1Test { function _generateTaikoMainnetContext() internal pure returns (IVerifier.Context memory) { return IVerifier.Context({ - blockId: 223_248, //from mainnet + batchId: 223_248, //from mainnet difficulty: 0, metaHash: bytes32(0xd7efb262f6f25cc817452a622009a22e5868e53e1f934d899d3ec68d8c4f2c5b), - transition: ITaikoInbox.TransitionV3({ + transition: ITaikoInbox.Transition({ parentHash: 0x317de24b32f09629524133334ad552a14e3de603d71a9cf9e88d722809f101b3, blockHash: 0x9966d3cf051d3d1e44e2a740169627506a619257c95374e812ca572de91ed885, stateRoot: 0x3ae3de1afa16b93a5c7ea20a0b36b43357061f5b8ef857053d68b2735c3df860 From d63a3c7a98243c0bf22a7bd8c39f97f92fa7b7d8 Mon Sep 17 00:00:00 2001 From: Daniel Wang Date: Fri, 10 Jan 2025 11:32:25 +0800 Subject: [PATCH 05/41] rename 2 --- .../contracts/layer1/based/ITaikoInbox.sol | 19 +++++----- .../contracts/layer1/based/TaikoInbox.sol | 38 ++++++++----------- .../contracts/layer1/devnet/DevnetInbox.sol | 4 +- .../contracts/layer1/hekla/HeklaInbox.sol | 4 +- .../contracts/layer1/mainnet/MainnetInbox.sol | 4 +- .../preconf/iface/IPreconfTaskManager.sol | 2 +- .../preconf/impl/PreconfTaskManager.sol | 4 +- .../contracts/layer1/provers/ProverSet.sol | 8 ++-- .../layer1/based/DeployProtocolOnL1.s.sol | 2 +- packages/protocol/test/layer1/Layer1Test.sol | 8 ++-- .../test/layer1/based/helpers/StubInbox.sol | 21 +++------- .../preconf/blocks/BlockProposing.t.sol | 2 +- .../tokenunlock/TokenUnlock_ProverSet.t.sol | 12 +++--- .../test/layer1/verifiers/SP1Verifier.t.sol | 2 +- 14 files changed, 57 insertions(+), 73 deletions(-) diff --git a/packages/protocol/contracts/layer1/based/ITaikoInbox.sol b/packages/protocol/contracts/layer1/based/ITaikoInbox.sol index 6bbc5374356..d67f391ccf4 100644 --- a/packages/protocol/contracts/layer1/based/ITaikoInbox.sol +++ b/packages/protocol/contracts/layer1/based/ITaikoInbox.sol @@ -105,7 +105,7 @@ interface ITaikoInbox { } /// @notice Struct holding Taiko configuration parameters. See {TaikoConfig}. - struct ConfigV3 { + struct Config { /// @notice The chain ID of the network where Taiko contracts are deployed. uint64 chainId; /// @notice The maximum number of verifications allowed when a block is proposed or proved. @@ -140,8 +140,7 @@ interface ITaikoInbox { mapping(uint256 batchId => mapping(bytes32 parentHash => uint24 transitionId)) transitionIds; // Ring buffer for transitions mapping( - uint256 batchId_mod_blockRingBufferSize - => mapping(uint24 transitionId => Transition ts) + uint256 batchId_mod_blockRingBufferSize => mapping(uint24 transitionId => Transition ts) ) transitions; bytes32 __reserve1; // Used as a ring buffer for Ether deposits Stats1 stats1; // slot 5 @@ -182,22 +181,22 @@ interface ITaikoInbox { /// @param metas The metadata of the proposed blocks. /// @param calldataUsed Whether calldata is used for txList DA. /// @param txListInCalldata The tx list in calldata. - event BlocksProposedV3(BatchMetadata[] metas, bool calldataUsed, bytes txListInCalldata); + event BatchesProposed(BatchMetadata[] metas, bool calldataUsed, bytes txListInCalldata); /// @notice Emitted when multiple transitions are proved. /// @param verifier The address of the verifier. /// @param transitions The transitions data. - event BlocksProvedV3(address verifier, uint64[] batchIds, Transition[] transitions); + event BatchesProved(address verifier, uint64[] batchIds, Transition[] transitions); /// @notice Emitted when a transition is overwritten by another one. /// @param batchId The block ID. /// @param tran The transition data that has been overwritten. - event TransitionOverwrittenV3(uint64 batchId, Transition tran); + event TransitionOverwritten(uint64 batchId, Transition tran); /// @notice Emitted when a block is verified. /// @param batchId The ID of the verified block. /// @param blockHash The hash of the verified block. - event BlockVerifiedV3(uint64 batchId, bytes32 blockHash); + event BatchesVerified(uint64 batchId, bytes32 blockHash); error AnchorBlockIdSmallerThanParent(); error AnchorBlockIdTooSmall(); @@ -242,7 +241,7 @@ interface ITaikoInbox { /// @param _txList The transaction list in calldata. If the txList is empty, blob will be used /// for data availability. /// @return An array of block metadata for each block proposed. - function proposeBlocksV3( + function proposeBatches( address _proposer, address _coinbase, BatchParams[] calldata _blockParams, @@ -255,7 +254,7 @@ interface ITaikoInbox { /// @param _metas Array of metadata for each block being proved. /// @param _transitions Array of block transitions to be proved. /// @param proof The aggregated cryptographic proof proving the blocks transitions. - function proveBlocksV3( + function proveBatches( BatchMetadata[] calldata _metas, Transition[] calldata _transitions, bytes calldata proof @@ -332,5 +331,5 @@ interface ITaikoInbox { /// @notice Retrieves the current protocol configuration. /// @return The current configuration. - function getConfigV3() external view returns (ConfigV3 memory); + function getConfig() external view returns (Config memory); } diff --git a/packages/protocol/contracts/layer1/based/TaikoInbox.sol b/packages/protocol/contracts/layer1/based/TaikoInbox.sol index 918d35416b4..ec2dab56415 100644 --- a/packages/protocol/contracts/layer1/based/TaikoInbox.sol +++ b/packages/protocol/contracts/layer1/based/TaikoInbox.sol @@ -51,7 +51,7 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { /// @param _paramsArray An array containing the parameters for each block being proposed. /// @param _txList The transaction list in calldata. /// @return metas_ Array of block metadata for each block proposed. - function proposeBlocksV3( + function proposeBatches( address _proposer, address _coinbase, BatchParams[] calldata _paramsArray, @@ -66,7 +66,7 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { Stats2 memory stats2 = state.stats2; require(!stats2.paused, ContractPaused()); - ConfigV3 memory config = getConfigV3(); + Config memory config = getConfig(); require(stats2.numBlocks >= config.forkHeights.pacaya, InvalidForkHeight()); unchecked { @@ -174,7 +174,7 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { } // end of for-loop _debitBond(_proposer, config.livenessBond * _paramsArray.length); - emit BlocksProposedV3(metas_, calldataUsed, _txList); + emit BatchesProposed(metas_, calldataUsed, _txList); _verifyBlocks(config, stats2, _paramsArray.length); } @@ -183,7 +183,7 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { /// @param _metas Array of block metadata to be proven. /// @param _transitions Array of transitions corresponding to the block metadata. /// @param _proof Cryptographic proof validating all the transitions. - function proveBlocksV3( + function proveBatches( BatchMetadata[] calldata _metas, Transition[] calldata _transitions, bytes calldata _proof @@ -197,7 +197,7 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { Stats2 memory stats2 = state.stats2; require(stats2.paused == false, ContractPaused()); - ConfigV3 memory config = getConfigV3(); + Config memory config = getConfig(); uint64[] memory batchIds = new uint64[](_metas.length); IVerifier.Context[] memory ctxs = new IVerifier.Context[](_metas.length); @@ -249,7 +249,7 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { Transition storage ts = state.transitions[slot][tid]; if (isOverwrite) { - emit TransitionOverwrittenV3(meta.batchId, ts); + emit TransitionOverwritten(meta.batchId, ts); } else if (tid == 1) { // Ensure that only the block proposer can prove the first transition before the // proving deadline. @@ -284,7 +284,7 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { address verifier = resolve(LibStrings.B_PROOF_VERIFIER, false); IVerifier(verifier).verifyProof(ctxs, _proof); - emit BlocksProvedV3(verifier, batchIds, _transitions); + emit BatchesProved(verifier, batchIds, _transitions); _verifyBlocks(config, stats2, _metas.length); } @@ -331,7 +331,7 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { view returns (Transition memory tran_) { - ConfigV3 memory config = getConfigV3(); + Config memory config = getConfig(); uint256 slot = _batchId % config.blockRingBufferSize; Batch storage blk = state.blocks[slot]; require(blk.batchId == _batchId, BlockNotFound()); @@ -366,7 +366,7 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { /// @inheritdoc ITaikoInbox function getBatch(uint64 _batchId) external view returns (Batch memory blk_) { - ConfigV3 memory config = getConfigV3(); + Config memory config = getConfig(); require(_batchId >= config.forkHeights.pacaya, InvalidForkHeight()); blk_ = state.blocks[_batchId % config.blockRingBufferSize]; @@ -398,7 +398,7 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { view returns (Transition memory tran_) { - ConfigV3 memory config = getConfigV3(); + Config memory config = getConfig(); uint64 slot = _batchId % config.blockRingBufferSize; Batch storage blk = state.blocks[slot]; @@ -410,7 +410,7 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { } /// @inheritdoc ITaikoInbox - function getConfigV3() public view virtual returns (ConfigV3 memory); + function getConfig() public view virtual returns (Config memory); // Internal functions ---------------------------------------------------------------------- @@ -435,7 +435,7 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { state.stats2.lastProposedIn = uint56(block.number); state.stats2.numBlocks = 1; - emit BlockVerifiedV3(0, _genesisBlockHash); + emit BatchesVerified(0, _genesisBlockHash); } function _unpause() internal override { @@ -458,13 +458,7 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { // Private functions ----------------------------------------------------------------------- - function _verifyBlocks( - ConfigV3 memory _config, - Stats2 memory _stats2, - uint256 _length - ) - private - { + function _verifyBlocks(Config memory _config, Stats2 memory _stats2, uint256 _length) private { uint64 batchId = _stats2.lastVerifiedBatch; uint256 slot = batchId % _config.blockRingBufferSize; Batch storage blk = state.blocks[slot]; @@ -473,8 +467,8 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { SyncBlock memory synced; - uint256 stopBlockId = (_config.maxBlocksToVerify * _length + _stats2.lastVerifiedBatch) - .min(_stats2.numBlocks); + uint256 stopBlockId = + (_config.maxBlocksToVerify * _length + _stats2.lastVerifiedBatch).min(_stats2.numBlocks); for (++batchId; batchId < stopBlockId; ++batchId) { slot = batchId % _config.blockRingBufferSize; @@ -514,7 +508,7 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { blk = state.blocks[_stats2.lastVerifiedBatch % _config.blockRingBufferSize]; blk.verifiedTransitionId = tid; - emit BlockVerifiedV3(_stats2.lastVerifiedBatch, blockHash); + emit BatchesVerified(_stats2.lastVerifiedBatch, blockHash); if (synced.batchId != 0) { if (synced.batchId != _stats2.lastVerifiedBatch) { diff --git a/packages/protocol/contracts/layer1/devnet/DevnetInbox.sol b/packages/protocol/contracts/layer1/devnet/DevnetInbox.sol index 4fcb5cc2152..5aaea3f178a 100644 --- a/packages/protocol/contracts/layer1/devnet/DevnetInbox.sol +++ b/packages/protocol/contracts/layer1/devnet/DevnetInbox.sol @@ -8,8 +8,8 @@ import "../based/TaikoInbox.sol"; /// @custom:security-contact security@taiko.xyz contract DevnetInbox is TaikoInbox { /// @inheritdoc ITaikoInbox - function getConfigV3() public pure override returns (ITaikoInbox.ConfigV3 memory) { - return ITaikoInbox.ConfigV3({ + function getConfig() public pure override returns (ITaikoInbox.Config memory) { + return ITaikoInbox.Config({ chainId: 167_001, blockMaxProposals: 324_000, blockRingBufferSize: 360_000, diff --git a/packages/protocol/contracts/layer1/hekla/HeklaInbox.sol b/packages/protocol/contracts/layer1/hekla/HeklaInbox.sol index 0d21e869a75..0b43f18d8d0 100644 --- a/packages/protocol/contracts/layer1/hekla/HeklaInbox.sol +++ b/packages/protocol/contracts/layer1/hekla/HeklaInbox.sol @@ -7,8 +7,8 @@ import "../based/TaikoInbox.sol"; /// @dev Labeled in address resolver as "taiko" /// @custom:security-contact security@taiko.xyz contract HeklaInbox is TaikoInbox { - function getConfigV3() public pure override returns (ITaikoInbox.ConfigV3 memory) { - return ITaikoInbox.ConfigV3({ + function getConfig() public pure override returns (ITaikoInbox.Config memory) { + return ITaikoInbox.Config({ chainId: LibNetwork.TAIKO_HEKLA, // Never change this value as ring buffer is being reused!!! blockMaxProposals: 324_000, diff --git a/packages/protocol/contracts/layer1/mainnet/MainnetInbox.sol b/packages/protocol/contracts/layer1/mainnet/MainnetInbox.sol index f7612e7b179..809f0ccc215 100644 --- a/packages/protocol/contracts/layer1/mainnet/MainnetInbox.sol +++ b/packages/protocol/contracts/layer1/mainnet/MainnetInbox.sol @@ -11,12 +11,12 @@ import "./libs/LibFasterReentryLock.sol"; /// @notice See the documentation in {TaikoL1}. /// @custom:security-contact security@taiko.xyz contract MainnetInbox is TaikoInbox { - function getConfigV3() public pure override returns (ITaikoInbox.ConfigV3 memory) { + function getConfig() public pure override returns (ITaikoInbox.Config memory) { // All hard-coded configurations: // - treasury: the actual TaikoL2 address. // - anchorGasLimit: 250_000 (based on internal devnet, its ~220_000 // after 256 L2 blocks) - return ITaikoInbox.ConfigV3({ + return ITaikoInbox.Config({ chainId: LibNetwork.TAIKO_MAINNET, // Ring buffers are being reused on the mainnet, therefore the following two // configuration values must NEVER be changed!!! diff --git a/packages/protocol/contracts/layer1/preconf/iface/IPreconfTaskManager.sol b/packages/protocol/contracts/layer1/preconf/iface/IPreconfTaskManager.sol index 6827ab9ff17..c0872aaacd5 100644 --- a/packages/protocol/contracts/layer1/preconf/iface/IPreconfTaskManager.sol +++ b/packages/protocol/contracts/layer1/preconf/iface/IPreconfTaskManager.sol @@ -60,7 +60,7 @@ interface IPreconfTaskManager { error NoRegisteredPreconfer(); /// @dev Accepts block proposal by an operator and forwards it to Taiko contract - function proposeBlocksV3( + function proposeBatches( address coinbase, ITaikoInbox.BatchParams[] calldata batchParams, bytes calldata txList, diff --git a/packages/protocol/contracts/layer1/preconf/impl/PreconfTaskManager.sol b/packages/protocol/contracts/layer1/preconf/impl/PreconfTaskManager.sol index dbd01b42d4a..19299009748 100644 --- a/packages/protocol/contracts/layer1/preconf/impl/PreconfTaskManager.sol +++ b/packages/protocol/contracts/layer1/preconf/impl/PreconfTaskManager.sol @@ -85,7 +85,7 @@ contract PreconfTaskManager is IPreconfTaskManager, Initializable { * @param lookaheadSetParams Collection of timestamps and preconfer addresses to be inserted in * the lookahead */ - function proposeBlocksV3( + function proposeBatches( address coinbase, ITaikoInbox.BatchParams[] calldata batchParams, bytes calldata txList, @@ -126,7 +126,7 @@ contract PreconfTaskManager is IPreconfTaskManager, Initializable { ); // Forward the block to Taiko's L1 contract - inbox.proposeBlocksV3(msg.sender, coinbase, batchParams, txList); + inbox.proposeBatches(msg.sender, coinbase, batchParams, txList); } /** diff --git a/packages/protocol/contracts/layer1/provers/ProverSet.sol b/packages/protocol/contracts/layer1/provers/ProverSet.sol index 53a180a3add..75194da4438 100644 --- a/packages/protocol/contracts/layer1/provers/ProverSet.sol +++ b/packages/protocol/contracts/layer1/provers/ProverSet.sol @@ -95,7 +95,7 @@ contract ProverSet is EssentialContract, IERC1271 { } /// @notice Propose multiple Taiko blocks. - function proposeBlocksV3( + function proposeBatches( ITaikoInbox.BatchParams[] calldata _paramsArray, bytes calldata _txList, bool _revertIfNotFirstProposal @@ -109,11 +109,11 @@ contract ProverSet is EssentialContract, IERC1271 { // Ensure this block is the first block proposed in the current L1 block. require(taiko.getStats2().lastProposedIn != block.number, NOT_FIRST_PROPOSAL()); } - return taiko.proposeBlocksV3(address(0), address(0), _paramsArray, _txList); + return taiko.proposeBatches(address(0), address(0), _paramsArray, _txList); } /// @notice Batch proves or contests Taiko blocks. - function proveBlocksV3( + function proveBatches( ITaikoInbox.BatchMetadata[] calldata _metas, ITaikoInbox.Transition[] calldata _transitions, bytes calldata _proof @@ -121,7 +121,7 @@ contract ProverSet is EssentialContract, IERC1271 { external onlyProver { - ITaikoInbox(inbox()).proveBlocksV3(_metas, _transitions, _proof); + ITaikoInbox(inbox()).proveBatches(_metas, _transitions, _proof); } /// @notice Deposits Taiko token to Taiko contract. diff --git a/packages/protocol/script/layer1/based/DeployProtocolOnL1.s.sol b/packages/protocol/script/layer1/based/DeployProtocolOnL1.s.sol index f0b59c6ba2a..ba290d5f0bd 100644 --- a/packages/protocol/script/layer1/based/DeployProtocolOnL1.s.sol +++ b/packages/protocol/script/layer1/based/DeployProtocolOnL1.s.sol @@ -65,7 +65,7 @@ contract DeployProtocolOnL1 is DeployCapability { SignalService(signalServiceAddr).authorize(taikoInboxAddr, true); } - uint64 l2ChainId = taikoInbox.getConfigV3().chainId; + uint64 l2ChainId = taikoInbox.getConfig().chainId; require(l2ChainId != block.chainid, "same chainid"); console2.log("------------------------------------------"); diff --git a/packages/protocol/test/layer1/Layer1Test.sol b/packages/protocol/test/layer1/Layer1Test.sol index 61bd331cdf3..9323bd64a4a 100644 --- a/packages/protocol/test/layer1/Layer1Test.sol +++ b/packages/protocol/test/layer1/Layer1Test.sol @@ -12,13 +12,13 @@ import "src/shared/bridge/Bridge.sol"; import "test/shared/CommonTest.sol"; contract ConfigurableInbox is TaikoInbox { - ITaikoInbox.ConfigV3 private __config; + ITaikoInbox.Config private __config; function initWithConfig( address _owner, address _rollupResolver, bytes32 _genesisBlockHash, - ITaikoInbox.ConfigV3 memory _config + ITaikoInbox.Config memory _config ) external initializer @@ -27,7 +27,7 @@ contract ConfigurableInbox is TaikoInbox { __config = _config; } - function getConfigV3() public view override returns (ITaikoInbox.ConfigV3 memory) { + function getConfig() public view override returns (ITaikoInbox.Config memory) { return __config; } @@ -39,7 +39,7 @@ contract ConfigurableInbox is TaikoInbox { abstract contract Layer1Test is CommonTest { function deployInbox( bytes32 _genesisBlockHash, - ITaikoInbox.ConfigV3 memory _config + ITaikoInbox.Config memory _config ) internal returns (TaikoInbox) diff --git a/packages/protocol/test/layer1/based/helpers/StubInbox.sol b/packages/protocol/test/layer1/based/helpers/StubInbox.sol index e2c323a5673..626d65c5739 100644 --- a/packages/protocol/test/layer1/based/helpers/StubInbox.sol +++ b/packages/protocol/test/layer1/based/helpers/StubInbox.sol @@ -6,7 +6,7 @@ import "src/layer1/based/ITaikoInbox.sol"; /// @title StubInbox /// @custom:security-contact security@taiko.xyz contract StubInbox is ITaikoInbox { - function proposeBlocksV3( + function proposeBatches( address _proposer, address _coinbase, BatchParams[] calldata _blockParams, @@ -16,7 +16,7 @@ contract StubInbox is ITaikoInbox { returns (ITaikoInbox.BatchMetadata[] memory) { } - function proveBlocksV3( + function proveBatches( ITaikoInbox.BatchMetadata[] calldata _metas, ITaikoInbox.Transition[] calldata _transitions, bytes calldata proof @@ -34,12 +34,7 @@ contract StubInbox is ITaikoInbox { return address(0); } - function getBatch(uint64 _batchId) - external - view - virtual - returns (ITaikoInbox.Batch memory ) - { } + function getBatch(uint64 _batchId) external view virtual returns (ITaikoInbox.Batch memory) { } function getTransition( uint64 _batchId, @@ -54,14 +49,10 @@ contract StubInbox is ITaikoInbox { function getLastVerifiedTransition() external view - returns (uint64 batchId_, Transition memory ) + returns (uint64 batchId_, Transition memory) { } - function getLastSyncedTransition() - external - view - returns (uint64 batchId_, Transition memory ) - { } + function getLastSyncedTransition() external view returns (uint64 batchId_, Transition memory) { } function getBatchVerifyingTransition(uint64 _batchId) external @@ -73,5 +64,5 @@ contract StubInbox is ITaikoInbox { function getStats2() external view returns (Stats2 memory) { } - function getConfigV3() external pure virtual returns (ITaikoInbox.ConfigV3 memory) { } + function getConfig() external pure virtual returns (ITaikoInbox.Config memory) { } } diff --git a/packages/protocol/test/layer1/preconf/blocks/BlockProposing.t.sol b/packages/protocol/test/layer1/preconf/blocks/BlockProposing.t.sol index 86efd1d30b9..fc360dfa98d 100644 --- a/packages/protocol/test/layer1/preconf/blocks/BlockProposing.t.sol +++ b/packages/protocol/test/layer1/preconf/blocks/BlockProposing.t.sol @@ -220,7 +220,7 @@ contract BlockProposing is BlocksFixtures { ITaikoInbox.BatchParams[] memory paramsArr = new ITaikoInbox.BatchParams[](1); paramsArr[0] = defaultParams; - preconfTaskManager.proposeBlocksV3( + preconfTaskManager.proposeBatches( msg.sender, paramsArr, "", lookaheadPointer, lookaheadSetParams ); } diff --git a/packages/protocol/test/layer1/team/tokenunlock/TokenUnlock_ProverSet.t.sol b/packages/protocol/test/layer1/team/tokenunlock/TokenUnlock_ProverSet.t.sol index ca9f8259a65..88d154b5f5a 100644 --- a/packages/protocol/test/layer1/team/tokenunlock/TokenUnlock_ProverSet.t.sol +++ b/packages/protocol/test/layer1/team/tokenunlock/TokenUnlock_ProverSet.t.sol @@ -14,8 +14,8 @@ pragma solidity ^0.8.24; // TokenUnlock private target; // TaikoToken private taikoToken; -// function getConfig() internal pure override returns (ITaikoInbox.ConfigV3 memory) { -// return ITaikoInbox.ConfigV3({ +// function getConfig() internal pure override returns (ITaikoInbox.Config memory) { +// return ITaikoInbox.Config({ // chainId: LibNetwork.TAIKO_MAINNET, // blockMaxProposals: 10, // blockRingBufferSize: 15, @@ -152,11 +152,11 @@ pragma solidity ^0.8.24; // vm.prank(Alice); // vm.expectRevert(TokenUnlock.PERMISSION_DENIED.selector); // ITaikoInbox.BlockParamsV3[] memory paramsArray = new ITaikoInbox.BlockParamsV3[](1); -// set.proposeBlocksV3(paramsArray, "txList", false); +// set.proposeBatches(paramsArray, "txList", false); // vm.prank(Carol); // ITaikoInbox.BlockMetadataV3[] memory metas = -// set.proposeBlocksV3(paramsArray, "txList", false); +// set.proposeBatches(paramsArray, "txList", false); // vm.startPrank(Bob); // vm.expectRevert(); @@ -174,10 +174,10 @@ pragma solidity ^0.8.24; // vm.prank(Alice); // vm.expectRevert(TokenUnlock.PERMISSION_DENIED.selector); -// set.proveBlocksV3(metas, transitions, "proof"); +// set.proveBatches(metas, transitions, "proof"); // vm.prank(Carol); -// set.proveBlocksV3(metas, transitions, "proof"); +// set.proveBatches(metas, transitions, "proof"); // vm.startPrank(Bob); // set.withdrawBond(livenessBond); diff --git a/packages/protocol/test/layer1/verifiers/SP1Verifier.t.sol b/packages/protocol/test/layer1/verifiers/SP1Verifier.t.sol index 543ba84e888..4d8cc0eae50 100644 --- a/packages/protocol/test/layer1/verifiers/SP1Verifier.t.sol +++ b/packages/protocol/test/layer1/verifiers/SP1Verifier.t.sol @@ -5,7 +5,7 @@ import { SP1Verifier as SP1RemoteVerifier } from "@sp1-contracts/src/v3.0.0/SP1V import "../Layer1Test.sol"; contract TaikoStub_ReturnMainnetChainId { - function getConfigV3() external pure returns (ITaikoInbox.ConfigV3 memory config) { + function getConfig() external pure returns (ITaikoInbox.Config memory config) { config.chainId = 167_000; } } From f393e0ad0e7a5213d7a952536002c085b6d1982d Mon Sep 17 00:00:00 2001 From: Daniel Wang Date: Fri, 10 Jan 2025 11:44:17 +0800 Subject: [PATCH 06/41] rename 4 --- .../contracts/layer1/based/ITaikoInbox.sol | 94 ++++++++------- .../contracts/layer1/based/TaikoInbox.sol | 109 +++++++++--------- .../contracts/layer1/devnet/DevnetInbox.sol | 6 +- .../contracts/layer1/hekla/HeklaInbox.sol | 6 +- .../contracts/layer1/mainnet/MainnetInbox.sol | 6 +- .../tokenunlock/TokenUnlock_ProverSet.t.sol | 6 +- 6 files changed, 113 insertions(+), 114 deletions(-) diff --git a/packages/protocol/contracts/layer1/based/ITaikoInbox.sol b/packages/protocol/contracts/layer1/based/ITaikoInbox.sol index d67f391ccf4..8700bc6119b 100644 --- a/packages/protocol/contracts/layer1/based/ITaikoInbox.sol +++ b/packages/protocol/contracts/layer1/based/ITaikoInbox.sol @@ -17,7 +17,7 @@ import "src/shared/based/LibSharedData.sol"; /// @dev Registered in the address resolver as "taiko". /// @custom:security-contact security@taiko.xyz interface ITaikoInbox { - struct SubBatch { + struct BlockParams { uint16 numTransactions; uint8 timeThift; } @@ -31,7 +31,7 @@ interface ITaikoInbox { uint32 txListSize; uint8[] blobIndices; bytes32[] signalSlots; - SubBatch[] subBlocks; + BlockParams[] blocks; } struct BatchMetadata { @@ -45,15 +45,15 @@ interface ITaikoInbox { bytes32 parentMetaHash; address proposer; uint96 livenessBond; - uint64 proposedAt; // Used by node/client post block proposal. - uint64 proposedIn; // Used by node/client post block proposal. + uint64 proposedAt; // Used by node/client + uint64 proposedIn; // Used by node/client uint32 txListOffset; uint32 txListSize; uint8[] blobIndices; uint64 anchorBlockId; bytes32 anchorBlockHash; bytes32[] signalSlots; - SubBatch[] subBlocks; + BlockParams[] blocks; bytes32 anchorInput; LibSharedData.BaseFeeConfig baseFeeConfig; } @@ -75,15 +75,13 @@ interface ITaikoInbox { uint64 anchorBlockId; uint24 nextTransitionId; uint8 numSubBlocks; - // The ID of the transaction that is used to verify this block. However, if this block is - // not verified as the last block in a batch, verifiedTransitionId will remain zero. + // The ID of the transaction that is used to verify this batch. However, if this batch is + // not verified as the last one in a transaction, verifiedTransitionId will remain zero. uint24 verifiedTransitionId; } /// @notice Forge is only able to run coverage in case the contracts by default capable of /// compiling without any optimization (neither optimizer runs, no compiling --via-ir flag). - /// @notice In order to resolve stack too deep without optimizations, we needed to introduce - /// outsourcing vars into structs below. struct Stats1 { uint64 __reserved1; uint64 __reserved2; @@ -108,17 +106,17 @@ interface ITaikoInbox { struct Config { /// @notice The chain ID of the network where Taiko contracts are deployed. uint64 chainId; - /// @notice The maximum number of verifications allowed when a block is proposed or proved. - uint64 blockMaxProposals; - /// @notice Size of the block ring buffer, allowing extra space for proposals. - uint64 blockRingBufferSize; - /// @notice The maximum number of verifications allowed when a block is proposed or proved. - uint64 maxBlocksToVerify; + /// @notice The maximum number of verifications allowed when a batch is proposed or proved. + uint64 maxBatchProposals; + /// @notice Size of the batch ring buffer, allowing extra space for proposals. + uint64 batchRingBufferSize; + /// @notice The maximum number of verifications allowed when a batch is proposed or proved. + uint64 maxBatchesTooVerify; /// @notice The maximum gas limit allowed for a block. uint32 blockMaxGasLimit; /// @notice The amount of Taiko token as a prover liveness bond. uint96 livenessBond; - /// @notice The number of L2 blocks between each L2-to-L1 state root sync. + /// @notice The number of batches between two L2-to-L1 state root sync. uint8 stateRootSyncInternal; /// @notice The max differences of the anchor height and the current block number. uint64 maxAnchorHeightOffset; @@ -134,13 +132,13 @@ interface ITaikoInbox { /// @notice Struct holding the state variables for the {Taiko} contract. struct State { - // Ring buffer for proposed blocks and a some recent verified blocks. - mapping(uint256 batchId_mod_blockRingBufferSize => Batch blk) blocks; + // Ring buffer for proposed batches and a some recent verified batches. + mapping(uint256 batchId_mod_batchRingBufferSize => Batch batch) batches; // Indexing to transition ids (ring buffer not possible) mapping(uint256 batchId => mapping(bytes32 parentHash => uint24 transitionId)) transitionIds; // Ring buffer for transitions mapping( - uint256 batchId_mod_blockRingBufferSize => mapping(uint24 transitionId => Transition ts) + uint256 batchId_mod_batchRingBufferSize => mapping(uint24 transitionId => Transition ts) ) transitions; bytes32 __reserve1; // Used as a ring buffer for Ether deposits Stats1 stats1; // slot 5 @@ -169,7 +167,7 @@ interface ITaikoInbox { /// @param amount The amount of tokens debited. event BondDebited(address indexed user, uint256 amount); - /// @notice Emitted when a block is synced. + /// @notice Emitted when a batch is synced. /// @param stats1 The Stats1 data structure. event Stats1Updated(Stats1 stats1); @@ -177,8 +175,8 @@ interface ITaikoInbox { /// @param stats2 The Stats2 data structure. event Stats2Updated(Stats2 stats2); - /// @notice Emitted when multiple blocks are proposed. - /// @param metas The metadata of the proposed blocks. + /// @notice Emitted when multiple batches are proposed. + /// @param metas The metadata of the proposed batches. /// @param calldataUsed Whether calldata is used for txList DA. /// @param txListInCalldata The tx list in calldata. event BatchesProposed(BatchMetadata[] metas, bool calldataUsed, bytes txListInCalldata); @@ -189,23 +187,23 @@ interface ITaikoInbox { event BatchesProved(address verifier, uint64[] batchIds, Transition[] transitions); /// @notice Emitted when a transition is overwritten by another one. - /// @param batchId The block ID. + /// @param batchId The batch ID. /// @param tran The transition data that has been overwritten. event TransitionOverwritten(uint64 batchId, Transition tran); - /// @notice Emitted when a block is verified. - /// @param batchId The ID of the verified block. - /// @param blockHash The hash of the verified block. + /// @notice Emitted when a batch is verified. + /// @param batchId The ID of the verified batch. + /// @param blockHash The hash of the verified batch. event BatchesVerified(uint64 batchId, bytes32 blockHash); error AnchorBlockIdSmallerThanParent(); error AnchorBlockIdTooSmall(); error AnchorBlockIdTooLarge(); error ArraySizesMismatch(); + error BatchNotFound(); + error BatchVerified(); error BlobIndexZero(); error BlobNotFound(); - error BlockNotFound(); - error BlockVerified(); error ContractPaused(); error CustomProposerMissing(); error CustomProposerNotAllowed(); @@ -219,7 +217,7 @@ interface ITaikoInbox { error InvalidTransitionStateRoot(); error MetaHashMismatch(); error MsgValueNotZero(); - error NoBlocksToPropose(); + error NoBatchToPropose(); error NoBlocksToProve(); error NotPreconfRouter(); error ParentMetaHashMismatch(); @@ -232,28 +230,28 @@ interface ITaikoInbox { error TooManySignals(); error TransitionNotFound(); - /// @notice Proposes multiple blocks with specified parameters and transaction list. + /// @notice Proposes multiple batches with specified parameters and transaction list. /// @param _proposer The address of the proposer, which is set by the PreconfTaskManager if /// enabled; otherwise, it must be address(0). /// @param _coinbase The address that will receive the block rewards; defaults to the proposer's /// address if set to address(0). - /// @param _blockParams An array containing the parameters for each block being proposed. + /// @param _batchParams An array containing the parameters for each batch being proposed. /// @param _txList The transaction list in calldata. If the txList is empty, blob will be used /// for data availability. - /// @return An array of block metadata for each block proposed. + /// @return An array of batch metadata for each batch proposed. function proposeBatches( address _proposer, address _coinbase, - BatchParams[] calldata _blockParams, + BatchParams[] calldata _batchParams, bytes calldata _txList ) external returns (BatchMetadata[] memory); - /// @notice Proves state transitions for multiple blocks with a single aggregated proof. - /// @param _metas Array of metadata for each block being proved. - /// @param _transitions Array of block transitions to be proved. - /// @param proof The aggregated cryptographic proof proving the blocks transitions. + /// @notice Proves state transitions for multiple batches with a single aggregated proof. + /// @param _metas Array of metadata for each batch being proved. + /// @param _transitions Array of batch transitions to be proved. + /// @param proof The aggregated cryptographic proof proving the batches transitions. function proveBatches( BatchMetadata[] calldata _metas, Transition[] calldata _transitions, @@ -287,14 +285,14 @@ interface ITaikoInbox { /// @return Stats2 structure containing the statistics. function getStats2() external view returns (Stats2 memory); - /// @notice Retrieves data about a specific block. - /// @param _batchId The ID of the block to retrieve. - /// @return batch_ The block data. + /// @notice Retrieves data about a specific batch. + /// @param _batchId The ID of the batch to retrieve. + /// @return batch_ The batch data. function getBatch(uint64 _batchId) external view returns (Batch memory batch_); /// @notice Retrieves a specific transition by batch ID and transition ID. This function may /// revert if the transition is not found. - /// @param _batchId The block ID. + /// @param _batchId The batch ID. /// @param _tid The transition ID. /// @return The specified transition. function getTransition( @@ -305,25 +303,25 @@ interface ITaikoInbox { view returns (ITaikoInbox.Transition memory); - /// @notice Retrieves the transition used for the last verified block. - /// @return batchId_ The block ID of the last verified transition. + /// @notice Retrieves the transition used for the last verified batch. + /// @return batchId_ The batch ID of the last verified transition. /// @return tran_ The last verified transition. function getLastVerifiedTransition() external view returns (uint64 batchId_, Transition memory tran_); - /// @notice Retrieves the transition used for the last synced block. - /// @return batchId_ The block ID of the last synced transition. + /// @notice Retrieves the transition used for the last synced batch. + /// @return batchId_ The batch ID of the last synced transition. /// @return tran_ The last synced transition. function getLastSyncedTransition() external view returns (uint64 batchId_, Transition memory tran_); - /// @notice Retrieves the transition used for verifying a block. - /// @param _batchId The block ID. - /// @return The transition used for verifying the block. + /// @notice Retrieves the transition used for verifying a batch. + /// @param _batchId The batch ID. + /// @return The transition used for verifying the batch. function getBatchVerifyingTransition(uint64 _batchId) external view diff --git a/packages/protocol/contracts/layer1/based/TaikoInbox.sol b/packages/protocol/contracts/layer1/based/TaikoInbox.sol index ec2dab56415..318919c78d1 100644 --- a/packages/protocol/contracts/layer1/based/TaikoInbox.sol +++ b/packages/protocol/contracts/layer1/based/TaikoInbox.sol @@ -43,14 +43,14 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { __Taiko_init(_owner, _rollupResolver, _genesisBlockHash); } - /// @notice Proposes multiple blocks. + /// @notice Proposes multiple batches. /// @param _proposer The address of the proposer, which is set by the PreconfTaskManager if /// enabled; otherwise, it must be address(0). /// @param _coinbase The address that will receive the block rewards; defaults to the /// proposer's address if set to address(0). - /// @param _paramsArray An array containing the parameters for each block being proposed. + /// @param _paramsArray An array containing the parameters for each batch being proposed. /// @param _txList The transaction list in calldata. - /// @return metas_ Array of block metadata for each block proposed. + /// @return metas_ Array of batch metadata for each batch proposed. function proposeBatches( address _proposer, address _coinbase, @@ -61,7 +61,7 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { nonReentrant returns (BatchMetadata[] memory metas_) { - require(_paramsArray.length != 0, NoBlocksToPropose()); + require(_paramsArray.length != 0, NoBatchToPropose()); Stats2 memory stats2 = state.stats2; require(!stats2.paused, ContractPaused()); @@ -72,7 +72,7 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { unchecked { require( stats2.numBlocks + _paramsArray.length - <= stats2.lastVerifiedBatch + config.blockMaxProposals, + <= stats2.lastVerifiedBatch + config.maxBatchProposals, TooManyBlocks() ); } @@ -90,13 +90,13 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { _coinbase = _proposer; } - // Keep track of last block's information. - BlockInfo memory lastBlock; + // Keep track of last batch's information. + BatchInfoInfo memory lastBatch; unchecked { Batch storage lastBlk = - state.blocks[(stats2.numBlocks - 1) % config.blockRingBufferSize]; + state.batches[(stats2.numBlocks - 1) % config.batchRingBufferSize]; - lastBlock = BlockInfo(lastBlk.metaHash, lastBlk.timestamp, lastBlk.anchorBlockId); + lastBatch = BatchInfoInfo(lastBlk.metaHash, lastBlk.timestamp, lastBlk.anchorBlockId); } metas_ = new BatchMetadata[](_paramsArray.length); @@ -112,13 +112,13 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { } updatedParams = _validateBlockParams( - _paramsArray[i], config.maxAnchorHeightOffset, config.maxSignalsToReceive, lastBlock + _paramsArray[i], config.maxAnchorHeightOffset, config.maxSignalsToReceive, lastBatch ); - // This section constructs the metadata for the proposed block, which is crucial for - // nodes/clients to process the block. The metadata itself is not stored on-chain; + // This section constructs the metadata for the proposed batch, which is crucial for + // nodes/clients to process the batch. The metadata itself is not stored on-chain; // instead, only its hash is kept. - // The metadata must be supplied as calldata prior to proving the block, enabling the + // The metadata must be supplied as calldata prior to proving the batch, enabling the // computation and verification of its integrity through the comparison of the metahash. unchecked { metas_[i] = BatchMetadata({ @@ -131,7 +131,7 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { batchId: stats2.numBlocks, gasLimit: config.blockMaxGasLimit, timestamp: updatedParams.timestamp, - parentMetaHash: lastBlock.metaHash, + parentMetaHash: lastBatch.metaHash, proposer: _proposer, livenessBond: config.livenessBond, proposedAt: uint64(block.timestamp), @@ -142,7 +142,7 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { anchorBlockId: updatedParams.anchorBlockId, anchorBlockHash: blockhash(updatedParams.anchorBlockId), signalSlots: _paramsArray[i].signalSlots, - subBlocks: _paramsArray[i].subBlocks, + blocks: _paramsArray[i].blocks, anchorInput: _paramsArray[i].anchorInput, baseFeeConfig: config.baseFeeConfig }); @@ -151,7 +151,7 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { require(metas_[i].txListHash != 0, BlobNotFound()); bytes32 metaHash = keccak256(abi.encode(metas_[i])); - Batch storage blk = state.blocks[stats2.numBlocks % config.blockRingBufferSize]; + Batch storage blk = state.batches[stats2.numBlocks % config.batchRingBufferSize]; // SSTORE #1 blk.metaHash = metaHash; @@ -160,12 +160,13 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { blk.timestamp = updatedParams.timestamp; blk.anchorBlockId = updatedParams.anchorBlockId; blk.nextTransitionId = 1; - blk.numSubBlocks = uint8(_paramsArray[i].subBlocks.length); + blk.numSubBlocks = uint8(_paramsArray[i].blocks.length); blk.verifiedTransitionId = 0; // SSTORE }} - // Update lastBlock to reference the most recently proposed block. - lastBlock = BlockInfo(metaHash, updatedParams.timestamp, updatedParams.anchorBlockId); + // Update lastBatch to reference the most recently proposed batch. + lastBatch = + BatchInfoInfo(metaHash, updatedParams.timestamp, updatedParams.anchorBlockId); unchecked { stats2.numBlocks += 1; @@ -179,9 +180,9 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { _verifyBlocks(config, stats2, _paramsArray.length); } - /// @notice Proves multiple blocks with a single aggregated proof. - /// @param _metas Array of block metadata to be proven. - /// @param _transitions Array of transitions corresponding to the block metadata. + /// @notice Proves multiple batches with a single aggregated proof. + /// @param _metas Array of batch metadata to be proven. + /// @param _transitions Array of transitions corresponding to the batch metadata. /// @param _proof Cryptographic proof validating all the transitions. function proveBatches( BatchMetadata[] calldata _metas, @@ -206,8 +207,8 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { batchIds[i] = meta.batchId; require(meta.batchId >= config.forkHeights.pacaya, InvalidForkHeight()); - require(meta.batchId > stats2.lastVerifiedBatch, BlockNotFound()); - require(meta.batchId < stats2.numBlocks, BlockNotFound()); + require(meta.batchId > stats2.lastVerifiedBatch, BatchNotFound()); + require(meta.batchId < stats2.numBlocks, BatchNotFound()); Transition calldata tran = _transitions[i]; require(tran.parentHash != 0, InvalidTransitionParentHash()); @@ -219,9 +220,9 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { ctxs[i].metaHash = keccak256(abi.encode(meta)); ctxs[i].transition = tran; - // Verify the block's metadata. - uint256 slot = meta.batchId % config.blockRingBufferSize; - Batch storage blk = state.blocks[slot]; + // Verify the batch's metadata. + uint256 slot = meta.batchId % config.batchRingBufferSize; + Batch storage blk = state.batches[slot]; require(ctxs[i].metaHash == blk.metaHash, MetaHashMismatch()); // Finds out if this transition is overwriting an existing one (with the same parent @@ -229,7 +230,7 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { uint24 tid; uint24 nextTransitionId = blk.nextTransitionId; if (nextTransitionId > 1) { - // This block has been proved at least once. + // This batch has been proved at least once. if (state.transitions[slot][1].parentHash == tran.parentHash) { // Overwrite the first transition. tid = 1; @@ -251,7 +252,7 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { if (isOverwrite) { emit TransitionOverwritten(meta.batchId, ts); } else if (tid == 1) { - // Ensure that only the block proposer can prove the first transition before the + // Ensure that only the proposer can prove the first transition before the // proving deadline. unchecked { uint256 deadline = @@ -271,10 +272,10 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { } if (meta.batchId % config.stateRootSyncInternal == 0) { - // This block is a "sync block", we need to save the state root. + // This batch is a "sync batch", we need to save the state root. ts.stateRoot = tran.stateRoot; } else { - // This block is not a "sync block", we need to zero out the storage slot. + // This batch is not a "sync batch", we need to zero out the storage slot. ts.stateRoot = bytes32(0); } @@ -332,9 +333,9 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { returns (Transition memory tran_) { Config memory config = getConfig(); - uint256 slot = _batchId % config.blockRingBufferSize; - Batch storage blk = state.blocks[slot]; - require(blk.batchId == _batchId, BlockNotFound()); + uint256 slot = _batchId % config.batchRingBufferSize; + Batch storage blk = state.batches[slot]; + require(blk.batchId == _batchId, BatchNotFound()); require(_tid != 0 && _tid < blk.nextTransitionId, TransitionNotFound()); return state.transitions[slot][_tid]; } @@ -369,8 +370,8 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { Config memory config = getConfig(); require(_batchId >= config.forkHeights.pacaya, InvalidForkHeight()); - blk_ = state.blocks[_batchId % config.blockRingBufferSize]; - require(blk_.batchId == _batchId, BlockNotFound()); + blk_ = state.batches[_batchId % config.batchRingBufferSize]; + require(blk_.batchId == _batchId, BatchNotFound()); } /// @notice Determines the operational layer of the contract, whether it is on Layer 1 (L1) or @@ -400,9 +401,9 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { { Config memory config = getConfig(); - uint64 slot = _batchId % config.blockRingBufferSize; - Batch storage blk = state.blocks[slot]; - require(blk.batchId == _batchId, BlockNotFound()); + uint64 slot = _batchId % config.batchRingBufferSize; + Batch storage blk = state.batches[slot]; + require(blk.batchId == _batchId, BatchNotFound()); if (blk.verifiedTransitionId != 0) { tran_ = state.transitions[slot][blk.verifiedTransitionId]; @@ -426,7 +427,7 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { require(_genesisBlockHash != 0, InvalidGenesisBlockHash()); state.transitions[0][1].blockHash = _genesisBlockHash; - Batch storage blk = state.blocks[0]; + Batch storage blk = state.batches[0]; blk.metaHash = bytes32(uint256(1)); blk.timestamp = uint64(block.timestamp); blk.anchorBlockId = uint64(block.number); @@ -460,19 +461,19 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { function _verifyBlocks(Config memory _config, Stats2 memory _stats2, uint256 _length) private { uint64 batchId = _stats2.lastVerifiedBatch; - uint256 slot = batchId % _config.blockRingBufferSize; - Batch storage blk = state.blocks[slot]; + uint256 slot = batchId % _config.batchRingBufferSize; + Batch storage blk = state.batches[slot]; uint24 tid = blk.verifiedTransitionId; bytes32 blockHash = state.transitions[slot][tid].blockHash; SyncBlock memory synced; - uint256 stopBlockId = - (_config.maxBlocksToVerify * _length + _stats2.lastVerifiedBatch).min(_stats2.numBlocks); + uint256 stopBlockId = (_config.maxBatchesTooVerify * _length + _stats2.lastVerifiedBatch) + .min(_stats2.numBlocks); for (++batchId; batchId < stopBlockId; ++batchId) { - slot = batchId % _config.blockRingBufferSize; - blk = state.blocks[slot]; + slot = batchId % _config.batchRingBufferSize; + blk = state.batches[slot]; // FIX Transition storage ts = state.transitions[slot][1]; @@ -506,14 +507,14 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { if (_stats2.lastVerifiedBatch != batchId) { _stats2.lastVerifiedBatch = batchId; - blk = state.blocks[_stats2.lastVerifiedBatch % _config.blockRingBufferSize]; + blk = state.batches[_stats2.lastVerifiedBatch % _config.batchRingBufferSize]; blk.verifiedTransitionId = tid; emit BatchesVerified(_stats2.lastVerifiedBatch, blockHash); if (synced.batchId != 0) { if (synced.batchId != _stats2.lastVerifiedBatch) { - // We write the synced block's verifiedTransitionId to storage - blk = state.blocks[synced.batchId % _config.blockRingBufferSize]; + // We write the synced batch's verifiedTransitionId to storage + blk = state.batches[synced.batchId % _config.batchRingBufferSize]; blk.verifiedTransitionId = synced.tid; } @@ -573,7 +574,7 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { BatchParams calldata _params, uint64 _maxAnchorHeightOffset, uint8 _maxSignalsToReceive, - BlockInfo memory _parent + BatchInfoInfo memory _parent ) private view @@ -610,8 +611,8 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { updatedParams_.timestamp = _params.timestamp; } - // Check if parent block has the right meta hash. This is to allow the proposer to - // make sure the block builds on the expected latest chain state. + // Check if parent batch has the right meta hash. This is to allow the proposer to + // make sure the batch builds on the expected latest chain state. require( _params.parentMetaHash == 0 || _params.parentMetaHash == _parent.metaHash, ParentMetaHashMismatch() @@ -630,14 +631,14 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { } require( - _params.subBlocks.length != 0 && _params.subBlocks.length <= type(uint8).max, + _params.blocks.length != 0 && _params.blocks.length <= type(uint8).max, InvalidSubBlocks() ); } // Memory-only structs ---------------------------------------------------------------------- - struct BlockInfo { + struct BatchInfoInfo { bytes32 metaHash; uint64 anchorBlockId; uint64 timestamp; diff --git a/packages/protocol/contracts/layer1/devnet/DevnetInbox.sol b/packages/protocol/contracts/layer1/devnet/DevnetInbox.sol index 5aaea3f178a..fbaa7b58c98 100644 --- a/packages/protocol/contracts/layer1/devnet/DevnetInbox.sol +++ b/packages/protocol/contracts/layer1/devnet/DevnetInbox.sol @@ -11,9 +11,9 @@ contract DevnetInbox is TaikoInbox { function getConfig() public pure override returns (ITaikoInbox.Config memory) { return ITaikoInbox.Config({ chainId: 167_001, - blockMaxProposals: 324_000, - blockRingBufferSize: 360_000, - maxBlocksToVerify: 16, + maxBatchProposals: 324_000, + batchRingBufferSize: 360_000, + maxBatchesTooVerify: 16, blockMaxGasLimit: 240_000_000, livenessBond: 125e18, // 125 Taiko token stateRootSyncInternal: 16, diff --git a/packages/protocol/contracts/layer1/hekla/HeklaInbox.sol b/packages/protocol/contracts/layer1/hekla/HeklaInbox.sol index 0b43f18d8d0..f66ce4338f7 100644 --- a/packages/protocol/contracts/layer1/hekla/HeklaInbox.sol +++ b/packages/protocol/contracts/layer1/hekla/HeklaInbox.sol @@ -11,10 +11,10 @@ contract HeklaInbox is TaikoInbox { return ITaikoInbox.Config({ chainId: LibNetwork.TAIKO_HEKLA, // Never change this value as ring buffer is being reused!!! - blockMaxProposals: 324_000, + maxBatchProposals: 324_000, // Never change this value as ring buffer is being reused!!! - blockRingBufferSize: 324_512, - maxBlocksToVerify: 16, + batchRingBufferSize: 324_512, + maxBatchesTooVerify: 16, blockMaxGasLimit: 240_000_000, livenessBond: 125e18, // 125 Taiko token stateRootSyncInternal: 16, diff --git a/packages/protocol/contracts/layer1/mainnet/MainnetInbox.sol b/packages/protocol/contracts/layer1/mainnet/MainnetInbox.sol index 809f0ccc215..29fa046d253 100644 --- a/packages/protocol/contracts/layer1/mainnet/MainnetInbox.sol +++ b/packages/protocol/contracts/layer1/mainnet/MainnetInbox.sol @@ -20,9 +20,9 @@ contract MainnetInbox is TaikoInbox { chainId: LibNetwork.TAIKO_MAINNET, // Ring buffers are being reused on the mainnet, therefore the following two // configuration values must NEVER be changed!!! - blockMaxProposals: 324_000, // DO NOT CHANGE!!! - blockRingBufferSize: 360_000, // DO NOT CHANGE!!! - maxBlocksToVerify: 16, + maxBatchProposals: 324_000, // DO NOT CHANGE!!! + batchRingBufferSize: 360_000, // DO NOT CHANGE!!! + maxBatchesTooVerify: 16, blockMaxGasLimit: 240_000_000, livenessBond: 125e18, // 125 Taiko token stateRootSyncInternal: 16, diff --git a/packages/protocol/test/layer1/team/tokenunlock/TokenUnlock_ProverSet.t.sol b/packages/protocol/test/layer1/team/tokenunlock/TokenUnlock_ProverSet.t.sol index 88d154b5f5a..f93d1be3734 100644 --- a/packages/protocol/test/layer1/team/tokenunlock/TokenUnlock_ProverSet.t.sol +++ b/packages/protocol/test/layer1/team/tokenunlock/TokenUnlock_ProverSet.t.sol @@ -17,9 +17,9 @@ pragma solidity ^0.8.24; // function getConfig() internal pure override returns (ITaikoInbox.Config memory) { // return ITaikoInbox.Config({ // chainId: LibNetwork.TAIKO_MAINNET, -// blockMaxProposals: 10, -// blockRingBufferSize: 15, -// maxBlocksToVerify: 5, +// maxBatchProposals: 10, +// batchRingBufferSize: 15, +// maxBatchesTooVerify: 5, // blockMaxGasLimit: 240_000_000, // livenessBond: livenessBond, // 125 Taiko token // stateRootSyncInternal: 5, From 0c5c089ef64af64a962426b7ccc41bf727a2520f Mon Sep 17 00:00:00 2001 From: Daniel Wang Date: Fri, 10 Jan 2025 11:57:39 +0800 Subject: [PATCH 07/41] rename 4 --- .../contracts/layer1/based/ITaikoInbox.sol | 23 ++- .../contracts/layer1/based/TaikoInbox.sol | 160 +++++++++--------- .../preconf/iface/IPreconfTaskManager.sol | 6 +- .../preconf/impl/PreconfTaskManager.sol | 8 +- .../contracts/layer1/provers/ProverSet.sol | 8 +- .../test/layer1/based/helpers/StubInbox.sol | 6 +- .../preconf/blocks/BlockProposing.t.sol | 6 +- 7 files changed, 104 insertions(+), 113 deletions(-) diff --git a/packages/protocol/contracts/layer1/based/ITaikoInbox.sol b/packages/protocol/contracts/layer1/based/ITaikoInbox.sol index 8700bc6119b..794d5519dcc 100644 --- a/packages/protocol/contracts/layer1/based/ITaikoInbox.sol +++ b/packages/protocol/contracts/layer1/based/ITaikoInbox.sol @@ -90,7 +90,7 @@ interface ITaikoInbox { } struct Stats2 { - uint64 numBlocks; + uint64 numBatches; uint64 lastVerifiedBatch; bool paused; uint56 lastProposedIn; @@ -175,11 +175,11 @@ interface ITaikoInbox { /// @param stats2 The Stats2 data structure. event Stats2Updated(Stats2 stats2); - /// @notice Emitted when multiple batches are proposed. - /// @param metas The metadata of the proposed batches. + /// @notice Emitted when a batch is proposed. + /// @param meta The metadata of the proposed batch. /// @param calldataUsed Whether calldata is used for txList DA. /// @param txListInCalldata The tx list in calldata. - event BatchesProposed(BatchMetadata[] metas, bool calldataUsed, bytes txListInCalldata); + event BatchProposed(BatchMetadata meta, bool calldataUsed, bytes txListInCalldata); /// @notice Emitted when multiple transitions are proved. /// @param verifier The address of the verifier. @@ -217,7 +217,6 @@ interface ITaikoInbox { error InvalidTransitionStateRoot(); error MetaHashMismatch(); error MsgValueNotZero(); - error NoBatchToPropose(); error NoBlocksToProve(); error NotPreconfRouter(); error ParentMetaHashMismatch(); @@ -226,27 +225,27 @@ interface ITaikoInbox { error TimestampSmallerThanParent(); error TimestampTooLarge(); error TimestampTooSmall(); - error TooManyBlocks(); + error TooManyBatches(); error TooManySignals(); error TransitionNotFound(); - /// @notice Proposes multiple batches with specified parameters and transaction list. + /// @notice Proposes a batch of blocks. /// @param _proposer The address of the proposer, which is set by the PreconfTaskManager if /// enabled; otherwise, it must be address(0). /// @param _coinbase The address that will receive the block rewards; defaults to the proposer's /// address if set to address(0). - /// @param _batchParams An array containing the parameters for each batch being proposed. + /// @param _batchParams Batch parameters. /// @param _txList The transaction list in calldata. If the txList is empty, blob will be used /// for data availability. - /// @return An array of batch metadata for each batch proposed. - function proposeBatches( + /// @return Batch metadata. + function proposeBatch( address _proposer, address _coinbase, - BatchParams[] calldata _batchParams, + BatchParams calldata _batchParams, bytes calldata _txList ) external - returns (BatchMetadata[] memory); + returns (BatchMetadata memory); /// @notice Proves state transitions for multiple batches with a single aggregated proof. /// @param _metas Array of metadata for each batch being proved. diff --git a/packages/protocol/contracts/layer1/based/TaikoInbox.sol b/packages/protocol/contracts/layer1/based/TaikoInbox.sol index 318919c78d1..f06270a82ae 100644 --- a/packages/protocol/contracts/layer1/based/TaikoInbox.sol +++ b/packages/protocol/contracts/layer1/based/TaikoInbox.sol @@ -48,32 +48,29 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { /// enabled; otherwise, it must be address(0). /// @param _coinbase The address that will receive the block rewards; defaults to the /// proposer's address if set to address(0). - /// @param _paramsArray An array containing the parameters for each batch being proposed. + /// @param _batchParams Batch parameters. /// @param _txList The transaction list in calldata. - /// @return metas_ Array of batch metadata for each batch proposed. - function proposeBatches( + /// @return meta_ Batch metadata. + function proposeBatch( address _proposer, address _coinbase, - BatchParams[] calldata _paramsArray, + BatchParams calldata _batchParams, bytes calldata _txList ) external nonReentrant - returns (BatchMetadata[] memory metas_) + returns (BatchMetadata memory meta_) { - require(_paramsArray.length != 0, NoBatchToPropose()); - Stats2 memory stats2 = state.stats2; require(!stats2.paused, ContractPaused()); Config memory config = getConfig(); - require(stats2.numBlocks >= config.forkHeights.pacaya, InvalidForkHeight()); + require(stats2.numBatches >= config.forkHeights.pacaya, InvalidForkHeight()); unchecked { require( - stats2.numBlocks + _paramsArray.length - <= stats2.lastVerifiedBatch + config.maxBatchProposals, - TooManyBlocks() + stats2.numBatches < stats2.lastVerifiedBatch + config.maxBatchProposals, + TooManyBatches() ); } @@ -93,91 +90,88 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { // Keep track of last batch's information. BatchInfoInfo memory lastBatch; unchecked { - Batch storage lastBlk = - state.batches[(stats2.numBlocks - 1) % config.batchRingBufferSize]; + Batch storage _lastBatch = + state.batches[(stats2.numBatches - 1) % config.batchRingBufferSize]; - lastBatch = BatchInfoInfo(lastBlk.metaHash, lastBlk.timestamp, lastBlk.anchorBlockId); + lastBatch = + BatchInfoInfo(_lastBatch.metaHash, _lastBatch.timestamp, _lastBatch.anchorBlockId); } - metas_ = new BatchMetadata[](_paramsArray.length); bool calldataUsed = _txList.length != 0; UpdatedParams memory updatedParams; - for (uint256 i; i < _paramsArray.length; ++i) { - if (!calldataUsed) { - require(_paramsArray[i].blobIndices.length != 0, BlobIndexZero()); - for (uint256 j; j < _paramsArray[i].blobIndices[j]; ++j) { - require(_paramsArray[i].blobIndices[j] != 0, BlobIndexZero()); - } + if (!calldataUsed) { + require(_batchParams.blobIndices.length != 0, BlobIndexZero()); + for (uint256 j; j < _batchParams.blobIndices[j]; ++j) { + require(_batchParams.blobIndices[j] != 0, BlobIndexZero()); } + } - updatedParams = _validateBlockParams( - _paramsArray[i], config.maxAnchorHeightOffset, config.maxSignalsToReceive, lastBatch - ); + updatedParams = _validateBlockParams( + _batchParams, config.maxAnchorHeightOffset, config.maxSignalsToReceive, lastBatch + ); - // This section constructs the metadata for the proposed batch, which is crucial for - // nodes/clients to process the batch. The metadata itself is not stored on-chain; - // instead, only its hash is kept. - // The metadata must be supplied as calldata prior to proving the batch, enabling the - // computation and verification of its integrity through the comparison of the metahash. - unchecked { - metas_[i] = BatchMetadata({ - difficulty: keccak256(abi.encode("TAIKO_DIFFICULTY", stats2.numBlocks)), - txListHash: calldataUsed - ? keccak256(_txList) - : _calcTxListHash(_paramsArray[i].blobIndices), - extraData: bytes32(uint256(config.baseFeeConfig.sharingPctg)), - coinbase: _coinbase, - batchId: stats2.numBlocks, - gasLimit: config.blockMaxGasLimit, - timestamp: updatedParams.timestamp, - parentMetaHash: lastBatch.metaHash, - proposer: _proposer, - livenessBond: config.livenessBond, - proposedAt: uint64(block.timestamp), - proposedIn: uint64(block.number), - txListOffset: _paramsArray[i].txListOffset, - txListSize: _paramsArray[i].txListSize, - blobIndices: calldataUsed ? new uint8[](0) : _paramsArray[i].blobIndices, - anchorBlockId: updatedParams.anchorBlockId, - anchorBlockHash: blockhash(updatedParams.anchorBlockId), - signalSlots: _paramsArray[i].signalSlots, - blocks: _paramsArray[i].blocks, - anchorInput: _paramsArray[i].anchorInput, - baseFeeConfig: config.baseFeeConfig - }); - } + // This section constructs the metadata for the proposed batch, which is crucial for + // nodes/clients to process the batch. The metadata itself is not stored on-chain; + // instead, only its hash is kept. + // The metadata must be supplied as calldata prior to proving the batch, enabling the + // computation and verification of its integrity through the comparison of the metahash. + unchecked { + meta_ = BatchMetadata({ + difficulty: keccak256(abi.encode("TAIKO_DIFFICULTY", stats2.numBatches)), + txListHash: calldataUsed + ? keccak256(_txList) + : _calcTxListHash(_batchParams.blobIndices), + extraData: bytes32(uint256(config.baseFeeConfig.sharingPctg)), + coinbase: _coinbase, + batchId: stats2.numBatches, + gasLimit: config.blockMaxGasLimit, + timestamp: updatedParams.timestamp, + parentMetaHash: lastBatch.metaHash, + proposer: _proposer, + livenessBond: config.livenessBond, + proposedAt: uint64(block.timestamp), + proposedIn: uint64(block.number), + txListOffset: _batchParams.txListOffset, + txListSize: _batchParams.txListSize, + blobIndices: calldataUsed ? new uint8[](0) : _batchParams.blobIndices, + anchorBlockId: updatedParams.anchorBlockId, + anchorBlockHash: blockhash(updatedParams.anchorBlockId), + signalSlots: _batchParams.signalSlots, + blocks: _batchParams.blocks, + anchorInput: _batchParams.anchorInput, + baseFeeConfig: config.baseFeeConfig + }); + } - require(metas_[i].txListHash != 0, BlobNotFound()); - bytes32 metaHash = keccak256(abi.encode(metas_[i])); + require(meta_.txListHash != 0, BlobNotFound()); + bytes32 metaHash = keccak256(abi.encode(meta_)); - Batch storage blk = state.batches[stats2.numBlocks % config.batchRingBufferSize]; - // SSTORE #1 - blk.metaHash = metaHash; + Batch storage blk = state.batches[stats2.numBatches % config.batchRingBufferSize]; + // SSTORE #1 + blk.metaHash = metaHash; - // SSTORE #2 {{ - blk.batchId = stats2.numBlocks; - blk.timestamp = updatedParams.timestamp; - blk.anchorBlockId = updatedParams.anchorBlockId; - blk.nextTransitionId = 1; - blk.numSubBlocks = uint8(_paramsArray[i].blocks.length); - blk.verifiedTransitionId = 0; - // SSTORE }} + // SSTORE #2 {{ + blk.batchId = stats2.numBatches; + blk.timestamp = updatedParams.timestamp; + blk.anchorBlockId = updatedParams.anchorBlockId; + blk.nextTransitionId = 1; + blk.numSubBlocks = uint8(_batchParams.blocks.length); + blk.verifiedTransitionId = 0; + // SSTORE }} - // Update lastBatch to reference the most recently proposed batch. - lastBatch = - BatchInfoInfo(metaHash, updatedParams.timestamp, updatedParams.anchorBlockId); + // Update lastBatch to reference the most recently proposed batch. + lastBatch = BatchInfoInfo(metaHash, updatedParams.timestamp, updatedParams.anchorBlockId); - unchecked { - stats2.numBlocks += 1; - stats2.lastProposedIn = uint56(block.number); - } - } // end of for-loop + unchecked { + stats2.numBatches += 1; + stats2.lastProposedIn = uint56(block.number); + } - _debitBond(_proposer, config.livenessBond * _paramsArray.length); - emit BatchesProposed(metas_, calldataUsed, _txList); + _debitBond(_proposer, config.livenessBond); + emit BatchProposed(meta_, calldataUsed, _txList); - _verifyBlocks(config, stats2, _paramsArray.length); + _verifyBlocks(config, stats2, 1); } /// @notice Proves multiple batches with a single aggregated proof. @@ -208,7 +202,7 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { batchIds[i] = meta.batchId; require(meta.batchId >= config.forkHeights.pacaya, InvalidForkHeight()); require(meta.batchId > stats2.lastVerifiedBatch, BatchNotFound()); - require(meta.batchId < stats2.numBlocks, BatchNotFound()); + require(meta.batchId < stats2.numBatches, BatchNotFound()); Transition calldata tran = _transitions[i]; require(tran.parentHash != 0, InvalidTransitionParentHash()); @@ -435,7 +429,7 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { blk.verifiedTransitionId = 1; state.stats2.lastProposedIn = uint56(block.number); - state.stats2.numBlocks = 1; + state.stats2.numBatches = 1; emit BatchesVerified(0, _genesisBlockHash); } @@ -469,7 +463,7 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { SyncBlock memory synced; uint256 stopBlockId = (_config.maxBatchesTooVerify * _length + _stats2.lastVerifiedBatch) - .min(_stats2.numBlocks); + .min(_stats2.numBatches); for (++batchId; batchId < stopBlockId; ++batchId) { slot = batchId % _config.batchRingBufferSize; diff --git a/packages/protocol/contracts/layer1/preconf/iface/IPreconfTaskManager.sol b/packages/protocol/contracts/layer1/preconf/iface/IPreconfTaskManager.sol index c0872aaacd5..168e24185fb 100644 --- a/packages/protocol/contracts/layer1/preconf/iface/IPreconfTaskManager.sol +++ b/packages/protocol/contracts/layer1/preconf/iface/IPreconfTaskManager.sol @@ -59,10 +59,10 @@ interface IPreconfTaskManager { /// @dev The registry does not have a single registered preconfer error NoRegisteredPreconfer(); - /// @dev Accepts block proposal by an operator and forwards it to Taiko contract - function proposeBatches( + /// @dev Accepts batch proposal by an operator and forwards it to Taiko contract + function proposeBatch( address coinbase, - ITaikoInbox.BatchParams[] calldata batchParams, + ITaikoInbox.BatchParams calldata batchParams, bytes calldata txList, uint256 lookaheadPointer, LookaheadSetParam[] calldata lookaheadSetParams diff --git a/packages/protocol/contracts/layer1/preconf/impl/PreconfTaskManager.sol b/packages/protocol/contracts/layer1/preconf/impl/PreconfTaskManager.sol index 19299009748..7b489ae15d9 100644 --- a/packages/protocol/contracts/layer1/preconf/impl/PreconfTaskManager.sol +++ b/packages/protocol/contracts/layer1/preconf/impl/PreconfTaskManager.sol @@ -69,7 +69,7 @@ contract PreconfTaskManager is IPreconfTaskManager, Initializable { } /** - * @notice Proposes a new Taiko L2 block. + * @notice Proposes a new batch of Taiko L2 block. * @dev The first caller in every epoch is expected to pass along the lookahead entries for the * next epoch. * The function reverts if the lookahead is lagging behind. This is possible if it is @@ -85,9 +85,9 @@ contract PreconfTaskManager is IPreconfTaskManager, Initializable { * @param lookaheadSetParams Collection of timestamps and preconfer addresses to be inserted in * the lookahead */ - function proposeBatches( + function proposeBatch( address coinbase, - ITaikoInbox.BatchParams[] calldata batchParams, + ITaikoInbox.BatchParams calldata batchParams, bytes calldata txList, uint256 lookaheadPointer, LookaheadSetParam[] calldata lookaheadSetParams @@ -126,7 +126,7 @@ contract PreconfTaskManager is IPreconfTaskManager, Initializable { ); // Forward the block to Taiko's L1 contract - inbox.proposeBatches(msg.sender, coinbase, batchParams, txList); + inbox.proposeBatch(msg.sender, coinbase, batchParams, txList); } /** diff --git a/packages/protocol/contracts/layer1/provers/ProverSet.sol b/packages/protocol/contracts/layer1/provers/ProverSet.sol index 75194da4438..9fe495cbe87 100644 --- a/packages/protocol/contracts/layer1/provers/ProverSet.sol +++ b/packages/protocol/contracts/layer1/provers/ProverSet.sol @@ -95,21 +95,21 @@ contract ProverSet is EssentialContract, IERC1271 { } /// @notice Propose multiple Taiko blocks. - function proposeBatches( - ITaikoInbox.BatchParams[] calldata _paramsArray, + function proposeBatch( + ITaikoInbox.BatchParams calldata _batchParams, bytes calldata _txList, bool _revertIfNotFirstProposal ) external onlyProver - returns (ITaikoInbox.BatchMetadata[] memory metas_) + returns (ITaikoInbox.BatchMetadata memory) { ITaikoInbox taiko = ITaikoInbox(inbox()); if (_revertIfNotFirstProposal) { // Ensure this block is the first block proposed in the current L1 block. require(taiko.getStats2().lastProposedIn != block.number, NOT_FIRST_PROPOSAL()); } - return taiko.proposeBatches(address(0), address(0), _paramsArray, _txList); + return taiko.proposeBatch(address(0), address(0), _batchParams, _txList); } /// @notice Batch proves or contests Taiko blocks. diff --git a/packages/protocol/test/layer1/based/helpers/StubInbox.sol b/packages/protocol/test/layer1/based/helpers/StubInbox.sol index 626d65c5739..dd14e741ac4 100644 --- a/packages/protocol/test/layer1/based/helpers/StubInbox.sol +++ b/packages/protocol/test/layer1/based/helpers/StubInbox.sol @@ -6,14 +6,14 @@ import "src/layer1/based/ITaikoInbox.sol"; /// @title StubInbox /// @custom:security-contact security@taiko.xyz contract StubInbox is ITaikoInbox { - function proposeBatches( + function proposeBatch( address _proposer, address _coinbase, - BatchParams[] calldata _blockParams, + BatchParams calldata _batchParams, bytes calldata _txList ) external - returns (ITaikoInbox.BatchMetadata[] memory) + returns (ITaikoInbox.BatchMetadata memory) { } function proveBatches( diff --git a/packages/protocol/test/layer1/preconf/blocks/BlockProposing.t.sol b/packages/protocol/test/layer1/preconf/blocks/BlockProposing.t.sol index fc360dfa98d..dbfd1e579a9 100644 --- a/packages/protocol/test/layer1/preconf/blocks/BlockProposing.t.sol +++ b/packages/protocol/test/layer1/preconf/blocks/BlockProposing.t.sol @@ -217,11 +217,9 @@ contract BlockProposing is BlocksFixtures { internal { ITaikoInbox.BatchParams memory defaultParams; - ITaikoInbox.BatchParams[] memory paramsArr = new ITaikoInbox.BatchParams[](1); - paramsArr[0] = defaultParams; - preconfTaskManager.proposeBatches( - msg.sender, paramsArr, "", lookaheadPointer, lookaheadSetParams + preconfTaskManager.proposeBatch( + msg.sender, defaultParams, "", lookaheadPointer, lookaheadSetParams ); } } From 50d903720b342bcd36045392c682b71138b50322 Mon Sep 17 00:00:00 2001 From: Daniel Wang Date: Fri, 10 Jan 2025 12:02:51 +0800 Subject: [PATCH 08/41] clean up --- .../contracts/layer1/based/TaikoInbox.sol | 23 ++++--------------- 1 file changed, 5 insertions(+), 18 deletions(-) diff --git a/packages/protocol/contracts/layer1/based/TaikoInbox.sol b/packages/protocol/contracts/layer1/based/TaikoInbox.sol index f06270a82ae..1986771439d 100644 --- a/packages/protocol/contracts/layer1/based/TaikoInbox.sol +++ b/packages/protocol/contracts/layer1/based/TaikoInbox.sol @@ -88,13 +88,9 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { } // Keep track of last batch's information. - BatchInfoInfo memory lastBatch; + Batch storage lastBatch; unchecked { - Batch storage _lastBatch = - state.batches[(stats2.numBatches - 1) % config.batchRingBufferSize]; - - lastBatch = - BatchInfoInfo(_lastBatch.metaHash, _lastBatch.timestamp, _lastBatch.anchorBlockId); + lastBatch = state.batches[(stats2.numBatches - 1) % config.batchRingBufferSize]; } bool calldataUsed = _txList.length != 0; @@ -160,9 +156,6 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { blk.verifiedTransitionId = 0; // SSTORE }} - // Update lastBatch to reference the most recently proposed batch. - lastBatch = BatchInfoInfo(metaHash, updatedParams.timestamp, updatedParams.anchorBlockId); - unchecked { stats2.numBatches += 1; stats2.lastProposedIn = uint56(block.number); @@ -460,7 +453,7 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { uint24 tid = blk.verifiedTransitionId; bytes32 blockHash = state.transitions[slot][tid].blockHash; - SyncBlock memory synced; + SyncBatch memory synced; uint256 stopBlockId = (_config.maxBatchesTooVerify * _length + _stats2.lastVerifiedBatch) .min(_stats2.numBatches); @@ -568,7 +561,7 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { BatchParams calldata _params, uint64 _maxAnchorHeightOffset, uint8 _maxSignalsToReceive, - BatchInfoInfo memory _parent + Batch memory _parent ) private view @@ -632,18 +625,12 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { // Memory-only structs ---------------------------------------------------------------------- - struct BatchInfoInfo { - bytes32 metaHash; - uint64 anchorBlockId; - uint64 timestamp; - } - struct UpdatedParams { uint64 anchorBlockId; uint64 timestamp; } - struct SyncBlock { + struct SyncBatch { uint64 batchId; uint24 tid; bytes32 stateRoot; From bfb6ba9efcc40c629b47505bfedc7e06c5664629 Mon Sep 17 00:00:00 2001 From: Daniel Wang Date: Fri, 10 Jan 2025 12:06:35 +0800 Subject: [PATCH 09/41] rename 6 --- .../contracts/layer1/based/TaikoInbox.sol | 105 ++++++++++-------- 1 file changed, 56 insertions(+), 49 deletions(-) diff --git a/packages/protocol/contracts/layer1/based/TaikoInbox.sol b/packages/protocol/contracts/layer1/based/TaikoInbox.sol index 1986771439d..2168b44eb9f 100644 --- a/packages/protocol/contracts/layer1/based/TaikoInbox.sol +++ b/packages/protocol/contracts/layer1/based/TaikoInbox.sol @@ -88,9 +88,9 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { } // Keep track of last batch's information. - Batch storage lastBatch; + Batch storage parentBatch; unchecked { - lastBatch = state.batches[(stats2.numBatches - 1) % config.batchRingBufferSize]; + parentBatch = state.batches[(stats2.numBatches - 1) % config.batchRingBufferSize]; } bool calldataUsed = _txList.length != 0; @@ -103,8 +103,8 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { } } - updatedParams = _validateBlockParams( - _batchParams, config.maxAnchorHeightOffset, config.maxSignalsToReceive, lastBatch + updatedParams = _validateBatchParams( + _batchParams, config.maxAnchorHeightOffset, config.maxSignalsToReceive, parentBatch ); // This section constructs the metadata for the proposed batch, which is crucial for @@ -123,7 +123,7 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { batchId: stats2.numBatches, gasLimit: config.blockMaxGasLimit, timestamp: updatedParams.timestamp, - parentMetaHash: lastBatch.metaHash, + parentMetaHash: parentBatch.metaHash, proposer: _proposer, livenessBond: config.livenessBond, proposedAt: uint64(block.timestamp), @@ -143,17 +143,17 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { require(meta_.txListHash != 0, BlobNotFound()); bytes32 metaHash = keccak256(abi.encode(meta_)); - Batch storage blk = state.batches[stats2.numBatches % config.batchRingBufferSize]; + Batch storage batch = state.batches[stats2.numBatches % config.batchRingBufferSize]; // SSTORE #1 - blk.metaHash = metaHash; + batch.metaHash = metaHash; // SSTORE #2 {{ - blk.batchId = stats2.numBatches; - blk.timestamp = updatedParams.timestamp; - blk.anchorBlockId = updatedParams.anchorBlockId; - blk.nextTransitionId = 1; - blk.numSubBlocks = uint8(_batchParams.blocks.length); - blk.verifiedTransitionId = 0; + batch.batchId = stats2.numBatches; + batch.timestamp = updatedParams.timestamp; + batch.anchorBlockId = updatedParams.anchorBlockId; + batch.nextTransitionId = 1; + batch.numSubBlocks = uint8(_batchParams.blocks.length); + batch.verifiedTransitionId = 0; // SSTORE }} unchecked { @@ -164,7 +164,7 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { _debitBond(_proposer, config.livenessBond); emit BatchProposed(meta_, calldataUsed, _txList); - _verifyBlocks(config, stats2, 1); + _verifyBatches(config, stats2, 1); } /// @notice Proves multiple batches with a single aggregated proof. @@ -209,13 +209,13 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { // Verify the batch's metadata. uint256 slot = meta.batchId % config.batchRingBufferSize; - Batch storage blk = state.batches[slot]; - require(ctxs[i].metaHash == blk.metaHash, MetaHashMismatch()); + Batch storage batch = state.batches[slot]; + require(ctxs[i].metaHash == batch.metaHash, MetaHashMismatch()); // Finds out if this transition is overwriting an existing one (with the same parent // hash) or is a new one. uint24 tid; - uint24 nextTransitionId = blk.nextTransitionId; + uint24 nextTransitionId = batch.nextTransitionId; if (nextTransitionId > 1) { // This batch has been proved at least once. if (state.transitions[slot][1].parentHash == tran.parentHash) { @@ -232,7 +232,7 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { bool isOverwrite = (tid != 0); if (tid == 0) { // This transition is new, we need to use the next available ID. - tid = blk.nextTransitionId++; + tid = batch.nextTransitionId++; } Transition storage ts = state.transitions[slot][tid]; @@ -274,7 +274,7 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { emit BatchesProved(verifier, batchIds, _transitions); - _verifyBlocks(config, stats2, _metas.length); + _verifyBatches(config, stats2, _metas.length); } /// @inheritdoc ITaikoInbox @@ -321,9 +321,9 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { { Config memory config = getConfig(); uint256 slot = _batchId % config.batchRingBufferSize; - Batch storage blk = state.batches[slot]; - require(blk.batchId == _batchId, BatchNotFound()); - require(_tid != 0 && _tid < blk.nextTransitionId, TransitionNotFound()); + Batch storage batch = state.batches[slot]; + require(batch.batchId == _batchId, BatchNotFound()); + require(_tid != 0 && _tid < batch.nextTransitionId, TransitionNotFound()); return state.transitions[slot][_tid]; } @@ -353,12 +353,12 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { } /// @inheritdoc ITaikoInbox - function getBatch(uint64 _batchId) external view returns (Batch memory blk_) { + function getBatch(uint64 _batchId) external view returns (Batch memory batch_) { Config memory config = getConfig(); require(_batchId >= config.forkHeights.pacaya, InvalidForkHeight()); - blk_ = state.batches[_batchId % config.batchRingBufferSize]; - require(blk_.batchId == _batchId, BatchNotFound()); + batch_ = state.batches[_batchId % config.batchRingBufferSize]; + require(batch_.batchId == _batchId, BatchNotFound()); } /// @notice Determines the operational layer of the contract, whether it is on Layer 1 (L1) or @@ -389,11 +389,11 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { Config memory config = getConfig(); uint64 slot = _batchId % config.batchRingBufferSize; - Batch storage blk = state.batches[slot]; - require(blk.batchId == _batchId, BatchNotFound()); + Batch storage batch = state.batches[slot]; + require(batch.batchId == _batchId, BatchNotFound()); - if (blk.verifiedTransitionId != 0) { - tran_ = state.transitions[slot][blk.verifiedTransitionId]; + if (batch.verifiedTransitionId != 0) { + tran_ = state.transitions[slot][batch.verifiedTransitionId]; } } @@ -414,12 +414,12 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { require(_genesisBlockHash != 0, InvalidGenesisBlockHash()); state.transitions[0][1].blockHash = _genesisBlockHash; - Batch storage blk = state.batches[0]; - blk.metaHash = bytes32(uint256(1)); - blk.timestamp = uint64(block.timestamp); - blk.anchorBlockId = uint64(block.number); - blk.nextTransitionId = 2; - blk.verifiedTransitionId = 1; + Batch storage batch = state.batches[0]; + batch.metaHash = bytes32(uint256(1)); + batch.timestamp = uint64(block.timestamp); + batch.anchorBlockId = uint64(block.number); + batch.nextTransitionId = 2; + batch.verifiedTransitionId = 1; state.stats2.lastProposedIn = uint56(block.number); state.stats2.numBatches = 1; @@ -446,11 +446,17 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { // Private functions ----------------------------------------------------------------------- - function _verifyBlocks(Config memory _config, Stats2 memory _stats2, uint256 _length) private { + function _verifyBatches( + Config memory _config, + Stats2 memory _stats2, + uint256 _length + ) + private + { uint64 batchId = _stats2.lastVerifiedBatch; uint256 slot = batchId % _config.batchRingBufferSize; - Batch storage blk = state.batches[slot]; - uint24 tid = blk.verifiedTransitionId; + Batch storage batch = state.batches[slot]; + uint24 tid = batch.verifiedTransitionId; bytes32 blockHash = state.transitions[slot][tid].blockHash; SyncBatch memory synced; @@ -460,7 +466,7 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { for (++batchId; batchId < stopBlockId; ++batchId) { slot = batchId % _config.batchRingBufferSize; - blk = state.batches[slot]; + batch = state.batches[slot]; // FIX Transition storage ts = state.transitions[slot][1]; @@ -481,7 +487,7 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { synced.stateRoot = ts.stateRoot; } - for (uint24 i = 2; i < blk.nextTransitionId; ++i) { + for (uint24 i = 2; i < batch.nextTransitionId; ++i) { ts = state.transitions[slot][i]; delete state.transitionIds[batchId][ts.parentHash]; } @@ -494,15 +500,15 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { if (_stats2.lastVerifiedBatch != batchId) { _stats2.lastVerifiedBatch = batchId; - blk = state.batches[_stats2.lastVerifiedBatch % _config.batchRingBufferSize]; - blk.verifiedTransitionId = tid; + batch = state.batches[_stats2.lastVerifiedBatch % _config.batchRingBufferSize]; + batch.verifiedTransitionId = tid; emit BatchesVerified(_stats2.lastVerifiedBatch, blockHash); if (synced.batchId != 0) { if (synced.batchId != _stats2.lastVerifiedBatch) { // We write the synced batch's verifiedTransitionId to storage - blk = state.batches[synced.batchId % _config.batchRingBufferSize]; - blk.verifiedTransitionId = synced.tid; + batch = state.batches[synced.batchId % _config.batchRingBufferSize]; + batch.verifiedTransitionId = synced.tid; } Stats1 memory stats1 = state.stats1; @@ -557,11 +563,11 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { emit BondDeposited(_user, _amount); } - function _validateBlockParams( + function _validateBatchParams( BatchParams calldata _params, uint64 _maxAnchorHeightOffset, uint8 _maxSignalsToReceive, - Batch memory _parent + Batch memory _parentBatch ) private view @@ -577,7 +583,8 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { ); require(_params.anchorBlockId < block.number, AnchorBlockIdTooLarge()); require( - _params.anchorBlockId >= _parent.anchorBlockId, AnchorBlockIdSmallerThanParent() + _params.anchorBlockId >= _parentBatch.anchorBlockId, + AnchorBlockIdSmallerThanParent() ); updatedParams_.anchorBlockId = _params.anchorBlockId; } @@ -593,7 +600,7 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { TimestampTooSmall() ); require(_params.timestamp <= block.timestamp, TimestampTooLarge()); - require(_params.timestamp >= _parent.timestamp, TimestampSmallerThanParent()); + require(_params.timestamp >= _parentBatch.timestamp, TimestampSmallerThanParent()); updatedParams_.timestamp = _params.timestamp; } @@ -601,7 +608,7 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { // Check if parent batch has the right meta hash. This is to allow the proposer to // make sure the batch builds on the expected latest chain state. require( - _params.parentMetaHash == 0 || _params.parentMetaHash == _parent.metaHash, + _params.parentMetaHash == 0 || _params.parentMetaHash == _parentBatch.metaHash, ParentMetaHashMismatch() ); } From 8738c90a2290010aabfb96d367cd648f9465c2fd Mon Sep 17 00:00:00 2001 From: Daniel Wang Date: Fri, 10 Jan 2025 12:13:21 +0800 Subject: [PATCH 10/41] maxBlocksPerBatch: 2048 --- packages/protocol/contracts/layer1/based/ITaikoInbox.sol | 2 ++ packages/protocol/contracts/layer1/based/TaikoInbox.sol | 9 +++++++-- .../protocol/contracts/layer1/devnet/DevnetInbox.sol | 1 + packages/protocol/contracts/layer1/hekla/HeklaInbox.sol | 1 + .../protocol/contracts/layer1/mainnet/MainnetInbox.sol | 1 + 5 files changed, 12 insertions(+), 2 deletions(-) diff --git a/packages/protocol/contracts/layer1/based/ITaikoInbox.sol b/packages/protocol/contracts/layer1/based/ITaikoInbox.sol index 794d5519dcc..325a2e426ed 100644 --- a/packages/protocol/contracts/layer1/based/ITaikoInbox.sol +++ b/packages/protocol/contracts/layer1/based/ITaikoInbox.sol @@ -126,6 +126,8 @@ interface ITaikoInbox { uint16 provingWindow; /// @notice The maximum number of signals to be received by TaikoL2. uint8 maxSignalsToReceive; + /// @notice The maximum number of blocks per batch. + uint16 maxBlocksPerBatch; /// @notice Historical heights of the forks. ForkHeights forkHeights; } diff --git a/packages/protocol/contracts/layer1/based/TaikoInbox.sol b/packages/protocol/contracts/layer1/based/TaikoInbox.sol index 2168b44eb9f..40fbc868fc0 100644 --- a/packages/protocol/contracts/layer1/based/TaikoInbox.sol +++ b/packages/protocol/contracts/layer1/based/TaikoInbox.sol @@ -104,7 +104,11 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { } updatedParams = _validateBatchParams( - _batchParams, config.maxAnchorHeightOffset, config.maxSignalsToReceive, parentBatch + _batchParams, + config.maxAnchorHeightOffset, + config.maxSignalsToReceive, + config.maxBlocksPerBatch, + parentBatch ); // This section constructs the metadata for the proposed batch, which is crucial for @@ -567,6 +571,7 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { BatchParams calldata _params, uint64 _maxAnchorHeightOffset, uint8 _maxSignalsToReceive, + uint16 _maxBlocksPerBatch, Batch memory _parentBatch ) private @@ -625,7 +630,7 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { } require( - _params.blocks.length != 0 && _params.blocks.length <= type(uint8).max, + _params.blocks.length != 0 && _params.blocks.length <= _maxBlocksPerBatch, InvalidSubBlocks() ); } diff --git a/packages/protocol/contracts/layer1/devnet/DevnetInbox.sol b/packages/protocol/contracts/layer1/devnet/DevnetInbox.sol index fbaa7b58c98..d684293cb75 100644 --- a/packages/protocol/contracts/layer1/devnet/DevnetInbox.sol +++ b/packages/protocol/contracts/layer1/devnet/DevnetInbox.sol @@ -27,6 +27,7 @@ contract DevnetInbox is TaikoInbox { }), provingWindow: 2 hours, maxSignalsToReceive: 16, + maxBlocksPerBatch: 2048, forkHeights: ITaikoInbox.ForkHeights({ ontake: 0, pacaya: 0 }) }); } diff --git a/packages/protocol/contracts/layer1/hekla/HeklaInbox.sol b/packages/protocol/contracts/layer1/hekla/HeklaInbox.sol index f66ce4338f7..f9341e454a5 100644 --- a/packages/protocol/contracts/layer1/hekla/HeklaInbox.sol +++ b/packages/protocol/contracts/layer1/hekla/HeklaInbox.sol @@ -28,6 +28,7 @@ contract HeklaInbox is TaikoInbox { }), provingWindow: 2 hours, maxSignalsToReceive: 16, + maxBlocksPerBatch: 2048, forkHeights: ITaikoInbox.ForkHeights({ ontake: 840_512, pacaya: 840_512 * 10 // TODO diff --git a/packages/protocol/contracts/layer1/mainnet/MainnetInbox.sol b/packages/protocol/contracts/layer1/mainnet/MainnetInbox.sol index 29fa046d253..eab0950cadd 100644 --- a/packages/protocol/contracts/layer1/mainnet/MainnetInbox.sol +++ b/packages/protocol/contracts/layer1/mainnet/MainnetInbox.sol @@ -36,6 +36,7 @@ contract MainnetInbox is TaikoInbox { }), provingWindow: 2 hours, maxSignalsToReceive: 16, + maxBlocksPerBatch: 2048, forkHeights: ITaikoInbox.ForkHeights({ ontake: 538_304, pacaya: 538_304 * 10 // TODO From e677c5eb4e7d3b93a661578cecab8002269421fe Mon Sep 17 00:00:00 2001 From: Daniel Wang Date: Fri, 10 Jan 2025 12:16:03 +0800 Subject: [PATCH 11/41] mainnet liveness bond now 1000 TAIKO --- packages/protocol/contracts/layer1/mainnet/MainnetInbox.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/protocol/contracts/layer1/mainnet/MainnetInbox.sol b/packages/protocol/contracts/layer1/mainnet/MainnetInbox.sol index eab0950cadd..358a97b4d6e 100644 --- a/packages/protocol/contracts/layer1/mainnet/MainnetInbox.sol +++ b/packages/protocol/contracts/layer1/mainnet/MainnetInbox.sol @@ -24,7 +24,7 @@ contract MainnetInbox is TaikoInbox { batchRingBufferSize: 360_000, // DO NOT CHANGE!!! maxBatchesTooVerify: 16, blockMaxGasLimit: 240_000_000, - livenessBond: 125e18, // 125 Taiko token + livenessBond: 1000e18, // 1000 Taiko token stateRootSyncInternal: 16, maxAnchorHeightOffset: 64, baseFeeConfig: LibSharedData.BaseFeeConfig({ From 4e705d4d95c66e0a3d0d0cc05dd87145f9c8c250 Mon Sep 17 00:00:00 2001 From: Daniel Wang Date: Fri, 10 Jan 2025 13:06:19 +0800 Subject: [PATCH 12/41] remove difficulty from metadata --- packages/protocol/contracts/layer1/based/ITaikoInbox.sol | 1 - packages/protocol/contracts/layer1/based/TaikoInbox.sol | 2 -- packages/protocol/contracts/layer1/devnet/DevnetInbox.sol | 2 +- packages/protocol/contracts/layer1/hekla/HeklaInbox.sol | 2 +- packages/protocol/contracts/layer1/mainnet/MainnetInbox.sol | 2 +- packages/protocol/contracts/layer1/verifiers/IVerifier.sol | 1 - packages/protocol/test/layer1/verifiers/SP1Verifier.t.sol | 3 --- 7 files changed, 3 insertions(+), 10 deletions(-) diff --git a/packages/protocol/contracts/layer1/based/ITaikoInbox.sol b/packages/protocol/contracts/layer1/based/ITaikoInbox.sol index 325a2e426ed..e8011247c66 100644 --- a/packages/protocol/contracts/layer1/based/ITaikoInbox.sol +++ b/packages/protocol/contracts/layer1/based/ITaikoInbox.sol @@ -35,7 +35,6 @@ interface ITaikoInbox { } struct BatchMetadata { - bytes32 difficulty; bytes32 txListHash; bytes32 extraData; address coinbase; diff --git a/packages/protocol/contracts/layer1/based/TaikoInbox.sol b/packages/protocol/contracts/layer1/based/TaikoInbox.sol index 40fbc868fc0..6e090bf416f 100644 --- a/packages/protocol/contracts/layer1/based/TaikoInbox.sol +++ b/packages/protocol/contracts/layer1/based/TaikoInbox.sol @@ -118,7 +118,6 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { // computation and verification of its integrity through the comparison of the metahash. unchecked { meta_ = BatchMetadata({ - difficulty: keccak256(abi.encode("TAIKO_DIFFICULTY", stats2.numBatches)), txListHash: calldataUsed ? keccak256(_txList) : _calcTxListHash(_batchParams.blobIndices), @@ -207,7 +206,6 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { require(tran.stateRoot != 0, InvalidTransitionStateRoot()); ctxs[i].batchId = meta.batchId; - ctxs[i].difficulty = meta.difficulty; ctxs[i].metaHash = keccak256(abi.encode(meta)); ctxs[i].transition = tran; diff --git a/packages/protocol/contracts/layer1/devnet/DevnetInbox.sol b/packages/protocol/contracts/layer1/devnet/DevnetInbox.sol index d684293cb75..1cc21fddae1 100644 --- a/packages/protocol/contracts/layer1/devnet/DevnetInbox.sol +++ b/packages/protocol/contracts/layer1/devnet/DevnetInbox.sol @@ -27,7 +27,7 @@ contract DevnetInbox is TaikoInbox { }), provingWindow: 2 hours, maxSignalsToReceive: 16, - maxBlocksPerBatch: 2048, + maxBlocksPerBatch: 256, forkHeights: ITaikoInbox.ForkHeights({ ontake: 0, pacaya: 0 }) }); } diff --git a/packages/protocol/contracts/layer1/hekla/HeklaInbox.sol b/packages/protocol/contracts/layer1/hekla/HeklaInbox.sol index f9341e454a5..57a91eed03f 100644 --- a/packages/protocol/contracts/layer1/hekla/HeklaInbox.sol +++ b/packages/protocol/contracts/layer1/hekla/HeklaInbox.sol @@ -28,7 +28,7 @@ contract HeklaInbox is TaikoInbox { }), provingWindow: 2 hours, maxSignalsToReceive: 16, - maxBlocksPerBatch: 2048, + maxBlocksPerBatch: 256, forkHeights: ITaikoInbox.ForkHeights({ ontake: 840_512, pacaya: 840_512 * 10 // TODO diff --git a/packages/protocol/contracts/layer1/mainnet/MainnetInbox.sol b/packages/protocol/contracts/layer1/mainnet/MainnetInbox.sol index 358a97b4d6e..5ae063d3bc2 100644 --- a/packages/protocol/contracts/layer1/mainnet/MainnetInbox.sol +++ b/packages/protocol/contracts/layer1/mainnet/MainnetInbox.sol @@ -36,7 +36,7 @@ contract MainnetInbox is TaikoInbox { }), provingWindow: 2 hours, maxSignalsToReceive: 16, - maxBlocksPerBatch: 2048, + maxBlocksPerBatch: 256, forkHeights: ITaikoInbox.ForkHeights({ ontake: 538_304, pacaya: 538_304 * 10 // TODO diff --git a/packages/protocol/contracts/layer1/verifiers/IVerifier.sol b/packages/protocol/contracts/layer1/verifiers/IVerifier.sol index 74554a7eb8c..b71d5eafa54 100644 --- a/packages/protocol/contracts/layer1/verifiers/IVerifier.sol +++ b/packages/protocol/contracts/layer1/verifiers/IVerifier.sol @@ -9,7 +9,6 @@ import "../based/ITaikoInbox.sol"; interface IVerifier { struct Context { uint64 batchId; - bytes32 difficulty; bytes32 metaHash; ITaikoInbox.Transition transition; } diff --git a/packages/protocol/test/layer1/verifiers/SP1Verifier.t.sol b/packages/protocol/test/layer1/verifiers/SP1Verifier.t.sol index 4d8cc0eae50..207e6972d92 100644 --- a/packages/protocol/test/layer1/verifiers/SP1Verifier.t.sol +++ b/packages/protocol/test/layer1/verifiers/SP1Verifier.t.sol @@ -74,7 +74,6 @@ contract TestSP1Verifier is Layer1Test { IVerifier.Context[] memory ctxs = new IVerifier.Context[](2); ctxs[0] = IVerifier.Context({ batchId: 393_333, - difficulty: 0, // TODO, need a non-zero value. metaHash: 0x207b2833fb6d804612da24d8785b870a19c7a3f25fa4aaeb9799cd442d65b031, transition: ITaikoInbox.Transition({ parentHash: 0xce519622a374dc014c005d7857de26d952751a9067d3e23ffe14da247aa8a399, @@ -84,7 +83,6 @@ contract TestSP1Verifier is Layer1Test { }); ctxs[1] = IVerifier.Context({ batchId: 393_334, - difficulty: 0, // TODO, need a non-zero value. metaHash: 0x946ba1a9c02fc2f01da49e31cb5be83c118193d0389987c6be616ce76426b44d, transition: ITaikoInbox.Transition({ parentHash: 0x941d557653da2214cbf3d30af8d9cadbc7b5f77b6c3e48bca548eba04eb9cd79, @@ -103,7 +101,6 @@ contract TestSP1Verifier is Layer1Test { function _generateTaikoMainnetContext() internal pure returns (IVerifier.Context memory) { return IVerifier.Context({ batchId: 223_248, //from mainnet - difficulty: 0, metaHash: bytes32(0xd7efb262f6f25cc817452a622009a22e5868e53e1f934d899d3ec68d8c4f2c5b), transition: ITaikoInbox.Transition({ parentHash: 0x317de24b32f09629524133334ad552a14e3de603d71a9cf9e88d722809f101b3, From 32f234d3fdfa493cc6d85cd71363f14c12d36bea Mon Sep 17 00:00:00 2001 From: Daniel Wang Date: Fri, 10 Jan 2025 13:45:45 +0800 Subject: [PATCH 13/41] Update InboxTestBase.sol --- .../test/layer1/based/InboxTestBase.sol | 471 +++++++++--------- 1 file changed, 229 insertions(+), 242 deletions(-) diff --git a/packages/protocol/test/layer1/based/InboxTestBase.sol b/packages/protocol/test/layer1/based/InboxTestBase.sol index 6629234a9d1..ceb1bed5b26 100644 --- a/packages/protocol/test/layer1/based/InboxTestBase.sol +++ b/packages/protocol/test/layer1/based/InboxTestBase.sol @@ -1,245 +1,232 @@ // SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.24; -// import "../Layer1Test.sol"; -// import "test/layer1/based/helpers/Verifier_ToggleStub.sol"; - -// abstract contract InboxTestBase is Layer1Test { -// mapping(uint256 => ITaikoInbox.BlockMetadataV3) internal blockMetadatas; -// ITaikoInbox internal inbox; -// TaikoToken internal bondToken; -// SignalService internal signalService; -// uint256 genesisBlockProposedAt; -// uint256 genesisBlockProposedIn; - -// function getConfig() internal view virtual returns (ITaikoInbox.ConfigV3 memory); - -// modifier transactBy(address transactor) override { -// vm.deal(transactor, 100 ether); -// if (bondToken != TaikoToken(address(0))) { -// bondToken.transfer(transactor, 10_000 ether); -// vm.startPrank(transactor); -// bondToken.approve(address(inbox), type(uint256).max); -// } else { -// vm.startPrank(transactor); -// } - -// _; -// vm.stopPrank(); -// } - -// function setUpOnEthereum() internal virtual override { -// genesisBlockProposedAt = block.timestamp; -// genesisBlockProposedIn = block.number; - -// inbox = deployInbox(correctBlockhash(0), getConfig()); - -// signalService = deploySignalService(address(new SignalService())); -// signalService.authorize(address(inbox), true); - -// resolver.registerAddress( -// block.chainid, "proof_verifier", address(new Verifier_ToggleStub()) -// ); - -// mineOneBlockAndWrap(12 seconds); -// } - -// modifier WhenLogAllBlocksAndTransitions() { -// _logAllBlocksAndTransitions(); -// _; -// } - -// modifier WhenMultipleBlocksAreProposedWithDefaultParameters(uint256 numBlocksToPropose) { -// _proposeBlocksWithDefaultParameters(numBlocksToPropose); -// _; -// } - -// modifier WhenMultipleBlocksAreProvedWithWrongTransitions( -// uint64 startBlockId, -// uint64 endBlockId -// ) { -// _proveBlocksWithWrongTransitions(range(startBlockId, endBlockId)); -// _; -// } - -// modifier WhenMultipleBlocksAreProvedWithCorrectTransitions( -// uint64 startBlockId, -// uint64 endBlockId -// ) { -// _proveBlocksWithCorrectTransitions(range(startBlockId, endBlockId)); -// _; -// } - -// // internal helper functions -// ------------------------------------------------------------------- - -// function _proposeBlocksWithDefaultParameters(uint256 numBlocksToPropose) -// internal -// returns (uint64[] memory blockIds) -// { -// // Provide a default value for txList -// bytes memory defaultTxList = abi.encodePacked("txList"); -// return _proposeBlocksWithDefaultParameters(numBlocksToPropose, defaultTxList); -// } - -// function _proposeBlocksWithDefaultParameters( -// uint256 numBlocksToPropose, -// bytes memory txList -// ) -// internal -// returns (uint64[] memory blockIds) -// { -// ITaikoInbox.BlockParamsV3[] memory blockParams = -// new ITaikoInbox.BlockParamsV3[](numBlocksToPropose); - -// ITaikoInbox.BlockMetadataV3[] memory metas = -// inbox.proposeBlocksV3(address(0), address(0), blockParams, txList); - -// // Initialize blockIds array -// blockIds = new uint64[](metas.length); -// for (uint256 i; i < metas.length; ++i) { -// blockMetadatas[metas[i].blockId] = metas[i]; -// blockIds[i] = metas[i].blockId; -// } -// } - -// function _proveBlocksWithCorrectTransitions(uint64[] memory blockIds) internal { -// ITaikoInbox.BlockMetadataV3[] memory metas = -// new ITaikoInbox.BlockMetadataV3[](blockIds.length); -// ITaikoInbox.TransitionV3[] memory transitions = -// new ITaikoInbox.TransitionV3[](blockIds.length); - -// for (uint256 i; i < metas.length; ++i) { -// metas[i] = blockMetadatas[blockIds[i]]; -// transitions[i].parentHash = correctBlockhash(blockIds[i] - 1); -// transitions[i].blockHash = correctBlockhash(blockIds[i]); -// transitions[i].stateRoot = correctStateRoot(blockIds[i]); -// } - -// inbox.proveBlocksV3(metas, transitions, "proof"); -// } - -// function _proveBlocksWithWrongTransitions(uint64[] memory blockIds) internal { -// ITaikoInbox.BlockMetadataV3[] memory metas = -// new ITaikoInbox.BlockMetadataV3[](blockIds.length); -// ITaikoInbox.TransitionV3[] memory transitions = -// new ITaikoInbox.TransitionV3[](blockIds.length); - -// for (uint256 i; i < metas.length; ++i) { -// metas[i] = blockMetadatas[blockIds[i]]; -// transitions[i].parentHash = randBytes32(); -// transitions[i].blockHash = randBytes32(); -// transitions[i].stateRoot = randBytes32(); -// } - -// inbox.proveBlocksV3(metas, transitions, "proof"); -// } - -// function _logAllBlocksAndTransitions() internal view { -// console2.log(unicode"|───────────────────────────────────────────────────────────────"); -// ITaikoInbox.Stats1 memory stats1 = inbox.getStats1(); -// console2.log("Stats1 - lastSyncedBlockId:", stats1.lastSyncedBlockId); -// console2.log("Stats1 - lastSyncedAt:", stats1.lastSyncedAt); - -// ITaikoInbox.Stats2 memory stats2 = inbox.getStats2(); -// console2.log("Stats2 - numBlocks:", stats2.numBlocks); -// console2.log("Stats2 - lastVerifiedBlockId:", stats2.lastVerifiedBlockId); -// console2.log("Stats2 - paused:", stats2.paused); -// console2.log("Stats2 - lastProposedIn:", stats2.lastProposedIn); -// console2.log("Stats2 - lastUnpausedAt:", stats2.lastUnpausedAt); - -// // console2.log("stats2.numBlocks:", stats2.numBlocks); -// // console2.log("getConfig().blockRingBufferSize:", getConfig().blockRingBufferSize); - -// uint64 firstBlockId = stats2.numBlocks > getConfig().blockRingBufferSize -// ? stats2.numBlocks - getConfig().blockRingBufferSize -// : 0; - -// for (uint64 i = firstBlockId; i < stats2.numBlocks; ++i) { -// ITaikoInbox.BlockV3 memory blk = inbox.getBlockV3(i); -// if (blk.blockId <= stats2.lastVerifiedBlockId) { -// console2.log(unicode"|─ ✔ block#", blk.blockId); -// } else { -// console2.log(unicode"|─── block#", blk.blockId); -// } -// console2.log(unicode"│ |── metahash:", -// Strings.toHexString(uint256(blk.metaHash))); -// console2.log(unicode"│ |── timestamp:", blk.timestamp); -// console2.log(unicode"│ |── anchorBlockId:", blk.anchorBlockId); -// console2.log(unicode"│ |── nextTransitionId:", blk.nextTransitionId); -// console2.log(unicode"│ |── verifiedTransitionId:", blk.verifiedTransitionId); - -// for (uint24 j = 1; j < blk.nextTransitionId; ++j) { -// ITaikoInbox.TransitionV3 memory tran = inbox.getTransitionV3(blk.blockId, j); -// console2.log(unicode"│ |── transition#", j); -// console2.log( -// unicode"│ │ |── parentHash:", -// Strings.toHexString(uint256(tran.parentHash)) -// ); -// console2.log( -// unicode"│ │ |── blockHash:", -// Strings.toHexString(uint256(tran.blockHash)) -// ); -// console2.log( -// unicode"│ │ └── stateRoot:", -// Strings.toHexString(uint256(tran.stateRoot)) -// ); -// } -// } -// console2.log(""); -// } - -// function correctBlockhash(uint256 blockId) internal pure returns (bytes32) { -// return bytes32(0x1000000 + blockId); -// } - -// function correctStateRoot(uint256 blockId) internal pure returns (bytes32) { -// return bytes32(0x2000000 + blockId); -// } - -// function range(uint64 start, uint64 end) internal pure returns (uint64[] memory arr) { -// arr = new uint64[](end - start); -// for (uint64 i; i < arr.length; ++i) { -// arr[i] = start + i; -// } -// } - -// function mintEther(address to, uint256 amountEth) internal { -// vm.deal(to, amountEth); -// console2.log("Ether balance:", to, to.balance); -// } - -// function mintTaikoToken(address to, uint256 amountTko) internal { -// bondToken.transfer(to, amountTko); - -// vm.prank(to); -// bondToken.approve(address(inbox), amountTko); - -// console2.log("Bond balance :", to, bondToken.balanceOf(to)); -// } - -// function setupBondTokenState( -// address user, -// uint256 initialBondBalance, -// uint256 bondAmount -// ) -// internal -// { -// vm.deal(user, 1000 ether); -// bondToken.transfer(user, initialBondBalance); - -// vm.prank(user); -// bondToken.approve(address(inbox), bondAmount); - -// vm.prank(user); -// inbox.depositBond(bondAmount); -// } - -// function simulateBlockDelay(uint256 secondsPerBlock, uint256 blocksToWait) internal { -// uint256 targetBlock = block.number + blocksToWait; -// uint256 targetTime = block.timestamp + (blocksToWait * secondsPerBlock); - -// vm.roll(targetBlock); -// vm.warp(targetTime); -// } -// } +import "../Layer1Test.sol"; +import "test/layer1/based/helpers/Verifier_ToggleStub.sol"; + +abstract contract InboxTestBase is Layer1Test { + mapping(uint256 => ITaikoInbox.BatchMetadata) internal batchMetadatas; + ITaikoInbox internal inbox; + TaikoToken internal bondToken; + SignalService internal signalService; + uint256 genesisBlockProposedAt; + uint256 genesisBlockProposedIn; + + function getConfig() internal view virtual returns (ITaikoInbox.Config memory); + + modifier transactBy(address transactor) override { + vm.deal(transactor, 100 ether); + if (bondToken != TaikoToken(address(0))) { + bondToken.transfer(transactor, 10_000 ether); + vm.startPrank(transactor); + bondToken.approve(address(inbox), type(uint256).max); + } else { + vm.startPrank(transactor); + } + + _; + vm.stopPrank(); + } + + function setUpOnEthereum() internal virtual override { + genesisBlockProposedAt = block.timestamp; + genesisBlockProposedIn = block.number; + + signalService = deploySignalService(address(new SignalService())); + signalService.authorize(address(inbox), true); + + resolver.registerAddress( + block.chainid, "proof_verifier", address(new Verifier_ToggleStub()) + ); + + mineOneBlockAndWrap(12 seconds); + } + + modifier WhenLogAllBlocksAndTransitions() { + _logAllBlocksAndTransitions(); + _; + } + + modifier WhenMultipleBlocksAreProposedWithDefaultParameters(uint256 numBlocksToPropose) { + _proposeBlocksWithDefaultParameters(numBlocksToPropose); + _; + } + + modifier WhenMultipleBatchesAreProvedWithWrongTransitions( + uint64 startBatchId, + uint64 endBatchId + ) { + _proveBatchesWithWrongTransitions(range(startBatchId, endBatchId)); + _; + } + + modifier WhenMultipleBatchesAreProvedWithCorrectTransitions( + uint64 startBatchId, + uint64 endBatchId + ) { + _proveBatchesWithCorrectTransitions(range(startBatchId, endBatchId)); + _; + } + + // internal helper functions + // ------------------------------------------------------------------- + + function _proposeBlocksWithDefaultParameters(uint256 numBlocksToPropose) + internal + returns (uint64 batchId) + { + // Provide a default value for txList + bytes memory defaultTxList = abi.encodePacked("txList"); + return _proposeBatchWithDefaultParameters(numBlocksToPropose, defaultTxList); + } + + function _proposeBatchWithDefaultParameters( + uint256 numBlocksToPropose, + bytes memory txList + ) + internal + returns (uint64 batchId) + { + ITaikoInbox.BatchParams memory batchParams; + + ITaikoInbox.BatchMetadata memory meta = + inbox.proposeBatch(address(0), address(0), batchParams, txList); + + return meta.batchId; + } + + function _proveBatchesWithCorrectTransitions(uint64[] memory batchIds) internal { + ITaikoInbox.BatchMetadata[] memory metas = new ITaikoInbox.BatchMetadata[](batchIds.length); + ITaikoInbox.Transition[] memory transitions = new ITaikoInbox.Transition[](batchIds.length); + + for (uint256 i; i < metas.length; ++i) { + metas[i] = batchMetadatas[batchIds[i]]; + transitions[i].parentHash = correctBlockhash(batchIds[i] - 1); + transitions[i].blockHash = correctBlockhash(batchIds[i]); + transitions[i].stateRoot = correctStateRoot(batchIds[i]); + } + + inbox.proveBatches(metas, transitions, "proof"); + } + + function _proveBatchesWithWrongTransitions(uint64[] memory batchIds) internal { + ITaikoInbox.BatchMetadata[] memory metas = new ITaikoInbox.BatchMetadata[](batchIds.length); + ITaikoInbox.Transition[] memory transitions = new ITaikoInbox.Transition[](batchIds.length); + + for (uint256 i; i < metas.length; ++i) { + metas[i] = batchMetadatas[batchIds[i]]; + transitions[i].parentHash = randBytes32(); + transitions[i].blockHash = randBytes32(); + transitions[i].stateRoot = randBytes32(); + } + + inbox.proveBatches(metas, transitions, "proof"); + } + + function _logAllBlocksAndTransitions() internal view { + console2.log(unicode"|───────────────────────────────────────────────────────────────"); + ITaikoInbox.Stats1 memory stats1 = inbox.getStats1(); + console2.log("Stats1 - lastSyncedBatch:", stats1.lastSyncedBatch); + console2.log("Stats1 - lastSyncedAt:", stats1.lastSyncedAt); + + ITaikoInbox.Stats2 memory stats2 = inbox.getStats2(); + console2.log("Stats2 - numBatches:", stats2.numBatches); + console2.log("Stats2 - lastVerifiedBatch:", stats2.lastVerifiedBatch); + console2.log("Stats2 - paused:", stats2.paused); + console2.log("Stats2 - lastProposedIn:", stats2.lastProposedIn); + console2.log("Stats2 - lastUnpausedAt:", stats2.lastUnpausedAt); + + // console2.log("stats2.numBlocks:", stats2.numBlocks); + // console2.log("getConfig().blockRingBufferSize:", getConfig().blockRingBufferSize); + + uint64 firstBatchId = stats2.numBatches > getConfig().maxBatchProposals + ? stats2.numBatches - getConfig().maxBatchProposals + : 0; + + for (uint64 i = firstBatchId; i < stats2.numBatches; ++i) { + ITaikoInbox.Batch memory batch = inbox.getBatch(i); + if (batch.batchId <= stats2.lastVerifiedBatch) { + console2.log(unicode"|─ ✔ batch#", batch.batchId); + } else { + console2.log(unicode"|─── batch#", batch.batchId); + } + console2.log(unicode"│ |── metahash:", Strings.toHexString(uint256(batch.metaHash))); + console2.log(unicode"│ |── timestamp:", batch.timestamp); + console2.log(unicode"│ |── anchorBlockId:", batch.anchorBlockId); + console2.log(unicode"│ |── nextTransitionId:", batch.nextTransitionId); + console2.log(unicode"│ |── verifiedTransitionId:", batch.verifiedTransitionId); + + for (uint24 j = 1; j < batch.nextTransitionId; ++j) { + ITaikoInbox.Transition memory tran = inbox.getTransition(batch.batchId, j); + console2.log(unicode"│ |── transition#", j); + console2.log( + unicode"│ │ |── parentHash:", + Strings.toHexString(uint256(tran.parentHash)) + ); + console2.log( + unicode"│ │ |── blockHash:", + Strings.toHexString(uint256(tran.blockHash)) + ); + console2.log( + unicode"│ │ └── stateRoot:", + Strings.toHexString(uint256(tran.stateRoot)) + ); + } + } + console2.log(""); + } + + function correctBlockhash(uint256 blockId) internal pure returns (bytes32) { + return bytes32(0x1000000 + blockId); + } + + function correctStateRoot(uint256 blockId) internal pure returns (bytes32) { + return bytes32(0x2000000 + blockId); + } + + function range(uint64 start, uint64 end) internal pure returns (uint64[] memory arr) { + arr = new uint64[](end - start); + for (uint64 i; i < arr.length; ++i) { + arr[i] = start + i; + } + } + + function mintEther(address to, uint256 amountEth) internal { + vm.deal(to, amountEth); + console2.log("Ether balance:", to, to.balance); + } + + function mintTaikoToken(address to, uint256 amountTko) internal { + bondToken.transfer(to, amountTko); + + vm.prank(to); + bondToken.approve(address(inbox), amountTko); + + console2.log("Bond balance :", to, bondToken.balanceOf(to)); + } + + function setupBondTokenState( + address user, + uint256 initialBondBalance, + uint256 bondAmount + ) + internal + { + vm.deal(user, 1000 ether); + bondToken.transfer(user, initialBondBalance); + + vm.prank(user); + bondToken.approve(address(inbox), bondAmount); + + vm.prank(user); + inbox.depositBond(bondAmount); + } + + function simulateBlockDelay(uint256 secondsPerBlock, uint256 blocksToWait) internal { + uint256 targetBlock = block.number + blocksToWait; + uint256 targetTime = block.timestamp + (blocksToWait * secondsPerBlock); + + vm.roll(targetBlock); + vm.warp(targetTime); + } +} From 955eb15f828dfdd60e469136338832c0285fd583 Mon Sep 17 00:00:00 2001 From: Daniel Wang Date: Fri, 10 Jan 2025 13:59:54 +0800 Subject: [PATCH 14/41] more --- .../contracts/layer1/based/ITaikoInbox.sol | 2 +- .../contracts/layer1/based/TaikoInbox.sol | 5 +- .../contracts/layer1/devnet/DevnetInbox.sol | 2 +- .../contracts/layer1/hekla/HeklaInbox.sol | 2 +- .../contracts/layer1/mainnet/MainnetInbox.sol | 2 +- .../layer1/based/InBoxTest_BlockParams.t.sol | 356 +++++++++--------- .../tokenunlock/TokenUnlock_ProverSet.t.sol | 2 +- 7 files changed, 193 insertions(+), 178 deletions(-) diff --git a/packages/protocol/contracts/layer1/based/ITaikoInbox.sol b/packages/protocol/contracts/layer1/based/ITaikoInbox.sol index e8011247c66..7b49aa18ac5 100644 --- a/packages/protocol/contracts/layer1/based/ITaikoInbox.sol +++ b/packages/protocol/contracts/layer1/based/ITaikoInbox.sol @@ -110,7 +110,7 @@ interface ITaikoInbox { /// @notice Size of the batch ring buffer, allowing extra space for proposals. uint64 batchRingBufferSize; /// @notice The maximum number of verifications allowed when a batch is proposed or proved. - uint64 maxBatchesTooVerify; + uint64 maxBatchesToVerify; /// @notice The maximum gas limit allowed for a block. uint32 blockMaxGasLimit; /// @notice The amount of Taiko token as a prover liveness bond. diff --git a/packages/protocol/contracts/layer1/based/TaikoInbox.sol b/packages/protocol/contracts/layer1/based/TaikoInbox.sol index 6e090bf416f..c01575e6129 100644 --- a/packages/protocol/contracts/layer1/based/TaikoInbox.sol +++ b/packages/protocol/contracts/layer1/based/TaikoInbox.sol @@ -463,8 +463,9 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { SyncBatch memory synced; - uint256 stopBlockId = (_config.maxBatchesTooVerify * _length + _stats2.lastVerifiedBatch) - .min(_stats2.numBatches); + uint256 stopBlockId = (_config.maxBatchesToVerify * _length + _stats2.lastVerifiedBatch).min( + _stats2.numBatches + ); for (++batchId; batchId < stopBlockId; ++batchId) { slot = batchId % _config.batchRingBufferSize; diff --git a/packages/protocol/contracts/layer1/devnet/DevnetInbox.sol b/packages/protocol/contracts/layer1/devnet/DevnetInbox.sol index 1cc21fddae1..b33e991e93e 100644 --- a/packages/protocol/contracts/layer1/devnet/DevnetInbox.sol +++ b/packages/protocol/contracts/layer1/devnet/DevnetInbox.sol @@ -13,7 +13,7 @@ contract DevnetInbox is TaikoInbox { chainId: 167_001, maxBatchProposals: 324_000, batchRingBufferSize: 360_000, - maxBatchesTooVerify: 16, + maxBatchesToVerify: 16, blockMaxGasLimit: 240_000_000, livenessBond: 125e18, // 125 Taiko token stateRootSyncInternal: 16, diff --git a/packages/protocol/contracts/layer1/hekla/HeklaInbox.sol b/packages/protocol/contracts/layer1/hekla/HeklaInbox.sol index 57a91eed03f..99111757927 100644 --- a/packages/protocol/contracts/layer1/hekla/HeklaInbox.sol +++ b/packages/protocol/contracts/layer1/hekla/HeklaInbox.sol @@ -14,7 +14,7 @@ contract HeklaInbox is TaikoInbox { maxBatchProposals: 324_000, // Never change this value as ring buffer is being reused!!! batchRingBufferSize: 324_512, - maxBatchesTooVerify: 16, + maxBatchesToVerify: 16, blockMaxGasLimit: 240_000_000, livenessBond: 125e18, // 125 Taiko token stateRootSyncInternal: 16, diff --git a/packages/protocol/contracts/layer1/mainnet/MainnetInbox.sol b/packages/protocol/contracts/layer1/mainnet/MainnetInbox.sol index 5ae063d3bc2..2e95ccddcc2 100644 --- a/packages/protocol/contracts/layer1/mainnet/MainnetInbox.sol +++ b/packages/protocol/contracts/layer1/mainnet/MainnetInbox.sol @@ -22,7 +22,7 @@ contract MainnetInbox is TaikoInbox { // configuration values must NEVER be changed!!! maxBatchProposals: 324_000, // DO NOT CHANGE!!! batchRingBufferSize: 360_000, // DO NOT CHANGE!!! - maxBatchesTooVerify: 16, + maxBatchesToVerify: 16, blockMaxGasLimit: 240_000_000, livenessBond: 1000e18, // 1000 Taiko token stateRootSyncInternal: 16, diff --git a/packages/protocol/test/layer1/based/InBoxTest_BlockParams.t.sol b/packages/protocol/test/layer1/based/InBoxTest_BlockParams.t.sol index 63773cc4bfa..12abd4442d4 100644 --- a/packages/protocol/test/layer1/based/InBoxTest_BlockParams.t.sol +++ b/packages/protocol/test/layer1/based/InBoxTest_BlockParams.t.sol @@ -1,174 +1,188 @@ // SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.24; -// import "./InboxTestBase.sol"; - -// contract InBoxTest_BlockParams is InboxTestBase { -// function getConfig() internal pure override returns (ITaikoInbox.ConfigV3 memory) { -// return ITaikoInbox.ConfigV3({ -// chainId: LibNetwork.TAIKO_MAINNET, -// blockMaxProposals: 10, -// blockRingBufferSize: 15, -// maxBlocksToVerify: 5, -// blockMaxGasLimit: 240_000_000, -// livenessBond: 125e18, // 125 Taiko token -// stateRootSyncInternal: 5, -// maxAnchorHeightOffset: 64, -// baseFeeConfig: LibSharedData.BaseFeeConfig({ -// adjustmentQuotient: 8, -// sharingPctg: 75, -// gasIssuancePerSecond: 5_000_000, -// minGasExcess: 1_340_000_000, // correspond to 0.008847185 gwei basefee -// maxGasIssuancePerBlock: 600_000_000 // two minutes: 5_000_000 * 120 -// }), -// provingWindow: 1 hours, -// maxSignalsToReceive: 16, -// forkHeights: ITaikoInbox.ForkHeights({ ontake: 0, pacaya: 0 }) -// }); -// } - -// function setUpOnEthereum() internal override { -// super.setUpOnEthereum(); -// bondToken = deployBondToken(); -// } - -// function test_validateBlockParams_defaults_when_anchorBlockId_is_zero() -// external -// transactBy(Alice) -// { -// ITaikoInbox.BlockParamsV3[] memory paramsArray = new ITaikoInbox.BlockParamsV3[](1); -// paramsArray[0] = ITaikoInbox.BlockParamsV3({ -// anchorBlockId: 0, // Simulate missing anchor block ID -// timestamp: 0, -// parentMetaHash: 0, -// signalSlots: new bytes32[](0), -// blobIndex: 0, -// txListOffset: 0, -// txListSize: 0, -// anchorInput: bytes32(0) -// }); - -// ITaikoInbox.BlockMetadataV3[] memory metas = -// inbox.proposeBlocksV3(address(0), address(0), paramsArray, "txList"); - -// // Assert that the default anchorBlockId was set correctly -// uint64 expectedAnchorBlockId = uint64(block.number - 1); -// assertEq(metas[0].anchorBlockId, expectedAnchorBlockId, "AnchorBlockId mismatch"); -// } - -// function test_validateBlockParams_reverts_when_anchorBlockId_too_small() -// external -// transactBy(Alice) -// { -// ITaikoInbox.ConfigV3 memory config = inbox.getConfigV3(); - -// // Advance the block number to create the appropriate test scenario -// vm.roll(config.maxAnchorHeightOffset + 2); - -// // Calculate an invalid anchorBlockId (too small) -// uint64 anchorBlockId = uint64(block.number - config.maxAnchorHeightOffset - 1); - -// ITaikoInbox.BlockParamsV3[] memory paramsArray = new ITaikoInbox.BlockParamsV3[](1); -// paramsArray[0] = ITaikoInbox.BlockParamsV3({ -// anchorBlockId: anchorBlockId, -// timestamp: 0, -// parentMetaHash: 0, -// signalSlots: new bytes32[](0), -// blobIndex: 0, -// txListOffset: 0, -// txListSize: 0, -// anchorInput: bytes32(0) -// }); - -// vm.expectRevert(ITaikoInbox.AnchorBlockIdTooSmall.selector); -// inbox.proposeBlocksV3(address(0), address(0), paramsArray, "txList"); -// } - -// function test_validateBlockParams_reverts_when_anchorBlockId_too_large() -// external -// transactBy(Alice) -// { -// // Calculate an invalid anchorBlockId (too large) -// uint64 anchorBlockId = uint64(block.number); - -// ITaikoInbox.BlockParamsV3[] memory paramsArray = new ITaikoInbox.BlockParamsV3[](1); -// paramsArray[0] = ITaikoInbox.BlockParamsV3({ -// anchorBlockId: anchorBlockId, -// timestamp: 0, -// parentMetaHash: 0, -// signalSlots: new bytes32[](0), -// blobIndex: 0, -// txListOffset: 0, -// txListSize: 0, -// anchorInput: bytes32(0) -// }); - -// vm.expectRevert(ITaikoInbox.AnchorBlockIdTooLarge.selector); -// inbox.proposeBlocksV3(address(0), address(0), paramsArray, "txList"); -// } - -// function test_validateBlockParams_reverts_when_anchorBlockId_smaller_than_parent() -// external -// transactBy(Alice) -// { -// vm.roll(10); -// _proposeBlocksWithDefaultParameters(1); -// ITaikoInbox.BlockV3 memory parent = inbox.getBlockV3(1); - -// ITaikoInbox.BlockParamsV3[] memory paramsArray = new ITaikoInbox.BlockParamsV3[](1); -// paramsArray[0] = ITaikoInbox.BlockParamsV3({ -// anchorBlockId: parent.anchorBlockId - 1, -// timestamp: 0, -// parentMetaHash: 0, -// signalSlots: new bytes32[](0), -// blobIndex: 0, -// txListOffset: 0, -// txListSize: 0, -// anchorInput: bytes32(0) -// }); - -// vm.expectRevert(ITaikoInbox.AnchorBlockIdSmallerThanParent.selector); -// inbox.proposeBlocksV3(address(0), address(0), paramsArray, "txList"); -// } - -// function test_validateBlockParams_when_anchorBlockId_is_not_zero() external transactBy(Alice) -// { -// ITaikoInbox.BlockParamsV3[] memory paramsArray = new ITaikoInbox.BlockParamsV3[](1); -// paramsArray[0] = ITaikoInbox.BlockParamsV3({ -// anchorBlockId: uint64(block.number - 1), -// timestamp: 0, -// parentMetaHash: 0, -// signalSlots: new bytes32[](0), -// blobIndex: 0, -// txListOffset: 0, -// txListSize: 0, -// anchorInput: bytes32(0) -// }); - -// ITaikoInbox.BlockMetadataV3[] memory metas = -// inbox.proposeBlocksV3(address(0), address(0), paramsArray, "txList"); - -// uint64 expectedAnchorBlockId = uint64(block.number - 1); -// assertEq(metas[0].anchorBlockId, expectedAnchorBlockId, "AnchorBlockId mismatch"); -// } - -// function test_validateBlockParams_reverts_when_timestamp_too_large() -// external -// transactBy(Alice) -// { -// ITaikoInbox.BlockParamsV3[] memory paramsArray = new ITaikoInbox.BlockParamsV3[](1); -// paramsArray[0] = ITaikoInbox.BlockParamsV3({ -// anchorBlockId: 0, -// timestamp: uint64(block.timestamp + 1), -// parentMetaHash: 0, -// signalSlots: new bytes32[](0), -// blobIndex: 0, -// txListOffset: 0, -// txListSize: 0, -// anchorInput: bytes32(0) -// }); - -// vm.expectRevert(ITaikoInbox.TimestampTooLarge.selector); -// inbox.proposeBlocksV3(address(0), address(0), paramsArray, "txList"); -// } -// } +import "./InboxTestBase.sol"; + +contract InBoxTest_BlockParams is InboxTestBase { + function getConfig() internal pure override returns (ITaikoInbox.Config memory) { + return ITaikoInbox.Config({ + chainId: LibNetwork.TAIKO_MAINNET, + maxBatchProposals: 10, + batchRingBufferSize: 15, + maxBatchesToVerify: 5, + blockMaxGasLimit: 240_000_000, + livenessBond: 125e18, // 125 Taiko token + stateRootSyncInternal: 5, + maxAnchorHeightOffset: 64, + baseFeeConfig: LibSharedData.BaseFeeConfig({ + adjustmentQuotient: 8, + sharingPctg: 75, + gasIssuancePerSecond: 5_000_000, + minGasExcess: 1_340_000_000, // correspond to 0.008847185 gwei basefee + maxGasIssuancePerBlock: 600_000_000 // two minutes: 5_000_000 * 120 + }), + provingWindow: 1 hours, + maxSignalsToReceive: 16, + maxBlocksPerBatch: 256, + forkHeights: ITaikoInbox.ForkHeights({ ontake: 0, pacaya: 0 }) + }); + } + + function setUpOnEthereum() internal override { + super.setUpOnEthereum(); + bondToken = deployBondToken(); + } + + function test_validateBlockParams_defaults_when_anchorBlockId_is_zero() + external + transactBy(Alice) + { + ITaikoInbox.BlockParams[] memory blocks = new ITaikoInbox.BlockParams[](1); + blocks[0] = ITaikoInbox.BlockParams({ numTransactions: 0, timeThift: 0 }); + + ITaikoInbox.BatchParams memory params = ITaikoInbox.BatchParams({ + anchorBlockId: 0, // Simulate missing anchor block ID + timestamp: 0, + parentMetaHash: 0, + signalSlots: new bytes32[](0), + blobIndices: new uint8[](0), + txListOffset: 0, + txListSize: 0, + anchorInput: bytes32(0), + blocks: blocks + }); + + ITaikoInbox.BatchMetadata memory meta = + inbox.proposeBatch(address(0), address(0), params, "txList"); + + // Assert that the default anchorBlockId was set correctly + uint64 expectedAnchorBlockId = uint64(block.number - 1); + assertEq(meta.anchorBlockId, expectedAnchorBlockId, "AnchorBlockId mismatch"); + } + + function test_validateBlockParams_reverts_when_anchorBlockId_too_small() + external + transactBy(Alice) + { + ITaikoInbox.Config memory config = inbox.getConfig(); + + // Advance the block number to create the appropriate test scenario + vm.roll(config.maxAnchorHeightOffset + 2); + + // Calculate an invalid anchorBlockId (too small) + uint64 anchorBlockId = uint64(block.number - config.maxAnchorHeightOffset - 1); + + ITaikoInbox.BlockParams[] memory blocks = new ITaikoInbox.BlockParams[](1); + blocks[0] = ITaikoInbox.BlockParams({ numTransactions: 0, timeThift: 0 }); + ITaikoInbox.BatchParams memory params = ITaikoInbox.BatchParams({ + anchorBlockId: anchorBlockId, + timestamp: 0, + parentMetaHash: 0, + signalSlots: new bytes32[](0), + blobIndices: new uint8[](0), + txListOffset: 0, + txListSize: 0, + anchorInput: bytes32(0), + blocks: blocks + }); + + vm.expectRevert(ITaikoInbox.AnchorBlockIdTooSmall.selector); + inbox.proposeBatch(address(0), address(0), params, "txList"); + } + + function test_validateBlockParams_reverts_when_anchorBlockId_too_large() + external + transactBy(Alice) + { + // Calculate an invalid anchorBlockId (too large) + uint64 anchorBlockId = uint64(block.number); + + ITaikoInbox.BlockParams[] memory blocks = new ITaikoInbox.BlockParams[](1); + blocks[0] = ITaikoInbox.BlockParams({ numTransactions: 0, timeThift: 0 }); + + ITaikoInbox.BatchParams memory params = ITaikoInbox.BatchParams({ + anchorBlockId: anchorBlockId, + timestamp: 0, + parentMetaHash: 0, + signalSlots: new bytes32[](0), + blobIndices: new uint8[](0), + txListOffset: 0, + txListSize: 0, + anchorInput: bytes32(0), + blocks: blocks + }); + + vm.expectRevert(ITaikoInbox.AnchorBlockIdTooLarge.selector); + inbox.proposeBatch(address(0), address(0), params, "txList"); + } + + function test_validateBlockParams_reverts_when_anchorBlockId_smaller_than_parent() + external + transactBy(Alice) + { + vm.roll(10); + _proposeBlocksWithDefaultParameters(1); + ITaikoInbox.Batch memory parent = inbox.getBatch(1); + + ITaikoInbox.BlockParams[] memory blocks = new ITaikoInbox.BlockParams[](1); + blocks[0] = ITaikoInbox.BlockParams({ numTransactions: 0, timeThift: 0 }); + ITaikoInbox.BatchParams memory params = ITaikoInbox.BatchParams({ + anchorBlockId: parent.anchorBlockId - 1, + timestamp: 0, + parentMetaHash: 0, + signalSlots: new bytes32[](0), + blobIndices: new uint8[](0), + txListOffset: 0, + txListSize: 0, + anchorInput: bytes32(0), + blocks: blocks + }); + + vm.expectRevert(ITaikoInbox.AnchorBlockIdSmallerThanParent.selector); + inbox.proposeBatch(address(0), address(0), params, "txList"); + } + + function test_validateBlockParams_when_anchorBlockId_is_not_zero() external transactBy(Alice) { + ITaikoInbox.BlockParams[] memory blocks = new ITaikoInbox.BlockParams[](1); + blocks[0] = ITaikoInbox.BlockParams({ numTransactions: 0, timeThift: 0 }); + ITaikoInbox.BatchParams memory params = ITaikoInbox.BatchParams({ + anchorBlockId: uint64(block.number - 1), + timestamp: 0, + parentMetaHash: 0, + signalSlots: new bytes32[](0), + blobIndices: new uint8[](0), + txListOffset: 0, + txListSize: 0, + anchorInput: bytes32(0), + blocks: blocks + }); + + ITaikoInbox.BatchMetadata memory meta = + inbox.proposeBatch(address(0), address(0), params, "txList"); + + uint64 expectedAnchorBlockId = uint64(block.number - 1); + assertEq(meta.anchorBlockId, expectedAnchorBlockId, "AnchorBlockId mismatch"); + } + + function test_validateBlockParams_reverts_when_timestamp_too_large() + external + transactBy(Alice) + { + ITaikoInbox.BlockParams[] memory blocks = new ITaikoInbox.BlockParams[](1); + blocks[0] = ITaikoInbox.BlockParams({ numTransactions: 0, timeThift: 0 }); + ITaikoInbox.BatchParams memory params = ITaikoInbox.BatchParams({ + anchorBlockId: 0, + timestamp: uint64(block.timestamp + 1), + parentMetaHash: 0, + signalSlots: new bytes32[](0), + blobIndices: new uint8[](0), + txListOffset: 0, + txListSize: 0, + anchorInput: bytes32(0), + blocks: blocks + }); + + vm.expectRevert(ITaikoInbox.TimestampTooLarge.selector); + inbox.proposeBatch(address(0), address(0), params, "txList"); + } +} diff --git a/packages/protocol/test/layer1/team/tokenunlock/TokenUnlock_ProverSet.t.sol b/packages/protocol/test/layer1/team/tokenunlock/TokenUnlock_ProverSet.t.sol index f93d1be3734..974379b4d1f 100644 --- a/packages/protocol/test/layer1/team/tokenunlock/TokenUnlock_ProverSet.t.sol +++ b/packages/protocol/test/layer1/team/tokenunlock/TokenUnlock_ProverSet.t.sol @@ -19,7 +19,7 @@ pragma solidity ^0.8.24; // chainId: LibNetwork.TAIKO_MAINNET, // maxBatchProposals: 10, // batchRingBufferSize: 15, -// maxBatchesTooVerify: 5, +// maxBatchesToVerify: 5, // blockMaxGasLimit: 240_000_000, // livenessBond: livenessBond, // 125 Taiko token // stateRootSyncInternal: 5, From bb65e281276cfa7a10884a92023df589edb18f76 Mon Sep 17 00:00:00 2001 From: Daniel Wang Date: Fri, 10 Jan 2025 14:15:59 +0800 Subject: [PATCH 15/41] fix --- .../contracts/layer1/based/ITaikoInbox.sol | 2 +- .../contracts/layer1/based/TaikoInbox.sol | 5 ++++- .../layer1/based/InBoxTest_BlockParams.t.sol | 3 ++- .../test/layer1/based/InboxTestBase.sol | 22 +++++++++++++------ 4 files changed, 22 insertions(+), 10 deletions(-) diff --git a/packages/protocol/contracts/layer1/based/ITaikoInbox.sol b/packages/protocol/contracts/layer1/based/ITaikoInbox.sol index 7b49aa18ac5..dd5b6d290b8 100644 --- a/packages/protocol/contracts/layer1/based/ITaikoInbox.sol +++ b/packages/protocol/contracts/layer1/based/ITaikoInbox.sol @@ -210,9 +210,9 @@ interface ITaikoInbox { error CustomProposerNotAllowed(); error EtherNotPaidAsBond(); error InsufficientBond(); + error InvalidBlockParams(); error InvalidForkHeight(); error InvalidGenesisBlockHash(); - error InvalidSubBlocks(); error InvalidTransitionBlockHash(); error InvalidTransitionParentHash(); error InvalidTransitionStateRoot(); diff --git a/packages/protocol/contracts/layer1/based/TaikoInbox.sol b/packages/protocol/contracts/layer1/based/TaikoInbox.sol index c01575e6129..f5fd5764ce8 100644 --- a/packages/protocol/contracts/layer1/based/TaikoInbox.sol +++ b/packages/protocol/contracts/layer1/based/TaikoInbox.sol @@ -12,6 +12,8 @@ import "src/shared/signal/ISignalService.sol"; import "src/layer1/verifiers/IVerifier.sol"; import "./ITaikoInbox.sol"; +import "forge-std/src/console2.sol"; + /// @title TaikoInbox /// @notice Acts as the inbox for the Taiko Alethia protocol, a simplified version of the /// original Taiko-Based Contestable Rollup (BCR). The tier-based proof system and @@ -628,9 +630,10 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { } } + console2.log("blocks length", _params.blocks.length); require( _params.blocks.length != 0 && _params.blocks.length <= _maxBlocksPerBatch, - InvalidSubBlocks() + InvalidBlockParams() ); } diff --git a/packages/protocol/test/layer1/based/InBoxTest_BlockParams.t.sol b/packages/protocol/test/layer1/based/InBoxTest_BlockParams.t.sol index 12abd4442d4..f4edc1713c1 100644 --- a/packages/protocol/test/layer1/based/InBoxTest_BlockParams.t.sol +++ b/packages/protocol/test/layer1/based/InBoxTest_BlockParams.t.sol @@ -39,7 +39,7 @@ contract InBoxTest_BlockParams is InboxTestBase { { ITaikoInbox.BlockParams[] memory blocks = new ITaikoInbox.BlockParams[](1); blocks[0] = ITaikoInbox.BlockParams({ numTransactions: 0, timeThift: 0 }); - + ITaikoInbox.BatchParams memory params = ITaikoInbox.BatchParams({ anchorBlockId: 0, // Simulate missing anchor block ID timestamp: 0, @@ -126,6 +126,7 @@ contract InBoxTest_BlockParams is InboxTestBase { ITaikoInbox.BlockParams[] memory blocks = new ITaikoInbox.BlockParams[](1); blocks[0] = ITaikoInbox.BlockParams({ numTransactions: 0, timeThift: 0 }); + ITaikoInbox.BatchParams memory params = ITaikoInbox.BatchParams({ anchorBlockId: parent.anchorBlockId - 1, timestamp: 0, diff --git a/packages/protocol/test/layer1/based/InboxTestBase.sol b/packages/protocol/test/layer1/based/InboxTestBase.sol index ceb1bed5b26..882737e2b9b 100644 --- a/packages/protocol/test/layer1/based/InboxTestBase.sol +++ b/packages/protocol/test/layer1/based/InboxTestBase.sol @@ -32,6 +32,8 @@ abstract contract InboxTestBase is Layer1Test { genesisBlockProposedAt = block.timestamp; genesisBlockProposedIn = block.number; + inbox = deployInbox(correctBlockhash(0), getConfig()); + signalService = deploySignalService(address(new SignalService())); signalService.authorize(address(inbox), true); @@ -47,8 +49,8 @@ abstract contract InboxTestBase is Layer1Test { _; } - modifier WhenMultipleBlocksAreProposedWithDefaultParameters(uint256 numBlocksToPropose) { - _proposeBlocksWithDefaultParameters(numBlocksToPropose); + modifier WhenMultipleBlocksAreProposedWithDefaultParameters(uint256 numBatchesToPropose) { + _proposeBlocksWithDefaultParameters(numBatchesToPropose); _; } @@ -71,26 +73,32 @@ abstract contract InboxTestBase is Layer1Test { // internal helper functions // ------------------------------------------------------------------- - function _proposeBlocksWithDefaultParameters(uint256 numBlocksToPropose) + function _proposeBlocksWithDefaultParameters(uint256 numBatchesToPropose) internal returns (uint64 batchId) { // Provide a default value for txList bytes memory defaultTxList = abi.encodePacked("txList"); - return _proposeBatchWithDefaultParameters(numBlocksToPropose, defaultTxList); + + return _proposeBatchWithDefaultParameters( numBatchesToPropose, defaultTxList); } function _proposeBatchWithDefaultParameters( - uint256 numBlocksToPropose, + uint256 numBatchesToPropose, bytes memory txList ) internal returns (uint64 batchId) { ITaikoInbox.BatchParams memory batchParams; + batchParams.blocks = new ITaikoInbox.BlockParams[](1); + batchParams.blocks[0] = ITaikoInbox.BlockParams({ numTransactions: 0, timeThift: 0 }); + + ITaikoInbox.BatchMetadata memory meta; - ITaikoInbox.BatchMetadata memory meta = - inbox.proposeBatch(address(0), address(0), batchParams, txList); + for (uint256 i; i < numBatchesToPropose; ++i) { + meta = inbox.proposeBatch(address(0), address(0), batchParams, txList); + } return meta.batchId; } From ac9f6e379b2091cde84b6e5bef5c4d09c81ef096 Mon Sep 17 00:00:00 2001 From: Daniel Wang Date: Fri, 10 Jan 2025 14:23:54 +0800 Subject: [PATCH 16/41] more --- .../contracts/layer1/based/TaikoInbox.sol | 3 +- .../layer1/based/InBoxTest_BlockParams.t.sol | 4 +- .../test/layer1/based/InboxTestBase.sol | 34 +- .../based/InboxTest_BondMechanics.t.sol | 251 ++++++------ .../test/layer1/based/InboxTest_BondToken.sol | 361 +++++++++--------- 5 files changed, 323 insertions(+), 330 deletions(-) diff --git a/packages/protocol/contracts/layer1/based/TaikoInbox.sol b/packages/protocol/contracts/layer1/based/TaikoInbox.sol index f5fd5764ce8..0c8605225d0 100644 --- a/packages/protocol/contracts/layer1/based/TaikoInbox.sol +++ b/packages/protocol/contracts/layer1/based/TaikoInbox.sol @@ -12,7 +12,7 @@ import "src/shared/signal/ISignalService.sol"; import "src/layer1/verifiers/IVerifier.sol"; import "./ITaikoInbox.sol"; -import "forge-std/src/console2.sol"; +// import "forge-std/src/console2.sol"; /// @title TaikoInbox /// @notice Acts as the inbox for the Taiko Alethia protocol, a simplified version of the @@ -630,7 +630,6 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { } } - console2.log("blocks length", _params.blocks.length); require( _params.blocks.length != 0 && _params.blocks.length <= _maxBlocksPerBatch, InvalidBlockParams() diff --git a/packages/protocol/test/layer1/based/InBoxTest_BlockParams.t.sol b/packages/protocol/test/layer1/based/InBoxTest_BlockParams.t.sol index f4edc1713c1..6817fb914b6 100644 --- a/packages/protocol/test/layer1/based/InBoxTest_BlockParams.t.sol +++ b/packages/protocol/test/layer1/based/InBoxTest_BlockParams.t.sol @@ -121,12 +121,12 @@ contract InBoxTest_BlockParams is InboxTestBase { transactBy(Alice) { vm.roll(10); - _proposeBlocksWithDefaultParameters(1); + _proposeBatchesWithDefaultParameters(1); ITaikoInbox.Batch memory parent = inbox.getBatch(1); ITaikoInbox.BlockParams[] memory blocks = new ITaikoInbox.BlockParams[](1); blocks[0] = ITaikoInbox.BlockParams({ numTransactions: 0, timeThift: 0 }); - + ITaikoInbox.BatchParams memory params = ITaikoInbox.BatchParams({ anchorBlockId: parent.anchorBlockId - 1, timestamp: 0, diff --git a/packages/protocol/test/layer1/based/InboxTestBase.sol b/packages/protocol/test/layer1/based/InboxTestBase.sol index 882737e2b9b..aa8642af68e 100644 --- a/packages/protocol/test/layer1/based/InboxTestBase.sol +++ b/packages/protocol/test/layer1/based/InboxTestBase.sol @@ -44,13 +44,13 @@ abstract contract InboxTestBase is Layer1Test { mineOneBlockAndWrap(12 seconds); } - modifier WhenLogAllBlocksAndTransitions() { - _logAllBlocksAndTransitions(); + modifier WhenLogAllBatchesAndTransitions() { + _logAllBatchesAndTransitions(); _; } - modifier WhenMultipleBlocksAreProposedWithDefaultParameters(uint256 numBatchesToPropose) { - _proposeBlocksWithDefaultParameters(numBatchesToPropose); + modifier WhenMultipleBatchesAreProposedWithDefaultParameters(uint256 numBatchesToPropose) { + _proposeBatchesWithDefaultParameters(numBatchesToPropose); _; } @@ -73,34 +73,30 @@ abstract contract InboxTestBase is Layer1Test { // internal helper functions // ------------------------------------------------------------------- - function _proposeBlocksWithDefaultParameters(uint256 numBatchesToPropose) + function _proposeBatchesWithDefaultParameters(uint256 numBatchesToPropose) internal - returns (uint64 batchId) + returns (uint64[] memory batchIds) { - // Provide a default value for txList - bytes memory defaultTxList = abi.encodePacked("txList"); - - return _proposeBatchWithDefaultParameters( numBatchesToPropose, defaultTxList); + return _proposeBatchesWithDefaultParameters(numBatchesToPropose, abi.encodePacked("txList")); } - function _proposeBatchWithDefaultParameters( + function _proposeBatchesWithDefaultParameters( uint256 numBatchesToPropose, bytes memory txList ) internal - returns (uint64 batchId) + returns (uint64[] memory batchIds) { ITaikoInbox.BatchParams memory batchParams; batchParams.blocks = new ITaikoInbox.BlockParams[](1); batchParams.blocks[0] = ITaikoInbox.BlockParams({ numTransactions: 0, timeThift: 0 }); - ITaikoInbox.BatchMetadata memory meta; + batchIds = new uint64[](numBatchesToPropose); for (uint256 i; i < numBatchesToPropose; ++i) { - meta = inbox.proposeBatch(address(0), address(0), batchParams, txList); + ITaikoInbox.BatchMetadata memory meta = inbox.proposeBatch(address(0), address(0), batchParams, txList); + batchIds[i] = meta.batchId; } - - return meta.batchId; } function _proveBatchesWithCorrectTransitions(uint64[] memory batchIds) internal { @@ -131,7 +127,7 @@ abstract contract InboxTestBase is Layer1Test { inbox.proveBatches(metas, transitions, "proof"); } - function _logAllBlocksAndTransitions() internal view { + function _logAllBatchesAndTransitions() internal view { console2.log(unicode"|───────────────────────────────────────────────────────────────"); ITaikoInbox.Stats1 memory stats1 = inbox.getStats1(); console2.log("Stats1 - lastSyncedBatch:", stats1.lastSyncedBatch); @@ -144,8 +140,8 @@ abstract contract InboxTestBase is Layer1Test { console2.log("Stats2 - lastProposedIn:", stats2.lastProposedIn); console2.log("Stats2 - lastUnpausedAt:", stats2.lastUnpausedAt); - // console2.log("stats2.numBlocks:", stats2.numBlocks); - // console2.log("getConfig().blockRingBufferSize:", getConfig().blockRingBufferSize); + // console2.log("stats2.numBatches:", stats2.numBatches); + // console2.log("getConfig().maxBatchProposals:", getConfig().maxBatchProposals); uint64 firstBatchId = stats2.numBatches > getConfig().maxBatchProposals ? stats2.numBatches - getConfig().maxBatchProposals diff --git a/packages/protocol/test/layer1/based/InboxTest_BondMechanics.t.sol b/packages/protocol/test/layer1/based/InboxTest_BondMechanics.t.sol index 987e1083ab6..8cbf94225ec 100644 --- a/packages/protocol/test/layer1/based/InboxTest_BondMechanics.t.sol +++ b/packages/protocol/test/layer1/based/InboxTest_BondMechanics.t.sol @@ -1,135 +1,132 @@ // SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.24; -// import "contracts/layer1/based/ITaikoInbox.sol"; -// import "./InboxTestBase.sol"; - -// contract InboxTest_BondMechanics is InboxTestBase { -// uint16 constant provingWindow = 1 hours; - -// function getConfig() internal pure override returns (ITaikoInbox.ConfigV3 memory) { -// return ITaikoInbox.ConfigV3({ -// chainId: LibNetwork.TAIKO_MAINNET, -// blockMaxProposals: 10, -// blockRingBufferSize: 15, -// maxBlocksToVerify: 5, -// blockMaxGasLimit: 240_000_000, -// livenessBond: 125e18, // 125 Taiko token -// stateRootSyncInternal: 5, -// maxAnchorHeightOffset: 64, -// baseFeeConfig: LibSharedData.BaseFeeConfig({ -// adjustmentQuotient: 8, -// sharingPctg: 75, -// gasIssuancePerSecond: 5_000_000, -// minGasExcess: 1_340_000_000, // correspond to 0.008847185 gwei basefee -// maxGasIssuancePerBlock: 600_000_000 // two minutes: 5_000_000 * 120 -// }), -// provingWindow: provingWindow, -// maxSignalsToReceive: 16, -// forkHeights: ITaikoInbox.ForkHeights({ ontake: 0, pacaya: 0 }) -// }); -// } - -// function setUpOnEthereum() internal override { -// super.setUpOnEthereum(); -// bondToken = deployBondToken(); -// } - -// function test_inbox_bonds_debit_and_credit_on_proposal_and_proof() external { -// vm.warp(1_000_000); - -// uint256 initialBondBalance = 100_000 ether; -// uint256 bondAmount = 1000 ether; - -// setupBondTokenState(Alice, initialBondBalance, bondAmount); - -// vm.prank(Alice); -// uint64[] memory blockIds = _proposeBlocksWithDefaultParameters({ numBlocksToPropose: 1 -// }); -// assertEq(inbox.bondBalanceOf(Alice) < bondAmount, true); - -// vm.prank(Alice); -// _proveBlocksWithCorrectTransitions(blockIds); - -// assertEq(inbox.bondBalanceOf(Alice), bondAmount); -// } - -// function test_only_proposer_can_prove_block_before_deadline() external { -// vm.warp(1_000_000); - -// uint256 initialBondBalance = 100_000 ether; -// uint256 bondAmount = 1000 ether; - -// setupBondTokenState(Alice, initialBondBalance, bondAmount); -// setupBondTokenState(Bob, initialBondBalance, bondAmount); - -// vm.prank(Alice); -// uint64[] memory blockIds = _proposeBlocksWithDefaultParameters({ numBlocksToPropose: 1 -// }); -// assertEq(inbox.bondBalanceOf(Alice) < bondAmount, true); - -// vm.prank(Bob); -// vm.expectRevert(ITaikoInbox.ProverNotPermitted.selector); -// _proveBlocksWithCorrectTransitions(blockIds); - -// assertEq(inbox.bondBalanceOf(Bob), bondAmount); -// } - -// function test_inbox_bonds_debited_on_proposal_not_credited_back_if_proved_after_deadline() -// external -// { -// vm.warp(1_000_000); - -// uint256 initialBondBalance = 100_000 ether; -// uint256 bondAmount = 1000 ether; - -// setupBondTokenState(Alice, initialBondBalance, bondAmount); - -// vm.prank(Alice); -// uint64[] memory blockIds = _proposeBlocksWithDefaultParameters({ numBlocksToPropose: 1 -// }); - -// uint256 aliceBondBalanceAfterProposal = inbox.bondBalanceOf(Alice); -// assertEq(aliceBondBalanceAfterProposal < bondAmount, true); - -// // Simulate waiting for blocks after proving deadline -// uint256 secondsPerBlock = 12; -// uint256 blocksToWait = provingWindow / secondsPerBlock + 1; -// simulateBlockDelay(secondsPerBlock, blocksToWait); - -// vm.prank(Alice); -// _proveBlocksWithCorrectTransitions(blockIds); - -// uint256 aliceBondBalanceAfterProof = inbox.bondBalanceOf(Alice); -// assertEq(aliceBondBalanceAfterProof, aliceBondBalanceAfterProposal); -// assertEq(aliceBondBalanceAfterProof < bondAmount, true); -// } - -// function test_inbox_bonds_debit_and_credit_on_proposal_and_proof_with_exact_proving_window() -// external -// { -// vm.warp(1_000_000); - -// uint256 initialBondBalance = 100_000 ether; -// uint256 bondAmount = 1000 ether; - -// setupBondTokenState(Alice, initialBondBalance, bondAmount); +import "contracts/layer1/based/ITaikoInbox.sol"; +import "./InboxTestBase.sol"; + +contract InboxTest_BondMechanics is InboxTestBase { + uint16 constant provingWindow = 1 hours; + + function getConfig() internal pure override returns (ITaikoInbox.Config memory) { + return ITaikoInbox.Config({ + chainId: LibNetwork.TAIKO_MAINNET, + maxBatchProposals: 10, + batchRingBufferSize: 15, + maxBatchesToVerify: 5, + blockMaxGasLimit: 240_000_000, + livenessBond: 125e18, // 125 Taiko token + stateRootSyncInternal: 5, + maxAnchorHeightOffset: 64, + baseFeeConfig: LibSharedData.BaseFeeConfig({ + adjustmentQuotient: 8, + sharingPctg: 75, + gasIssuancePerSecond: 5_000_000, + minGasExcess: 1_340_000_000, // correspond to 0.008847185 gwei basefee + maxGasIssuancePerBlock: 600_000_000 // two minutes: 5_000_000 * 120 + }), + provingWindow: 1 hours, + maxSignalsToReceive: 16, + maxBlocksPerBatch: 256, + forkHeights: ITaikoInbox.ForkHeights({ ontake: 0, pacaya: 0 }) + }); + } + + function setUpOnEthereum() internal override { + super.setUpOnEthereum(); + bondToken = deployBondToken(); + } + + function test_inbox_bonds_debit_and_credit_on_proposal_and_proof() external { + vm.warp(1_000_000); + + uint256 initialBondBalance = 100_000 ether; + uint256 bondAmount = 1000 ether; + + setupBondTokenState(Alice, initialBondBalance, bondAmount); + + vm.prank(Alice); + uint64[] memory batchIds = _proposeBatchesWithDefaultParameters(1); + assertEq(inbox.bondBalanceOf(Alice) < bondAmount, true); + + vm.prank(Alice); + _proveBatchesWithCorrectTransitions(batchIds); + + assertEq(inbox.bondBalanceOf(Alice), bondAmount); + } + + function test_only_proposer_can_prove_block_before_deadline() external { + vm.warp(1_000_000); + + uint256 initialBondBalance = 100_000 ether; + uint256 bondAmount = 1000 ether; + + setupBondTokenState(Alice, initialBondBalance, bondAmount); + setupBondTokenState(Bob, initialBondBalance, bondAmount); + + vm.prank(Alice); + uint64[] memory batchIds = _proposeBatchesWithDefaultParameters(1); + assertEq(inbox.bondBalanceOf(Alice) < bondAmount, true); + + vm.prank(Bob); + vm.expectRevert(ITaikoInbox.ProverNotPermitted.selector); + _proveBatchesWithCorrectTransitions(batchIds); + + assertEq(inbox.bondBalanceOf(Bob), bondAmount); + } + + function test_inbox_bonds_debited_on_proposal_not_credited_back_if_proved_after_deadline() + external + { + vm.warp(1_000_000); + + uint256 initialBondBalance = 100_000 ether; + uint256 bondAmount = 1000 ether; + + setupBondTokenState(Alice, initialBondBalance, bondAmount); + + vm.prank(Alice); + uint64[] memory batchIds = _proposeBatchesWithDefaultParameters(1); + + uint256 aliceBondBalanceAfterProposal = inbox.bondBalanceOf(Alice); + assertEq(aliceBondBalanceAfterProposal < bondAmount, true); + + // Simulate waiting for blocks after proving deadline + uint256 secondsPerBlock = 12; + uint256 blocksToWait = provingWindow / secondsPerBlock + 1; + simulateBlockDelay(secondsPerBlock, blocksToWait); + + vm.prank(Alice); + _proveBatchesWithCorrectTransitions(batchIds); + + uint256 aliceBondBalanceAfterProof = inbox.bondBalanceOf(Alice); + assertEq(aliceBondBalanceAfterProof, aliceBondBalanceAfterProposal); + assertEq(aliceBondBalanceAfterProof < bondAmount, true); + } + + function test_inbox_bonds_debit_and_credit_on_proposal_and_proof_with_exact_proving_window() + external + { + vm.warp(1_000_000); + + uint256 initialBondBalance = 100_000 ether; + uint256 bondAmount = 1000 ether; + + setupBondTokenState(Alice, initialBondBalance, bondAmount); -// vm.prank(Alice); -// uint64[] memory blockIds = _proposeBlocksWithDefaultParameters({ numBlocksToPropose: 1 -// }); + vm.prank(Alice); + uint64[] memory batchIds = _proposeBatchesWithDefaultParameters( 1); -// uint256 aliceBondBalanceAfterProposal = inbox.bondBalanceOf(Alice); -// assertEq(aliceBondBalanceAfterProposal < bondAmount, true); + uint256 aliceBondBalanceAfterProposal = inbox.bondBalanceOf(Alice); + assertEq(aliceBondBalanceAfterProposal < bondAmount, true); -// // Simulate waiting for exactly the proving window -// uint256 secondsPerBlock = 12; -// uint256 blocksToWait = provingWindow / secondsPerBlock; -// simulateBlockDelay(secondsPerBlock, blocksToWait); + // Simulate waiting for exactly the proving window + uint256 secondsPerBlock = 12; + uint256 blocksToWait = provingWindow / secondsPerBlock; + simulateBlockDelay(secondsPerBlock, blocksToWait); -// vm.prank(Alice); -// _proveBlocksWithCorrectTransitions(blockIds); + vm.prank(Alice); + _proveBatchesWithCorrectTransitions(batchIds); -// assertEq(inbox.bondBalanceOf(Alice), bondAmount); -// } -// } + assertEq(inbox.bondBalanceOf(Alice), bondAmount); + } +} diff --git a/packages/protocol/test/layer1/based/InboxTest_BondToken.sol b/packages/protocol/test/layer1/based/InboxTest_BondToken.sol index aa7849a82b7..d1970705dd4 100644 --- a/packages/protocol/test/layer1/based/InboxTest_BondToken.sol +++ b/packages/protocol/test/layer1/based/InboxTest_BondToken.sol @@ -1,200 +1,201 @@ // SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.24; -// import "contracts/layer1/based/ITaikoInbox.sol"; -// import "./InboxTestBase.sol"; - -// contract InboxTest_BondToken is InboxTestBase { -// function getConfig() internal pure override returns (ITaikoInbox.ConfigV3 memory) { -// return ITaikoInbox.ConfigV3({ -// chainId: LibNetwork.TAIKO_MAINNET, -// blockMaxProposals: 10, -// blockRingBufferSize: 15, -// maxBlocksToVerify: 5, -// blockMaxGasLimit: 240_000_000, -// livenessBond: 125e18, // 125 Taiko token -// stateRootSyncInternal: 5, -// maxAnchorHeightOffset: 64, -// baseFeeConfig: LibSharedData.BaseFeeConfig({ -// adjustmentQuotient: 8, -// sharingPctg: 75, -// gasIssuancePerSecond: 5_000_000, -// minGasExcess: 1_340_000_000, // correspond to 0.008847185 gwei basefee -// maxGasIssuancePerBlock: 600_000_000 // two minutes: 5_000_000 * 120 -// }), -// provingWindow: 1 hours, -// maxSignalsToReceive: 16, -// forkHeights: ITaikoInbox.ForkHeights({ ontake: 0, pacaya: 0 }) -// }); -// } - -// function setUpOnEthereum() internal override { -// super.setUpOnEthereum(); -// bondToken = deployBondToken(); -// } - -// function test_inbox_deposit_withdraw() external { -// vm.warp(1_000_000); -// vm.deal(Alice, 1000 ether); - -// uint256 transferAmount = 1234 ether; -// bondToken.transfer(Alice, transferAmount); -// assertEq(bondToken.balanceOf(Alice), transferAmount); - -// uint256 depositAmount = 1 ether; -// uint256 withdrawAmount = 0.5 ether; - -// vm.prank(Alice); -// bondToken.approve(address(inbox), depositAmount); - -// vm.prank(Alice); -// inbox.depositBond(depositAmount); -// assertEq(inbox.bondBalanceOf(Alice), depositAmount); - -// vm.prank(Alice); -// inbox.withdrawBond(withdrawAmount); -// assertEq(inbox.bondBalanceOf(Alice), depositAmount - withdrawAmount); -// } - -// function test_inbox_withdraw_more_than_bond_balance() external { -// vm.warp(1_000_000); -// vm.deal(Alice, 1000 ether); - -// uint256 transferAmount = 10 ether; -// uint256 depositAmount = 1 ether; -// uint256 withdrawAmount = 2 ether; - -// bondToken.transfer(Alice, transferAmount); - -// vm.prank(Alice); -// bondToken.approve(address(inbox), depositAmount); - -// vm.prank(Alice); -// inbox.depositBond(depositAmount); - -// vm.prank(Alice); -// vm.expectRevert(ITaikoInbox.InsufficientBond.selector); -// inbox.withdrawBond(withdrawAmount); -// } - -// function test_inbox_insufficient_approval() external { -// vm.warp(1_000_000); -// vm.deal(Alice, 1000 ether); - -// uint256 transferAmount = 10 ether; -// uint256 insufficientApproval = 5 ether; -// uint256 depositAmount = 10 ether; - -// bondToken.transfer(Alice, transferAmount); - -// vm.prank(Alice); -// bondToken.approve(address(inbox), insufficientApproval); - -// vm.prank(Alice); -// vm.expectRevert("ERC20: insufficient allowance"); -// inbox.depositBond(depositAmount); -// } - -// function test_inbox_exceeding_balance() external { -// vm.warp(1_000_000); -// vm.deal(Alice, 1000 ether); - -// uint256 transferAmount = 10 ether; -// uint256 depositAmount = 12 ether; - -// bondToken.transfer(Alice, transferAmount); - -// vm.prank(Alice); -// bondToken.approve(address(inbox), depositAmount); - -// vm.prank(Alice); -// vm.expectRevert("ERC20: transfer amount exceeds balance"); -// inbox.depositBond(depositAmount); -// } - -// function test_inbox_no_value_sent_on_deposit() external { -// vm.warp(1_000_000); -// vm.deal(Alice, 1000 ether); - -// uint256 transferAmount = 10 ether; -// uint256 depositAmount = 1 ether; - -// bondToken.transfer(Alice, transferAmount); +import "contracts/layer1/based/ITaikoInbox.sol"; +import "./InboxTestBase.sol"; + +contract InboxTest_BondToken is InboxTestBase { + function getConfig() internal pure override returns (ITaikoInbox.Config memory) { + return ITaikoInbox.Config({ + chainId: LibNetwork.TAIKO_MAINNET, + maxBatchProposals: 10, + batchRingBufferSize: 15, + maxBatchesToVerify: 5, + blockMaxGasLimit: 240_000_000, + livenessBond: 125e18, // 125 Taiko token + stateRootSyncInternal: 5, + maxAnchorHeightOffset: 64, + baseFeeConfig: LibSharedData.BaseFeeConfig({ + adjustmentQuotient: 8, + sharingPctg: 75, + gasIssuancePerSecond: 5_000_000, + minGasExcess: 1_340_000_000, // correspond to 0.008847185 gwei basefee + maxGasIssuancePerBlock: 600_000_000 // two minutes: 5_000_000 * 120 + }), + provingWindow: 1 hours, + maxSignalsToReceive: 16, + maxBlocksPerBatch: 256, + forkHeights: ITaikoInbox.ForkHeights({ ontake: 0, pacaya: 0 }) + }); + } + + function setUpOnEthereum() internal override { + super.setUpOnEthereum(); + bondToken = deployBondToken(); + } + + function test_inbox_deposit_withdraw() external { + vm.warp(1_000_000); + vm.deal(Alice, 1000 ether); + + uint256 transferAmount = 1234 ether; + bondToken.transfer(Alice, transferAmount); + assertEq(bondToken.balanceOf(Alice), transferAmount); + + uint256 depositAmount = 1 ether; + uint256 withdrawAmount = 0.5 ether; + + vm.prank(Alice); + bondToken.approve(address(inbox), depositAmount); + + vm.prank(Alice); + inbox.depositBond(depositAmount); + assertEq(inbox.bondBalanceOf(Alice), depositAmount); + + vm.prank(Alice); + inbox.withdrawBond(withdrawAmount); + assertEq(inbox.bondBalanceOf(Alice), depositAmount - withdrawAmount); + } + + function test_inbox_withdraw_more_than_bond_balance() external { + vm.warp(1_000_000); + vm.deal(Alice, 1000 ether); + + uint256 transferAmount = 10 ether; + uint256 depositAmount = 1 ether; + uint256 withdrawAmount = 2 ether; + + bondToken.transfer(Alice, transferAmount); + + vm.prank(Alice); + bondToken.approve(address(inbox), depositAmount); + + vm.prank(Alice); + inbox.depositBond(depositAmount); + + vm.prank(Alice); + vm.expectRevert(ITaikoInbox.InsufficientBond.selector); + inbox.withdrawBond(withdrawAmount); + } + + function test_inbox_insufficient_approval() external { + vm.warp(1_000_000); + vm.deal(Alice, 1000 ether); + + uint256 transferAmount = 10 ether; + uint256 insufficientApproval = 5 ether; + uint256 depositAmount = 10 ether; + + bondToken.transfer(Alice, transferAmount); + + vm.prank(Alice); + bondToken.approve(address(inbox), insufficientApproval); + + vm.prank(Alice); + vm.expectRevert("ERC20: insufficient allowance"); + inbox.depositBond(depositAmount); + } + + function test_inbox_exceeding_balance() external { + vm.warp(1_000_000); + vm.deal(Alice, 1000 ether); + + uint256 transferAmount = 10 ether; + uint256 depositAmount = 12 ether; + + bondToken.transfer(Alice, transferAmount); + + vm.prank(Alice); + bondToken.approve(address(inbox), depositAmount); + + vm.prank(Alice); + vm.expectRevert("ERC20: transfer amount exceeds balance"); + inbox.depositBond(depositAmount); + } + + function test_inbox_no_value_sent_on_deposit() external { + vm.warp(1_000_000); + vm.deal(Alice, 1000 ether); + + uint256 transferAmount = 10 ether; + uint256 depositAmount = 1 ether; + + bondToken.transfer(Alice, transferAmount); -// vm.prank(Alice); -// bondToken.approve(address(inbox), depositAmount); + vm.prank(Alice); + bondToken.approve(address(inbox), depositAmount); -// vm.prank(Alice); -// vm.expectRevert(ITaikoInbox.MsgValueNotZero.selector); -// inbox.depositBond{ value: 1 }(depositAmount); -// } + vm.prank(Alice); + vm.expectRevert(ITaikoInbox.MsgValueNotZero.selector); + inbox.depositBond{ value: 1 }(depositAmount); + } -// function test_inbox_deposit_and_withdraw_from_multiple_users() external { -// vm.warp(1_000_000); -// vm.deal(Alice, 1000 ether); -// vm.deal(Bob, 50 ether); + function test_inbox_deposit_and_withdraw_from_multiple_users() external { + vm.warp(1_000_000); + vm.deal(Alice, 1000 ether); + vm.deal(Bob, 50 ether); -// uint256 transferAmountAlice = 20 ether; -// uint256 transferAmountBob = 10 ether; + uint256 transferAmountAlice = 20 ether; + uint256 transferAmountBob = 10 ether; -// // Transfer bond tokens to Alice and Bob -// bondToken.transfer(Alice, transferAmountAlice); -// assertEq(bondToken.balanceOf(Alice), transferAmountAlice); + // Transfer bond tokens to Alice and Bob + bondToken.transfer(Alice, transferAmountAlice); + assertEq(bondToken.balanceOf(Alice), transferAmountAlice); -// bondToken.transfer(Bob, transferAmountBob); -// assertEq(bondToken.balanceOf(Bob), transferAmountBob); + bondToken.transfer(Bob, transferAmountBob); + assertEq(bondToken.balanceOf(Bob), transferAmountBob); -// uint256 aliceFirstDeposit = 2 ether; -// uint256 aliceSecondDeposit = 3 ether; -// uint256 aliceFirstWithdraw = 1 ether; -// uint256 aliceSecondWithdraw = 1.5 ether; + uint256 aliceFirstDeposit = 2 ether; + uint256 aliceSecondDeposit = 3 ether; + uint256 aliceFirstWithdraw = 1 ether; + uint256 aliceSecondWithdraw = 1.5 ether; -// uint256 bobDeposit = 5 ether; -// uint256 bobWithdraw = 2 ether; + uint256 bobDeposit = 5 ether; + uint256 bobWithdraw = 2 ether; -// vm.prank(Alice); -// bondToken.approve(address(inbox), aliceFirstDeposit); + vm.prank(Alice); + bondToken.approve(address(inbox), aliceFirstDeposit); -// vm.prank(Alice); -// inbox.depositBond(aliceFirstDeposit); -// assertEq(inbox.bondBalanceOf(Alice), aliceFirstDeposit); + vm.prank(Alice); + inbox.depositBond(aliceFirstDeposit); + assertEq(inbox.bondBalanceOf(Alice), aliceFirstDeposit); -// vm.prank(Bob); -// bondToken.approve(address(inbox), bobDeposit); + vm.prank(Bob); + bondToken.approve(address(inbox), bobDeposit); -// vm.prank(Bob); -// inbox.depositBond(bobDeposit); -// assertEq(inbox.bondBalanceOf(Bob), bobDeposit); + vm.prank(Bob); + inbox.depositBond(bobDeposit); + assertEq(inbox.bondBalanceOf(Bob), bobDeposit); -// vm.prank(Alice); -// bondToken.approve(address(inbox), aliceSecondDeposit); + vm.prank(Alice); + bondToken.approve(address(inbox), aliceSecondDeposit); -// vm.prank(Alice); -// inbox.depositBond(aliceSecondDeposit); -// assertEq(inbox.bondBalanceOf(Alice), aliceFirstDeposit + aliceSecondDeposit); + vm.prank(Alice); + inbox.depositBond(aliceSecondDeposit); + assertEq(inbox.bondBalanceOf(Alice), aliceFirstDeposit + aliceSecondDeposit); -// vm.prank(Bob); -// inbox.withdrawBond(bobWithdraw); -// assertEq(inbox.bondBalanceOf(Bob), bobDeposit - bobWithdraw); + vm.prank(Bob); + inbox.withdrawBond(bobWithdraw); + assertEq(inbox.bondBalanceOf(Bob), bobDeposit - bobWithdraw); -// vm.prank(Alice); -// inbox.withdrawBond(aliceFirstWithdraw); -// assertEq( -// inbox.bondBalanceOf(Alice), aliceFirstDeposit + aliceSecondDeposit - -// aliceFirstWithdraw -// ); + vm.prank(Alice); + inbox.withdrawBond(aliceFirstWithdraw); + assertEq( + inbox.bondBalanceOf(Alice), aliceFirstDeposit + aliceSecondDeposit - +aliceFirstWithdraw + ); -// vm.prank(Alice); -// inbox.withdrawBond(aliceSecondWithdraw); -// assertEq( -// inbox.bondBalanceOf(Alice), -// aliceFirstDeposit + aliceSecondDeposit - aliceFirstWithdraw - aliceSecondWithdraw -// ); - -// assertEq( -// inbox.bondBalanceOf(Alice), -// aliceFirstDeposit + aliceSecondDeposit - aliceFirstWithdraw - aliceSecondWithdraw -// ); -// assertEq(inbox.bondBalanceOf(Bob), bobDeposit - bobWithdraw); -// } -// } + vm.prank(Alice); + inbox.withdrawBond(aliceSecondWithdraw); + assertEq( + inbox.bondBalanceOf(Alice), + aliceFirstDeposit + aliceSecondDeposit - aliceFirstWithdraw - aliceSecondWithdraw + ); + + assertEq( + inbox.bondBalanceOf(Alice), + aliceFirstDeposit + aliceSecondDeposit - aliceFirstWithdraw - aliceSecondWithdraw + ); + assertEq(inbox.bondBalanceOf(Bob), bobDeposit - bobWithdraw); + } +} From 870a3469469be5dc138afb49c22fb958f8de538e Mon Sep 17 00:00:00 2001 From: Daniel Wang Date: Fri, 10 Jan 2025 14:37:05 +0800 Subject: [PATCH 17/41] fix --- packages/protocol/contracts/layer1/based/ITaikoInbox.sol | 2 +- packages/protocol/contracts/layer1/based/TaikoInbox.sol | 2 +- packages/protocol/test/layer1/based/InboxTestBase.sol | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/protocol/contracts/layer1/based/ITaikoInbox.sol b/packages/protocol/contracts/layer1/based/ITaikoInbox.sol index dd5b6d290b8..a1369094d26 100644 --- a/packages/protocol/contracts/layer1/based/ITaikoInbox.sol +++ b/packages/protocol/contracts/layer1/based/ITaikoInbox.sol @@ -52,7 +52,7 @@ interface ITaikoInbox { uint64 anchorBlockId; bytes32 anchorBlockHash; bytes32[] signalSlots; - BlockParams[] blocks; + bytes blocks; bytes32 anchorInput; LibSharedData.BaseFeeConfig baseFeeConfig; } diff --git a/packages/protocol/contracts/layer1/based/TaikoInbox.sol b/packages/protocol/contracts/layer1/based/TaikoInbox.sol index 0c8605225d0..c17b08c3e21 100644 --- a/packages/protocol/contracts/layer1/based/TaikoInbox.sol +++ b/packages/protocol/contracts/layer1/based/TaikoInbox.sol @@ -139,7 +139,7 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { anchorBlockId: updatedParams.anchorBlockId, anchorBlockHash: blockhash(updatedParams.anchorBlockId), signalSlots: _batchParams.signalSlots, - blocks: _batchParams.blocks, + blocks: abi.encode(_batchParams.blocks), anchorInput: _batchParams.anchorInput, baseFeeConfig: config.baseFeeConfig }); diff --git a/packages/protocol/test/layer1/based/InboxTestBase.sol b/packages/protocol/test/layer1/based/InboxTestBase.sol index aa8642af68e..8c1ecfa3669 100644 --- a/packages/protocol/test/layer1/based/InboxTestBase.sol +++ b/packages/protocol/test/layer1/based/InboxTestBase.sol @@ -95,6 +95,7 @@ abstract contract InboxTestBase is Layer1Test { for (uint256 i; i < numBatchesToPropose; ++i) { ITaikoInbox.BatchMetadata memory meta = inbox.proposeBatch(address(0), address(0), batchParams, txList); + batchMetadatas[meta.batchId] = meta; batchIds[i] = meta.batchId; } } From 0e8cbe0d95bd0770cd6ec70036c51a8aa1138657 Mon Sep 17 00:00:00 2001 From: Daniel Wang Date: Fri, 10 Jan 2025 15:34:22 +0800 Subject: [PATCH 18/41] blobIndices to numBlobs --- .../contracts/layer1/based/ITaikoInbox.sol | 8 +++---- .../contracts/layer1/based/TaikoInbox.sol | 21 ++++++---------- packages/protocol/test/layer1/Layer1Test.sol | 2 +- .../layer1/based/InBoxTest_BlockParams.t.sol | 12 +++++----- .../test/layer1/based/InboxTestBase.sol | 5 ++-- .../based/InboxTest_BondMechanics.t.sol | 4 ++-- .../test/layer1/based/InboxTest_BondToken.sol | 3 +-- .../based/InboxTest_CalldataForTxList.t.sol | 2 +- .../layer2/token/BridgedTaikoToken.t.sol | 4 ++-- .../test/shared/tokenvault/ERC20Vault.h.sol | 10 ++++---- .../test/shared/tokenvault/ERC20Vault.t.sol | 24 +++++++++---------- 11 files changed, 44 insertions(+), 51 deletions(-) diff --git a/packages/protocol/contracts/layer1/based/ITaikoInbox.sol b/packages/protocol/contracts/layer1/based/ITaikoInbox.sol index a1369094d26..f0855027ab9 100644 --- a/packages/protocol/contracts/layer1/based/ITaikoInbox.sol +++ b/packages/protocol/contracts/layer1/based/ITaikoInbox.sol @@ -29,7 +29,7 @@ interface ITaikoInbox { uint64 timestamp; uint32 txListOffset; uint32 txListSize; - uint8[] blobIndices; + uint8 numBlobs; bytes32[] signalSlots; BlockParams[] blocks; } @@ -48,7 +48,7 @@ interface ITaikoInbox { uint64 proposedIn; // Used by node/client uint32 txListOffset; uint32 txListSize; - uint8[] blobIndices; + uint8 numBlobs; uint64 anchorBlockId; bytes32 anchorBlockHash; bytes32[] signalSlots; @@ -198,13 +198,13 @@ interface ITaikoInbox { event BatchesVerified(uint64 batchId, bytes32 blockHash); error AnchorBlockIdSmallerThanParent(); - error AnchorBlockIdTooSmall(); error AnchorBlockIdTooLarge(); + error AnchorBlockIdTooSmall(); error ArraySizesMismatch(); error BatchNotFound(); error BatchVerified(); - error BlobIndexZero(); error BlobNotFound(); + error BlobNotSpecified(); error ContractPaused(); error CustomProposerMissing(); error CustomProposerNotAllowed(); diff --git a/packages/protocol/contracts/layer1/based/TaikoInbox.sol b/packages/protocol/contracts/layer1/based/TaikoInbox.sol index c17b08c3e21..473d044a7ec 100644 --- a/packages/protocol/contracts/layer1/based/TaikoInbox.sol +++ b/packages/protocol/contracts/layer1/based/TaikoInbox.sol @@ -98,12 +98,7 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { bool calldataUsed = _txList.length != 0; UpdatedParams memory updatedParams; - if (!calldataUsed) { - require(_batchParams.blobIndices.length != 0, BlobIndexZero()); - for (uint256 j; j < _batchParams.blobIndices[j]; ++j) { - require(_batchParams.blobIndices[j] != 0, BlobIndexZero()); - } - } + require(calldataUsed || _batchParams.numBlobs != 0, BlobNotSpecified()); updatedParams = _validateBatchParams( _batchParams, @@ -120,9 +115,7 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { // computation and verification of its integrity through the comparison of the metahash. unchecked { meta_ = BatchMetadata({ - txListHash: calldataUsed - ? keccak256(_txList) - : _calcTxListHash(_batchParams.blobIndices), + txListHash: calldataUsed ? keccak256(_txList) : _calcTxListHash(_batchParams.numBlobs), extraData: bytes32(uint256(config.baseFeeConfig.sharingPctg)), coinbase: _coinbase, batchId: stats2.numBatches, @@ -135,7 +128,7 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { proposedIn: uint64(block.number), txListOffset: _batchParams.txListOffset, txListSize: _batchParams.txListSize, - blobIndices: calldataUsed ? new uint8[](0) : _batchParams.blobIndices, + numBlobs: calldataUsed ? 0 : _batchParams.numBlobs, anchorBlockId: updatedParams.anchorBlockId, anchorBlockHash: blockhash(updatedParams.anchorBlockId), signalSlots: _batchParams.signalSlots, @@ -439,10 +432,10 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { state.stats2.paused = true; } - function _calcTxListHash(uint8[] memory blobIndices) internal view virtual returns (bytes32) { - bytes32[] memory blobHashes = new bytes32[](blobIndices.length); - for (uint256 i; i < blobIndices.length; ++i) { - blobHashes[i] = blobhash(blobIndices[i]); + function _calcTxListHash(uint8 _numBlobs) internal view virtual returns (bytes32) { + bytes32[] memory blobHashes = new bytes32[](_numBlobs); + for (uint256 i; i < _numBlobs; ++i) { + blobHashes[i] = blobhash(i); require(blobHashes[i] != 0, BlobNotFound()); } return keccak256(abi.encode(blobHashes)); diff --git a/packages/protocol/test/layer1/Layer1Test.sol b/packages/protocol/test/layer1/Layer1Test.sol index 9323bd64a4a..29bb3276f47 100644 --- a/packages/protocol/test/layer1/Layer1Test.sol +++ b/packages/protocol/test/layer1/Layer1Test.sol @@ -31,7 +31,7 @@ contract ConfigurableInbox is TaikoInbox { return __config; } - function _calcTxListHash(uint8[] memory) internal pure override returns (bytes32) { + function _calcTxListHash(uint8) internal pure override returns (bytes32) { return keccak256("BLOB"); } } diff --git a/packages/protocol/test/layer1/based/InBoxTest_BlockParams.t.sol b/packages/protocol/test/layer1/based/InBoxTest_BlockParams.t.sol index 6817fb914b6..6d567d176b7 100644 --- a/packages/protocol/test/layer1/based/InBoxTest_BlockParams.t.sol +++ b/packages/protocol/test/layer1/based/InBoxTest_BlockParams.t.sol @@ -45,7 +45,7 @@ contract InBoxTest_BlockParams is InboxTestBase { timestamp: 0, parentMetaHash: 0, signalSlots: new bytes32[](0), - blobIndices: new uint8[](0), + numBlobs: 0, txListOffset: 0, txListSize: 0, anchorInput: bytes32(0), @@ -79,7 +79,7 @@ contract InBoxTest_BlockParams is InboxTestBase { timestamp: 0, parentMetaHash: 0, signalSlots: new bytes32[](0), - blobIndices: new uint8[](0), + numBlobs: 0, txListOffset: 0, txListSize: 0, anchorInput: bytes32(0), @@ -105,7 +105,7 @@ contract InBoxTest_BlockParams is InboxTestBase { timestamp: 0, parentMetaHash: 0, signalSlots: new bytes32[](0), - blobIndices: new uint8[](0), + numBlobs: 0, txListOffset: 0, txListSize: 0, anchorInput: bytes32(0), @@ -132,7 +132,7 @@ contract InBoxTest_BlockParams is InboxTestBase { timestamp: 0, parentMetaHash: 0, signalSlots: new bytes32[](0), - blobIndices: new uint8[](0), + numBlobs: 0, txListOffset: 0, txListSize: 0, anchorInput: bytes32(0), @@ -151,7 +151,7 @@ contract InBoxTest_BlockParams is InboxTestBase { timestamp: 0, parentMetaHash: 0, signalSlots: new bytes32[](0), - blobIndices: new uint8[](0), + numBlobs: 0, txListOffset: 0, txListSize: 0, anchorInput: bytes32(0), @@ -176,7 +176,7 @@ contract InBoxTest_BlockParams is InboxTestBase { timestamp: uint64(block.timestamp + 1), parentMetaHash: 0, signalSlots: new bytes32[](0), - blobIndices: new uint8[](0), + numBlobs: 0, txListOffset: 0, txListSize: 0, anchorInput: bytes32(0), diff --git a/packages/protocol/test/layer1/based/InboxTestBase.sol b/packages/protocol/test/layer1/based/InboxTestBase.sol index 8c1ecfa3669..a4c27768a1f 100644 --- a/packages/protocol/test/layer1/based/InboxTestBase.sol +++ b/packages/protocol/test/layer1/based/InboxTestBase.sol @@ -90,11 +90,12 @@ abstract contract InboxTestBase is Layer1Test { ITaikoInbox.BatchParams memory batchParams; batchParams.blocks = new ITaikoInbox.BlockParams[](1); batchParams.blocks[0] = ITaikoInbox.BlockParams({ numTransactions: 0, timeThift: 0 }); - + batchIds = new uint64[](numBatchesToPropose); for (uint256 i; i < numBatchesToPropose; ++i) { - ITaikoInbox.BatchMetadata memory meta = inbox.proposeBatch(address(0), address(0), batchParams, txList); + ITaikoInbox.BatchMetadata memory meta = + inbox.proposeBatch(address(0), address(0), batchParams, txList); batchMetadatas[meta.batchId] = meta; batchIds[i] = meta.batchId; } diff --git a/packages/protocol/test/layer1/based/InboxTest_BondMechanics.t.sol b/packages/protocol/test/layer1/based/InboxTest_BondMechanics.t.sol index 8cbf94225ec..2f7e089bab2 100644 --- a/packages/protocol/test/layer1/based/InboxTest_BondMechanics.t.sol +++ b/packages/protocol/test/layer1/based/InboxTest_BondMechanics.t.sol @@ -114,7 +114,7 @@ contract InboxTest_BondMechanics is InboxTestBase { setupBondTokenState(Alice, initialBondBalance, bondAmount); vm.prank(Alice); - uint64[] memory batchIds = _proposeBatchesWithDefaultParameters( 1); + uint64[] memory batchIds = _proposeBatchesWithDefaultParameters(1); uint256 aliceBondBalanceAfterProposal = inbox.bondBalanceOf(Alice); assertEq(aliceBondBalanceAfterProposal < bondAmount, true); @@ -125,7 +125,7 @@ contract InboxTest_BondMechanics is InboxTestBase { simulateBlockDelay(secondsPerBlock, blocksToWait); vm.prank(Alice); - _proveBatchesWithCorrectTransitions(batchIds); + _proveBatchesWithCorrectTransitions(batchIds); assertEq(inbox.bondBalanceOf(Alice), bondAmount); } diff --git a/packages/protocol/test/layer1/based/InboxTest_BondToken.sol b/packages/protocol/test/layer1/based/InboxTest_BondToken.sol index d1970705dd4..7260e0123d1 100644 --- a/packages/protocol/test/layer1/based/InboxTest_BondToken.sol +++ b/packages/protocol/test/layer1/based/InboxTest_BondToken.sol @@ -181,8 +181,7 @@ contract InboxTest_BondToken is InboxTestBase { vm.prank(Alice); inbox.withdrawBond(aliceFirstWithdraw); assertEq( - inbox.bondBalanceOf(Alice), aliceFirstDeposit + aliceSecondDeposit - -aliceFirstWithdraw + inbox.bondBalanceOf(Alice), aliceFirstDeposit + aliceSecondDeposit - aliceFirstWithdraw ); vm.prank(Alice); diff --git a/packages/protocol/test/layer1/based/InboxTest_CalldataForTxList.t.sol b/packages/protocol/test/layer1/based/InboxTest_CalldataForTxList.t.sol index 700ecb1eb65..7837247c83e 100644 --- a/packages/protocol/test/layer1/based/InboxTest_CalldataForTxList.t.sol +++ b/packages/protocol/test/layer1/based/InboxTest_CalldataForTxList.t.sol @@ -71,7 +71,7 @@ pragma solidity ^0.8.24; // blockParams[0].blobIndex = 0; // Blob index not provided // vm.prank(Alice); -// vm.expectRevert(ITaikoInbox.BlobIndexZero.selector); +// vm.expectRevert(ITaikoInbox.BlobNotSpecified.selector); // inbox.proposeBlocksV3(address(0), address(0), blockParams, txList); // } diff --git a/packages/protocol/test/shared/layer2/token/BridgedTaikoToken.t.sol b/packages/protocol/test/shared/layer2/token/BridgedTaikoToken.t.sol index eabefe4742b..29c3c388fb8 100644 --- a/packages/protocol/test/shared/layer2/token/BridgedTaikoToken.t.sol +++ b/packages/protocol/test/shared/layer2/token/BridgedTaikoToken.t.sol @@ -24,7 +24,7 @@ contract BridgedTaikoTokenTest is CommonTest { resolver.registerAddress(block.chainid, LibStrings.B_ERC20_VAULT, deployer); } - function test_init() public { + function test_init() public view { assertEq(token.name(), "Taiko Token"); assertEq(token.symbol(), "TAIKO"); assertEq(token.owner(), deployer); @@ -56,7 +56,7 @@ contract BridgedTaikoTokenTest is CommonTest { token.burn(500 ether); } - function test_canonical() public { + function test_canonical() public view { (address canonicalAddr, uint256 chainId) = token.canonical(); assertEq(canonicalAddr, 0x10dea67478c5F8C5E2D90e5E9B26dBe60c54d800); assertEq(chainId, 1); diff --git a/packages/protocol/test/shared/tokenvault/ERC20Vault.h.sol b/packages/protocol/test/shared/tokenvault/ERC20Vault.h.sol index f44c1c5b3e3..8bb92cae975 100644 --- a/packages/protocol/test/shared/tokenvault/ERC20Vault.h.sol +++ b/packages/protocol/test/shared/tokenvault/ERC20Vault.h.sol @@ -8,14 +8,14 @@ import "src/layer1/based/ITaikoInbox.sol"; contract BridgedERC20V2_WithHelloWorld is BridgedERC20V2, CanSayHelloWorld { } contract PrankTaikoInbox { - ITaikoInbox.BlockV3 internal blk; + ITaikoInbox.Batch internal batch; - function setBlock(ITaikoInbox.BlockV3 memory _blk) external { - blk = _blk; + function setBatch(ITaikoInbox.Batch memory _batch) external { + batch = _batch; } - function getBlockV3(uint64) external view returns (ITaikoInbox.BlockV3 memory) { - return blk; + function getBatch(uint64) external view returns (ITaikoInbox.Batch memory) { + return batch; } function isOnL1() external pure returns (bool) { diff --git a/packages/protocol/test/shared/tokenvault/ERC20Vault.t.sol b/packages/protocol/test/shared/tokenvault/ERC20Vault.t.sol index 493fbe36fe4..8ae0ff9bf14 100644 --- a/packages/protocol/test/shared/tokenvault/ERC20Vault.t.sol +++ b/packages/protocol/test/shared/tokenvault/ERC20Vault.t.sol @@ -257,9 +257,9 @@ contract TestERC20Vault is CommonTest { uint64 blockId = 1; bytes32 blockMetaHash = bytes32("metahash"); - ITaikoInbox.BlockV3 memory blk; - blk.metaHash = blockMetaHash; - taikoInbox.setBlock(blk); + ITaikoInbox.Batch memory batch; + batch.metaHash = blockMetaHash; + taikoInbox.setBatch(batch); eERC20Token1.approve(address(eVault), 2); @@ -317,9 +317,9 @@ contract TestERC20Vault is CommonTest { uint64 blockId = 1; bytes32 blockMetaHash = bytes32("metahash"); - ITaikoInbox.BlockV3 memory blk; - blk.metaHash = blockMetaHash; - taikoInbox.setBlock(blk); + ITaikoInbox.Batch memory batch; + batch.metaHash = blockMetaHash; + taikoInbox.setBatch(batch); eERC20Token1.approve(address(eVault), 2); @@ -368,9 +368,9 @@ contract TestERC20Vault is CommonTest { uint64 blockId = 1; bytes32 blockMetaHash = bytes32("metahash1"); - ITaikoInbox.BlockV3 memory blk; - blk.metaHash = blockMetaHash; - taikoInbox.setBlock(blk); + ITaikoInbox.Batch memory batch; + batch.metaHash = blockMetaHash; + taikoInbox.setBatch(batch); eERC20Token1.approve(address(eVault), 2); eVault.solve( @@ -398,9 +398,9 @@ contract TestERC20Vault is CommonTest { bytes32 blockMetaHash = bytes32("metahash1"); bytes32 mismatchedBlockMetahash = bytes32("metahash2"); - ITaikoInbox.BlockV3 memory blk; - blk.metaHash = blockMetaHash; - taikoInbox.setBlock(blk); + ITaikoInbox.Batch memory batch; + batch.metaHash = blockMetaHash; + taikoInbox.setBatch(batch); vm.expectRevert(ERC20Vault.VAULT_METAHASH_MISMATCH.selector); eVault.solve( From f8d6f5bd9784a500ffdfa6f3f45687dfe6776f35 Mon Sep 17 00:00:00 2001 From: Daniel Wang Date: Sat, 11 Jan 2025 17:28:26 +0800 Subject: [PATCH 19/41] Update TaikoInbox.sol --- .../contracts/layer1/based/TaikoInbox.sol | 52 ++++++++++--------- 1 file changed, 27 insertions(+), 25 deletions(-) diff --git a/packages/protocol/contracts/layer1/based/TaikoInbox.sol b/packages/protocol/contracts/layer1/based/TaikoInbox.sol index 473d044a7ec..c28b23b4ea5 100644 --- a/packages/protocol/contracts/layer1/based/TaikoInbox.sol +++ b/packages/protocol/contracts/layer1/based/TaikoInbox.sol @@ -113,30 +113,32 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { // instead, only its hash is kept. // The metadata must be supplied as calldata prior to proving the batch, enabling the // computation and verification of its integrity through the comparison of the metahash. - unchecked { - meta_ = BatchMetadata({ - txListHash: calldataUsed ? keccak256(_txList) : _calcTxListHash(_batchParams.numBlobs), - extraData: bytes32(uint256(config.baseFeeConfig.sharingPctg)), - coinbase: _coinbase, - batchId: stats2.numBatches, - gasLimit: config.blockMaxGasLimit, - timestamp: updatedParams.timestamp, - parentMetaHash: parentBatch.metaHash, - proposer: _proposer, - livenessBond: config.livenessBond, - proposedAt: uint64(block.timestamp), - proposedIn: uint64(block.number), - txListOffset: _batchParams.txListOffset, - txListSize: _batchParams.txListSize, - numBlobs: calldataUsed ? 0 : _batchParams.numBlobs, - anchorBlockId: updatedParams.anchorBlockId, - anchorBlockHash: blockhash(updatedParams.anchorBlockId), - signalSlots: _batchParams.signalSlots, - blocks: abi.encode(_batchParams.blocks), - anchorInput: _batchParams.anchorInput, - baseFeeConfig: config.baseFeeConfig - }); - } + // + // Note that `difficulty` has been removed from the metadata. The client and prover must use + // the following approach to calculate a block's difficulty: + // `keccak256(abi.encode("TAIKO_DIFFICULTY", block.number))` + meta_ = BatchMetadata({ + txListHash: calldataUsed ? keccak256(_txList) : _calcTxListHash(_batchParams.numBlobs), + extraData: bytes32(uint256(config.baseFeeConfig.sharingPctg)), + coinbase: _coinbase, + batchId: stats2.numBatches, + gasLimit: config.blockMaxGasLimit, + timestamp: updatedParams.timestamp, + parentMetaHash: parentBatch.metaHash, + proposer: _proposer, + livenessBond: config.livenessBond, + proposedAt: uint64(block.timestamp), + proposedIn: uint64(block.number), + txListOffset: _batchParams.txListOffset, + txListSize: _batchParams.txListSize, + numBlobs: calldataUsed ? 0 : _batchParams.numBlobs, + anchorBlockId: updatedParams.anchorBlockId, + anchorBlockHash: blockhash(updatedParams.anchorBlockId), + signalSlots: _batchParams.signalSlots, + blocks: abi.encode(_batchParams.blocks), + anchorInput: _batchParams.anchorInput, + baseFeeConfig: config.baseFeeConfig + }); require(meta_.txListHash != 0, BlobNotFound()); bytes32 metaHash = keccak256(abi.encode(meta_)); @@ -598,8 +600,8 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { >= block.timestamp, TimestampTooSmall() ); - require(_params.timestamp <= block.timestamp, TimestampTooLarge()); require(_params.timestamp >= _parentBatch.timestamp, TimestampSmallerThanParent()); + require(_params.timestamp <= block.timestamp, TimestampTooLarge()); updatedParams_.timestamp = _params.timestamp; } From 115de845014f5db14eade2778872eba1b00df3ad Mon Sep 17 00:00:00 2001 From: Daniel Wang Date: Sat, 11 Jan 2025 17:34:04 +0800 Subject: [PATCH 20/41] Update TaikoInbox.sol --- packages/protocol/contracts/layer1/based/TaikoInbox.sol | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/packages/protocol/contracts/layer1/based/TaikoInbox.sol b/packages/protocol/contracts/layer1/based/TaikoInbox.sol index c28b23b4ea5..d18c2ac7135 100644 --- a/packages/protocol/contracts/layer1/based/TaikoInbox.sol +++ b/packages/protocol/contracts/layer1/based/TaikoInbox.sol @@ -601,11 +601,16 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { TimestampTooSmall() ); require(_params.timestamp >= _parentBatch.timestamp, TimestampSmallerThanParent()); - require(_params.timestamp <= block.timestamp, TimestampTooLarge()); updatedParams_.timestamp = _params.timestamp; } + uint256 maxTimestamp = _params.timestamp; + for (uint256 i; i < _params.blocks.length; ++i) { + maxTimestamp += _params.blocks[i].timeThift; + } + require(maxTimestamp <= block.timestamp, TimestampTooLarge()); + // Check if parent batch has the right meta hash. This is to allow the proposer to // make sure the batch builds on the expected latest chain state. require( From 5006b22fd3574ae7b3ebe13708e4aee1802e8ecb Mon Sep 17 00:00:00 2001 From: Daniel Wang Date: Sun, 12 Jan 2025 10:31:27 +0800 Subject: [PATCH 21/41] Update InboxTest_EtherAsBond.t.sol --- .../layer1/based/InboxTest_EtherAsBond.t.sol | 296 +++++++++--------- 1 file changed, 148 insertions(+), 148 deletions(-) diff --git a/packages/protocol/test/layer1/based/InboxTest_EtherAsBond.t.sol b/packages/protocol/test/layer1/based/InboxTest_EtherAsBond.t.sol index 8484b965212..01f3f6ac663 100644 --- a/packages/protocol/test/layer1/based/InboxTest_EtherAsBond.t.sol +++ b/packages/protocol/test/layer1/based/InboxTest_EtherAsBond.t.sol @@ -1,151 +1,151 @@ // SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.24; -// import "contracts/layer1/based/ITaikoInbox.sol"; -// import "./InboxTestBase.sol"; - -// contract InboxTest_EtherAsBond is InboxTestBase { -// function getConfig() internal pure override returns (ITaikoInbox.ConfigV3 memory) { -// return ITaikoInbox.ConfigV3({ -// chainId: LibNetwork.TAIKO_MAINNET, -// blockMaxProposals: 10, -// blockRingBufferSize: 15, -// maxBlocksToVerify: 5, -// blockMaxGasLimit: 240_000_000, -// livenessBond: 125e18, // 125 Taiko token -// stateRootSyncInternal: 5, -// maxAnchorHeightOffset: 64, -// baseFeeConfig: LibSharedData.BaseFeeConfig({ -// adjustmentQuotient: 8, -// sharingPctg: 75, -// gasIssuancePerSecond: 5_000_000, -// minGasExcess: 1_340_000_000, // correspond to 0.008847185 gwei basefee -// maxGasIssuancePerBlock: 600_000_000 // two minutes: 5_000_000 * 120 -// }), -// provingWindow: 1 hours, -// maxSignalsToReceive: 16, -// forkHeights: ITaikoInbox.ForkHeights({ ontake: 0, pacaya: 0 }) -// }); -// } - -// function setUpOnEthereum() internal override { -// super.setUpOnEthereum(); - -// // Use Ether as bond token -// bondToken = TaikoToken(address(0)); -// } - -// function test_inbox_deposit_withdraw() external { -// vm.warp(1_000_000); -// vm.deal(Alice, 1000 ether); - -// uint256 depositAmount = 1 ether; -// uint256 withdrawAmount = 0.5 ether; - -// vm.prank(Alice); -// inbox.depositBond{ value: depositAmount }(depositAmount); -// assertEq(inbox.bondBalanceOf(Alice), depositAmount); - -// vm.prank(Alice); -// inbox.withdrawBond(withdrawAmount); -// assertEq(inbox.bondBalanceOf(Alice), depositAmount - withdrawAmount); -// } - -// function test_inbox_withdraw_more_than_bond_balance() external { -// vm.warp(1_000_000); -// vm.deal(Alice, 1000 ether); - -// uint256 depositAmount = 1 ether; -// uint256 withdrawAmount = 2 ether; - -// vm.prank(Alice); -// inbox.depositBond{ value: depositAmount }(depositAmount); - -// vm.prank(Alice); -// vm.expectRevert(ITaikoInbox.InsufficientBond.selector); -// inbox.withdrawBond(withdrawAmount); -// } - -// function test_inbox_exceeding_balance() external { -// vm.warp(1_000_000); -// vm.deal(Alice, 0.5 ether); - -// uint256 depositAmount = 1 ether; - -// vm.prank(Alice); -// vm.expectRevert(); -// inbox.depositBond{ value: depositAmount }(depositAmount); -// } - -// function test_inbox_overpayment_of_ether() external { -// vm.warp(1_000_000); -// vm.deal(Alice, 1000 ether); - -// uint256 depositAmount = 1 ether; - -// vm.prank(Alice); -// vm.expectRevert(ITaikoInbox.EtherNotPaidAsBond.selector); -// inbox.depositBond{ value: depositAmount + 1 }(depositAmount); -// } - -// function test_inbox_eth_not_paid_as_bond_on_deposit() external { -// vm.warp(1_000_000); -// vm.deal(Alice, 1000 ether); - -// uint256 depositAmount = 1 ether; - -// vm.prank(Alice); -// vm.expectRevert(ITaikoInbox.EtherNotPaidAsBond.selector); -// inbox.depositBond{ value: 0 }(depositAmount); -// } - -// function test_inbox_bond_balance_after_multiple_operations() external { -// vm.warp(1_000_000); -// vm.deal(Alice, 1000 ether); -// vm.deal(Bob, 50 ether); - -// uint256 aliceFirstDeposit = 2 ether; -// uint256 aliceSecondDeposit = 3 ether; -// uint256 aliceFirstWithdraw = 1 ether; -// uint256 aliceSecondWithdraw = 1.5 ether; - -// uint256 bobDeposit = 5 ether; -// uint256 bobWithdraw = 2 ether; - -// vm.prank(Alice); -// inbox.depositBond{ value: aliceFirstDeposit }(aliceFirstDeposit); -// assertEq(inbox.bondBalanceOf(Alice), aliceFirstDeposit); - -// vm.prank(Bob); -// inbox.depositBond{ value: bobDeposit }(bobDeposit); -// assertEq(inbox.bondBalanceOf(Bob), bobDeposit); - -// vm.prank(Alice); -// inbox.depositBond{ value: aliceSecondDeposit }(aliceSecondDeposit); -// assertEq(inbox.bondBalanceOf(Alice), aliceFirstDeposit + aliceSecondDeposit); - -// vm.prank(Bob); -// inbox.withdrawBond(bobWithdraw); -// assertEq(inbox.bondBalanceOf(Bob), bobDeposit - bobWithdraw); - -// vm.prank(Alice); -// inbox.withdrawBond(aliceFirstWithdraw); -// assertEq( -// inbox.bondBalanceOf(Alice), aliceFirstDeposit + aliceSecondDeposit - -// aliceFirstWithdraw -// ); - -// vm.prank(Alice); -// inbox.withdrawBond(aliceSecondWithdraw); -// assertEq( -// inbox.bondBalanceOf(Alice), -// aliceFirstDeposit + aliceSecondDeposit - aliceFirstWithdraw - aliceSecondWithdraw -// ); - -// assertEq( -// inbox.bondBalanceOf(Alice), -// aliceFirstDeposit + aliceSecondDeposit - aliceFirstWithdraw - aliceSecondWithdraw -// ); -// assertEq(inbox.bondBalanceOf(Bob), bobDeposit - bobWithdraw); -// } -// } +import "contracts/layer1/based/ITaikoInbox.sol"; +import "./InboxTestBase.sol"; + +contract InboxTest_EtherAsBond is InboxTestBase { + function getConfig() internal pure override returns (ITaikoInbox.Config memory) { + return ITaikoInbox.Config({ + chainId: LibNetwork.TAIKO_MAINNET, + maxBatchProposals: 10, + batchRingBufferSize: 15, + maxBatchesToVerify: 5, + blockMaxGasLimit: 240_000_000, + livenessBond: 125e18, // 125 Taiko token + stateRootSyncInternal: 5, + maxAnchorHeightOffset: 64, + baseFeeConfig: LibSharedData.BaseFeeConfig({ + adjustmentQuotient: 8, + sharingPctg: 75, + gasIssuancePerSecond: 5_000_000, + minGasExcess: 1_340_000_000, // correspond to 0.008847185 gwei basefee + maxGasIssuancePerBlock: 600_000_000 // two minutes: 5_000_000 * 120 + }), + provingWindow: 1 hours, + maxSignalsToReceive: 16, + maxBlocksPerBatch: 256, + forkHeights: ITaikoInbox.ForkHeights({ ontake: 0, pacaya: 0 }) + }); + } + + function setUpOnEthereum() internal override { + super.setUpOnEthereum(); + + // Use Ether as bond token + bondToken = TaikoToken(address(0)); + } + + function test_inbox_deposit_withdraw() external { + vm.warp(1_000_000); + vm.deal(Alice, 1000 ether); + + uint256 depositAmount = 1 ether; + uint256 withdrawAmount = 0.5 ether; + + vm.prank(Alice); + inbox.depositBond{ value: depositAmount }(depositAmount); + assertEq(inbox.bondBalanceOf(Alice), depositAmount); + + vm.prank(Alice); + inbox.withdrawBond(withdrawAmount); + assertEq(inbox.bondBalanceOf(Alice), depositAmount - withdrawAmount); + } + + function test_inbox_withdraw_more_than_bond_balance() external { + vm.warp(1_000_000); + vm.deal(Alice, 1000 ether); + + uint256 depositAmount = 1 ether; + uint256 withdrawAmount = 2 ether; + + vm.prank(Alice); + inbox.depositBond{ value: depositAmount }(depositAmount); + + vm.prank(Alice); + vm.expectRevert(ITaikoInbox.InsufficientBond.selector); + inbox.withdrawBond(withdrawAmount); + } + + function test_inbox_exceeding_balance() external { + vm.warp(1_000_000); + vm.deal(Alice, 0.5 ether); + + uint256 depositAmount = 1 ether; + + vm.prank(Alice); + vm.expectRevert(); + inbox.depositBond{ value: depositAmount }(depositAmount); + } + + function test_inbox_overpayment_of_ether() external { + vm.warp(1_000_000); + vm.deal(Alice, 1000 ether); + + uint256 depositAmount = 1 ether; + + vm.prank(Alice); + vm.expectRevert(ITaikoInbox.EtherNotPaidAsBond.selector); + inbox.depositBond{ value: depositAmount + 1 }(depositAmount); + } + + function test_inbox_eth_not_paid_as_bond_on_deposit() external { + vm.warp(1_000_000); + vm.deal(Alice, 1000 ether); + + uint256 depositAmount = 1 ether; + + vm.prank(Alice); + vm.expectRevert(ITaikoInbox.EtherNotPaidAsBond.selector); + inbox.depositBond{ value: 0 }(depositAmount); + } + + function test_inbox_bond_balance_after_multiple_operations() external { + vm.warp(1_000_000); + vm.deal(Alice, 1000 ether); + vm.deal(Bob, 50 ether); + + uint256 aliceFirstDeposit = 2 ether; + uint256 aliceSecondDeposit = 3 ether; + uint256 aliceFirstWithdraw = 1 ether; + uint256 aliceSecondWithdraw = 1.5 ether; + + uint256 bobDeposit = 5 ether; + uint256 bobWithdraw = 2 ether; + + vm.prank(Alice); + inbox.depositBond{ value: aliceFirstDeposit }(aliceFirstDeposit); + assertEq(inbox.bondBalanceOf(Alice), aliceFirstDeposit); + + vm.prank(Bob); + inbox.depositBond{ value: bobDeposit }(bobDeposit); + assertEq(inbox.bondBalanceOf(Bob), bobDeposit); + + vm.prank(Alice); + inbox.depositBond{ value: aliceSecondDeposit }(aliceSecondDeposit); + assertEq(inbox.bondBalanceOf(Alice), aliceFirstDeposit + aliceSecondDeposit); + + vm.prank(Bob); + inbox.withdrawBond(bobWithdraw); + assertEq(inbox.bondBalanceOf(Bob), bobDeposit - bobWithdraw); + + vm.prank(Alice); + inbox.withdrawBond(aliceFirstWithdraw); + assertEq( + inbox.bondBalanceOf(Alice), aliceFirstDeposit + aliceSecondDeposit - aliceFirstWithdraw + ); + + vm.prank(Alice); + inbox.withdrawBond(aliceSecondWithdraw); + assertEq( + inbox.bondBalanceOf(Alice), + aliceFirstDeposit + aliceSecondDeposit - aliceFirstWithdraw - aliceSecondWithdraw + ); + + assertEq( + inbox.bondBalanceOf(Alice), + aliceFirstDeposit + aliceSecondDeposit - aliceFirstWithdraw - aliceSecondWithdraw + ); + assertEq(inbox.bondBalanceOf(Bob), bobDeposit - bobWithdraw); + } +} From d57280c8323c5bdadbfdec4a9b963d3f3107e2a0 Mon Sep 17 00:00:00 2001 From: Daniel Wang Date: Sun, 12 Jan 2025 10:48:34 +0800 Subject: [PATCH 22/41] Update InboxTest_CalldataForTxList.t.sol --- .../based/InboxTest_CalldataForTxList.t.sol | 343 ++++++++++-------- 1 file changed, 182 insertions(+), 161 deletions(-) diff --git a/packages/protocol/test/layer1/based/InboxTest_CalldataForTxList.t.sol b/packages/protocol/test/layer1/based/InboxTest_CalldataForTxList.t.sol index 7837247c83e..f3546d278a1 100644 --- a/packages/protocol/test/layer1/based/InboxTest_CalldataForTxList.t.sol +++ b/packages/protocol/test/layer1/based/InboxTest_CalldataForTxList.t.sol @@ -1,175 +1,196 @@ // SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.24; -// import "contracts/layer1/based/ITaikoInbox.sol"; -// import "./InboxTestBase.sol"; - -// contract InboxTest_CalldataForTxList is InboxTestBase { -// function getConfig() internal pure override returns (ITaikoInbox.ConfigV3 memory) { -// return ITaikoInbox.ConfigV3({ -// chainId: LibNetwork.TAIKO_MAINNET, -// blockMaxProposals: 10, -// blockRingBufferSize: 15, -// maxBlocksToVerify: 5, -// blockMaxGasLimit: 240_000_000, -// livenessBond: 125e18, // 125 Taiko token -// stateRootSyncInternal: 5, -// maxAnchorHeightOffset: 64, -// baseFeeConfig: LibSharedData.BaseFeeConfig({ -// adjustmentQuotient: 8, -// sharingPctg: 75, -// gasIssuancePerSecond: 5_000_000, -// minGasExcess: 1_340_000_000, // correspond to 0.008847185 gwei basefee -// maxGasIssuancePerBlock: 600_000_000 // two minutes: 5_000_000 * 120 -// }), -// provingWindow: 1 hours, -// maxSignalsToReceive: 16, -// forkHeights: ITaikoInbox.ForkHeights({ ontake: 0, pacaya: 0 }) -// }); -// } - -// function setUpOnEthereum() internal override { -// super.setUpOnEthereum(); -// bondToken = deployBondToken(); -// } - -// function test_calldata_used_for_txlist_da() external { -// vm.warp(1_000_000); - -// uint256 initialBondBalance = 100_000 ether; -// uint256 bondAmount = 1000 ether; - -// setupBondTokenState(Alice, initialBondBalance, bondAmount); - -// // Define the txList in calldata -// bytes memory txList = abi.encodePacked("txList"); -// bytes32 expectedHash = keccak256(txList); - -// vm.prank(Alice); -// uint64[] memory blockIds = -// _proposeBlocksWithDefaultParameters({ numBlocksToPropose: 1, txList: txList }); -// for (uint256 i; i < blockIds.length; ++i) { -// ITaikoInbox.BlockMetadataV3 memory meta = blockMetadatas[blockIds[i]]; -// assertEq(meta.txListHash, expectedHash); -// } - -// vm.prank(Alice); -// _proveBlocksWithCorrectTransitions(blockIds); -// } - -// function test_block_rejection_due_to_missing_txlist_and_blobindex() external { -// vm.warp(1_000_000); - -// uint256 initialBondBalance = 100_000 ether; -// uint256 bondAmount = 1000 ether; - -// setupBondTokenState(Alice, initialBondBalance, bondAmount); - -// // Define empty txList -// bytes memory txList = ""; -// ITaikoInbox.BlockParamsV3[] memory blockParams = new ITaikoInbox.BlockParamsV3[](1); -// blockParams[0].blobIndex = 0; // Blob index not provided - -// vm.prank(Alice); -// vm.expectRevert(ITaikoInbox.BlobNotSpecified.selector); -// inbox.proposeBlocksV3(address(0), address(0), blockParams, txList); -// } - -// function test_propose_block_with_empty_txlist_and_valid_blobindex() external { -// vm.warp(1_000_000); - -// uint256 initialBondBalance = 100_000 ether; -// uint256 bondAmount = 1000 ether; - -// setupBondTokenState(Alice, initialBondBalance, bondAmount); - -// // Define empty txList -// bytes memory txList = ""; -// ITaikoInbox.BlockParamsV3[] memory blockParams = new ITaikoInbox.BlockParamsV3[](1); -// blockParams[0].blobIndex = 1; // Valid blob index - -// vm.prank(Alice); -// ITaikoInbox.BlockMetadataV3[] memory metas = -// inbox.proposeBlocksV3(address(0), address(0), blockParams, txList); - -// ITaikoInbox.BlockMetadataV3 memory meta = metas[0]; -// assertTrue(meta.txListHash != 0, "txListHash should not be zero for valid blobIndex"); - -// vm.prank(Alice); -// uint64[] memory blockIds = new uint64[](metas.length); -// for (uint256 i; i < metas.length; ++i) { -// blockMetadatas[metas[i].blockId] = metas[i]; -// blockIds[i] = metas[i].blockId; -// } -// _proveBlocksWithCorrectTransitions(blockIds); -// } - -// function test_multiple_blocks_with_different_txlist() external { -// vm.warp(1_000_000); - -// uint256 initialBondBalance = 100_000 ether; -// uint256 bondAmount = 1000 ether; - -// setupBondTokenState(Alice, initialBondBalance, bondAmount); - -// bytes memory txList1 = abi.encodePacked("txList1"); -// bytes memory txList2 = abi.encodePacked("txList2"); -// bytes32 expectedHash1 = keccak256(txList1); -// bytes32 expectedHash2 = keccak256(txList2); - -// vm.prank(Alice); -// uint64[] memory blockIds1 = _proposeBlocksWithDefaultParameters(1, txList1); -// ITaikoInbox.BlockMetadataV3 memory meta1 = blockMetadatas[blockIds1[0]]; -// assertEq(meta1.txListHash, expectedHash1, "txListHash mismatch for block 1"); - -// vm.prank(Alice); -// uint64[] memory blockIds2 = _proposeBlocksWithDefaultParameters(1, txList2); -// ITaikoInbox.BlockMetadataV3 memory meta2 = blockMetadatas[blockIds2[0]]; -// assertEq(meta2.txListHash, expectedHash2, "txListHash mismatch for block 2"); +import "contracts/layer1/based/ITaikoInbox.sol"; +import "./InboxTestBase.sol"; + +contract InboxTest_CalldataForTxList is InboxTestBase { + function getConfig() internal pure override returns (ITaikoInbox.Config memory) { + return ITaikoInbox.Config({ + chainId: LibNetwork.TAIKO_MAINNET, + maxBatchProposals: 10, + batchRingBufferSize: 15, + maxBatchesToVerify: 5, + blockMaxGasLimit: 240_000_000, + livenessBond: 125e18, // 125 Taiko token + stateRootSyncInternal: 5, + maxAnchorHeightOffset: 64, + baseFeeConfig: LibSharedData.BaseFeeConfig({ + adjustmentQuotient: 8, + sharingPctg: 75, + gasIssuancePerSecond: 5_000_000, + minGasExcess: 1_340_000_000, // correspond to 0.008847185 gwei basefee + maxGasIssuancePerBlock: 600_000_000 // two minutes: 5_000_000 * 120 + }), + provingWindow: 1 hours, + maxSignalsToReceive: 16, + maxBlocksPerBatch: 256, + forkHeights: ITaikoInbox.ForkHeights({ ontake: 0, pacaya: 0 }) + }); + } + + function setUpOnEthereum() internal override { + super.setUpOnEthereum(); + bondToken = deployBondToken(); + } + + function test_calldata_used_for_txlist_da() external { + vm.warp(1_000_000); + + uint256 initialBondBalance = 100_000 ether; + uint256 bondAmount = 1000 ether; + + setupBondTokenState(Alice, initialBondBalance, bondAmount); + + // Define the txList in calldata + bytes memory txList = abi.encodePacked("txList"); + bytes32 expectedHash = keccak256(txList); + + vm.prank(Alice); + uint64[] memory batchIds = + _proposeBatchesWithDefaultParameters({ numBatchesToPropose: 1, txList: txList }); + + for (uint256 i; i < batchIds.length; ++i) { + ITaikoInbox.BatchMetadata memory meta = batchMetadatas[batchIds[i]]; + assertEq(meta.txListHash, expectedHash); + } + + vm.prank(Alice); + _proveBatchesWithCorrectTransitions(batchIds); + } + + function test_block_rejection_due_to_missing_txlist_and_blobindex() external { + vm.warp(1_000_000); + + uint256 initialBondBalance = 100_000 ether; + uint256 bondAmount = 1000 ether; + + setupBondTokenState(Alice, initialBondBalance, bondAmount); + + ITaikoInbox.BlockParams[] memory blocks = new ITaikoInbox.BlockParams[](1); + blocks[0] = ITaikoInbox.BlockParams({ numTransactions: 0, timeThift: 0 }); + + ITaikoInbox.BatchParams memory batchParams = ITaikoInbox.BatchParams({ + anchorBlockId: 0, + timestamp: 0, + parentMetaHash: 0, + signalSlots: new bytes32[](0), + numBlobs: 0, // missing blob index + txListOffset: 0, + txListSize: 0, + anchorInput: bytes32(0), + blocks: blocks + }); + + vm.prank(Alice); + vm.expectRevert(ITaikoInbox.BlobNotSpecified.selector); + // With empty txList + inbox.proposeBatch(address(0), address(0), batchParams, ""); + } + + function test_propose_block_with_empty_txlist_and_valid_blobindex() external { + vm.warp(1_000_000); + + uint256 initialBondBalance = 100_000 ether; + uint256 bondAmount = 1000 ether; + + setupBondTokenState(Alice, initialBondBalance, bondAmount); + + ITaikoInbox.BlockParams[] memory blocks = new ITaikoInbox.BlockParams[](1); + blocks[0] = ITaikoInbox.BlockParams({ numTransactions: 0, timeThift: 0 }); + + ITaikoInbox.BatchParams memory batchParams = ITaikoInbox.BatchParams({ + anchorBlockId: 0, + timestamp: 0, + parentMetaHash: 0, + signalSlots: new bytes32[](0), + numBlobs: 1, // one blob + txListOffset: 0, + txListSize: 0, + anchorInput: bytes32(0), + blocks: blocks + }); + + vm.prank(Alice); + + // With empty txList + ITaikoInbox.BatchMetadata memory meta = + inbox.proposeBatch(address(0), address(0), batchParams, ""); + assertTrue(meta.txListHash != 0, "txListHash should not be zero for valid blobIndex"); + + batchMetadatas[meta.batchId] = meta; + + vm.prank(Alice); + uint64[] memory batchIds = new uint64[](1); + batchIds[0] = meta.batchId; -// vm.prank(Alice); -// _proveBlocksWithCorrectTransitions(blockIds2); + _proveBatchesWithCorrectTransitions(batchIds); + } -// vm.prank(Alice); -// _proveBlocksWithCorrectTransitions(blockIds1); -// } + function test_multiple_blocks_with_different_txlist() external { + vm.warp(1_000_000); -// function test_prove_block_with_mismatched_txlist() external { -// vm.warp(1_000_000); + uint256 initialBondBalance = 100_000 ether; + uint256 bondAmount = 1000 ether; -// uint256 initialBondBalance = 100_000 ether; -// uint256 bondAmount = 1000 ether; + setupBondTokenState(Alice, initialBondBalance, bondAmount); -// setupBondTokenState(Alice, initialBondBalance, bondAmount); - -// // Define a correct txList for proposal -// bytes memory txList = abi.encodePacked("correct txList"); + bytes memory txList1 = abi.encodePacked("txList1"); + bytes memory txList2 = abi.encodePacked("txList2"); + bytes32 expectedHash1 = keccak256(txList1); + bytes32 expectedHash2 = keccak256(txList2); -// vm.prank(Alice); -// uint64[] memory blockIds = _proposeBlocksWithDefaultParameters(1, txList); + vm.prank(Alice); + uint64[] memory batchIds1 = _proposeBatchesWithDefaultParameters(1, txList1); + ITaikoInbox.BatchMetadata memory meta1 = batchMetadatas[batchIds1[0]]; + assertEq(meta1.txListHash, expectedHash1, "txListHash mismatch for block 1"); -// // Define an incorrect txList for proof -// bytes32 incorrectHash = keccak256(abi.encodePacked("incorrect txList")); + vm.prank(Alice); + uint64[] memory batchIds2 = _proposeBatchesWithDefaultParameters(1, txList2); + ITaikoInbox.BatchMetadata memory meta2 = batchMetadatas[batchIds2[0]]; + assertEq(meta2.txListHash, expectedHash2, "txListHash mismatch for block 2"); -// // Attempt to prove the block with the incorrect txList -// ITaikoInbox.BlockMetadataV3 memory meta = blockMetadatas[blockIds[0]]; -// meta.txListHash = incorrectHash; + vm.prank(Alice); + _proveBatchesWithCorrectTransitions(batchIds2); -// ITaikoInbox.BlockMetadataV3[] memory metas = -// new ITaikoInbox.BlockMetadataV3[](blockIds.length); -// ITaikoInbox.TransitionV3[] memory transitions = -// new ITaikoInbox.TransitionV3[](blockIds.length); + vm.prank(Alice); + _proveBatchesWithCorrectTransitions(batchIds1); + } -// for (uint256 i; i < blockIds.length; ++i) { -// metas[i] = blockMetadatas[blockIds[i]]; -// metas[i].txListHash = incorrectHash; -// transitions[i].parentHash = correctBlockhash(blockIds[i] - 1); -// transitions[i].blockHash = correctBlockhash(blockIds[i]); -// transitions[i].stateRoot = correctStateRoot(blockIds[i]); -// } + function test_prove_block_with_mismatched_txlist() external { + vm.warp(1_000_000); -// vm.prank(Alice); -// vm.expectRevert(ITaikoInbox.MetaHashMismatch.selector); -// inbox.proveBlocksV3(metas, transitions, "proof"); -// } -// } + uint256 initialBondBalance = 100_000 ether; + uint256 bondAmount = 1000 ether; + + setupBondTokenState(Alice, initialBondBalance, bondAmount); + + // Define a correct txList for proposal + bytes memory txList = abi.encodePacked("correct txList"); + + vm.prank(Alice); + uint64[] memory batchIds = _proposeBatchesWithDefaultParameters(1, txList); + + // Define an incorrect txList for proof + bytes32 incorrectHash = keccak256(abi.encodePacked("incorrect txList")); + + // Attempt to prove the block with the incorrect txList + ITaikoInbox.BatchMetadata memory meta = batchMetadatas[batchIds[0]]; + meta.txListHash = incorrectHash; + + ITaikoInbox.BatchMetadata[] memory metas = new ITaikoInbox.BatchMetadata[](batchIds.length); + ITaikoInbox.Transition[] memory transitions = new ITaikoInbox.Transition[](batchIds.length); + + for (uint256 i; i < batchIds.length; ++i) { + metas[i] = batchMetadatas[batchIds[i]]; + metas[i].txListHash = incorrectHash; + transitions[i].parentHash = correctBlockhash(batchIds[i] - 1); + transitions[i].blockHash = correctBlockhash(batchIds[i]); + transitions[i].stateRoot = correctStateRoot(batchIds[i]); + } + + vm.prank(Alice); + vm.expectRevert(ITaikoInbox.MetaHashMismatch.selector); + inbox.proveBatches(metas, transitions, "proof"); + } +} From b1a7fe95527a0f3b9d0d114a3db05527031f6581 Mon Sep 17 00:00:00 2001 From: Daniel Wang Date: Sun, 12 Jan 2025 10:58:49 +0800 Subject: [PATCH 23/41] more --- .../contracts/layer1/based/ITaikoInbox.sol | 4 +- .../contracts/layer1/based/TaikoInbox.sol | 24 +- .../test/layer1/based/InboxTestBase.sol | 6 +- .../test/layer1/based/InboxTest_Suite1.t.sol | 778 +++++++++--------- 4 files changed, 405 insertions(+), 407 deletions(-) diff --git a/packages/protocol/contracts/layer1/based/ITaikoInbox.sol b/packages/protocol/contracts/layer1/based/ITaikoInbox.sol index f0855027ab9..d55d2b52ce3 100644 --- a/packages/protocol/contracts/layer1/based/ITaikoInbox.sol +++ b/packages/protocol/contracts/layer1/based/ITaikoInbox.sol @@ -84,13 +84,13 @@ interface ITaikoInbox { struct Stats1 { uint64 __reserved1; uint64 __reserved2; - uint64 lastSyncedBatch; + uint64 lastSyncedBatchId; uint64 lastSyncedAt; } struct Stats2 { uint64 numBatches; - uint64 lastVerifiedBatch; + uint64 lastVerifiedBatchId; bool paused; uint56 lastProposedIn; uint64 lastUnpausedAt; diff --git a/packages/protocol/contracts/layer1/based/TaikoInbox.sol b/packages/protocol/contracts/layer1/based/TaikoInbox.sol index d18c2ac7135..a30c5a2eed2 100644 --- a/packages/protocol/contracts/layer1/based/TaikoInbox.sol +++ b/packages/protocol/contracts/layer1/based/TaikoInbox.sol @@ -71,7 +71,7 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { unchecked { require( - stats2.numBatches < stats2.lastVerifiedBatch + config.maxBatchProposals, + stats2.numBatches < stats2.lastVerifiedBatchId + config.maxBatchProposals, TooManyBatches() ); } @@ -194,7 +194,7 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { batchIds[i] = meta.batchId; require(meta.batchId >= config.forkHeights.pacaya, InvalidForkHeight()); - require(meta.batchId > stats2.lastVerifiedBatch, BatchNotFound()); + require(meta.batchId > stats2.lastVerifiedBatchId, BatchNotFound()); require(meta.batchId < stats2.numBatches, BatchNotFound()); Transition calldata tran = _transitions[i]; @@ -332,7 +332,7 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { view returns (uint64 batchId_, Transition memory tran_) { - batchId_ = state.stats2.lastVerifiedBatch; + batchId_ = state.stats2.lastVerifiedBatchId; tran_ = getBatchVerifyingTransition(batchId_); } @@ -342,7 +342,7 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { view returns (uint64 batchId_, Transition memory tran_) { - batchId_ = state.stats1.lastSyncedBatch; + batchId_ = state.stats1.lastSyncedBatchId; tran_ = getBatchVerifyingTransition(batchId_); } @@ -452,7 +452,7 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { ) private { - uint64 batchId = _stats2.lastVerifiedBatch; + uint64 batchId = _stats2.lastVerifiedBatchId; uint256 slot = batchId % _config.batchRingBufferSize; Batch storage batch = state.batches[slot]; uint24 tid = batch.verifiedTransitionId; @@ -460,7 +460,7 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { SyncBatch memory synced; - uint256 stopBlockId = (_config.maxBatchesToVerify * _length + _stats2.lastVerifiedBatch).min( + uint256 stopBlockId = (_config.maxBatchesToVerify * _length + _stats2.lastVerifiedBatchId).min( _stats2.numBatches ); @@ -497,22 +497,22 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { --batchId; } - if (_stats2.lastVerifiedBatch != batchId) { - _stats2.lastVerifiedBatch = batchId; + if (_stats2.lastVerifiedBatchId != batchId) { + _stats2.lastVerifiedBatchId = batchId; - batch = state.batches[_stats2.lastVerifiedBatch % _config.batchRingBufferSize]; + batch = state.batches[_stats2.lastVerifiedBatchId % _config.batchRingBufferSize]; batch.verifiedTransitionId = tid; - emit BatchesVerified(_stats2.lastVerifiedBatch, blockHash); + emit BatchesVerified(_stats2.lastVerifiedBatchId, blockHash); if (synced.batchId != 0) { - if (synced.batchId != _stats2.lastVerifiedBatch) { + if (synced.batchId != _stats2.lastVerifiedBatchId) { // We write the synced batch's verifiedTransitionId to storage batch = state.batches[synced.batchId % _config.batchRingBufferSize]; batch.verifiedTransitionId = synced.tid; } Stats1 memory stats1 = state.stats1; - stats1.lastSyncedBatch = synced.batchId; + stats1.lastSyncedBatchId = synced.batchId; stats1.lastSyncedAt = uint64(block.timestamp); state.stats1 = stats1; diff --git a/packages/protocol/test/layer1/based/InboxTestBase.sol b/packages/protocol/test/layer1/based/InboxTestBase.sol index a4c27768a1f..ad3be723eb2 100644 --- a/packages/protocol/test/layer1/based/InboxTestBase.sol +++ b/packages/protocol/test/layer1/based/InboxTestBase.sol @@ -132,12 +132,12 @@ abstract contract InboxTestBase is Layer1Test { function _logAllBatchesAndTransitions() internal view { console2.log(unicode"|───────────────────────────────────────────────────────────────"); ITaikoInbox.Stats1 memory stats1 = inbox.getStats1(); - console2.log("Stats1 - lastSyncedBatch:", stats1.lastSyncedBatch); + console2.log("Stats1 - lastSyncedBatchId:", stats1.lastSyncedBatchId); console2.log("Stats1 - lastSyncedAt:", stats1.lastSyncedAt); ITaikoInbox.Stats2 memory stats2 = inbox.getStats2(); console2.log("Stats2 - numBatches:", stats2.numBatches); - console2.log("Stats2 - lastVerifiedBatch:", stats2.lastVerifiedBatch); + console2.log("Stats2 - lastVerifiedBatchId:", stats2.lastVerifiedBatchId); console2.log("Stats2 - paused:", stats2.paused); console2.log("Stats2 - lastProposedIn:", stats2.lastProposedIn); console2.log("Stats2 - lastUnpausedAt:", stats2.lastUnpausedAt); @@ -151,7 +151,7 @@ abstract contract InboxTestBase is Layer1Test { for (uint64 i = firstBatchId; i < stats2.numBatches; ++i) { ITaikoInbox.Batch memory batch = inbox.getBatch(i); - if (batch.batchId <= stats2.lastVerifiedBatch) { + if (batch.batchId <= stats2.lastVerifiedBatchId) { console2.log(unicode"|─ ✔ batch#", batch.batchId); } else { console2.log(unicode"|─── batch#", batch.batchId); diff --git a/packages/protocol/test/layer1/based/InboxTest_Suite1.t.sol b/packages/protocol/test/layer1/based/InboxTest_Suite1.t.sol index 26f99dda96b..2fc34999a16 100644 --- a/packages/protocol/test/layer1/based/InboxTest_Suite1.t.sol +++ b/packages/protocol/test/layer1/based/InboxTest_Suite1.t.sol @@ -1,395 +1,393 @@ // SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.24; -// import "./InboxTestBase.sol"; - -// contract InboxTest_Suite1 is InboxTestBase { -// function getConfig() internal pure override returns (ITaikoInbox.ConfigV3 memory) { -// return ITaikoInbox.ConfigV3({ -// chainId: LibNetwork.TAIKO_MAINNET, -// blockMaxProposals: 10, -// blockRingBufferSize: 15, -// maxBlocksToVerify: 5, -// blockMaxGasLimit: 240_000_000, -// livenessBond: 125e18, // 125 Taiko token -// stateRootSyncInternal: 5, -// maxAnchorHeightOffset: 64, -// baseFeeConfig: LibSharedData.BaseFeeConfig({ -// adjustmentQuotient: 8, -// sharingPctg: 75, -// gasIssuancePerSecond: 5_000_000, -// minGasExcess: 1_340_000_000, // correspond to 0.008847185 gwei basefee -// maxGasIssuancePerBlock: 600_000_000 // two minutes: 5_000_000 * 120 -// }), -// provingWindow: 1 hours, -// maxSignalsToReceive: 16, -// forkHeights: ITaikoInbox.ForkHeights({ ontake: 0, pacaya: 0 }) -// }); -// } - -// function setUpOnEthereum() internal override { -// super.setUpOnEthereum(); -// bondToken = deployBondToken(); -// } - -// function test_inbox_query_right_after_genesis_block() external view { -// // - All stats are correct and expected -// ITaikoInbox.Stats1 memory stats1 = inbox.getStats1(); -// assertEq(stats1.lastSyncedBlockId, 0); -// assertEq(stats1.lastSyncedAt, 0); - -// ITaikoInbox.Stats2 memory stats2 = inbox.getStats2(); -// assertEq(stats2.numBlocks, 1); -// assertEq(stats2.lastVerifiedBlockId, 0); -// assertEq(stats2.paused, false); -// assertEq(stats2.lastProposedIn, genesisBlockProposedIn); -// assertEq(stats2.lastUnpausedAt, 0); - -// // - Verify genesis block -// ITaikoInbox.BlockV3 memory blk = inbox.getBlockV3(0); -// assertEq(blk.blockId, 0); -// assertEq(blk.metaHash, bytes32(uint256(1))); -// assertEq(blk.timestamp, genesisBlockProposedAt); -// assertEq(blk.anchorBlockId, genesisBlockProposedIn); -// assertEq(blk.nextTransitionId, 2); -// assertEq(blk.verifiedTransitionId, 1); - -// (uint64 blockId, ITaikoInbox.TransitionV3 memory tran) = -// inbox.getLastVerifiedTransitionV3(); -// assertEq(blockId, 0); -// assertEq(tran.blockHash, correctBlockhash(0)); -// assertEq(tran.stateRoot, bytes32(uint256(0))); - -// (blockId, tran) = inbox.getLastSyncedTransitionV3(); -// assertEq(blockId, 0); -// assertEq(tran.blockHash, correctBlockhash(0)); -// assertEq(tran.stateRoot, bytes32(uint256(0))); -// } - -// function test_inbox_query_blocks_not_exist_will_revert() external { -// vm.expectRevert(ITaikoInbox.BlockNotFound.selector); -// inbox.getBlockV3(1); -// } - -// function test_inbox_max_block_proposal() -// external -// transactBy(Alice) -// WhenMultipleBlocksAreProposedWithDefaultParameters(9) -// WhenLogAllBlocksAndTransitions -// { -// // - All stats are correct and expected - -// ITaikoInbox.Stats1 memory stats1 = inbox.getStats1(); -// assertEq(stats1.lastSyncedBlockId, 0); -// assertEq(stats1.lastSyncedAt, 0); - -// ITaikoInbox.Stats2 memory stats2 = inbox.getStats2(); -// assertEq(stats2.numBlocks, 10); -// assertEq(stats2.lastVerifiedBlockId, 0); -// assertEq(stats2.paused, false); -// assertEq(stats2.lastProposedIn, block.number); -// assertEq(stats2.lastUnpausedAt, 0); - -// // - Verify genesis block -// ITaikoInbox.BlockV3 memory blk = inbox.getBlockV3(0); -// assertEq(blk.blockId, 0); -// assertEq(blk.metaHash, bytes32(uint256(1))); -// assertEq(blk.timestamp, genesisBlockProposedAt); -// assertEq(blk.anchorBlockId, genesisBlockProposedIn); -// assertEq(blk.nextTransitionId, 2); -// assertEq(blk.verifiedTransitionId, 1); - -// // Verify block data -// for (uint64 i = 1; i < 10; ++i) { -// blk = inbox.getBlockV3(i); -// assertEq(blk.blockId, i); -// assertEq(blk.metaHash, keccak256(abi.encode(blockMetadatas[i]))); - -// assertEq(blk.timestamp, block.timestamp); -// assertEq(blk.anchorBlockId, block.number - 1); -// assertEq(blk.nextTransitionId, 1); -// assertEq(blk.verifiedTransitionId, 0); -// } - -// // - Proposing one block block will revert -// vm.expectRevert(ITaikoInbox.TooManyBlocks.selector); -// _proposeBlocksWithDefaultParameters({ numBlocksToPropose: 1 }); -// } - -// function test_inbox_exceed_max_block_proposal_will_revert() -// external -// transactBy(Alice) -// WhenMultipleBlocksAreProposedWithDefaultParameters(9) -// WhenLogAllBlocksAndTransitions -// { -// // - Proposing one block block will revert -// vm.expectRevert(ITaikoInbox.TooManyBlocks.selector); -// _proposeBlocksWithDefaultParameters({ numBlocksToPropose: 1 }); -// } - -// function test_inbox_prove_with_wrong_transitions_will_not_finalize_blocks() -// external -// transactBy(Alice) -// WhenMultipleBlocksAreProposedWithDefaultParameters(6) -// WhenMultipleBlocksAreProvedWithWrongTransitions(1, 7) -// WhenLogAllBlocksAndTransitions -// { -// // - All stats are correct and expected - -// ITaikoInbox.Stats1 memory stats1 = inbox.getStats1(); -// assertEq(stats1.lastSyncedBlockId, 0); -// assertEq(stats1.lastSyncedAt, 0); - -// ITaikoInbox.Stats2 memory stats2 = inbox.getStats2(); -// assertEq(stats2.numBlocks, 7); -// assertEq(stats2.lastVerifiedBlockId, 0); -// assertEq(stats2.paused, false); -// assertEq(stats2.lastProposedIn, block.number); -// assertEq(stats2.lastUnpausedAt, 0); - -// // - Verify genesis block -// ITaikoInbox.BlockV3 memory blk = inbox.getBlockV3(0); -// assertEq(blk.blockId, 0); -// assertEq(blk.metaHash, bytes32(uint256(1))); -// assertEq(blk.timestamp, genesisBlockProposedAt); -// assertEq(blk.anchorBlockId, genesisBlockProposedIn); -// assertEq(blk.nextTransitionId, 2); -// assertEq(blk.verifiedTransitionId, 1); - -// // Verify block data -// for (uint64 i = 1; i < 7; ++i) { -// blk = inbox.getBlockV3(i); -// assertEq(blk.blockId, i); -// assertEq(blk.metaHash, keccak256(abi.encode(blockMetadatas[i]))); - -// assertEq(blk.timestamp, block.timestamp); -// assertEq(blk.anchorBlockId, block.number - 1); -// assertEq(blk.nextTransitionId, 2); -// assertEq(blk.verifiedTransitionId, 0); -// } -// } - -// function test_inbox_prove_block_not_exist_will_revert() external transactBy(Alice) { -// uint64[] memory blockIds = new uint64[](1); -// blockIds[0] = 1; -// vm.expectRevert(ITaikoInbox.BlockNotFound.selector); -// _proveBlocksWithCorrectTransitions(blockIds); -// } - -// function test_inbox_prove_verified_block_will_revert() -// external -// transactBy(Alice) -// WhenMultipleBlocksAreProposedWithDefaultParameters(1) -// WhenMultipleBlocksAreProvedWithCorrectTransitions(1, 2) -// { -// uint64[] memory blockIds = new uint64[](1); -// blockIds[0] = 1; -// vm.expectRevert(ITaikoInbox.BlockNotFound.selector); -// _proveBlocksWithCorrectTransitions(blockIds); -// } - -// function test_inbox_propose_and_prove_many_blocks_with_first_transition_being_correct() -// external -// transactBy(Alice) -// WhenMultipleBlocksAreProposedWithDefaultParameters(9) -// WhenMultipleBlocksAreProvedWithCorrectTransitions(1, 10) -// WhenLogAllBlocksAndTransitions -// { -// // - All stats are correct and expected - -// ITaikoInbox.Stats1 memory stats1 = inbox.getStats1(); -// assertEq(stats1.lastSyncedBlockId, 5); -// assertEq(stats1.lastSyncedAt, block.timestamp); - -// ITaikoInbox.Stats2 memory stats2 = inbox.getStats2(); -// assertEq(stats2.numBlocks, 10); -// assertEq(stats2.lastVerifiedBlockId, 9); -// assertEq(stats2.paused, false); -// assertEq(stats2.lastProposedIn, block.number); -// assertEq(stats2.lastUnpausedAt, 0); - -// (uint64 blockId, ITaikoInbox.TransitionV3 memory tran) = -// inbox.getLastVerifiedTransitionV3(); -// assertEq(blockId, 9); -// assertEq(tran.blockHash, correctBlockhash(9)); -// assertEq(tran.stateRoot, bytes32(uint256(0))); - -// (blockId, tran) = inbox.getLastSyncedTransitionV3(); -// assertEq(blockId, 5); -// assertEq(tran.blockHash, correctBlockhash(5)); -// assertEq(tran.stateRoot, correctStateRoot(5)); - -// // - Verify genesis block -// ITaikoInbox.BlockV3 memory blk = inbox.getBlockV3(0); -// assertEq(blk.blockId, 0); -// assertEq(blk.metaHash, bytes32(uint256(1))); -// assertEq(blk.timestamp, genesisBlockProposedAt); -// assertEq(blk.anchorBlockId, genesisBlockProposedIn); -// assertEq(blk.nextTransitionId, 2); -// assertEq(blk.verifiedTransitionId, 1); - -// // Verify block data -// for (uint64 i = 1; i < 10; ++i) { -// blk = inbox.getBlockV3(i); -// assertEq(blk.blockId, i); -// assertEq(blk.metaHash, keccak256(abi.encode(blockMetadatas[i]))); - -// assertEq(blk.timestamp, block.timestamp); -// assertEq(blk.anchorBlockId, block.number - 1); -// assertEq(blk.nextTransitionId, 2); -// if (i % getConfig().stateRootSyncInternal == 0 || i == stats2.lastVerifiedBlockId) { -// assertEq(blk.verifiedTransitionId, 1); -// } else { -// assertEq(blk.verifiedTransitionId, 0); -// } -// } -// } - -// function test_inbox_propose_and_prove_many_blocks_with_second_transition_being_correct() -// external -// transactBy(Alice) -// WhenMultipleBlocksAreProposedWithDefaultParameters(9) -// WhenMultipleBlocksAreProvedWithWrongTransitions(1, 10) -// WhenMultipleBlocksAreProvedWithCorrectTransitions(1, 10) -// WhenLogAllBlocksAndTransitions -// { -// // - All stats are correct and expected - -// ITaikoInbox.Stats1 memory stats1 = inbox.getStats1(); -// assertEq(stats1.lastSyncedBlockId, 5); -// assertEq(stats1.lastSyncedAt, block.timestamp); - -// ITaikoInbox.Stats2 memory stats2 = inbox.getStats2(); -// assertEq(stats2.numBlocks, 10); -// assertEq(stats2.lastVerifiedBlockId, 9); -// assertEq(stats2.paused, false); -// assertEq(stats2.lastProposedIn, block.number); -// assertEq(stats2.lastUnpausedAt, 0); - -// // - Verify genesis block -// ITaikoInbox.BlockV3 memory blk = inbox.getBlockV3(0); -// assertEq(blk.blockId, 0); -// assertEq(blk.metaHash, bytes32(uint256(1))); -// assertEq(blk.timestamp, genesisBlockProposedAt); -// assertEq(blk.anchorBlockId, genesisBlockProposedIn); -// assertEq(blk.nextTransitionId, 2); -// assertEq(blk.verifiedTransitionId, 1); - -// // Verify block data -// for (uint64 i = 1; i < 10; ++i) { -// blk = inbox.getBlockV3(i); -// assertEq(blk.blockId, i); -// assertEq(blk.metaHash, keccak256(abi.encode(blockMetadatas[i]))); - -// assertEq(blk.timestamp, block.timestamp); -// assertEq(blk.anchorBlockId, block.number - 1); -// assertEq(blk.nextTransitionId, 3); -// if (i % getConfig().stateRootSyncInternal == 0 || i == stats2.lastVerifiedBlockId) { -// assertEq(blk.verifiedTransitionId, 2); -// } else { -// assertEq(blk.verifiedTransitionId, 0); -// } -// } -// } - -// function test_inbox_ring_buffer_will_be_reused() -// external -// transactBy(Alice) -// WhenMultipleBlocksAreProposedWithDefaultParameters(9) -// WhenMultipleBlocksAreProvedWithCorrectTransitions(1, 10) -// WhenMultipleBlocksAreProposedWithDefaultParameters(8) -// WhenLogAllBlocksAndTransitions -// WhenMultipleBlocksAreProvedWithCorrectTransitions(14, 16) -// WhenLogAllBlocksAndTransitions -// WhenMultipleBlocksAreProvedWithCorrectTransitions(10, 11) -// WhenLogAllBlocksAndTransitions -// { -// // - All stats are correct and expected - -// ITaikoInbox.Stats1 memory stats1 = inbox.getStats1(); -// assertEq(stats1.lastSyncedBlockId, 10); -// assertEq(stats1.lastSyncedAt, block.timestamp); - -// ITaikoInbox.Stats2 memory stats2 = inbox.getStats2(); -// assertEq(stats2.numBlocks, 18); -// assertEq(stats2.lastVerifiedBlockId, 10); -// assertEq(stats2.paused, false); -// assertEq(stats2.lastProposedIn, block.number); -// assertEq(stats2.lastUnpausedAt, 0); - -// (uint64 blockId, ITaikoInbox.TransitionV3 memory tran) = -// inbox.getLastVerifiedTransitionV3(); -// assertEq(blockId, 10); -// assertEq(tran.blockHash, correctBlockhash(10)); -// assertEq(tran.stateRoot, correctStateRoot(10)); - -// (blockId, tran) = inbox.getLastSyncedTransitionV3(); -// assertEq(blockId, 10); -// assertEq(tran.blockHash, correctBlockhash(10)); -// assertEq(tran.stateRoot, correctStateRoot(10)); - -// // Verify block data -// for (uint64 i = 8; i < 15; ++i) { -// ITaikoInbox.BlockV3 memory blk = inbox.getBlockV3(i); -// assertEq(blk.blockId, i); -// assertEq(blk.metaHash, keccak256(abi.encode(blockMetadatas[i]))); - -// assertEq(blk.timestamp, block.timestamp); -// assertEq(blk.anchorBlockId, block.number - 1); -// if (i == 8) { -// assertEq(blk.verifiedTransitionId, 0); -// assertEq(blk.nextTransitionId, 2); -// } else if (i == 9) { -// assertEq(blk.verifiedTransitionId, 1); -// assertEq(blk.nextTransitionId, 2); -// } else if (i == 10) { -// assertEq(blk.verifiedTransitionId, 1); -// assertEq(blk.nextTransitionId, 2); -// } else if (i == 11 || i == 12 || i == 13 || i == 16 || i == 17) { -// assertEq(blk.verifiedTransitionId, 0); -// assertEq(blk.nextTransitionId, 1); -// } else if (i == 14 || i == 15) { -// assertEq(blk.verifiedTransitionId, 0); -// assertEq(blk.nextTransitionId, 2); -// } -// } -// } - -// function test_inbox_reprove_the_same_block_is_ok() -// external -// transactBy(Alice) -// WhenMultipleBlocksAreProposedWithDefaultParameters(1) -// WhenLogAllBlocksAndTransitions -// { -// ITaikoInbox.BlockMetadataV3[] memory metas = new ITaikoInbox.BlockMetadataV3[](1); -// ITaikoInbox.TransitionV3[] memory transitions = new ITaikoInbox.TransitionV3[](1); - -// metas[0] = blockMetadatas[1]; - -// transitions[0].parentHash = bytes32(uint256(0x100)); -// transitions[0].blockHash = bytes32(uint256(0x101)); -// transitions[0].stateRoot = bytes32(uint256(0x102)); -// inbox.proveBlocksV3(metas, transitions, "proof"); -// _logAllBlocksAndTransitions(); - -// transitions[0].parentHash = bytes32(uint256(0x100)); -// transitions[0].blockHash = bytes32(uint256(0x111)); -// transitions[0].stateRoot = bytes32(uint256(0x112)); -// inbox.proveBlocksV3(metas, transitions, "proof"); -// _logAllBlocksAndTransitions(); - -// transitions[0].parentHash = bytes32(uint256(0x200)); -// transitions[0].blockHash = bytes32(uint256(0x201)); -// transitions[0].stateRoot = bytes32(uint256(0x202)); -// inbox.proveBlocksV3(metas, transitions, "proof"); -// _logAllBlocksAndTransitions(); - -// transitions[0].parentHash = bytes32(uint256(0x200)); -// transitions[0].blockHash = bytes32(uint256(0x211)); -// transitions[0].stateRoot = bytes32(uint256(0x212)); -// inbox.proveBlocksV3(metas, transitions, "proof"); -// _logAllBlocksAndTransitions(); -// } +import "./InboxTestBase.sol"; + +contract InboxTest_Suite1 is InboxTestBase { + function getConfig() internal pure override returns (ITaikoInbox.Config memory) { + return ITaikoInbox.Config({ + chainId: LibNetwork.TAIKO_MAINNET, + maxBatchProposals: 10, + batchRingBufferSize: 15, + maxBatchesToVerify: 5, + blockMaxGasLimit: 240_000_000, + livenessBond: 125e18, // 125 Taiko token + stateRootSyncInternal: 5, + maxAnchorHeightOffset: 64, + baseFeeConfig: LibSharedData.BaseFeeConfig({ + adjustmentQuotient: 8, + sharingPctg: 75, + gasIssuancePerSecond: 5_000_000, + minGasExcess: 1_340_000_000, // correspond to 0.008847185 gwei basefee + maxGasIssuancePerBlock: 600_000_000 // two minutes: 5_000_000 * 120 + }), + provingWindow: 1 hours, + maxSignalsToReceive: 16, + maxBlocksPerBatch: 256, + forkHeights: ITaikoInbox.ForkHeights({ ontake: 0, pacaya: 0 }) + }); + } + + function setUpOnEthereum() internal override { + super.setUpOnEthereum(); + bondToken = deployBondToken(); + } + + function test_inbox_query_right_after_genesis_block() external view { + // - All stats are correct and expected + ITaikoInbox.Stats1 memory stats1 = inbox.getStats1(); + assertEq(stats1.lastSyncedBatchId, 0); + assertEq(stats1.lastSyncedAt, 0); + + ITaikoInbox.Stats2 memory stats2 = inbox.getStats2(); + assertEq(stats2.numBatches, 1); + assertEq(stats2.lastVerifiedBatchId, 0); + assertEq(stats2.paused, false); + assertEq(stats2.lastProposedIn, genesisBlockProposedIn); + assertEq(stats2.lastUnpausedAt, 0); + + // - Verify genesis block + ITaikoInbox.Batch memory blk = inbox.getBatch(0); + assertEq(blk.batchId, 0); + assertEq(blk.metaHash, bytes32(uint256(1))); + assertEq(blk.timestamp, genesisBlockProposedAt); + assertEq(blk.anchorBlockId, genesisBlockProposedIn); + assertEq(blk.nextTransitionId, 2); + assertEq(blk.verifiedTransitionId, 1); + + (uint64 batchId, ITaikoInbox.Transition memory tran) = inbox.getLastVerifiedTransition(); + assertEq(batchId, 0); + assertEq(tran.blockHash, correctBlockhash(0)); + assertEq(tran.stateRoot, bytes32(uint256(0))); + + (batchId, tran) = inbox.getLastSyncedTransition(); + assertEq(batchId, 0); + assertEq(tran.blockHash, correctBlockhash(0)); + assertEq(tran.stateRoot, bytes32(uint256(0))); + } + + function test_inbox_query_batches_not_exist_will_revert() external { + vm.expectRevert(ITaikoInbox.BatchNotFound.selector); + inbox.getBatch(1); + } + + function test_inbox_max_block_proposal() + external + transactBy(Alice) + WhenMultipleBatchesAreProposedWithDefaultParameters(9) + WhenLogAllBatchesAndTransitions + { + // - All stats are correct and expected + + ITaikoInbox.Stats1 memory stats1 = inbox.getStats1(); + assertEq(stats1.lastSyncedBatchId, 0); + assertEq(stats1.lastSyncedAt, 0); + + ITaikoInbox.Stats2 memory stats2 = inbox.getStats2(); + assertEq(stats2.numBatches, 10); + assertEq(stats2.lastVerifiedBatchId, 0); + assertEq(stats2.paused, false); + assertEq(stats2.lastProposedIn, block.number); + assertEq(stats2.lastUnpausedAt, 0); + + // - Verify genesis block + ITaikoInbox.Batch memory blk = inbox.getBatch(0); + assertEq(blk.batchId, 0); + assertEq(blk.metaHash, bytes32(uint256(1))); + assertEq(blk.timestamp, genesisBlockProposedAt); + assertEq(blk.anchorBlockId, genesisBlockProposedIn); + assertEq(blk.nextTransitionId, 2); + assertEq(blk.verifiedTransitionId, 1); + + // Verify block data + for (uint64 i = 1; i < 10; ++i) { + blk = inbox.getBatch(i); + assertEq(blk.batchId, i); + assertEq(blk.metaHash, keccak256(abi.encode(batchMetadatas[i]))); + + assertEq(blk.timestamp, block.timestamp); + assertEq(blk.anchorBlockId, block.number - 1); + assertEq(blk.nextTransitionId, 1); + assertEq(blk.verifiedTransitionId, 0); + } + + // - Proposing one block block will revert + vm.expectRevert(ITaikoInbox.TooManyBatches.selector); + _proposeBatchesWithDefaultParameters({ numBatchesToPropose: 1 }); + } + + function test_inbox_exceed_max_block_proposal_will_revert() + external + transactBy(Alice) + WhenMultipleBatchesAreProposedWithDefaultParameters(9) + WhenLogAllBatchesAndTransitions + { + // - Proposing one block block will revert + vm.expectRevert(ITaikoInbox.TooManyBatches.selector); + _proposeBatchesWithDefaultParameters({ numBatchesToPropose: 1 }); + } + + function test_inbox_prove_with_wrong_transitions_will_not_finalize_blocks() + external + transactBy(Alice) + WhenMultipleBatchesAreProposedWithDefaultParameters(6) + WhenMultipleBatchesAreProvedWithWrongTransitions(1, 7) + WhenLogAllBatchesAndTransitions + { + // - All stats are correct and expected + + ITaikoInbox.Stats1 memory stats1 = inbox.getStats1(); + assertEq(stats1.lastSyncedBatchId, 0); + assertEq(stats1.lastSyncedAt, 0); + + ITaikoInbox.Stats2 memory stats2 = inbox.getStats2(); + assertEq(stats2.numBatches, 7); + assertEq(stats2.lastVerifiedBatchId, 0); + assertEq(stats2.paused, false); + assertEq(stats2.lastProposedIn, block.number); + assertEq(stats2.lastUnpausedAt, 0); + + // - Verify genesis block + ITaikoInbox.Batch memory blk = inbox.getBatch(0); + assertEq(blk.batchId, 0); + assertEq(blk.metaHash, bytes32(uint256(1))); + assertEq(blk.timestamp, genesisBlockProposedAt); + assertEq(blk.anchorBlockId, genesisBlockProposedIn); + assertEq(blk.nextTransitionId, 2); + assertEq(blk.verifiedTransitionId, 1); + + // Verify block data + for (uint64 i = 1; i < 7; ++i) { + blk = inbox.getBatch(i); + assertEq(blk.batchId, i); + assertEq(blk.metaHash, keccak256(abi.encode(batchMetadatas[i]))); + + assertEq(blk.timestamp, block.timestamp); + assertEq(blk.anchorBlockId, block.number - 1); + assertEq(blk.nextTransitionId, 2); + assertEq(blk.verifiedTransitionId, 0); + } + } + + function test_inbox_prove_block_not_exist_will_revert() external transactBy(Alice) { + uint64[] memory batchIds = new uint64[](1); + batchIds[0] = 1; + vm.expectRevert(ITaikoInbox.BatchNotFound.selector); + _proveBatchesWithCorrectTransitions(batchIds); + } + + function test_inbox_prove_verified_block_will_revert() + external + transactBy(Alice) + WhenMultipleBatchesAreProposedWithDefaultParameters(1) + WhenMultipleBatchesAreProvedWithCorrectTransitions(1, 2) + { + uint64[] memory batchIds = new uint64[](1); + batchIds[0] = 1; + vm.expectRevert(ITaikoInbox.BatchNotFound.selector); + _proveBatchesWithCorrectTransitions(batchIds); + } + + function test_inbox_propose_and_prove_many_blocks_with_first_transition_being_correct() + external + transactBy(Alice) + WhenMultipleBatchesAreProposedWithDefaultParameters(9) + WhenMultipleBatchesAreProvedWithCorrectTransitions(1, 10) + WhenLogAllBatchesAndTransitions + { + // - All stats are correct and expected + + ITaikoInbox.Stats1 memory stats1 = inbox.getStats1(); + assertEq(stats1.lastSyncedBatchId, 5); + assertEq(stats1.lastSyncedAt, block.timestamp); + + ITaikoInbox.Stats2 memory stats2 = inbox.getStats2(); + assertEq(stats2.numBatches, 10); + assertEq(stats2.lastVerifiedBatchId, 9); + assertEq(stats2.paused, false); + assertEq(stats2.lastProposedIn, block.number); + assertEq(stats2.lastUnpausedAt, 0); + + (uint64 batchId, ITaikoInbox.Transition memory tran) = inbox.getLastVerifiedTransition(); + assertEq(batchId, 9); + assertEq(tran.blockHash, correctBlockhash(9)); + assertEq(tran.stateRoot, bytes32(uint256(0))); + + (batchId, tran) = inbox.getLastSyncedTransition(); + assertEq(batchId, 5); + assertEq(tran.blockHash, correctBlockhash(5)); + assertEq(tran.stateRoot, correctStateRoot(5)); + + // - Verify genesis block + ITaikoInbox.Batch memory blk = inbox.getBatch(0); + assertEq(blk.batchId, 0); + assertEq(blk.metaHash, bytes32(uint256(1))); + assertEq(blk.timestamp, genesisBlockProposedAt); + assertEq(blk.anchorBlockId, genesisBlockProposedIn); + assertEq(blk.nextTransitionId, 2); + assertEq(blk.verifiedTransitionId, 1); + + // Verify block data + for (uint64 i = 1; i < 10; ++i) { + blk = inbox.getBatch(i); + assertEq(blk.batchId, i); + assertEq(blk.metaHash, keccak256(abi.encode(batchMetadatas[i]))); + + assertEq(blk.timestamp, block.timestamp); + assertEq(blk.anchorBlockId, block.number - 1); + assertEq(blk.nextTransitionId, 2); + if (i % getConfig().stateRootSyncInternal == 0 || i == stats2.lastVerifiedBatchId) { + assertEq(blk.verifiedTransitionId, 1); + } else { + assertEq(blk.verifiedTransitionId, 0); + } + } + } + + function test_inbox_propose_and_prove_many_blocks_with_second_transition_being_correct() + external + transactBy(Alice) + WhenMultipleBatchesAreProposedWithDefaultParameters(9) + WhenMultipleBatchesAreProvedWithWrongTransitions(1, 10) + WhenMultipleBatchesAreProvedWithCorrectTransitions(1, 10) + WhenLogAllBatchesAndTransitions + { + // - All stats are correct and expected + + ITaikoInbox.Stats1 memory stats1 = inbox.getStats1(); + assertEq(stats1.lastSyncedBatchId, 5); + assertEq(stats1.lastSyncedAt, block.timestamp); + + ITaikoInbox.Stats2 memory stats2 = inbox.getStats2(); + assertEq(stats2.numBatches, 10); + assertEq(stats2.lastVerifiedBatchId, 9); + assertEq(stats2.paused, false); + assertEq(stats2.lastProposedIn, block.number); + assertEq(stats2.lastUnpausedAt, 0); + + // - Verify genesis block + ITaikoInbox.Batch memory blk = inbox.getBatch(0); + assertEq(blk.batchId, 0); + assertEq(blk.metaHash, bytes32(uint256(1))); + assertEq(blk.timestamp, genesisBlockProposedAt); + assertEq(blk.anchorBlockId, genesisBlockProposedIn); + assertEq(blk.nextTransitionId, 2); + assertEq(blk.verifiedTransitionId, 1); + + // Verify block data + for (uint64 i = 1; i < 10; ++i) { + blk = inbox.getBatch(i); + assertEq(blk.batchId, i); + assertEq(blk.metaHash, keccak256(abi.encode(batchMetadatas[i]))); + + assertEq(blk.timestamp, block.timestamp); + assertEq(blk.anchorBlockId, block.number - 1); + assertEq(blk.nextTransitionId, 3); + if (i % getConfig().stateRootSyncInternal == 0 || i == stats2.lastVerifiedBatchId) { + assertEq(blk.verifiedTransitionId, 2); + } else { + assertEq(blk.verifiedTransitionId, 0); + } + } + } + + function test_inbox_ring_buffer_will_be_reused() + external + transactBy(Alice) + WhenMultipleBatchesAreProposedWithDefaultParameters(9) + WhenMultipleBatchesAreProvedWithCorrectTransitions(1, 10) + WhenMultipleBatchesAreProposedWithDefaultParameters(8) + WhenLogAllBatchesAndTransitions + WhenMultipleBatchesAreProvedWithCorrectTransitions(14, 16) + WhenLogAllBatchesAndTransitions + WhenMultipleBatchesAreProvedWithCorrectTransitions(10, 11) + WhenLogAllBatchesAndTransitions + { + // - All stats are correct and expected + + ITaikoInbox.Stats1 memory stats1 = inbox.getStats1(); + assertEq(stats1.lastSyncedBatchId, 10); + assertEq(stats1.lastSyncedAt, block.timestamp); + + ITaikoInbox.Stats2 memory stats2 = inbox.getStats2(); + assertEq(stats2.numBatches, 18); + assertEq(stats2.lastVerifiedBatchId, 10); + assertEq(stats2.paused, false); + assertEq(stats2.lastProposedIn, block.number); + assertEq(stats2.lastUnpausedAt, 0); + + (uint64 batchId, ITaikoInbox.Transition memory tran) = inbox.getLastVerifiedTransition(); + assertEq(batchId, 10); + assertEq(tran.blockHash, correctBlockhash(10)); + assertEq(tran.stateRoot, correctStateRoot(10)); + + (batchId, tran) = inbox.getLastSyncedTransition(); + assertEq(batchId, 10); + assertEq(tran.blockHash, correctBlockhash(10)); + assertEq(tran.stateRoot, correctStateRoot(10)); + + // Verify block data + for (uint64 i = 8; i < 15; ++i) { + ITaikoInbox.Batch memory blk = inbox.getBatch(i); + assertEq(blk.batchId, i); + assertEq(blk.metaHash, keccak256(abi.encode(batchMetadatas[i]))); + + assertEq(blk.timestamp, block.timestamp); + assertEq(blk.anchorBlockId, block.number - 1); + if (i == 8) { + assertEq(blk.verifiedTransitionId, 0); + assertEq(blk.nextTransitionId, 2); + } else if (i == 9) { + assertEq(blk.verifiedTransitionId, 1); + assertEq(blk.nextTransitionId, 2); + } else if (i == 10) { + assertEq(blk.verifiedTransitionId, 1); + assertEq(blk.nextTransitionId, 2); + } else if (i == 11 || i == 12 || i == 13 || i == 16 || i == 17) { + assertEq(blk.verifiedTransitionId, 0); + assertEq(blk.nextTransitionId, 1); + } else if (i == 14 || i == 15) { + assertEq(blk.verifiedTransitionId, 0); + assertEq(blk.nextTransitionId, 2); + } + } + } + + function test_inbox_reprove_the_same_block_is_ok() + external + transactBy(Alice) + WhenMultipleBatchesAreProposedWithDefaultParameters(1) + WhenLogAllBatchesAndTransitions + { + ITaikoInbox.BatchMetadata[] memory metas = new ITaikoInbox.BatchMetadata[](1); + ITaikoInbox.Transition[] memory transitions = new ITaikoInbox.Transition[](1); + + metas[0] = batchMetadatas[1]; + + transitions[0].parentHash = bytes32(uint256(0x100)); + transitions[0].blockHash = bytes32(uint256(0x101)); + transitions[0].stateRoot = bytes32(uint256(0x102)); + inbox.proveBatches(metas, transitions, "proof"); + _logAllBatchesAndTransitions(); + + transitions[0].parentHash = bytes32(uint256(0x100)); + transitions[0].blockHash = bytes32(uint256(0x111)); + transitions[0].stateRoot = bytes32(uint256(0x112)); + inbox.proveBatches(metas, transitions, "proof"); + _logAllBatchesAndTransitions(); + + transitions[0].parentHash = bytes32(uint256(0x200)); + transitions[0].blockHash = bytes32(uint256(0x201)); + transitions[0].stateRoot = bytes32(uint256(0x202)); + inbox.proveBatches(metas, transitions, "proof"); + _logAllBatchesAndTransitions(); + + transitions[0].parentHash = bytes32(uint256(0x200)); + transitions[0].blockHash = bytes32(uint256(0x211)); + transitions[0].stateRoot = bytes32(uint256(0x212)); + inbox.proveBatches(metas, transitions, "proof"); + _logAllBatchesAndTransitions(); + } // function test_proposeBlocksV3_reverts_for_invalid_proposer_and_preconfRouter() // external @@ -452,4 +450,4 @@ pragma solidity ^0.8.24; // _logAllBlocksAndTransitions(); // } -// } +} From aad180418c4a139e125da00fd00198e050915473 Mon Sep 17 00:00:00 2001 From: Daniel Wang Date: Sun, 12 Jan 2025 11:11:03 +0800 Subject: [PATCH 24/41] fix --- .../contracts/layer1/based/TaikoInbox.sol | 5 +- .../protocol/snapshots/InboxTest_Suite1.json | 4 + .../test/layer1/based/InboxTestBase.sol | 1 + .../test/layer1/based/InboxTest_Suite1.t.sol | 121 +++++++++--------- 4 files changed, 67 insertions(+), 64 deletions(-) create mode 100644 packages/protocol/snapshots/InboxTest_Suite1.json diff --git a/packages/protocol/contracts/layer1/based/TaikoInbox.sol b/packages/protocol/contracts/layer1/based/TaikoInbox.sol index a30c5a2eed2..58f3bfc22a0 100644 --- a/packages/protocol/contracts/layer1/based/TaikoInbox.sol +++ b/packages/protocol/contracts/layer1/based/TaikoInbox.sol @@ -460,9 +460,8 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { SyncBatch memory synced; - uint256 stopBlockId = (_config.maxBatchesToVerify * _length + _stats2.lastVerifiedBatchId).min( - _stats2.numBatches - ); + uint256 stopBlockId = (_config.maxBatchesToVerify * _length + _stats2.lastVerifiedBatchId) + .min(_stats2.numBatches); for (++batchId; batchId < stopBlockId; ++batchId) { slot = batchId % _config.batchRingBufferSize; diff --git a/packages/protocol/snapshots/InboxTest_Suite1.json b/packages/protocol/snapshots/InboxTest_Suite1.json new file mode 100644 index 00000000000..09eeca0b90f --- /dev/null +++ b/packages/protocol/snapshots/InboxTest_Suite1.json @@ -0,0 +1,4 @@ +{ + "proposeBatch": "1164762", + "proveBatches": "275868" +} diff --git a/packages/protocol/test/layer1/based/InboxTestBase.sol b/packages/protocol/test/layer1/based/InboxTestBase.sol index ad3be723eb2..d08a396c6ea 100644 --- a/packages/protocol/test/layer1/based/InboxTestBase.sol +++ b/packages/protocol/test/layer1/based/InboxTestBase.sol @@ -89,6 +89,7 @@ abstract contract InboxTestBase is Layer1Test { { ITaikoInbox.BatchParams memory batchParams; batchParams.blocks = new ITaikoInbox.BlockParams[](1); + // TODO: remove the next line batchParams.blocks[0] = ITaikoInbox.BlockParams({ numTransactions: 0, timeThift: 0 }); batchIds = new uint64[](numBatchesToPropose); diff --git a/packages/protocol/test/layer1/based/InboxTest_Suite1.t.sol b/packages/protocol/test/layer1/based/InboxTest_Suite1.t.sol index 2fc34999a16..7cea69eb755 100644 --- a/packages/protocol/test/layer1/based/InboxTest_Suite1.t.sol +++ b/packages/protocol/test/layer1/based/InboxTest_Suite1.t.sol @@ -389,65 +389,64 @@ contract InboxTest_Suite1 is InboxTestBase { _logAllBatchesAndTransitions(); } -// function test_proposeBlocksV3_reverts_for_invalid_proposer_and_preconfRouter() -// external -// transactBy(Alice) -// { -// uint64 count = 1; - -// vm.expectRevert(ITaikoInbox.CustomProposerNotAllowed.selector); -// inbox.proposeBlocksV3(Alice, address(0), new ITaikoInbox.BlockParamsV3[](count), -// "txList"); - -// vm.startPrank(deployer); -// address preconfRouter = Bob; -// resolver.registerAddress(block.chainid, "preconf_router", preconfRouter); -// vm.stopPrank(); - -// vm.startPrank(Alice); -// vm.expectRevert(ITaikoInbox.NotPreconfRouter.selector); -// inbox.proposeBlocksV3( -// preconfRouter, address(0), new ITaikoInbox.BlockParamsV3[](count), "txList" -// ); -// vm.stopPrank(); - -// vm.startPrank(preconfRouter); -// vm.expectRevert(ITaikoInbox.CustomProposerMissing.selector); -// inbox.proposeBlocksV3( -// address(0), address(0), new ITaikoInbox.BlockParamsV3[](count), "txList" -// ); -// vm.stopPrank(); -// } - -// function test_inbox_measure_gas_used() -// external -// transactBy(Alice) -// WhenMultipleBlocksAreProposedWithDefaultParameters(9) -// WhenMultipleBlocksAreProvedWithCorrectTransitions(1, 10) -// WhenLogAllBlocksAndTransitions -// { -// uint64 count = 1; - -// vm.startSnapshotGas("proposeBlocksV3"); -// ITaikoInbox.BlockMetadataV3[] memory metas = inbox.proposeBlocksV3( -// address(0), address(0), new ITaikoInbox.BlockParamsV3[](count), "txList" -// ); -// uint256 gasProposeBlocksV3 = vm.stopSnapshotGas("proposeBlocksV3"); -// console2.log("Gas per block - proposing:", gasProposeBlocksV3 / count); - -// ITaikoInbox.TransitionV3[] memory transitions = new ITaikoInbox.TransitionV3[](count); -// for (uint256 i; i < metas.length; ++i) { -// transitions[i].parentHash = correctBlockhash(metas[i].blockId - 1); -// transitions[i].blockHash = correctBlockhash(metas[i].blockId); -// transitions[i].stateRoot = correctStateRoot(metas[i].blockId); -// } - -// vm.startSnapshotGas("proveBlocksV3"); -// inbox.proveBlocksV3(metas, transitions, "proof"); -// uint256 gasProveBlocksV3 = vm.stopSnapshotGas("proveBlocksV3"); -// console2.log("Gas per block - proving:", gasProveBlocksV3 / count); -// console2.log("Gas per block - total:", (gasProposeBlocksV3 + gasProveBlocksV3) / count); - -// _logAllBlocksAndTransitions(); -// } + function test_proposeBatch_reverts_for_invalid_proposer_and_preconfRouter() + external + transactBy(Alice) + { + ITaikoInbox.BatchParams memory params; + + vm.expectRevert(ITaikoInbox.CustomProposerNotAllowed.selector); + inbox.proposeBatch(Alice, address(0), params, "txList"); + + vm.startPrank(deployer); + address preconfRouter = Bob; + resolver.registerAddress(block.chainid, "preconf_router", preconfRouter); + vm.stopPrank(); + + vm.startPrank(Alice); + vm.expectRevert(ITaikoInbox.NotPreconfRouter.selector); + inbox.proposeBatch(preconfRouter, address(0), params, "txList"); + vm.stopPrank(); + + vm.startPrank(preconfRouter); + vm.expectRevert(ITaikoInbox.CustomProposerMissing.selector); + inbox.proposeBatch(address(0), address(0), params, "txList"); + vm.stopPrank(); + } + + function test_inbox_measure_gas_used() + external + transactBy(Alice) + WhenMultipleBatchesAreProposedWithDefaultParameters(9) + WhenMultipleBatchesAreProvedWithCorrectTransitions(1, 10) + WhenLogAllBatchesAndTransitions + { + uint64 count = 3; + + vm.startSnapshotGas("proposeBatch"); + + uint64[] memory batchIds = _proposeBatchesWithDefaultParameters(count); + + uint256 gasProposeBatches = vm.stopSnapshotGas("proposeBatch"); + console2.log("Gas per block - proposing:", gasProposeBatches / count); + + ITaikoInbox.BatchMetadata[] memory metas = new ITaikoInbox.BatchMetadata[](count); + ITaikoInbox.Transition[] memory transitions = new ITaikoInbox.Transition[](count); + + for (uint256 i; i < batchIds.length; ++i) { + metas[i] = batchMetadatas[batchIds[i]]; + + transitions[i].parentHash = correctBlockhash(batchIds[i] - 1); + transitions[i].blockHash = correctBlockhash(batchIds[i]); + transitions[i].stateRoot = correctStateRoot(batchIds[i]); + } + + vm.startSnapshotGas("proveBatches"); + inbox.proveBatches(metas, transitions, "proof"); + uint256 gasProveBatches = vm.stopSnapshotGas("proveBatches"); + console2.log("Gas per block - proving:", gasProveBatches / count); + console2.log("Gas per block - total:", (gasProposeBatches + gasProveBatches) / count); + + _logAllBatchesAndTransitions(); + } } From 15ec428fe12ff6f27ed42af4d89c8a2ca6e4e529 Mon Sep 17 00:00:00 2001 From: Daniel Wang Date: Sun, 12 Jan 2025 11:14:55 +0800 Subject: [PATCH 25/41] fix --- .../protocol/snapshots/InboxTest_Suite1.json | 4 ++-- ...ockParams.t.sol => InBoxTest_Params.t.sol} | 20 +++++++------------ .../test/layer1/based/InboxTestBase.sol | 2 -- 3 files changed, 9 insertions(+), 17 deletions(-) rename packages/protocol/test/layer1/based/{InBoxTest_BlockParams.t.sol => InBoxTest_Params.t.sol} (91%) diff --git a/packages/protocol/snapshots/InboxTest_Suite1.json b/packages/protocol/snapshots/InboxTest_Suite1.json index 09eeca0b90f..cddc1d6260e 100644 --- a/packages/protocol/snapshots/InboxTest_Suite1.json +++ b/packages/protocol/snapshots/InboxTest_Suite1.json @@ -1,4 +1,4 @@ { - "proposeBatch": "1164762", - "proveBatches": "275868" + "proposeBatch": "1164606", + "proveBatches": "275864" } diff --git a/packages/protocol/test/layer1/based/InBoxTest_BlockParams.t.sol b/packages/protocol/test/layer1/based/InBoxTest_Params.t.sol similarity index 91% rename from packages/protocol/test/layer1/based/InBoxTest_BlockParams.t.sol rename to packages/protocol/test/layer1/based/InBoxTest_Params.t.sol index 6d567d176b7..430c15d562d 100644 --- a/packages/protocol/test/layer1/based/InBoxTest_BlockParams.t.sol +++ b/packages/protocol/test/layer1/based/InBoxTest_Params.t.sol @@ -3,7 +3,7 @@ pragma solidity ^0.8.24; import "./InboxTestBase.sol"; -contract InBoxTest_BlockParams is InboxTestBase { +contract InBoxTest_Params is InboxTestBase { function getConfig() internal pure override returns (ITaikoInbox.Config memory) { return ITaikoInbox.Config({ chainId: LibNetwork.TAIKO_MAINNET, @@ -33,10 +33,7 @@ contract InBoxTest_BlockParams is InboxTestBase { bondToken = deployBondToken(); } - function test_validateBlockParams_defaults_when_anchorBlockId_is_zero() - external - transactBy(Alice) - { + function test_validateParams_defaults_when_anchorBlockId_is_zero() external transactBy(Alice) { ITaikoInbox.BlockParams[] memory blocks = new ITaikoInbox.BlockParams[](1); blocks[0] = ITaikoInbox.BlockParams({ numTransactions: 0, timeThift: 0 }); @@ -60,7 +57,7 @@ contract InBoxTest_BlockParams is InboxTestBase { assertEq(meta.anchorBlockId, expectedAnchorBlockId, "AnchorBlockId mismatch"); } - function test_validateBlockParams_reverts_when_anchorBlockId_too_small() + function test_validateParams_reverts_when_anchorBlockId_too_small() external transactBy(Alice) { @@ -90,7 +87,7 @@ contract InBoxTest_BlockParams is InboxTestBase { inbox.proposeBatch(address(0), address(0), params, "txList"); } - function test_validateBlockParams_reverts_when_anchorBlockId_too_large() + function test_validateParams_reverts_when_anchorBlockId_too_large() external transactBy(Alice) { @@ -116,7 +113,7 @@ contract InBoxTest_BlockParams is InboxTestBase { inbox.proposeBatch(address(0), address(0), params, "txList"); } - function test_validateBlockParams_reverts_when_anchorBlockId_smaller_than_parent() + function test_validateParams_reverts_when_anchorBlockId_smaller_than_parent() external transactBy(Alice) { @@ -143,7 +140,7 @@ contract InBoxTest_BlockParams is InboxTestBase { inbox.proposeBatch(address(0), address(0), params, "txList"); } - function test_validateBlockParams_when_anchorBlockId_is_not_zero() external transactBy(Alice) { + function test_validateParams_when_anchorBlockId_is_not_zero() external transactBy(Alice) { ITaikoInbox.BlockParams[] memory blocks = new ITaikoInbox.BlockParams[](1); blocks[0] = ITaikoInbox.BlockParams({ numTransactions: 0, timeThift: 0 }); ITaikoInbox.BatchParams memory params = ITaikoInbox.BatchParams({ @@ -165,10 +162,7 @@ contract InBoxTest_BlockParams is InboxTestBase { assertEq(meta.anchorBlockId, expectedAnchorBlockId, "AnchorBlockId mismatch"); } - function test_validateBlockParams_reverts_when_timestamp_too_large() - external - transactBy(Alice) - { + function test_validateParams_reverts_when_timestamp_too_large() external transactBy(Alice) { ITaikoInbox.BlockParams[] memory blocks = new ITaikoInbox.BlockParams[](1); blocks[0] = ITaikoInbox.BlockParams({ numTransactions: 0, timeThift: 0 }); ITaikoInbox.BatchParams memory params = ITaikoInbox.BatchParams({ diff --git a/packages/protocol/test/layer1/based/InboxTestBase.sol b/packages/protocol/test/layer1/based/InboxTestBase.sol index d08a396c6ea..4663928aa3c 100644 --- a/packages/protocol/test/layer1/based/InboxTestBase.sol +++ b/packages/protocol/test/layer1/based/InboxTestBase.sol @@ -89,8 +89,6 @@ abstract contract InboxTestBase is Layer1Test { { ITaikoInbox.BatchParams memory batchParams; batchParams.blocks = new ITaikoInbox.BlockParams[](1); - // TODO: remove the next line - batchParams.blocks[0] = ITaikoInbox.BlockParams({ numTransactions: 0, timeThift: 0 }); batchIds = new uint64[](numBatchesToPropose); From ef8d096e7799fcce370ec0104ed7d80350178e3b Mon Sep 17 00:00:00 2001 From: Daniel Wang Date: Sun, 12 Jan 2025 11:34:43 +0800 Subject: [PATCH 26/41] more fix --- .../contracts/layer1/based/ITaikoInbox.sol | 9 ++-- .../contracts/layer1/based/TaikoInbox.sol | 51 +++++++++++-------- .../protocol/snapshots/InboxTest_Suite1.json | 2 +- 3 files changed, 35 insertions(+), 27 deletions(-) diff --git a/packages/protocol/contracts/layer1/based/ITaikoInbox.sol b/packages/protocol/contracts/layer1/based/ITaikoInbox.sol index d55d2b52ce3..60d70a369a4 100644 --- a/packages/protocol/contracts/layer1/based/ITaikoInbox.sol +++ b/packages/protocol/contracts/layer1/based/ITaikoInbox.sol @@ -67,13 +67,13 @@ interface ITaikoInbox { /// @notice 3 slots used. struct Batch { bytes32 metaHash; // slot 1 - address _reserved2; - uint96 _reserved3; + uint64 lastBlockId; + uint192 _reserved3; uint64 batchId; // slot 3 uint64 timestamp; uint64 anchorBlockId; uint24 nextTransitionId; - uint8 numSubBlocks; + uint8 reserved4; // The ID of the transaction that is used to verify this batch. However, if this batch is // not verified as the last one in a transaction, verifiedTransitionId will remain zero. uint24 verifiedTransitionId; @@ -204,13 +204,13 @@ interface ITaikoInbox { error BatchNotFound(); error BatchVerified(); error BlobNotFound(); + error BlockNotFound(); error BlobNotSpecified(); error ContractPaused(); error CustomProposerMissing(); error CustomProposerNotAllowed(); error EtherNotPaidAsBond(); error InsufficientBond(); - error InvalidBlockParams(); error InvalidForkHeight(); error InvalidGenesisBlockHash(); error InvalidTransitionBlockHash(); @@ -227,6 +227,7 @@ interface ITaikoInbox { error TimestampTooLarge(); error TimestampTooSmall(); error TooManyBatches(); + error TooManyBlocks(); error TooManySignals(); error TransitionNotFound(); diff --git a/packages/protocol/contracts/layer1/based/TaikoInbox.sol b/packages/protocol/contracts/layer1/based/TaikoInbox.sol index 58f3bfc22a0..268ad9da1d0 100644 --- a/packages/protocol/contracts/layer1/based/TaikoInbox.sol +++ b/packages/protocol/contracts/layer1/based/TaikoInbox.sol @@ -90,9 +90,9 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { } // Keep track of last batch's information. - Batch storage parentBatch; + Batch storage lastBatch; unchecked { - parentBatch = state.batches[(stats2.numBatches - 1) % config.batchRingBufferSize]; + lastBatch = state.batches[(stats2.numBatches - 1) % config.batchRingBufferSize]; } bool calldataUsed = _txList.length != 0; @@ -105,7 +105,7 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { config.maxAnchorHeightOffset, config.maxSignalsToReceive, config.maxBlocksPerBatch, - parentBatch + lastBatch ); // This section constructs the metadata for the proposed batch, which is crucial for @@ -124,7 +124,7 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { batchId: stats2.numBatches, gasLimit: config.blockMaxGasLimit, timestamp: updatedParams.timestamp, - parentMetaHash: parentBatch.metaHash, + parentMetaHash: lastBatch.metaHash, proposer: _proposer, livenessBond: config.livenessBond, proposedAt: uint64(block.timestamp), @@ -152,8 +152,17 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { batch.timestamp = updatedParams.timestamp; batch.anchorBlockId = updatedParams.anchorBlockId; batch.nextTransitionId = 1; - batch.numSubBlocks = uint8(_batchParams.blocks.length); batch.verifiedTransitionId = 0; + batch.reserved4 = 0; + // SSTORE }} + + // SSTORE #3 {{ + if (stats2.numBatches == config.forkHeights.pacaya) { + batch.lastBlockId = batch.batchId + uint8(_batchParams.blocks.length) - 1; + } else { + batch.lastBlockId = lastBatch.lastBlockId + uint8(_batchParams.blocks.length); + } + batch._reserved3 = 0; // SSTORE }} unchecked { @@ -458,7 +467,7 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { uint24 tid = batch.verifiedTransitionId; bytes32 blockHash = state.transitions[slot][tid].blockHash; - SyncBatch memory synced; + SyncBlock memory synced; uint256 stopBlockId = (_config.maxBatchesToVerify * _length + _stats2.lastVerifiedBatchId) .min(_stats2.numBatches); @@ -481,7 +490,7 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { blockHash = ts.blockHash; if (batchId % _config.stateRootSyncInternal == 0) { - synced.batchId = batchId; + synced.blockId = batch.lastBlockId; synced.tid = tid; synced.stateRoot = ts.stateRoot; } @@ -503,15 +512,15 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { batch.verifiedTransitionId = tid; emit BatchesVerified(_stats2.lastVerifiedBatchId, blockHash); - if (synced.batchId != 0) { - if (synced.batchId != _stats2.lastVerifiedBatchId) { + if (synced.blockId != 0) { + if (synced.blockId != _stats2.lastVerifiedBatchId) { // We write the synced batch's verifiedTransitionId to storage - batch = state.batches[synced.batchId % _config.batchRingBufferSize]; + batch = state.batches[synced.blockId % _config.batchRingBufferSize]; batch.verifiedTransitionId = synced.tid; } Stats1 memory stats1 = state.stats1; - stats1.lastSyncedBatchId = synced.batchId; + stats1.lastSyncedBatchId = synced.blockId; stats1.lastSyncedAt = uint64(block.timestamp); state.stats1 = stats1; @@ -519,7 +528,7 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { // Ask signal service to write cross chain signal ISignalService(resolve(LibStrings.B_SIGNAL_SERVICE, false)).syncChainData( - _config.chainId, LibStrings.H_STATE_ROOT, synced.batchId, synced.stateRoot + _config.chainId, LibStrings.H_STATE_ROOT, synced.blockId, synced.stateRoot ); } } @@ -567,7 +576,7 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { uint64 _maxAnchorHeightOffset, uint8 _maxSignalsToReceive, uint16 _maxBlocksPerBatch, - Batch memory _parentBatch + Batch memory _lastBatch ) private view @@ -583,7 +592,7 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { ); require(_params.anchorBlockId < block.number, AnchorBlockIdTooLarge()); require( - _params.anchorBlockId >= _parentBatch.anchorBlockId, + _params.anchorBlockId >= _lastBatch.anchorBlockId, AnchorBlockIdSmallerThanParent() ); updatedParams_.anchorBlockId = _params.anchorBlockId; @@ -599,7 +608,7 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { >= block.timestamp, TimestampTooSmall() ); - require(_params.timestamp >= _parentBatch.timestamp, TimestampSmallerThanParent()); + require(_params.timestamp >= _lastBatch.timestamp, TimestampSmallerThanParent()); updatedParams_.timestamp = _params.timestamp; } @@ -613,7 +622,7 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { // Check if parent batch has the right meta hash. This is to allow the proposer to // make sure the batch builds on the expected latest chain state. require( - _params.parentMetaHash == 0 || _params.parentMetaHash == _parentBatch.metaHash, + _params.parentMetaHash == 0 || _params.parentMetaHash == _lastBatch.metaHash, ParentMetaHashMismatch() ); } @@ -629,10 +638,8 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { } } - require( - _params.blocks.length != 0 && _params.blocks.length <= _maxBlocksPerBatch, - InvalidBlockParams() - ); + require(_params.blocks.length != 0, BlockNotFound()); + require(_params.blocks.length <= _maxBlocksPerBatch, TooManyBlocks()); } // Memory-only structs ---------------------------------------------------------------------- @@ -642,8 +649,8 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { uint64 timestamp; } - struct SyncBatch { - uint64 batchId; + struct SyncBlock { + uint64 blockId; uint24 tid; bytes32 stateRoot; } diff --git a/packages/protocol/snapshots/InboxTest_Suite1.json b/packages/protocol/snapshots/InboxTest_Suite1.json index cddc1d6260e..395a171ccb9 100644 --- a/packages/protocol/snapshots/InboxTest_Suite1.json +++ b/packages/protocol/snapshots/InboxTest_Suite1.json @@ -1,4 +1,4 @@ { - "proposeBatch": "1164606", + "proposeBatch": "1227812", "proveBatches": "275864" } From cf01330b8b09bf97d7916913f30b4e8e8f9a6a06 Mon Sep 17 00:00:00 2001 From: dantaik <99078276+dantaik@users.noreply.github.com> Date: Sun, 12 Jan 2025 03:39:42 +0000 Subject: [PATCH 27/41] forge fmt & update contract layout tables --- packages/protocol/snapshots/InboxTest_Suite1.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/protocol/snapshots/InboxTest_Suite1.json b/packages/protocol/snapshots/InboxTest_Suite1.json index 395a171ccb9..4db9c9bb837 100644 --- a/packages/protocol/snapshots/InboxTest_Suite1.json +++ b/packages/protocol/snapshots/InboxTest_Suite1.json @@ -1,4 +1,4 @@ { "proposeBatch": "1227812", - "proveBatches": "275864" -} + "proveBatches": "275970" +} \ No newline at end of file From c40ae0e1d8bfe6fc07eab92b10c9441c3ffb27bd Mon Sep 17 00:00:00 2001 From: Daniel Wang Date: Sun, 12 Jan 2025 11:43:54 +0800 Subject: [PATCH 28/41] fix --- .../contracts/layer1/based/ITaikoInbox.sol | 2 +- .../contracts/layer1/based/TaikoInbox.sol | 2 +- .../layer1/fork/V2ToV3ForkManager.sol | 37 ------------------- .../protocol/snapshots/InboxTest_Suite1.json | 4 -- .../test/layer1/based/InboxTestBase.sol | 23 ++++++++++-- .../based/InboxTest_CalldataForTxList.t.sol | 12 +++--- .../test/layer1/based/InboxTest_Suite1.t.sol | 14 +++---- 7 files changed, 34 insertions(+), 60 deletions(-) delete mode 100644 packages/protocol/contracts/layer1/fork/V2ToV3ForkManager.sol delete mode 100644 packages/protocol/snapshots/InboxTest_Suite1.json diff --git a/packages/protocol/contracts/layer1/based/ITaikoInbox.sol b/packages/protocol/contracts/layer1/based/ITaikoInbox.sol index 60d70a369a4..a6dda1de2d6 100644 --- a/packages/protocol/contracts/layer1/based/ITaikoInbox.sol +++ b/packages/protocol/contracts/layer1/based/ITaikoInbox.sol @@ -52,7 +52,7 @@ interface ITaikoInbox { uint64 anchorBlockId; bytes32 anchorBlockHash; bytes32[] signalSlots; - bytes blocks; + BlockParams[] blocks; bytes32 anchorInput; LibSharedData.BaseFeeConfig baseFeeConfig; } diff --git a/packages/protocol/contracts/layer1/based/TaikoInbox.sol b/packages/protocol/contracts/layer1/based/TaikoInbox.sol index 268ad9da1d0..e75aeccfcde 100644 --- a/packages/protocol/contracts/layer1/based/TaikoInbox.sol +++ b/packages/protocol/contracts/layer1/based/TaikoInbox.sol @@ -135,7 +135,7 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { anchorBlockId: updatedParams.anchorBlockId, anchorBlockHash: blockhash(updatedParams.anchorBlockId), signalSlots: _batchParams.signalSlots, - blocks: abi.encode(_batchParams.blocks), + blocks: _batchParams.blocks, anchorInput: _batchParams.anchorInput, baseFeeConfig: config.baseFeeConfig }); diff --git a/packages/protocol/contracts/layer1/fork/V2ToV3ForkManager.sol b/packages/protocol/contracts/layer1/fork/V2ToV3ForkManager.sol deleted file mode 100644 index a7ef6e674b8..00000000000 --- a/packages/protocol/contracts/layer1/fork/V2ToV3ForkManager.sol +++ /dev/null @@ -1,37 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.24; - -import "./ForkManager.sol"; - -/// @title TaikoV2Selectors (Ontake) -/// @custom:security-contact security@taiko.xyz -/// @notice This interface is used to route specific transactions to the v2 version of the contract. -/// @dev Function selectors are calculated independently of the return type. Therefore, -/// we have omitted the `returns` statements from all functions to avoid maintaining -/// the return struct definitions. -interface TaikoV2Selectors { - function proposeBlocksV2(bytes[] calldata, bytes[] calldata) external; - function proveBlocks(uint64[] calldata, bytes[] calldata, bytes calldata) external; - function getBlockV2(uint64) external; - function getTransition(uint64, uint32) external; - function getConfig() external; -} - -/// @title V2ToV3ForkManager (Ontake -> Pacaya) -/// @custom:security-contact security@taiko.xyz -contract V2ToV3ForkManager is ForkManager { - constructor( - address _v2OntakeFork, - address _v3PacayaFork - ) - ForkManager(_v2OntakeFork, _v3PacayaFork) - { } - - function shouldRouteToOldFork(bytes4 _selector) internal pure override returns (bool) { - return _selector == TaikoV2Selectors.proposeBlocksV2.selector - || _selector == TaikoV2Selectors.proveBlocks.selector - || _selector == TaikoV2Selectors.getBlockV2.selector - || _selector == TaikoV2Selectors.getTransition.selector - || _selector == TaikoV2Selectors.getConfig.selector; - } -} diff --git a/packages/protocol/snapshots/InboxTest_Suite1.json b/packages/protocol/snapshots/InboxTest_Suite1.json deleted file mode 100644 index 4db9c9bb837..00000000000 --- a/packages/protocol/snapshots/InboxTest_Suite1.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "proposeBatch": "1227812", - "proveBatches": "275970" -} \ No newline at end of file diff --git a/packages/protocol/test/layer1/based/InboxTestBase.sol b/packages/protocol/test/layer1/based/InboxTestBase.sol index 4663928aa3c..1efc0b7f2df 100644 --- a/packages/protocol/test/layer1/based/InboxTestBase.sol +++ b/packages/protocol/test/layer1/based/InboxTestBase.sol @@ -5,7 +5,7 @@ import "../Layer1Test.sol"; import "test/layer1/based/helpers/Verifier_ToggleStub.sol"; abstract contract InboxTestBase is Layer1Test { - mapping(uint256 => ITaikoInbox.BatchMetadata) internal batchMetadatas; + mapping(uint256 => bytes) private _batchMetadatas; ITaikoInbox internal inbox; TaikoToken internal bondToken; SignalService internal signalService; @@ -73,6 +73,21 @@ abstract contract InboxTestBase is Layer1Test { // internal helper functions // ------------------------------------------------------------------- + function _saveMetadata(ITaikoInbox.BatchMetadata memory _metadata) internal { + _batchMetadatas[_metadata.batchId] = abi.encode(_metadata); + } + + function _loadMetadata(uint64 _batchId) + internal + view + returns (ITaikoInbox.BatchMetadata memory meta_) + { + bytes memory data = _batchMetadatas[_batchId]; + if (data.length != 0) { + meta_ = abi.decode(data, (ITaikoInbox.BatchMetadata)); + } + } + function _proposeBatchesWithDefaultParameters(uint256 numBatchesToPropose) internal returns (uint64[] memory batchIds) @@ -95,7 +110,7 @@ abstract contract InboxTestBase is Layer1Test { for (uint256 i; i < numBatchesToPropose; ++i) { ITaikoInbox.BatchMetadata memory meta = inbox.proposeBatch(address(0), address(0), batchParams, txList); - batchMetadatas[meta.batchId] = meta; + _saveMetadata(meta); batchIds[i] = meta.batchId; } } @@ -105,7 +120,7 @@ abstract contract InboxTestBase is Layer1Test { ITaikoInbox.Transition[] memory transitions = new ITaikoInbox.Transition[](batchIds.length); for (uint256 i; i < metas.length; ++i) { - metas[i] = batchMetadatas[batchIds[i]]; + metas[i] = _loadMetadata(batchIds[i]); transitions[i].parentHash = correctBlockhash(batchIds[i] - 1); transitions[i].blockHash = correctBlockhash(batchIds[i]); transitions[i].stateRoot = correctStateRoot(batchIds[i]); @@ -119,7 +134,7 @@ abstract contract InboxTestBase is Layer1Test { ITaikoInbox.Transition[] memory transitions = new ITaikoInbox.Transition[](batchIds.length); for (uint256 i; i < metas.length; ++i) { - metas[i] = batchMetadatas[batchIds[i]]; + metas[i] = _loadMetadata(batchIds[i]); transitions[i].parentHash = randBytes32(); transitions[i].blockHash = randBytes32(); transitions[i].stateRoot = randBytes32(); diff --git a/packages/protocol/test/layer1/based/InboxTest_CalldataForTxList.t.sol b/packages/protocol/test/layer1/based/InboxTest_CalldataForTxList.t.sol index f3546d278a1..416d86cf0da 100644 --- a/packages/protocol/test/layer1/based/InboxTest_CalldataForTxList.t.sol +++ b/packages/protocol/test/layer1/based/InboxTest_CalldataForTxList.t.sol @@ -51,7 +51,7 @@ contract InboxTest_CalldataForTxList is InboxTestBase { _proposeBatchesWithDefaultParameters({ numBatchesToPropose: 1, txList: txList }); for (uint256 i; i < batchIds.length; ++i) { - ITaikoInbox.BatchMetadata memory meta = batchMetadatas[batchIds[i]]; + ITaikoInbox.BatchMetadata memory meta = _loadMetadata(batchIds[i]); assertEq(meta.txListHash, expectedHash); } @@ -118,7 +118,7 @@ contract InboxTest_CalldataForTxList is InboxTestBase { inbox.proposeBatch(address(0), address(0), batchParams, ""); assertTrue(meta.txListHash != 0, "txListHash should not be zero for valid blobIndex"); - batchMetadatas[meta.batchId] = meta; + _saveMetadata(meta); vm.prank(Alice); uint64[] memory batchIds = new uint64[](1); @@ -142,12 +142,12 @@ contract InboxTest_CalldataForTxList is InboxTestBase { vm.prank(Alice); uint64[] memory batchIds1 = _proposeBatchesWithDefaultParameters(1, txList1); - ITaikoInbox.BatchMetadata memory meta1 = batchMetadatas[batchIds1[0]]; + ITaikoInbox.BatchMetadata memory meta1 = _loadMetadata(batchIds1[0]); assertEq(meta1.txListHash, expectedHash1, "txListHash mismatch for block 1"); vm.prank(Alice); uint64[] memory batchIds2 = _proposeBatchesWithDefaultParameters(1, txList2); - ITaikoInbox.BatchMetadata memory meta2 = batchMetadatas[batchIds2[0]]; + ITaikoInbox.BatchMetadata memory meta2 = _loadMetadata(batchIds2[0]); assertEq(meta2.txListHash, expectedHash2, "txListHash mismatch for block 2"); vm.prank(Alice); @@ -175,14 +175,14 @@ contract InboxTest_CalldataForTxList is InboxTestBase { bytes32 incorrectHash = keccak256(abi.encodePacked("incorrect txList")); // Attempt to prove the block with the incorrect txList - ITaikoInbox.BatchMetadata memory meta = batchMetadatas[batchIds[0]]; + ITaikoInbox.BatchMetadata memory meta = _loadMetadata(batchIds[0]); meta.txListHash = incorrectHash; ITaikoInbox.BatchMetadata[] memory metas = new ITaikoInbox.BatchMetadata[](batchIds.length); ITaikoInbox.Transition[] memory transitions = new ITaikoInbox.Transition[](batchIds.length); for (uint256 i; i < batchIds.length; ++i) { - metas[i] = batchMetadatas[batchIds[i]]; + metas[i] = _loadMetadata(batchIds[i]); metas[i].txListHash = incorrectHash; transitions[i].parentHash = correctBlockhash(batchIds[i] - 1); transitions[i].blockHash = correctBlockhash(batchIds[i]); diff --git a/packages/protocol/test/layer1/based/InboxTest_Suite1.t.sol b/packages/protocol/test/layer1/based/InboxTest_Suite1.t.sol index 7cea69eb755..9feeb5ecb42 100644 --- a/packages/protocol/test/layer1/based/InboxTest_Suite1.t.sol +++ b/packages/protocol/test/layer1/based/InboxTest_Suite1.t.sol @@ -103,7 +103,7 @@ contract InboxTest_Suite1 is InboxTestBase { for (uint64 i = 1; i < 10; ++i) { blk = inbox.getBatch(i); assertEq(blk.batchId, i); - assertEq(blk.metaHash, keccak256(abi.encode(batchMetadatas[i]))); + assertEq(blk.metaHash, keccak256(abi.encode(_loadMetadata(i)))); assertEq(blk.timestamp, block.timestamp); assertEq(blk.anchorBlockId, block.number - 1); @@ -160,7 +160,7 @@ contract InboxTest_Suite1 is InboxTestBase { for (uint64 i = 1; i < 7; ++i) { blk = inbox.getBatch(i); assertEq(blk.batchId, i); - assertEq(blk.metaHash, keccak256(abi.encode(batchMetadatas[i]))); + assertEq(blk.metaHash, keccak256(abi.encode(_loadMetadata(i)))); assertEq(blk.timestamp, block.timestamp); assertEq(blk.anchorBlockId, block.number - 1); @@ -231,7 +231,7 @@ contract InboxTest_Suite1 is InboxTestBase { for (uint64 i = 1; i < 10; ++i) { blk = inbox.getBatch(i); assertEq(blk.batchId, i); - assertEq(blk.metaHash, keccak256(abi.encode(batchMetadatas[i]))); + assertEq(blk.metaHash, keccak256(abi.encode(_loadMetadata(i)))); assertEq(blk.timestamp, block.timestamp); assertEq(blk.anchorBlockId, block.number - 1); @@ -278,7 +278,7 @@ contract InboxTest_Suite1 is InboxTestBase { for (uint64 i = 1; i < 10; ++i) { blk = inbox.getBatch(i); assertEq(blk.batchId, i); - assertEq(blk.metaHash, keccak256(abi.encode(batchMetadatas[i]))); + assertEq(blk.metaHash, keccak256(abi.encode(_loadMetadata(i)))); assertEq(blk.timestamp, block.timestamp); assertEq(blk.anchorBlockId, block.number - 1); @@ -330,7 +330,7 @@ contract InboxTest_Suite1 is InboxTestBase { for (uint64 i = 8; i < 15; ++i) { ITaikoInbox.Batch memory blk = inbox.getBatch(i); assertEq(blk.batchId, i); - assertEq(blk.metaHash, keccak256(abi.encode(batchMetadatas[i]))); + assertEq(blk.metaHash, keccak256(abi.encode(_loadMetadata(i)))); assertEq(blk.timestamp, block.timestamp); assertEq(blk.anchorBlockId, block.number - 1); @@ -362,7 +362,7 @@ contract InboxTest_Suite1 is InboxTestBase { ITaikoInbox.BatchMetadata[] memory metas = new ITaikoInbox.BatchMetadata[](1); ITaikoInbox.Transition[] memory transitions = new ITaikoInbox.Transition[](1); - metas[0] = batchMetadatas[1]; + metas[0] = _loadMetadata(1); transitions[0].parentHash = bytes32(uint256(0x100)); transitions[0].blockHash = bytes32(uint256(0x101)); @@ -434,7 +434,7 @@ contract InboxTest_Suite1 is InboxTestBase { ITaikoInbox.Transition[] memory transitions = new ITaikoInbox.Transition[](count); for (uint256 i; i < batchIds.length; ++i) { - metas[i] = batchMetadatas[batchIds[i]]; + metas[i] = _loadMetadata(batchIds[i]); transitions[i].parentHash = correctBlockhash(batchIds[i] - 1); transitions[i].blockHash = correctBlockhash(batchIds[i]); From c3dfa171ae8d727a7bb8f6e64c19665c89d2541c Mon Sep 17 00:00:00 2001 From: Daniel Wang Date: Sun, 12 Jan 2025 11:44:05 +0800 Subject: [PATCH 29/41] Update InboxTest_Suite1.json From 4b4f26c9bec861be4aa52ec06f311f6c683c289b Mon Sep 17 00:00:00 2001 From: Daniel Wang Date: Sun, 12 Jan 2025 11:47:15 +0800 Subject: [PATCH 30/41] Create PacayaForkManager.sol --- .../layer1/fork/PacayaForkManager.sol | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 packages/protocol/contracts/layer1/fork/PacayaForkManager.sol diff --git a/packages/protocol/contracts/layer1/fork/PacayaForkManager.sol b/packages/protocol/contracts/layer1/fork/PacayaForkManager.sol new file mode 100644 index 00000000000..248e7de0b4e --- /dev/null +++ b/packages/protocol/contracts/layer1/fork/PacayaForkManager.sol @@ -0,0 +1,37 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.24; + +import "./ForkManager.sol"; + +/// @title OntakeSelectors +/// @custom:security-contact security@taiko.xyz +/// @notice This interface is used to route specific transactions to the v2 version of the contract. +/// @dev Function selectors are calculated independently of the return type. Therefore, +/// we have omitted the `returns` statements from all functions to avoid maintaining +/// the return struct definitions. +interface OntakeSelectors { + function proposeBlocksV2(bytes[] calldata, bytes[] calldata) external; + function proveBlocks(uint64[] calldata, bytes[] calldata, bytes calldata) external; + function getBlockV2(uint64) external; + function getTransition(uint64, uint32) external; + function getConfig() external; +} + +/// @title PacayaForkManager (Ontake -> Pacaya) +/// @custom:security-contact security@taiko.xyz +contract PacayaForkManager is ForkManager { + constructor( + address _ontakeFork, + address _pacayaFork + ) + ForkManager(_ontakeFork, _pacayaFork) + { } + + function shouldRouteToOldFork(bytes4 _selector) internal pure override returns (bool) { + return _selector == OntakeSelectors.proposeBlocksV2.selector + || _selector == OntakeSelectors.proveBlocks.selector + || _selector == OntakeSelectors.getBlockV2.selector + || _selector == OntakeSelectors.getTransition.selector + || _selector == OntakeSelectors.getConfig.selector; + } +} From 3a62b8e61f42b48b0d9197d203fed9f7c9a48675 Mon Sep 17 00:00:00 2001 From: Daniel Wang Date: Sun, 12 Jan 2025 11:52:34 +0800 Subject: [PATCH 31/41] rename --- .../contracts/layer1/based/ITaikoInbox.sol | 4 ++-- .../protocol/contracts/layer1/based/TaikoInbox.sol | 14 +++++++------- .../contracts/layer1/devnet/DevnetInbox.sol | 2 +- .../protocol/contracts/layer1/hekla/HeklaInbox.sol | 2 +- .../contracts/layer1/mainnet/MainnetInbox.sol | 2 +- .../script/layer1/based/DeployProtocolOnL1.s.sol | 2 +- packages/protocol/test/layer1/Layer1Test.sol | 2 +- .../test/layer1/based/InBoxTest_Params.t.sol | 2 +- .../protocol/test/layer1/based/InboxTestBase.sol | 4 ++-- .../test/layer1/based/helpers/StubInbox.sol | 4 ++-- .../team/tokenunlock/TokenUnlock_ProverSet.t.sol | 2 +- .../test/layer1/verifiers/SP1Verifier.t.sol | 2 +- 12 files changed, 21 insertions(+), 21 deletions(-) diff --git a/packages/protocol/contracts/layer1/based/ITaikoInbox.sol b/packages/protocol/contracts/layer1/based/ITaikoInbox.sol index a6dda1de2d6..484b7a53e70 100644 --- a/packages/protocol/contracts/layer1/based/ITaikoInbox.sol +++ b/packages/protocol/contracts/layer1/based/ITaikoInbox.sol @@ -296,7 +296,7 @@ interface ITaikoInbox { /// @param _batchId The batch ID. /// @param _tid The transition ID. /// @return The specified transition. - function getTransition( + function getTransitionV3( uint64 _batchId, uint24 _tid ) @@ -330,5 +330,5 @@ interface ITaikoInbox { /// @notice Retrieves the current protocol configuration. /// @return The current configuration. - function getConfig() external view returns (Config memory); + function getConfigV3() external view returns (Config memory); } diff --git a/packages/protocol/contracts/layer1/based/TaikoInbox.sol b/packages/protocol/contracts/layer1/based/TaikoInbox.sol index e75aeccfcde..0eaecec73fa 100644 --- a/packages/protocol/contracts/layer1/based/TaikoInbox.sol +++ b/packages/protocol/contracts/layer1/based/TaikoInbox.sol @@ -66,7 +66,7 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { Stats2 memory stats2 = state.stats2; require(!stats2.paused, ContractPaused()); - Config memory config = getConfig(); + Config memory config = getConfigV3(); require(stats2.numBatches >= config.forkHeights.pacaya, InvalidForkHeight()); unchecked { @@ -194,7 +194,7 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { Stats2 memory stats2 = state.stats2; require(stats2.paused == false, ContractPaused()); - Config memory config = getConfig(); + Config memory config = getConfigV3(); uint64[] memory batchIds = new uint64[](_metas.length); IVerifier.Context[] memory ctxs = new IVerifier.Context[](_metas.length); @@ -319,7 +319,7 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { } /// @inheritdoc ITaikoInbox - function getTransition( + function getTransitionV3( uint64 _batchId, uint24 _tid ) @@ -327,7 +327,7 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { view returns (Transition memory tran_) { - Config memory config = getConfig(); + Config memory config = getConfigV3(); uint256 slot = _batchId % config.batchRingBufferSize; Batch storage batch = state.batches[slot]; require(batch.batchId == _batchId, BatchNotFound()); @@ -362,7 +362,7 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { /// @inheritdoc ITaikoInbox function getBatch(uint64 _batchId) external view returns (Batch memory batch_) { - Config memory config = getConfig(); + Config memory config = getConfigV3(); require(_batchId >= config.forkHeights.pacaya, InvalidForkHeight()); batch_ = state.batches[_batchId % config.batchRingBufferSize]; @@ -394,7 +394,7 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { view returns (Transition memory tran_) { - Config memory config = getConfig(); + Config memory config = getConfigV3(); uint64 slot = _batchId % config.batchRingBufferSize; Batch storage batch = state.batches[slot]; @@ -406,7 +406,7 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { } /// @inheritdoc ITaikoInbox - function getConfig() public view virtual returns (Config memory); + function getConfigV3() public view virtual returns (Config memory); // Internal functions ---------------------------------------------------------------------- diff --git a/packages/protocol/contracts/layer1/devnet/DevnetInbox.sol b/packages/protocol/contracts/layer1/devnet/DevnetInbox.sol index b33e991e93e..fa4075b4248 100644 --- a/packages/protocol/contracts/layer1/devnet/DevnetInbox.sol +++ b/packages/protocol/contracts/layer1/devnet/DevnetInbox.sol @@ -8,7 +8,7 @@ import "../based/TaikoInbox.sol"; /// @custom:security-contact security@taiko.xyz contract DevnetInbox is TaikoInbox { /// @inheritdoc ITaikoInbox - function getConfig() public pure override returns (ITaikoInbox.Config memory) { + function getConfigV3() public pure override returns (ITaikoInbox.Config memory) { return ITaikoInbox.Config({ chainId: 167_001, maxBatchProposals: 324_000, diff --git a/packages/protocol/contracts/layer1/hekla/HeklaInbox.sol b/packages/protocol/contracts/layer1/hekla/HeklaInbox.sol index 99111757927..2fd4fe76dff 100644 --- a/packages/protocol/contracts/layer1/hekla/HeklaInbox.sol +++ b/packages/protocol/contracts/layer1/hekla/HeklaInbox.sol @@ -7,7 +7,7 @@ import "../based/TaikoInbox.sol"; /// @dev Labeled in address resolver as "taiko" /// @custom:security-contact security@taiko.xyz contract HeklaInbox is TaikoInbox { - function getConfig() public pure override returns (ITaikoInbox.Config memory) { + function getConfigV3() public pure override returns (ITaikoInbox.Config memory) { return ITaikoInbox.Config({ chainId: LibNetwork.TAIKO_HEKLA, // Never change this value as ring buffer is being reused!!! diff --git a/packages/protocol/contracts/layer1/mainnet/MainnetInbox.sol b/packages/protocol/contracts/layer1/mainnet/MainnetInbox.sol index 2e95ccddcc2..1629cd620a1 100644 --- a/packages/protocol/contracts/layer1/mainnet/MainnetInbox.sol +++ b/packages/protocol/contracts/layer1/mainnet/MainnetInbox.sol @@ -11,7 +11,7 @@ import "./libs/LibFasterReentryLock.sol"; /// @notice See the documentation in {TaikoL1}. /// @custom:security-contact security@taiko.xyz contract MainnetInbox is TaikoInbox { - function getConfig() public pure override returns (ITaikoInbox.Config memory) { + function getConfigV3() public pure override returns (ITaikoInbox.Config memory) { // All hard-coded configurations: // - treasury: the actual TaikoL2 address. // - anchorGasLimit: 250_000 (based on internal devnet, its ~220_000 diff --git a/packages/protocol/script/layer1/based/DeployProtocolOnL1.s.sol b/packages/protocol/script/layer1/based/DeployProtocolOnL1.s.sol index ba290d5f0bd..f0b59c6ba2a 100644 --- a/packages/protocol/script/layer1/based/DeployProtocolOnL1.s.sol +++ b/packages/protocol/script/layer1/based/DeployProtocolOnL1.s.sol @@ -65,7 +65,7 @@ contract DeployProtocolOnL1 is DeployCapability { SignalService(signalServiceAddr).authorize(taikoInboxAddr, true); } - uint64 l2ChainId = taikoInbox.getConfig().chainId; + uint64 l2ChainId = taikoInbox.getConfigV3().chainId; require(l2ChainId != block.chainid, "same chainid"); console2.log("------------------------------------------"); diff --git a/packages/protocol/test/layer1/Layer1Test.sol b/packages/protocol/test/layer1/Layer1Test.sol index 29bb3276f47..04f68adcf60 100644 --- a/packages/protocol/test/layer1/Layer1Test.sol +++ b/packages/protocol/test/layer1/Layer1Test.sol @@ -27,7 +27,7 @@ contract ConfigurableInbox is TaikoInbox { __config = _config; } - function getConfig() public view override returns (ITaikoInbox.Config memory) { + function getConfigV3() public view override returns (ITaikoInbox.Config memory) { return __config; } diff --git a/packages/protocol/test/layer1/based/InBoxTest_Params.t.sol b/packages/protocol/test/layer1/based/InBoxTest_Params.t.sol index 430c15d562d..964aeedb28c 100644 --- a/packages/protocol/test/layer1/based/InBoxTest_Params.t.sol +++ b/packages/protocol/test/layer1/based/InBoxTest_Params.t.sol @@ -61,7 +61,7 @@ contract InBoxTest_Params is InboxTestBase { external transactBy(Alice) { - ITaikoInbox.Config memory config = inbox.getConfig(); + ITaikoInbox.Config memory config = inbox.getConfigV3(); // Advance the block number to create the appropriate test scenario vm.roll(config.maxAnchorHeightOffset + 2); diff --git a/packages/protocol/test/layer1/based/InboxTestBase.sol b/packages/protocol/test/layer1/based/InboxTestBase.sol index 1efc0b7f2df..6c5ad2893d1 100644 --- a/packages/protocol/test/layer1/based/InboxTestBase.sol +++ b/packages/protocol/test/layer1/based/InboxTestBase.sol @@ -157,7 +157,7 @@ abstract contract InboxTestBase is Layer1Test { console2.log("Stats2 - lastUnpausedAt:", stats2.lastUnpausedAt); // console2.log("stats2.numBatches:", stats2.numBatches); - // console2.log("getConfig().maxBatchProposals:", getConfig().maxBatchProposals); + // console2.log("getConfigV3().maxBatchProposals:", getConfigV3().maxBatchProposals); uint64 firstBatchId = stats2.numBatches > getConfig().maxBatchProposals ? stats2.numBatches - getConfig().maxBatchProposals @@ -177,7 +177,7 @@ abstract contract InboxTestBase is Layer1Test { console2.log(unicode"│ |── verifiedTransitionId:", batch.verifiedTransitionId); for (uint24 j = 1; j < batch.nextTransitionId; ++j) { - ITaikoInbox.Transition memory tran = inbox.getTransition(batch.batchId, j); + ITaikoInbox.Transition memory tran = inbox.getTransitionV3(batch.batchId, j); console2.log(unicode"│ |── transition#", j); console2.log( unicode"│ │ |── parentHash:", diff --git a/packages/protocol/test/layer1/based/helpers/StubInbox.sol b/packages/protocol/test/layer1/based/helpers/StubInbox.sol index dd14e741ac4..86e458d5fc5 100644 --- a/packages/protocol/test/layer1/based/helpers/StubInbox.sol +++ b/packages/protocol/test/layer1/based/helpers/StubInbox.sol @@ -36,7 +36,7 @@ contract StubInbox is ITaikoInbox { function getBatch(uint64 _batchId) external view virtual returns (ITaikoInbox.Batch memory) { } - function getTransition( + function getTransitionV3( uint64 _batchId, uint24 _tid ) @@ -64,5 +64,5 @@ contract StubInbox is ITaikoInbox { function getStats2() external view returns (Stats2 memory) { } - function getConfig() external pure virtual returns (ITaikoInbox.Config memory) { } + function getConfigV3() external pure virtual returns (ITaikoInbox.Config memory) { } } diff --git a/packages/protocol/test/layer1/team/tokenunlock/TokenUnlock_ProverSet.t.sol b/packages/protocol/test/layer1/team/tokenunlock/TokenUnlock_ProverSet.t.sol index 974379b4d1f..4ba9af45a57 100644 --- a/packages/protocol/test/layer1/team/tokenunlock/TokenUnlock_ProverSet.t.sol +++ b/packages/protocol/test/layer1/team/tokenunlock/TokenUnlock_ProverSet.t.sol @@ -14,7 +14,7 @@ pragma solidity ^0.8.24; // TokenUnlock private target; // TaikoToken private taikoToken; -// function getConfig() internal pure override returns (ITaikoInbox.Config memory) { +// function getConfigV3() internal pure override returns (ITaikoInbox.Config memory) { // return ITaikoInbox.Config({ // chainId: LibNetwork.TAIKO_MAINNET, // maxBatchProposals: 10, diff --git a/packages/protocol/test/layer1/verifiers/SP1Verifier.t.sol b/packages/protocol/test/layer1/verifiers/SP1Verifier.t.sol index 207e6972d92..2d19f29b9cb 100644 --- a/packages/protocol/test/layer1/verifiers/SP1Verifier.t.sol +++ b/packages/protocol/test/layer1/verifiers/SP1Verifier.t.sol @@ -5,7 +5,7 @@ import { SP1Verifier as SP1RemoteVerifier } from "@sp1-contracts/src/v3.0.0/SP1V import "../Layer1Test.sol"; contract TaikoStub_ReturnMainnetChainId { - function getConfig() external pure returns (ITaikoInbox.Config memory config) { + function getConfigV3() external pure returns (ITaikoInbox.Config memory config) { config.chainId = 167_000; } } From bf5f441a8db9aa81ad75db67b92494adacc0e1a1 Mon Sep 17 00:00:00 2001 From: dantaik <99078276+dantaik@users.noreply.github.com> Date: Sun, 12 Jan 2025 03:56:37 +0000 Subject: [PATCH 32/41] forge fmt & update contract layout tables --- .../protocol/contracts/layer1/fork/PacayaForkManager.sol | 7 +------ packages/protocol/snapshots/InboxTest_Suite1.json | 4 ++++ 2 files changed, 5 insertions(+), 6 deletions(-) create mode 100644 packages/protocol/snapshots/InboxTest_Suite1.json diff --git a/packages/protocol/contracts/layer1/fork/PacayaForkManager.sol b/packages/protocol/contracts/layer1/fork/PacayaForkManager.sol index 248e7de0b4e..51fa5d1e2a3 100644 --- a/packages/protocol/contracts/layer1/fork/PacayaForkManager.sol +++ b/packages/protocol/contracts/layer1/fork/PacayaForkManager.sol @@ -20,12 +20,7 @@ interface OntakeSelectors { /// @title PacayaForkManager (Ontake -> Pacaya) /// @custom:security-contact security@taiko.xyz contract PacayaForkManager is ForkManager { - constructor( - address _ontakeFork, - address _pacayaFork - ) - ForkManager(_ontakeFork, _pacayaFork) - { } + constructor(address _ontakeFork, address _pacayaFork) ForkManager(_ontakeFork, _pacayaFork) { } function shouldRouteToOldFork(bytes4 _selector) internal pure override returns (bool) { return _selector == OntakeSelectors.proposeBlocksV2.selector diff --git a/packages/protocol/snapshots/InboxTest_Suite1.json b/packages/protocol/snapshots/InboxTest_Suite1.json new file mode 100644 index 00000000000..cff8d17902f --- /dev/null +++ b/packages/protocol/snapshots/InboxTest_Suite1.json @@ -0,0 +1,4 @@ +{ + "proposeBatch": "1920271", + "proveBatches": "297545" +} \ No newline at end of file From 7e3b658a0add72b7ef952491ab4f35ea2a5af819 Mon Sep 17 00:00:00 2001 From: Daniel Wang Date: Sun, 12 Jan 2025 16:14:03 +0800 Subject: [PATCH 33/41] rename --- .../contracts/layer1/based/ITaikoInbox.sol | 4 ++-- .../protocol/contracts/layer1/based/TaikoInbox.sol | 14 +++++++------- .../contracts/layer1/devnet/DevnetInbox.sol | 2 +- .../protocol/contracts/layer1/hekla/HeklaInbox.sol | 2 +- .../contracts/layer1/mainnet/MainnetInbox.sol | 2 +- .../script/layer1/based/DeployProtocolOnL1.s.sol | 2 +- packages/protocol/test/layer1/Layer1Test.sol | 2 +- .../test/layer1/based/InBoxTest_Params.t.sol | 2 +- .../protocol/test/layer1/based/InboxTestBase.sol | 4 ++-- .../test/layer1/based/helpers/StubInbox.sol | 4 ++-- .../team/tokenunlock/TokenUnlock_ProverSet.t.sol | 2 +- .../test/layer1/verifiers/SP1Verifier.t.sol | 2 +- 12 files changed, 21 insertions(+), 21 deletions(-) diff --git a/packages/protocol/contracts/layer1/based/ITaikoInbox.sol b/packages/protocol/contracts/layer1/based/ITaikoInbox.sol index 484b7a53e70..a6dda1de2d6 100644 --- a/packages/protocol/contracts/layer1/based/ITaikoInbox.sol +++ b/packages/protocol/contracts/layer1/based/ITaikoInbox.sol @@ -296,7 +296,7 @@ interface ITaikoInbox { /// @param _batchId The batch ID. /// @param _tid The transition ID. /// @return The specified transition. - function getTransitionV3( + function getTransition( uint64 _batchId, uint24 _tid ) @@ -330,5 +330,5 @@ interface ITaikoInbox { /// @notice Retrieves the current protocol configuration. /// @return The current configuration. - function getConfigV3() external view returns (Config memory); + function getConfig() external view returns (Config memory); } diff --git a/packages/protocol/contracts/layer1/based/TaikoInbox.sol b/packages/protocol/contracts/layer1/based/TaikoInbox.sol index 0eaecec73fa..e75aeccfcde 100644 --- a/packages/protocol/contracts/layer1/based/TaikoInbox.sol +++ b/packages/protocol/contracts/layer1/based/TaikoInbox.sol @@ -66,7 +66,7 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { Stats2 memory stats2 = state.stats2; require(!stats2.paused, ContractPaused()); - Config memory config = getConfigV3(); + Config memory config = getConfig(); require(stats2.numBatches >= config.forkHeights.pacaya, InvalidForkHeight()); unchecked { @@ -194,7 +194,7 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { Stats2 memory stats2 = state.stats2; require(stats2.paused == false, ContractPaused()); - Config memory config = getConfigV3(); + Config memory config = getConfig(); uint64[] memory batchIds = new uint64[](_metas.length); IVerifier.Context[] memory ctxs = new IVerifier.Context[](_metas.length); @@ -319,7 +319,7 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { } /// @inheritdoc ITaikoInbox - function getTransitionV3( + function getTransition( uint64 _batchId, uint24 _tid ) @@ -327,7 +327,7 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { view returns (Transition memory tran_) { - Config memory config = getConfigV3(); + Config memory config = getConfig(); uint256 slot = _batchId % config.batchRingBufferSize; Batch storage batch = state.batches[slot]; require(batch.batchId == _batchId, BatchNotFound()); @@ -362,7 +362,7 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { /// @inheritdoc ITaikoInbox function getBatch(uint64 _batchId) external view returns (Batch memory batch_) { - Config memory config = getConfigV3(); + Config memory config = getConfig(); require(_batchId >= config.forkHeights.pacaya, InvalidForkHeight()); batch_ = state.batches[_batchId % config.batchRingBufferSize]; @@ -394,7 +394,7 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { view returns (Transition memory tran_) { - Config memory config = getConfigV3(); + Config memory config = getConfig(); uint64 slot = _batchId % config.batchRingBufferSize; Batch storage batch = state.batches[slot]; @@ -406,7 +406,7 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { } /// @inheritdoc ITaikoInbox - function getConfigV3() public view virtual returns (Config memory); + function getConfig() public view virtual returns (Config memory); // Internal functions ---------------------------------------------------------------------- diff --git a/packages/protocol/contracts/layer1/devnet/DevnetInbox.sol b/packages/protocol/contracts/layer1/devnet/DevnetInbox.sol index fa4075b4248..b33e991e93e 100644 --- a/packages/protocol/contracts/layer1/devnet/DevnetInbox.sol +++ b/packages/protocol/contracts/layer1/devnet/DevnetInbox.sol @@ -8,7 +8,7 @@ import "../based/TaikoInbox.sol"; /// @custom:security-contact security@taiko.xyz contract DevnetInbox is TaikoInbox { /// @inheritdoc ITaikoInbox - function getConfigV3() public pure override returns (ITaikoInbox.Config memory) { + function getConfig() public pure override returns (ITaikoInbox.Config memory) { return ITaikoInbox.Config({ chainId: 167_001, maxBatchProposals: 324_000, diff --git a/packages/protocol/contracts/layer1/hekla/HeklaInbox.sol b/packages/protocol/contracts/layer1/hekla/HeklaInbox.sol index 2fd4fe76dff..99111757927 100644 --- a/packages/protocol/contracts/layer1/hekla/HeklaInbox.sol +++ b/packages/protocol/contracts/layer1/hekla/HeklaInbox.sol @@ -7,7 +7,7 @@ import "../based/TaikoInbox.sol"; /// @dev Labeled in address resolver as "taiko" /// @custom:security-contact security@taiko.xyz contract HeklaInbox is TaikoInbox { - function getConfigV3() public pure override returns (ITaikoInbox.Config memory) { + function getConfig() public pure override returns (ITaikoInbox.Config memory) { return ITaikoInbox.Config({ chainId: LibNetwork.TAIKO_HEKLA, // Never change this value as ring buffer is being reused!!! diff --git a/packages/protocol/contracts/layer1/mainnet/MainnetInbox.sol b/packages/protocol/contracts/layer1/mainnet/MainnetInbox.sol index 1629cd620a1..2e95ccddcc2 100644 --- a/packages/protocol/contracts/layer1/mainnet/MainnetInbox.sol +++ b/packages/protocol/contracts/layer1/mainnet/MainnetInbox.sol @@ -11,7 +11,7 @@ import "./libs/LibFasterReentryLock.sol"; /// @notice See the documentation in {TaikoL1}. /// @custom:security-contact security@taiko.xyz contract MainnetInbox is TaikoInbox { - function getConfigV3() public pure override returns (ITaikoInbox.Config memory) { + function getConfig() public pure override returns (ITaikoInbox.Config memory) { // All hard-coded configurations: // - treasury: the actual TaikoL2 address. // - anchorGasLimit: 250_000 (based on internal devnet, its ~220_000 diff --git a/packages/protocol/script/layer1/based/DeployProtocolOnL1.s.sol b/packages/protocol/script/layer1/based/DeployProtocolOnL1.s.sol index f0b59c6ba2a..ba290d5f0bd 100644 --- a/packages/protocol/script/layer1/based/DeployProtocolOnL1.s.sol +++ b/packages/protocol/script/layer1/based/DeployProtocolOnL1.s.sol @@ -65,7 +65,7 @@ contract DeployProtocolOnL1 is DeployCapability { SignalService(signalServiceAddr).authorize(taikoInboxAddr, true); } - uint64 l2ChainId = taikoInbox.getConfigV3().chainId; + uint64 l2ChainId = taikoInbox.getConfig().chainId; require(l2ChainId != block.chainid, "same chainid"); console2.log("------------------------------------------"); diff --git a/packages/protocol/test/layer1/Layer1Test.sol b/packages/protocol/test/layer1/Layer1Test.sol index 04f68adcf60..29bb3276f47 100644 --- a/packages/protocol/test/layer1/Layer1Test.sol +++ b/packages/protocol/test/layer1/Layer1Test.sol @@ -27,7 +27,7 @@ contract ConfigurableInbox is TaikoInbox { __config = _config; } - function getConfigV3() public view override returns (ITaikoInbox.Config memory) { + function getConfig() public view override returns (ITaikoInbox.Config memory) { return __config; } diff --git a/packages/protocol/test/layer1/based/InBoxTest_Params.t.sol b/packages/protocol/test/layer1/based/InBoxTest_Params.t.sol index 964aeedb28c..430c15d562d 100644 --- a/packages/protocol/test/layer1/based/InBoxTest_Params.t.sol +++ b/packages/protocol/test/layer1/based/InBoxTest_Params.t.sol @@ -61,7 +61,7 @@ contract InBoxTest_Params is InboxTestBase { external transactBy(Alice) { - ITaikoInbox.Config memory config = inbox.getConfigV3(); + ITaikoInbox.Config memory config = inbox.getConfig(); // Advance the block number to create the appropriate test scenario vm.roll(config.maxAnchorHeightOffset + 2); diff --git a/packages/protocol/test/layer1/based/InboxTestBase.sol b/packages/protocol/test/layer1/based/InboxTestBase.sol index 6c5ad2893d1..1efc0b7f2df 100644 --- a/packages/protocol/test/layer1/based/InboxTestBase.sol +++ b/packages/protocol/test/layer1/based/InboxTestBase.sol @@ -157,7 +157,7 @@ abstract contract InboxTestBase is Layer1Test { console2.log("Stats2 - lastUnpausedAt:", stats2.lastUnpausedAt); // console2.log("stats2.numBatches:", stats2.numBatches); - // console2.log("getConfigV3().maxBatchProposals:", getConfigV3().maxBatchProposals); + // console2.log("getConfig().maxBatchProposals:", getConfig().maxBatchProposals); uint64 firstBatchId = stats2.numBatches > getConfig().maxBatchProposals ? stats2.numBatches - getConfig().maxBatchProposals @@ -177,7 +177,7 @@ abstract contract InboxTestBase is Layer1Test { console2.log(unicode"│ |── verifiedTransitionId:", batch.verifiedTransitionId); for (uint24 j = 1; j < batch.nextTransitionId; ++j) { - ITaikoInbox.Transition memory tran = inbox.getTransitionV3(batch.batchId, j); + ITaikoInbox.Transition memory tran = inbox.getTransition(batch.batchId, j); console2.log(unicode"│ |── transition#", j); console2.log( unicode"│ │ |── parentHash:", diff --git a/packages/protocol/test/layer1/based/helpers/StubInbox.sol b/packages/protocol/test/layer1/based/helpers/StubInbox.sol index 86e458d5fc5..dd14e741ac4 100644 --- a/packages/protocol/test/layer1/based/helpers/StubInbox.sol +++ b/packages/protocol/test/layer1/based/helpers/StubInbox.sol @@ -36,7 +36,7 @@ contract StubInbox is ITaikoInbox { function getBatch(uint64 _batchId) external view virtual returns (ITaikoInbox.Batch memory) { } - function getTransitionV3( + function getTransition( uint64 _batchId, uint24 _tid ) @@ -64,5 +64,5 @@ contract StubInbox is ITaikoInbox { function getStats2() external view returns (Stats2 memory) { } - function getConfigV3() external pure virtual returns (ITaikoInbox.Config memory) { } + function getConfig() external pure virtual returns (ITaikoInbox.Config memory) { } } diff --git a/packages/protocol/test/layer1/team/tokenunlock/TokenUnlock_ProverSet.t.sol b/packages/protocol/test/layer1/team/tokenunlock/TokenUnlock_ProverSet.t.sol index 4ba9af45a57..974379b4d1f 100644 --- a/packages/protocol/test/layer1/team/tokenunlock/TokenUnlock_ProverSet.t.sol +++ b/packages/protocol/test/layer1/team/tokenunlock/TokenUnlock_ProverSet.t.sol @@ -14,7 +14,7 @@ pragma solidity ^0.8.24; // TokenUnlock private target; // TaikoToken private taikoToken; -// function getConfigV3() internal pure override returns (ITaikoInbox.Config memory) { +// function getConfig() internal pure override returns (ITaikoInbox.Config memory) { // return ITaikoInbox.Config({ // chainId: LibNetwork.TAIKO_MAINNET, // maxBatchProposals: 10, diff --git a/packages/protocol/test/layer1/verifiers/SP1Verifier.t.sol b/packages/protocol/test/layer1/verifiers/SP1Verifier.t.sol index 2d19f29b9cb..207e6972d92 100644 --- a/packages/protocol/test/layer1/verifiers/SP1Verifier.t.sol +++ b/packages/protocol/test/layer1/verifiers/SP1Verifier.t.sol @@ -5,7 +5,7 @@ import { SP1Verifier as SP1RemoteVerifier } from "@sp1-contracts/src/v3.0.0/SP1V import "../Layer1Test.sol"; contract TaikoStub_ReturnMainnetChainId { - function getConfigV3() external pure returns (ITaikoInbox.Config memory config) { + function getConfig() external pure returns (ITaikoInbox.Config memory config) { config.chainId = 167_000; } } From 4c6ea11e16a6420391613ab3320be0668c1004d3 Mon Sep 17 00:00:00 2001 From: dantaik <99078276+dantaik@users.noreply.github.com> Date: Sun, 12 Jan 2025 08:17:54 +0000 Subject: [PATCH 34/41] forge fmt & update contract layout tables --- packages/protocol/snapshots/InboxTest_Suite1.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/protocol/snapshots/InboxTest_Suite1.json b/packages/protocol/snapshots/InboxTest_Suite1.json index cff8d17902f..b15d4df633f 100644 --- a/packages/protocol/snapshots/InboxTest_Suite1.json +++ b/packages/protocol/snapshots/InboxTest_Suite1.json @@ -1,4 +1,4 @@ { - "proposeBatch": "1920271", - "proveBatches": "297545" + "proposeBatch": "1920205", + "proveBatches": "297612" } \ No newline at end of file From fb86c41eb24163c45d220555f6a95050f492b586 Mon Sep 17 00:00:00 2001 From: Daniel Wang Date: Sun, 12 Jan 2025 19:45:00 +0800 Subject: [PATCH 35/41] return blockId --- .../contracts/layer1/based/ITaikoInbox.sol | 8 ++++--- .../contracts/layer1/based/TaikoInbox.sol | 24 +++++++++++-------- .../test/layer1/based/InboxTest_Suite1.t.sol | 18 +++++++++----- .../test/layer1/based/helpers/StubInbox.sol | 4 ++-- 4 files changed, 33 insertions(+), 21 deletions(-) diff --git a/packages/protocol/contracts/layer1/based/ITaikoInbox.sol b/packages/protocol/contracts/layer1/based/ITaikoInbox.sol index a6dda1de2d6..9c99655986a 100644 --- a/packages/protocol/contracts/layer1/based/ITaikoInbox.sol +++ b/packages/protocol/contracts/layer1/based/ITaikoInbox.sol @@ -82,7 +82,7 @@ interface ITaikoInbox { /// @notice Forge is only able to run coverage in case the contracts by default capable of /// compiling without any optimization (neither optimizer runs, no compiling --via-ir flag). struct Stats1 { - uint64 __reserved1; + uint64 genesisHeight; uint64 __reserved2; uint64 lastSyncedBatchId; uint64 lastSyncedAt; @@ -306,19 +306,21 @@ interface ITaikoInbox { /// @notice Retrieves the transition used for the last verified batch. /// @return batchId_ The batch ID of the last verified transition. + /// @return blockId_ The block ID of the last verified block. /// @return tran_ The last verified transition. function getLastVerifiedTransition() external view - returns (uint64 batchId_, Transition memory tran_); + returns (uint64 batchId_, uint64 blockId_, Transition memory tran_); /// @notice Retrieves the transition used for the last synced batch. /// @return batchId_ The batch ID of the last synced transition. + /// @return blockId_ The block ID of the last synced block. /// @return tran_ The last synced transition. function getLastSyncedTransition() external view - returns (uint64 batchId_, Transition memory tran_); + returns (uint64 batchId_, uint64 blockId_, Transition memory tran_); /// @notice Retrieves the transition used for verifying a batch. /// @param _batchId The batch ID. diff --git a/packages/protocol/contracts/layer1/based/TaikoInbox.sol b/packages/protocol/contracts/layer1/based/TaikoInbox.sol index e75aeccfcde..f13c78d0b78 100644 --- a/packages/protocol/contracts/layer1/based/TaikoInbox.sol +++ b/packages/protocol/contracts/layer1/based/TaikoInbox.sol @@ -339,9 +339,10 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { function getLastVerifiedTransition() external view - returns (uint64 batchId_, Transition memory tran_) + returns (uint64 batchId_, uint64 blockId_, Transition memory tran_) { batchId_ = state.stats2.lastVerifiedBatchId; + blockId_ = getBatch(batchId_).lastBlockId; tran_ = getBatchVerifyingTransition(batchId_); } @@ -349,9 +350,10 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { function getLastSyncedTransition() external view - returns (uint64 batchId_, Transition memory tran_) + returns (uint64 batchId_, uint64 blockId_, Transition memory tran_) { batchId_ = state.stats1.lastSyncedBatchId; + blockId_ = getBatch(batchId_).lastBlockId; tran_ = getBatchVerifyingTransition(batchId_); } @@ -360,14 +362,7 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { return state.bondBalance[_user]; } - /// @inheritdoc ITaikoInbox - function getBatch(uint64 _batchId) external view returns (Batch memory batch_) { - Config memory config = getConfig(); - require(_batchId >= config.forkHeights.pacaya, InvalidForkHeight()); - - batch_ = state.batches[_batchId % config.batchRingBufferSize]; - require(batch_.batchId == _batchId, BatchNotFound()); - } + /// @notice Determines the operational layer of the contract, whether it is on Layer 1 (L1) or /// Layer 2 (L2). @@ -388,6 +383,15 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { return resolve(LibStrings.B_BOND_TOKEN, true); } + /// @inheritdoc ITaikoInbox + function getBatch(uint64 _batchId) public view returns (Batch memory batch_) { + Config memory config = getConfig(); + require(_batchId >= config.forkHeights.pacaya, InvalidForkHeight()); + + batch_ = state.batches[_batchId % config.batchRingBufferSize]; + require(batch_.batchId == _batchId, BatchNotFound()); + } + /// @inheritdoc ITaikoInbox function getBatchVerifyingTransition(uint64 _batchId) public diff --git a/packages/protocol/test/layer1/based/InboxTest_Suite1.t.sol b/packages/protocol/test/layer1/based/InboxTest_Suite1.t.sol index 9feeb5ecb42..87fb607e03b 100644 --- a/packages/protocol/test/layer1/based/InboxTest_Suite1.t.sol +++ b/packages/protocol/test/layer1/based/InboxTest_Suite1.t.sol @@ -55,13 +55,15 @@ contract InboxTest_Suite1 is InboxTestBase { assertEq(blk.nextTransitionId, 2); assertEq(blk.verifiedTransitionId, 1); - (uint64 batchId, ITaikoInbox.Transition memory tran) = inbox.getLastVerifiedTransition(); + (uint64 batchId, uint64 blockId, ITaikoInbox.Transition memory tran) = inbox.getLastVerifiedTransition(); assertEq(batchId, 0); + assertEq(blockId, 0); assertEq(tran.blockHash, correctBlockhash(0)); assertEq(tran.stateRoot, bytes32(uint256(0))); - (batchId, tran) = inbox.getLastSyncedTransition(); + (batchId, blockId, tran) = inbox.getLastSyncedTransition(); assertEq(batchId, 0); + assertEq(blockId, 0); assertEq(tran.blockHash, correctBlockhash(0)); assertEq(tran.stateRoot, bytes32(uint256(0))); } @@ -208,13 +210,15 @@ contract InboxTest_Suite1 is InboxTestBase { assertEq(stats2.lastProposedIn, block.number); assertEq(stats2.lastUnpausedAt, 0); - (uint64 batchId, ITaikoInbox.Transition memory tran) = inbox.getLastVerifiedTransition(); + (uint64 batchId, uint64 blockId, ITaikoInbox.Transition memory tran) = inbox.getLastVerifiedTransition(); assertEq(batchId, 9); + assertEq(blockId, 9); assertEq(tran.blockHash, correctBlockhash(9)); assertEq(tran.stateRoot, bytes32(uint256(0))); - (batchId, tran) = inbox.getLastSyncedTransition(); + (batchId, blockId, tran) = inbox.getLastSyncedTransition(); assertEq(batchId, 5); + assertEq(blockId, 5); assertEq(tran.blockHash, correctBlockhash(5)); assertEq(tran.stateRoot, correctStateRoot(5)); @@ -316,13 +320,15 @@ contract InboxTest_Suite1 is InboxTestBase { assertEq(stats2.lastProposedIn, block.number); assertEq(stats2.lastUnpausedAt, 0); - (uint64 batchId, ITaikoInbox.Transition memory tran) = inbox.getLastVerifiedTransition(); + (uint64 batchId, uint64 blockId, ITaikoInbox.Transition memory tran) = inbox.getLastVerifiedTransition(); assertEq(batchId, 10); + assertEq(blockId, 10); assertEq(tran.blockHash, correctBlockhash(10)); assertEq(tran.stateRoot, correctStateRoot(10)); - (batchId, tran) = inbox.getLastSyncedTransition(); + (batchId, blockId, tran) = inbox.getLastSyncedTransition(); assertEq(batchId, 10); + assertEq(blockId, 10); assertEq(tran.blockHash, correctBlockhash(10)); assertEq(tran.stateRoot, correctStateRoot(10)); diff --git a/packages/protocol/test/layer1/based/helpers/StubInbox.sol b/packages/protocol/test/layer1/based/helpers/StubInbox.sol index dd14e741ac4..feddca8294a 100644 --- a/packages/protocol/test/layer1/based/helpers/StubInbox.sol +++ b/packages/protocol/test/layer1/based/helpers/StubInbox.sol @@ -49,10 +49,10 @@ contract StubInbox is ITaikoInbox { function getLastVerifiedTransition() external view - returns (uint64 batchId_, Transition memory) + returns (uint64 batchId_, uint64 blockId_, Transition memory) { } - function getLastSyncedTransition() external view returns (uint64 batchId_, Transition memory) { } + function getLastSyncedTransition() external view returns (uint64 batchId_, uint64 blockId_, Transition memory) { } function getBatchVerifyingTransition(uint64 _batchId) external From f1af5da23f881f6fa960ffb18fc1cf91a327dada Mon Sep 17 00:00:00 2001 From: Daniel Wang Date: Sun, 12 Jan 2025 19:47:50 +0800 Subject: [PATCH 36/41] Update TaikoInbox.sol --- packages/protocol/contracts/layer1/based/TaikoInbox.sol | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/protocol/contracts/layer1/based/TaikoInbox.sol b/packages/protocol/contracts/layer1/based/TaikoInbox.sol index f13c78d0b78..8125606663d 100644 --- a/packages/protocol/contracts/layer1/based/TaikoInbox.sol +++ b/packages/protocol/contracts/layer1/based/TaikoInbox.sol @@ -433,8 +433,11 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { batch.nextTransitionId = 2; batch.verifiedTransitionId = 1; + state.stats1.genesisHeight = uint64(block.number); + state.stats2.lastProposedIn = uint56(block.number); state.stats2.numBatches = 1; + emit BatchesVerified(0, _genesisBlockHash); } From 9313aae9024b85581de8c8f9e931067effb2bedc Mon Sep 17 00:00:00 2001 From: dantaik <99078276+dantaik@users.noreply.github.com> Date: Sun, 12 Jan 2025 11:53:19 +0000 Subject: [PATCH 37/41] forge fmt & update contract layout tables --- packages/protocol/contracts/layer1/based/TaikoInbox.sol | 6 ++---- .../protocol/test/layer1/based/InboxTest_Suite1.t.sol | 9 ++++++--- .../protocol/test/layer1/based/helpers/StubInbox.sol | 6 +++++- 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/packages/protocol/contracts/layer1/based/TaikoInbox.sol b/packages/protocol/contracts/layer1/based/TaikoInbox.sol index 8125606663d..fe149211279 100644 --- a/packages/protocol/contracts/layer1/based/TaikoInbox.sol +++ b/packages/protocol/contracts/layer1/based/TaikoInbox.sol @@ -362,8 +362,6 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { return state.bondBalance[_user]; } - - /// @notice Determines the operational layer of the contract, whether it is on Layer 1 (L1) or /// Layer 2 (L2). /// @return True if the contract is operating on L1, false if on L2. @@ -383,7 +381,7 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { return resolve(LibStrings.B_BOND_TOKEN, true); } - /// @inheritdoc ITaikoInbox + /// @inheritdoc ITaikoInbox function getBatch(uint64 _batchId) public view returns (Batch memory batch_) { Config memory config = getConfig(); require(_batchId >= config.forkHeights.pacaya, InvalidForkHeight()); @@ -437,7 +435,7 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { state.stats2.lastProposedIn = uint56(block.number); state.stats2.numBatches = 1; - + emit BatchesVerified(0, _genesisBlockHash); } diff --git a/packages/protocol/test/layer1/based/InboxTest_Suite1.t.sol b/packages/protocol/test/layer1/based/InboxTest_Suite1.t.sol index 87fb607e03b..1f6ec835681 100644 --- a/packages/protocol/test/layer1/based/InboxTest_Suite1.t.sol +++ b/packages/protocol/test/layer1/based/InboxTest_Suite1.t.sol @@ -55,7 +55,8 @@ contract InboxTest_Suite1 is InboxTestBase { assertEq(blk.nextTransitionId, 2); assertEq(blk.verifiedTransitionId, 1); - (uint64 batchId, uint64 blockId, ITaikoInbox.Transition memory tran) = inbox.getLastVerifiedTransition(); + (uint64 batchId, uint64 blockId, ITaikoInbox.Transition memory tran) = + inbox.getLastVerifiedTransition(); assertEq(batchId, 0); assertEq(blockId, 0); assertEq(tran.blockHash, correctBlockhash(0)); @@ -210,7 +211,8 @@ contract InboxTest_Suite1 is InboxTestBase { assertEq(stats2.lastProposedIn, block.number); assertEq(stats2.lastUnpausedAt, 0); - (uint64 batchId, uint64 blockId, ITaikoInbox.Transition memory tran) = inbox.getLastVerifiedTransition(); + (uint64 batchId, uint64 blockId, ITaikoInbox.Transition memory tran) = + inbox.getLastVerifiedTransition(); assertEq(batchId, 9); assertEq(blockId, 9); assertEq(tran.blockHash, correctBlockhash(9)); @@ -320,7 +322,8 @@ contract InboxTest_Suite1 is InboxTestBase { assertEq(stats2.lastProposedIn, block.number); assertEq(stats2.lastUnpausedAt, 0); - (uint64 batchId, uint64 blockId, ITaikoInbox.Transition memory tran) = inbox.getLastVerifiedTransition(); + (uint64 batchId, uint64 blockId, ITaikoInbox.Transition memory tran) = + inbox.getLastVerifiedTransition(); assertEq(batchId, 10); assertEq(blockId, 10); assertEq(tran.blockHash, correctBlockhash(10)); diff --git a/packages/protocol/test/layer1/based/helpers/StubInbox.sol b/packages/protocol/test/layer1/based/helpers/StubInbox.sol index feddca8294a..0e381254911 100644 --- a/packages/protocol/test/layer1/based/helpers/StubInbox.sol +++ b/packages/protocol/test/layer1/based/helpers/StubInbox.sol @@ -52,7 +52,11 @@ contract StubInbox is ITaikoInbox { returns (uint64 batchId_, uint64 blockId_, Transition memory) { } - function getLastSyncedTransition() external view returns (uint64 batchId_, uint64 blockId_, Transition memory) { } + function getLastSyncedTransition() + external + view + returns (uint64 batchId_, uint64 blockId_, Transition memory) + { } function getBatchVerifyingTransition(uint64 _batchId) external From 2284ff9d10afbd5385285cb35be1d0bb36137ca7 Mon Sep 17 00:00:00 2001 From: Daniel Wang Date: Sun, 12 Jan 2025 20:10:13 +0800 Subject: [PATCH 38/41] ignore --- .gitignore | 1 + packages/protocol/snapshots/InboxTest_Suite1.json | 4 ---- 2 files changed, 1 insertion(+), 4 deletions(-) delete mode 100644 packages/protocol/snapshots/InboxTest_Suite1.json diff --git a/.gitignore b/.gitignore index 0d0cf5a22b0..9d23425fd5b 100644 --- a/.gitignore +++ b/.gitignore @@ -120,3 +120,4 @@ __pycache__/ # Idea .idea/ +packages/protocol/snapshots/InboxTest_Suite1.json diff --git a/packages/protocol/snapshots/InboxTest_Suite1.json b/packages/protocol/snapshots/InboxTest_Suite1.json deleted file mode 100644 index b15d4df633f..00000000000 --- a/packages/protocol/snapshots/InboxTest_Suite1.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "proposeBatch": "1920205", - "proveBatches": "297612" -} \ No newline at end of file From bcba67d8a5e5230df95375f026d1113400dd8772 Mon Sep 17 00:00:00 2001 From: davidtaikocha <104078303+davidtaikocha@users.noreply.github.com> Date: Sun, 12 Jan 2025 12:34:10 +0000 Subject: [PATCH 39/41] forge fmt & update contract layout tables --- packages/protocol/contract_layout_layer1.md | 1223 +++++++++++++++++++ packages/protocol/contract_layout_layer2.md | 707 +++++++++++ 2 files changed, 1930 insertions(+) diff --git a/packages/protocol/contract_layout_layer1.md b/packages/protocol/contract_layout_layer1.md index e69de29bb2d..d76706356ad 100644 --- a/packages/protocol/contract_layout_layer1.md +++ b/packages/protocol/contract_layout_layer1.md @@ -0,0 +1,1223 @@ +## ERC1155Vault + +╭-----------------------------+------------------------------------------------------+------+--------+-------+-----------------------------------------------------------╮ +| Name | Type | Slot | Offset | Bytes | ++========================================================================================================================================================================+ +| _initialized | uint8 | 0 | 0 | 1 | +| +| _initializing | bool | 0 | 1 | 1 | +| +| __gap | uint256[50] | 1 | 0 | 1600 | +| +| _owner | address | 51 | 0 | 20 | +| +| __gap | uint256[49] | 52 | 0 | 1568 | +| +| _pendingOwner | address | 101 | 0 | 20 | +| +| __gap | uint256[49] | 102 | 0 | 1568 | +| +| __resolver | address | 151 | 0 | 20 | +| +| __gapFromOldAddressResolver | uint256[49] | 152 | 0 | 1568 | +| +| __reentry | uint8 | 201 | 0 | 1 | +| +| __paused | uint8 | 201 | 1 | 1 | +| +| __gap | uint256[49] | 202 | 0 | 1568 | +| +| __gap | uint256[50] | 251 | 0 | 1600 | +| +| bridgedToCanonical | mapping(address => struct BaseNFTVault.CanonicalNFT) | 301 | 0 | 32 | +| +| canonicalToBridged | mapping(uint256 => mapping(address => address)) | 302 | 0 | 32 | +| +| __gap | uint256[48] | 303 | 0 | 1536 | +| +| __gap | uint256[50] | 351 | 0 | 1600 | +| +| __gap | uint256[50] | 401 | 0 | 1600 | +| +| __gap | uint256[50] | 451 | 0 | 1600 | +╰-----------------------------+------------------------------------------------------+------+--------+-------+-----------------------------------------------------------╯ + + +## ERC20Vault + +╭-----------------------------+------------------------------------------------------+------+--------+-------+-------------------------------------------------------╮ +| Name | Type | Slot | Offset | Bytes | ++====================================================================================================================================================================+ +| _initialized | uint8 | 0 | 0 | 1 | +| +| _initializing | bool | 0 | 1 | 1 | +| +| __gap | uint256[50] | 1 | 0 | 1600 | +| +| _owner | address | 51 | 0 | 20 | +| +| __gap | uint256[49] | 52 | 0 | 1568 | +| +| _pendingOwner | address | 101 | 0 | 20 | +| +| __gap | uint256[49] | 102 | 0 | 1568 | +| +| __resolver | address | 151 | 0 | 20 | +| +| __gapFromOldAddressResolver | uint256[49] | 152 | 0 | 1568 | +| +| __reentry | uint8 | 201 | 0 | 1 | +| +| __paused | uint8 | 201 | 1 | 1 | +| +| __gap | uint256[49] | 202 | 0 | 1568 | +| +| __gap | uint256[50] | 251 | 0 | 1600 | +| +| bridgedToCanonical | mapping(address => struct ERC20Vault.CanonicalERC20) | 301 | 0 | 32 | +| +| canonicalToBridged | mapping(uint256 => mapping(address => address)) | 302 | 0 | 32 | +| +| btokenDenylist | mapping(address => bool) | 303 | 0 | 32 | +| +| lastMigrationStart | mapping(uint256 => mapping(address => uint256)) | 304 | 0 | 32 | +| +| solverConditionToSolver | mapping(bytes32 => address) | 305 | 0 | 32 | +| +| __gap | uint256[45] | 306 | 0 | 1440 | +╰-----------------------------+------------------------------------------------------+------+--------+-------+-------------------------------------------------------╯ + + +## ERC721Vault + +╭-----------------------------+------------------------------------------------------+------+--------+-------+---------------------------------------------------------╮ +| Name | Type | Slot | Offset | Bytes | ++======================================================================================================================================================================+ +| _initialized | uint8 | 0 | 0 | 1 | +| +| _initializing | bool | 0 | 1 | 1 | +| +| __gap | uint256[50] | 1 | 0 | 1600 | +| +| _owner | address | 51 | 0 | 20 | +| +| __gap | uint256[49] | 52 | 0 | 1568 | +| +| _pendingOwner | address | 101 | 0 | 20 | +| +| __gap | uint256[49] | 102 | 0 | 1568 | +| +| __resolver | address | 151 | 0 | 20 | +| +| __gapFromOldAddressResolver | uint256[49] | 152 | 0 | 1568 | +| +| __reentry | uint8 | 201 | 0 | 1 | +| +| __paused | uint8 | 201 | 1 | 1 | +| +| __gap | uint256[49] | 202 | 0 | 1568 | +| +| __gap | uint256[50] | 251 | 0 | 1600 | +| +| bridgedToCanonical | mapping(address => struct BaseNFTVault.CanonicalNFT) | 301 | 0 | 32 | +| +| canonicalToBridged | mapping(uint256 => mapping(address => address)) | 302 | 0 | 32 | +| +| __gap | uint256[48] | 303 | 0 | 1536 | +| +| __gap | uint256[50] | 351 | 0 | 1600 | +╰-----------------------------+------------------------------------------------------+------+--------+-------+---------------------------------------------------------╯ + + +## BridgedERC20 + +╭-----------------------------+-------------------------------------------------+------+--------+-------+-----------------------------------------------------------╮ +| Name | Type | Slot | Offset | Bytes | ++===================================================================================================================================================================+ +| _initialized | uint8 | 0 | 0 | 1 | +| +| _initializing | bool | 0 | 1 | 1 | +| +| __gap | uint256[50] | 1 | 0 | 1600 | +| +| _owner | address | 51 | 0 | 20 | +| +| __gap | uint256[49] | 52 | 0 | 1568 | +| +| _pendingOwner | address | 101 | 0 | 20 | +| +| __gap | uint256[49] | 102 | 0 | 1568 | +| +| __resolver | address | 151 | 0 | 20 | +| +| __gapFromOldAddressResolver | uint256[49] | 152 | 0 | 1568 | +| +| __reentry | uint8 | 201 | 0 | 1 | +| +| __paused | uint8 | 201 | 1 | 1 | +| +| __gap | uint256[49] | 202 | 0 | 1568 | +| +| _balances | mapping(address => uint256) | 251 | 0 | 32 | +| +| _allowances | mapping(address => mapping(address => uint256)) | 252 | 0 | 32 | +| +| _totalSupply | uint256 | 253 | 0 | 32 | +| +| _name | string | 254 | 0 | 32 | +| +| _symbol | string | 255 | 0 | 32 | +| +| __gap | uint256[45] | 256 | 0 | 1440 | +| +| srcToken | address | 301 | 0 | 20 | +| +| __srcDecimals | uint8 | 301 | 20 | 1 | +| +| srcChainId | uint256 | 302 | 0 | 32 | +| +| migratingAddress | address | 303 | 0 | 20 | +| +| migratingInbound | bool | 303 | 20 | 1 | +| +| __gap | uint256[47] | 304 | 0 | 1504 | +╰-----------------------------+-------------------------------------------------+------+--------+-------+-----------------------------------------------------------╯ + + +## BridgedERC20V2 + +╭-----------------------------+--------------------------------------------------------+------+--------+-------+---------------------------------------------------------------╮ +| Name | Type | Slot | Offset | Bytes | ++==============================================================================================================================================================================+ +| _initialized | uint8 | 0 | 0 | 1 | +| +| _initializing | bool | 0 | 1 | 1 | +| +| __gap | uint256[50] | 1 | 0 | 1600 | +| +| _owner | address | 51 | 0 | 20 | +| +| __gap | uint256[49] | 52 | 0 | 1568 | +| +| _pendingOwner | address | 101 | 0 | 20 | +| +| __gap | uint256[49] | 102 | 0 | 1568 | +| +| __resolver | address | 151 | 0 | 20 | +| +| __gapFromOldAddressResolver | uint256[49] | 152 | 0 | 1568 | +| +| __reentry | uint8 | 201 | 0 | 1 | +| +| __paused | uint8 | 201 | 1 | 1 | +| +| __gap | uint256[49] | 202 | 0 | 1568 | +| +| _balances | mapping(address => uint256) | 251 | 0 | 32 | +| +| _allowances | mapping(address => mapping(address => uint256)) | 252 | 0 | 32 | +| +| _totalSupply | uint256 | 253 | 0 | 32 | +| +| _name | string | 254 | 0 | 32 | +| +| _symbol | string | 255 | 0 | 32 | +| +| __gap | uint256[45] | 256 | 0 | 1440 | +| +| srcToken | address | 301 | 0 | 20 | +| +| __srcDecimals | uint8 | 301 | 20 | 1 | +| +| srcChainId | uint256 | 302 | 0 | 32 | +| +| migratingAddress | address | 303 | 0 | 20 | +| +| migratingInbound | bool | 303 | 20 | 1 | +| +| __gap | uint256[47] | 304 | 0 | 1504 | +| +| _hashedName | bytes32 | 351 | 0 | 32 | +| +| _hashedVersion | bytes32 | 352 | 0 | 32 | +| +| _name | string | 353 | 0 | 32 | +| +| _version | string | 354 | 0 | 32 | +| +| __gap | uint256[48] | 355 | 0 | 1536 | +| +| _nonces | mapping(address => struct CountersUpgradeable.Counter) | 403 | 0 | 32 | +| +| __gap | uint256[49] | 404 | 0 | 1568 | +╰-----------------------------+--------------------------------------------------------+------+--------+-------+---------------------------------------------------------------╯ + + +## BridgedERC721 + +╭-----------------------------+----------------------------------------------+------+--------+-------+-------------------------------------------------------------╮ +| Name | Type | Slot | Offset | Bytes | ++==================================================================================================================================================================+ +| _initialized | uint8 | 0 | 0 | 1 | +| +| _initializing | bool | 0 | 1 | 1 | +| +| __gap | uint256[50] | 1 | 0 | 1600 | +| +| _owner | address | 51 | 0 | 20 | +| +| __gap | uint256[49] | 52 | 0 | 1568 | +| +| _pendingOwner | address | 101 | 0 | 20 | +| +| __gap | uint256[49] | 102 | 0 | 1568 | +| +| __resolver | address | 151 | 0 | 20 | +| +| __gapFromOldAddressResolver | uint256[49] | 152 | 0 | 1568 | +| +| __reentry | uint8 | 201 | 0 | 1 | +| +| __paused | uint8 | 201 | 1 | 1 | +| +| __gap | uint256[49] | 202 | 0 | 1568 | +| +| __gap | uint256[50] | 251 | 0 | 1600 | +| +| _name | string | 301 | 0 | 32 | +| +| _symbol | string | 302 | 0 | 32 | +| +| _owners | mapping(uint256 => address) | 303 | 0 | 32 | +| +| _balances | mapping(address => uint256) | 304 | 0 | 32 | +| +| _tokenApprovals | mapping(uint256 => address) | 305 | 0 | 32 | +| +| _operatorApprovals | mapping(address => mapping(address => bool)) | 306 | 0 | 32 | +| +| __gap | uint256[44] | 307 | 0 | 1408 | +| +| srcToken | address | 351 | 0 | 20 | +| +| srcChainId | uint256 | 352 | 0 | 32 | +| +| __gap | uint256[48] | 353 | 0 | 1536 | +╰-----------------------------+----------------------------------------------+------+--------+-------+-------------------------------------------------------------╯ + + +## BridgedERC1155 + +╭-----------------------------+-------------------------------------------------+------+--------+-------+---------------------------------------------------------------╮ +| Name | Type | Slot | Offset | Bytes | ++=======================================================================================================================================================================+ +| _initialized | uint8 | 0 | 0 | 1 | +| +| _initializing | bool | 0 | 1 | 1 | +| +| __gap | uint256[50] | 1 | 0 | 1600 | +| +| _owner | address | 51 | 0 | 20 | +| +| __gap | uint256[49] | 52 | 0 | 1568 | +| +| _pendingOwner | address | 101 | 0 | 20 | +| +| __gap | uint256[49] | 102 | 0 | 1568 | +| +| __resolver | address | 151 | 0 | 20 | +| +| __gapFromOldAddressResolver | uint256[49] | 152 | 0 | 1568 | +| +| __reentry | uint8 | 201 | 0 | 1 | +| +| __paused | uint8 | 201 | 1 | 1 | +| +| __gap | uint256[49] | 202 | 0 | 1568 | +| +| __gap | uint256[50] | 251 | 0 | 1600 | +| +| _balances | mapping(uint256 => mapping(address => uint256)) | 301 | 0 | 32 | +| +| _operatorApprovals | mapping(address => mapping(address => bool)) | 302 | 0 | 32 | +| +| _uri | string | 303 | 0 | 32 | +| +| __gap | uint256[47] | 304 | 0 | 1504 | +| +| srcToken | address | 351 | 0 | 20 | +| +| srcChainId | uint256 | 352 | 0 | 32 | +| +| symbol | string | 353 | 0 | 32 | +| +| name | string | 354 | 0 | 32 | +| +| __gap | uint256[46] | 355 | 0 | 1472 | +╰-----------------------------+-------------------------------------------------+------+--------+-------+---------------------------------------------------------------╯ + + +## Bridge + +╭-----------------------------+-----------------------------------------+------+--------+-------+-------------------------------------------╮ +| Name | Type | Slot | Offset | Bytes | ++===========================================================================================================================================+ +| _initialized | uint8 | 0 | 0 | 1 | +| +| _initializing | bool | 0 | 1 | 1 | +| +| __gap | uint256[50] | 1 | 0 | 1600 | +| +| _owner | address | 51 | 0 | 20 | +| +| __gap | uint256[49] | 52 | 0 | 1568 | +| +| _pendingOwner | address | 101 | 0 | 20 | +| +| __gap | uint256[49] | 102 | 0 | 1568 | +| +| __resolver | address | 151 | 0 | 20 | +| +| __gapFromOldAddressResolver | uint256[49] | 152 | 0 | 1568 | +| +| __reentry | uint8 | 201 | 0 | 1 | +| +| __paused | uint8 | 201 | 1 | 1 | +| +| __gap | uint256[49] | 202 | 0 | 1568 | +| +| __reserved1 | uint64 | 251 | 0 | 8 | +| +| nextMessageId | uint64 | 251 | 8 | 8 | +| +| messageStatus | mapping(bytes32 => enum IBridge.Status) | 252 | 0 | 32 | +| +| __ctx | struct IBridge.Context | 253 | 0 | 64 | +| +| __reserved2 | uint256 | 255 | 0 | 32 | +| +| __reserved3 | uint256 | 256 | 0 | 32 | +| +| __gap | uint256[44] | 257 | 0 | 1408 | +╰-----------------------------+-----------------------------------------+------+--------+-------+-------------------------------------------╯ + + +## QuotaManager + +╭-----------------------------+-----------------------------------------------+------+--------+-------+-------------------------------------------------------╮ +| Name | Type | Slot | Offset | Bytes | ++=============================================================================================================================================================+ +| _initialized | uint8 | 0 | 0 | 1 | +| +| _initializing | bool | 0 | 1 | 1 | +| +| __gap | uint256[50] | 1 | 0 | 1600 | +| +| _owner | address | 51 | 0 | 20 | +| +| __gap | uint256[49] | 52 | 0 | 1568 | +| +| _pendingOwner | address | 101 | 0 | 20 | +| +| __gap | uint256[49] | 102 | 0 | 1568 | +| +| __resolver | address | 151 | 0 | 20 | +| +| __gapFromOldAddressResolver | uint256[49] | 152 | 0 | 1568 | +| +| __reentry | uint8 | 201 | 0 | 1 | +| +| __paused | uint8 | 201 | 1 | 1 | +| +| __gap | uint256[49] | 202 | 0 | 1568 | +| +| tokenQuota | mapping(address => struct QuotaManager.Quota) | 251 | 0 | 32 | +| +| quotaPeriod | uint24 | 252 | 0 | 3 | +| +| __gap | uint256[48] | 253 | 0 | 1536 | +╰-----------------------------+-----------------------------------------------+------+--------+-------+-------------------------------------------------------╯ + + +## DefaultResolver + +╭-----------------------------+-------------------------------------------------+------+--------+-------+-------------------------------------------------------------╮ +| Name | Type | Slot | Offset | Bytes | ++=====================================================================================================================================================================+ +| _initialized | uint8 | 0 | 0 | 1 | +| +| _initializing | bool | 0 | 1 | 1 | +| +| __gap | uint256[50] | 1 | 0 | 1600 | +| +| _owner | address | 51 | 0 | 20 | +| +| __gap | uint256[49] | 52 | 0 | 1568 | +| +| _pendingOwner | address | 101 | 0 | 20 | +| +| __gap | uint256[49] | 102 | 0 | 1568 | +| +| __resolver | address | 151 | 0 | 20 | +| +| __gapFromOldAddressResolver | uint256[49] | 152 | 0 | 1568 | +| +| __reentry | uint8 | 201 | 0 | 1 | +| +| __paused | uint8 | 201 | 1 | 1 | +| +| __gap | uint256[49] | 202 | 0 | 1568 | +| +| __addresses | mapping(uint256 => mapping(bytes32 => address)) | 251 | 0 | 32 | +| +| __gap | uint256[49] | 252 | 0 | 1568 | +╰-----------------------------+-------------------------------------------------+------+--------+-------+-------------------------------------------------------------╯ + + +## EssentialContract + +╭-----------------------------+-------------+------+--------+-------+-----------------------------------------------------------------╮ +| Name | Type | Slot | Offset | Bytes | ++=====================================================================================================================================+ +| _initialized | uint8 | 0 | 0 | 1 | +| +| _initializing | bool | 0 | 1 | 1 | +| +| __gap | uint256[50] | 1 | 0 | 1600 | +| +| _owner | address | 51 | 0 | 20 | +| +| __gap | uint256[49] | 52 | 0 | 1568 | +| +| _pendingOwner | address | 101 | 0 | 20 | +| +| __gap | uint256[49] | 102 | 0 | 1568 | +| +| __resolver | address | 151 | 0 | 20 | +| +| __gapFromOldAddressResolver | uint256[49] | 152 | 0 | 1568 | +| +| __reentry | uint8 | 201 | 0 | 1 | +| +| __paused | uint8 | 201 | 1 | 1 | +| +| __gap | uint256[49] | 202 | 0 | 1568 | +╰-----------------------------+-------------+------+--------+-------+-----------------------------------------------------------------╯ + + +## SignalService + +╭-----------------------------+-----------------------------------------------+------+--------+-------+---------------------------------------------------------╮ +| Name | Type | Slot | Offset | Bytes | ++===============================================================================================================================================================+ +| _initialized | uint8 | 0 | 0 | 1 | +| +| _initializing | bool | 0 | 1 | 1 | +| +| __gap | uint256[50] | 1 | 0 | 1600 | +| +| _owner | address | 51 | 0 | 20 | +| +| __gap | uint256[49] | 52 | 0 | 1568 | +| +| _pendingOwner | address | 101 | 0 | 20 | +| +| __gap | uint256[49] | 102 | 0 | 1568 | +| +| __resolver | address | 151 | 0 | 20 | +| +| __gapFromOldAddressResolver | uint256[49] | 152 | 0 | 1568 | +| +| __reentry | uint8 | 201 | 0 | 1 | +| +| __paused | uint8 | 201 | 1 | 1 | +| +| __gap | uint256[49] | 202 | 0 | 1568 | +| +| topBlockId | mapping(uint64 => mapping(bytes32 => uint64)) | 251 | 0 | 32 | +| +| isAuthorized | mapping(address => bool) | 252 | 0 | 32 | +| +| _receivedSignals | mapping(bytes32 => bool) | 253 | 0 | 32 | +| +| __gap | uint256[47] | 254 | 0 | 1504 | +╰-----------------------------+-----------------------------------------------+------+--------+-------+---------------------------------------------------------╯ + + +## TaikoToken + +╭-----------------------------------------------------+---------------------------------------------------------------+------+--------+-------+--------------------------------------------------╮ +| Name | Type | Slot | Offset | Bytes | ++================================================================================================================================================================================================+ +| _initialized | uint8 | 0 | 0 | 1 | +| +| _initializing | bool | 0 | 1 | 1 | +| +| __gap | uint256[50] | 1 | 0 | 1600 | +| +| _owner | address | 51 | 0 | 20 | +| +| __gap | uint256[49] | 52 | 0 | 1568 | +| +| _pendingOwner | address | 101 | 0 | 20 | +| +| __gap | uint256[49] | 102 | 0 | 1568 | +| +| __resolver | address | 151 | 0 | 20 | +| +| __gapFromOldAddressResolver | uint256[49] | 152 | 0 | 1568 | +| +| __reentry | uint8 | 201 | 0 | 1 | +| +| __paused | uint8 | 201 | 1 | 1 | +| +| __gap | uint256[49] | 202 | 0 | 1568 | +| +| __slots_previously_used_by_ERC20SnapshotUpgradeable | uint256[50] | 251 | 0 | 1600 | +| +| _balances | mapping(address => uint256) | 301 | 0 | 32 | +| +| _allowances | mapping(address => mapping(address => uint256)) | 302 | 0 | 32 | +| +| _totalSupply | uint256 | 303 | 0 | 32 | +| +| _name | string | 304 | 0 | 32 | +| +| _symbol | string | 305 | 0 | 32 | +| +| __gap | uint256[45] | 306 | 0 | 1440 | +| +| _hashedName | bytes32 | 351 | 0 | 32 | +| +| _hashedVersion | bytes32 | 352 | 0 | 32 | +| +| _name | string | 353 | 0 | 32 | +| +| _version | string | 354 | 0 | 32 | +| +| __gap | uint256[48] | 355 | 0 | 1536 | +| +| _nonces | mapping(address => struct CountersUpgradeable.Counter) | 403 | 0 | 32 | +| +| _PERMIT_TYPEHASH_DEPRECATED_SLOT | bytes32 | 404 | 0 | 32 | +| +| __gap | uint256[49] | 405 | 0 | 1568 | +| +| _delegates | mapping(address => address) | 454 | 0 | 32 | +| +| _checkpoints | mapping(address => struct ERC20VotesUpgradeable.Checkpoint[]) | 455 | 0 | 32 | +| +| _totalSupplyCheckpoints | struct ERC20VotesUpgradeable.Checkpoint[] | 456 | 0 | 32 | +| +| __gap | uint256[47] | 457 | 0 | 1504 | +| +| __gap | uint256[50] | 504 | 0 | 1600 | +╰-----------------------------------------------------+---------------------------------------------------------------+------+--------+-------+--------------------------------------------------╯ + + +## SgxAndZkVerifier + +╭-----------------------------+-------------+------+--------+-------+--------------------------------------------------------------------------╮ +| Name | Type | Slot | Offset | Bytes | ++==============================================================================================================================================+ +| _initialized | uint8 | 0 | 0 | 1 | +| +| _initializing | bool | 0 | 1 | 1 | +| +| __gap | uint256[50] | 1 | 0 | 1600 | +| +| _owner | address | 51 | 0 | 20 | +| +| __gap | uint256[49] | 52 | 0 | 1568 | +| +| _pendingOwner | address | 101 | 0 | 20 | +| +| __gap | uint256[49] | 102 | 0 | 1568 | +| +| __resolver | address | 151 | 0 | 20 | +| +| __gapFromOldAddressResolver | uint256[49] | 152 | 0 | 1568 | +| +| __reentry | uint8 | 201 | 0 | 1 | +| +| __paused | uint8 | 201 | 1 | 1 | +| +| __gap | uint256[49] | 202 | 0 | 1568 | +| +| __gap | uint256[50] | 251 | 0 | 1600 | +| +| __gap | uint256[50] | 301 | 0 | 1600 | +╰-----------------------------+-------------+------+--------+-------+--------------------------------------------------------------------------╯ + + +## Risc0Verifier + +╭-----------------------------+--------------------------+------+--------+-------+------------------------------------------------------------╮ +| Name | Type | Slot | Offset | Bytes | ++=============================================================================================================================================+ +| _initialized | uint8 | 0 | 0 | 1 | +| +| _initializing | bool | 0 | 1 | 1 | +| +| __gap | uint256[50] | 1 | 0 | 1600 | +| +| _owner | address | 51 | 0 | 20 | +| +| __gap | uint256[49] | 52 | 0 | 1568 | +| +| _pendingOwner | address | 101 | 0 | 20 | +| +| __gap | uint256[49] | 102 | 0 | 1568 | +| +| __resolver | address | 151 | 0 | 20 | +| +| __gapFromOldAddressResolver | uint256[49] | 152 | 0 | 1568 | +| +| __reentry | uint8 | 201 | 0 | 1 | +| +| __paused | uint8 | 201 | 1 | 1 | +| +| __gap | uint256[49] | 202 | 0 | 1568 | +| +| isImageTrusted | mapping(bytes32 => bool) | 251 | 0 | 32 | +| +| __gap | uint256[49] | 252 | 0 | 1568 | +╰-----------------------------+--------------------------+------+--------+-------+------------------------------------------------------------╯ + + +## SP1Verifier + +╭-----------------------------+--------------------------+------+--------+-------+--------------------------------------------------------╮ +| Name | Type | Slot | Offset | Bytes | ++=========================================================================================================================================+ +| _initialized | uint8 | 0 | 0 | 1 | +| +| _initializing | bool | 0 | 1 | 1 | +| +| __gap | uint256[50] | 1 | 0 | 1600 | +| +| _owner | address | 51 | 0 | 20 | +| +| __gap | uint256[49] | 52 | 0 | 1568 | +| +| _pendingOwner | address | 101 | 0 | 20 | +| +| __gap | uint256[49] | 102 | 0 | 1568 | +| +| __resolver | address | 151 | 0 | 20 | +| +| __gapFromOldAddressResolver | uint256[49] | 152 | 0 | 1568 | +| +| __reentry | uint8 | 201 | 0 | 1 | +| +| __paused | uint8 | 201 | 1 | 1 | +| +| __gap | uint256[49] | 202 | 0 | 1568 | +| +| isProgramTrusted | mapping(bytes32 => bool) | 251 | 0 | 32 | +| +| __gap | uint256[49] | 252 | 0 | 1568 | +╰-----------------------------+--------------------------+------+--------+-------+--------------------------------------------------------╯ + + +## SgxVerifier + +╭-----------------------------+-------------------------------------------------+------+--------+-------+--------------------------------------------------------╮ +| Name | Type | Slot | Offset | Bytes | ++================================================================================================================================================================+ +| _initialized | uint8 | 0 | 0 | 1 | +| +| _initializing | bool | 0 | 1 | 1 | +| +| __gap | uint256[50] | 1 | 0 | 1600 | +| +| _owner | address | 51 | 0 | 20 | +| +| __gap | uint256[49] | 52 | 0 | 1568 | +| +| _pendingOwner | address | 101 | 0 | 20 | +| +| __gap | uint256[49] | 102 | 0 | 1568 | +| +| __resolver | address | 151 | 0 | 20 | +| +| __gapFromOldAddressResolver | uint256[49] | 152 | 0 | 1568 | +| +| __reentry | uint8 | 201 | 0 | 1 | +| +| __paused | uint8 | 201 | 1 | 1 | +| +| __gap | uint256[49] | 202 | 0 | 1568 | +| +| nextInstanceId | uint256 | 251 | 0 | 32 | +| +| instances | mapping(uint256 => struct SgxVerifier.Instance) | 252 | 0 | 32 | +| +| addressRegistered | mapping(address => bool) | 253 | 0 | 32 | +| +| __gap | uint256[47] | 254 | 0 | 1504 | +╰-----------------------------+-------------------------------------------------+------+--------+-------+--------------------------------------------------------╯ + + +## AutomataDcapV3Attestation + +╭-----------------------------+-------------------------------------------------+------+--------+-------+-----------------------------------------------------------------------------------------------╮ +| Name | Type | Slot | Offset | Bytes | ++=======================================================================================================================================================================================================+ +| _initialized | uint8 | 0 | 0 | 1 | +| +| _initializing | bool | 0 | 1 | 1 | +| +| __gap | uint256[50] | 1 | 0 | 1600 | +| +| _owner | address | 51 | 0 | 20 | +| +| __gap | uint256[49] | 52 | 0 | 1568 | +| +| _pendingOwner | address | 101 | 0 | 20 | +| +| __gap | uint256[49] | 102 | 0 | 1568 | +| +| __resolver | address | 151 | 0 | 20 | +| +| __gapFromOldAddressResolver | uint256[49] | 152 | 0 | 1568 | +| +| __reentry | uint8 | 201 | 0 | 1 | +| +| __paused | uint8 | 201 | 1 | 1 | +| +| __gap | uint256[49] | 202 | 0 | 1568 | +| +| sigVerifyLib | contract ISigVerifyLib | 251 | 0 | 20 | +| +| pemCertLib | contract IPEMCertChainLib | 252 | 0 | 20 | +| +| checkLocalEnclaveReport | bool | 252 | 20 | 1 | +| +| trustedUserMrEnclave | mapping(bytes32 => bool) | 253 | 0 | 32 | +| +| trustedUserMrSigner | mapping(bytes32 => bool) | 254 | 0 | 32 | +| +| serialNumIsRevoked | mapping(uint256 => mapping(bytes => bool)) | 255 | 0 | 32 | +| +| tcbInfo | mapping(string => struct TCBInfoStruct.TCBInfo) | 256 | 0 | 32 | +| +| qeIdentity | struct EnclaveIdStruct.EnclaveId | 257 | 0 | 128 | +| +| __gap | uint256[39] | 261 | 0 | 1248 | +╰-----------------------------+-------------------------------------------------+------+--------+-------+-----------------------------------------------------------------------------------------------╯ + + +## TaikoInbox + +╭-----------------------------+--------------------------+------+--------+-------+--------------------------------------------------╮ +| Name | Type | Slot | Offset | Bytes | ++===================================================================================================================================+ +| _initialized | uint8 | 0 | 0 | 1 | +| +| _initializing | bool | 0 | 1 | 1 | +| +| __gap | uint256[50] | 1 | 0 | 1600 | +| +| _owner | address | 51 | 0 | 20 | +| +| __gap | uint256[49] | 52 | 0 | 1568 | +| +| _pendingOwner | address | 101 | 0 | 20 | +| +| __gap | uint256[49] | 102 | 0 | 1568 | +| +| __resolver | address | 151 | 0 | 20 | +| +| __gapFromOldAddressResolver | uint256[49] | 152 | 0 | 1568 | +| +| __reentry | uint8 | 201 | 0 | 1 | +| +| __paused | uint8 | 201 | 1 | 1 | +| +| __gap | uint256[49] | 202 | 0 | 1568 | +| +| state | struct ITaikoInbox.State | 251 | 0 | 1600 | +╰-----------------------------+--------------------------+------+--------+-------+--------------------------------------------------╯ + + +## HeklaInbox + +╭-----------------------------+--------------------------+------+--------+-------+--------------------------------------------------╮ +| Name | Type | Slot | Offset | Bytes | ++===================================================================================================================================+ +| _initialized | uint8 | 0 | 0 | 1 | +| +| _initializing | bool | 0 | 1 | 1 | +| +| __gap | uint256[50] | 1 | 0 | 1600 | +| +| _owner | address | 51 | 0 | 20 | +| +| __gap | uint256[49] | 52 | 0 | 1568 | +| +| _pendingOwner | address | 101 | 0 | 20 | +| +| __gap | uint256[49] | 102 | 0 | 1568 | +| +| __resolver | address | 151 | 0 | 20 | +| +| __gapFromOldAddressResolver | uint256[49] | 152 | 0 | 1568 | +| +| __reentry | uint8 | 201 | 0 | 1 | +| +| __paused | uint8 | 201 | 1 | 1 | +| +| __gap | uint256[49] | 202 | 0 | 1568 | +| +| state | struct ITaikoInbox.State | 251 | 0 | 1600 | +╰-----------------------------+--------------------------+------+--------+-------+--------------------------------------------------╯ + + +## MainnetBridge + +╭-----------------------------+-----------------------------------------+------+--------+-------+----------------------------------------------------------------------╮ +| Name | Type | Slot | Offset | Bytes | ++======================================================================================================================================================================+ +| _initialized | uint8 | 0 | 0 | 1 | +| +| _initializing | bool | 0 | 1 | 1 | +| +| __gap | uint256[50] | 1 | 0 | 1600 | +| +| _owner | address | 51 | 0 | 20 | +| +| __gap | uint256[49] | 52 | 0 | 1568 | +| +| _pendingOwner | address | 101 | 0 | 20 | +| +| __gap | uint256[49] | 102 | 0 | 1568 | +| +| __resolver | address | 151 | 0 | 20 | +| +| __gapFromOldAddressResolver | uint256[49] | 152 | 0 | 1568 | +| +| __reentry | uint8 | 201 | 0 | 1 | +| +| __paused | uint8 | 201 | 1 | 1 | +| +| __gap | uint256[49] | 202 | 0 | 1568 | +| +| __reserved1 | uint64 | 251 | 0 | 8 | +| +| nextMessageId | uint64 | 251 | 8 | 8 | +| +| messageStatus | mapping(bytes32 => enum IBridge.Status) | 252 | 0 | 32 | +| +| __ctx | struct IBridge.Context | 253 | 0 | 64 | +| +| __reserved2 | uint256 | 255 | 0 | 32 | +| +| __reserved3 | uint256 | 256 | 0 | 32 | +| +| __gap | uint256[44] | 257 | 0 | 1408 | +╰-----------------------------+-----------------------------------------+------+--------+-------+----------------------------------------------------------------------╯ + + +## MainnetSignalService + +╭-----------------------------+-----------------------------------------------+------+--------+-------+------------------------------------------------------------------------------------╮ +| Name | Type | Slot | Offset | Bytes | ++==========================================================================================================================================================================================+ +| _initialized | uint8 | 0 | 0 | 1 | +| +| _initializing | bool | 0 | 1 | 1 | +| +| __gap | uint256[50] | 1 | 0 | 1600 | +| +| _owner | address | 51 | 0 | 20 | +| +| __gap | uint256[49] | 52 | 0 | 1568 | +| +| _pendingOwner | address | 101 | 0 | 20 | +| +| __gap | uint256[49] | 102 | 0 | 1568 | +| +| __resolver | address | 151 | 0 | 20 | +| +| __gapFromOldAddressResolver | uint256[49] | 152 | 0 | 1568 | +| +| __reentry | uint8 | 201 | 0 | 1 | +| +| __paused | uint8 | 201 | 1 | 1 | +| +| __gap | uint256[49] | 202 | 0 | 1568 | +| +| topBlockId | mapping(uint64 => mapping(bytes32 => uint64)) | 251 | 0 | 32 | +| +| isAuthorized | mapping(address => bool) | 252 | 0 | 32 | +| +| _receivedSignals | mapping(bytes32 => bool) | 253 | 0 | 32 | +| +| __gap | uint256[47] | 254 | 0 | 1504 | +╰-----------------------------+-----------------------------------------------+------+--------+-------+------------------------------------------------------------------------------------╯ + + +## MainnetERC20Vault + +╭-----------------------------+------------------------------------------------------+------+--------+-------+------------------------------------------------------------------------------╮ +| Name | Type | Slot | Offset | Bytes | ++===========================================================================================================================================================================================+ +| _initialized | uint8 | 0 | 0 | 1 | +| +| _initializing | bool | 0 | 1 | 1 | +| +| __gap | uint256[50] | 1 | 0 | 1600 | +| +| _owner | address | 51 | 0 | 20 | +| +| __gap | uint256[49] | 52 | 0 | 1568 | +| +| _pendingOwner | address | 101 | 0 | 20 | +| +| __gap | uint256[49] | 102 | 0 | 1568 | +| +| __resolver | address | 151 | 0 | 20 | +| +| __gapFromOldAddressResolver | uint256[49] | 152 | 0 | 1568 | +| +| __reentry | uint8 | 201 | 0 | 1 | +| +| __paused | uint8 | 201 | 1 | 1 | +| +| __gap | uint256[49] | 202 | 0 | 1568 | +| +| __gap | uint256[50] | 251 | 0 | 1600 | +| +| bridgedToCanonical | mapping(address => struct ERC20Vault.CanonicalERC20) | 301 | 0 | 32 | +| +| canonicalToBridged | mapping(uint256 => mapping(address => address)) | 302 | 0 | 32 | +| +| btokenDenylist | mapping(address => bool) | 303 | 0 | 32 | +| +| lastMigrationStart | mapping(uint256 => mapping(address => uint256)) | 304 | 0 | 32 | +| +| solverConditionToSolver | mapping(bytes32 => address) | 305 | 0 | 32 | +| +| __gap | uint256[45] | 306 | 0 | 1440 | +╰-----------------------------+------------------------------------------------------+------+--------+-------+------------------------------------------------------------------------------╯ + + +## MainnetERC1155Vault + +╭-----------------------------+------------------------------------------------------+------+--------+-------+----------------------------------------------------------------------------------╮ +| Name | Type | Slot | Offset | Bytes | ++===============================================================================================================================================================================================+ +| _initialized | uint8 | 0 | 0 | 1 | +| +| _initializing | bool | 0 | 1 | 1 | +| +| __gap | uint256[50] | 1 | 0 | 1600 | +| +| _owner | address | 51 | 0 | 20 | +| +| __gap | uint256[49] | 52 | 0 | 1568 | +| +| _pendingOwner | address | 101 | 0 | 20 | +| +| __gap | uint256[49] | 102 | 0 | 1568 | +| +| __resolver | address | 151 | 0 | 20 | +| +| __gapFromOldAddressResolver | uint256[49] | 152 | 0 | 1568 | +| +| __reentry | uint8 | 201 | 0 | 1 | +| +| __paused | uint8 | 201 | 1 | 1 | +| +| __gap | uint256[49] | 202 | 0 | 1568 | +| +| __gap | uint256[50] | 251 | 0 | 1600 | +| +| bridgedToCanonical | mapping(address => struct BaseNFTVault.CanonicalNFT) | 301 | 0 | 32 | +| +| canonicalToBridged | mapping(uint256 => mapping(address => address)) | 302 | 0 | 32 | +| +| __gap | uint256[48] | 303 | 0 | 1536 | +| +| __gap | uint256[50] | 351 | 0 | 1600 | +| +| __gap | uint256[50] | 401 | 0 | 1600 | +| +| __gap | uint256[50] | 451 | 0 | 1600 | +╰-----------------------------+------------------------------------------------------+------+--------+-------+----------------------------------------------------------------------------------╯ + + +## MainnetERC721Vault + +╭-----------------------------+------------------------------------------------------+------+--------+-------+--------------------------------------------------------------------------------╮ +| Name | Type | Slot | Offset | Bytes | ++=============================================================================================================================================================================================+ +| _initialized | uint8 | 0 | 0 | 1 | +| +| _initializing | bool | 0 | 1 | 1 | +| +| __gap | uint256[50] | 1 | 0 | 1600 | +| +| _owner | address | 51 | 0 | 20 | +| +| __gap | uint256[49] | 52 | 0 | 1568 | +| +| _pendingOwner | address | 101 | 0 | 20 | +| +| __gap | uint256[49] | 102 | 0 | 1568 | +| +| __resolver | address | 151 | 0 | 20 | +| +| __gapFromOldAddressResolver | uint256[49] | 152 | 0 | 1568 | +| +| __reentry | uint8 | 201 | 0 | 1 | +| +| __paused | uint8 | 201 | 1 | 1 | +| +| __gap | uint256[49] | 202 | 0 | 1568 | +| +| __gap | uint256[50] | 251 | 0 | 1600 | +| +| bridgedToCanonical | mapping(address => struct BaseNFTVault.CanonicalNFT) | 301 | 0 | 32 | +| +| canonicalToBridged | mapping(uint256 => mapping(address => address)) | 302 | 0 | 32 | +| +| __gap | uint256[48] | 303 | 0 | 1536 | +| +| __gap | uint256[50] | 351 | 0 | 1600 | +╰-----------------------------+------------------------------------------------------+------+--------+-------+--------------------------------------------------------------------------------╯ + + +## MainnetInbox + +╭-----------------------------+--------------------------+------+--------+-------+--------------------------------------------------------╮ +| Name | Type | Slot | Offset | Bytes | ++=========================================================================================================================================+ +| _initialized | uint8 | 0 | 0 | 1 | +| +| _initializing | bool | 0 | 1 | 1 | +| +| __gap | uint256[50] | 1 | 0 | 1600 | +| +| _owner | address | 51 | 0 | 20 | +| +| __gap | uint256[49] | 52 | 0 | 1568 | +| +| _pendingOwner | address | 101 | 0 | 20 | +| +| __gap | uint256[49] | 102 | 0 | 1568 | +| +| __resolver | address | 151 | 0 | 20 | +| +| __gapFromOldAddressResolver | uint256[49] | 152 | 0 | 1568 | +| +| __reentry | uint8 | 201 | 0 | 1 | +| +| __paused | uint8 | 201 | 1 | 1 | +| +| __gap | uint256[49] | 202 | 0 | 1568 | +| +| state | struct ITaikoInbox.State | 251 | 0 | 1600 | +╰-----------------------------+--------------------------+------+--------+-------+--------------------------------------------------------╯ + + +## TokenUnlock + +╭-----------------------------+--------------------------+------+--------+-------+---------------------------------------------------╮ +| Name | Type | Slot | Offset | Bytes | ++====================================================================================================================================+ +| _initialized | uint8 | 0 | 0 | 1 | +| +| _initializing | bool | 0 | 1 | 1 | +| +| __gap | uint256[50] | 1 | 0 | 1600 | +| +| _owner | address | 51 | 0 | 20 | +| +| __gap | uint256[49] | 52 | 0 | 1568 | +| +| _pendingOwner | address | 101 | 0 | 20 | +| +| __gap | uint256[49] | 102 | 0 | 1568 | +| +| __resolver | address | 151 | 0 | 20 | +| +| __gapFromOldAddressResolver | uint256[49] | 152 | 0 | 1568 | +| +| __reentry | uint8 | 201 | 0 | 1 | +| +| __paused | uint8 | 201 | 1 | 1 | +| +| __gap | uint256[49] | 202 | 0 | 1568 | +| +| amountVested | uint256 | 251 | 0 | 32 | +| +| recipient | address | 252 | 0 | 20 | +| +| tgeTimestamp | uint64 | 252 | 20 | 8 | +| +| isProverSet | mapping(address => bool) | 253 | 0 | 32 | +| +| __gap | uint256[47] | 254 | 0 | 1504 | +╰-----------------------------+--------------------------+------+--------+-------+---------------------------------------------------╯ + + +## ProverSet + +╭-----------------------------+--------------------------+------+--------+-------+--------------------------------------------------╮ +| Name | Type | Slot | Offset | Bytes | ++===================================================================================================================================+ +| _initialized | uint8 | 0 | 0 | 1 | +| +| _initializing | bool | 0 | 1 | 1 | +| +| __gap | uint256[50] | 1 | 0 | 1600 | +| +| _owner | address | 51 | 0 | 20 | +| +| __gap | uint256[49] | 52 | 0 | 1568 | +| +| _pendingOwner | address | 101 | 0 | 20 | +| +| __gap | uint256[49] | 102 | 0 | 1568 | +| +| __resolver | address | 151 | 0 | 20 | +| +| __gapFromOldAddressResolver | uint256[49] | 152 | 0 | 1568 | +| +| __reentry | uint8 | 201 | 0 | 1 | +| +| __paused | uint8 | 201 | 1 | 1 | +| +| __gap | uint256[49] | 202 | 0 | 1568 | +| +| isProver | mapping(address => bool) | 251 | 0 | 32 | +| +| admin | address | 252 | 0 | 20 | +| +| __gap | uint256[48] | 253 | 0 | 1536 | +╰-----------------------------+--------------------------+------+--------+-------+--------------------------------------------------╯ + + +## ForkManager + +╭---------------+-------------+------+--------+-------+---------------------------------------------------╮ +| Name | Type | Slot | Offset | Bytes | ++=========================================================================================================+ +| _initialized | uint8 | 0 | 0 | 1 | +| +| _initializing | bool | 0 | 1 | 1 | +| +| __gap | uint256[50] | 1 | 0 | 1600 | +| +| _owner | address | 51 | 0 | 20 | +| +| __gap | uint256[49] | 52 | 0 | 1568 | +| +| _pendingOwner | address | 101 | 0 | 20 | +| +| __gap | uint256[49] | 102 | 0 | 1568 | +╰---------------+-------------+------+--------+-------+---------------------------------------------------╯ + + diff --git a/packages/protocol/contract_layout_layer2.md b/packages/protocol/contract_layout_layer2.md index e69de29bb2d..13c68295ee0 100644 --- a/packages/protocol/contract_layout_layer2.md +++ b/packages/protocol/contract_layout_layer2.md @@ -0,0 +1,707 @@ +## ERC1155Vault + +╭-----------------------------+------------------------------------------------------+------+--------+-------+-----------------------------------------------------------╮ +| Name | Type | Slot | Offset | Bytes | ++========================================================================================================================================================================+ +| _initialized | uint8 | 0 | 0 | 1 | +| +| _initializing | bool | 0 | 1 | 1 | +| +| __gap | uint256[50] | 1 | 0 | 1600 | +| +| _owner | address | 51 | 0 | 20 | +| +| __gap | uint256[49] | 52 | 0 | 1568 | +| +| _pendingOwner | address | 101 | 0 | 20 | +| +| __gap | uint256[49] | 102 | 0 | 1568 | +| +| __resolver | address | 151 | 0 | 20 | +| +| __gapFromOldAddressResolver | uint256[49] | 152 | 0 | 1568 | +| +| __reentry | uint8 | 201 | 0 | 1 | +| +| __paused | uint8 | 201 | 1 | 1 | +| +| __gap | uint256[49] | 202 | 0 | 1568 | +| +| __gap | uint256[50] | 251 | 0 | 1600 | +| +| bridgedToCanonical | mapping(address => struct BaseNFTVault.CanonicalNFT) | 301 | 0 | 32 | +| +| canonicalToBridged | mapping(uint256 => mapping(address => address)) | 302 | 0 | 32 | +| +| __gap | uint256[48] | 303 | 0 | 1536 | +| +| __gap | uint256[50] | 351 | 0 | 1600 | +| +| __gap | uint256[50] | 401 | 0 | 1600 | +| +| __gap | uint256[50] | 451 | 0 | 1600 | +╰-----------------------------+------------------------------------------------------+------+--------+-------+-----------------------------------------------------------╯ + + +## ERC20Vault + +╭-----------------------------+------------------------------------------------------+------+--------+-------+-------------------------------------------------------╮ +| Name | Type | Slot | Offset | Bytes | ++====================================================================================================================================================================+ +| _initialized | uint8 | 0 | 0 | 1 | +| +| _initializing | bool | 0 | 1 | 1 | +| +| __gap | uint256[50] | 1 | 0 | 1600 | +| +| _owner | address | 51 | 0 | 20 | +| +| __gap | uint256[49] | 52 | 0 | 1568 | +| +| _pendingOwner | address | 101 | 0 | 20 | +| +| __gap | uint256[49] | 102 | 0 | 1568 | +| +| __resolver | address | 151 | 0 | 20 | +| +| __gapFromOldAddressResolver | uint256[49] | 152 | 0 | 1568 | +| +| __reentry | uint8 | 201 | 0 | 1 | +| +| __paused | uint8 | 201 | 1 | 1 | +| +| __gap | uint256[49] | 202 | 0 | 1568 | +| +| __gap | uint256[50] | 251 | 0 | 1600 | +| +| bridgedToCanonical | mapping(address => struct ERC20Vault.CanonicalERC20) | 301 | 0 | 32 | +| +| canonicalToBridged | mapping(uint256 => mapping(address => address)) | 302 | 0 | 32 | +| +| btokenDenylist | mapping(address => bool) | 303 | 0 | 32 | +| +| lastMigrationStart | mapping(uint256 => mapping(address => uint256)) | 304 | 0 | 32 | +| +| solverConditionToSolver | mapping(bytes32 => address) | 305 | 0 | 32 | +| +| __gap | uint256[45] | 306 | 0 | 1440 | +╰-----------------------------+------------------------------------------------------+------+--------+-------+-------------------------------------------------------╯ + + +## ERC721Vault + +╭-----------------------------+------------------------------------------------------+------+--------+-------+---------------------------------------------------------╮ +| Name | Type | Slot | Offset | Bytes | ++======================================================================================================================================================================+ +| _initialized | uint8 | 0 | 0 | 1 | +| +| _initializing | bool | 0 | 1 | 1 | +| +| __gap | uint256[50] | 1 | 0 | 1600 | +| +| _owner | address | 51 | 0 | 20 | +| +| __gap | uint256[49] | 52 | 0 | 1568 | +| +| _pendingOwner | address | 101 | 0 | 20 | +| +| __gap | uint256[49] | 102 | 0 | 1568 | +| +| __resolver | address | 151 | 0 | 20 | +| +| __gapFromOldAddressResolver | uint256[49] | 152 | 0 | 1568 | +| +| __reentry | uint8 | 201 | 0 | 1 | +| +| __paused | uint8 | 201 | 1 | 1 | +| +| __gap | uint256[49] | 202 | 0 | 1568 | +| +| __gap | uint256[50] | 251 | 0 | 1600 | +| +| bridgedToCanonical | mapping(address => struct BaseNFTVault.CanonicalNFT) | 301 | 0 | 32 | +| +| canonicalToBridged | mapping(uint256 => mapping(address => address)) | 302 | 0 | 32 | +| +| __gap | uint256[48] | 303 | 0 | 1536 | +| +| __gap | uint256[50] | 351 | 0 | 1600 | +╰-----------------------------+------------------------------------------------------+------+--------+-------+---------------------------------------------------------╯ + + +## BridgedERC20 + +╭-----------------------------+-------------------------------------------------+------+--------+-------+-----------------------------------------------------------╮ +| Name | Type | Slot | Offset | Bytes | ++===================================================================================================================================================================+ +| _initialized | uint8 | 0 | 0 | 1 | +| +| _initializing | bool | 0 | 1 | 1 | +| +| __gap | uint256[50] | 1 | 0 | 1600 | +| +| _owner | address | 51 | 0 | 20 | +| +| __gap | uint256[49] | 52 | 0 | 1568 | +| +| _pendingOwner | address | 101 | 0 | 20 | +| +| __gap | uint256[49] | 102 | 0 | 1568 | +| +| __resolver | address | 151 | 0 | 20 | +| +| __gapFromOldAddressResolver | uint256[49] | 152 | 0 | 1568 | +| +| __reentry | uint8 | 201 | 0 | 1 | +| +| __paused | uint8 | 201 | 1 | 1 | +| +| __gap | uint256[49] | 202 | 0 | 1568 | +| +| _balances | mapping(address => uint256) | 251 | 0 | 32 | +| +| _allowances | mapping(address => mapping(address => uint256)) | 252 | 0 | 32 | +| +| _totalSupply | uint256 | 253 | 0 | 32 | +| +| _name | string | 254 | 0 | 32 | +| +| _symbol | string | 255 | 0 | 32 | +| +| __gap | uint256[45] | 256 | 0 | 1440 | +| +| srcToken | address | 301 | 0 | 20 | +| +| __srcDecimals | uint8 | 301 | 20 | 1 | +| +| srcChainId | uint256 | 302 | 0 | 32 | +| +| migratingAddress | address | 303 | 0 | 20 | +| +| migratingInbound | bool | 303 | 20 | 1 | +| +| __gap | uint256[47] | 304 | 0 | 1504 | +╰-----------------------------+-------------------------------------------------+------+--------+-------+-----------------------------------------------------------╯ + + +## BridgedERC20V2 + +╭-----------------------------+--------------------------------------------------------+------+--------+-------+---------------------------------------------------------------╮ +| Name | Type | Slot | Offset | Bytes | ++==============================================================================================================================================================================+ +| _initialized | uint8 | 0 | 0 | 1 | +| +| _initializing | bool | 0 | 1 | 1 | +| +| __gap | uint256[50] | 1 | 0 | 1600 | +| +| _owner | address | 51 | 0 | 20 | +| +| __gap | uint256[49] | 52 | 0 | 1568 | +| +| _pendingOwner | address | 101 | 0 | 20 | +| +| __gap | uint256[49] | 102 | 0 | 1568 | +| +| __resolver | address | 151 | 0 | 20 | +| +| __gapFromOldAddressResolver | uint256[49] | 152 | 0 | 1568 | +| +| __reentry | uint8 | 201 | 0 | 1 | +| +| __paused | uint8 | 201 | 1 | 1 | +| +| __gap | uint256[49] | 202 | 0 | 1568 | +| +| _balances | mapping(address => uint256) | 251 | 0 | 32 | +| +| _allowances | mapping(address => mapping(address => uint256)) | 252 | 0 | 32 | +| +| _totalSupply | uint256 | 253 | 0 | 32 | +| +| _name | string | 254 | 0 | 32 | +| +| _symbol | string | 255 | 0 | 32 | +| +| __gap | uint256[45] | 256 | 0 | 1440 | +| +| srcToken | address | 301 | 0 | 20 | +| +| __srcDecimals | uint8 | 301 | 20 | 1 | +| +| srcChainId | uint256 | 302 | 0 | 32 | +| +| migratingAddress | address | 303 | 0 | 20 | +| +| migratingInbound | bool | 303 | 20 | 1 | +| +| __gap | uint256[47] | 304 | 0 | 1504 | +| +| _hashedName | bytes32 | 351 | 0 | 32 | +| +| _hashedVersion | bytes32 | 352 | 0 | 32 | +| +| _name | string | 353 | 0 | 32 | +| +| _version | string | 354 | 0 | 32 | +| +| __gap | uint256[48] | 355 | 0 | 1536 | +| +| _nonces | mapping(address => struct CountersUpgradeable.Counter) | 403 | 0 | 32 | +| +| __gap | uint256[49] | 404 | 0 | 1568 | +╰-----------------------------+--------------------------------------------------------+------+--------+-------+---------------------------------------------------------------╯ + + +## BridgedERC721 + +╭-----------------------------+----------------------------------------------+------+--------+-------+-------------------------------------------------------------╮ +| Name | Type | Slot | Offset | Bytes | ++==================================================================================================================================================================+ +| _initialized | uint8 | 0 | 0 | 1 | +| +| _initializing | bool | 0 | 1 | 1 | +| +| __gap | uint256[50] | 1 | 0 | 1600 | +| +| _owner | address | 51 | 0 | 20 | +| +| __gap | uint256[49] | 52 | 0 | 1568 | +| +| _pendingOwner | address | 101 | 0 | 20 | +| +| __gap | uint256[49] | 102 | 0 | 1568 | +| +| __resolver | address | 151 | 0 | 20 | +| +| __gapFromOldAddressResolver | uint256[49] | 152 | 0 | 1568 | +| +| __reentry | uint8 | 201 | 0 | 1 | +| +| __paused | uint8 | 201 | 1 | 1 | +| +| __gap | uint256[49] | 202 | 0 | 1568 | +| +| __gap | uint256[50] | 251 | 0 | 1600 | +| +| _name | string | 301 | 0 | 32 | +| +| _symbol | string | 302 | 0 | 32 | +| +| _owners | mapping(uint256 => address) | 303 | 0 | 32 | +| +| _balances | mapping(address => uint256) | 304 | 0 | 32 | +| +| _tokenApprovals | mapping(uint256 => address) | 305 | 0 | 32 | +| +| _operatorApprovals | mapping(address => mapping(address => bool)) | 306 | 0 | 32 | +| +| __gap | uint256[44] | 307 | 0 | 1408 | +| +| srcToken | address | 351 | 0 | 20 | +| +| srcChainId | uint256 | 352 | 0 | 32 | +| +| __gap | uint256[48] | 353 | 0 | 1536 | +╰-----------------------------+----------------------------------------------+------+--------+-------+-------------------------------------------------------------╯ + + +## BridgedERC1155 + +╭-----------------------------+-------------------------------------------------+------+--------+-------+---------------------------------------------------------------╮ +| Name | Type | Slot | Offset | Bytes | ++=======================================================================================================================================================================+ +| _initialized | uint8 | 0 | 0 | 1 | +| +| _initializing | bool | 0 | 1 | 1 | +| +| __gap | uint256[50] | 1 | 0 | 1600 | +| +| _owner | address | 51 | 0 | 20 | +| +| __gap | uint256[49] | 52 | 0 | 1568 | +| +| _pendingOwner | address | 101 | 0 | 20 | +| +| __gap | uint256[49] | 102 | 0 | 1568 | +| +| __resolver | address | 151 | 0 | 20 | +| +| __gapFromOldAddressResolver | uint256[49] | 152 | 0 | 1568 | +| +| __reentry | uint8 | 201 | 0 | 1 | +| +| __paused | uint8 | 201 | 1 | 1 | +| +| __gap | uint256[49] | 202 | 0 | 1568 | +| +| __gap | uint256[50] | 251 | 0 | 1600 | +| +| _balances | mapping(uint256 => mapping(address => uint256)) | 301 | 0 | 32 | +| +| _operatorApprovals | mapping(address => mapping(address => bool)) | 302 | 0 | 32 | +| +| _uri | string | 303 | 0 | 32 | +| +| __gap | uint256[47] | 304 | 0 | 1504 | +| +| srcToken | address | 351 | 0 | 20 | +| +| srcChainId | uint256 | 352 | 0 | 32 | +| +| symbol | string | 353 | 0 | 32 | +| +| name | string | 354 | 0 | 32 | +| +| __gap | uint256[46] | 355 | 0 | 1472 | +╰-----------------------------+-------------------------------------------------+------+--------+-------+---------------------------------------------------------------╯ + + +## Bridge + +╭-----------------------------+-----------------------------------------+------+--------+-------+-------------------------------------------╮ +| Name | Type | Slot | Offset | Bytes | ++===========================================================================================================================================+ +| _initialized | uint8 | 0 | 0 | 1 | +| +| _initializing | bool | 0 | 1 | 1 | +| +| __gap | uint256[50] | 1 | 0 | 1600 | +| +| _owner | address | 51 | 0 | 20 | +| +| __gap | uint256[49] | 52 | 0 | 1568 | +| +| _pendingOwner | address | 101 | 0 | 20 | +| +| __gap | uint256[49] | 102 | 0 | 1568 | +| +| __resolver | address | 151 | 0 | 20 | +| +| __gapFromOldAddressResolver | uint256[49] | 152 | 0 | 1568 | +| +| __reentry | uint8 | 201 | 0 | 1 | +| +| __paused | uint8 | 201 | 1 | 1 | +| +| __gap | uint256[49] | 202 | 0 | 1568 | +| +| __reserved1 | uint64 | 251 | 0 | 8 | +| +| nextMessageId | uint64 | 251 | 8 | 8 | +| +| messageStatus | mapping(bytes32 => enum IBridge.Status) | 252 | 0 | 32 | +| +| __ctx | struct IBridge.Context | 253 | 0 | 64 | +| +| __reserved2 | uint256 | 255 | 0 | 32 | +| +| __reserved3 | uint256 | 256 | 0 | 32 | +| +| __gap | uint256[44] | 257 | 0 | 1408 | +╰-----------------------------+-----------------------------------------+------+--------+-------+-------------------------------------------╯ + + +## QuotaManager + +╭-----------------------------+-----------------------------------------------+------+--------+-------+-------------------------------------------------------╮ +| Name | Type | Slot | Offset | Bytes | ++=============================================================================================================================================================+ +| _initialized | uint8 | 0 | 0 | 1 | +| +| _initializing | bool | 0 | 1 | 1 | +| +| __gap | uint256[50] | 1 | 0 | 1600 | +| +| _owner | address | 51 | 0 | 20 | +| +| __gap | uint256[49] | 52 | 0 | 1568 | +| +| _pendingOwner | address | 101 | 0 | 20 | +| +| __gap | uint256[49] | 102 | 0 | 1568 | +| +| __resolver | address | 151 | 0 | 20 | +| +| __gapFromOldAddressResolver | uint256[49] | 152 | 0 | 1568 | +| +| __reentry | uint8 | 201 | 0 | 1 | +| +| __paused | uint8 | 201 | 1 | 1 | +| +| __gap | uint256[49] | 202 | 0 | 1568 | +| +| tokenQuota | mapping(address => struct QuotaManager.Quota) | 251 | 0 | 32 | +| +| quotaPeriod | uint24 | 252 | 0 | 3 | +| +| __gap | uint256[48] | 253 | 0 | 1536 | +╰-----------------------------+-----------------------------------------------+------+--------+-------+-------------------------------------------------------╯ + + +## DefaultResolver + +╭-----------------------------+-------------------------------------------------+------+--------+-------+-------------------------------------------------------------╮ +| Name | Type | Slot | Offset | Bytes | ++=====================================================================================================================================================================+ +| _initialized | uint8 | 0 | 0 | 1 | +| +| _initializing | bool | 0 | 1 | 1 | +| +| __gap | uint256[50] | 1 | 0 | 1600 | +| +| _owner | address | 51 | 0 | 20 | +| +| __gap | uint256[49] | 52 | 0 | 1568 | +| +| _pendingOwner | address | 101 | 0 | 20 | +| +| __gap | uint256[49] | 102 | 0 | 1568 | +| +| __resolver | address | 151 | 0 | 20 | +| +| __gapFromOldAddressResolver | uint256[49] | 152 | 0 | 1568 | +| +| __reentry | uint8 | 201 | 0 | 1 | +| +| __paused | uint8 | 201 | 1 | 1 | +| +| __gap | uint256[49] | 202 | 0 | 1568 | +| +| __addresses | mapping(uint256 => mapping(bytes32 => address)) | 251 | 0 | 32 | +| +| __gap | uint256[49] | 252 | 0 | 1568 | +╰-----------------------------+-------------------------------------------------+------+--------+-------+-------------------------------------------------------------╯ + + +## EssentialContract + +╭-----------------------------+-------------+------+--------+-------+-----------------------------------------------------------------╮ +| Name | Type | Slot | Offset | Bytes | ++=====================================================================================================================================+ +| _initialized | uint8 | 0 | 0 | 1 | +| +| _initializing | bool | 0 | 1 | 1 | +| +| __gap | uint256[50] | 1 | 0 | 1600 | +| +| _owner | address | 51 | 0 | 20 | +| +| __gap | uint256[49] | 52 | 0 | 1568 | +| +| _pendingOwner | address | 101 | 0 | 20 | +| +| __gap | uint256[49] | 102 | 0 | 1568 | +| +| __resolver | address | 151 | 0 | 20 | +| +| __gapFromOldAddressResolver | uint256[49] | 152 | 0 | 1568 | +| +| __reentry | uint8 | 201 | 0 | 1 | +| +| __paused | uint8 | 201 | 1 | 1 | +| +| __gap | uint256[49] | 202 | 0 | 1568 | +╰-----------------------------+-------------+------+--------+-------+-----------------------------------------------------------------╯ + + +## SignalService + +╭-----------------------------+-----------------------------------------------+------+--------+-------+---------------------------------------------------------╮ +| Name | Type | Slot | Offset | Bytes | ++===============================================================================================================================================================+ +| _initialized | uint8 | 0 | 0 | 1 | +| +| _initializing | bool | 0 | 1 | 1 | +| +| __gap | uint256[50] | 1 | 0 | 1600 | +| +| _owner | address | 51 | 0 | 20 | +| +| __gap | uint256[49] | 52 | 0 | 1568 | +| +| _pendingOwner | address | 101 | 0 | 20 | +| +| __gap | uint256[49] | 102 | 0 | 1568 | +| +| __resolver | address | 151 | 0 | 20 | +| +| __gapFromOldAddressResolver | uint256[49] | 152 | 0 | 1568 | +| +| __reentry | uint8 | 201 | 0 | 1 | +| +| __paused | uint8 | 201 | 1 | 1 | +| +| __gap | uint256[49] | 202 | 0 | 1568 | +| +| topBlockId | mapping(uint64 => mapping(bytes32 => uint64)) | 251 | 0 | 32 | +| +| isAuthorized | mapping(address => bool) | 252 | 0 | 32 | +| +| _receivedSignals | mapping(bytes32 => bool) | 253 | 0 | 32 | +| +| __gap | uint256[47] | 254 | 0 | 1504 | +╰-----------------------------+-----------------------------------------------+------+--------+-------+---------------------------------------------------------╯ + + +## BridgedTaikoToken + +╭-----------------------------------------------------+---------------------------------------------------------------+------+--------+-------+----------------------------------------------------------------╮ +| Name | Type | Slot | Offset | Bytes | ++==============================================================================================================================================================================================================+ +| _initialized | uint8 | 0 | 0 | 1 | +| +| _initializing | bool | 0 | 1 | 1 | +| +| __gap | uint256[50] | 1 | 0 | 1600 | +| +| _owner | address | 51 | 0 | 20 | +| +| __gap | uint256[49] | 52 | 0 | 1568 | +| +| _pendingOwner | address | 101 | 0 | 20 | +| +| __gap | uint256[49] | 102 | 0 | 1568 | +| +| __resolver | address | 151 | 0 | 20 | +| +| __gapFromOldAddressResolver | uint256[49] | 152 | 0 | 1568 | +| +| __reentry | uint8 | 201 | 0 | 1 | +| +| __paused | uint8 | 201 | 1 | 1 | +| +| __gap | uint256[49] | 202 | 0 | 1568 | +| +| __slots_previously_used_by_ERC20SnapshotUpgradeable | uint256[50] | 251 | 0 | 1600 | +| +| _balances | mapping(address => uint256) | 301 | 0 | 32 | +| +| _allowances | mapping(address => mapping(address => uint256)) | 302 | 0 | 32 | +| +| _totalSupply | uint256 | 303 | 0 | 32 | +| +| _name | string | 304 | 0 | 32 | +| +| _symbol | string | 305 | 0 | 32 | +| +| __gap | uint256[45] | 306 | 0 | 1440 | +| +| _hashedName | bytes32 | 351 | 0 | 32 | +| +| _hashedVersion | bytes32 | 352 | 0 | 32 | +| +| _name | string | 353 | 0 | 32 | +| +| _version | string | 354 | 0 | 32 | +| +| __gap | uint256[48] | 355 | 0 | 1536 | +| +| _nonces | mapping(address => struct CountersUpgradeable.Counter) | 403 | 0 | 32 | +| +| _PERMIT_TYPEHASH_DEPRECATED_SLOT | bytes32 | 404 | 0 | 32 | +| +| __gap | uint256[49] | 405 | 0 | 1568 | +| +| _delegates | mapping(address => address) | 454 | 0 | 32 | +| +| _checkpoints | mapping(address => struct ERC20VotesUpgradeable.Checkpoint[]) | 455 | 0 | 32 | +| +| _totalSupplyCheckpoints | struct ERC20VotesUpgradeable.Checkpoint[] | 456 | 0 | 32 | +| +| __gap | uint256[47] | 457 | 0 | 1504 | +| +| __gap | uint256[50] | 504 | 0 | 1600 | +╰-----------------------------------------------------+---------------------------------------------------------------+------+--------+-------+----------------------------------------------------------------╯ + + +## DelegateOwner + +╭-----------------------------+-------------+------+--------+-------+--------------------------------------------------╮ +| Name | Type | Slot | Offset | Bytes | ++======================================================================================================================+ +| _initialized | uint8 | 0 | 0 | 1 | +| +| _initializing | bool | 0 | 1 | 1 | +| +| __gap | uint256[50] | 1 | 0 | 1600 | +| +| _owner | address | 51 | 0 | 20 | +| +| __gap | uint256[49] | 52 | 0 | 1568 | +| +| _pendingOwner | address | 101 | 0 | 20 | +| +| __gap | uint256[49] | 102 | 0 | 1568 | +| +| __resolver | address | 151 | 0 | 20 | +| +| __gapFromOldAddressResolver | uint256[49] | 152 | 0 | 1568 | +| +| __reentry | uint8 | 201 | 0 | 1 | +| +| __paused | uint8 | 201 | 1 | 1 | +| +| __gap | uint256[49] | 202 | 0 | 1568 | +| +| remoteChainId | uint64 | 251 | 0 | 8 | +| +| admin | address | 251 | 8 | 20 | +| +| nextTxId | uint64 | 252 | 0 | 8 | +| +| remoteOwner | address | 252 | 8 | 20 | +| +| __gap | uint256[48] | 253 | 0 | 1536 | +╰-----------------------------+-------------+------+--------+-------+--------------------------------------------------╯ + + +## TaikoAnchor + +╭-----------------------------+-----------------------------+------+--------+-------+----------------------------------------------------╮ +| Name | Type | Slot | Offset | Bytes | ++========================================================================================================================================+ +| _initialized | uint8 | 0 | 0 | 1 | +| +| _initializing | bool | 0 | 1 | 1 | +| +| __gap | uint256[50] | 1 | 0 | 1600 | +| +| _owner | address | 51 | 0 | 20 | +| +| __gap | uint256[49] | 52 | 0 | 1568 | +| +| _pendingOwner | address | 101 | 0 | 20 | +| +| __gap | uint256[49] | 102 | 0 | 1568 | +| +| __resolver | address | 151 | 0 | 20 | +| +| __gapFromOldAddressResolver | uint256[49] | 152 | 0 | 1568 | +| +| __reentry | uint8 | 201 | 0 | 1 | +| +| __paused | uint8 | 201 | 1 | 1 | +| +| __gap | uint256[49] | 202 | 0 | 1568 | +| +| _blockhashes | mapping(uint256 => bytes32) | 251 | 0 | 32 | +| +| publicInputHash | bytes32 | 252 | 0 | 32 | +| +| parentGasExcess | uint64 | 253 | 0 | 8 | +| +| lastSyncedBlock | uint64 | 253 | 8 | 8 | +| +| parentTimestamp | uint64 | 253 | 16 | 8 | +| +| parentGasTarget | uint64 | 253 | 24 | 8 | +| +| l1ChainId | uint64 | 254 | 0 | 8 | +| +| anchorInput | bytes32 | 255 | 0 | 32 | +| +| __gap | uint256[45] | 256 | 0 | 1440 | +╰-----------------------------+-----------------------------+------+--------+-------+----------------------------------------------------╯ + + From 61a4c8b04d91b1d0b967aeeaf443be3da5f8eeca Mon Sep 17 00:00:00 2001 From: Daniel Wang Date: Mon, 13 Jan 2025 10:39:05 +0800 Subject: [PATCH 40/41] fix a bug --- .../contracts/layer1/based/TaikoInbox.sol | 10 +- .../snapshots/InboxTest_ProposeAndProve.json | 4 + .../test/layer1/based/InBoxTest_Params.t.sol | 2 +- .../test/layer1/based/InboxTestBase.sol | 11 +- ....t.sol => InboxTest_ProposeAndProve.t.sol} | 231 +++++++++++------- 5 files changed, 168 insertions(+), 90 deletions(-) create mode 100644 packages/protocol/snapshots/InboxTest_ProposeAndProve.json rename packages/protocol/test/layer1/based/{InboxTest_Suite1.t.sol => InboxTest_ProposeAndProve.t.sol} (66%) diff --git a/packages/protocol/contracts/layer1/based/TaikoInbox.sol b/packages/protocol/contracts/layer1/based/TaikoInbox.sol index fe149211279..e932ece94d8 100644 --- a/packages/protocol/contracts/layer1/based/TaikoInbox.sol +++ b/packages/protocol/contracts/layer1/based/TaikoInbox.sol @@ -495,6 +495,7 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { blockHash = ts.blockHash; if (batchId % _config.stateRootSyncInternal == 0) { + synced.batchId = batchId; synced.blockId = batch.lastBlockId; synced.tid = tid; synced.stateRoot = ts.stateRoot; @@ -517,15 +518,15 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { batch.verifiedTransitionId = tid; emit BatchesVerified(_stats2.lastVerifiedBatchId, blockHash); - if (synced.blockId != 0) { - if (synced.blockId != _stats2.lastVerifiedBatchId) { + if (synced.batchId != 0) { + if (synced.batchId != _stats2.lastVerifiedBatchId) { // We write the synced batch's verifiedTransitionId to storage - batch = state.batches[synced.blockId % _config.batchRingBufferSize]; + batch = state.batches[synced.batchId % _config.batchRingBufferSize]; batch.verifiedTransitionId = synced.tid; } Stats1 memory stats1 = state.stats1; - stats1.lastSyncedBatchId = synced.blockId; + stats1.lastSyncedBatchId = batch.batchId; stats1.lastSyncedAt = uint64(block.timestamp); state.stats1 = stats1; @@ -655,6 +656,7 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko { } struct SyncBlock { + uint64 batchId; uint64 blockId; uint24 tid; bytes32 stateRoot; diff --git a/packages/protocol/snapshots/InboxTest_ProposeAndProve.json b/packages/protocol/snapshots/InboxTest_ProposeAndProve.json new file mode 100644 index 00000000000..bd97a93ab80 --- /dev/null +++ b/packages/protocol/snapshots/InboxTest_ProposeAndProve.json @@ -0,0 +1,4 @@ +{ + "proposeBatch": "1920492", + "proveBatches": "297825" +} diff --git a/packages/protocol/test/layer1/based/InBoxTest_Params.t.sol b/packages/protocol/test/layer1/based/InBoxTest_Params.t.sol index 430c15d562d..826eb40cab0 100644 --- a/packages/protocol/test/layer1/based/InBoxTest_Params.t.sol +++ b/packages/protocol/test/layer1/based/InBoxTest_Params.t.sol @@ -3,7 +3,7 @@ pragma solidity ^0.8.24; import "./InboxTestBase.sol"; -contract InBoxTest_Params is InboxTestBase { +contract InboxTest_Params is InboxTestBase { function getConfig() internal pure override returns (ITaikoInbox.Config memory) { return ITaikoInbox.Config({ chainId: LibNetwork.TAIKO_MAINNET, diff --git a/packages/protocol/test/layer1/based/InboxTestBase.sol b/packages/protocol/test/layer1/based/InboxTestBase.sol index 1efc0b7f2df..dbfb182a2be 100644 --- a/packages/protocol/test/layer1/based/InboxTestBase.sol +++ b/packages/protocol/test/layer1/based/InboxTestBase.sol @@ -11,6 +11,7 @@ abstract contract InboxTestBase is Layer1Test { SignalService internal signalService; uint256 genesisBlockProposedAt; uint256 genesisBlockProposedIn; + uint256 private __blocksPerBatch; function getConfig() internal view virtual returns (ITaikoInbox.Config memory); @@ -32,6 +33,8 @@ abstract contract InboxTestBase is Layer1Test { genesisBlockProposedAt = block.timestamp; genesisBlockProposedIn = block.number; + __blocksPerBatch = 1; + inbox = deployInbox(correctBlockhash(0), getConfig()); signalService = deploySignalService(address(new SignalService())); @@ -44,6 +47,11 @@ abstract contract InboxTestBase is Layer1Test { mineOneBlockAndWrap(12 seconds); } + modifier WhenEachBatchHasMultipleBlocks(uint256 _blocksPerBatch) { + __blocksPerBatch = _blocksPerBatch; + _; + } + modifier WhenLogAllBatchesAndTransitions() { _logAllBatchesAndTransitions(); _; @@ -103,7 +111,7 @@ abstract contract InboxTestBase is Layer1Test { returns (uint64[] memory batchIds) { ITaikoInbox.BatchParams memory batchParams; - batchParams.blocks = new ITaikoInbox.BlockParams[](1); + batchParams.blocks = new ITaikoInbox.BlockParams[](__blocksPerBatch); batchIds = new uint64[](numBatchesToPropose); @@ -172,6 +180,7 @@ abstract contract InboxTestBase is Layer1Test { } console2.log(unicode"│ |── metahash:", Strings.toHexString(uint256(batch.metaHash))); console2.log(unicode"│ |── timestamp:", batch.timestamp); + console2.log(unicode"│ |── lastBlockId:", batch.lastBlockId); console2.log(unicode"│ |── anchorBlockId:", batch.anchorBlockId); console2.log(unicode"│ |── nextTransitionId:", batch.nextTransitionId); console2.log(unicode"│ |── verifiedTransitionId:", batch.verifiedTransitionId); diff --git a/packages/protocol/test/layer1/based/InboxTest_Suite1.t.sol b/packages/protocol/test/layer1/based/InboxTest_ProposeAndProve.t.sol similarity index 66% rename from packages/protocol/test/layer1/based/InboxTest_Suite1.t.sol rename to packages/protocol/test/layer1/based/InboxTest_ProposeAndProve.t.sol index 1f6ec835681..6c272858150 100644 --- a/packages/protocol/test/layer1/based/InboxTest_Suite1.t.sol +++ b/packages/protocol/test/layer1/based/InboxTest_ProposeAndProve.t.sol @@ -3,7 +3,7 @@ pragma solidity ^0.8.24; import "./InboxTestBase.sol"; -contract InboxTest_Suite1 is InboxTestBase { +contract InboxTest_ProposeAndProve is InboxTestBase { function getConfig() internal pure override returns (ITaikoInbox.Config memory) { return ITaikoInbox.Config({ chainId: LibNetwork.TAIKO_MAINNET, @@ -47,13 +47,13 @@ contract InboxTest_Suite1 is InboxTestBase { assertEq(stats2.lastUnpausedAt, 0); // - Verify genesis block - ITaikoInbox.Batch memory blk = inbox.getBatch(0); - assertEq(blk.batchId, 0); - assertEq(blk.metaHash, bytes32(uint256(1))); - assertEq(blk.timestamp, genesisBlockProposedAt); - assertEq(blk.anchorBlockId, genesisBlockProposedIn); - assertEq(blk.nextTransitionId, 2); - assertEq(blk.verifiedTransitionId, 1); + ITaikoInbox.Batch memory batch = inbox.getBatch(0); + assertEq(batch.batchId, 0); + assertEq(batch.metaHash, bytes32(uint256(1))); + assertEq(batch.timestamp, genesisBlockProposedAt); + assertEq(batch.anchorBlockId, genesisBlockProposedIn); + assertEq(batch.nextTransitionId, 2); + assertEq(batch.verifiedTransitionId, 1); (uint64 batchId, uint64 blockId, ITaikoInbox.Transition memory tran) = inbox.getLastVerifiedTransition(); @@ -94,24 +94,24 @@ contract InboxTest_Suite1 is InboxTestBase { assertEq(stats2.lastUnpausedAt, 0); // - Verify genesis block - ITaikoInbox.Batch memory blk = inbox.getBatch(0); - assertEq(blk.batchId, 0); - assertEq(blk.metaHash, bytes32(uint256(1))); - assertEq(blk.timestamp, genesisBlockProposedAt); - assertEq(blk.anchorBlockId, genesisBlockProposedIn); - assertEq(blk.nextTransitionId, 2); - assertEq(blk.verifiedTransitionId, 1); + ITaikoInbox.Batch memory batch = inbox.getBatch(0); + assertEq(batch.batchId, 0); + assertEq(batch.metaHash, bytes32(uint256(1))); + assertEq(batch.timestamp, genesisBlockProposedAt); + assertEq(batch.anchorBlockId, genesisBlockProposedIn); + assertEq(batch.nextTransitionId, 2); + assertEq(batch.verifiedTransitionId, 1); // Verify block data for (uint64 i = 1; i < 10; ++i) { - blk = inbox.getBatch(i); - assertEq(blk.batchId, i); - assertEq(blk.metaHash, keccak256(abi.encode(_loadMetadata(i)))); - - assertEq(blk.timestamp, block.timestamp); - assertEq(blk.anchorBlockId, block.number - 1); - assertEq(blk.nextTransitionId, 1); - assertEq(blk.verifiedTransitionId, 0); + batch = inbox.getBatch(i); + assertEq(batch.batchId, i); + assertEq(batch.metaHash, keccak256(abi.encode(_loadMetadata(i)))); + + assertEq(batch.timestamp, block.timestamp); + assertEq(batch.anchorBlockId, block.number - 1); + assertEq(batch.nextTransitionId, 1); + assertEq(batch.verifiedTransitionId, 0); } // - Proposing one block block will revert @@ -151,24 +151,24 @@ contract InboxTest_Suite1 is InboxTestBase { assertEq(stats2.lastUnpausedAt, 0); // - Verify genesis block - ITaikoInbox.Batch memory blk = inbox.getBatch(0); - assertEq(blk.batchId, 0); - assertEq(blk.metaHash, bytes32(uint256(1))); - assertEq(blk.timestamp, genesisBlockProposedAt); - assertEq(blk.anchorBlockId, genesisBlockProposedIn); - assertEq(blk.nextTransitionId, 2); - assertEq(blk.verifiedTransitionId, 1); + ITaikoInbox.Batch memory batch = inbox.getBatch(0); + assertEq(batch.batchId, 0); + assertEq(batch.metaHash, bytes32(uint256(1))); + assertEq(batch.timestamp, genesisBlockProposedAt); + assertEq(batch.anchorBlockId, genesisBlockProposedIn); + assertEq(batch.nextTransitionId, 2); + assertEq(batch.verifiedTransitionId, 1); // Verify block data for (uint64 i = 1; i < 7; ++i) { - blk = inbox.getBatch(i); - assertEq(blk.batchId, i); - assertEq(blk.metaHash, keccak256(abi.encode(_loadMetadata(i)))); - - assertEq(blk.timestamp, block.timestamp); - assertEq(blk.anchorBlockId, block.number - 1); - assertEq(blk.nextTransitionId, 2); - assertEq(blk.verifiedTransitionId, 0); + batch = inbox.getBatch(i); + assertEq(batch.batchId, i); + assertEq(batch.metaHash, keccak256(abi.encode(_loadMetadata(i)))); + + assertEq(batch.timestamp, block.timestamp); + assertEq(batch.anchorBlockId, block.number - 1); + assertEq(batch.nextTransitionId, 2); + assertEq(batch.verifiedTransitionId, 0); } } @@ -191,7 +191,8 @@ contract InboxTest_Suite1 is InboxTestBase { _proveBatchesWithCorrectTransitions(batchIds); } - function test_inbox_propose_and_prove_many_blocks_with_first_transition_being_correct() + function test_inbox_propose_1block_per_batch_and_prove_many_blocks_with_first_transition_being_correct( + ) external transactBy(Alice) WhenMultipleBatchesAreProposedWithDefaultParameters(9) @@ -225,27 +226,89 @@ contract InboxTest_Suite1 is InboxTestBase { assertEq(tran.stateRoot, correctStateRoot(5)); // - Verify genesis block - ITaikoInbox.Batch memory blk = inbox.getBatch(0); - assertEq(blk.batchId, 0); - assertEq(blk.metaHash, bytes32(uint256(1))); - assertEq(blk.timestamp, genesisBlockProposedAt); - assertEq(blk.anchorBlockId, genesisBlockProposedIn); - assertEq(blk.nextTransitionId, 2); - assertEq(blk.verifiedTransitionId, 1); + ITaikoInbox.Batch memory batch = inbox.getBatch(0); + assertEq(batch.batchId, 0); + assertEq(batch.metaHash, bytes32(uint256(1))); + assertEq(batch.timestamp, genesisBlockProposedAt); + assertEq(batch.anchorBlockId, genesisBlockProposedIn); + assertEq(batch.nextTransitionId, 2); + assertEq(batch.verifiedTransitionId, 1); // Verify block data for (uint64 i = 1; i < 10; ++i) { - blk = inbox.getBatch(i); - assertEq(blk.batchId, i); - assertEq(blk.metaHash, keccak256(abi.encode(_loadMetadata(i)))); + batch = inbox.getBatch(i); + assertEq(batch.batchId, i); + assertEq(batch.metaHash, keccak256(abi.encode(_loadMetadata(i)))); - assertEq(blk.timestamp, block.timestamp); - assertEq(blk.anchorBlockId, block.number - 1); - assertEq(blk.nextTransitionId, 2); + assertEq(batch.timestamp, block.timestamp); + assertEq(batch.anchorBlockId, block.number - 1); + assertEq(batch.nextTransitionId, 2); if (i % getConfig().stateRootSyncInternal == 0 || i == stats2.lastVerifiedBatchId) { - assertEq(blk.verifiedTransitionId, 1); + assertEq(batch.verifiedTransitionId, 1); } else { - assertEq(blk.verifiedTransitionId, 0); + assertEq(batch.verifiedTransitionId, 0); + } + } + } + + function test_inbox_propose_7block_per_batch_and_prove_many_blocks_with_first_transition_being_correct( + ) + external + WhenEachBatchHasMultipleBlocks(7) + transactBy(Alice) + WhenMultipleBatchesAreProposedWithDefaultParameters(9) + WhenMultipleBatchesAreProvedWithCorrectTransitions(1, 10) + WhenLogAllBatchesAndTransitions + { + // - All stats are correct and expected + + ITaikoInbox.Stats1 memory stats1 = inbox.getStats1(); + assertEq(stats1.lastSyncedBatchId, 5); + assertEq(stats1.lastSyncedAt, block.timestamp); + + ITaikoInbox.Stats2 memory stats2 = inbox.getStats2(); + assertEq(stats2.numBatches, 10); + assertEq(stats2.lastVerifiedBatchId, 9); + assertEq(stats2.paused, false); + assertEq(stats2.lastProposedIn, block.number); + assertEq(stats2.lastUnpausedAt, 0); + + (uint64 batchId, uint64 blockId, ITaikoInbox.Transition memory tran) = + inbox.getLastVerifiedTransition(); + assertEq(batchId, 9); + assertEq(blockId, 9 * 7); + assertEq(tran.blockHash, correctBlockhash(9)); + assertEq(tran.stateRoot, bytes32(uint256(0))); + + (batchId, blockId, tran) = inbox.getLastSyncedTransition(); + assertEq(batchId, 5); + assertEq(blockId, 5 * 7); + assertEq(tran.blockHash, correctBlockhash(5)); + assertEq(tran.stateRoot, correctStateRoot(5)); + + // - Verify genesis block + ITaikoInbox.Batch memory batch = inbox.getBatch(0); + assertEq(batch.batchId, 0); + assertEq(batch.metaHash, bytes32(uint256(1))); + assertEq(batch.timestamp, genesisBlockProposedAt); + assertEq(batch.anchorBlockId, genesisBlockProposedIn); + assertEq(batch.nextTransitionId, 2); + assertEq(batch.verifiedTransitionId, 1); + + // Verify block data + for (uint64 i = 1; i < 10; ++i) { + batch = inbox.getBatch(i); + assertEq(batch.batchId, i); + assertEq(batch.metaHash, keccak256(abi.encode(_loadMetadata(i)))); + + assertEq(batch.timestamp, block.timestamp); + assertEq(batch.lastBlockId, i * 7); + assertEq(batch.anchorBlockId, block.number - 1); + assertEq(batch.nextTransitionId, 2); + if (i % getConfig().stateRootSyncInternal == 0 || i == stats2.lastVerifiedBatchId) { + assertEq(batch.verifiedTransitionId, 1); + } else { + assertEq(batch.verifiedTransitionId, 0); } } } @@ -272,27 +335,27 @@ contract InboxTest_Suite1 is InboxTestBase { assertEq(stats2.lastUnpausedAt, 0); // - Verify genesis block - ITaikoInbox.Batch memory blk = inbox.getBatch(0); - assertEq(blk.batchId, 0); - assertEq(blk.metaHash, bytes32(uint256(1))); - assertEq(blk.timestamp, genesisBlockProposedAt); - assertEq(blk.anchorBlockId, genesisBlockProposedIn); - assertEq(blk.nextTransitionId, 2); - assertEq(blk.verifiedTransitionId, 1); + ITaikoInbox.Batch memory batch = inbox.getBatch(0); + assertEq(batch.batchId, 0); + assertEq(batch.metaHash, bytes32(uint256(1))); + assertEq(batch.timestamp, genesisBlockProposedAt); + assertEq(batch.anchorBlockId, genesisBlockProposedIn); + assertEq(batch.nextTransitionId, 2); + assertEq(batch.verifiedTransitionId, 1); // Verify block data for (uint64 i = 1; i < 10; ++i) { - blk = inbox.getBatch(i); - assertEq(blk.batchId, i); - assertEq(blk.metaHash, keccak256(abi.encode(_loadMetadata(i)))); + batch = inbox.getBatch(i); + assertEq(batch.batchId, i); + assertEq(batch.metaHash, keccak256(abi.encode(_loadMetadata(i)))); - assertEq(blk.timestamp, block.timestamp); - assertEq(blk.anchorBlockId, block.number - 1); - assertEq(blk.nextTransitionId, 3); + assertEq(batch.timestamp, block.timestamp); + assertEq(batch.anchorBlockId, block.number - 1); + assertEq(batch.nextTransitionId, 3); if (i % getConfig().stateRootSyncInternal == 0 || i == stats2.lastVerifiedBatchId) { - assertEq(blk.verifiedTransitionId, 2); + assertEq(batch.verifiedTransitionId, 2); } else { - assertEq(blk.verifiedTransitionId, 0); + assertEq(batch.verifiedTransitionId, 0); } } } @@ -337,27 +400,27 @@ contract InboxTest_Suite1 is InboxTestBase { // Verify block data for (uint64 i = 8; i < 15; ++i) { - ITaikoInbox.Batch memory blk = inbox.getBatch(i); - assertEq(blk.batchId, i); - assertEq(blk.metaHash, keccak256(abi.encode(_loadMetadata(i)))); + ITaikoInbox.Batch memory batch = inbox.getBatch(i); + assertEq(batch.batchId, i); + assertEq(batch.metaHash, keccak256(abi.encode(_loadMetadata(i)))); - assertEq(blk.timestamp, block.timestamp); - assertEq(blk.anchorBlockId, block.number - 1); + assertEq(batch.timestamp, block.timestamp); + assertEq(batch.anchorBlockId, block.number - 1); if (i == 8) { - assertEq(blk.verifiedTransitionId, 0); - assertEq(blk.nextTransitionId, 2); + assertEq(batch.verifiedTransitionId, 0); + assertEq(batch.nextTransitionId, 2); } else if (i == 9) { - assertEq(blk.verifiedTransitionId, 1); - assertEq(blk.nextTransitionId, 2); + assertEq(batch.verifiedTransitionId, 1); + assertEq(batch.nextTransitionId, 2); } else if (i == 10) { - assertEq(blk.verifiedTransitionId, 1); - assertEq(blk.nextTransitionId, 2); + assertEq(batch.verifiedTransitionId, 1); + assertEq(batch.nextTransitionId, 2); } else if (i == 11 || i == 12 || i == 13 || i == 16 || i == 17) { - assertEq(blk.verifiedTransitionId, 0); - assertEq(blk.nextTransitionId, 1); + assertEq(batch.verifiedTransitionId, 0); + assertEq(batch.nextTransitionId, 1); } else if (i == 14 || i == 15) { - assertEq(blk.verifiedTransitionId, 0); - assertEq(blk.nextTransitionId, 2); + assertEq(batch.verifiedTransitionId, 0); + assertEq(batch.nextTransitionId, 2); } } } From 5b60189f504dca610695e003340b1329cae3d75c Mon Sep 17 00:00:00 2001 From: Daniel Wang Date: Mon, 13 Jan 2025 10:40:05 +0800 Subject: [PATCH 41/41] fix --- .gitignore | 2 +- packages/protocol/snapshots/InboxTest_ProposeAndProve.json | 4 ---- 2 files changed, 1 insertion(+), 5 deletions(-) delete mode 100644 packages/protocol/snapshots/InboxTest_ProposeAndProve.json diff --git a/.gitignore b/.gitignore index 9d23425fd5b..b00841d3fe2 100644 --- a/.gitignore +++ b/.gitignore @@ -120,4 +120,4 @@ __pycache__/ # Idea .idea/ -packages/protocol/snapshots/InboxTest_Suite1.json +packages/protocol/snapshots/InboxTest_ProposeAndProve.json diff --git a/packages/protocol/snapshots/InboxTest_ProposeAndProve.json b/packages/protocol/snapshots/InboxTest_ProposeAndProve.json deleted file mode 100644 index bd97a93ab80..00000000000 --- a/packages/protocol/snapshots/InboxTest_ProposeAndProve.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "proposeBatch": "1920492", - "proveBatches": "297825" -}