Skip to content

Commit 665deed

Browse files
arya2claudeconradoplg
authored
feat(zebrad): add zcashd-compat mode with a supervised zcashd wallet sidecar (#10952)
* feat(network): always gossip blocks to configured zcashd-compat sidecar peers Adds block_gossip_peer_ips plumbing so inbound peers from configured IPs: - always receive AdvertiseBlock inventory broadcasts, - get one reserved inbound connection slot, - bypass the recent-IP reconnection throttle, - are exempt from the find-response stall detector. Adds init_with_block_gossip_peer_ips to keep the existing init API stable. Ported from Zakura (zakura-core/zakura) commits ad1a89b341 and 4036e47114. * feat(zebrad): add zcashd-compat mode with supervised zcashd sidecar Adds a [zcashd_compat] config section and --zcashd-compat start flag. When enabled, Zebra pins block gossip to the sidecar's inbound peer IPs and optionally spawns and supervises a hard-locked zcashd wallet sidecar: - config: enabled/manage_zcashd/zcashd_source/zcashd_path/datadir/extra args - preflight: Linux hardware and disk checks with --unsafe-low-specs override - datadir: bootstrap zcashd datadir and a minimal zcash.conf on first start - managed: SHA256-pinned sidecar download from the embedded release manifest - supervisor: spawn zcashd pinned to Zebra's P2P listener, restart with capped backoff, and SIGTERM with a grace period on shutdown Ported from Zakura (zakura-core/zakura), adapted to Zebra's start command and config conventions. * feat(zcashd-compat): add installer, make targets, sync-check, and Docker compat image - scripts/install-zebra.sh: interactive installer with split-binary, supervised, Docker, and build-from-source zcashd-compat modes; downloads SHA256-pinned zebrad release and valargroup/zcashd sidecar binaries with no build dependencies required - make/zcashd-compat.mk + root Makefile: start/status/sync targets - deploy/zcashd-compat/sync-check.sh: peer-pinning and height-drift checks - docker: runtime-zcashd-compat image stage and ZCASHD_COMPAT_ENABLED entrypoint opt-in Ported from Zakura (zakura-core/zakura), adapted to Zebra release artifact naming, zfnd Docker images, and Zebra's config keys. * docs(zcashd-compat): add zcashd-compat book chapter and changelog entry * test(zcashd-compat): add regtest integration test suite for the zcashd sidecar Ports Zakura's zcashd-compat integration harness and 26 tests covering startup, chain agreement, wallet RPCs, transparent tx flow, supervisor resilience, and reorg handling (depths 1-80, restart cycles, churn soak). Tests are #[ignore]d and gated on TEST_ZCASHD_COMPAT=1 with a zcashd binary from TEST_ZCASHD_PATH or the embedded manifest. Run with: cargo nextest run --profile zcashd-compat-integration --run-ignored=only * fix(zcashd-compat): reject zebrad binaries without zcashd-compat support in the installer The installer downloaded the pinned zebrad release for zcashd-compat profiles, but no Zebra release includes zcashd-compat mode yet, so the printed start commands failed at startup with 'unknown field zcashd_compat'. Check 'zebrad start --help' for the --zcashd-compat flag after resolving the binary, and fail with guidance to build from a zcashd-compat branch and re-run with --zebrad-path --no-download. * fix(network): queue block gossip for busy sidecars and canonicalize ban checks - A configured zcashd-compat sidecar that is busy with another request when a block is advertised no longer misses the advert: the latest advert is queued per sidecar and delivered as soon as the peer is ready again, driven by a detached task so the connection does not cancel it. - Inbound ban checks now also match the canonical IP, so an IPv4-mapped IPv6 connection cannot dodge an IPv4 ban and then claim the zcashd-compat reserved slot and its privileges. - Documents the new init variant in the zebra-network changelog. * fix(zcashd-compat): terminate the sidecar on signal shutdown, re-verify cached binaries, and skip unknown-datadir disk checks - On SIGINT/SIGTERM the runtime drops the start future without running the supervisor's shutdown path, orphaning the supervised zcashd. Track the child pid and terminate it synchronously after runtime shutdown (SIGTERM, grace period, SIGKILL last resort, reaping via waitpid). - The managed zcashd cache now records and re-verifies the extracted binary's own SHA256 on every reuse, so a modified or corrupted cached executable is re-downloaded instead of executed. - Preflight no longer requires disk capacity for a zcashd datadir it invented: in externally managed mode without an explicit zcashd_datadir, the sidecar's disk usage is unknown to Zebra and is not checked. - Renames supervisor metrics to the dot-separated zcashd.compat.supervisor.* convention, documents block_gossip_peer_ips as a trusted-peer privilege boundary, and fixes the manifest consumer docs. * test(zcashd-compat): fix harness leaks and timeouts, add graceful-shutdown coverage and a scheduled CI workflow - Construct the test setup before the readiness waits so its Drop guard kills the supervised zcashd when setup fails, instead of leaking it. - Treat empty TEST_ZCASHD_COOKIE_FILE/RPC_USER env values as unset (the Make targets export them unconditionally). - Add per-request timeouts to the zcashd RPC test client so polling limits are actually enforced. - Rename zebrad_clean_shutdown to zebrad_abrupt_kill (it SIGKILLs zebrad), and add zebrad_graceful_shutdown_stops_zcashd, which SIGTERMs zebrad and asserts the supervised zcashd also exits. - Correct the suite README: opt-in CI status, real test names and assertions, and the actual entry-point file. - Add a manual + weekly-scheduled zcashd-compat regtest workflow that runs the suite against the manifest-pinned sidecar build. * fix(zcashd-compat): make supervised targets enable supervision, bound sync-check RPC calls, and clarify docs - The compat-zebrad-start-supervised targets now set MANAGE_ZCASHD=true; they previously started zebrad in externally managed mode. - sync-check.sh curl calls get connect/total timeouts so a stalled RPC cannot defeat the check deadline. - The installer explains that zcashd-compat Docker images are not published yet and points at make compat-docker-build. - The book marks the embedded third-party sidecar download as experimental pending a provenance decision, and fixes a garbled sentence. * fix(zcashd-compat): deep-review fixes for slot lockout, shutdown paths, and tooling checks Correctness: - Sidecar-listed IPs now reserve one slot per configured IP and fall back to the public pool when reserved slots are taken, so an unrelated local process or a fast sidecar reconnect can no longer lock the real sidecar out. - The abandoned-zcashd cleanup now also runs on error exits (moved into RuntimeRun::run, since APPLICATION.shutdown never returns), only forgets the child pid once its exit is confirmed, and checks waitpid before signalling so a recycled pid is never SIGTERMed. - The queued sidecar block advert now skips peers banned while it was queued, matching broadcast_all_queued. - p2p_connect_addr substitutes the loopback of the listener's own IP family, so an IPv6-only listener no longer sends the sidecar to 127.0.0.1. - Preflight runs in spawn_blocking, and checks the cached sidecar's provenance marker instead of re-hashing the whole binary a second time at startup. - Child log sanitizing also routes non-ASCII bytes to the slow path, so C1 controls like single-byte CSI cannot reach the terminal. - Archive/binary digest comparisons are ASCII-case-insensitive; pid casts use i32::try_from instead of . - Bare 'make' prints help instead of downloading the sidecar archive; the compat status pgrep checks no longer match their own shell wrapper; the make drift check fails on missing heights instead of passing on empty vars; the installer requires a numeric port in --zebra-p2p-addr. - Test teardown kills the sidecar before the fallible zebrad asserts, so an early return cannot leak it. Cleanups from the same review: sidecar identity checks unified on the O(1) tracked key set (route_p2c, gossip selection), hex::encode for digests, struct-update syntax in the test builder, and cfg-gated dead_code allows. * fix(zcashd-compat): sweep-review fixes for arg precedence, installer commands, and download policy - Duplicate -datadir=/-conf= values in zcashd_extra_args now resolve to the LAST occurrence, matching zcashd's own single-valued option semantics, so bootstrap/preflight prepare the datadir zcashd actually uses. - Warn at startup when zcashd_compat.p2p_connect_addr is non-loopback but block_gossip_peer_ips is the loopback default: in cross-container topologies the sidecar's source IP is not loopback and it would silently lose every sidecar privilege. The book example now shows a real non-loopback source IP. - The installer's docker-supervised command uses the compat image's ZCASHD_COMPAT_ENABLED entrypoint opt-in again (it printed a command that failed at startup with 'zcashd_source=path requires zcashd_path'), and keeps the sidecar wallet RPC on loopback instead of exposing it on every host interface under --network host. - The default-profile native and build-from-source commands now pass the selected network instead of silently starting Mainnet. - The managed download's redirect policy enforces HTTPS on every hop, as its security contract documents, not just on the final URL. - Docs: config and zebra-network changelog describe the real reserved-slot pool (one slot per listed IP, public-pool fallback with normal limits). * feat(rpc): add regtest generatetoaddress and a zcashd wallet-conformance harness Adds a regtest-only generatetoaddress RPC that mines blocks paying the coinbase to a caller-specified address (reusing the generate path via a per-call miner-params override on a cloned block-template handler, leaving the configured mining.miner_address untouched). Adds zebrad/tests/zcashd-wallet-conformance/, a Python harness that runs zcashd wallet/RPC tests against a Zebra + zcashd-sidecar pairing: N sidecars fan into one Zebra, which is the miner and relay, and node[i].generate() mines coinbase to node i's own wallet via generatetoaddress. Includes a single-node and a faithful multi-node wallet port, plus run_upstream.py, an adapter that runs unmodified upstream tests by monkeypatching the framework's node-lifecycle and topology primitives. The Zebra half is validated live (generate and generatetoaddress mine to the correct address on regtest); end-to-end runs against the third-party sidecar binary are documented as pending a capable environment. * chore(zcashd-compat): pull the sidecar zcashd from ZcashFoundation/zcashd Points the embedded manifest, installer, and docs at the new ZcashFoundation/zcashd zebra-compat-v1.0.0 release (forked from valargroup/zcashd) instead of valargroup directly. The runtime binary is the same SHA256-pinned artifact. Also fixes the wallet-conformance harness sidecar config: bind RPC to loopback explicitly (the default all-interfaces bind fails in restricted sandboxes) and drop the allowdeprecated args that this zcashd version rejects. * fix(network): always answer getheaders with a headers message A `FindHeaders` request that resolves to no new headers was mapped to `Response::Nil`, which sends nothing back to the peer. The `getheaders` protocol requires a `headers` response, so leaving it unanswered keeps the peer's `getheaders` request pending forever. A zcashd sidecar following Zebra defers every later inv-triggered `getheaders` behind that stuck request and never syncs. Always reply with a `headers` message, even when it is empty. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(state): fix Regtest difficulty and block time for zcashd sidecar sync Two Regtest mining behaviours prevented a zcashd sidecar from following a Zebra Regtest chain over P2P: - Zebra retargeted difficulty on Regtest, while zcashd uses a fixed minimum difficulty with no retargeting (`fPowNoRetargeting`). The sidecar rejected Zebra's headers as "bad-diffbits". Pin every Regtest block to the powLimit in `expected_difficulty_threshold`, which both the block template and validation use, so mining and validation stay consistent. - Block time was `now()` clamped to `[median-time-past + 1, median-time-past + 90 min]`. A fresh Regtest chain starts from the 2011-era genesis, so real time is always far ahead and every block pinned to `max_time`, racing chain time ~90 min per block and outrunning the sidecar's acceptable block-time window. Advance Regtest block time minimally instead, matching zcashd's regtest behaviour and keeping mined timestamps tightly clustered. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * test(zcashd-compat): make the wallet conformance harness pass end-to-end Get the single-node zcashd wallet RPC conformance run passing against the real Zebra + zcashd-sidecar pairing: - Give Zebra's RPC client a generous timeout, since mining many Regtest blocks in one `generate` call is slow. - Use `COINBASE_MATURITY + 1` confirmations for spendable-coinbase checks: `z_getbalanceforaccount` is purely confirmation-gated and does not apply coinbase maturity itself, so maturity is expressed as a minconf. - Wait for Zebra (the miner) to accept the wallet tx into its own mempool before mining the confirming block, and drive zcashd's transaction-relay trickle by advancing the sidecar's frozen `mocktime`. With the clock frozen, zcashd's `nNextInvSend` timer never elapses, so it never flushes queued tx invs to Zebra; real-clock nodes are unaffected. Block sync is unaffected because block invs are sent unconditionally. - Poll for balances/confirmations to tolerate wallet-scan lag. - Read an optional `HARNESS_TRACING_FILTER` env var (deliberately not `ZEBRA_`-prefixed, which zebrad treats as config-field overrides). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * test(zcashd-compat): port the multi-node wallet test to the shielded flow This zcashd build disables the legacy transparent `getnewaddress` and does not credit transparent coinbase to a unified-address receiver, so rewrite the multi-node conformance test to use the account / unified-address / shielded z_* RPCs, mirroring the single-node conformance test. Three sidecars fan into one Zebra, each mining its own shielded coinbase, and a shielded z_sendmany transfer propagates node0 -> Zebra -> node2. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * docs(zcashd-compat): document the shielded flow, Regtest fixes, and adapter limits Update the wallet-conformance README and the run_upstream adapter docstring to match the working harness: the shielded-first wallet flow (accounts / unified addresses / z_* RPCs), the Regtest behaviours required for a sidecar to follow Zebra (fixed difficulty, minimal block-time advance, getheaders always answered, mocktime clock-advance to drive tx relay), the validated end-to-end PASS status of both conformance tests, and the real config-matching limits of running unmodified upstream tests. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(ci): satisfy hadolint, shellcheck, and markdownlint - docker/Dockerfile: DL3022 is a false positive on the external `zcashd_compat` named build context (passed via docker build --build-context, which hadolint cannot model); ignore it inline. - scripts/install-zebra.sh: remove literal duplicate alternatives in three case patterns (SC2221/SC2222). - zcashd-wallet-conformance README: dash list bullets and underscore emphasis per the repo markdownlint config (MD004/MD049). * build(docker): bump the pinned curl to the current trixie security release The runtime image pins curl=8.14.1-2+deb13u3, which was superseded in the Debian trixie repository by +deb13u4, so apt-get install fails and every Docker image build errors out. * build(deps): update yanked spin 0.9.8 to 0.9.9 spin 0.9.8 was yanked from crates.io, failing the cargo-deny advisories checks. cargo update -p spin moves the lockfile to the 0.9.9 replacement. * docs(rpc): declare the new required RpcServer method as a breaking change cargo-semver-checks flags RpcServer::generate_to_address as a major break (new trait method without a default). Declare it under an Unreleased 'Breaking Changes' heading in the crate changelog, as the pr-gate workflow requires for PRs with a breaking-change title marker. * fix(ci): satisfy codespell An unpinned codespell in the spell-check job gained new dictionary entries: fix a long-standing 'reclaculated' comment typo and reword 'Implementors' in the new zebra-rpc changelog entry. * build(docker): bump pinned protobuf-compiler to the trixie point release Debian superseded protobuf-compiler=3.21.12-11 with 3.21.12-11+deb13u1, failing apt-get install in the build stage like the earlier curl pin. * ci(lint): pin a known-good nightly for cargo-udeps The 2026-07-13 and 2026-07-14 nightlies ICE while building zebra-chain's tests with -Z binary-dep-depinfo, failing the unused-deps job on every run. Pin nightly-2026-07-12, verified locally against the same build. Unpin once a fixed nightly ships. * test(zcashd-compat): port the Rust wallet and tx-flow tests to the shielded flow The sidecar zcashd build is shielded-first: it rejects -allowdeprecated=getnewaddress at startup (crash-looping the supervisor and failing every test in the suite), disables the legacy transparent getnewaddress, and does not credit transparent coinbase to an account. Drop the fatal startup argument, and port address generation and the two tx-flow tests to the account / unified-address / z_sendmany flow, funding the wallet by mining coinbase to its Sapling receiver via zebrad's regtest-only generatetoaddress — matching the Python conformance harness. All three ported tests pass against a live sidecar. * chore(zcashd-compat): point the installer at the v6.0.0-zcashd-compat.1 preview release The installer previously downloaded zebrad from the v6.0.0 release, whose binaries do not include zcashd-compat support. Pin the preview release tag and its archive checksum so the binary install modes work end-to-end. * feat(zcashd-compat): make the runtime-zcashd-compat image self-contained The stage previously required an externally prepared build context with a zcashd binary. It now downloads and hash-verifies the ZcashFoundation/zcashd zebra-compat sidecar release inside the build (zcashd and zcash-cli), so a plain 'docker build --target runtime-zcashd-compat' produces a complete supervised-sidecar image. The sidecar release ships x86_64 Linux binaries only, so the stage is amd64-only. The baked-in release is overridable via build args, and make compat-docker-build no longer needs a prepare step. * ci(release): publish the zcashd-compat sidecar image from branch releases Point the release Docker build at the runtime-zcashd-compat target so a release from this branch publishes the sidecar-bundled image (revert to 'runtime' before merging to main), and pin the installer's Docker modes to the published image tag. * rpc: add default impl for new generate_to_address to avoid major bump * ci: revert dockerfile_target to 'runtime' * remove unneeded prop.txt file * fix build * update changelog * address low-hanging high-impact copilot findings * cargo fmt * route PushTransaction to zcashd-compat sidecar peers, rename block broadcast helpers to sidecar broadcast * make chowning datadirs more robust * point install script to 6.2.0 --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> Co-authored-by: Conrado Gouvea <conrado@zfnd.org>
1 parent 10f79fa commit 665deed

63 files changed

Lines changed: 13886 additions & 52 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.config/nextest.toml

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,20 @@ slow-timeout = { period = "30m", terminate-after = 2 }
5252

5353
[test-groups]
5454
serial-state = { max-threads = 1 }
55+
# zcashd-compat integration tests each spawn a zebrad + zcashd on
56+
# bind-probed-then-released ports, so they must never run concurrently, even
57+
# under a parallel profile invoked with --run-ignored=all.
58+
serial-zcashd-compat = { max-threads = 1 }
59+
60+
# Force zcashd-compat integration tests serial in every profile, so a parallel
61+
# --run-ignored=all run cannot collide on their released RPC/P2P ports.
62+
[[profile.default.overrides]]
63+
filter = 'test(~integration::zcashd_compat::)'
64+
test-group = 'serial-zcashd-compat'
65+
66+
[[profile.ci.overrides]]
67+
filter = 'test(~integration::zcashd_compat::)'
68+
test-group = 'serial-zcashd-compat'
5569

5670
# Stateful tests share on-disk state, so run them serially. This override sets
5771
# only the test-group: adding slow-timeout here would shadow every per-test
@@ -103,3 +117,29 @@ slow-timeout = { period = "90m", terminate-after = 1 }
103117

104118
[profile.check-no-git-dependencies]
105119
default-filter = 'test(=unit::end_of_support::check_no_git_dependencies)'
120+
121+
# --- zcashd-compat Profiles ---
122+
123+
[profile.zcashd-compat-integration]
124+
# Run zcashd-compat tests one at a time to avoid port conflicts and resource exhaustion.
125+
test-threads = 1
126+
slow-timeout = { period = "15m", terminate-after = 2 }
127+
failure-output = "immediate"
128+
default-filter = 'package(zebrad) and test(~zcashd_compat)'
129+
130+
[profile.zcashd-compat-soak]
131+
# Long-running local soak for the reorg churn stress test.
132+
test-threads = 1
133+
slow-timeout = { period = "4h", terminate-after = 1 }
134+
failure-output = "immediate"
135+
default-filter = 'package(zebrad) and test(=integration::zcashd_compat::zcashd_compat_reorg_churn)'
136+
137+
[profile.zcashd-compat-external]
138+
# External mode: connect to pre-running mainnet/testnet zebrad + zcashd.
139+
# Set TEST_ZCASHD_COMPAT_NETWORK, TEST_ZEBRAD_RPC_ADDR,
140+
# TEST_ZCASHD_RPC_ADDR, and auth env vars before running.
141+
# No block mining — 5 minutes per test is sufficient.
142+
test-threads = 1
143+
slow-timeout = { period = "5m", terminate-after = 2 }
144+
failure-output = "immediate"
145+
default-filter = 'package(zebrad) and test(~zcashd_compat)'
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
name: zcashd-compat Regtest
2+
3+
# Runs the managed zcashd-compat Regtest integration suite.
4+
#
5+
# The test harness spawns a fresh zebrad and zcashd on randomised ports, so no
6+
# external infrastructure is required. The sidecar zcashd binary is the
7+
# SHA256-pinned build from zebrad/zcashd-compat-manifest.json.
8+
#
9+
# Manual and scheduled only for now: the suite is new and not yet required.
10+
# Add a pull_request paths trigger once it has a green track record.
11+
on:
12+
workflow_dispatch:
13+
schedule:
14+
# Weekly, Monday 04:00 UTC.
15+
- cron: "0 4 * * 1"
16+
17+
concurrency:
18+
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
19+
cancel-in-progress: true
20+
21+
permissions:
22+
contents: read
23+
24+
env:
25+
CARGO_TERM_COLOR: always
26+
RUST_BACKTRACE: 1
27+
RUST_LIB_BACKTRACE: 1
28+
RUST_LOG: info
29+
COLORBT_SHOW_HIDDEN: 1
30+
31+
jobs:
32+
zcashd-compat-regtest:
33+
name: zcashd-compat regtest suite
34+
permissions:
35+
contents: read
36+
runs-on: ubuntu-latest
37+
timeout-minutes: 120
38+
39+
steps:
40+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2
41+
with:
42+
persist-credentials: false
43+
44+
- uses: actions-rust-lang/setup-rust-toolchain@46268bd060767258de96ed93c1251119784f2ab6 #v1.16.1
45+
with:
46+
toolchain: stable
47+
cache-key: zcashd-compat-regtest
48+
cache-on-failure: true
49+
50+
- uses: taiki-e/install-action@65851e10cd6c377f11a60e600abc07cb08643468 #v2.79.3
51+
with:
52+
tool: cargo-nextest
53+
54+
- name: Fetch the pinned sidecar zcashd
55+
run: make compat-zcashd-prepare
56+
57+
- name: Run zcashd-compat regtest suite
58+
run: make compat-test-regtest TEST_ZCASHD_PATH="$PWD/target/zcashd-compat/extracted/bin/zcashd"

CHANGELOG.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,30 @@ All notable changes to Zebra are documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org).
77

8+
## [Unreleased]
9+
10+
### Added
11+
12+
- New regtest-only `generatetoaddress` RPC that mines blocks paying the coinbase
13+
to a caller-specified address, instead of the configured `mining.miner_address`.
14+
This lets a test harness fund several wallets from one node; it is used by the
15+
zcashd wallet-conformance harness
16+
([#10952](https://github.com/ZcashFoundation/zebra/pull/10952))
17+
- New _EXPERIMENTAL_ zcashd-compat mode (`zebrad start --zcashd-compat` or
18+
`[zcashd_compat]` config section) for operators migrating from `zcashd` while
19+
keeping its wallet and RPC surface: Zebra faces the Zcash network and always
20+
includes the configured sidecar peers in block gossip (reserving them an
21+
inbound connection slot), while a hard-locked `zcashd` wallet build runs as a
22+
P2P sidecar with a single outbound connection to the local Zebra node. Zebra
23+
can optionally download (SHA256-pinned), spawn, and supervise the sidecar
24+
(`manage_zcashd = true`). Includes an interactive installer
25+
(`scripts/install-zebra.sh`) with binary, Docker, and build-from-source modes,
26+
a `runtime-zcashd-compat` Docker image stage, make targets, a sync-check
27+
script, and a Zebra Book chapter (`user/zcashd-compat.md`)
28+
([#10952](https://github.com/ZcashFoundation/zebra/pull/10952)). Credits to
29+
[zakura](https://github.com/zakura-core/zakura) authors for the major part of
30+
this implementation.
31+
832
## [Zebra 6.1.0](https://github.com/ZcashFoundation/zebra/releases/tag/v6.1.0) - 2026-07-17
933

1034
### Added

Cargo.lock

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1609,6 +1609,16 @@ version = "0.2.9"
16091609
source = "registry+https://github.com/rust-lang/crates.io-index"
16101610
checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d"
16111611

1612+
[[package]]
1613+
name = "filetime"
1614+
version = "0.2.29"
1615+
source = "registry+https://github.com/rust-lang/crates.io-index"
1616+
checksum = "5c287a33c7f0a620c38e641e7f60827713987b3c0f26e8ddc9462cc69cf75759"
1617+
dependencies = [
1618+
"cfg-if",
1619+
"libc",
1620+
]
1621+
16121622
[[package]]
16131623
name = "find-msvc-tools"
16141624
version = "0.1.9"
@@ -5466,6 +5476,17 @@ version = "1.0.1"
54665476
source = "registry+https://github.com/rust-lang/crates.io-index"
54675477
checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369"
54685478

5479+
[[package]]
5480+
name = "tar"
5481+
version = "0.4.46"
5482+
source = "registry+https://github.com/rust-lang/crates.io-index"
5483+
checksum = "3f6221d9a6003c78398e3b239969f352578258df48c8eb051caadae0015bc840"
5484+
dependencies = [
5485+
"filetime",
5486+
"libc",
5487+
"xattr",
5488+
]
5489+
54695490
[[package]]
54705491
name = "tempfile"
54715492
version = "3.27.0"
@@ -7027,6 +7048,16 @@ dependencies = [
70277048
"zeroize",
70287049
]
70297050

7051+
[[package]]
7052+
name = "xattr"
7053+
version = "1.6.1"
7054+
source = "registry+https://github.com/rust-lang/crates.io-index"
7055+
checksum = "32e45ad4206f6d2479085147f02bc2ef834ac85886624a23575ae137c8aa8156"
7056+
dependencies = [
7057+
"libc",
7058+
"rustix",
7059+
]
7060+
70307061
[[package]]
70317062
name = "xdg"
70327063
version = "3.0.0"
@@ -7638,6 +7669,7 @@ dependencies = [
76387669
"console-subscriber",
76397670
"derive-new",
76407671
"dirs",
7672+
"flate2",
76417673
"futures",
76427674
"hex",
76437675
"hex-literal",
@@ -7655,6 +7687,7 @@ dependencies = [
76557687
"log",
76567688
"metrics",
76577689
"metrics-exporter-prometheus",
7690+
"nix",
76587691
"num-integer",
76597692
"once_cell",
76607693
"opentelemetry",
@@ -7667,12 +7700,15 @@ dependencies = [
76677700
"rand 0.8.6",
76687701
"rayon",
76697702
"regex",
7703+
"reqwest 0.12.28",
76707704
"semver",
76717705
"sentry",
76727706
"serde",
76737707
"serde_json",
7708+
"sha2 0.10.9",
76747709
"strum",
76757710
"strum_macros",
7711+
"tar",
76767712
"tempfile",
76777713
"thiserror 2.0.18",
76787714
"thread-priority",

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ ed25519-zebra = "4.2"
6969
elasticsearch = { version = "8.17.0-alpha.1", default-features = false }
7070
equihash = "0.3"
7171
ff = "0.13"
72-
futures = "0.3.31"
72+
futures = "0.3.32"
7373
futures-core = "0.3.31"
7474
futures-util = "0.3.31"
7575
group = "0.13"

Makefile

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
.PHONY: help
2+
3+
# Keep `make` with no target printing help: the first rule in an included
4+
# file would otherwise become the default goal.
5+
.DEFAULT_GOAL := help
6+
7+
include make/zcashd-compat.mk
8+
9+
help:
10+
@echo "Available targets:"
11+
@echo ""
12+
@echo " zcashd-compat:"
13+
@echo " compat-docker-build Build Docker zcashd-compat image"
14+
@echo " compat-zcashd-prepare Fetch/verify the zcashd-compat sidecar artifact (for tests)"
15+
@echo " compat-docker-start Start Docker zcashd-compat with mounted snapshots"
16+
@echo " compat-zebrad-start-supervised Start zebrad with zcashd supervision enabled"
17+
@echo " compat-zebrad-start-unsupervised Start zebrad with zcashd supervision disabled"
18+
@echo " compat-zcashd-start-standalone Start sidecar zcashd as a standalone process"
19+
@echo " compat-zebrad-status Check zebrad liveness and RPC health"
20+
@echo " compat-zcashd-status Check zcashd liveness and RPC health"
21+
@echo " compat-status-sync Run both status checks and enforce max drift"

book/src/SUMMARY.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
- [Tracing Zebra](user/tracing.md)
1313
- [Zebra Metrics](user/metrics.md)
1414
- [Zebra Health Endpoints](user/health.md)
15+
- [zcashd-compat Mode](user/zcashd-compat.md)
1516
- [Lightwalletd](user/lightwalletd.md)
1617
- [zk-SNARK Parameters](user/parameters.md)
1718
- [Mining](user/mining.md)

0 commit comments

Comments
 (0)