Source bitcoin-node from the bitcoind-gunix flake instead of hand-pinned downloads #4

Closed
opened 2026-07-17 15:18:11 +01:00 by vnprc-agent · 0 comments
Collaborator

User story: As the operator maintaining the hashpool template-provider stack, I want the Bitcoin Core node binary to come from a single verified flake input instead of a hand-pinned tarball download duplicated across three files — so that bumping the node version is one nix flake update with build-time byte-parity verification, not a manual sha256 recompute in three places that can silently ship a stale or mismatched binary.

Context

The template provider runs multiprocess Bitcoin Core (bitcoin -m node) with sv2-tp connected over a unix IPC socket. The node binary is packaged by hand and pinned in three independent places, each carrying its own version string:

Pin site What it pins How it sources the binary
bitcoin-node.nix version + per-platform sha256 fetchurl the bitcoincore.org tarball + autoPatchelfHook
scripts/build.sh BITCOIN_VERSION curl the tarball on the VPS, cache in /tmp
scripts/ship.sh BITCOIN_VERSION curl the tarball locally, cache in /tmp

The .nix file feeds dev (devenv + .#bitcoin-node); the two scripts feed production (testnet4). They are not derived from each other — a version bump must be applied to all three by hand, and the deploy scripts reuse a cached /tmp binary even when the version string changes. Issue #2's plan review surfaced this duplication as a correctness hazard: a half-applied bump ships a mismatched node/tp pair (a hard Init.makeMining outage).

bitcoind-gunix builds the official Bitcoin Core GUIX release and gates the build on byte-for-byte sha256 parity — a successful nix build is the verification. Consumed as a flake input, it makes the flake lock the single source of truth for the node version and replaces all three hand-maintained pins.

Scope (the ask)

Replace the hand-pinned node packaging with a bitcoind-gunix flake input:

  • Add bitcoind-gunix as a flake input and expose the multiprocess node binary (bin/bitcoin + libexec/bitcoin-node) from it, in place of bitcoin-node.nix.
  • Retire the BITCOIN_VERSION pin + curl//tmp download in scripts/build.sh and scripts/ship.sh, sourcing the flake-built binary instead (built from the store, or whatever deploy path the spike settles).
  • Delete bitcoin-node.nix once nothing imports it.

This is version-neutral: it changes how the node is sourced, not which version runs.

Spike first (exploratory — resolve before the implementation shape is fixed)

Three unknowns gate the design. Run a spike and record the answers before writing the dev plan:

# Question Why it matters
1 Does gunix expose libexec/bitcoin-node (the multiprocess layout), or only bitcoind? If only bitcoind, the default (swap the input) fails — fall back to consuming its tarball output or adding a package.
2 Version parity: gunix currently builds v31.0; issue #2 targets 31.1. Either bump gunix to 31.1 or land this after gunix catches up. Do not regress the node version below what #2 shipped.
3 Does the production deploy move to nix build + copy-from-store, or keep a download? This is the real surface area — the deploy scripts currently avoid requiring nix on the binary path.

Default path if the spike is clean: swap bitcoin-node.nix → gunix input, deploy from the store. Alternatives (extract from gunix's tarball, add a package, or defer) are follow-ups only if the default fails.

Boundaries (out of scope)

  • sv2-tp packaging stays as-is (sv2-tp.nix). gunix covers only the Bitcoin node; stratum-mining/sv2-tp is a separate upstream with no gunix equivalent.
  • The version upgrade itself (sv2-tp 1.0.6→1.1.1 + Core 30.2→31.1) is issue #2, on the existing mechanism. This issue is the packaging swap that follows — not a re-do of the bump.
  • The Allod bitcoin-node service VM (notes/allod/bitcoin-node-vm.md) is a different machine and repo; it already plans gunix for a Tor-only wallet node. Shared dependency, separate deliverable.
  • No secrets, no new host, no wallet/RPC exposure changes.

Validation

  • nix build .#bitcoin-node (or the gunix-derived attr) yields bin/bitcoin + bin/bitcoin-cli + libexec/bitcoin-node, and gunix's sha256 gate passes.
  • devenv up brings up the node + sv2-tp over IPC with no Init.makeMining / interfaces.cpp errors (the same regtest smoke test as issue #2).
  • git grep BITCOIN_VERSION plus a scan for any remaining node version pin returns only intended results — the three-way duplication is gone.
  • Production deploy path verified on regtest before the human-gated testnet4 step.

Sequencing

Follows issue #2 (which ships 31.1 on the existing mechanism, reviewed and near-converged). Refs #2. The dev plan will live at notes/hashpool/dev-plans/<slug>.md per the plan-review process; this is its tracking issue.

**User story:** As the operator maintaining the hashpool template-provider stack, I want the Bitcoin Core node binary to come from a single verified flake input instead of a hand-pinned tarball download duplicated across three files — so that bumping the node version is one `nix flake update` with build-time byte-parity verification, not a manual sha256 recompute in three places that can silently ship a stale or mismatched binary. ## Context The template provider runs multiprocess Bitcoin Core (`bitcoin -m node`) with `sv2-tp` connected over a unix IPC socket. The node binary is packaged by hand and pinned in **three independent places**, each carrying its own version string: | Pin site | What it pins | How it sources the binary | |---|---|---| | `bitcoin-node.nix` | `version` + per-platform sha256 | `fetchurl` the bitcoincore.org tarball + `autoPatchelfHook` | | `scripts/build.sh` | `BITCOIN_VERSION` | `curl` the tarball on the VPS, cache in `/tmp` | | `scripts/ship.sh` | `BITCOIN_VERSION` | `curl` the tarball locally, cache in `/tmp` | The `.nix` file feeds dev (`devenv` + `.#bitcoin-node`); the two scripts feed production (testnet4). They are not derived from each other — a version bump must be applied to all three by hand, and the deploy scripts reuse a cached `/tmp` binary even when the version string changes. Issue #2's plan review surfaced this duplication as a correctness hazard: a half-applied bump ships a mismatched node/tp pair (a hard `Init.makeMining` outage). [`bitcoind-gunix`](https://github.com/0xB10C/bitcoind-gunix) builds the official Bitcoin Core GUIX release and gates the build on byte-for-byte sha256 parity — a successful `nix build` **is** the verification. Consumed as a flake input, it makes the flake lock the single source of truth for the node version and replaces all three hand-maintained pins. ## Scope (the ask) Replace the hand-pinned node packaging with a `bitcoind-gunix` flake input: - Add `bitcoind-gunix` as a flake input and expose the multiprocess node binary (`bin/bitcoin` + `libexec/bitcoin-node`) from it, in place of `bitcoin-node.nix`. - Retire the `BITCOIN_VERSION` pin + `curl`/`/tmp` download in `scripts/build.sh` and `scripts/ship.sh`, sourcing the flake-built binary instead (built from the store, or whatever deploy path the spike settles). - Delete `bitcoin-node.nix` once nothing imports it. This is **version-neutral**: it changes *how* the node is sourced, not *which* version runs. ## Spike first (exploratory — resolve before the implementation shape is fixed) Three unknowns gate the design. Run a spike and record the answers before writing the dev plan: | # | Question | Why it matters | |---|---|---| | 1 | Does gunix expose `libexec/bitcoin-node` (the multiprocess layout), or only `bitcoind`? | If only `bitcoind`, the default (swap the input) fails — fall back to consuming its `tarball` output or adding a package. | | 2 | Version parity: gunix currently builds **v31.0**; issue #2 targets **31.1**. | Either bump gunix to 31.1 or land this after gunix catches up. Do not regress the node version below what #2 shipped. | | 3 | Does the production deploy move to `nix build` + copy-from-store, or keep a download? | This is the real surface area — the deploy scripts currently avoid requiring nix on the binary path. | Default path if the spike is clean: swap `bitcoin-node.nix` → gunix input, deploy from the store. Alternatives (extract from gunix's `tarball`, add a package, or defer) are follow-ups only if the default fails. ## Boundaries (out of scope) - **`sv2-tp` packaging** stays as-is (`sv2-tp.nix`). gunix covers only the Bitcoin node; `stratum-mining/sv2-tp` is a separate upstream with no gunix equivalent. - **The version upgrade itself** (sv2-tp 1.0.6→1.1.1 + Core 30.2→31.1) is issue #2, on the existing mechanism. This issue is the packaging swap that follows — not a re-do of the bump. - **The Allod `bitcoin-node` service VM** (`notes/allod/bitcoin-node-vm.md`) is a different machine and repo; it already plans gunix for a Tor-only wallet node. Shared dependency, separate deliverable. - No secrets, no new host, no wallet/RPC exposure changes. ## Validation - `nix build .#bitcoin-node` (or the gunix-derived attr) yields `bin/bitcoin` + `bin/bitcoin-cli` + `libexec/bitcoin-node`, and gunix's sha256 gate passes. - `devenv up` brings up the node + `sv2-tp` over IPC with no `Init.makeMining` / `interfaces.cpp` errors (the same regtest smoke test as issue #2). - `git grep BITCOIN_VERSION` plus a scan for any remaining node version pin returns only intended results — the three-way duplication is gone. - Production deploy path verified on regtest before the human-gated testnet4 step. ## Sequencing Follows issue #2 (which ships 31.1 on the existing mechanism, reviewed and near-converged). Refs #2. The dev plan will live at `notes/hashpool/dev-plans/<slug>.md` per the plan-review process; this is its tracking issue.
vnprc closed this issue 2026-07-17 22:50:31 +01:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
vnprc/hashpool#4
No description provided.