Skip to content

refactor(testing): type proof_setting as an IntEnum and fix its derivation - #907

Merged
tcoratger merged 1 commit into
leanEthereum:mainfrom
tcoratger:refactor/proof-setting-int-enum
Jun 10, 2026
Merged

refactor(testing): type proof_setting as an IntEnum and fix its derivation#907
tcoratger merged 1 commit into
leanEthereum:mainfrom
tcoratger:refactor/proof-setting-int-enum

Conversation

@tcoratger

Copy link
Copy Markdown
Collaborator

Motivation

The emitted proof_setting field was a bare int with three magic values, documented only by a re-explaining inline comment block at the single place it was assigned:

# - 0 mocked,
# - 1 real and must verify,
# - 2 real and must fail verification.
if mock_prover:
    proof_setting = 0
elif test_spec.expected_rejection is not None:
    proof_setting = 2
else:
    proof_setting = 1

Two problems:

  1. Stringly/numerically typed — the meaning lives in a comment, not the type.
  2. Derivation bugproof_setting was set to 2 ("real proof must fail verification") for any vector carrying an expected rejection, even when the rejection is non-crypto (e.g. an unknown parent, a slot mismatch) and the proof is perfectly valid. A client that verifies such a proof (and it passes) then rejects for the real reason is behaving correctly, yet contradicts proof_setting=2.

What this does

Self-documenting IntEnum. Each member carries its own meaning:

class ProofSetting(IntEnum):
    MOCKED = 0           # the proof is mocked and must not be verified
    REAL_AND_VALID = 1   # the proof is real and must verify
    REAL_AND_INVALID = 2 # the proof is real and must fail verification

The fixture field is retyped to ProofSetting. Because it is an IntEnum, it serializes to the same integer (0/1/2) — emitted vectors are byte-identical — and ProofSetting.MOCKED == 0 still holds for any consumer comparing against integers.

Fixed derivation. REAL_AND_INVALID is now reserved for rejections whose direct cause is the proof failing verification:

PROOF_FAILURE_REJECTION_REASONS = frozenset(
    {RejectionReason.INVALID_SIGNATURE, RejectionReason.INVALID_BLOCK_PROOF}
)

Every other rejection keeps its valid proof and maps to REAL_AND_VALID.

The default mocked lane is unaffected (every vector is MOCKED), so generated vectors do not churn; only the real-crypto authoritative set is corrected for non-crypto negative vectors.

Testing

  • just check passes (lint, format, ty, codespell, mdformat).
  • Verified the field serializes to a plain int (0/1/2) for every member, and ProofSetting.MOCKED == 0.
  • Verified the reason mapping: UNKNOWN_PARENT_BLOCK is not a proof failure; INVALID_SIGNATURE/INVALID_BLOCK_PROOF are.
  • Mocked fill smoke on a rejection test runs clean and emits proofSetting: 0.

🤖 Generated with Claude Code

…ation

proof_setting was a bare int (0 mocked / 1 real-verify / 2 real-fail) whose
meaning lived only in a re-explaining inline comment block at the one place
it was assigned.

Introduce a self-documenting ProofSetting IntEnum, where each member carries
its own meaning, and retype the fixture field to it.
The enum serializes to the same integer, so emitted vectors are unchanged.

Fix the derivation bug: proof_setting was set to 2 (real proof must fail
verification) for any vector carrying an expected rejection, even when the
rejection was non-crypto (for example an unknown parent) and the proof was
perfectly valid.
Only a rejection whose direct cause is the proof failing verification
(INVALID_SIGNATURE or INVALID_BLOCK_PROOF) now maps to REAL_AND_INVALID;
every other rejection keeps its valid proof and maps to REAL_AND_VALID.

The default mocked lane is unaffected (every vector is MOCKED), so generated
vectors do not churn; only the real-crypto authoritative set is corrected.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@tcoratger
tcoratger merged commit feb4869 into leanEthereum:main Jun 10, 2026
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