ci: ship both zebra-state and zaino backends in one image + deb#538
Merged
Conversation
added 2 commits
July 1, 2026 17:59
Zallet's chain-data backend is a compile-time, mutually-exclusive Cargo
feature: `zebra-state` (default; reads a co-located zebrad's state directly,
needs the `indexer` feature + shared state dir, no regtest) or `zaino` (talks
to Zebra over JSON-RPC in separate containers, supports regtest). The published
alpha.4 image only had the default zebra-state backend, so it can't run in the
z3 stack (`zallet start` -> "the zebra-state backend requires an
[indexer.read_state_service] config section").
Build BOTH binaries and ship them together, additively (the existing `zallet`
command is unchanged):
- `zallet` -> zebra-state (default, unchanged name/entrypoint/docs)
- `zallet-zaino` -> zaino backend (new, additive)
One Docker image and one Debian package now carry both binaries; consumers pick
the backend by which binary they run (z3 sets its command to `zallet-zaino`).
Standalone GitHub Release binaries gain a `-zaino` variant.
- Dockerfile.stagex: two `cargo install` passes (--no-default-features
--features {zebra-state,zaino},rpc-cli,zcashd-import); the zaino build is
installed to a separate --root and renamed to zallet-zaino. Runtime ships
both; ENTRYPOINT stays `zallet`.
- flake.nix (arm64/Nix): parametrized `mkZallet`; exposes packages.zallet
(default) + packages.zallet-zaino. Only the default carries the
completions/manpages share tree (same CLI surface).
- build-arm64-nix.yml: builds both flake packages, stages both binaries into
the shared runtime artifact.
- binaries-and-deb-release.yml: seeds both binaries for cargo-deb; signs/SBOMs
both standalone binaries; one attestation covers both.
- zallet/Cargo.toml: cargo-deb assets add target/release/zallet-zaino.
- docs: installation guide explains the two backends / binaries.
The default (`zallet` / zebra-state) is byte-for-byte the prior default;
--no-default-features --features zebra-state,... is just the explicit form of
the previous implicit default. Only the additive zaino binary is new.
Ship a third invocable name so the default (zebra-state) backend is nameable both ways: `zallet` (unchanged) and `zallet-zebra-state` (symlink -> zallet, same binary). `zallet-zaino` stays the real second binary. Applied in the Docker runtime, the .deb (cargo-deb preserves the symlink asset), and the arm64 Nix staging. Docs updated to note zallet/zallet-zebra-state need a zebrad built with the `indexer` feature, and that users without it should run zallet-zaino.
3 tasks
pacu
approved these changes
Jul 1, 2026
…docs Incorporate pacu's PR #534 ("Choosing a chain backend") so both doc efforts tell one coherent story on the same files, and this PR supersedes #534: - installation/README.md: adopt the "Choosing a chain backend" heading + #534's comparison table (adds the Linux-only vs cross-platform distinction), the source-build `cargo install --no-default-features --features zaino` commands, and the mutual-exclusivity compile-error warning. Extend it with the pre-compiled-artifact split (zallet / zallet-zebra-state / zallet-zaino in the image + deb; the -zaino standalone binary). - setup.md: add #534's cross-reference from the chain-state section to the new installation content. Closes #533 (same issue #534 targeted).
nuttycom
approved these changes
Jul 2, 2026
nuttycom
left a comment
Contributor
There was a problem hiding this comment.
utACK; please expedite, Binance is requesting this.
2 tasks
2 tasks
y4ssi
pushed a commit
to y4ssi/wallet-ci-test
that referenced
this pull request
Jul 8, 2026
PR zcash#538 added the additive zallet-zaino binary to both runtime export paths (Dockerfile.stagex export stage + build-arm64-nix.yml), but the "Stage exported binaries" step in binaries-and-deb-release.yml only copied zallet from the artifact root, never zallet-zaino. Two later steps in the same job already assumed it was there: - "Prepare standalone binary artifact": cp build/${PLATFORM_KEY}/zallet-zaino - "Seed cargo target tree" (.deb staging): install ... zallet-zaino Both failed with "No such file or directory" the first time the dual-backend pipeline ran end-to-end (re-release of v0.1.0-alpha.4, zcash/zallet run 28603304440, job "Build and deploy Zallet linux-arm64 binaries and packages"). Add the missing install + a matching sanity check, mirroring the existing zallet check.
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.
Problem
Zallet's chain-data backend is a compile-time, mutually-exclusive Cargo feature:
zebra-state(default) — reads a co-locatedzebrad's state directly viaReadStateService; requires azebradbuilt with the non-defaultindexerfeature + a shared state dir; no regtest.zaino(--no-default-features --features zaino) — talks to Zebra over JSON-RPC in separate containers; supports regtest.The published
v0.1.0-alpha.4image ships only the defaultzebra-statebackend, so it can't run in split-container stacks like z3:zallet startfails withthe zebra-state backend requires an [indexer.read_state_service] config section. Because the backend is fixed at Zallet compile time, bumping Zebra/Zaino doesn't help — a zaino-backend image has to be published. This blocks z3#49.What this does
Build both backends and ship them together, additively — the existing
zalletcommand is unchanged. Three invocable names:zebradbuilt withindexer?zalletzebra-state(default)zallet-zebra-statezalletzebra-statezallet-zainozainozalletis the default and is byte-for-byte the previous default build.zallet-zebra-stateis just an explicit alias (a symlink to the same binary).zallet-zainois the only new binary.Resulting artifacts
zodlinc/zallet:<tag>/usr/local/bin/zallet+zallet-zebra-state(symlink);ENTRYPOINT=zallet/usr/local/bin/zallet-zainozallet(single package)/usr/bin/zallet+/usr/bin/zallet-zebra-state(symlink)/usr/bin/zallet-zainozallet-<version>-linux-<arch>zallet-<version>-linux-<arch>-zainoOne image and one
.debcarry both backends; you pick by which binary you run. (Standalone binaries stay single-binary by nature, so the zaino one is a separate-zainofile.zallet-zebra-stateis a symlink only in the image + deb, where a filesystem exists.)Changes
Dockerfile.stagex— twocargo installpasses (--no-default-features --features {zebra-state,zaino},rpc-cli,zcashd-import); zaino installs to a separate--rootand is renamedzallet-zaino; azallet-zebra-state -> zalletsymlink is created. Runtime ships all three names;ENTRYPOINTstayszallet.flake.nix(arm64/Nix) — parametrizedmkZallet; exposespackages.zallet(default) +packages.zallet-zaino. Only the default carries the completions/manpages share tree (identical CLI surface).build-arm64-nix.yml— builds both flake packages; stages both binaries + thezallet-zebra-statesymlink into the shared runtime artifact.binaries-and-deb-release.yml— seeds both binaries + the symlink forcargo-deb; signs + SBOMs both standalone binaries; one attestation covers both.zallet/Cargo.toml— cargo-deb assets addzallet-zainoand thezallet-zebra-statesymlink (cargo-deb ^2.10 preserves symlink assets).indexerrequirement, and when to pickzallet-zaino.Notes
zallet/ zebra-state) is byte-for-byte the prior default:--no-default-features --features zebra-state,...is just the explicit form of the previous implicitdefault = ["zebra-state"].release.ymlneeds no change.ci.yml), so the feature strings are proven.After merge
Dispatch a re-release with full SLSA (no re-tag):
gh workflow run release.yml -f tag=v0.1.0-alpha.4. Then z3 re-pointsZ3_ZALLET_IMAGE→zodlinc/zallet:v0.1.0-alpha.4and runszallet-zaino, unblocking z3#49.Docs: supersedes #534
#534 (@pacu, "document zaino backend selection") was closed unmerged in favor of this PR. Since both touched the same doc files (
book/src/guide/installation/README.md+setup.md), its content is carried here: the "Choosing a chain backend" section with the comparison table (including the Linux-only vs cross-platform distinction), thecargo install --no-default-features --features zainobuild commands, and the mutual-exclusivity compile-error warning. This PR extends that with the pre-built-artifact story — thezallet/zallet-zebra-state/zallet-zainobinaries shipped in the Docker image + Debian package. Also closes #533.