Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .github/workflows/audits.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,13 @@ jobs:
# is a checked-in symlink to the root's, as is its deny.toml. Policies and
# imports are graph-specific, so config.toml and imports.lock are real
# per-workspace files (cargo-vet errors on policy entries for crates that
# are not in the current graph, so a shared config cannot serve all three).
# are not in the current graph, so a shared config cannot serve all four).
cargo-vet:
name: Vet Rust dependencies (${{ matrix.workspace }})
runs-on: ubuntu-latest
strategy:
matrix:
workspace: [".", "backends/zebra", "backends/zaino"]
workspace: [".", "backends/zebra", "backends/zaino", "backends/zinder"]
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
Expand All @@ -41,7 +41,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
workspace: [".", "backends/zebra", "backends/zaino"]
workspace: [".", "backends/zebra", "backends/zaino", "backends/zinder"]
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
Expand Down
24 changes: 17 additions & 7 deletions .github/workflows/binaries-and-deb-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -259,8 +259,8 @@ jobs:

# Basic sanity check: the export image carries three binaries at its
# root (zcash/zallet#540): /zallet is the launcher, and
# /zallet-zebra + /zallet-zaino are the real backend binaries.
for bin in zallet zallet-zebra zallet-zaino; do
# /zallet-zebra, /zallet-zaino, and /zallet-zinder are the real backend binaries.
for bin in zallet zallet-zebra zallet-zaino zallet-zinder; do
if [[ ! -s "${ARTIFACT_ROOT}/${bin}" ]]; then
echo "Missing ${bin} binary under ${ARTIFACT_ROOT}" >&2
find "${ARTIFACT_ROOT}" -maxdepth 5 || true
Expand All @@ -277,6 +277,7 @@ jobs:
install -m 0755 "${ARTIFACT_ROOT}/zallet" "build/${PLATFORM_KEY}/zallet"
install -m 0755 "${ARTIFACT_ROOT}/zallet-zebra" "build/${PLATFORM_KEY}/zallet-zebra"
install -m 0755 "${ARTIFACT_ROOT}/zallet-zaino" "build/${PLATFORM_KEY}/zallet-zaino"
install -m 0755 "${ARTIFACT_ROOT}/zallet-zinder" "build/${PLATFORM_KEY}/zallet-zinder"

# Copy the usr/local tree as-is (completions, manpages, docs, etc.)
# If there is no usr/local in the artifact, this won't fail because of '|| true'
Expand Down Expand Up @@ -306,6 +307,10 @@ jobs:
-v "$PWD/build/${{ matrix.platform_key }}/zallet-zaino":/usr/local/bin/zallet-zaino:ro \
"debian:${SMOKE_TEST_DISTRO}-slim" \
/usr/local/bin/zallet-zaino -h
docker run --rm --platform ${{ matrix.platform }} \
-v "$PWD/build/${{ matrix.platform_key }}/zallet-zinder":/usr/local/bin/zallet-zinder:ro \
"debian:${SMOKE_TEST_DISTRO}-slim" \
/usr/local/bin/zallet-zinder -h

- name: Prepare standalone binary artifact
env:
Expand All @@ -322,6 +327,7 @@ jobs:
# `-launcher` artifact rather than replacing the plain name.
cp "build/${PLATFORM_KEY}/zallet-zebra" "standalone/zallet-${RELEASE_VERSION}-${BINARY_SUFFIX}"
cp "build/${PLATFORM_KEY}/zallet-zaino" "standalone/zallet-${RELEASE_VERSION}-${BINARY_SUFFIX}-zaino"
cp "build/${PLATFORM_KEY}/zallet-zinder" "standalone/zallet-${RELEASE_VERSION}-${BINARY_SUFFIX}-zinder"
cp "build/${PLATFORM_KEY}/zallet" "standalone/zallet-${RELEASE_VERSION}-${BINARY_SUFFIX}-launcher"

- name: Generate provenance chain metadata
Expand Down Expand Up @@ -369,7 +375,8 @@ jobs:
run: |
set -euo pipefail
for b in "standalone/zallet-${RELEASE_VERSION}-${BINARY_SUFFIX}" \
"standalone/zallet-${RELEASE_VERSION}-${BINARY_SUFFIX}-zaino"; do
"standalone/zallet-${RELEASE_VERSION}-${BINARY_SUFFIX}-zaino" \
"standalone/zallet-${RELEASE_VERSION}-${BINARY_SUFFIX}-zinder"; do
gpg -u sysadmin@zodl.com --armor --digest-algo SHA256 --detach-sign "$b"
done

Expand All @@ -383,8 +390,8 @@ jobs:
from pathlib import Path

base = f"standalone/zallet-{os.environ['RELEASE_VERSION']}-{os.environ['BINARY_SUFFIX']}"
# SBOM for both backend binaries (default zebra-state + additive zaino).
for binary_path in (Path(base), Path(f"{base}-zaino")):
# SBOM for every backend binary.
for binary_path in (Path(base), Path(f"{base}-zaino"), Path(f"{base}-zinder")):
if not binary_path.exists():
raise SystemExit(f"Missing binary at {binary_path}")
checksum = hashlib.sha256(binary_path.read_bytes()).hexdigest()
Expand Down Expand Up @@ -413,6 +420,7 @@ jobs:
subject-path: |
standalone/zallet-${{ env.RELEASE_VERSION }}-${{ matrix.binary_suffix }}
standalone/zallet-${{ env.RELEASE_VERSION }}-${{ matrix.binary_suffix }}-zaino
standalone/zallet-${{ env.RELEASE_VERSION }}-${{ matrix.binary_suffix }}-zinder
standalone/zallet-${{ env.RELEASE_VERSION }}-${{ matrix.binary_suffix }}-launcher

- name: Save binary attestation bundle
Expand All @@ -423,6 +431,7 @@ jobs:
# binary has a co-located .intoto.jsonl next to it in the Release.
cp -- "$BUNDLE_PATH" "standalone/zallet-${RELEASE_VERSION}-${{ matrix.binary_suffix }}.intoto.jsonl"
cp -- "$BUNDLE_PATH" "standalone/zallet-${RELEASE_VERSION}-${{ matrix.binary_suffix }}-zaino.intoto.jsonl"
cp -- "$BUNDLE_PATH" "standalone/zallet-${RELEASE_VERSION}-${{ matrix.binary_suffix }}-zinder.intoto.jsonl"
cp -- "$BUNDLE_PATH" "standalone/zallet-${RELEASE_VERSION}-${{ matrix.binary_suffix }}-launcher.intoto.jsonl"

- name: Seed cargo target tree with the imported artifacts
Expand All @@ -443,12 +452,13 @@ jobs:

# Seed the launcher and both real backend binaries for cargo-deb
# --no-build: the `zallet` package installs `zallet` = the launcher
# plus the two backend binaries it dispatches to (zcash/zallet#540;
# plus the backend binaries it dispatches to (zcash/zallet#540;
# the pre-split zallet-zebra *symlink* is obsolete — it is a
# real binary now).
install -m 0755 "build/${PLATFORM_KEY}/zallet" "${TARGET_DIR}/zallet"
install -m 0755 "build/${PLATFORM_KEY}/zallet-zebra" "${TARGET_DIR}/zallet-zebra"
install -m 0755 "build/${PLATFORM_KEY}/zallet-zaino" "${TARGET_DIR}/zallet-zaino"
install -m 0755 "build/${PLATFORM_KEY}/zallet-zinder" "${TARGET_DIR}/zallet-zinder"

# Copy the whole completions tree (whatever is inside)
cp -a "${ROOT}/completions/." "${COMPLETIONS_DIR}/" 2>/dev/null || true
Expand All @@ -458,7 +468,7 @@ jobs:

# Copy Debian copyright metadata. The license inventory is generated
# by gen-copyright on the amd64 StageX path only; it is the union of
# all three shipped binaries' dependency graphs and arch-independent,
# all shipped binaries' dependency graphs and arch-independent,
# so the arm64 (Nix-built) leg reuses the amd64 artifact's copy.
if [[ -f "${ROOT}/debian-copyright" ]]; then
install -m 0644 "${ROOT}/debian-copyright" "${TARGET_DIR}/debian-copyright"
Expand Down
7 changes: 4 additions & 3 deletions .github/workflows/build-arm64-nix.yml
Original file line number Diff line number Diff line change
Expand Up @@ -83,11 +83,11 @@ jobs:

- name: Build static aarch64-musl binaries (reproducible)
run: |
# The merged `zallet` package carries the launcher + both backend
# The merged `zallet` package carries the launcher + all backend
# binaries (each from its own workspace, zcash/zallet#540) plus the
# share tree.
nix build .#zallet --print-build-logs
for bin in zallet zallet-zebra zallet-zaino; do
for bin in zallet zallet-zebra zallet-zaino zallet-zinder; do
test -x "./result/bin/${bin}"
file -L "./result/bin/${bin}" | tee "/tmp/${bin}-file.txt"
grep -q "aarch64" "/tmp/${bin}-file.txt"
Expand Down Expand Up @@ -118,12 +118,13 @@ jobs:
install -m0755 /tmp/zallet-bins/zallet "${DEST}/zallet"
install -m0755 /tmp/zallet-bins/zallet-zebra "${DEST}/zallet-zebra"
install -m0755 /tmp/zallet-bins/zallet-zaino "${DEST}/zallet-zaino"
install -m0755 /tmp/zallet-bins/zallet-zinder "${DEST}/zallet-zinder"
# share tree comes from the zebra-state backend build only.
if [ -d /tmp/zallet-share ]; then
cp -aL /tmp/zallet-share/. "${SHARE}/"
fi
# NOTE: no debian-copyright here — the license inventory is the union
# of all three binaries' graphs, generated by gen-copyright on the
# of all binaries' graphs, generated by gen-copyright on the
# amd64 StageX path; it is arch-independent, and the deb job falls
# back to the amd64 artifact's copy for the arm64 leg.
echo "staged tree:"; find "${DEST}" -maxdepth 4 -type f | head -30
Expand Down
21 changes: 18 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -62,13 +62,19 @@ jobs:
cargo test
--manifest-path backends/zebra/Cargo.toml
--features zcashd-import,rpc-cli,tokio-console
- name: Run tests (zinder backend)
run: >
cargo test
--manifest-path backends/zinder/Cargo.toml
--features zcashd-import,rpc-cli,tokio-console
# End-to-end check of the `zallet` launcher: config-driven dispatch to the
# backend binaries, and the backend binaries' own backend-key validation.
- name: Launcher dispatch smoke test
run: |
cargo build --bin zallet
cargo build --manifest-path backends/zebra/Cargo.toml --bin zallet-zebra
cargo build --manifest-path backends/zaino/Cargo.toml --bin zallet-zaino
cargo build --manifest-path backends/zinder/Cargo.toml --bin zallet-zinder
bindir="$(mktemp -d)"
datadir="$(mktemp -d)"
cp target/debug/zallet "$bindir/"
Expand Down Expand Up @@ -97,11 +103,20 @@ jobs:
cp backends/zaino/target/debug/zallet-zaino "$bindir/"
"$bindir/zallet" --datadir "$datadir" --version

# The same config-driven dispatch works for the Zinder backend.
sed -i 's/backend = "zaino"/backend = "zinder"/' "$datadir/zallet.toml"
if out=$("$bindir/zallet" --datadir "$datadir" --version 2>&1); then
echo "expected dispatch to a missing zallet-zinder to fail"; exit 1
fi
echo "$out" | grep -q "zallet-zinder" || { echo "error did not name zallet-zinder: $out"; exit 1; }
cp backends/zinder/target/debug/zallet-zinder "$bindir/"
"$bindir/zallet" --datadir "$datadir" --version

# Belt-and-braces: a backend binary invoked directly against a config
# that names the other backend refuses to run.
if out=$("$bindir/zallet-zebra" --datadir "$datadir" example-config -o - \
--this-is-alpha-code-and-you-will-need-to-recreate-the-example-later 2>&1); then
echo "expected zallet-zebra to reject a backend=zaino config"; exit 1
echo "expected zallet-zebra to reject a backend=zinder config"; exit 1
fi
echo "$out" | grep -q "provides the 'zebra' backend" \
|| { echo "unexpected mismatch error: $out"; exit 1; }
Expand Down Expand Up @@ -185,7 +200,7 @@ jobs:
# Multi-path rm requires bash: the Windows default shell (pwsh) aliases
# `rm` to Remove-Item, which rejects multiple positional paths.
shell: bash
run: rm Cargo.lock backends/zebra/Cargo.lock backends/zaino/Cargo.lock
run: rm Cargo.lock backends/zebra/Cargo.lock backends/zaino/Cargo.lock backends/zinder/Cargo.lock
- name: Build crates (zallet-core)
run: >
cargo build
Expand All @@ -209,7 +224,7 @@ jobs:
# The `--` is load-bearing: the deleted lockfiles are not regenerated on
# platforms that skip a backend build, and git fatals on a pathspec for
# a nonexistent path unless the paths are `--`-separated.
run: git diff --exit-code -- ':!Cargo.lock' ':!backends/zebra/Cargo.lock' ':!backends/zaino/Cargo.lock'
run: git diff --exit-code -- ':!Cargo.lock' ':!backends/zebra/Cargo.lock' ':!backends/zaino/Cargo.lock' ':!backends/zinder/Cargo.lock'

trigger-integration:
name: Trigger integration tests
Expand Down
28 changes: 28 additions & 0 deletions .github/workflows/lints.yml
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,16 @@ jobs:
--all-targets
args: >
-D warnings
- name: Run clippy (zinder backend)
uses: auguwu/clippy-action@94a9ff2f6920180b89e5c03d121d0af04a9d3e03 # 1.4.0
with:
token: ${{ secrets.GITHUB_TOKEN }}
check-args: >
--manifest-path backends/zinder/Cargo.toml
--features zcashd-import,rpc-cli,tokio-console
--all-targets
args: >
-D warnings

clippy-beta:
name: Clippy (beta)
Expand Down Expand Up @@ -99,6 +109,16 @@ jobs:
--all-targets
args: >
-W clippy::all
- name: Run Clippy (beta, zinder backend)
uses: auguwu/clippy-action@94a9ff2f6920180b89e5c03d121d0af04a9d3e03 # 1.4.0
with:
token: ${{ secrets.GITHUB_TOKEN }}
check-args: >
--manifest-path backends/zinder/Cargo.toml
--features zcashd-import,rpc-cli,tokio-console
--all-targets
args: >
-W clippy::all

doc-links:
name: Intra-doc links
Expand All @@ -110,6 +130,7 @@ jobs:
- run: cargo fetch
- run: cargo fetch --manifest-path backends/zebra/Cargo.toml
- run: cargo fetch --manifest-path backends/zaino/Cargo.toml
- run: cargo fetch --manifest-path backends/zinder/Cargo.toml
# Requires #![deny(rustdoc::broken_intra_doc_links)] in crates.
- name: Check intra-doc links (zallet-core)
run: >
Expand All @@ -126,6 +147,11 @@ jobs:
cargo doc
--manifest-path backends/zaino/Cargo.toml
--document-private-items
- name: Check intra-doc links (zinder backend)
run: >
cargo doc
--manifest-path backends/zinder/Cargo.toml
--document-private-items

fmt:
name: Rustfmt
Expand All @@ -140,6 +166,8 @@ jobs:
run: cargo fmt --manifest-path backends/zebra/Cargo.toml -- --check
- name: Check formatting (zaino backend)
run: cargo fmt --manifest-path backends/zaino/Cargo.toml -- --check
- name: Check formatting (zinder backend)
run: cargo fmt --manifest-path backends/zinder/Cargo.toml -- --check

hadolint:
name: Hadolint (${{ matrix.dockerfile }})
Expand Down
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@ be considered breaking changes.

### Added

- A `zinder` chain backend can now sync wallets through Zinder's native gRPC
API. It uses epoch-pinned chain reads, chain and mempool event streams,
per-outpoint transparent spend detection, and Zinder's transaction
broadcaster; startup rejects incompatible networks, contract revisions, or
capability sets before opening the wallet database.
- `migrate-zcashd-wallet` now supports passphrase-encrypted zcashd wallets:
when the wallet's key material is encrypted, the command interactively
requests the wallet passphrase and decrypts the key material during the
Expand Down
Loading
Loading