Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions zebra-network/src/zakura/block_sync/admission.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,17 +30,17 @@ pub(super) struct AdmissionDecision {
pub(super) max_request_bytes: u64,
}

// Return the highest height that can be rescued by a floor-rescue request.
pub(super) fn max_floor_rescue_start_height(download_floor: block::Height) -> block::Height {
/// Return the highest start height that can be rescued by a floor request.
pub(super) fn floor_rescue_high(download_floor: block::Height) -> block::Height {
next_height(download_floor).unwrap_or(download_floor)
}

pub(super) fn request_priority(
download_floor: block::Height,
start_height: block::Height,
) -> RequestPriority {
// This is <= because down
if start_height <= max_floor_rescue_start_height(download_floor) {
// The next height above the floor can still unblock the current floor.
if start_height <= floor_rescue_high(download_floor) {
RequestPriority::Floor
} else {
RequestPriority::AboveFloor
Expand Down
2 changes: 1 addition & 1 deletion zebra-network/src/zakura/block_sync/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ pub const MAX_BS_INFLIGHT_REQUESTS: u32 = 32_768;
/// Default total response byte target advertised per range response.
pub const DEFAULT_BS_MAX_RESPONSE_BYTES: u32 = 32 * 1024 * 1024;
/// Default global byte budget reserved for later block-download scheduling.
pub const DEFAULT_BS_MAX_INFLIGHT_BLOCK_BYTES: u64 = 2 * 1024 * 1024 * 1024;
pub const DEFAULT_BS_MAX_INFLIGHT_BLOCK_BYTES: u64 = 6 * 1024 * 1024 * 1024;
/// Worst-case serialized bytes reserved per requested block body.
///
/// Block-sync reserves this much per requested block at send time and only ever
Expand Down
44 changes: 21 additions & 23 deletions zebra-network/src/zakura/block_sync/peer_routine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,7 @@ use tokio_util::sync::CancellationToken;

use super::events::RoutineToReactor;
use super::{
admission::{
admission_decision, max_floor_rescue_start_height, AdmissionSnapshot, RequestPriority,
},
admission::{admission_decision, floor_rescue_high, AdmissionSnapshot, RequestPriority},
peer_registry::{hard_outbound_capacity, PeerRegistry},
pipe::block_sync_guard,
reactor::{
Expand Down Expand Up @@ -570,11 +568,11 @@ impl PeerRoutine {
let max_count = local_peer_count_cap;
let response_byte_cap = u64::from(self.max_response_bytes.max(1));

let sequencer_view = *self.sequencer_view.borrow();
let floor_high = max_floor_rescue_start_height(sequencer_view.download_floor);
let view = *self.sequencer_view.borrow();
let floor_high = floor_rescue_high(view.download_floor);
let mut request_priority = RequestPriority::Floor;
let (reserved_above_floor_bytes, reserved_above_floor_blocks) =
self.work.reserved_above(sequencer_view.download_floor);
self.work.reserved_above(view.download_floor);
let mut items = if servable_low <= floor_high
&& self
.work
Expand All @@ -589,11 +587,11 @@ impl PeerRoutine {
admission_decision(
&self.config,
AdmissionSnapshot {
download_floor: sequencer_view.download_floor,
reorder_buffered_bytes: sequencer_view.reorder_buffered_bytes,
reorder_buffered_blocks: sequencer_view.reorder_len,
applying_buffered_bytes: sequencer_view.applying_buffered_bytes,
applying_buffered_blocks: sequencer_view.applying_len,
download_floor: view.download_floor,
reorder_buffered_bytes: view.reorder_buffered_bytes,
reorder_buffered_blocks: view.reorder_len,
applying_buffered_bytes: view.applying_buffered_bytes,
applying_buffered_blocks: view.applying_len,
sequencer_input_queued_bytes: self
.sequencer_input_bytes
.load(std::sync::atomic::Ordering::Relaxed),
Expand Down Expand Up @@ -629,11 +627,11 @@ impl PeerRoutine {
let Some(decision) = admission_decision(
&self.config,
AdmissionSnapshot {
download_floor: sequencer_view.download_floor,
reorder_buffered_bytes: sequencer_view.reorder_buffered_bytes,
reorder_buffered_blocks: sequencer_view.reorder_len,
applying_buffered_bytes: sequencer_view.applying_buffered_bytes,
applying_buffered_blocks: sequencer_view.applying_len,
download_floor: view.download_floor,
reorder_buffered_bytes: view.reorder_buffered_bytes,
reorder_buffered_blocks: view.reorder_len,
applying_buffered_bytes: view.applying_buffered_bytes,
applying_buffered_blocks: view.applying_len,
sequencer_input_queued_bytes: self
.sequencer_input_bytes
.load(std::sync::atomic::Ordering::Relaxed),
Expand Down Expand Up @@ -1188,17 +1186,17 @@ impl PeerRoutine {
self.record_received(serialized_bytes);
self.trace_body_received(height, serialized_bytes, None, None, None);

let view = *self.sequencer_view.borrow();
let sequencer_view = *self.sequencer_view.borrow();
let (reserved_above_floor_bytes, reserved_above_floor_blocks) =
self.work.reserved_above(view.download_floor);
self.work.reserved_above(sequencer_view.download_floor);
let Some(decision) = admission_decision(
&self.config,
AdmissionSnapshot {
download_floor: view.download_floor,
reorder_buffered_bytes: view.reorder_buffered_bytes,
reorder_buffered_blocks: view.reorder_len,
applying_buffered_bytes: view.applying_buffered_bytes,
applying_buffered_blocks: view.applying_len,
download_floor: sequencer_view.download_floor,
reorder_buffered_bytes: sequencer_view.reorder_buffered_bytes,
reorder_buffered_blocks: sequencer_view.reorder_len,
applying_buffered_bytes: sequencer_view.applying_buffered_bytes,
applying_buffered_blocks: sequencer_view.applying_len,
sequencer_input_queued_bytes: self
.sequencer_input_bytes
.load(std::sync::atomic::Ordering::Relaxed),
Expand Down
2 changes: 1 addition & 1 deletion zebra-network/src/zakura/block_sync/reorder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ impl ReorderBuffer {
}

/// Highest buffered height, if any. The shed-for-floor-starvation path drops
/// this (the body furthest from the download floor) to free budget for a
/// this (the body furthest from the committed floor) to free budget for a
/// lower, commit-unblocking request.
pub(super) fn max_height(&self) -> Option<block::Height> {
self.blocks.keys().next_back().copied()
Expand Down
32 changes: 16 additions & 16 deletions zebra-network/src/zakura/block_sync/sequencer_task.rs
Original file line number Diff line number Diff line change
Expand Up @@ -134,12 +134,6 @@ pub(super) enum SequencerControlInput {
/// the peer-outstanding clause of `reset_tip_conflicts_with_local_work`.
peer_outstanding_conflicts_at_tip: bool,
},
/// Synchronously pop the speculative high tail until a floor request can
/// reserve `needed_bytes`, then wake the requester to retry the reservation.
FundFloorReservation {
needed_bytes: u64,
reply: oneshot::Sender<bool>,
},
/// A verifier apply completion.
ApplyFinished {
token: BlockApplyToken,
Expand All @@ -148,6 +142,12 @@ pub(super) enum SequencerControlInput {
result: BlockApplyResult,
local_frontier: Option<BlockSyncFrontiers>,
},
/// Synchronously pop the speculative high tail until a floor request can
/// reserve `needed_bytes`, then wake the requester to retry the reservation.
FundFloorReservation {
needed_bytes: u64,
reply: oneshot::Sender<bool>,
},
}

/// The progress view the reactor reacts to. A `watch` (latest-wins) send never
Expand Down Expand Up @@ -349,6 +349,16 @@ impl SequencerTask {
.await;
true
}
SequencerControlInput::ApplyFinished {
token,
height,
hash,
result,
local_frontier,
} => {
self.handle_apply_finished(token, height, hash, result, local_frontier)
.await
}
SequencerControlInput::FundFloorReservation {
needed_bytes,
reply,
Expand All @@ -362,16 +372,6 @@ impl SequencerTask {
let _ = reply.send(self.budget.available() >= needed_bytes);
shed
}
SequencerControlInput::ApplyFinished {
token,
height,
hash,
result,
local_frontier,
} => {
self.handle_apply_finished(token, height, hash, result, local_frontier)
.await
}
}
}

Expand Down
18 changes: 9 additions & 9 deletions zebra-network/src/zakura/handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,12 +67,12 @@ use crate::{
};
use crate::{BoxError, Config, MAX_TX_INV_IN_SENT_MESSAGE};

/// Conservative default for total Zakura connections when P2P v2 is enabled.
pub const DEFAULT_ZAKURA_MAX_CONNECTIONS: usize = 32;
/// Conservative default for simultaneous Zakura control handshakes.
pub const DEFAULT_ZAKURA_MAX_PENDING_HANDSHAKES: usize = 8;
/// Conservative default for stream-open churn per connection.
pub const DEFAULT_ZAKURA_STREAM_OPEN_RATE_PER_SECOND: u32 = 16;
/// Default total Zakura connections when P2P v2 is enabled.
pub const DEFAULT_ZAKURA_MAX_CONNECTIONS: usize = 256;
/// Default simultaneous Zakura control handshakes.
pub const DEFAULT_ZAKURA_MAX_PENDING_HANDSHAKES: usize = 32;
/// Default stream-open churn per connection.
pub const DEFAULT_ZAKURA_STREAM_OPEN_RATE_PER_SECOND: u32 = 32;
/// Per-kind inbound message rate per connection.
///
/// This is a generous universal cap: block-sync legitimately delivers
Expand Down Expand Up @@ -111,11 +111,11 @@ pub const DEFAULT_ZAKURA_KEEP_ALIVE_INTERVAL: Duration = Duration::from_secs(10)
/// reclaim the slot without disturbing active transfers.
pub const ZAKURA_DUPLICATE_EVICT_MIN_AGE: Duration = Duration::from_secs(300);
/// QUIC stream receive window used by Zakura endpoints.
pub const DEFAULT_ZAKURA_STREAM_RECEIVE_WINDOW: u32 = 3 * 1024 * 1024;
pub const DEFAULT_ZAKURA_STREAM_RECEIVE_WINDOW: u32 = 32 * 1024 * 1024;
/// QUIC connection receive window used by Zakura endpoints.
pub const DEFAULT_ZAKURA_RECEIVE_WINDOW: u32 = 16 * 1024 * 1024;
pub const DEFAULT_ZAKURA_RECEIVE_WINDOW: u32 = 32 * 1024 * 1024;
/// QUIC send window used by Zakura endpoints.
pub const DEFAULT_ZAKURA_SEND_WINDOW: u64 = 16 * 1024 * 1024;
pub const DEFAULT_ZAKURA_SEND_WINDOW: u64 = 32 * 1024 * 1024;
/// Initial backoff before re-dialing a configured Zakura bootstrap peer.
pub const DEFAULT_ZAKURA_REDIAL_INITIAL_BACKOFF: Duration = Duration::from_secs(1);
/// Maximum backoff between re-dials of a configured Zakura bootstrap peer.
Expand Down
169 changes: 169 additions & 0 deletions zebrad/tests/common/configs/v5.0.0-rc.4.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
# Default configuration for zebrad.
#
# This file can be used as a skeleton for custom configs.
#
# Unspecified fields use default values. Optional fields are Some(field) if the
# field is present and None if it is absent.
#
# This file is generated as an example using zebrad's current defaults.
# You should set only the config options you want to keep, and delete the rest.
# Only a subset of fields are present in the skeleton, since optional values
# whose default is None are omitted.
#
# The config format (including a complete list of sections and fields) is
# documented here:
# https://docs.rs/zebrad/latest/zebrad/config/struct.ZebradConfig.html
#
# CONFIGURATION SOURCES (in order of precedence, highest to lowest):
#
# 1. Environment variables with ZEBRA_ prefix (highest precedence)
# - Format: ZEBRA_SECTION__KEY (double underscore for nested keys)
# - Examples:
# - ZEBRA_NETWORK__NETWORK=Testnet
# - ZEBRA_RPC__LISTEN_ADDR=127.0.0.1:8232
# - ZEBRA_STATE__CACHE_DIR=/path/to/cache
# - ZEBRA_TRACING__FILTER=debug
# - ZEBRA_METRICS__ENDPOINT_ADDR=0.0.0.0:9999
#
# 2. Configuration file (TOML format)
# - At the path specified via -c flag, e.g. `zebrad -c myconfig.toml start`, or
# - At the default path in the user's preference directory (platform-dependent, see below)
#
# 3. Hard-coded defaults (lowest precedence)
#
# The user's preference directory and the default path to the `zebrad` config are platform dependent,
# based on `dirs::preference_dir`, see https://docs.rs/dirs/latest/dirs/fn.preference_dir.html :
#
# | Platform | Value | Example |
# | -------- | ------------------------------------- | ---------------------------------------------- |
# | Linux | `$XDG_CONFIG_HOME` or `$HOME/.config` | `/home/alice/.config/zebrad.toml` |
# | macOS | `$HOME/Library/Preferences` | `/Users/Alice/Library/Preferences/zebrad.toml` |
# | Windows | `{FOLDERID_RoamingAppData}` | `C:\Users\Alice\AppData\Local\zebrad.toml` |

[consensus]
checkpoint_sync = true
disable_vct_fast_sync = false

@evan-forbes evan-forbes Jun 27, 2026

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

seems fine for the test failure, but ofc I have less context here

also in a future pr, we could change this to avoid a double negative I think. we could just have the default be

vct_fast_sync = true

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

happy to add this to the flups at the end if reviewers agree

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

sgtm


[health]
enforce_on_test_networks = false
min_connected_peers = 1
ready_max_blocks_behind = 2
ready_max_tip_age = "5m"

[mempool]
eviction_memory_time = "1h"
max_datacarrier_bytes = 83
tx_cost_limit = 80000000

[metrics]

[mining]
internal_miner = false

[network]
cache_dir = true
crawl_new_peer_interval = "1m 1s"
initial_mainnet_peers = [
"dnsseed.str4d.xyz:8233",
"dnsseed.z.cash:8233",
"mainnet.seeder.shieldedinfra.net:8233",
"mainnet.seeder.zfnd.org:8233",
]
initial_testnet_peers = [
"dnsseed.testnet.z.cash:18233",
"testnet.seeder.zfnd.org:18233",
]
legacy_p2p = true
listen_addr = "[::]:8233"
max_connections_per_ip = 1
network = "Mainnet"
peerset_initial_target_size = 100
v2_p2p = true

[network.zakura]
bootstrap_peers = []
listen_addr = "0.0.0.0:8234"
max_connections = 256
max_pending_handshakes = 32
message_rate_per_second = 2048
stream_open_rate_per_second = 32

[network.zakura.block_sync]
fanout = 1
floor_peer_avoid_cooldown = "8s"
floor_watchdog_tick = "1s"
initial_inflight_requests = 64
max_blocks_per_response = 1
max_inflight_block_bytes = 6442450944
max_inflight_requests = 32000
max_reorder_lookahead_blocks = 4096
max_reorder_lookahead_bytes = 6408896512
max_response_bytes = 33554432
max_submitted_block_applies = 400
request_timeout = "8s"
size_deviation_tolerance = 200
status_refresh_interval = "30s"

[network.zakura.block_sync.peer_limits]
inbound_queue_depth = 128
max_inbound_peers = 256
max_outbound_peers = 256
max_pending_escalations = 32
outbound_queue_depth = 128

[network.zakura.header_sync]
accept_new_blocks = true
max_headers_per_response = 1000
max_inflight_requests = 10
status_refresh_interval = "30s"

[network.zakura.header_sync.peer_limits]
inbound_queue_depth = 128
max_inbound_peers = 256
max_outbound_peers = 256
max_pending_escalations = 32
outbound_queue_depth = 128

[rpc]
cookie_dir = "cache_dir"
cookie_file_name = ".cookie"
debug_force_finished_sync = false
enable_cookie_auth = true
max_response_body_size = 52428800
parallel_cpu_threads = 0

[state]
cache_dir = "cache_dir"
debug_skip_non_finalized_state_backup_task = false
delete_old_database = true
ephemeral = false
should_backup_non_finalized_state = true
storage_mode = "archive"

[sync]
checkpoint_verify_concurrency_limit = 1000
download_concurrency_limit = 100
full_verify_concurrency_limit = 20
parallel_cpu_threads = 0
zakura_block_apply_concurrency_limit = 32

[tracing]
buffer_limit = 128000
force_use_color = false
use_color = true
use_journald = false

[zcashd_compat]
cookie_dir = "cache_dir"
cookie_file_name = ".zcashd-compat.cookie"
enable_cookie_auth = true
enabled = false
manage_zcashd = false
restart_backoff = "2s"
restart_backoff_max = "5m"
restart_reset_after = "1h"
shutdown_grace_period = "5m"
startup_delay = "1s"
unsafe_allow_remote_http = false
zcashd_extra_args = []
zcashd_source = "path"