Skip to content

Add BlockHeader library for parsing and verifying RLP-encoded block headers#6395

Open
Amxx wants to merge 9 commits intoOpenZeppelin:masterfrom
Amxx:feature/blockheaders
Open

Add BlockHeader library for parsing and verifying RLP-encoded block headers#6395
Amxx wants to merge 9 commits intoOpenZeppelin:masterfrom
Amxx:feature/blockheaders

Conversation

@Amxx
Copy link
Collaborator

@Amxx Amxx commented Mar 5, 2026

Fixes #5803

PR Checklist

  • Tests
  • Documentation
  • Changeset entry (run npx changeset add)

@Amxx Amxx added this to the 5.7 milestone Mar 5, 2026
@Amxx Amxx requested a review from a team as a code owner March 5, 2026 10:58
@Amxx Amxx added the idea label Mar 5, 2026
@changeset-bot
Copy link

changeset-bot bot commented Mar 5, 2026

🦋 Changeset detected

Latest commit: 52fea03

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
openzeppelin-solidity Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 5, 2026

Walkthrough

This pull request introduces a new BlockHeader library for parsing and verifying RLP-encoded Ethereum block headers. The library includes enums for supported hardfork versions and header fields, an error definition, a verification function, and multiple getter functions to extract individual header fields. It also includes helper functions to parse RLP-encoded header data. The changes are accompanied by a corresponding test suite and documentation updates.

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately and concisely summarizes the main change: adding a BlockHeader library for RLP-encoded block header parsing and verification.
Description check ✅ Passed The PR description references issue #5803 and indicates completion of documentation, tests, and changeset entry requirements via checklist.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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

Copy link
Contributor

@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: 2

🧹 Nitpick comments (1)
contracts/utils/BlockHeader.sol (1)

182-188: Consider a parse-once API to avoid repeated full RLP decodes.

Each getter re-runs _parseHeader, so multi-field consumers pay repeated decode/allocation cost. A parse-once overload would reduce cost for real integrations.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@contracts/utils/BlockHeader.sol` around lines 182 - 188, The current getters
repeatedly call _parseHeader (which calls RLP.decodeList) causing repeated full
RLP decodes and allocations; add a parse-once API by creating a new function
(e.g., parseHeader or parseHeaderCached) that calls RLP.decodeList once and
returns Memory.Slice[] memory, then add overloaded variants of the existing
getters (or internal helpers) that accept Memory.Slice[] memory fields so
callers can decode once and reuse the slices; update callers to call
parseHeader(...) once and then call the new getters that take the pre-parsed
Memory.Slice[] to avoid repeated RLP.decodeList work.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@contracts/utils/BlockHeader.sol`:
- Around line 143-145: The nonce bytes are taken from readBytes32() which places
the 8-byte nonce in the low (right-most) 64 bits, but bytes8(bytes32) extracts
the high bytes so non-zero nonces are lost; in getNonce(bytes memory headerRLP)
call _parseHeader(...)[uint8(HeaderField.Nonce)].readBytes32(), cast that result
to uint64 first (e.g. uint64(...)) and then to bytes8 so you extract the low 8
bytes correctly (or use an existing readUint64 helper if present), and add a
unit test that decodes a header with a non-zero nonce (e.g. 0x0102030405060708)
to verify the fix.

In `@test/utils/BlockHeader.test.js`:
- Around line 46-69: The test suite misses coverage for $verifyBlockHeader and
the Amsterdam boundary ($getBlockAccessListHash) on non-Amsterdam headers; add
unit tests in BlockHeader.test.js that (1) call
this.mock.$verifyBlockHeader(headerRLP) with a valid headerRLP (and an invalid
one) to assert success and expected failure behavior, and (2) create a
non-Amsterdam headerRLP (no accessList/baseTxType fields) and assert
this.mock.$getBlockAccessListHash(headerRLP) returns the expected
empty/undefined/default value, plus a separate test for an Amsterdam header that
does return the access list hash. Reference the existing headerRLP variable and
block fixtures used in the file when composing these tests.

---

Nitpick comments:
In `@contracts/utils/BlockHeader.sol`:
- Around line 182-188: The current getters repeatedly call _parseHeader (which
calls RLP.decodeList) causing repeated full RLP decodes and allocations; add a
parse-once API by creating a new function (e.g., parseHeader or
parseHeaderCached) that calls RLP.decodeList once and returns Memory.Slice[]
memory, then add overloaded variants of the existing getters (or internal
helpers) that accept Memory.Slice[] memory fields so callers can decode once and
reuse the slices; update callers to call parseHeader(...) once and then call the
new getters that take the pre-parsed Memory.Slice[] to avoid repeated
RLP.decodeList work.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: b3009e47-0b41-430d-81f8-ba56f8560974

📥 Commits

Reviewing files that changed from the base of the PR and between 3daafbf and 8b96c25.

📒 Files selected for processing (4)
  • contracts/mocks/Stateless.sol
  • contracts/utils/BlockHeader.sol
  • contracts/utils/README.adoc
  • test/utils/BlockHeader.test.js

@Amxx Amxx force-pushed the feature/blockheaders branch from ba51e79 to 0a37a29 Compare March 5, 2026 13:06
@OpenZeppelin OpenZeppelin deleted a comment from coderabbitai bot Mar 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Support RLP-encoded block header validation against blockHash

1 participant