fix: solo prev-hash BLOCKER + S1-S4 doc fixes + release-please#9
Merged
Merged
Conversation
`_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>
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
Post-v0.7.0 follow-up addressing the consolidated final review:
solo.py:_template_to_jobproduced aprev_stratum_hexwhose
swap_wordsround-trip cancelled into a no-op, leaving display BE inthe hashing-time header. Submit-time
_assemble_headerindependently doesBE→LE, so against a real
bitcoindsolo mode the miner would have silentlyproduced invalid blocks. Masked by
FAKE_TEMPLATE.previousblockhash = "0"*64(symmetric fixed-point under any byte permutation).
positional, CHANGELOG link footer, README missing
--log-file.for automated releases, mirroring the setup we run in Aegis-Protocol.
code concerns and 11 docs nice-to-haves are tracked in
ROADMAP.mdunder «Запланировано на 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 timethis work landed, both PR #7 and PR #8 were already squash-merged into
main, so cherry-picking back into the historical branches has nopractical effect. Bundling everything in one fresh branch keeps
git blamehonest and avoids ghost-branch maintenance.What's in the four commits
3ea1847fix(solo): prev-hash byte-order BLOCKER B1 — internal LE in header25c0ae4docs: address final-review S1-S4 should-fix items35948f9ci: add release-please workflow for automated releasesdbc7108docs(roadmap): defer M-1..M-4, test-gaps, nice-to-haves to v0.7.x/v0.8.0B1 fix details
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.yml—googleapis/release-please-action@v5with
release-type: python. Token resolutionRELEASE_PLEASE_TOKEN || GITHUB_TOKEN— fine-grained PAT preferred so the release-PR triggersdownstream 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.xfeat:→ minor andfix:→patch),
extra-fileslistssrc/hope_hash/__init__.pyfor the__version__bump..release-please-manifest.json— pins current version at0.7.0.pyproject.tomlswitched fromdynamic = ["version"]to a staticversion = "0.7.0"field; both that field and__version__carry an# x-release-please-versioncomment marker so release-please updatesthem deterministically.
Action required after merge: create a fine-grained PAT (
contents:write+pull-requests:writeon this repo) and store it as repo secretRELEASE_PLEASE_TOKEN. Without it the first release-PR is created withGITHUB_TOKENand won't trigger CI — close+reopen will work as a one-timeworkaround.
Test plan
py -3.11 -m unittest discover -s tests— 244 passing (was 242, +2 sentinels for B1).pip install -e .after pyproject change — version 0.7.0 readable from bothpip show hope-hashandfrom hope_hash import __version__.00000000000000000002a7c4c1e48d76c5a37902165a270156b7a8d72728a054) — no fixed-point masking.fix(solo):commit alone should proposev0.7.1).--solo --rpc-url ... --rpc-cookie ...against a regtest bitcoind node.References
[Unreleased]summary🤖 Generated with Claude Code