Skip to content
Closed
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
1 change: 1 addition & 0 deletions .claude/scheduled_tasks.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"sessionId":"5d11d1e0-123c-4116-9054-2646710b8c68","pid":2222350,"procStart":"11975237","acquiredAt":1780623034771}
2 changes: 1 addition & 1 deletion .codespellrc
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
[codespell]
ignore-words-list = crate,Sur,inout,Groth,groth,re-use,abl,zcash,zcashd,zebrad,zebra,utxo,utxos,nullifier,nullifiers,sapling,orchard,sprout,backpressure,proptest,thiserror,rocksdb,libsecp,fullnode,peerset,threadsafe,unrepresentable,getblocktemplate,syncer,Actix,Akka,mermaid,println,eprintln,usize,nocapture,Parallelizable,invis,UTXO,Zcash,Zaino,Zallet,librustzcash,Mainnet,Testnet,mainnet,testnet,idents,reentrancy,serializable,deserializable,deserialization,zkSNARK,zkSNARKs,lightwalletd,statics,ser,endianity,aranges
ignore-words-list = crate,Sur,inout,Groth,groth,re-use,abl,zcash,zcashd,zebrad,zebra,utxo,utxos,nullifier,nullifiers,sapling,orchard,sprout,backpressure,proptest,thiserror,rocksdb,libsecp,fullnode,peerset,threadsafe,unrepresentable,getblocktemplate,syncer,Actix,Akka,mermaid,println,eprintln,usize,nocapture,Parallelizable,invis,UTXO,Zcash,Zaino,Zallet,librustzcash,Mainnet,Testnet,mainnet,testnet,idents,reentrancy,serializable,deserializable,deserialization,zkSNARK,zkSNARKs,lightwalletd,statics,ser,endianity,aranges,daa
exclude-file = book/mermaid.min.js
skip = ./zebra-rpc/qa/rpc-tests,./supply-chain,./target
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ and this project adheres to [Semantic Versioning](https://semver.org).
- Added bounded Zakura P2P v2 upgrade prelude and control-handshake wire types,
including transcript binding, native-vs-upgraded control validation, and
duplicate-peer handling scaffolding.
- Added bounded Zakura header-sync stream-5 wire messages, stateless header
validation, and the default `network.zakura.header_sync` config surface.
- Include the `zebra-rollback-state` and `zebra-prune-state` utilities alongside
`zebrad` in release Docker images and Docker CI builds.
- Use the `5.0.0-rc.3` release identity for this fork's v5 rollback build.
Expand Down
3 changes: 3 additions & 0 deletions zebra-network/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
legacy stream is dropped, so mutually capable peers move their gossip and
inventory traffic onto Zakura with no configured bootstrap peers. Any neutral
problem (no live endpoint, malformed/rejected prelude) falls back to legacy.
- Added Zakura header-sync stream-5 wire constants, bounded message codecs,
stateless header validation, and the default `network.zakura.header_sync`
config surface.

### Changed

Expand Down
38 changes: 38 additions & 0 deletions zebra-network/src/config/tests/vectors.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
//! Fixed test vectors for zebra-network configuration.

use std::time::Duration;

use static_assertions::const_assert;
use zebra_chain::{
block::Height,
Expand All @@ -11,6 +13,7 @@ use zebra_chain::{

use crate::{
constants::{INBOUND_PEER_LIMIT_MULTIPLIER, OUTBOUND_PEER_LIMIT_MULTIPLIER},
zakura::{DEFAULT_HS_MAX_INFLIGHT, DEFAULT_HS_RANGE},
Config,
};

Expand Down Expand Up @@ -161,6 +164,20 @@ fn p2p_v2_old_config_without_zakura_fields_uses_safe_defaults() {
assert!(config.zakura.bootstrap_peers.is_empty());
assert!(config.zakura.max_connections > 0);
assert!(config.zakura.max_pending_handshakes > 0);
assert_eq!(
config.zakura.header_sync.max_headers_per_response,
DEFAULT_HS_RANGE
);
assert_eq!(
config.zakura.header_sync.max_inflight_requests,
DEFAULT_HS_MAX_INFLIGHT
);
assert_eq!(
config.zakura.header_sync.status_refresh_interval,
Duration::from_secs(30)
);
assert_eq!(config.zakura.header_sync.anchor_height, None);
assert_eq!(config.zakura.header_sync.anchor_hash, None);
}

#[test]
Expand All @@ -185,6 +202,18 @@ fn p2p_v2_unknown_future_config_fields_are_rejected() {
nested.to_string().contains("unknown field"),
"unexpected error for unknown nested field: {nested}",
);

let header_sync = toml::from_str::<Config>(
r#"
[zakura.header_sync]
future_field = true
"#,
)
.expect_err("deny_unknown_fields rejects unknown header-sync fields");
assert!(
header_sync.to_string().contains("unknown field"),
"unexpected error for unknown header-sync field: {header_sync}",
);
}

#[test]
Expand All @@ -203,6 +232,11 @@ fn p2p_v2_config_roundtrip_keeps_dconfig_zakura_fields() {
stream_open_rate_per_second = 11
message_rate_per_second = 13
trace_dir = "target/zakura-test-traces"

[zakura.header_sync]
max_headers_per_response = 333
max_inflight_requests = 9
status_refresh_interval = "45s"
"#,
)
.unwrap();
Expand All @@ -214,6 +248,10 @@ fn p2p_v2_config_roundtrip_keeps_dconfig_zakura_fields() {
assert!(serialized.contains("bootstrap_peers"));
assert!(serialized.contains("max_connections = 7"));
assert!(serialized.contains("trace_dir = \"target/zakura-test-traces\""));
assert!(serialized.contains("[zakura.header_sync]"));
assert!(serialized.contains("max_headers_per_response = 333"));
assert!(serialized.contains("max_inflight_requests = 9"));
assert!(serialized.contains("status_refresh_interval = \"45s\""));
assert_eq!(toml::from_str::<Config>(&serialized).unwrap(), config);
}

Expand Down
2 changes: 1 addition & 1 deletion zebra-network/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ pub use crate::{
isolated::{connect_isolated, connect_isolated_tcp_direct},
meta_addr::{PeerAddrState, PeerSocketAddr},
peer::{Client, ConnectedAddr, ConnectionInfo, HandshakeError, PeerError, SharedPeerError},
peer_set::init,
peer_set::{init, init_with_zakura_header_sync},
policies::RetryLimit,
protocol::{
external::{Version, VersionMessage, MAX_TX_INV_IN_SENT_MESSAGE},
Expand Down
2 changes: 1 addition & 1 deletion zebra-network/src/peer_set.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,4 @@ pub(crate) use limit::{ActiveConnectionCounter, ConnectionTracker};
use inventory_registry::InventoryRegistry;
pub(crate) use set::PeerSet;

pub use initialize::init;
pub use initialize::{init, init_with_zakura_header_sync};
31 changes: 21 additions & 10 deletions zebra-network/src/peer_set/initialize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -111,19 +111,27 @@ where
S::Future: Send + 'static,
C: ChainTip + Clone + Send + Sync + 'static,
{
let (peer_set, address_book, misbehavior_tx, _zakura_endpoint) =
init_with_zakura_endpoint(config, inbound_service, latest_chain_tip, user_agent).await;
let (peer_set, address_book, misbehavior_tx, _zakura_endpoint) = init_with_zakura_header_sync(
config,
inbound_service,
latest_chain_tip,
user_agent,
advertised_services,
None,
)
.await;

(peer_set, address_book, misbehavior_tx)
}

/// Initialize a peer set and expose the live Zakura endpoint (used by the
/// legacy->Zakura upgrade handshake connector).
async fn init_with_zakura_endpoint<S, C>(
/// Initialize a peer set and optionally expose a real-driver Zakura header-sync endpoint.
pub async fn init_with_zakura_header_sync<S, C>(
config: Config,
inbound_service: S,
latest_chain_tip: C,
user_agent: String,
advertised_services: PeerServices,
header_sync_driver_startup: Option<crate::zakura::ZakuraHeaderSyncDriverStartup>,
) -> (
Buffer<BoxService<Request, Response, BoxError>, Request>,
Arc<std::sync::Mutex<AddressBook>>,
Expand All @@ -146,16 +154,19 @@ where
// handshake builder consumes the original below. The factory only runs when
// `v2_p2p` is enabled; otherwise the endpoint is `None` and the clone drops.
let inbound_for_zakura_sink = inbound_service.clone();
let zakura_endpoint =
crate::zakura::spawn_zakura_endpoint(&config, move |supervisor, trace| {
let zakura_endpoint = crate::zakura::spawn_zakura_endpoint_with_header_sync_driver(
&config,
move |supervisor, trace| {
Arc::new(crate::zakura::LegacyGossipSink::spawn_with_trace(
inbound_for_zakura_sink,
supervisor,
trace,
)) as Arc<dyn crate::zakura::Service>
})
.await
.expect("Zakura endpoint should start when P2P v2 is enabled");
},
header_sync_driver_startup,
)
.await
.expect("Zakura endpoint should start when P2P v2 is enabled");

let (
address_book,
Expand Down
9 changes: 7 additions & 2 deletions zebra-network/src/zakura.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ use crate::{
mod discovery;
mod handler;
mod handshake;
mod header_sync;
mod legacy_gossip;
#[cfg(any(test, feature = "zakura-testkit"))]
pub mod testkit;
Expand All @@ -26,11 +27,12 @@ pub mod transport;
pub use discovery::*;
pub use handler::*;
pub use handshake::*;
pub use header_sync::*;
pub use legacy_gossip::*;
pub use trace::{
peer_label as zakura_trace_peer_label, reject_reason_label as zakura_trace_reject_reason_label,
ZakuraTrace, ZakuraTraceEvent, CONN_TABLE, HANDSHAKE_TABLE, LEGACY_REQUEST_TABLE,
RATELIMIT_TABLE, STREAM_TABLE,
ZakuraTrace, ZakuraTraceEvent, CONN_TABLE, HANDSHAKE_TABLE, HEADER_SYNC_TABLE,
LEGACY_REQUEST_TABLE, RATELIMIT_TABLE, STREAM_TABLE,
};
pub use transport::*;

Expand All @@ -49,6 +51,9 @@ pub const IROH_VERSION: &str = "0.92.0";
/// Capability bit for the legacy gossip compatibility service.
pub const ZAKURA_CAP_LEGACY_GOSSIP: u64 = 1 << 0;

/// Capability bit for the native header-sync service.
pub const ZAKURA_CAP_HEADER_SYNC: u64 = 1 << 1;

/// Capability bit for the native discovery service.
pub const ZAKURA_CAP_DISCOVERY: u64 = 1 << 2;

Expand Down
Loading