Peer Discovery

First Launch

When the wallet is launched for the first time, it requests an initial set of peers from the public DNS introducer. You can make the same request from the command line using dig:


; <<>> DiG 9.10.6 <<>>

;; ANSWER SECTION: 300	IN	A 300	IN	A 300	IN	A 300	IN	A 300	IN	A 300	IN	A 300	IN	A 300	IN	A

If the DNS request fails, it will fall back to contacting the WebSocket introducer at wss://

This process only happens at first launch. Once an initial set of peers is obtained from the introducer, the wallet uses a local database of peers and will only contact the introducer again as a fallback if it runs out.


In order to maintain a robust local database, the wallet requests more peers from each peer it connects to. After completing a handshake, it immediately sends a request_peers message and listens for a respond_peers message, containing a list of (typically 1,000) IP addresses and ports.

Local Database

The local database is based on Bitcoin's addrman, a "stochastic address manager".

As stated in the source, its design goals are to

  • Keep the address tables in-memory, and asynchronously dump the entire table to peers.dat.
  • Make sure no (localized) attacker can fill the entire table with his nodes/addresses.

To that end:

  • Addresses are organized into buckets that can each store up to 64 entries.
    • Addresses to which our node has not successfully connected go into 1024 "new" buckets.
      • Based on the address range (/16 for IPv4) of the source of information, or if an asmap is provided, the AS it belongs to (for IPv4/IPv6), 64 buckets are selected at random.
      • The actual bucket is chosen from one of these, based on the range in which the address itself is located.
      • The position in the bucket is chosen based on the full address.
      • One single address can occur in up to 8 different buckets to increase selection chances for addresses that are seen frequently. The chance for increasing this multiplicity decreases exponentially.
      • When adding a new address to an occupied position of a bucket, it will not replace the existing entry unless that address is also stored in another bucket or it doesn't meet one of several quality criteria (see IsTerrible for exact criteria).
    • Addresses of nodes that are known to be accessible go into 256 "tried" buckets.
      • Each address range selects at random 8 of these buckets.
      • The actual bucket is chosen from one of these, based on the full address.
      • When adding a new good address to an occupied position of a bucket, a FEELER connection to the old address is attempted. The old entry is only replaced and moved back to the "new" buckets if this attempt was unsuccessful.
    • Bucket selection is based on cryptographic hashing, using a randomly-generated 256-bit key, which should not be observable by adversaries.