tests: add v3 onion address validator + fix Phase 1.5 build break

Adds src/test/onion_v3_tests.cpp with 8 Boost.Test cases that validate
every hardcoded seed in src/onionseed.h against the v3 hidden service
checksum algorithm (SHA3-256 of ".onion checksum" || pubkey || version).

Test cases:
  * onion_v3_valid_known_seeds - all 7 hardcoded seeds must validate
  * onion_v3_detects_transposition - catches the btb6/gtb6 bug from 2026-06-21
  * onion_v3_detects_wrong_length - too short, too long
  * onion_v3_detects_missing_suffix - .com instead of .onion
  * onion_v3_detects_invalid_base32 - chars 0,1,8,9 + uppercase rejected
  * onion_v3_detects_bad_version_byte - all-'a' body has invalid checksum
  * onion_v3_round_trip_encoding - base32 encode/decode is deterministic
  * onion_v3_audit_summary - overall summary check

The C++ validator mirrors scripts/validate_onion_seeds.py exactly so the
two implementations stay in sync. Catches corruption at CI/build time
instead of daemon runtime.

Also fixes an unrelated build break: GetPeerInflightCap() was called from
syncmanager.cpp:533 but never declared in syncmanager.h. The function
intent was 'windowSize / peerCount + 1' - inlined that here so the test
build can succeed.
This commit is contained in:
Sami Ahmed
2026-06-21 16:48:58 -07:00
parent f58d0a5a15
commit 20bb571690
2 changed files with 219 additions and 1 deletions
+1 -1
View File
@@ -530,7 +530,7 @@ unsigned int CSyncManager::QueueBlocksParallel(unsigned int nWindow)
// Phase 1.5: per-peer inflight counting via HeaderNode.pnodeLastRequest.
// Skip a peer if they're at their share of the global window. This caps the
// damage a single .onion peer can do if they're feeding low-quality blocks.
const unsigned int nPerPeerCap = GetPeerInflightCap(vEligiblePeers.size());
const unsigned int nPerPeerCap = HEADER_DOWNLOAD_WINDOW / std::max(1u, (unsigned int)vEligiblePeers.size()) + 1;
std::map<const CNode*, unsigned int> mapPeerInflight;
{
const int64_t nNowInflight = GetTime() * 1000000;