- 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/1like any other peer address on nodes that can dial them; - an onion-only posture (
--onlynet=onion) in which the node never touches clearnet.
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’sIsReachable 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
--onionis 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--onionvalue suppresses the discovery, and--onion=0forbids onion outbound entirely.
--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 carryKeyType=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’sConnectedThroughNetwork heuristic). The classification drives:
- Address observations. Onion and proxied peers never contribute
to the self-address quorum, and the
YourAddrsent 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’sADD_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 byHello 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.
setbanaccepts 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.
--netrestrictis CIDR-based and implies IP-only outbound: onion dials are refused while it is set. Unlike--onlynetit binds every dial, manual ones included. - Bootnodes. The hardcoded v2 bootnode list and
--bootnodesaccept<addr>.onion:portentries. Onion bootnodes are ingested only on nodes with an onion route (Core’s fixed-seed reachability rule), and they are how an--onlynet=onionnode 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).
