<p>That code is from <code>src\addrman.cpp</code>. The code's author has in the past <a href="https://bitcointalk.org/index.php?topic=97297.0" rel="nofollow noreferrer">pointed out the associated comments</a> in <a href="https://github.com/bitcoin/bitcoin/blob/master/src/addrman.h#L91" rel="nofollow noreferrer"><code>addrman.h</code></a> starting around line 91</p>
<p>You should refer to the original source but I'll quote the relevant comments here</p>
<p>(<a href="https://opensource.org/licenses/mit-license.php" rel="nofollow noreferrer">https://opensource.org/licenses/mit-license.php</a>)</p>
<p>Stochastic address manager</p>
<p>Design goals:</p>
<ul>
<li>Keep the address tables in-memory, and asynchronously dump the entire table to peers.dat.</li>
<li>Make sure no (localized) attacker can fill the entire table with his nodes/addresses.</li>
</ul>
<p>To that end:</p>
<ul>
<li>Addresses are organized into buckets that can each store up to 64 entries.
<ul>
<li>Addresses to which our node has not successfully connected go into 1024 &quot;new&quot; buckets.
<ul>
<li>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.</li>
<li>The actual bucket is chosen from one of these, based on the range in which the address itself is located.</li>
<li>The position in the bucket is chosen based on the full address.</li>
<li>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.</li>
<li>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).</li>
<li>Addresses of nodes that are known to be accessible go into 256 &quot;tried&quot; buckets.
<ul>
<li>Each address range selects at random 8 of these buckets.</li>
<li>The actual bucket is chosen from one of these, based on the full address.</li>
<li>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 &quot;new&quot; buckets if this
attempt was unsuccessful.</li>
</ul>
</li>
<li>Bucket selection is based on cryptographic hashing, using a randomly-generated 256-bit key, which should not
be observable by adversaries.</li>
<li>Several indexes are kept for high performance. Setting m_consistency_check_ratio with the -checkaddrman
configuration option will introduce (expensive) consistency checks for the entire data structure.</li>
</ul>
</li>
</ul>
</li>
</ul>
<blockquote>
<p><strong>I don't understand how an entry can map to 8 buckets when the data in the entry is the same.</strong></p>
</blockquote>
<p>To me, the comments suggest that, for tried nodes, the address <em>range</em> (e.g. 99.0/16) selects eight buckets but the whole address (e.g. 99.0.0.55) selects one of those eight.</p>
<p>I've no idea if that helps, but I think it ought to, and if not, someone more knowledgable will probably provide a better answer.</p>

CC BY-SA 4.0
2022-10-12T10:30:32.153Z
2022-10-12T11:04:36.137Z
2022-10-12T11:04:36.137Z
RedGrittyBrick
<p>Bitcoin core states that an entry can be part of maximum 8 buckets. I don't understand how an entry can map to 8 buckets when the data in the entry is the same.</p>
<pre><code>uint64_t hash1 = (CHashWriter(SER_GETHASH, 0) &lt;&lt; nKey &lt;&lt; GetGroup(asmap) &lt;&lt; vchSourceGroupKey).GetCheapHash();

uint64_t hash2 = (CHashWriter(SER_GETHASH, 0) &lt;&lt; nKey &lt;&lt; vchSourceGroupKey &lt;&lt; (hash1 % ADDRMAN_NEW_BUCKETS_PER_SOURCE_GROUP)).GetCheapHash();

return hash2 % ADDRMAN_NEW_BUCKET_COUNT;
</code></pre>
<p>When the input is the same, how can it return 8 different values?</p>

<bitcoin-core><bitcoind><bitcoin-core-development>
Bucketing algorithm in Bitcoin
Vinay Shetty
# Bucketing algorithm in Bitcoin

(Asked by: username_0 on 2022-10-12)

Bitcoin core states that an entry can be part of maximum 8 buckets. I don't understand how an entry can map to 8 buckets when the data in the entry is the same.
uint64_t hash1 = (CHashWriter(SER_GETHASH, 0) << nKey << GetGroup(asmap) << vchSourceGroupKey).GetCheapHash();

uint64_t hash2 = (CHashWriter(SER_GETHASH, 0) << nKey << vchSourceGroupKey << (hash1 % ADDRMAN_NEW_BUCKETS_PER_SOURCE_GROUP)).GetCheapHash();

return hash2 % ADDRMAN_NEW_BUCKET_COUNT;

When the input is the same, how can it return 8 different values?

**Tags:** bitcoin-core, bitcoind, bitcoin-core-development


---

## 1 answers

### Answer by username_1 on 2022-10-12. Score: 1

That code is from `src\addrman.cpp`. The code's author has in the past [pointed out the associated comments](https://bitcointalk.org/index.php?topic=97297.0) in [`addrman.h`](https://github.com/bitcoin/bitcoin/blob/master/src/addrman.h#L91) starting around line 91

You should refer to the original source but I'll quote the relevant comments here

(<https://opensource.org/licenses/mit-license.php>)

Stochastic address manager

Design goals:

* 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.
    - Several indexes are kept for high performance. Setting m\_consistency\_check\_ratio with the -checkaddrman
      configuration option will introduce (expensive) consistency checks for the entire data structure.

> **I don't understand how an entry can map to 8 buckets when the data in the entry is the same.**

To me, the comments suggest that, for tried nodes, the address *range* (e.g. 99.0/16) selects eight buckets but the whole address (e.g. 99.0.0.55) selects one of those eight.

I've no idea if that helps, but I think it ought to, and if not, someone more knowledgable will probably provide a better answer.


---

