Crate zebra_network

source ·
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 Requests 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:

  • Responses to previously sent outbound Requests, or
  • inbound Requests 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:

Outbound Zcash Connector Service:

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
    • accepts Requests assigned to this peer by the PeerSet
    • sends each request to the peer as Zcash Message
    • waits for the inbound response Message from the peer, and returns it as a Response

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
    • accepts inbound Zcash Messages from this peer
    • handles each message as a Request to the inbound service
    • sends the Response to the peer as Zcash Messages
  • 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”)

Inbound Network Service:

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§

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.
  • meta_addr 🔒
    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.
  • Types used in the definition of Request, Response, and VersionMessage.

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 implements Error.
  • 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§

Functions§

  • Transform a PeerSocketAddr into a canonical Zebra PeerSocketAddr, 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, and latest_chain_tip.

Type Aliases§

  • Type alias to make working with tower traits easier.