Skip to content

Zebra chain view - #1

Closed
nuttycom wants to merge 14 commits into
generic_chain_viewfrom
zebra-chain-view
Closed

Zebra chain view#1
nuttycom wants to merge 14 commits into
generic_chain_viewfrom
zebra-chain-view

Conversation

@nuttycom

Copy link
Copy Markdown
Owner

No description provided.

The scan-range loop in `initialize` can complete without ever routing
the tip block through `put_blocks` — e.g. when the wallet has no
shielded scan work and `suggest_scan_ranges` returns nothing in the
bands the filter accepts. `update_chain_tip` then records the new
height but no `BlockMetadata` is committed for it, and any caller
asking the wallet for its view of the tip via
`getwalletstatus.wallet_tip` sees `None` indefinitely.

This strands integration-tests `rebuild_cache`, which spawns several
trivially-synced wallets in parallel and waits for all of them to
report a `wallet_tip` matching `node_tip`; shards exercising this path
hang until the GitHub Actions 6h cap cancels them.

When the scan-range loop is about to exit, commit metadata for the
tip block against the *same* `chain_view` snapshot we just read
`current_tip` from, so tree state and the block payload come from a
single consistent chain view. Best-effort: if the indexer can't serve
the block (transient outage), log a warning and let `steady_state`
populate metadata once the indexer catches up. Skip at height 0
where `scan_block` would otherwise underflow on `tree_state_as_of`.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
nuttycom added a commit that referenced this pull request Jun 22, 2026
…ures

The zaino (default) and zebra-state chain backends are mutually-exclusive cargo
features; enabling both (as `--all-features` does) trips the compile_error guard
in lib.rs, so every test/clippy/build job using --all-features failed to compile.
Replace --all-features with explicit per-backend feature sets:

- ci.yml: the required Linux test job runs both backends; the cross-platform /
  NU7 / merchant_terminal jobs track the default zaino backend; build-latest
  builds the zebra-state backend on Linux only.
- lints.yml: Clippy (MSRV) and Clippy (beta) lint both backends.

Both backends build on the pinned 1.85.1 MSRV toolchain. Fixes CI on PR #1.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Comment thread zallet/src/components/chain/zaino.rs Outdated
async fn find_fork_point(
&self,
known_tip: &BlockHash,
locator: &[BlockHash],

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be sorted? This could return different results depending on the order of locators provided

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nvm, I see this is described below as expected to be ordered by height

Comment thread zallet/src/components/sync/locator.rs Outdated
pub(super) fn build_block_locator(
db_data: &DbConnection,
tip: BlockHeight,
) -> Result<Vec<BlockHash>, SyncError> {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not create a named locator type?


/// The maximum depth below the tip that a locator spans, matching Zebra's
/// `MAX_BLOCK_REORG_HEIGHT` so the locator always covers the reorg window.
const MAX_LOCATOR_DEPTH: u32 = 1000;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps TODO for another day: could this and PRUNING_DEPTH be network parameters provided by Zebra, so that we don't have hard-coded constants expected to match their hard-coded constants?

nuttycom added a commit that referenced this pull request Jun 22, 2026
…ures

The zaino (default) and zebra-state chain backends are mutually-exclusive cargo
features; enabling both (as `--all-features` does) trips the compile_error guard
in lib.rs, so every test/clippy/build job using --all-features failed to compile.
Replace --all-features with explicit per-backend feature sets:

- ci.yml: the required Linux test job runs both backends; the cross-platform /
  NU7 / merchant_terminal jobs track the default zaino backend; build-latest
  builds the zebra-state backend on Linux only.
- lints.yml: Clippy (MSRV) and Clippy (beta) lint both backends.

Both backends build on the pinned 1.85.1 MSRV toolchain. Fixes CI on PR #1.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@nuttycom

Copy link
Copy Markdown
Owner Author

force-pushed to rebase on zcash#489

@nuttycom
nuttycom force-pushed the generic_chain_view branch from ec0a8a4 to 1ee55da Compare June 22, 2026 19:46
nuttycom added a commit that referenced this pull request Jun 22, 2026
…ures

The zaino (default) and zebra-state chain backends are mutually-exclusive cargo
features; enabling both (as `--all-features` does) trips the compile_error guard
in lib.rs, so every test/clippy/build job using --all-features failed to compile.
Replace --all-features with explicit per-backend feature sets:

- ci.yml: the required Linux test job runs both backends; the cross-platform /
  NU7 / merchant_terminal jobs track the default zaino backend; build-latest
  builds the zebra-state backend on Linux only.
- lints.yml: Clippy (MSRV) and Clippy (beta) lint both backends.

Both backends build on the pinned 1.85.1 MSRV toolchain. Fixes CI on PR #1.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
nuttycom and others added 2 commits June 22, 2026 10:16
Abstract over chain data sources by turning `Chain` and `ChainView` into traits.
sync: Ensure `initialize` leaves `block_metadata(tip)` populated
nuttycom added a commit that referenced this pull request Jun 22, 2026
…ures

The zaino (default) and zebra-state chain backends are mutually-exclusive cargo
features; enabling both (as `--all-features` does) trips the compile_error guard
in lib.rs, so every test/clippy/build job using --all-features failed to compile.
Replace --all-features with explicit per-backend feature sets:

- ci.yml: the required Linux test job runs both backends; the cross-platform /
  NU7 / merchant_terminal jobs track the default zaino backend; build-latest
  builds the zebra-state backend on Linux only.
- lints.yml: Clippy (MSRV) and Clippy (beta) lint both backends.

Both backends build on the pinned 1.85.1 MSRV toolchain. Fixes CI on PR #1.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
pacu and others added 11 commits June 22, 2026 18:06
`ErrorKind::Sync.context(...).into()` cannot convert to `ChainError`
since that trait bound is not implemented. Use `ChainError::backend`
instead, consistent with the existing pattern in the same function.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
sync: fix ChainError conversion in initialize tip scan
ChainView::find_fork_point now takes a block locator (the wallet's own block hashes, highest height first) rather than a single hash, matching the locator-based zebra-state FindForkPoint request that the upcoming Zebra backend will use. A new sync/locator.rs builds the locator from the wallet DB (mirroring zebra-state's block_locator_heights). The Zaino backend iterates the locator and resolves the first entry from its retained side chains, which is behavior-preserving for the wallet's previous tip (locator[0]).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Adds mutually-exclusive `zaino` (default) and `zebra-state` cargo features (a compile_error enforces exactly one). The zebra-state backend opens zebrad's state read-only via init_read_state_with_syncer and uses a small direct jsonrpsee validator client for mempool/tx-submission rather than zaino-fetch (which transitively pulls zebra-state v8 + rocksdb, re-coupling the wallet to Zaino's zebra version). The zebra deps are direct optional git deps pinned to the find-fork-point rev; a global [patch] would rewrite Zaino's transitive zebra deps and break the default build. ZebraChainView is stubbed; read methods land in subsequent plans. A cfg-selected ChainBackend alias wires the construction sites.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Adds a mockable ChainReader seam (real impl over the ReadStateService, plus a test mock), zebra<->zcash_primitives conversions, and the wallet-side pinned height->hash resolver: finalized heights are served by height directly, non-finalized heights by hash via a memoized header walk down from the captured tip. Implements tip, get_block, get_block_header, tree_state_as_of, stream_blocks, get_transaction[_status], find_fork_point, block_height, and the subtree roots. Reorg-induced inconsistencies (a pinned hash walked off the retained set, or a best-chain-only treestate missing for a pinned non-finalized hash) surface as ChainError::Unavailable. The mempool stream remains stubbed (next plan).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
get_mempool_stream polls getrawmempool over JSON-RPC, yields each newly-seen
transaction parsed at the tip+1 branch, and ends when the chain tip changes
(checked against the captured tip each interval) - matching the existing
emit-new/end-on-tip-change contract the sync loop relies on. The unused
ChainTipChange is dropped from ZebraChain.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
When a captured chain view references a non-finalized block that is reorged
away mid-read, the read now surfaces as ChainError::Unavailable. The
steady-state loop classifies that as retryable: it discards the stale view,
backs off briefly, and re-pins to the current tip, instead of propagating a
fatal error that shuts the wallet down. The loop body is extracted into
steady_state_iteration taking &mut prev_tip, so progress already committed to
the wallet is preserved across the retry. Only the zebra-state backend produces
Unavailable; the Zaino backend is unchanged.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ection

The config generator emits the optional [indexer.read_state_service] section
(added in fc40c07), but the cli_tests example-config golden was never
regenerated to include it. This stayed hidden because the cli_tests target has
required-features = ["zcashd-import"], which the `--features zaino` local gate
does not enable, and CI's `--all-features` run never compiled (the zaino and
zebra-state backends are mutually exclusive). The section is backend-independent,
so the single golden serves both backends.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ures

The zaino (default) and zebra-state chain backends are mutually-exclusive cargo
features; enabling both (as `--all-features` does) trips the compile_error guard
in lib.rs, so every test/clippy/build job using --all-features failed to compile.
Replace --all-features with explicit per-backend feature sets:

- ci.yml: the required Linux test job runs both backends; the cross-platform /
  NU7 / merchant_terminal jobs track the default zaino backend; build-latest
  builds the zebra-state backend on Linux only.
- lints.yml: Clippy (MSRV) and Clippy (beta) lint both backends.

Both backends build on the pinned 1.85.1 MSRV toolchain. Fixes CI on PR #1.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
find_fork_point previously took a raw &[BlockHash] whose descending-chain-height
ordering was an unenforced convention maintained only by build_block_locator. A
mis-ordered slice would silently yield the wrong fork point, since the per-entry
"first match wins" search assumes the highest-height entry comes first.

Introduce a BlockLocator newtype whose from_blocks(impl IntoIterator<Item =
ChainBlock>) constructor asserts (and documents) the strictly-decreasing-height
construction invariant, and thread &BlockLocator through ChainView/ChainReader
find_fork_point and the Zaino/Zebra backends. build_block_locator now returns a
BlockLocator.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Flip the default chain-data backend from zaino to zebra-state. A bare
cargo build/test now builds the direct read-state-service backend (pulling the
zebra deps, targeting a co-located zebrad with the indexer feature; no regtest);
the Zaino backend is opt-in via --no-default-features --features zaino.

CI per-backend invocations are made explicit (--no-default-features --features
zaino,... / ...zebra-state,...) so they no longer depend on which feature is the
default; cross-platform / NU7 / merchant jobs continue to track zaino. The
mutual-exclusion guard hints are updated to point at zaino as the opt-in.

The .deb package is explicitly pinned to the zebra-state backend
(default-features = false), rather than inheriting the default, since released
mainnet/testnet packages should use the more reliable direct read-state-service
backend regardless of any future default change.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@nuttycom
nuttycom deleted the branch generic_chain_view June 22, 2026 23:07
@nuttycom nuttycom closed this Jun 22, 2026
@nuttycom

Copy link
Copy Markdown
Owner Author

Closed in favor of zcash#493

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants