Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

revert some changes #15774

Merged
merged 4 commits into from
Feb 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions packages/protocol/contracts/L1/TaikoL1.sol
Original file line number Diff line number Diff line change
Expand Up @@ -167,8 +167,13 @@ contract TaikoL1 is
/// @notice Important: as this contract doesn't send each block's state root as a signal when
/// the block is verified, bridging developers should subscribe to CrossChainSynced events
/// to ensure all synced state roots are verifiable using merkle proofs.
function getSyncedSnippet() public view override returns (ICrossChainSync.Snippet memory) {
return LibUtils.getSyncedSnippet(state, getConfig());
function getSyncedSnippet(uint64 blockId)
public
view
override
returns (ICrossChainSync.Snippet memory)
{
return LibUtils.getSyncedSnippet(state, getConfig(), blockId);
}

/// @notice Gets the state variables of the TaikoL1 contract.
Expand Down
9 changes: 4 additions & 5 deletions packages/protocol/contracts/L1/libs/LibUtils.sol
Original file line number Diff line number Diff line change
Expand Up @@ -55,25 +55,24 @@ library LibUtils {

function getSyncedSnippet(
TaikoData.State storage state,
TaikoData.Config memory config
TaikoData.Config memory config,
uint64 blockId
)
external
view
returns (ICrossChainSync.Snippet memory)
{
uint64 _blockId = state.slotB.lastVerifiedBlockId;
uint64 _blockId = blockId == 0 ? state.slotB.lastVerifiedBlockId : blockId;
uint64 slot = _blockId % config.blockRingBufferSize;

TaikoData.Block storage blk = state.blocks[slot];

if (blk.blockId != _blockId) revert L1_BLOCK_MISMATCH();
if (blk.verifiedTransitionId == 0) revert L1_TRANSITION_NOT_FOUND();

TaikoData.TransitionState storage transition =
state.transitions[slot][blk.verifiedTransitionId];

return ICrossChainSync.Snippet({
blockId: _blockId,
blockId: blockId,
blockHash: transition.blockHash,
stateRoot: transition.stateRoot
});
Expand Down
42 changes: 25 additions & 17 deletions packages/protocol/contracts/L2/TaikoL2.sol
Original file line number Diff line number Diff line change
Expand Up @@ -45,15 +45,15 @@ contract TaikoL2 is CrossChainOwned, ICrossChainSync {

// Mapping from L2 block numbers to their block hashes.
// All L2 block hashes will be saved in this mapping.
mapping(uint256 blockId => bytes32 blockHash) public l2Hashes; // slot 1
mapping(uint256 blockId => bytes32 blockHash) public l2Hashes;
mapping(uint256 l1height => ICrossChainSync.Snippet) public snippets;

// A hash to check the integrity of public inputs.
bytes32 public publicInputHash; // slot 2
uint64 public gasExcess; // slot 3
bytes32 public publicInputHash; // slot 3
uint64 public gasExcess; // slot 4
uint64 public latestSyncedL1Height;

Snippet private _l1Snippet; // slot 4, 5, 6

uint256[144] private __gap;
uint256[146] private __gap;

event Anchored(bytes32 parentHash, uint64 gasExcess);

Expand Down Expand Up @@ -147,15 +147,17 @@ contract TaikoL2 is CrossChainOwned, ICrossChainSync {
ownerChainId, "state_root", l1StateRoot
);

emit CrossChainSynced(l1Height, l1BlockHash, l1StateRoot);

// Update state variables
l2Hashes[parentId] = blockhash(parentId);
snippets[l1Height] = ICrossChainSync.Snippet({
blockId: l1Height,
blockHash: l1BlockHash,
stateRoot: l1StateRoot
});
publicInputHash = publicInputHashNew;

_l1Snippet.blockId = l1Height;
_l1Snippet.blockHash = l1BlockHash;
_l1Snippet.stateRoot = l1StateRoot;
emit CrossChainSynced(l1Height, l1BlockHash, l1StateRoot);

latestSyncedL1Height = l1Height;
emit Anchored(blockhash(parentId), gasExcess);
}

Expand All @@ -170,8 +172,14 @@ contract TaikoL2 is CrossChainOwned, ICrossChainSync {
}

/// @inheritdoc ICrossChainSync
function getSyncedSnippet() public view returns (ICrossChainSync.Snippet memory) {
return _l1Snippet;
function getSyncedSnippet(uint64 blockId)
public
view
override
returns (ICrossChainSync.Snippet memory)
{
uint256 id = blockId == 0 ? latestSyncedL1Height : blockId;
return snippets[id];
}

/// @notice Gets the basefee and gas excess using EIP-1559 configuration for
Expand Down Expand Up @@ -263,10 +271,10 @@ contract TaikoL2 is CrossChainOwned, ICrossChainSync {
// Calculate how much more gas to issue to offset gas excess.
// after each L1 block time, config.gasTarget more gas is issued,
// the gas excess will be reduced accordingly.
// Note that when _l1Snippet.blockId is zero, we skip this step.
// Note that when latestSyncedL1Height is zero, we skip this step.
uint256 numL1Blocks;
if (_l1Snippet.blockId > 0 && l1Height > _l1Snippet.blockId) {
numL1Blocks = l1Height - _l1Snippet.blockId;
if (latestSyncedL1Height > 0 && l1Height > latestSyncedL1Height) {
numL1Blocks = l1Height - latestSyncedL1Height;
}

if (numL1Blocks > 0) {
Expand Down
4 changes: 3 additions & 1 deletion packages/protocol/contracts/common/ICrossChainSync.sol
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ interface ICrossChainSync {
event CrossChainSynced(uint64 indexed blockId, bytes32 blockHash, bytes32 stateRoot);

/// @notice Fetches the hash of a block from the opposite chain.
/// @param blockId The target block id. Specifying 0 retrieves the hash
/// of the latest block.
/// @return snippet The block hash and signal root synced.
function getSyncedSnippet() external view returns (Snippet memory snippet);
function getSyncedSnippet(uint64 blockId) external view returns (Snippet memory snippet);
}
2 changes: 1 addition & 1 deletion packages/protocol/test/HelperContracts.sol
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ contract DummyCrossChainSync is EssentialContract, ICrossChainSync {
_snippet.stateRoot = stateRoot;
}

function getSyncedSnippet() public view returns (Snippet memory) {
function getSyncedSnippet(uint64 /*blockId*/ ) public view returns (Snippet memory) {
return _snippet;
}
}
31 changes: 23 additions & 8 deletions packages/protocol/test/L1/TaikoL1.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -192,11 +192,13 @@ contract TaikoL1Test is TaikoL1TestBase {
}

/// @dev getCrossChainBlockHash tests
function test_L1_getCrossChainSnippet_Genesis() external {
ICrossChainSync.Snippet memory snippet = L1.getSyncedSnippet();
assertEq(snippet.blockId, 0);
assertEq(snippet.blockHash, GENESIS_BLOCK_HASH);
assertEq(snippet.stateRoot, 0);
function test_L1_getCrossChainBlockHash0() external {
bytes32 genHash = L1.getSyncedSnippet(0).blockHash;
assertEq(GENESIS_BLOCK_HASH, genHash);

// Reverts if block is not yet verified!
vm.expectRevert(TaikoErrors.L1_BLOCK_MISMATCH.selector);
L1.getSyncedSnippet(1);
}

/// @dev getSyncedSnippet tests
Expand Down Expand Up @@ -233,13 +235,26 @@ contract TaikoL1Test is TaikoL1TestBase {

verifyBlock(Carol, 1);

assertEq(L1.getSyncedSnippet().blockId, blockId);
assertEq(L1.getSyncedSnippet().blockHash, blockHash);
assertEq(L1.getSyncedSnippet().stateRoot, stateRoot);
// Querying written blockhash
assertEq(L1.getSyncedSnippet(blockId).blockHash, blockHash);

mine(5);
parentHashes[blockId] = blockHash;
}

uint64 queriedBlockId = 1;
bytes32 expectedSR = bytes32(1e9 + uint256(queriedBlockId));

assertEq(expectedSR, L1.getSyncedSnippet(queriedBlockId).stateRoot);

// 2nd
queriedBlockId = 2;
expectedSR = bytes32(1e9 + uint256(queriedBlockId));
assertEq(expectedSR, L1.getSyncedSnippet(queriedBlockId).stateRoot);

// Not found -> reverts
vm.expectRevert(TaikoErrors.L1_BLOCK_MISMATCH.selector);
L1.getSyncedSnippet((count + 1));
}

function test_L1_deposit_hash_creation() external {
Expand Down
Loading