diff --git a/lib/pages/settings_views/global_settings_view/xpub_view.dart b/lib/pages/settings_views/global_settings_view/xpub_view.dart index e499218cc..b8694ed51 100644 --- a/lib/pages/settings_views/global_settings_view/xpub_view.dart +++ b/lib/pages/settings_views/global_settings_view/xpub_view.dart @@ -154,17 +154,17 @@ class _XPubViewState extends ConsumerState { rootNavigator: true, ).pop, ), - AnimatedSize( - duration: const Duration( - milliseconds: 150, - ), - child: Padding( - padding: const EdgeInsets.fromLTRB(32, 0, 32, 32), - child: child, - ), - ), ], ), + AnimatedSize( + duration: const Duration( + milliseconds: 150, + ), + child: Padding( + padding: const EdgeInsets.fromLTRB(32, 0, 32, 32), + child: child, + ), + ), ], ), ), diff --git a/lib/services/coins/bitcoincash/bitcoincash_wallet.dart b/lib/services/coins/bitcoincash/bitcoincash_wallet.dart index 8c9d4d911..7903927ae 100644 --- a/lib/services/coins/bitcoincash/bitcoincash_wallet.dart +++ b/lib/services/coins/bitcoincash/bitcoincash_wallet.dart @@ -1,6 +1,7 @@ import 'dart:async'; import 'dart:convert'; import 'dart:io'; +import 'dart:math'; import 'package:bech32/bech32.dart'; import 'package:bip32/bip32.dart' as bip32; @@ -377,7 +378,7 @@ class BitcoinCashWallet extends CoinServiceAPI level: LogLevel.Info); } - Future, DerivePathType>> _checkGaps( + Future, DerivePathType, int>> _checkGaps( int maxNumberOfIndexesToCheck, int maxUnusedAddressGap, int txCountBatchSize, @@ -387,6 +388,8 @@ class BitcoinCashWallet extends CoinServiceAPI ) async { List addressArray = []; int gapCounter = 0; + int highestIndexWithHistory = 0; + for (int index = 0; index < maxNumberOfIndexesToCheck && gapCounter < maxUnusedAddressGap; index += txCountBatchSize) { @@ -460,6 +463,10 @@ class BitcoinCashWallet extends CoinServiceAPI if (count > 0) { iterationsAddressArray.add(txCountCallArgs["${_id}_$k"]!); + // update highest + highestIndexWithHistory = index + k; + + // reset counter gapCounter = 0; } @@ -471,7 +478,7 @@ class BitcoinCashWallet 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 getTransactionCacheEarly(List allAddresses) async { @@ -519,9 +526,9 @@ class BitcoinCashWallet extends CoinServiceAPI deriveTypes.add(DerivePathType.bch44); } - final List, DerivePathType>>> + final List, DerivePathType, int>>> receiveFutures = []; - final List, DerivePathType>>> + final List, DerivePathType, int>>> changeFutures = []; const receiveChain = 0; @@ -579,6 +586,8 @@ class BitcoinCashWallet extends CoinServiceAPI final changeResults = futuresResult[1]; final List 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) { @@ -590,10 +599,15 @@ class BitcoinCashWallet 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) { @@ -605,17 +619,32 @@ class BitcoinCashWallet 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 { await db.putAddresses(addressesToStore); } - await _updateUTXOs(); + await Future.wait([ + _refreshTransactions(), + _updateUTXOs(), + ]); await Future.wait([ updateCachedId(walletId),