feat: bitcoind-backend preset for split-deployment hosts#3
Merged
Conversation
`public-frigate` configured bitcoind + fulcrum + ZMQ + optional mesh exposure inline. Once a backend-only preset becomes necessary (a host that runs the same stack for a remote `frigate-edge` consumer, with no frigate of its own — see following commit), both presets need the same wiring. Move it to a private `_internal/bitcoin-stack.nix` helper, mirroring the pattern already used for `frigate-tls-acme`. The helper takes options under `services._roost.bitcoin-stack` (an internal namespace, marked `internal = true` throughout), and parent presets wire them from their own typed options. No behavior change for existing consumers — `public-frigate`'s external surface is identical (same options, same defaults, same runtime config). Verified by `regtest-preset`, which exercises the full preset and continues to pass against the refactored module. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
`bitcoind-backend` is the sibling preset to `public-frigate`: bitcoind
+ fulcrum + ZMQ sequence publisher, exposed on a private interface,
with no frigate process on this box. Pairs with `frigate-edge` on
remote consumer hosts. Useful when the latency-sensitive consumer is
in a different DC from the existing public-frigate host (the
loopback cost is loopback; the remote-backend cost is per-call RTT)
and the consumer host can't afford the ~950 GB storage that
bitcoind+fulcrum needs.
Shares the bitcoind+fulcrum+expose logic with `public-frigate` via
the `_internal/bitcoin-stack.nix` helper from the preceding commit;
this preset is mostly an options surface and a small `mkIf` that
wires the helper.
Also adds:
- `nixosModules.bitcoind-backend-host` — a batteries-included
bundle (nix-bitcoin + the preset), so consumers needing only
`roost` in their flake inputs can deploy a backend host.
- `test/regtest-backend.nix` — single-VM nixosTest that boots
`bitcoind-backend`, mines 101 regtest blocks, and verifies the
backend ports listen on the configured mesh address, the
configured rpcauth user can authenticate, and a wrong password
is rejected.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Ruff F541 fired in CI because the curl invocation in regtest-backend
was f-stringed but the only interpolations were Nix `${...}`, which
are resolved at Nix eval time. By the time Python sees the lines,
there are no `{}` placeholders left — drop the `f` prefix, and
collapse `{{ }}` back to `{ }` in the JSON bodies (those were only
escaped to survive f-string syntax).
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
A
bitcoind-backendpreset: same bitcoind + fulcrum + ZMQ stackpublic-frigateconfigures, exposed on a private interface, but with no frigate process. Pairs withfrigate-edgeon a separate consumer host. Lets you put the backend services close to the consumer when they need to live in different DCs (e.g. avoid ~25ms inter-DC RTT for the latency-sensitive RPC path) without making the consumer carry the ~950 GB of bitcoind+txindex+fulcrum storage.Two logical commits:
refactor: extract bitcoind + fulcrum into a shared internal helper— moves the inline bitcoind/fulcrum/ZMQ/exposeBackends logic out ofpublic-frigate.nixinto a new_internal/bitcoin-stack.nix, mirroring the pattern already used forfrigate-tls-acme. No behavior change;regtest-presetcontinues to pass against the refactored module.feat: add bitcoind-backend preset for split-deployment backend host— the new preset itself. Reusesbitcoin-stack. Adds:nixosModules.bitcoind-backend— the preset alone (consumer brings nix-bitcoin)nixosModules.bitcoind-backend-host— batteries-included (nix-bitcoin + preset)test/regtest-backend.nix— single-VM nixosTest validating bindings, auth, and 401 on bad passwordOn bitcoin-implementation flexibility
The preset's external contract is "Bitcoin Core RPC + ZMQ sequence on a private interface." The current implementation uses nix-bitcoin's
services.bitcoind. To swap to a Core fork like Knots: just setservices.bitcoind.packagein the consumer's host config — no preset change. For a non-Core implementation that speaks the same RPC + ZMQ contract (e.g. btcd), a sibling preset (btcd-backend?) would provide the same exposed interface via different internals;frigate-edgedoesn't know the difference.Test plan
regtest-e2e,regtest-preset,regtest-edge,regtest-backend,wireguard-mesh)regtest-backendtest exercises the preset's full surface: bindings, rpcauth round-trip, wrong-password rejection.🤖 Generated with Claude Code