Skip to content

refactor(varint): parametrize the canonical LEB128 codec with max_bytes#798

Merged
tcoratger merged 1 commit into
leanEthereum:mainfrom
tcoratger:refactor/varint-parametrize-max-bytes
May 29, 2026
Merged

refactor(varint): parametrize the canonical LEB128 codec with max_bytes#798
tcoratger merged 1 commit into
leanEthereum:mainfrom
tcoratger:refactor/varint-parametrize-max-bytes

Conversation

@tcoratger
Copy link
Copy Markdown
Collaborator

Summary

The networking and snappy modules each carried a self-contained LEB128 implementation. The two algorithms were identical, differing only in the byte cap (10 vs 5). One implementation was a slow drift away from the other waiting to happen.

This PR keeps the networking varint as the single source of truth and gives both encode and decode a max_bytes parameter (default 10 = uint64 cap). Snappy now imports the canonical codec and passes 5 via a new SNAPPY_VARINT_MAX_BYTES constant.

Changes

src/lean_spec/node/networking/varint.py — the canonical home:

  • encode_varint(value, max_bytes=10) and decode_varint(data, offset=0, max_bytes=10) both take an explicit cap.
  • Encode now also enforces the cap (rejects values that don't fit in max_bytes * 7 bits) — symmetric with decode.
  • The "too long" error message formats the actual cap.

src/lean_spec/node/snappy/ — caller migration:

  • encoding.py: 159-line encode_varint32/decode_varint32 deleted; module now contains only tag-encoding logic.
  • compress.py: imports encode_varint from networking and passes max_bytes=SNAPPY_VARINT_MAX_BYTES.
  • decompress.py: imports decode_varint and catches VarintError (the old ValueError path is gone).
  • constants.py: stale VARINT_CONTINUATION_BIT / VARINT_DATA_MASK removed; replaced by SNAPPY_VARINT_MAX_BYTES = 5.

Tests

  • tests/lean_spec/node/networking/test_varint.py: new TestMaxBytesParameter class covers the 5-byte cap boundary — success at the largest value that fits, error at one bit over, truncation, and oversize input.
  • tests/lean_spec/node/snappy/test_snappy.py: TestVarintEncoding renamed to TestSnappyLengthPrefix. Tests now exercise the canonical codec through the snappy cap, plus an integration test that asserts an oversize prefix surfaces as SnappyDecompressionError.
  • tests/lean_spec/node/networking/test_reqresp.py: the error-message match updated to the new formatted message.

Test plan

  • just check — ruff, format, ty, codespell, mdformat pass
  • uv run pytest tests/lean_spec/node/{networking/test_varint,networking/test_reqresp,snappy/test_snappy,snappy/test_framing}.py — 229 tests pass
  • CI green on this PR

Net change: +126/−201 across 8 files. No backward-compatibility shims, no re-exports.

🤖 Generated with Claude Code

The networking and snappy modules each carried a self-contained LEB128
implementation. The two algorithms were identical, differing only in
byte cap (10 vs 5). One implementation was a slow drift away from the
other waiting to happen.

Keep the networking varint as the single source of truth and give both
encode and decode a max_bytes parameter (default 10 = uint64 cap).
Snappy now imports the canonical codec and passes 5 via a new
SNAPPY_VARINT_MAX_BYTES constant.

Encode now also enforces the cap, so per-cap semantics are symmetric.
The snappy length-prefix tests run against the canonical codec, plus
an integration test that asserts an oversize prefix surfaces as a
SnappyDecompressionError.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@tcoratger tcoratger merged commit 9d6af5b into leanEthereum:main May 29, 2026
12 of 13 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.

1 participant