Skip to content

add timeout-without-lockin and variant detection examples (#108, #109) - #116

Merged
neverDefined merged 1 commit into
mainfrom
feat/phase-6-timeout-example
Apr 27, 2026
Merged

add timeout-without-lockin and variant detection examples (#108, #109)#116
neverDefined merged 1 commit into
mainfrom
feat/phase-6-timeout-example

Conversation

@neverDefined

Copy link
Copy Markdown
Owner

Summary

Closes Phase 6.1. Two final worked examples plus a small validation hardening of time.go that surfaced during development.

TestExampleTimeoutWithoutLockin (closes #108)

Narrated mirror of TestExampleActivateTestdummy for the BIP9 FAILED path. Uses WarpTime to drag MTP past a configured timeout, then mines to the second retarget boundary where Bitcoin Core evaluates STARTED → FAILED.

Two non-obvious recipe details surfaced and are documented inline:

  • Signaling-vs-timeout precedence. Core's BIP9 checks the signaling threshold before the timeout check, and regtest's default block-version policy signals every STARTED deployment automatically. Without intervention, testdummy would LOCKED_IN before timeout could fire. The test passes -blockversion=0x20000000 (BIP9 baseline with no deployment bits set) via ExtraArgs to suppress signaling so the FAILED path is reachable.
  • uint32 block-timestamp cap. Block headers store nTime as uint32, max 4_294_967_295 (year 2106). Setting mocktime above this cap causes generatetoaddress to fail with a cryptic time-too-old error (the value overflows). The test uses timeout = 4_000_000_000 (year 2096) — comfortably under the cap.

Skips on Inquisition, where testdummy is a heretical deployment that isn't -vbparams-overridable.

TestVariantDetection (closes #109)

Smoke test that Variant() resolves to VariantCore or VariantInquisition (not the zero-value VariantUnknown — that would indicate a getnetworkinfo.subversion parser regression). Logs the detected variant and binary path so CI output records which build the suite ran against.

time.go — uint32 cap validation

Surfaced by the timeout test work. Added maxBlockTime constant (4_294_967_295) and validation:

  • MineWithTimestampContext rejects unix > maxBlockTime up front with a clear message.
  • WarpTimeContext rejects target > maxBlockTime up front.

Both methods' godoc updated. Existing SetMockTime keeps the looser maxMockTime = 9_223_372_036 cap (matches Core's RPC validation) since you can call setmocktime for non-mining purposes.

Test plan

  • make ai-check green (against bitcoind-inquisition on PATH).
  • TestVariantDetection passes on Inquisition (logs running against variant: inquisition).
  • TestExampleTimeoutWithoutLockin t.Skips cleanly on Inquisition.
  • On Core (verified via temporary BinaryPath-override probe): TestExampleTimeoutWithoutLockin runs to completion with final status: failed. Probe was deleted before commit.

Notes

🤖 Generated with Claude Code

Phase 6.E.3 + 6.E.4: closes Phase 6.1 milestone with the final two
worked examples.

examples_test.go — TestExampleTimeoutWithoutLockin
The narrated mirror of TestExampleActivateTestdummy for the FAILED path.
Configures testdummy with a far-future timeout (year 2096), uses the
new WarpTime to drag MTP past it, mines to the second retarget boundary
where Core's BIP9 evaluates STARTED → FAILED.

Two non-obvious recipe details surfaced during development:
- Bitcoin Core's BIP9 evaluates the signaling threshold BEFORE the
  timeout check, so on regtest where every block signals by default,
  the deployment LOCKED_IN before timeout could fire. Adding
  -blockversion=0x20000000 to ExtraArgs suppresses signaling so the
  failure path is reachable.
- Block timestamps are uint32 — values above 4_294_967_295 (year 2106)
  overflow when bitcoind constructs the block, surfacing as a cryptic
  "time-too-old" error from generatetoaddress. Bumped time.go to
  validate against this limit (new maxBlockTime constant) so callers
  see an actionable error up front.

Skips on Inquisition, where testdummy is a "heretical" deployment that
isn't BIP9-overridable via -vbparams.

examples_inquisition_test.go — TestVariantDetection
Smoke test that Variant() resolves to Core or Inquisition (not the
zero-value VariantUnknown — that means subversion parsing regressed).
Logs the detected variant and the binary path so CI output records
which build the suite ran against.

time.go — uint32 cap validation
- new maxBlockTime constant (4_294_967_295)
- MineWithTimestamp rejects unix > maxBlockTime up front
- WarpTime rejects target > maxBlockTime up front
Documented in both methods' godoc.

Closes #108, #109. Closes Phase 6.1 milestone.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@neverDefined
neverDefined merged commit 1d95947 into main Apr 27, 2026
4 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.

[Phase 6.E.4] TestVariantDetection smoke test [Phase 6.E.3] TestExampleTimeoutWithoutLockin via WarpTime

1 participant