Skip to content

fix(rpc): use NU6 subsidy metadata for NU6.1 and later upgrades - #11172

Merged
mergify[bot] merged 4 commits into
ZcashFoundation:mainfrom
jiehuo100net:fix/11029-nu6-or-later-subsidy-metadata
Aug 5, 2026
Merged

fix(rpc): use NU6 subsidy metadata for NU6.1 and later upgrades#11172
mergify[bot] merged 4 commits into
ZcashFoundation:mainfrom
jiehuo100net:fix/11029-nu6-or-later-subsidy-metadata

Conversation

@jiehuo100net

@jiehuo100net jiehuo100net commented Aug 2, 2026

Copy link
Copy Markdown
Contributor

Motivation

Closes #11029.

get_block_subsidy decides which funding stream metadata to return by comparing the height's
active upgrade against NU6 with an exact match:

let is_nu6 = NetworkUpgrade::current(&net, height) == NetworkUpgrade::Nu6;

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:

  • The receiving function already declares the intended semantics. FundingStream::new_internal
    names its parameter is_post_nu6, and passes it to FundingStreamReceiver::info(is_post_nu6),
    which selects "Zcash Community Grants NU6" + LOCKBOX_SPECIFICATION versus "Major Grants" +
    FUNDING_STREAM_SPECIFICATION. The call site was passing an exact-match result into a parameter
    that asks for "NU6 or later".
  • This is already live on Mainnet, and has been since NU6.1 at height 3,146,400 — earlier than
    the NU6.3 activation the issue points at. Every getblocksubsidy call above that height has been
    taking the pre-NU6 branch.

Amounts are unaffected: they come from funding_stream_values, which is consensus code and does
not 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:

let is_post_nu6 = NetworkUpgrade::current(&net, height) >= NetworkUpgrade::Nu6;

NetworkUpgrade's variants are documented as ordered by activation height ("Enum variants must be
ordered by activation height"), and the enum derives Ord/PartialOrd, so >= is the comparison
that expresses "NU6 or later" without introducing a new helper or new semantics.

The issue also asks to audit zebra-rpc for other exact == NetworkUpgrade::Nu6 comparisons.
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.2
    and 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:

assertion `left == right` failed: Nu6_1 at height Height(3146400) must use the
"Zcash Community Grants NU6" label
  left: "Major Grants"
 right: "Zcash Community Grants NU6"

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 — clean
  • cargo clippy -p zebra-rpc --all-targets -- -D warnings — clean
  • cargo test -p zebra-rpc --lib87 passed, 0 failed, 1 ignored (includes the
    getblocksubsidy snapshot 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.

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
oxarbitrage self-requested a review August 4, 2026 18:27
oxarbitrage
oxarbitrage previously approved these changes Aug 4, 2026

@oxarbitrage oxarbitrage left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Looks good to me, a bit verbose but correct.

Comment thread zebra-rpc/src/methods.rs Outdated
Comment thread zebra-rpc/src/methods/tests/vectors.rs Outdated
Comment thread zebra-rpc/CHANGELOG.md Outdated
Comment thread CHANGELOG.md Outdated
jiehuo100net and others added 2 commits August 5, 2026 01:39
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.

@oxarbitrage oxarbitrage left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thanks!

@mergify mergify Bot added the queued label Aug 5, 2026
@mergify

mergify Bot commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

Merge Queue Status

  • Entered queue2026-08-05 12:50 UTC · Rule: batched · triggered by rule move to any queue if GitHub Rulesets are satisfied
  • Checks passed · on draft merge queue: checking main (5098bdc) and #11172 together #11188
  • Merged2026-08-05 13:25 UTC · at 77829dfb4e40221cac02deda23de9cd2dd41cbb0 · merge

This pull request spent 35 minutes 12 seconds in the queue, including 34 minutes 18 seconds running CI.

Required conditions to merge

@mergify
mergify Bot merged commit da29357 into ZcashFoundation:main Aug 5, 2026
114 of 118 checks passed
@mergify mergify Bot removed the queued label Aug 5, 2026
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.

bug: extend getblocksubsidy NU6 metadata handling to later NU6.x upgrades

2 participants