z_getbalances: split transparent balance into regular and coinbase; z_listunspent: add 'generated' flag#639
Open
pacu wants to merge 4 commits into
Open
z_getbalances: split transparent balance into regular and coinbase; z_listunspent: add 'generated' flag#639pacu wants to merge 4 commits into
pacu wants to merge 4 commits into
Conversation
This was referenced Jul 17, 2026
pacu
marked this pull request as ready for review
July 17, 2026 13:19
Adds a 'generated' boolean to each transparent UTXO in the z_listunspent response, matching the field zcashd's listunspent uses to mark coinbase outputs. This lets callers (e.g. mining-pool operators, issue #635) classify UTXOs without a getrawtransaction round-trip per txid. The transparent query now runs twice per address, once with CoinbaseFilter::NonCoinbaseOnly (tagged generated=false) and once with CoinbaseFilter::CoinbaseOnly (tagged generated=true). The two filters partition the set previously returned by AllTransparentOutputs: outputs with an unknown tx_index are treated as non-coinbase by the former and excluded by the latter, so the union is exact and disjoint. Immature coinbase outputs remain excluded by the shared upstream maturity clause. Transparent rows are now ordered non-coinbase-then-coinbase per address; no output ordering was ever documented. Shielded outputs omit the field entirely. The transparent entry construction is extracted into a pure helper so its JSON rendering is unit-tested without a database. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017WB1TU6tyLmMa1n4SQ9XgK
pacu
force-pushed
the
fix-635-transparent-coinbase-balance
branch
2 times, most recently
from
July 19, 2026 19:18
6599fac to
200bbb8
Compare
Consumes the upstream AccountBalance split of the unshielded balance into regular (non-coinbase) and coinbase buckets, via a temporary [patch.crates-io] path pin to a patched librustzcash worktree (to be replaced with a git rev once the librustzcash PR branch is pushed, and removed once released to crates.io). The librustzcash workspace component crates are patched alongside so Cargo does not resolve duplicate copies. z_getbalances now populates both `transparent.regular` and `transparent.coinbase` per account, and the account `total` now includes transparent value in its `spendable` and `pending` buckets (previously only shielded pools contributed). Immature coinbase is reported as pending rather than spendable. Dust continues to be sourced from AccountBalance::uneconomic_value, which already spans both transparent buckets, so it is counted exactly once. z_getbalanceforaccount and z_gettotalbalance intentionally keep their combined transparent view (regular + coinbase); unit tests now pin that behaviour across the upstream change. Fixes #635. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017WB1TU6tyLmMa1n4SQ9XgK
Point [patch.crates-io] (workspace root and both backend workspaces) at zcash/librustzcash@47344ee188, the branch providing the transparent regular/coinbase AccountBalance split consumed by z_getbalances. The workspace component crates are patched alongside to avoid duplicate crate resolutions. Remove once a release containing the split ships on crates.io. This branch is based on current librustzcash main, so the single stack-wide pin also carries `WalletDb::transactionally_with_extension`, which main pinned d09d1f390f for (the atomic z_importkey writes); that pin is replaced rather than duplicated. Following upstream zcash/librustzcash#2650, `create_proposed_transactions` takes an optional expiry-height override; the z_sendmany and z_shieldcoinbase call sites pass `None`, keeping the builder-derived expiry. The pinned stack requires zewif 1.0.0-rc.3, so zewif and zewif-zcashd move to their rc.3 releases together. Also records the z_getbalances fix and the z_listunspent 'generated' field in the changelog. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017WB1TU6tyLmMa1n4SQ9XgK
nuttycom
force-pushed
the
fix-635-transparent-coinbase-balance
branch
from
July 19, 2026 23:52
6bf5337 to
6a21786
Compare
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.
Fixes #635.
Summary
z_getbalancesnow delivers its documented transparent balance contract, andz_listunspentidentifies coinbase UTXOs — so integrators (mining pools in particular) can finally read "how much can I pay to a transparent recipient" directly from the wallet.z_getbalances(fe6ce4b):transparent.regularcontains only non-coinbase funds;transparent.coinbaseis populated (immature coinbase reported aspending, mature asspendable); the accounttotalnow includes transparent value in itsspendable/pendingbuckets, sototal == sum of partsacross all five pools. Previouslyregularsilently included coinbase,coinbasewas never emitted, andtotal.spendableignored the transparent pool entirely — the combination that halted the reporting pool's payouts withInsufficient balance (have 0, …).z_listunspent(dd87ed2, standalone/cherry-pickable): transparent entries gain"generated": true|false(coinbase origin, mirroring zcashd'slistunspent; omitted on shielded entries), replacing the per-UTXOgetrawtransactionround-trip integrators needed. Implemented via two disjointCoinbaseFilterqueries; requires no librustzcash changes.68ad944): the balance split comes from Split AccountBalance unshielded balance into regular and coinbase buckets librustzcash#2654;[patch.crates-io](workspace root + both backend workspaces) pins that branch (196f12439a) until a release containing it ships.z_gettotalbalancesemantics are intentionally unchanged (pinned by new tests).Verification
cargo test -p zallet-core: 208 passed (14 new unit tests: full rendering matrix for the split incl. dust-counted-once and total-equals-sum-of-parts; semantics pins forz_getbalanceforaccount/z_gettotalbalance;generatedserialization contract). Both backendscargo checkclean against the pin.wallet_transparent_coinbase_balance.py, see the accompanying integration-tests PR): immature coinbase →coinbase.pending; mature →coinbase.spendablewith exact zatoshi sums; post-shieldz_sendmanyz→t output lands inregular.spendableonly;generatedflags correct on every entry;z_gettotalbalancecross-check passes.Notes for review:
z_listunspenttransparent output ordering changed (non-coinbase before coinbase per address; no ordering was documented). Immature coinbase remains excluded fromz_listunspent(upstream maturity clause), whilez_getbalancesnow does show it as pending — intentional and now-documented behavior.🤖 Generated with Claude Code
https://claude.ai/code/session_017WB1TU6tyLmMa1n4SQ9XgK