btc restore gap fix

This commit is contained in:
julian 2023-04-26 09:27:29 -06:00
parent 61bb4b839d
commit 2bfce21058

View file

@ -423,7 +423,7 @@ class BitcoinWallet extends CoinServiceAPI
level: LogLevel.Info);
}
Future<Tuple2<List<isar_models.Address>, DerivePathType>> _checkGaps(
Future<Tuple3<List<isar_models.Address>, DerivePathType, int>> _checkGaps(
int maxNumberOfIndexesToCheck,
int maxUnusedAddressGap,
int txCountBatchSize,
@ -433,6 +433,8 @@ class BitcoinWallet extends CoinServiceAPI
) async {
List<isar_models.Address> addressArray = [];
int gapCounter = 0;
int highestIndexWithHistory = 0;
for (int index = 0;
index < maxNumberOfIndexesToCheck && gapCounter < maxUnusedAddressGap;
index += txCountBatchSize) {
@ -506,6 +508,9 @@ class BitcoinWallet extends CoinServiceAPI
if (count > 0) {
iterationsAddressArray.add(txCountCallArgs["${_id}_$k"]!);
// update highest
highestIndexWithHistory = index + k;
// reset counter
gapCounter = 0;
}
@ -518,7 +523,7 @@ class BitcoinWallet extends CoinServiceAPI
// cache all the transactions while waiting for the current function to finish.
unawaited(getTransactionCacheEarly(iterationsAddressArray));
}
return Tuple2(addressArray, type);
return Tuple3(addressArray, type, highestIndexWithHistory);
}
Future<void> getTransactionCacheEarly(List<String> allAddresses) async {
@ -562,9 +567,9 @@ class BitcoinWallet extends CoinServiceAPI
DerivePathType.bip84,
];
final List<Future<Tuple2<List<isar_models.Address>, DerivePathType>>>
final List<Future<Tuple3<List<isar_models.Address>, DerivePathType, int>>>
receiveFutures = [];
final List<Future<Tuple2<List<isar_models.Address>, DerivePathType>>>
final List<Future<Tuple3<List<isar_models.Address>, DerivePathType, int>>>
changeFutures = [];
const receiveChain = 0;
@ -623,6 +628,7 @@ class BitcoinWallet extends CoinServiceAPI
final List<isar_models.Address> addressesToStore = [];
int highestReceivingIndexWithHistory = 0;
// If restoring a wallet that never received any funds, then set receivingArray manually
// If we didn't do this, it'd store an empty array
for (final tuple in receiveResults) {
@ -634,10 +640,13 @@ class BitcoinWallet extends CoinServiceAPI
);
addressesToStore.add(address);
} else {
highestReceivingIndexWithHistory =
max(tuple.item3, highestReceivingIndexWithHistory);
addressesToStore.addAll(tuple.item1);
}
}
int highestChangeIndexWithHistory = 0;
// If restoring a wallet that never sent any funds with change, then set changeArray
// manually. If we didn't do this, it'd store an empty array.
for (final tuple in changeResults) {
@ -649,10 +658,20 @@ class BitcoinWallet extends CoinServiceAPI
);
addressesToStore.add(address);
} else {
highestChangeIndexWithHistory =
max(tuple.item3, highestChangeIndexWithHistory);
addressesToStore.addAll(tuple.item1);
}
}
// remove extra addresses to help minimize risk of creating a large gap
addressesToStore.removeWhere((e) =>
e.subType == isar_models.AddressSubType.change &&
e.derivationIndex > highestChangeIndexWithHistory);
addressesToStore.removeWhere((e) =>
e.subType == isar_models.AddressSubType.receiving &&
e.derivationIndex > highestReceivingIndexWithHistory);
if (isRescan) {
await db.updateOrPutAddresses(addressesToStore);
} else {