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

feat(protocol): allow specifying signals per L2 block #18905

Merged
merged 15 commits into from
Feb 10, 2025
3 changes: 1 addition & 2 deletions packages/protocol/contracts/layer1/based/ITaikoInbox.sol
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ interface ITaikoInbox {
// For all other blocks in the same batch, the block timestamp is its parent block's
// timestamp plus this time shift value.
uint8 timeShift;
bytes32[] signalSlots;
}

struct BlobParams {
Expand All @@ -52,7 +53,6 @@ interface ITaikoInbox {
bytes32 anchorInput;
uint64 lastBlockTimestamp;
bool revertIfNotFirstProposal;
bytes32[] signalSlots;
// Specifies the number of blocks to be generated from this batch.
BlobParams blobParams;
BlockParams[] blocks;
Expand Down Expand Up @@ -80,7 +80,6 @@ interface ITaikoInbox {
bytes32 anchorBlockHash;
bytes32 anchorInput;
LibSharedData.BaseFeeConfig baseFeeConfig;
bytes32[] signalSlots;
}

/// @dev This struct holds batch metadata essential for proving the batch.
Expand Down
40 changes: 22 additions & 18 deletions packages/protocol/contracts/layer1/based/TaikoInbox.sol
Original file line number Diff line number Diff line change
Expand Up @@ -143,11 +143,7 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko {
anchorBlockId: anchorBlockId,
anchorBlockHash: blockhash(anchorBlockId),
anchorInput: params.anchorInput,
baseFeeConfig: config.baseFeeConfig,
//
// Signals are applied only to the first block of the batch.
// For the remaining blocks, an empty list shall be used by the anchorV3 function.
signalSlots: params.signalSlots
baseFeeConfig: config.baseFeeConfig
});

require(info_.anchorBlockHash != 0, ZeroAnchorBlockHash());
Expand Down Expand Up @@ -794,8 +790,29 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko {
require(lastBlockTimestamp_ <= block.timestamp, TimestampTooLarge());

uint64 totalShift;
address signalService;

for (uint256 i; i < blocksLength; ++i) {
totalShift += _params.blocks[i].timeShift;

uint256 signalSlotsLength = _params.blocks[i].signalSlots.length;

if (signalSlotsLength != 0) {
require(signalSlotsLength <= _maxSignalsToReceive, TooManySignals());

if (signalService == address(0)) {
signalService = resolve(LibStrings.B_SIGNAL_SERVICE, false);
}

for (uint256 j; j < signalSlotsLength; ++j) {
require(
ISignalService(signalService).isSignalSent(
_params.blocks[i].signalSlots[j]
),
SignalNotSent()
);
}
}
}

require(lastBlockTimestamp_ >= totalShift, TimestampTooSmall());
Expand All @@ -819,19 +836,6 @@ abstract contract TaikoInbox is EssentialContract, ITaikoInbox, ITaiko {
);
}

uint256 signalSlotsLength = _params.signalSlots.length;

if (signalSlotsLength != 0) {
require(signalSlotsLength <= _maxSignalsToReceive, TooManySignals());

ISignalService signalService =
ISignalService(resolve(LibStrings.B_SIGNAL_SERVICE, false));

for (uint256 i; i < signalSlotsLength; ++i) {
require(signalService.isSignalSent(_params.signalSlots[i]), SignalNotSent());
}
}

require(blocksLength != 0, BlockNotFound());
require(blocksLength <= _maxBlocksPerBatch, TooManyBlocks());
}
Expand Down
6 changes: 5 additions & 1 deletion packages/protocol/test/layer1/based/InboxTest_Params.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,11 @@ contract InboxTest_Params is InboxTestBase {
ITaikoInbox.Batch memory parent = inbox.getBatch(1);

ITaikoInbox.BlockParams[] memory blocks = new ITaikoInbox.BlockParams[](1);
blocks[0] = ITaikoInbox.BlockParams({ numTransactions: 0, timeShift: 0 });
blocks[0] = ITaikoInbox.BlockParams({
numTransactions: 0,
timeShift: 0,
signalSlots: new bytes32[](0)
});

ITaikoInbox.BatchParams memory params;
params.blocks = new ITaikoInbox.BlockParams[](1);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ contract MockTaikoInbox is EssentialContract {
info_ = ITaikoInbox.BatchInfo({
txsHash: keccak256(_txList),
blobHashes: new bytes32[](0),
signalSlots: new bytes32[](0),
blobByteOffset: 0,
blobByteSize: 0,
extraData: bytes32(0),
Expand Down
14 changes: 10 additions & 4 deletions packages/protocol/test/layer1/preconf/router/RouterTest.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,11 @@ contract RouterTest is RouterTestBase {

// Setup block params
ITaikoInbox.BlockParams[] memory blockParams = new ITaikoInbox.BlockParams[](1);
blockParams[0] = ITaikoInbox.BlockParams({ numTransactions: 1, timeShift: 1 });
blockParams[0] = ITaikoInbox.BlockParams({
numTransactions: 1,
timeShift: 1,
signalSlots: new bytes32[](0)
});

ITaikoInbox.BlobParams memory blobParams;

Expand All @@ -43,7 +47,6 @@ contract RouterTest is RouterTestBase {
anchorInput: bytes32(0),
lastBlockTimestamp: uint64(block.timestamp),
revertIfNotFirstProposal: false,
signalSlots: new bytes32[](0),
blobParams: blobParams,
blocks: blockParams
});
Expand Down Expand Up @@ -115,7 +118,11 @@ contract RouterTest is RouterTestBase {

// Setup block params
ITaikoInbox.BlockParams[] memory blockParams = new ITaikoInbox.BlockParams[](1);
blockParams[0] = ITaikoInbox.BlockParams({ numTransactions: 1, timeShift: 1 });
blockParams[0] = ITaikoInbox.BlockParams({
numTransactions: 1,
timeShift: 1,
signalSlots: new bytes32[](0)
});

ITaikoInbox.BlobParams memory blobParams;

Expand All @@ -128,7 +135,6 @@ contract RouterTest is RouterTestBase {
anchorInput: bytes32(0),
lastBlockTimestamp: uint64(block.timestamp),
revertIfNotFirstProposal: false,
signalSlots: new bytes32[](0),
blobParams: blobParams,
blocks: blockParams
});
Expand Down