Skip to main content
The Parallax client integrates the Tor network following Bitcoin Core’s model. A Tor-enabled node runs:
  • SOCKS5-proxied outbound connections (--proxy, --onion) with per-connection stream isolation, so Tor places every peer on its own circuit;
  • a Tor v3 onion service for the P2P listener (--listenonion, on by default), created through the Tor control port and reachable with no port forwarding;
  • onion address storage and gossip: Tor v3 addresses flow through the addrman and parallax-disc/1 like any other peer address on nodes that can dial them;
  • an onion-only posture (--onlynet=onion) in which the node never touches clearnet.
Operator setup is documented in Running over Tor; this page specifies the protocol behavior.

Addressing

parallax-disc/1 carries addresses in BIP155 form, and Tor v3 is one of its networks: network id 0x04 with the 32-byte ed25519 service public key as the address body. The .onion hostname (base32 of key, checksum and version per Tor’s rend-spec-v3) is reconstructed whenever an address is rendered or handed to the SOCKS5 proxy; only the key travels on the wire and in addrbook.rlp. The wire format, persistence schema and relay rules are identical for every node version — nodes without a Tor route relay onion entries at the reduced unreachable-network fanout without storing them, so onion addresses propagate through the whole network regardless of how many nodes dial them.

Reachability

Which networks a node stores and dials is local configuration, Bitcoin Core’s IsReachable model. IPv4 and IPv6 are reachable by default, minus --onlynet exclusions. Onion is reachable when an onion route exists:
  • an explicit --onion=<ip:port> proxy, or
  • --proxy=<ip:port>, which routes all networks, or
  • the route auto-discovered from the Tor daemon: when --onion is unset and the control port is available, the node asks the daemon for its SOCKS listener (GETINFO net/listeners/socks) and installs it as the onion proxy, with stream isolation always on. An explicit --onion value suppresses the discovery, and --onion=0 forbids onion outbound entirely.
The gossip storage gate, dial scheduler, feeler, anchor replay and bootnode ingest all consult the same policy. Reachability can change at runtime: a node started before its Tor daemon begins with onion unreachable and flips it the moment the control port answers, at which point the bootstrap work that had to be skipped — ingesting that network’s bootnodes, replaying its anchors, re-running the cold-start address fetch — is replayed. --onlynet restricts automatic outbound connections only. Operator-initiated dials (addnode, addPeer, dialV2) and configured static nodes reach any network the node has a route to, as in Core, where -onlynet governs the connections the node makes on its own.

Keeping clearnet off the wire

A node whose clearnet traffic is proxied (--proxy) or which has no reachable clearnet network at all (--onlynet=onion) suppresses every subsystem that would reveal its address regardless of the proxy: the discv4 UDP socket is never opened (Tor carries no UDP, so answering a probe would tie the node’s onion presence to its IP), enrtree discovery does not resolve, UPnP/NAT-PMP announcements are disabled, and DNS-seed bootstrapping either goes through the proxy or is skipped. Peer connections are unaffected — they are what the proxy is for. --onion alone does not trigger any of this: it routes only .onion targets, so a dual-stack node using Tor to reach onion peers keeps its ordinary clearnet discovery intact.

Identity and handshake

Onion entries carry KeyType=0x00 and connect exclusively through the BIP324-style v2 handshake. No persistent identity is lost by this: the v2 handshake authenticates “whoever answered at this address”, and a Tor v3 rendezvous cryptographically authenticates the endpoint against the ed25519 key embedded in the address itself — a stronger binding than an ip:port dial provides. Onion targets are always passed to the SOCKS5 proxy as hostnames; no name resolution happens locally. With --proxy set, DNS-seed bootstrapping likewise moves off the system resolver: seed hostnames are handed to the proxy as connection targets and the resulting sessions warm the addrbook through the ordinary GetPeers exchange.

The onion service

With --listenonion, the node maintains a control-port session to the Tor daemon (--torcontrol, cookie or --torpassword authentication) and creates an ephemeral v3 onion service targeting its P2P listener. The service key persists in <datadir>/onion_v3_private_key, keeping the onion address stable across restarts. The service always advertises the network default port (32110) regardless of the local listen port, so nodes on non-standard ports are not distinguished by their port number. If the control connection drops, Tor discards the service; the client reconnects with exponential backoff and re-creates it.

Peer network classification

Every peer has an effective network. Outbound peers take their dial target’s network. Inbound streams arriving from loopback while the onion service is active are classified as onion — the Tor daemon delivers rendezvous streams from 127.0.0.1 (Bitcoin Core’s ConnectedThroughNetwork heuristic). The classification drives:
  • Address observations. Onion and proxied peers never contribute to the self-address quorum, and the YourAddr sent to a proxied peer is all-zero: what such sessions observe is the proxy, not the node’s address.
  • Outbound diversity. Network-group accounting keys on the dial target, never the socket address (which under a proxy is the proxy itself). Onion addresses group by the top 4 bits of the service key, the same rule the addrman uses for bucketing.
  • Eviction. Inbound onion peers arrive from loopback and fall under the localhost protection reservation in the inbound eviction algorithm.
  • addrman feedback and anchors. Success and failure credit, and block-relay-only anchor persistence, key on the dial target, so proxied and onion entries age correctly and onion anchors replay across restarts (skipped when the restarted node has no onion route).
admin_peers exposes the classification: network.network names the transport (ipv4, ipv6, onion) and network.address the logical dial target, while remoteAddress remains the socket-level endpoint. Inbound onion peers have no logical address — they are anonymous by design.

Self-advertisement

The disc greeting advertises the node’s own addresses per network. Sessions with onion peers are told only the onion address: a node’s IP never crosses a Tor circuit, so an onion-only operator’s IP cannot leak to the peers most likely to be observing. Clearnet sessions receive the quorum-confirmed IP claim plus the onion address; peers without a Tor route relay the onion entry onward at the unreachable fanout. The onion self-address is authoritative — it comes from the control port’s ADD_ONION response and bypasses the observation quorum, like an operator-supplied --nat extip: address.

Mutual connections

Two Tor nodes that hold each other’s onion addresses can end up mutually connected: each dials the other while accepting the other’s dial. Both sessions persist. No address correlates the two legs — inbound onion peers are anonymous — and the client deliberately does not correlate them by Hello nonce either: the nonce is unauthenticated and stable for a node’s lifetime, so any peer of a peer learns it and could replay it to make a victim drop a genuine session. Bitcoin Core cannot detect mutual connections at all and keeps both; Parallax makes the same choice for the same net effect, without adding an eclipse-assist primitive. The consequence is visible in admin_peers: a dual-stack peer reached over both clearnet and Tor, or a peer that dialed back while we dialed it, appears as two entries. Dialing an address a live session already represents is still suppressed, so the peer count does not grow without bound.

Bans, netrestrict, bootnodes

  • Bans. setban accepts a Tor v3 address as an exact-host entry in the persistent ban list, alongside IP and CIDR entries. There is no subnet form and no discourage tier for onion space; onion bans are enforced at the outbound dial gate. Banning also disconnects a matching live peer where one can be identified — outbound peers are matched by the address they were dialed at, so proxied and onion peers are covered; a purely inbound onion stream cannot be attributed to an address and is left to drop on its own.
  • netrestrict. --netrestrict is CIDR-based and implies IP-only outbound: onion dials are refused while it is set. Unlike --onlynet it binds every dial, manual ones included.
  • Bootnodes. The hardcoded v2 bootnode list and --bootnodes accept <addr>.onion:port entries. Onion bootnodes are ingested only on nodes with an onion route (Core’s fixed-seed reachability rule), and they are how an --onlynet=onion node bootstraps without any clearnet contact.

Compatibility

Nothing about Tor support requires coordination across the network. The wire format, addrbook.rlp schema and anchors.dat format are unchanged; nodes without Tor support or without a Tor route relay onion entries without storing them, and dial gates simply skip networks they cannot reach. Onion connectivity grows as individual operators enable Tor. The planned v3.0 parallax-disc/2 wire format retains BIP155 addressing, so onion peers survive the removal of the legacy identity fields (see the deprecation timeline).