@@ -85,10 +85,16 @@ ReadStatus PartiallyDownloadedBlock::InitData(const CBlockHeaderAndShortTxIDs& c
85
85
while (txn_available[i + index_offset])
86
86
index_offset++;
87
87
shorttxids[cmpctblock.shorttxids [i]] = i + index_offset;
88
- // Bucket selection is a simple Binomial distribution. If we assume blocks of
89
- // 10,000 transactions, allowing up to 12 elements per bucket should only fail
90
- // once every ~1.3 million blocks and once every 74,000 blocks in a worst-case
91
- // 16,000-transaction block.
88
+ // To determine the chance that the number of entries in a bucket exceeds N,
89
+ // we use the fact that the number of elements in a single bucket is
90
+ // binomially distributed (with n = the number of shorttxids S, and p =
91
+ // 1 / the number of buckets), that in the worst case the number of buckets is
92
+ // equal to S (due to std::unordered_map having a default load factor of 1.0),
93
+ // and that the chance for any bucket to exceed N elements is at most
94
+ // buckets * (the chance that any given bucket is above N elements).
95
+ // Thus: P(max_elements_per_bucket > N) <= S * (1 - cdf(binomial(n=S,p=1/S), N)).
96
+ // If we assume blocks of up to 16000, allowing 12 elements per bucket should
97
+ // only fail once per ~1 million block transfers (per peer and connection).
92
98
if (shorttxids.bucket_size (shorttxids.bucket (cmpctblock.shorttxids [i])) > 12 )
93
99
return READ_STATUS_FAILED;
94
100
}
0 commit comments