Skip to content

Commit e36436c

Browse files
authored
Merge pull request #10 from init4tech/anna/one-per-rebase
feat: simple limiting 1 ru block per host block
2 parents 995e1b9 + b145808 commit e36436c

File tree

2 files changed

+30
-0
lines changed

2 files changed

+30
-0
lines changed

src/Zenith.sol

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,10 @@ contract Zenith is HostPassage, AccessControlDefaultAdminRules {
2828
/// rollupChainId => nextSequence number
2929
mapping(uint256 => uint256) public nextSequence;
3030

31+
/// @notice The host block number that a block was last submitted at for a given rollup chainId.
32+
/// rollupChainId => host blockNumber that block was last submitted at
33+
mapping(uint256 => uint256) public lastSubmittedAtBlock;
34+
3135
/// @notice Thrown when a block submission is attempted with a sequence number that is not the next block for the rollup chainId.
3236
/// @dev Blocks must be submitted in strict monotonic increasing order.
3337
/// @param expected - the correct next sequence number for the given rollup chainId.
@@ -41,6 +45,9 @@ contract Zenith is HostPassage, AccessControlDefaultAdminRules {
4145
/// @param derivedSequencer - the derived signer of the block data that is not a permissioned sequencer.
4246
error BadSignature(address derivedSequencer);
4347

48+
/// @notice Thrown when attempting to submit more than one rollup block per host block
49+
error OneRollupBlockPerHostBlock();
50+
4451
/// @notice Emitted when a new rollup block is successfully submitted.
4552
/// @param sequencer - the address of the sequencer that signed the block.
4653
/// @param header - the block header information for the block.
@@ -100,6 +107,9 @@ contract Zenith is HostPassage, AccessControlDefaultAdminRules {
100107
// assert that signature is valid && sequencer is permissioned
101108
if (!hasRole(SEQUENCER_ROLE, sequencer)) revert BadSignature(sequencer);
102109

110+
// assert this is the first rollup block submitted for this host block
111+
if (lastSubmittedAtBlock[header.rollupChainId] == block.number) revert OneRollupBlockPerHostBlock();
112+
lastSubmittedAtBlock[header.rollupChainId] = block.number;
103113

104114
// emit event
105115
emit BlockSubmitted(sequencer, header, blockDataHash);

test/Zenith.t.sol

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,5 +97,25 @@ contract ZenithTest is Test {
9797
vm.expectRevert(abi.encodeWithSelector(Zenith.BadSignature.selector, derivedSigner));
9898
target.submitBlock(header, blockDataHash, v, r, s, blockData);
9999
}
100+
101+
// cannot submit two rollup blocks within one host block
102+
function test_onePerBlock() public {
103+
// sign block commitmenet with correct sequencer key
104+
(uint8 v, bytes32 r, bytes32 s) = vm.sign(sequencerKey, commit);
105+
106+
// should emit BlockSubmitted event
107+
vm.expectEmit();
108+
emit BlockSubmitted(vm.addr(sequencerKey), header, blockDataHash);
109+
target.submitBlock(header, blockDataHash, v, r, s, blockData);
110+
111+
// incerement the header sequence
112+
header.sequence += 1;
113+
commit = target.blockCommitment(header, blockDataHash);
114+
(v, r, s) = vm.sign(sequencerKey, commit);
115+
116+
// should revert with OneRollupBlockPerHostBlock
117+
// (NOTE: this test works because forge does not increment block.number when it mines a transaction)
118+
vm.expectRevert(abi.encodeWithSelector(Zenith.OneRollupBlockPerHostBlock.selector));
119+
target.submitBlock(header, blockDataHash, v, r, s, blockData);
100120
}
101121
}

0 commit comments

Comments
 (0)