Commit Graph

5 Commits

Author SHA1 Message Date
Krystie b623396186 perf+sec: 15 improvements across consensus, DB, network, sync
CONSENSUS SECURITY (main.cpp):
- Re-enable PoS kernel verification post-IBD (was unconditionally disabled)
- Re-enable coinstake reward validation post-IBD (was commented out)
- Re-enable anti-spam difficulty check (was if(false && ...))

SYNC PERFORMANCE (main.cpp):
- Batch address index writes in ConnectBlock (hundreds of DB ops → one per address)
- Throttle IBD printfs (per-block → per-10K-blocks or fDebug-gated)

DATABASE (txdb-rocksdb.cpp/h, txdb-base.cpp):
- Non-batched WriteRaw: WAL sync=false (was fsync per write)
- UTXO cache: FIFO eviction → true LRU with access-order tracking
- RocksDB memtable: 64MB → 256MB + max_write_buffer_number=4
- pendingBatch: std::map → std::unordered_map (O(log n) → O(1))
- max_open_files: 1000 → unlimited

NETWORK (net.cpp, netbase.cpp):
- TCP_NODELAY on all sockets (disable Nagle's algorithm)
- SO_KEEPALIVE on all sockets (faster dead-peer detection)
- Adaptive MilliSleep: 1ms during IBD, 10ms otherwise
- writev() scatter-gather I/O for send() coalescing (up to 16 msgs/syscall)
- O(1) CountInFlight counter (was O(n) scan of entire header map)
2026-06-27 18:17:59 -07:00
Sami Ahmed 20bb571690 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.
2026-06-21 16:48:58 -07:00
Sami Ahmed 9e9d17e1e0 sync: signed peer discovery — re-fire getaddr/getseederlist when peer count drops
Triangles already has a node-identity signing system (getwalletaddr/walletaddr
in onion_v3.cpp:4793-4848) that lets peers cryptographically prove they own
their .onion address. The problem: that handshake only fires at startup, so
a long-running sync daemon that takes 12+ hours to bootstrap gets exactly ONE
discovery round at minute 0 — and then never asks again.

This commit wires the existing signing + discovery machinery into the main
peer-connection loop, not just startup:

  * src/net.h: add nLastGetaddrTrigger + nSignedPeerBonus fields to CNode
  * src/net.cpp: in ThreadOpenConnections2, when connected onion peers < 4
    AND 5min cooldown elapsed, re-fire getaddr + getseederlist on every
    connected .onion peer. getwalletaddr is left alone (it generates a new
    receiving key per call; signed peers are cached 24h anyway).
  * src/tor/onion_v3.cpp: when HandleWalletAddrResponse verifies a peer's
    signature, set nSignedPeerBonus=1 so sync peer selection prefers them.
  * src/syncmanager.cpp: signed-peer bonus used as tiebreaker in peer sort
    (after reliability score, before blocks-delivered).

Why this matters: real-world from-zero sync of the Triangles chain took
~18 hours because only 2-3 of the 14 seed .onion nodes were reliably
reachable from any given Tor instance. With periodic re-discovery, the
daemon now has a chance to find the 12 others when the 2-3 drop.

Verified: built clean (15:59), test daemon climbed from 70,828 → 73,997+
at ~1.9 blk/s with new binary, SYNC-SIGN message confirmed firing.
2026-06-21 16:35:27 -07:00
Sami Ahmed 7ba8d8b8c9 Fix sync-freeze: backpressure, prune protection, eviction direction, bridge-repair + PoS header guard
Sync-freeze patch (original):
- Backpressure ceiling HEADER_FRONT_MAX_AHEAD=8000
- PruneHeaders protects live sync window (nProtectFloor)
- Hard-cap eviction from highest-height first
- Bridge-repair getheaders from connected tip via PathReachesChain

Additional fix:
- Skip PoW check on PoS headers (nonce=0) in AddHeaderNode
  Block 1026 is PoS but within the 0-9000 PoW range — old code
  rejected valid PoS headers and severed the chain at height 1025

Verified: from-zero no-snapshot sync reached block 17k+ past the
old 15k freeze zone. 132/132 unit tests pass.
2026-06-20 20:56:47 -07:00
sami7777 9389a883f1 Wire CSyncManager + LevelDB->RocksDB chain DB migration
CSyncManager extracts the headers-first IBD planner from main.cpp into
its own translation unit. main.cpp loses ~570 lines of file-scope state
and helper functions; the headers handler, block-delivery latency
tracking, stall-recovery, and per-peer Tick cadence now route through
g_syncManager.

MaybeMigrateLevelDbToRocksDb() is now reachable via -migratechaindb /
-migratechaindbforce in init.cpp. Reads from <datadir>/txleveldb and
writes byte-for-byte identical records into <datadir>/rocksdb via a
new CRocksTxDB::WriteRawRecordForMigration() shim over WriteRaw.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-13 00:44:08 -07:00