Add BlockHeader library for parsing and verifying RLP-encoded block headers#6395
Add BlockHeader library for parsing and verifying RLP-encoded block headers#6395Amxx wants to merge 9 commits intoOpenZeppelin:masterfrom
Conversation
🦋 Changeset detectedLatest commit: 52fea03 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
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 |
WalkthroughThis 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)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
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
📒 Files selected for processing (4)
contracts/mocks/Stateless.solcontracts/utils/BlockHeader.solcontracts/utils/README.adoctest/utils/BlockHeader.test.js
ba51e79 to
0a37a29
Compare
Fixes #5803
PR Checklist
npx changeset add)