# PR #20407 — Review Fixes

## Overview

Address review feedback on erigontech/erigon#20407 (`commitment: nibbles
consolidation`). Three items, all mechanical:

1. Restore the `TestRLPEncodeDecodeWithAccountsAndStorage` regression test
   that was inadvertently dropped when `execution/commitment/trie/encoding_test.go`
   was deleted during nibble consolidation. The test has nothing to do
   with hex/compact encoding — it was just co-located in the same file.
   Append it to the existing `execution/commitment/trie/trie_test.go`.
2. Add direct table-driven tests for `nibbles.CommonPrefixLen` and
   `nibbles.HasTerm` in `execution/commitment/nibbles/nibbles_test.go`.
   Both are currently only exercised indirectly via callers.
3. Update the doc block for `witnessKeyNibblesToBytes` /
   `witnessKeyBytesToNibbles` in `execution/commitment/trie/witness_marshalling.go`
   to note the legacy `len(input) < 2` corner case where the function
   returns the input as-is and no header byte is produced — so the
   documented bit layout does not apply.

## Context

Files involved:

- `execution/commitment/trie/trie_test.go` — 707 lines. Already imports
  `bytes`, `testing`, `testify/require`, `erigon/common`,
  `erigon/common/crypto`, `erigon/execution/types/accounts`. Has
  `newEmpty()` helper at line 49 and `TestDeepHash` at line 253
  using the same `DeepHash` API. Missing only the `holiman/uint256`
  import (which the restored test requires).
- `execution/commitment/nibbles/nibbles.go` — `HasTerm` at line 92,
  `CommonPrefixLen` at line 97. `Terminator = 0x10` exported constant
  at line 27.
- `execution/commitment/nibbles/nibbles_test.go` — existing tests at
  lines 28 (`TestHexToCompact`), 52 (`TestKeybytesHex`), 82
  (`TestHexCompactRoundtrip`). Plus a fuzz target and benchmarks.
  Add new tests alongside these.
- `execution/commitment/trie/witness_marshalling.go` — doc block at
  lines 164–177; `witnessKeyNibblesToBytes` function at 178–209 with
  the `len(nibbles) < 2` short-circuit at 179–184.

Reference for Task 1 — the deleted test lives at git rev
`cfd9bcb9ac^:execution/commitment/trie/encoding_test.go` lines 88–214
(the deletion commit was `cfd9bcb9ac`). To retrieve verbatim:

```
git show cfd9bcb9ac^:execution/commitment/trie/encoding_test.go
```

The test function is `TestRLPEncodeDecodeWithAccountsAndStorage`. It
uses only the following symbols, all of which still exist in the
current `trie` package: `newEmpty`, `EmptyRoot`, `Trie.UpdateAccount`,
`Trie.Update`, `Trie.DeepHash`, `Trie.Hash`, `Trie.RLPEncode`,
`RLPDecode`, `Trie.GetAccount`. Verified by grep.

## Development Approach

- Regular (code first, then run the added/restored tests directly).
- One task per commit. Each task must build and its directly affected
  tests must pass before commit.
- Per-task validation: targeted `go build` and `go test -run <name>`
  on the affected package. No full `make erigon integration` at the
  per-task level.
- A final verification task runs `make lint` (loop until clean per
  the non-deterministic lint guidance in the repo CLAUDE.md) and
  short-mode tests on the affected packages.
- Commit-message prefix style per repo CLAUDE.md: `package(s): description`.

## Implementation Steps

### Task 1: Restore TestRLPEncodeDecodeWithAccountsAndStorage into trie_test.go

**Files:**
- Modify: `execution/commitment/trie/trie_test.go`

Rationale: This test is a regression in PR #20407 — it was co-located
in `trie/encoding_test.go` with the hex/compact tests that legitimately
moved to the new `nibbles` package. It validates a wholly unrelated
path: `Trie.RLPEncode` / `RLPDecode` roundtrip for a unified trie
containing accounts and storage subtries. Bring it back verbatim to
`trie_test.go`.

- [x] Retrieve the deleted test verbatim from git: run `git show cfd9bcb9ac^:execution/commitment/trie/encoding_test.go` and extract lines 88–214 (the function `TestRLPEncodeDecodeWithAccountsAndStorage`, closing brace included). Do NOT copy any surrounding imports or the other deleted tests (`TestHexCompact`, `TestHexKeybytes`) — those moved to the `nibbles` package correctly.
- [x] Append the test function at the end of `execution/commitment/trie/trie_test.go`, after the last existing function. Preserve exact function body, including comments and variable names.
- [x] Add `"github.com/holiman/uint256"` to the import block in `trie_test.go`. All other symbols the test uses (`common.Address`, `common.HexToAddress`, `common.HexToHash`, `crypto.Keccak256Hash`, `crypto.Keccak256`, `accounts.Account`, `accounts.EmptyCodeHash`, `accounts.InternCodeHash`, `require.*`, `newEmpty`, `EmptyRoot`) are already available via existing imports or the same package.
- [x] Build: `go build ./execution/commitment/trie/...`
- [x] Test: `go test -run TestRLPEncodeDecodeWithAccountsAndStorage -count=1 ./execution/commitment/trie/...` — must pass.
- [x] Commit: `commitment/trie: restore TestRLPEncodeDecodeWithAccountsAndStorage`

### Task 2: Add direct unit tests for nibbles.CommonPrefixLen and nibbles.HasTerm

**Files:**
- Modify: `execution/commitment/nibbles/nibbles_test.go`

Rationale: Both helpers are currently only exercised indirectly
through callers. A few table-driven cases make the package self-contained
and catch edge-case regressions early. Keep the tests small and
focused — no fuzz targets, no benchmarks (those aren't needed for
these trivial helpers).

- [x] Add a `TestCommonPrefixLen` table-driven test in `nibbles_test.go`. Cover at minimum: both empty slices (expect 0); a empty + b non-empty (0); equal slices (full length); no common prefix (0); partial prefix; a is prefix of b (len(a)); b is prefix of a (len(b)); single-byte equal / differing cases. Use `require.Equal` for assertions.
- [x] Add a `TestHasTerm` table-driven test in `nibbles_test.go`. Cover: empty slice (false); slice ending in `nibbles.Terminator` / `0x10` (true); slice ending in a non-terminator byte like `0x0f` or `0x00` (false); single-element `{Terminator}` (true); single-element non-terminator (false).
- [x] Both tests should go after the existing `TestHexCompactRoundtrip` (around line ~120 depending on exact position) and before any fuzz target / benchmark block if present. Match the code style of the existing tests in the same file.
- [x] Build: `go build ./execution/commitment/nibbles/...`
- [x] Test: `go test -run 'TestCommonPrefixLen|TestHasTerm' -count=1 ./execution/commitment/nibbles/...` — both must pass.
- [x] Commit: `commitment/nibbles: add direct tests for CommonPrefixLen and HasTerm`

### Task 3: Document the len < 2 legacy corner case in witness key helpers

**Files:**
- Modify: `execution/commitment/trie/witness_marshalling.go`

Rationale: Copilot correctly noticed that the doc block at lines
164–177 describes "Bit layout of the first byte" as if a header byte
is always present, but the implementation at lines 179–184 returns
the input as-is when `len(nibbles) < 2`. Add a sentence noting this
legacy corner case so readers don't assume the bit layout always
applies.

- [x] In the doc block immediately above `witnessKeyNibblesToBytes` (currently lines 164–177), insert a sentence/paragraph just before the "Bit layout of the first byte:" line stating that inputs of length `< 2` are returned as-is for legacy compatibility, and that in that case there is no header byte, so the bit layout below does not apply. Preserve the rest of the block (the "DO NOT fix" warning and the pointer to `nibbles.HexToCompact` / `nibbles.CompactToHex`).
- [x] Do NOT change the function body or the wire format. This is documentation only.
- [x] Do NOT duplicate the doc block on `witnessKeyBytesToNibbles` — the existing code only documents the `NibblesToBytes` direction with this block; leave `BytesToNibbles` as it is.
- [x] Build: `go build ./execution/commitment/trie/...`
- [x] Test (sanity): `go test -run TestWitness -count=1 ./execution/commitment/trie/...` — ensures no accidental behavior change.
- [x] Commit: `commitment/trie: document witness key len<2 legacy corner case`

### Task 4: Final verification

- [x] `go build ./...`
- [x] `make lint` — run up to 3 times (non-deterministic per repo CLAUDE.md). Fix any reported errors; re-run until clean.
- [x] `go test -short -count=1 ./execution/commitment/... ./execution/commitment/nibbles/... ./execution/commitment/trie/...` — broad sanity run on affected packages in short mode.
- [x] Move this plan to `docs/plans/completed/` and commit: `docs: mark PR 20407 review-fixes plan as completed`.
