fix(rpc): use NU6 subsidy metadata for NU6.1 and later upgrades - #11172
Merged
mergify[bot] merged 4 commits intoAug 5, 2026
Merged
Conversation
get_block_subsidy compared the height's active upgrade against NU6 with an exact match, so heights governed by NU6.1, NU6.2 and NU6.3 fell through to pre-NU6 funding stream metadata even though they are inside the NU6-style funding and lockbox regime. FundingStream::new_internal already names its parameter is_post_nu6, and NetworkUpgrade's variants are documented as ordered by activation height, so this is an ordering comparison rather than an exact match. Amounts are computed by funding_stream_values and were never affected; only the recipient labels and specification URLs were wrong.
The PR gate requires a new bullet under ## [Unreleased] in each directly changed publishable package's own CHANGELOG.md. The root CHANGELOG.md only counts for the zebrad package.
oxarbitrage
self-requested a review
August 4, 2026 18:27
oxarbitrage
previously approved these changes
Aug 4, 2026
oxarbitrage
left a comment
Contributor
There was a problem hiding this comment.
Looks good to me, a bit verbose but correct.
Applies the review suggestions on ZcashFoundation#11172 verbatim: one line for the ordering comparison instead of three, and shorter changelog entries that link the PR rather than the issue, matching the surrounding entries. Co-authored-by: oxarbitrage <21685097+oxarbitrage@users.noreply.github.com>
Both tests shared the same 25-line RpcImpl setup and differed only in the expected recipient label. Walk the boundary as a table instead, with NU5 as the pre-NU6 row, and keep the either-label lookup so a height that returns no major grants stream still panics rather than passing vacuously.
Contributor
Merge Queue Status
This pull request spent 35 minutes 12 seconds in the queue, including 34 minutes 18 seconds running CI. Required conditions to merge
|
47 tasks
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.
Motivation
Closes #11029.
get_block_subsidydecides which funding stream metadata to return by comparing the height'sactive upgrade against NU6 with an exact match:
Heights governed by NU6.1, NU6.2 and NU6.3 are squarely inside the NU6-style funding and lockbox
regime, but an exact match makes them fall through to the pre-NU6 branch, so they are labelled
with pre-NU6 recipient names and specification URLs.
Two things make this more than a cosmetic mismatch:
FundingStream::new_internalnames its parameter
is_post_nu6, and passes it toFundingStreamReceiver::info(is_post_nu6),which selects
"Zcash Community Grants NU6"+LOCKBOX_SPECIFICATIONversus"Major Grants"+FUNDING_STREAM_SPECIFICATION. The call site was passing an exact-match result into a parameterthat asks for "NU6 or later".
the NU6.3 activation the issue points at. Every
getblocksubsidycall above that height has beentaking the pre-NU6 branch.
Amounts are unaffected: they come from
funding_stream_values, which is consensus code and doesnot consult this flag. Only the labels and specification URLs were wrong.
Solution
Make it an ordering comparison, and rename the local to match the parameter it feeds:
NetworkUpgrade's variants are documented as ordered by activation height ("Enum variants must beordered by activation height"), and the enum derives
Ord/PartialOrd, so>=is the comparisonthat expresses "NU6 or later" without introducing a new helper or new semantics.
The issue also asks to audit
zebra-rpcfor other exact== NetworkUpgrade::Nu6comparisons.There are none — this call site was the only one in the workspace.
Test evidence
One table-driven regression test in
zebra-rpc/src/methods/tests/vectors.rs:rpc_getblocksubsidy_major_grants_metadata_across_nu6_boundary— walks NU5, NU6, NU6.1, NU6.2and NU6.3 at their Mainnet activation heights and asserts the major grants stream carries the
label of that height's era. The NU5 row pins the pre-NU6 side, so the check cannot be widened
past the NU6 boundary either.
The test looks the stream up by either label and panics if neither is present, so it fails
loudly rather than passing vacuously if a height ever returns no funding streams.
Reverting the fix to
==fails on the value, at the earliest affected upgrade:The NU5 row still passes under that revert, so the table is pinning the boundary rather than the
fix.
Checks (all debug):
cargo fmt --all -- --check— cleancargo clippy -p zebra-rpc --all-targets -- -D warnings— cleancargo test -p zebra-rpc --lib— 87 passed, 0 failed, 1 ignored (includes thegetblocksubsidysnapshot tests, which are unchanged)AI disclosure
Claude Code was used for code navigation, to draft the tests and this description, and to run the
checks above. Mechanism, the ordering-comparison choice, and the negative control were verified
against the source by the contributor, who is the sole responsible author.