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 dns-introducer.chia.net
; <<>> DiG 9.10.6 <<>> dns-introducer.chia.net
…
;; ANSWER SECTION:
dns-introducer.chia.net. 300 IN A 92.50.125.229
dns-introducer.chia.net. 300 IN A 81.37.13.181
dns-introducer.chia.net. 300 IN A 91.19.71.46
dns-introducer.chia.net. 300 IN A 74.194.156.4
dns-introducer.chia.net. 300 IN A 216.181.141.2
dns-introducer.chia.net. 300 IN A 58.23.151.100
dns-introducer.chia.net. 300 IN A 96.237.143.145
dns-introducer.chia.net. 300 IN A 60.138.183.225
…
If the DNS request fails, it will fall back to contacting the WebSocket introducer at wss://introducer.chia.net:8444/ws
.
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.
Gossip
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.