Skip to content

fix: solo prev-hash BLOCKER + S1-S4 doc fixes + release-please#9

Merged
devAsmodeus merged 4 commits into
mainfrom
fix/post-v0.7.0-blocker-and-release-please
May 3, 2026
Merged

fix: solo prev-hash BLOCKER + S1-S4 doc fixes + release-please#9
devAsmodeus merged 4 commits into
mainfrom
fix/post-v0.7.0-blocker-and-release-please

Conversation

@devAsmodeus
Copy link
Copy Markdown
Owner

Summary

Post-v0.7.0 follow-up addressing the consolidated final review:

  • 1 BLOCKER (B1)solo.py:_template_to_job produced a prev_stratum_hex
    whose swap_words round-trip cancelled into a no-op, leaving display BE in
    the hashing-time header. Submit-time _assemble_header independently does
    BE→LE, so against a real bitcoind solo mode the miner would have silently
    produced invalid blocks. Masked by FAKE_TEMPLATE.previousblockhash = "0"*64
    (symmetric fixed-point under any byte permutation).
  • 4 SHOULD-FIX (S1–S4) — docker-compose port comment, docker run example
    positional, CHANGELOG link footer, README missing --log-file.
  • CI — adopted release-please
    for automated releases, mirroring the setup we run in Aegis-Protocol.
  • Planning — M-1..M-4 (security MEDIUMs), 6 test-gaps, 6 non-blocking
    code concerns and 11 docs nice-to-haves are tracked in ROADMAP.md
    under «Запланировано на v0.7.x / v0.8.0».

Why one PR (not the original 3-PR stack split)

The original recommended order was B1→PR#7, S1-S4→PR#8. By the time
this work landed, both PR #7 and PR #8 were already squash-merged into
main, so cherry-picking back into the historical branches has no
practical effect. Bundling everything in one fresh branch keeps git blame honest and avoids ghost-branch maintenance.

What's in the four commits

Commit Scope
3ea1847 fix(solo): prev-hash byte-order BLOCKER B1 — internal LE in header
25c0ae4 docs: address final-review S1-S4 should-fix items
35948f9 ci: add release-please workflow for automated releases
dbc7108 docs(roadmap): defer M-1..M-4, test-gaps, nice-to-haves to v0.7.x/v0.8.0

B1 fix details

- prev_be = bytes.fromhex(tmpl["previousblockhash"])
- prev_stratum_hex = b"".join(prev_be[i:i+4][::-1] for i in range(0, 32, 4)).hex()
+ prev_be = bytes.fromhex(tmpl["previousblockhash"])
+ prev_internal_le = prev_be[::-1]
+ prev_stratum_hex = b"".join(prev_internal_le[i:i+4][::-1] for i in range(0, 32, 4)).hex()

After the fix, swap_words(prev_stratum_hex) == prev_be[::-1] (internal LE),
which is what the block header actually needs.

release-please setup

  • .github/workflows/release-please.ymlgoogleapis/release-please-action@v5
    with release-type: python. Token resolution RELEASE_PLEASE_TOKEN || GITHUB_TOKEN — fine-grained PAT preferred so the release-PR triggers
    downstream CI; falls back to GITHUB_TOKEN with a manual close+reopen
    workaround if the secret is absent.
  • release-please-config.json — single-package monorepo at root,
    bump-minor-pre-major: true (so on v0.x feat: → minor and fix:
    patch), extra-files lists src/hope_hash/__init__.py for the
    __version__ bump.
  • .release-please-manifest.json — pins current version at 0.7.0.
  • pyproject.toml switched from dynamic = ["version"] to a static
    version = "0.7.0" field; both that field and __version__ carry an
    # x-release-please-version comment marker so release-please updates
    them deterministically.

Action required after merge: create a fine-grained PAT (contents:write +
pull-requests:write on this repo) and store it as repo secret
RELEASE_PLEASE_TOKEN. Without it the first release-PR is created with
GITHUB_TOKEN and won't trigger CI — close+reopen will work as a one-time
workaround.

Test plan

  • py -3.11 -m unittest discover -s tests244 passing (was 242, +2 sentinels for B1).
  • pip install -e . after pyproject change — version 0.7.0 readable from both pip show hope-hash and from hope_hash import __version__.
  • New regression sentinels use a real non-symmetric mainnet prev-hash (block #800000, 00000000000000000002a7c4c1e48d76c5a37902165a270156b7a8d72728a054) — no fixed-point masking.
  • After merge: confirm release-please opens a release-PR for the next conventional commit (the fix(solo): commit alone should propose v0.7.1).
  • After merge: optional manual smoke test of --solo --rpc-url ... --rpc-cookie ... against a regtest bitcoind node.

References

🤖 Generated with Claude Code

devAsmodeus and others added 4 commits May 4, 2026 00:04
`_template_to_job` собирал prevhash в Stratum-style как `BE_chunked_per_4`,
что после `swap_words` в `_build_header_base` сокращалось в no-op и
оставляло display BE на месте prev_hash. Submit-time `_assemble_header`
независимо делает BE→LE, поэтому hashing-time и submit-time заголовки
расходились — на реальном bitcoind solo-mode тихо подписывал бы
невалидные блоки.

Фикс: считаем `prev_internal_le = prev_be[::-1]`, затем per-4-byte
reverse, чтобы `swap_words(prev_stratum_hex) == prev_internal_le`.

Маскировал баг тестовый `FAKE_TEMPLATE.previousblockhash = "0"*64` —
симметричный фикспоинт под любой байт-перестановкой. Добавлены два
sentinel-теста с реальным mainnet prev-hash (block #800000):
`test_template_to_job_prevhash_internal_le_after_swap_words` и
`test_build_header_base_uses_internal_le_prevhash`.

Tests: 242 → 244.

Refs: docs/handoff/final-review.md B1.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- S1: docker-compose.yml header — :8001 is the web dashboard,
  :8000 hosts /metrics + /healthz (was misnamed, sent first-run users
  to the Prometheus exposition page).
- S2: docs/deploy.{en,ru}.md §6 docker run example — replace literal
  `docker` positional with `mybox`; the arg is `worker_name` for the
  pool, not a subcommand. Added inline comment.
- S3: CHANGELOG.md link footer — restore compare-links for v0.3.0
  through v0.7.0 and re-anchor [Unreleased] against v0.7.0 (was stuck
  at v0.2.0 since the 0.3.0 release).
- S4: README.md advanced flags table (EN + RU halves) — add
  `--log-file PATH`, which lives in cli.py and is used in the TUI
  workflow but was missing from the table.

Refs: docs/handoff/final-review.md S1-S4.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Mirrors the setup used in Aegis-Protocol: conventional-commit pushes to
main now open an automated release-PR with aggregated CHANGELOG, version
bumps and a GitHub release + tag once merged.

- .github/workflows/release-please.yml — googleapis/release-please-action@v5
  with release-type: python. Token resolution: RELEASE_PLEASE_TOKEN
  (fine-grained PAT, contents:write + pull-requests:write) preferred to
  trigger downstream CI on the release-PR; falls back to GITHUB_TOKEN
  (release-PR will need manual close+reopen to pick up CI).
- release-please-config.json — single-package monorepo setup at root,
  bump-minor-pre-major: true so v0.x stays semver-pre-1.0 friendly,
  extra-files lists src/hope_hash/__init__.py for the __version__ bump.
- .release-please-manifest.json — pins current version "0.7.0" so
  release-please knows where to start.
- pyproject.toml — switch from `dynamic = ["version"]` (hatch-style) to
  static `version = "0.7.0"` so release-please can do an in-place bump.
  The legacy [tool.hatch.version] block is removed; hatch reads the
  static field. `__version__` in __init__.py stays the runtime SoT.
- Both version strings carry a `# x-release-please-version` comment
  marker so release-please updates them deterministically.

Refs: ROADMAP.md «Запланировано на v0.7.x / v0.8.0».

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Final-review left 4 MEDIUM security findings, 6 test-gaps and 11 docs
nice-to-haves once B1 + S1-S4 land. They're not blockers for this
PR-stack merge, but they need a home so they don't drift.

- ROADMAP.md gets a new «Запланировано на v0.7.x / v0.8.0» section with
  every leftover item from final-review, grouped by category and tied
  back to file:line references where applicable.
- docs/handoff/final-review.md gets a 2026-05-03 status banner noting
  B1 and S1-S4 are now closed, tests are 244, and pointing to ROADMAP
  for the rest.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@devAsmodeus devAsmodeus merged commit aeac6d7 into main May 3, 2026
10 checks passed
@devAsmodeus devAsmodeus deleted the fix/post-v0.7.0-blocker-and-release-please branch May 3, 2026 21:07
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