Skip to content

Conversation

@luiz-lvj
Copy link
Collaborator

@luiz-lvj luiz-lvj commented Jan 16, 2026

Add Linea Chain Support to Block Hash Pusher

This PR adds support for Linea L2 to the block hash pusher system, enabling Ethereum L1 block hashes to be pushed to Linea L2.

Contracts:

  • LineaPusher - L1 contract that pushes block hashes to Linea L2 via Linea Rollup.sendMessage()
  • LineaBuffer - L2 contract that receives and stores block hashes with access control via L2MessageService

PS: this PR must be merged after #56 and #57

Summary by CodeRabbit

  • New Features

    • Added support for pushing block hashes between Linea L1 and L2 networks
    • Integrated cross-chain messaging functionality with configurable access controls
  • Documentation

    • Updated Block Hash Pusher documentation with Linea integration details

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link

coderabbitai bot commented Jan 16, 2026

📝 Walkthrough

Walkthrough

Adds Linea network support to the block hash pusher system by introducing a new submodule, creating LineaPusher and LineaBuffer contracts for L1-to-L2 cross-chain communication, updating import mappings, and providing comprehensive tests and documentation.

Changes

Cohort / File(s) Summary
Submodule and Import Configuration
.gitmodules, lib/linea-monorepo, remappings.txt
Adds linea-monorepo submodule entry and creates import mapping for @linea-contracts pointing to the submodule's contracts directory.
Linea Buffer Contract
src/contracts/block-hash-pusher/linea/LineaBuffer.sol
New L2 contract extending BaseBuffer for receiving and storing L1 block hashes. Implements access control via L2 MessageService, allows one-time pusher configuration by owner, and includes comprehensive error handling.
Linea Pusher Contract
src/contracts/block-hash-pusher/linea/LineaPusher.sol
New L1 contract extending BlockHashArrayBuilder for pushing batched block hashes to L2 via Linea's messaging service. Encodes calldata and handles L2 transaction fees through immutable references to the rollup and buffer addresses.
Documentation
src/contracts/block-hash-pusher/README.md
Adds Linea section documenting deployment, access control, required addresses, configuration, and message flow for LineaPusher and LineaBuffer.
LineaBuffer Tests
test/block-hash-pusher/linea/LineaBuffer.t.sol
Comprehensive test suite covering hash reception, sender validation, pusher address management, and access control with fuzzing and revert scenarios.
LineaPusher Tests
test/block-hash-pusher/linea/LineaPusher.t.sol
Test suite validating pushHashes behavior including fork testing, fuzzing, value sufficiency checks, batch size validation, and view function correctness.
Mock Linea Message Service
test/block-hash-pusher/mocks/MockLineaMessageService.sol
Mock implementation of IMessageService and IClaimMessageV1 for testing, supporting message sending and claiming with sender context management and calldata execution.

Sequence Diagram(s)

sequenceDiagram
    actor User
    participant L1 as LineaPusher<br/>(L1)
    participant MessageService as Linea<br/>MessageService
    participant L2 as LineaBuffer<br/>(L2)
    
    User->>L1: pushHashes(firstBlock, batchSize, l2TxData)
    L1->>L1: Build block hash array
    L1->>L1: Encode receiveHashes calldata
    L1->>MessageService: sendMessage(buffer, fee, calldata)
    MessageService->>MessageService: Store & emit MessageSent
    
    Note over MessageService: L2 message relay
    
    MessageService->>L2: claimMessage(...) 
    L2->>L2: Verify sender == MessageService
    L2->>L2: Extract pusher from MessageService
    L2->>L2: Validate pusher address matches
    L2->>L2: Store block hashes
    L2->>MessageService: Emit MessageClaimed
    MessageService->>L1: Message execution confirmed
    L1->>L1: Emit BlockHashesPushed
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~30 minutes

Suggested reviewers

  • pepebndc
  • nahimterrazas
  • frangio

Poem

🐇 A Linea is drawn, from L1 to L2,
Through forests of hashes, both old and new,
With buffers and pushers in harmony bound,
Cross-chain block storage—on Linea found! 📦✨

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Add Linea pusher and buffer' directly and concisely summarizes the main change: introducing two new Linea-related contracts (LineaPusher and LineaBuffer) to support pushing block hashes to Linea L2.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@luiz-lvj luiz-lvj requested a review from frangio January 16, 2026 15:48
pragma solidity 0.8.30;

import {IBuffer} from "./interfaces/IBuffer.sol";
import {AddressAliasHelper} from "@arbitrum/nitro-contracts/src/libraries/AddressAliasHelper.sol";
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is not used

}

/// @inheritdoc IBuffer
function receiveHashes(uint256 firstBlockNumber, bytes32[] calldata blockHashes) external {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

on the interface blockHashes is memory, here is calldata

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, changed it to calldata

address private _pusherAddress;

/// @notice Thrown when attempting to receive hashes before the pusher address has been set.
error PusherAddressNotSet();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There seem to be a few errors and events that show up in every Buffer. Perhaps those should be moved to IBuffer?

@luiz-lvj luiz-lvj marked this pull request as ready for review January 23, 2026 14:26
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@src/contracts/block-hash-pusher/linea/LineaPusher.sol`:
- Around line 27-30: Add explicit zero-address checks in the constructor to fail
fast if rollup_ or bufferAddress_ is address(0). In the constructor of
LineaPusher.sol, validate rollup_ and bufferAddress_ with require(rollup_ !=
address(0), "...") and require(bufferAddress_ != address(0), "...") before
assigning to _lineaRollup and _bufferAddress, using clear revert messages that
identify the bad parameter (e.g., "LineaPusher: rollup is zero address" and
"LineaPusher: buffer is zero address").
🧹 Nitpick comments (2)
src/contracts/block-hash-pusher/linea/LineaBuffer.sol (1)

20-51: Consider making _l2MessageService immutable.
It’s constructor-only state, so immutable saves storage reads and locks the invariant.

♻️ Proposed refactor
-    address private _l2MessageService;
+    address private immutable _l2MessageService;

-    constructor(address l2MessageService_, address initialOwner_) Ownable(initialOwner_) {
-        _l2MessageService = l2MessageService_;
-
-        if (l2MessageService_ == address(0)) {
-            revert InvalidL2MessageServiceAddress();
-        }
-    }
+    constructor(address l2MessageService_, address initialOwner_) Ownable(initialOwner_) {
+        if (l2MessageService_ == address(0)) {
+            revert InvalidL2MessageServiceAddress();
+        }
+        _l2MessageService = l2MessageService_;
+    }
test/block-hash-pusher/linea/LineaBuffer.t.sol (1)

45-56: Unused l2Calldata variable.

Line 51 creates l2Calldata but it's not used since the test calls receiveHashes directly. This is a minor cleanup opportunity.

♻️ Suggested cleanup
     function testFuzz_receiveHashes_reverts_if_sender_is_not_linea_message_service(address notLineaMessageService)
         public
     {
         vm.assume(notLineaMessageService != address(mockLineaMessageService));
         LineaBuffer buffer = new LineaBuffer(address(mockLineaMessageService), owner);
 
-        bytes memory l2Calldata = abi.encodeCall(buffer.receiveHashes, (1, new bytes32[](1)));
-
         vm.expectRevert(abi.encodeWithSelector(LineaBuffer.InvalidSender.selector));
         vm.prank(notLineaMessageService);
         buffer.receiveHashes(1, new bytes32[](1));
     }

Comment on lines +27 to +30
constructor(address rollup_, address bufferAddress_) {
_lineaRollup = rollup_;
_bufferAddress = bufferAddress_;
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Add zero-address checks for rollup and buffer.
Fail fast on misconfiguration to avoid sending messages to address(0).

🐛 Proposed fix
     constructor(address rollup_, address bufferAddress_) {
+        require(rollup_ != address(0) && bufferAddress_ != address(0), "LineaPusher: zero address");
         _lineaRollup = rollup_;
         _bufferAddress = bufferAddress_;
     }
🤖 Prompt for AI Agents
In `@src/contracts/block-hash-pusher/linea/LineaPusher.sol` around lines 27 - 30,
Add explicit zero-address checks in the constructor to fail fast if rollup_ or
bufferAddress_ is address(0). In the constructor of LineaPusher.sol, validate
rollup_ and bufferAddress_ with require(rollup_ != address(0), "...") and
require(bufferAddress_ != address(0), "...") before assigning to _lineaRollup
and _bufferAddress, using clear revert messages that identify the bad parameter
(e.g., "LineaPusher: rollup is zero address" and "LineaPusher: buffer is zero
address").

@luiz-lvj luiz-lvj merged commit 6599163 into main Jan 23, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants