java-topology/defects/wasabi-0001/patch/wasabi-0001.md

1.2 KiB

UNDF: UNDF-2026-000000920

wasabi-0001: CoinJoinCoinSelector.AnonScoreTxSourceBiasedShuffle O(N^3) List.Any inside nested loop

Location

WalletWasabi/WabiSabi/Client/CoinJoin/Client/CoinJoinCoinSelector.cs:319

Defect

AnonScoreTxSourceBiasedShuffle iterates coins.Length times (outer loop). For each iteration, it scans remaining (inner loop), and for each element calls alternating.Any(x => x.TransactionId == c.TransactionId) and orderedCoins.Any(x => x.TransactionId == c.TransactionId), both O(N) linear scans on lists. This is O(N^3) total.

Additional O(N^2) sites in the same file:

  • Line 227: winner.Any(x => x.TransactionId == coin.TransactionId) inside foreach
  • Line 287: winner.Any(y => y.ScriptPubKey == x.ScriptPubKey) inside .Where()

Severity

MEDIUM. MaxInputsRegistrableByWallet = 10 so N is bounded, but AnonScoreTxSourceBiasedShuffle operates on coins which can be the full filtered UTXO set (could be hundreds). At N=100, the cubic loop performs ~1M comparisons vs ~300 with HashSet.

Fix

Track TransactionId values in HashSet for O(1) membership checks.

Estimated speedup

At N=100: ~333x reduction in comparison operations.