refactor(xmss): hoist 0x-hex JSON serialization into a shared mixin#824
Merged
Merged
Conversation
Introduce HexSerializedContainer holding the single model_serializer that emits a 0x-prefixed hex SSZ payload in JSON mode. PublicKey, SecretKey, and Signature now inherit it. This removes the hand-rolled per-field serializer on KeyPair and the duplicate serializer on Signature. The container base already decodes such hex strings on the way in, so roundtrips are unchanged. Key halves now serialize as 0x-prefixed hex (previously plain hex). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Simplifies XMSS container JSON serialization by hoisting the repeated
0x-prefixed hex serializer into a single shared mixin.HexSerializedContainer, aContainersubclass holding the lone@model_serializer(mode="plain", when_used="json")that emits"0x" + encode_bytes().hex().PublicKey,SecretKey, andSignaturenow inherit it.field_serializeronKeyPairand the duplicate serializer that previously lived onSignature.The base container already decodes such hex strings on the way in (its existing wrap-validator accepts hex with or without a
0xprefix), so encode/decode roundtrips are unchanged.Why a mixin and not the base
Containermode="plain"replaces a model's entire JSON representation. Putting it on the baseContainerwould force all 21 subclasses (Block,State,Checkpoint,Attestation, ...) to collapse from structured objects into opaque hex blobs, breaking the human-readable fixture format and the state-transition / fork-choice fixtures. Hex is only the right shape for the opaque cryptographic blobs, so it stays opt-in.Behavior change
Key halves (
public_key/secret_key) now serialize as0x-prefixed hex; previouslyKeyPairemitted plain hex. Plain hex is still accepted on input.Generated SSZ test vectors for
PublicKeynow emit a0xhex string for theirvaluefield instead of a nested{root, parameter}object — consistent with howSignaturealready behaved. Regenerate fixtures withuv run filland review that diff.Testing
uv run pytest tests/lean_spec/spec/crypto/xmss/→ 196 passedjust check→ passes (lint, format, ty, codespell, mdformat, lock)🤖 Generated with Claude Code