Skip to content

Commit dd67c85

Browse files
committed
optimize/cleanup electrumx_interface wallet addresses saved on recover/rescan
1 parent 8a0f78e commit dd67c85

3 files changed

Lines changed: 161 additions & 327 deletions

File tree

lib/wallets/wallet/impl/firo_wallet.dart

Lines changed: 49 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import 'dart:async';
22
import 'dart:convert';
3-
import 'dart:math';
43

54
import 'package:decimal/decimal.dart';
65
import 'package:isar_community/isar.dart';
@@ -81,41 +80,37 @@ class FiroWallet<T extends ElectrumXCurrencyInterface> extends Bip39HDWallet<T>
8180
final List<Address> allAddressesOld =
8281
await fetchAddressesForElectrumXScan();
8382

84-
final Set<String> receivingAddresses =
85-
allAddressesOld
86-
.where((e) => e.subType == AddressSubType.receiving)
87-
.map((e) => convertAddressString(e.value))
88-
.toSet();
83+
final Set<String> receivingAddresses = allAddressesOld
84+
.where((e) => e.subType == AddressSubType.receiving)
85+
.map((e) => convertAddressString(e.value))
86+
.toSet();
8987

90-
final Set<String> changeAddresses =
91-
allAddressesOld
92-
.where((e) => e.subType == AddressSubType.change)
93-
.map((e) => convertAddressString(e.value))
94-
.toSet();
88+
final Set<String> changeAddresses = allAddressesOld
89+
.where((e) => e.subType == AddressSubType.change)
90+
.map((e) => convertAddressString(e.value))
91+
.toSet();
9592

9693
final allAddressesSet = {...receivingAddresses, ...changeAddresses};
9794

9895
final List<Map<String, dynamic>> allTxHashes = await fetchHistory(
9996
allAddressesSet,
10097
);
10198

102-
final sparkCoins =
103-
await mainDB.isar.sparkCoins
104-
.where()
105-
.walletIdEqualToAnyLTagHash(walletId)
106-
.findAll();
99+
final sparkCoins = await mainDB.isar.sparkCoins
100+
.where()
101+
.walletIdEqualToAnyLTagHash(walletId)
102+
.findAll();
107103

108104
final List<Map<String, dynamic>> allTransactions = [];
109105

110106
// some lelantus transactions aren't fetched via wallet addresses so they
111107
// will never show as confirmed in the gui.
112-
final unconfirmedTransactions =
113-
await mainDB.isar.transactionV2s
114-
.where()
115-
.walletIdEqualTo(walletId)
116-
.filter()
117-
.heightIsNull()
118-
.findAll();
108+
final unconfirmedTransactions = await mainDB.isar.transactionV2s
109+
.where()
110+
.walletIdEqualTo(walletId)
111+
.filter()
112+
.heightIsNull()
113+
.findAll();
119114
for (final tx in unconfirmedTransactions) {
120115
final txn = await electrumXCachedClient.getTransaction(
121116
txHash: tx.txid,
@@ -154,13 +149,12 @@ class FiroWallet<T extends ElectrumXCurrencyInterface> extends Bip39HDWallet<T>
154149
final currentHeight = await chainHeight;
155150

156151
for (final txHash in allTxHashes) {
157-
final storedTx =
158-
await mainDB.isar.transactionV2s
159-
.where()
160-
.walletIdEqualTo(walletId)
161-
.filter()
162-
.txidEqualTo(txHash["tx_hash"] as String)
163-
.findFirst();
152+
final storedTx = await mainDB.isar.transactionV2s
153+
.where()
154+
.walletIdEqualTo(walletId)
155+
.filter()
156+
.txidEqualTo(txHash["tx_hash"] as String)
157+
.findFirst();
164158

165159
if (storedTx?.isConfirmed(
166160
currentHeight,
@@ -214,8 +208,9 @@ class FiroWallet<T extends ElectrumXCurrencyInterface> extends Bip39HDWallet<T>
214208
bool isSparkMint = false;
215209
final bool isSparkSpend = txData["type"] == 9 && txData["version"] == 3;
216210
final bool isMySpark = sparkTxids.contains(txData["txid"] as String);
217-
final bool isMySpentSpark =
218-
missing.where((e) => e.txid == txData["txid"]).isNotEmpty;
211+
final bool isMySpentSpark = missing
212+
.where((e) => e.txid == txData["txid"])
213+
.isNotEmpty;
219214

220215
final sparkCoinsInvolvedReceived = sparkCoins.where(
221216
(e) =>
@@ -298,19 +293,17 @@ class FiroWallet<T extends ElectrumXCurrencyInterface> extends Bip39HDWallet<T>
298293
if (output.addresses.isEmpty &&
299294
output.scriptPubKeyHex.length >= 488) {
300295
// likely spark related
301-
final opByte =
302-
output.scriptPubKeyHex
303-
.substring(0, 2)
304-
.toUint8ListFromHex
305-
.first;
296+
final opByte = output.scriptPubKeyHex
297+
.substring(0, 2)
298+
.toUint8ListFromHex
299+
.first;
306300
if (opByte == OP_SPARKMINT || opByte == OP_SPARKSMINT) {
307301
final serCoin = base64Encode(
308302
output.scriptPubKeyHex.substring(2, 488).toUint8ListFromHex,
309303
);
310-
final coin =
311-
sparkCoinsInvolvedReceived
312-
.where((e) => e.serializedCoinB64!.startsWith(serCoin))
313-
.firstOrNull;
304+
final coin = sparkCoinsInvolvedReceived
305+
.where((e) => e.serializedCoinB64!.startsWith(serCoin))
306+
.firstOrNull;
314307

315308
if (coin == null) {
316309
// not ours
@@ -403,10 +396,9 @@ class FiroWallet<T extends ElectrumXCurrencyInterface> extends Bip39HDWallet<T>
403396
txid: txData["txid"] as String,
404397
network: cryptoCurrency.network,
405398
);
406-
spentSparkCoins =
407-
sparkCoinsInvolvedSpent
408-
.where((e) => tags.contains(e.lTagHash))
409-
.toList();
399+
spentSparkCoins = sparkCoinsInvolvedSpent
400+
.where((e) => tags.contains(e.lTagHash))
401+
.toList();
410402
} else if (isSparkSpend) {
411403
parseAnonFees();
412404
} else if (isSparkMint) {
@@ -490,11 +482,10 @@ class FiroWallet<T extends ElectrumXCurrencyInterface> extends Bip39HDWallet<T>
490482
if (usedCoins.isNotEmpty) {
491483
input = input.copyWith(
492484
addresses: usedCoins.map((e) => e.address).toList(),
493-
valueStringSats:
494-
usedCoins
495-
.map((e) => e.value)
496-
.reduce((value, element) => value += element)
497-
.toString(),
485+
valueStringSats: usedCoins
486+
.map((e) => e.value)
487+
.reduce((value, element) => value += element)
488+
.toString(),
498489
walletOwns: true,
499490
);
500491
wasSentFromThisWallet = true;
@@ -505,11 +496,10 @@ class FiroWallet<T extends ElectrumXCurrencyInterface> extends Bip39HDWallet<T>
505496
spentSparkCoins.isNotEmpty) {
506497
input = input.copyWith(
507498
addresses: spentSparkCoins.map((e) => e.address).toList(),
508-
valueStringSats:
509-
spentSparkCoins
510-
.map((e) => e.value)
511-
.fold(BigInt.zero, (p, e) => p + e)
512-
.toString(),
499+
valueStringSats: spentSparkCoins
500+
.map((e) => e.value)
501+
.fold(BigInt.zero, (p, e) => p + e)
502+
.toString(),
513503
walletOwns: true,
514504
);
515505
wasSentFromThisWallet = true;
@@ -755,53 +745,10 @@ class FiroWallet<T extends ElectrumXCurrencyInterface> extends Bip39HDWallet<T>
755745
Future.wait(changeFutures),
756746
]);
757747

758-
final receiveResults = futuresResult[0];
759-
final changeResults = futuresResult[1];
760-
761-
final List<Address> addressesToStore = [];
762-
763-
int highestReceivingIndexWithHistory = 0;
764-
765-
for (final tuple in receiveResults) {
766-
if (tuple.addresses.isEmpty) {
767-
if (info.otherData[WalletInfoKeys.reuseAddress] != true) {
768-
await checkReceivingAddressForTransactions();
769-
}
770-
} else {
771-
highestReceivingIndexWithHistory = max(
772-
tuple.index,
773-
highestReceivingIndexWithHistory,
774-
);
775-
addressesToStore.addAll(tuple.addresses);
776-
}
777-
}
778-
779-
int highestChangeIndexWithHistory = 0;
780-
// If restoring a wallet that never sent any funds with change, then set changeArray
781-
// manually. If we didn't do this, it'd store an empty array.
782-
for (final tuple in changeResults) {
783-
if (tuple.addresses.isEmpty) {
784-
await checkChangeAddressForTransactions();
785-
} else {
786-
highestChangeIndexWithHistory = max(
787-
tuple.index,
788-
highestChangeIndexWithHistory,
789-
);
790-
addressesToStore.addAll(tuple.addresses);
791-
}
792-
}
793-
794-
// remove extra addresses to help minimize risk of creating a large gap
795-
addressesToStore.removeWhere(
796-
(e) =>
797-
e.subType == AddressSubType.change &&
798-
e.derivationIndex > highestChangeIndexWithHistory,
799-
);
800-
addressesToStore.removeWhere(
801-
(e) =>
802-
e.subType == AddressSubType.receiving &&
803-
e.derivationIndex > highestReceivingIndexWithHistory,
804-
);
748+
final List<Address> addressesToStore = processGapCheckResults([
749+
...futuresResult[0],
750+
...futuresResult[1],
751+
]);
805752

806753
await mainDB.updateOrPutAddresses(addressesToStore);
807754

0 commit comments

Comments
 (0)