feat(network): run the experimental v2 (QUIC) transport in the peer set - #11277
feat(network): run the experimental v2 (QUIC) transport in the peer set#11277arya2 wants to merge 7 commits into
Conversation
And one more auto-invalidated finding. Analyzed five files, diff |
Merge Protections🔴 1 of 1 protections blocking · waiting on ⛓️ dependency
🔴 ⛓️ Depends-On RequirementsWaiting for
This rule is failing.Requirement based on the presence of
|
b5486d6 to
c8c2e6d
Compare
A node that only dials version 2 to its configured peers cannot grow the version 2 network: relayed addresses carry no indication of which transports their peer accepts, so every peer learned from the network is dialed over the legacy protocol forever. Learn reachability by dialing. The peer book records which transports each address has answered on, the crawler dials version 2 wherever a peer is known to accept it, and a small share of peers with unknown version 2 reachability are probed before their legacy dial. A probe is one QUIC initial packet to an address that already passed the book's filters, in place of the TCP SYN the node would have sent anyway, and every failure falls back to the legacy transport immediately -- so a node is never worse off than a legacy-only node. Requests that only version 2 peers can answer are marked, so the peer set routes them to a version 2 peer instead of spending the request on a legacy peer that would refuse it. Reachability is keyed by address, not by transport: a peer banned over one transport cannot return over the other, and cannot occupy two address book entries by being reachable two ways. Reachability is not persisted across restarts, and is learned only from outbound dials. book/src/dev/dual-protocol-networking.md records that and the rest of what is left before the network upgrade.
… watch cells Zebra's concurrency policy forbids mutexes in new code. Replace every mutex the version 2 transport work added: - SharedConnectionCounter now counts with atomic slots; its trackers hold a slot guard, and try_track_connection reserves a slot in one atomic update, so the transports' accept loops cannot overshoot a shared limit. - HandshakeNonces stores the nonce set in a watch channel used as a cell: registration mutates inside send_modify, and the self-connection check reads a borrow snapshot. - The v2 connection's shared per-connection caches (pushed and sent blocks, reconstruction and mempool mirrors, address cache, token bucket, and the announcement singleton set) live in watch-backed SharedCell values with the same atomic-update discipline.
…imiter The two transports' accept loops checked the shared inbound counter and then reserved a slot as separate steps, so both could pass the check at the last free slot and overshoot the configured limit; and each kept its own per-IP limiter, letting one IP hold max_connections_per_ip connections on TCP plus the same again on QUIC. Reserve the slot in one atomic counter update, and share one watch-backed per-IP limiter between the listeners.
…v2 handshakes Outbound v2 requests run concurrently, so a peer that stalled on one request while several were in flight would trip the consecutive-timeout disconnect when their timers fired together, even if it had just answered other requests. Snapshot the response count when each request is sent, and only count a timeout when no response at all arrived while it was outstanding. Also supervise the accept loop's handshake tasks like the legacy listener, so their panics stop the node instead of silently reducing connectivity; record the terminal connection-attempt metric for both stages of inbound v2 connections; and yield after each accepted connection, matching the legacy listener's starvation protection.
…ban and gossip gaps The blocking actor thread inhibited tokio auto-advance, hanging paused-clock tests. Sub-threshold misbehavior reports re-created banned peers' book entries, expired bans never left the published bans watch, gossip-bucket admission never ran on the production intake path, ban removals skipped the recently-live refresh, and bucket evictions cleared the per-IP most-recent cache for entries that were not cached.
c8c2e6d to
bcbfabc
Compare
Motivation
Final PR of the five-PR stack implementing the draft version 2 Zcash P2P network protocol (zcash/zips#1344). This PR wires the v2 transport into the peer set behind experimental config options, and removes the stack's
#[allow(dead_code)]scaffolding.Solution
peer_set/initialize/v2_transport.rs: a QUIC endpoint that accepts inbound v2 connections on the UDP port of the listen address (whennetwork.experimental_v2_listenis enabled) and maintains connections tonetwork.initial_v2_peers, redialling them when they fail or disconnect.Clients and join the peer set alongside legacy peers; connection attempt metrics are recorded for both stages of inbound v2 connections.network.experimental_v2_listenandnetwork.initial_v2_peers.Tests
zebra-networksuite passes (260 tests);cargo clippy -p zebra-network --all-targetswarning-free;zebradbuilds; config compatibility test updated.Specifications & References
Follow-up Work
V2Protocol/V2Internalvariants.AI Disclosure
PR Checklist
type(scope): description