Skip to content

feat(network): Batches and parallelizes block downloads#10442

Open
arya2 wants to merge 13 commits intomainfrom
syncer-performance
Open

feat(network): Batches and parallelizes block downloads#10442
arya2 wants to merge 13 commits intomainfrom
syncer-performance

Conversation

@arya2
Copy link
Copy Markdown
Contributor

@arya2 arya2 commented Mar 31, 2026

Motivation

We want to improve Zebra's initial sync performance.

Solution

See commit messages for more information

Tests

Running full Testnet sync locally.

Follow-up Work

  • Sync-specific peer quality tracking, P2C uses EWMA latency for load, but during sync what matters is throughput and reliability
  • Switch from TCP to QUIC
  • Peer chain height is known but unused for sync routing
  • Peers only process one request at a time, but Zebra could send several requests at once rather than sending once, waiting for a response, etc.

AI Disclosure

  • No AI tools were used in this PR
  • AI tools were used: All changes were Opus 4.6 except updating the latency threshold from 0.95 to 0.9 somewhere.

PR Checklist

  • The PR name is suitable for the release notes.
  • The PR follows the contribution guidelines.
  • This change was discussed in an issue or with the team beforehand.
  • The solution is tested.
  • The documentation and changelogs are up to date.

@arya2 arya2 marked this pull request as ready for review April 1, 2026 18:34
@arya2 arya2 marked this pull request as draft April 3, 2026 19:19
…ing downloads

Move download_batch from a free function to an instance method on Downloads,
add pending_download_hashes tracking to prevent duplicate downloads, and
handle duplicate block verification gracefully instead of panicking.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR improves Zebra's initial block sync performance by batching and parallelizing block downloads. Instead of requesting blocks one-at-a-time sequentially, the syncer now groups blocks into adaptively-sized batches, sends multiple batches concurrently, and overlaps download progress with tip discovery. This reduces per-request overhead, maximizes network utilization, and eliminates pipeline stalls. The PR also improves peer routing during sync: multi-block requests target peers at or above the current chain height, and tip discovery requests spread fanout across distinct peers for better diversity.

Changes:

  • Implement batched block downloads with per-block retry logic and dynamic batch sizing based on observed block sizes
  • Run multiple batches concurrently using SelectAll to interleave block arrivals and prevent waiting for entire batches
  • Extend tips proactively while downloads are in-flight, and drain completed downloads during tip discovery, eliminating pipeline stalls
  • Add peer routing logic to prefer peers at/above chain tip height for multi-block requests and distinct peers for tip-discovery fanout
  • Update integration tests to verify batched request behavior and concurrent verification

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
zebrad/src/components/sync/downloads.rs Implements batched download logic with dynamic batch sizing, retry mechanism, and block size tracking for adaptive batching
zebrad/src/components/sync.rs Integrates batched downloads, adds drain_ready_downloads() to pipeline during tip discovery, and refactors tip extension to run concurrently
zebra-network/src/peer_set/set.rs Adds peer routing for multi-block requests (targeting tall peers) and tip-discovery requests (targeting distinct peers), with recent-peer tracking
zebra-network/src/peer/load_tracked_client.rs Adds remote_height() method to expose peer's reported chain height for peer selection during sync
zebrad/src/components/sync/tests/vectors.rs Updates test expectations to verify batched request behavior instead of sequential per-block requests

// Report block size for adaptive batch sizing.
{
use zebra_chain::serialization::ZcashSerialize;
let _ = block_size_sender.send(block.zcash_serialized_size());
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Record the number of every hundredth block. Start at a random number in 0..99, i.e. compute and send the serialized size if block.height + random_num % 100 == 0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

C-feature Category: New features P-Medium ⚡

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants