Skip to content

feat(zcash_local_net)!: prefetch block templates via getblocktemplate long polling - #284

Merged
zancas merged 1 commit into
devfrom
template_prefetch_generate_blocks
Aug 23, 2026
Merged

feat(zcash_local_net)!: prefetch block templates via getblocktemplate long polling#284
zancas merged 1 commit into
devfrom
template_prefetch_generate_blocks

Conversation

@zancas

@zancas zancas commented Aug 23, 2026

Copy link
Copy Markdown
Member

What this changes

Every generated regtest block pays about 2.2 seconds inside zebrad's getblocktemplate handler. The handler builds a fresh shielded coinbase transaction for each template, and the build includes a proof. Zebra already owns the remedy. A getblocktemplate call that presents the previous template's longpollid makes zebrad precompute the next coinbase while it waits for the tip to change. Zebrad then answers the tip change with a provisional empty template built from that precomputation.

Zebrad::generate_blocks now parks that long-poll request after each mined block. Zebrad performs the coinbase proof work while the calling test syncs wallets and runs assertions. The next generate_blocks call consumes the prefetched template instead of paying the template construction inline.

Correctness guards

The prefetched template is an empty provisional block. The harness consumes it only when three conditions hold:

  1. The mempool is empty.
  2. The template's height equals the target height.
  3. The template carries no transactions.

Any other state aborts the prefetch and falls back to the previous fetch-fresh path. The documented contract holds: generated blocks confirm the transactions the server has received.

Measured effect

Measured on zingolib's send_shield_cycle fixture, with per-phase instrumentation, two runs per configuration:

Configuration Mining total Empty separation blocks
Before 27.7–28.9 s 2.4–2.7 s each
After 22.3–24.0 s 0.4–1.6 s each

Transaction-bearing confirmation blocks keep the full path and their cost is unchanged.

API surface

BlockTemplate gains a long_poll_id field (deserialized from longpollid), which is the breaking surface and carries a CHANGELOG entry. submit_template_block splits into fetch_block_template, fetch_block_template_long_poll, and submit_block_from_template. mempool_txids exposes the consumption gate's mempool probe. Existing callers of submit_template_block are unaffected.

🤖 Generated with Claude Code

… long polling

Profiling zingolib's send_shield_cycle round trip showed that every
generated regtest block pays about 2.2 seconds inside zebrad's
getblocktemplate handler, which constructs a fresh shielded coinbase
transaction, proof included, for each template. Zebra already owns the
remedy: a getblocktemplate call that presents the previous template's
longpollid makes zebrad precompute the next coinbase while it waits for
the tip to change, and answer the tip change with a provisional empty
template built from that precomputation.

Zebrad::generate_blocks now parks exactly that long-poll request after
each mined block, so zebrad performs the coinbase proof work while the
calling test syncs wallets and runs assertions. The next
generate_blocks call consumes the prefetched template only when three
guards hold: the mempool is empty, the template's height is the target
height, and the template carries no transactions. Any other state
aborts the prefetch and falls back to the previous fetch-fresh path,
which preserves the documented contract that generated blocks confirm
the transactions the server has received. Measured on send_shield_cycle,
empty separation blocks drop from about 2.5 seconds to between 0.4 and
1.6 seconds, and the fixture's total mining cost falls from about 28 to
23 seconds.

BlockTemplate gains the long_poll_id field, and submit_template_block
splits into fetch_block_template, fetch_block_template_long_poll, and
submit_block_from_template, with mempool_txids exposing the gate's
mempool probe. The field addition is the breaking surface, recorded in
the crate CHANGELOG.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

@zancas zancas left a comment

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Self approved.

@zancas
zancas merged commit 89cf104 into dev Aug 23, 2026
12 checks passed
@zancas
zancas deleted the template_prefetch_generate_blocks branch August 23, 2026 21:42
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.

1 participant