Put the deposit inside the gap it is meant to prove - #30
Merged
Merged
Conversation
The first real run reported a failure that was not one, which is the failure mode a proof script can least afford. A follower treats its own tip as already applied. The script set that tip to `max(created_index - 1, 0)`, so when the coin turned out to be in the *first* block of the window -- which is what the chain handed us on the first try -- the clamp put the follower's tip on the deposit's own block. The deposit was therefore never inside the induced gap, never applied, and the spend that followed matched nothing. Output: two FAILs that looked exactly like a broken reconciler and were nothing of the kind. It now starts on the block before the window when the coin is in the first one, and says so if that block cannot be read. The same run exposed a check that passed for the wrong reason. "The coin left the record when spent" asserted an empty outpoint set, which is also what you get when nothing was ever added -- so it printed PASS on the one run where the deposit was never seen. It is now conditioned on the deposit having been seen. Worth recording what the run did prove, because it is the part no fixture can: 34,247 real mainnet transactions parsed with zero malformed, and catch-up refetched exactly the missed blocks and landed on the tip. The machinery worked; it was handed a gap with nothing in it. Refs #24 Co-Authored-By: Claude Opus 5 <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.
The first real run of
tools/induced_gap_proof.pyreported a failure that was not one — the failure mode a proof script can least afford, since it points the finger at the code it is supposed to be checking.What happened
A follower treats its own tip as already applied. The script chose that tip with
max(created_index - 1, 0), so when the coin turned out to be in the first block of the window — which is what the chain handed us on the very first try — the clamp put the tip on the deposit's own block.The deposit was therefore never inside the induced gap, never applied, and the spend that followed matched nothing. Two FAILs that look exactly like a broken reconciler and are nothing of the kind.
It now starts on the block before the window in that case, and reports clearly if that block cannot be read.
A check that passed for the wrong reason
The same run exposed this:
…on a run where the coin was never in the record at all. An empty outpoint set is also what you get when nothing was ever added, so the check was vacuous precisely when it mattered most. It is now conditioned on the deposit having been seen.
What the run did prove
Worth recording, because this is the half no fixture can reach:
The repair machinery worked. It was handed a gap with nothing in it.
Regression test
test_a_coin_in_the_first_block_of_the_window_is_still_inside_the_gapbuilds exactly that shape and requires a pass. It fails against the old clamp.One test was written and then deleted rather than kept: an attempt to assert the vacuous-pass case through
run()turned out to be unreachable, because the script only proceeds when it has found a deposit and spend inside the window. The conditioned check stays as defence in depth, with the reasoning in a comment where the condition is; a test asserting an unreachable state is noise that later readers have to disprove.Checks
194 tests, ruff clean. Issue #24 stays open until a run passes end to end.
Refs #24
🤖 Generated with Claude Code