MOAD-0001 (CWE-407): - cake_wallet-0001: exchange_view_model token injection List.any() O(T*L), 275x - cake_wallet-0002: currency_pairs_utils/pairs_utils List.contains() O(ALL*N), 139x - cake_wallet-0003: monero/wownero _usedAddresses List.contains() O(S*U), 275x MOAD-0004 (CWE-312): - cake_wallet-0004: zcash_taddress_rotation prints wallet seeds to verbose log MOAD-0002: NOTED (SettingsStore 2228 lines, DI 1765 lines, global currentWallet) MOAD-0003: CLEAN (no Zone.current / zone-scoped wallet identity) MOAD-0005: CLEAN (Dart single-threaded, no concurrent cache races) 8/8 unit tests PASS
68 lines
2.1 KiB
Dart
68 lines
2.1 KiB
Dart
/// Unit test for cake_wallet-0003: monero/wownero _usedAddresses
|
|
/// List<String>.contains() O(S*U) in _newSubaddress filtering.
|
|
|
|
int opsDefect = 0;
|
|
int opsFix = 0;
|
|
|
|
void main() {
|
|
// Monero wallets can accumulate hundreds of used addresses
|
|
final sizes = [
|
|
[50, 100], // 50 subaddresses, 100 used addresses
|
|
[200, 500], // heavy usage
|
|
];
|
|
|
|
for (final pair in sizes) {
|
|
final S = pair[0]; // subaddresses to filter
|
|
final U = pair[1]; // used addresses
|
|
|
|
final allAddresses = List.generate(S, (i) => 'addr_$i');
|
|
final usedList = List.generate(U, (i) => 'addr_${i * 2}'); // even indices are "used"
|
|
|
|
// --- Defect: List.contains per subaddress ---
|
|
opsDefect = 0;
|
|
final unusedDefect = allAddresses.where((addr) {
|
|
for (final used in usedList) {
|
|
opsDefect++;
|
|
if (used == addr) return false;
|
|
}
|
|
return true;
|
|
}).toList();
|
|
|
|
// --- Fix: Set.contains per subaddress ---
|
|
opsFix = 0;
|
|
final usedSet = usedList.toSet();
|
|
final unusedFix = allAddresses.where((addr) {
|
|
opsFix++;
|
|
return !usedSet.contains(addr);
|
|
}).toList();
|
|
|
|
assert(unusedDefect.length == unusedFix.length,
|
|
'FAIL: results differ (${unusedDefect.length} vs ${unusedFix.length})');
|
|
|
|
final ratio = opsDefect / opsFix;
|
|
print('S=$S U=$U: defect=$opsDefect fix=$opsFix ratio=${ratio.toStringAsFixed(1)}x '
|
|
'${ratio > 2 ? "PASS" : "FAIL"}');
|
|
assert(ratio > 2);
|
|
}
|
|
|
|
// Also verify the dedup pattern: addAll + toSet + clear + addAll vs just Set.addAll
|
|
final existing = ['a', 'b', 'c'];
|
|
final incoming = ['b', 'c', 'd', 'e'];
|
|
|
|
// Defect: List with manual dedup
|
|
final listResult = <String>[];
|
|
listResult.addAll(existing);
|
|
listResult.addAll(incoming);
|
|
final deduped = listResult.toSet().toList();
|
|
|
|
// Fix: Set with addAll
|
|
final setResult = <String>{};
|
|
setResult.addAll(existing);
|
|
setResult.addAll(incoming);
|
|
|
|
assert(deduped.toSet().length == setResult.length,
|
|
'FAIL: dedup results differ');
|
|
print('Dedup correctness: PASS (${setResult.length} unique)');
|
|
|
|
print('cake_wallet-0003: ALL PASS');
|
|
}
|