Skip to content

fix: make detector report output deterministic - #30

Merged
LORDBABUINO merged 2 commits into
mainfrom
fix/deterministic-report-output
Sep 4, 2026
Merged

fix: make detector report output deterministic#30
LORDBABUINO merged 2 commits into
mainfrom
fix/deterministic-report-output

Conversation

@LORDBABUINO

Copy link
Copy Markdown
Collaborator

Two identical scans could produce reports with findings in different orders, and in two spots with different wording, because detectors iterated HashSet/HashMap directly: the our_txids collect pattern repeated across 13 detectors, our_addrs iteration in address reuse, and two places that formatted a HashSet straight into description/details text.

Changes:

  1. A private ordered_txids helper (collect + sort) replaces the per-detector pattern; address reuse iterates addresses sorted; cluster merge emits funding_sources as an ordered map; behavioral fingerprint formats script types as a sorted list instead of debug-printing a set.
  2. detect_all now applies a final stable sort of findings and warnings by (type, description), so the report order is fully reproducible.
  3. While touching the correction texts: CIOH and consolidation corrections now also recommend Payjoin (BIP-78), which merges inputs without revealing common ownership. Honest advice for the paying-someone case that coin control alone does not cover.

Test: a new node-free test target (engine/tests/determinism.rs) builds a synthetic WalletHistory rich enough to fire all 16 detectors (asserted one by one), then runs the full pipeline five times and requires byte-identical serialized reports. Each in-process run uses fresh HashMap seeds, so this fails reliably against the old code (recorded red run) and passed in three extra fresh processes after the fix. Also verified live on mainnet: two identical scans through the HTTP API returned byte-identical bodies. Suite 41/41, clippy -D warnings clean.

Detectors iterated HashSet/HashMap directly, so two scans of the same
wallet produced findings in different order and, in three spots, with
different content (sets dumped into descriptions and details). Sort
txids and addresses before iterating, sort set-derived arrays before
formatting, and stable-sort findings and warnings in detect_all.
Both corrections only pointed at coin control and CoinJoin. When the
user is making a payment anyway, a Payjoin (BIP-78) merges inputs
without revealing common ownership, so mention it as the preferred
option for that case.
@LORDBABUINO
LORDBABUINO merged commit 6d01f6e into main Sep 4, 2026
3 checks passed
@LORDBABUINO
LORDBABUINO deleted the fix/deterministic-report-output branch September 4, 2026 04:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant