Skip to content

Commit

Permalink
feat(protocol): allow resetting genesis hash on L1 before 1st block i…
Browse files Browse the repository at this point in the history
…s proposed (#17078)

Co-authored-by: dantaik <[email protected]>
  • Loading branch information
dantaik and dantaik authored May 10, 2024
1 parent 4903bec commit 2b4816e
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 24 deletions.
1 change: 1 addition & 0 deletions packages/protocol/contracts/L1/TaikoErrors.sol
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ abstract contract TaikoErrors {
error L1_NOT_ASSIGNED_PROVER();
error L1_PROVING_PAUSED();
error L1_RECEIVE_DISABLED();
error L1_TOO_LATE();
error L1_TOO_MANY_BLOCKS();
error L1_TRANSITION_ID_ZERO();
error L1_TRANSITION_NOT_FOUND();
Expand Down
4 changes: 4 additions & 0 deletions packages/protocol/contracts/L1/TaikoL1.sol
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,10 @@ contract TaikoL1 is EssentialContract, ITaikoL1, TaikoEvents, TaikoErrors {
state.__reserve1 = 0;
}

function resetGenesisHash(bytes32 _genesisBlockHash) external onlyOwner {
LibVerifying.resetGenesisHash(state, _genesisBlockHash);
}

/// @inheritdoc ITaikoL1
function proposeBlock(
bytes calldata _params,
Expand Down
64 changes: 40 additions & 24 deletions packages/protocol/contracts/L1/libs/LibVerifying.sol
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ library LibVerifying {
error L1_INVALID_CONFIG();
error L1_INVALID_GENESIS_HASH();
error L1_TRANSITION_ID_ZERO();
error L1_TOO_LATE();

/// @notice Initializes the Taiko protocol state.
/// @param _state The state to initialize.
Expand All @@ -54,33 +55,14 @@ library LibVerifying {
internal
{
if (!_isConfigValid(_config)) revert L1_INVALID_CONFIG();
if (_genesisBlockHash == 0) revert L1_INVALID_GENESIS_HASH();

// Init state
_state.slotA.genesisHeight = uint64(block.number);
_state.slotA.genesisTimestamp = uint64(block.timestamp);
_state.slotB.numBlocks = 1;
_setupGenesisBlock(_state, _genesisBlockHash);
}

// Init the genesis block
TaikoData.Block storage blk = _state.blocks[0];
blk.nextTransitionId = 2;
blk.proposedAt = uint64(block.timestamp);
blk.verifiedTransitionId = 1;
blk.metaHash = bytes32(uint256(1)); // Give the genesis metahash a non-zero value.
function resetGenesisHash(TaikoData.State storage _state, bytes32 _genesisBlockHash) internal {
if (_state.slotB.numBlocks != 1) revert L1_TOO_LATE();

// Init the first state transition
TaikoData.TransitionState storage ts = _state.transitions[0][1];
ts.blockHash = _genesisBlockHash;
ts.prover = address(0);
ts.timestamp = uint64(block.timestamp);

emit BlockVerified({
blockId: 0,
prover: address(0),
blockHash: _genesisBlockHash,
stateRoot: 0,
tier: 0
});
_setupGenesisBlock(_state, _genesisBlockHash);
}

/// @dev Verifies up to N blocks.
Expand Down Expand Up @@ -211,6 +193,40 @@ library LibVerifying {
emit StateVariablesUpdated({ slotB: _state.slotB });
}

function _setupGenesisBlock(
TaikoData.State storage _state,
bytes32 _genesisBlockHash
)
private
{
if (_genesisBlockHash == 0) revert L1_INVALID_GENESIS_HASH();
// Init state
_state.slotA.genesisHeight = uint64(block.number);
_state.slotA.genesisTimestamp = uint64(block.timestamp);
_state.slotB.numBlocks = 1;

// Init the genesis block
TaikoData.Block storage blk = _state.blocks[0];
blk.nextTransitionId = 2;
blk.proposedAt = uint64(block.timestamp);
blk.verifiedTransitionId = 1;
blk.metaHash = bytes32(uint256(1)); // Give the genesis metahash a non-zero value.

// Init the first state transition
TaikoData.TransitionState storage ts = _state.transitions[0][1];
ts.blockHash = _genesisBlockHash;
ts.prover = address(0);
ts.timestamp = uint64(block.timestamp);

emit BlockVerified({
blockId: 0,
prover: address(0),
blockHash: _genesisBlockHash,
stateRoot: 0,
tier: 0
});
}

function _syncChainData(
TaikoData.State storage _state,
TaikoData.Config memory _config,
Expand Down

0 comments on commit 2b4816e

Please sign in to comment.