Expand description
Networking code for Zebra.
§Network Protocol Design
The Zcash network protocol is inherited from Bitcoin, which uses a stateful network protocol in which messages can arrive in any order (even before a handshake is complete!). The same Bitcoin message may be a request or a response depending on context.
§Achieving Concurrency
This crate translates the legacy Zcash network protocol
into a stateless, request-response oriented protocol defined by
the Request
and Response
enums. zebra-network
completely
encapsulates all peer handling code behind a single
[tower::Service
] representing “the network”, which load-balances
outbound Request
s over available peers.
Unlike the underlying legacy network protocol, Zebra’s PeerSet
[tower::Service
] guarantees that each Request
future will resolve to the
correct Response
, rather than an unrelated Response
message.
Each peer connection is handled by a distinct peer::Connection
task.
The Zcash network protocol is bidirectional, so Zebra interprets incoming
Zcash messages as either:
Response
s to previously sent outboundRequest
s, or- inbound
Request
s to an internal [tower::Service
] representing “this node”.
All connection state is isolated to individual peers, so this
design is structurally immune to the recent ping
attack.
§Connection Pool
Because [tower::Service
]s provide backpressure information, we
can dynamically manage the size of the connection pool according
to inbound and outbound demand. The inbound service can shed load
when it is not ready for requests, causing those peer connections
to close, and the outbound service can connect to additional peers
when it is overloaded.
§zebra-network
Structure
[zebra-network::init
] is the main entry point for zebra-network
.
It uses the following services, tasks, and endpoints:
§Low-Level Network Connections
Inbound Zcash Listener Task:
- accepts inbound connections on the listener port
- initiates Zcash
peer::Handshake
s, which createspeer::Connection
tasks for each inbound connection
Outbound Zcash Connector Service:
- initiates outbound connections to peer addresses
- initiates Zcash
peer::Handshake
s, which createspeer::Connection
tasks for each outbound connection
Zebra uses direct TCP connections to share blocks and mempool transactions with other peers.
The isolated
APIs provide anonymised TCP and Tor
connections to individual peers.
These isolated connections can be used to send user-generated transactions anonymously.
Tor connections are currently disabled until arti-client
’s dependency x25519-dalek v1.2.0
is updated to a higher version. See #5492.
§Individual Peer Connections
Each new peer connection spawns the following tasks:
peer::Client
Service:
- provides an interface for outbound requests to an individual peer
peer::Connection
Service:
- manages connection state: awaiting a request, or handling an inbound or outbound response
- provides an interface for inbound requests from an individual peer
- drops peer connections if the inbound request queue is overloaded
Since the Zcash network protocol is bidirectional, inbound and outbound connections are handled using the same logic.
§Connection Pool
PeerSet
Network Service:
- provides an interface for other services and tasks running within this node
to make requests to remote peers (“the rest of the network”)
- accepts
Request
s from the local node - sends each request to a
peer::Client
using randomised load-balancing - returns the
Response
from thepeer::Client
- accepts
Inbound Network Service:
- provides an interface for remote peers to request data held by this node
- accepts inbound Zcash
Request
s frompeer::Connection
s - handles each message as a
Request
to the local node - sends the
Response
to thepeer::Connection
- accepts inbound Zcash
Note: the inbound service is implemented by the [zebra-network::init
] caller.
Peer Inventory Service:
- tracks gossiped
inv
advertisements for each peer - updated before each
PeerSet
request is processed - tracks missing inventory for each peer
- used by the
PeerSet
to route block and transaction requests to peers that have the requested data
§Peer Discovery
AddressBook
Service:
- maintains a list of peer addresses and associated connection attempt metadata
- address book metadata is used to prioritise peer connection attempts
- updated by an independent thread based on peer connection status changes
- caches peer addresses to disk regularly using an independent task
Initial Seed Peer Task: On startup:
- loads seed peers from the config, resolving them via DNS if required
- loads cached peer addresses from disk
- initiates new outbound peer connections to seed and cached peers
- adds seed and cached peer addresses to the
AddressBook
Peer Crawler Task:
- discovers new peer addresses by sending
Addr
requests to connected peers - initiates new outbound peer connections in response to application demand
Re-exports§
pub use crate::address_book_peers::AddressBookPeers;
pub use crate::config::CacheDir;
pub use crate::config::Config;
Modules§
- The
AddressBook
manages information about what peers exist, when they were seen, and what services they provide. - A AddressBookPeers trait for getting the
MetaAddr
of recently live peers. - The timestamp collector collects liveness information from peers.
- Configuration for Zebra’s network communication.
- Definitions of Zebra network constants, including:
- isolated 🔒Creating isolated connections to specific peers.
- An address-with-metadata type used in Bitcoin networking.
- peer 🔒Peer connection handling.
- An async task that regularly updates the peer cache on disk from the current address book.
- peer_
set 🔒 - policies 🔒
- protocol 🔒Zcash network protocol handling.
Structs§
- A database of peer listener addresses, their advertised services, and information on when they were last seen.
- The “client” duplex half of a peer connection.
- The metadata for a peer connection.
- A thin wrapper for
SocketAddr
which hides peer IP addresses in logs and metrics. - A very basic retry policy with a limited number of retry attempts.
- A wrapper around
Arc<PeerError>
that implementsError
. - A protocol version number.
- A
version
message.
Enums§
- The peer address that we are handshaking with.
- An error during a handshake with a remote peer.
- A generic peer inventory response status.
- Peer connection state, based on our interactions with the peer.
- An error related to peer connection handling.
- A network request, represented in internal format.
- A response to a network request, represented in internal format.
Constants§
- The maximum number of transaction inventory items in a network message received from a peer.
Functions§
- Transform a
PeerSocketAddr
into a canonical ZebraPeerSocketAddr
, converting IPv6-mapped IPv4 addresses, and removing IPv6 scope IDs and flow information. - Creates a Zcash peer connection using the provided data stream. This connection is completely isolated from all other node state.
- Creates a direct TCP Zcash peer connection to
addr
. This connection is completely isolated from all other node state. - Creates an isolated Zcash peer connection using the provided data stream. This function is for testing purposes only.
- Creates an isolated Zcash peer connection using the provided data stream. This function is for testing purposes only.
- Initialize a peer set, using a network
config
,inbound_service
, andlatest_chain_tip
.
Type Aliases§
- Type alias to make working with tower traits easier.