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.