fix(rpc): cache the getblocktemplate coinbase per block - #10847
Merged
Conversation
upbqdn
force-pushed
the
gbt-coinbase-cache
branch
from
June 28, 2026 14:38
d80223d to
8c1946c
Compare
jvff
previously approved these changes
Jun 30, 2026
Member
|
/changelog |
|
Proposed changelog entries for this PR. Review and paste into the relevant ## Top-level `CHANGELOG.md` — `[Unreleased]`
### Fixed
- `getblocktemplate` now caches the built coinbase transaction per block height and total fees, so repeated short-poll requests within the same block no longer rebuild it. This prevents CPU saturation and multi-second template latency when mining to a shielded (Sapling or Orchard) address.
---
## `zebra-rpc/CHANGELOG.md` — `[Unreleased]`
### Fixed
- `getblocktemplate` now caches the built coinbase transaction per `(height, fees)`, so repeated short-poll requests within a block no longer rebuild it. This avoids re-running the Sapling/Orchard proof on every request when mining to a shielded address, which otherwise pegged the CPU and made each template take seconds. |
upbqdn
force-pushed
the
gbt-coinbase-cache
branch
from
July 1, 2026 12:14
88c43e2 to
7f95ccc
Compare
`getblocktemplate` rebuilt the coinbase on every request, re-running the Sapling/Orchard proof for shielded miner addresses. The existing precompute only feeds long-poll clients, so short-polling pools (which re-request without long polling) re-proved the coinbase on every poll — pegging the CPU and making each template take seconds. Cache the built coinbase keyed on `(height, fees)` so repeated requests within a block reuse it, and clear the cache when the coinbase data is randomized.
Transaction selection builds a fake coinbase to size the block, which re-proved the shielded coinbase on every getblocktemplate call, outside the per-block cache. Route it through the same cache: only the first call per block proves.
The `Option`-returning `CoinbaseCache::get` tripped `clippy::unwrap_in_result` (denied via `-D warnings` in the test-crates MSRV build). Recover the guard on poison at all three lock sites; a coinbase cache need not crash the node over an unrelated thread's panic. Claude-Session: https://claude.ai/code/session_01VUPwpe81Ws8c5MeXWWgZb7
upbqdn
force-pushed
the
gbt-coinbase-cache
branch
from
July 1, 2026 13:02
7f95ccc to
7cdaa26
Compare
jvff
approved these changes
Jul 1, 2026
Contributor
Merge Queue Status
This pull request spent 50 minutes 34 seconds in the queue, including 40 minutes 9 seconds running CI. Required conditions to merge
|
This was referenced Jul 1, 2026
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 #10846.
Solution
Cache the built coinbase per
(height, fees)so short-pollgetblocktemplaterequests within a block reuse it instead of re-running the Sapling/Orchard proof. The ZIP-317 fee-calculation fake coinbase is routed through the same cache (it re-proved too).randomize_coinbase_dataclears it (Regtestgenerateonly).Tests
Unit tests assert a cache hit reuses identical bytes while two fresh shielded builds differ. Verified on a live testnet pool: shielded
getblocktemplatedropped from ~6 core-sec/call to ~0 (cached) — only the first call per block proves.AI Disclosure
Claude Code was used for the ZIP-317-path fix and the end-to-end validation.