A bug in the respective layer 0/1/2 network code that results in unintended smart contract behavior with no concrete funds at direct risk
Description
Fjord derivation rejects valid Brotli channels at the activation boundary
Summary
The Fjord upgrade activates derivation changes from the timestamp of the L1 block currently being processed. The channel reader applies that rule when it decides whether Fjord channel parameters should be used. BatchReader::next_batch then performs a second Brotli gate against the decoded batch's L2 timestamp instead of the L1 derivation context.
That mismatch causes valid post-Fjord Brotli channels to be discarded if they contain a batch whose L2 timestamp is still pre-Fjord.
The derivation pipeline selects Fjord channel parameters from the current L1 origin:
That is consistent with the Fjord derivation specification: derivation changes apply when the pipeline is processing data from an L1 block whose timestamp is at or after the activation time.
The decoded channel is then passed into BatchReader::next_batch, which performs an additional Brotli check:
batch.timestamp() is the L2 timestamp embedded in the decoded batch. It is not the same value as the L1 timestamp that governs derivation activation. Around the fork boundary, those values can legitimately differ.
As a result, the node can enter the Fjord derivation path, accept Brotli channel framing, and then discard the channel solely because the decoded L2 batch timestamp has not yet crossed the same boundary.
Impact
This is a protocol-transition derivation bug.
A node following this implementation can reject spec-valid Brotli channel data during the Fjord activation window. The direct consequence is liveness loss in derivation: valid channel data is dropped, the reader advances to the next channel, and the node waits for replacement data that is not actually required by the protocol.
I would rate this as a medium-severity issue. It is a concrete consensus/derivation correctness failure in in-scope code, but I am not claiming direct funds risk or a demonstrated network-wide outage.
Observed on Current Public Code
This issue is present in the public base/base repository on main as of commit dd3b5eb575be368280a5cd4e14be57b78c30712e dated April 26, 2026.
Proof of Concept
Fjord Brotli activation mismatch poc
Overview
This PoC demonstrates that the node accepts a Brotli channel once the decoded batch timestamp itself has crossed the Fjord boundary, but rejects the same class of channel when the L1 derivation context is already post-Fjord and the decoded batch timestamp is still pre-Fjord.
That is the condition that proves the activation check is using the wrong clock.
Test Code
Insert the following into crates/consensus/derive/src/stages/channel/channel_reader.rs under the existing test module.
The second test is the proof of impact: the current implementation drops a Brotli channel even though the derivation pipeline is already operating in a post-Fjord L1 context.