From 6c3cddb48af2aba8c5e3d4295dd223020e19bbc7 Mon Sep 17 00:00:00 2001 From: julian Date: Thu, 20 Apr 2023 17:53:09 -0600 Subject: [PATCH] clean up bch restore process --- .../coins/bitcoincash/bitcoincash_wallet.dart | 298 ++++++------------ 1 file changed, 88 insertions(+), 210 deletions(-) diff --git a/lib/services/coins/bitcoincash/bitcoincash_wallet.dart b/lib/services/coins/bitcoincash/bitcoincash_wallet.dart index 42f48478f..0b86bc3da 100644 --- a/lib/services/coins/bitcoincash/bitcoincash_wallet.dart +++ b/lib/services/coins/bitcoincash/bitcoincash_wallet.dart @@ -376,13 +376,14 @@ class BitcoinCashWallet extends CoinServiceAPI level: LogLevel.Info); } - Future> _checkGaps( - int maxNumberOfIndexesToCheck, - int maxUnusedAddressGap, - int txCountBatchSize, - bip32.BIP32 root, - DerivePathType type, - int chain) async { + Future, DerivePathType>> _checkGaps( + int maxNumberOfIndexesToCheck, + int maxUnusedAddressGap, + int txCountBatchSize, + bip32.BIP32 root, + DerivePathType type, + int chain, + ) async { List addressArray = []; int returningIndex = -1; Map> derivations = {}; @@ -443,12 +444,8 @@ class BitcoinCashWallet extends CoinServiceAPI : isar_models.AddressSubType.change, ); - receivingNodes.addAll({ - "${_id}_$j": { - "node": node, - "address": address, - } - }); + addressArray.add(address); + txCountCallArgs.addAll({ "${_id}_$j": addressString, }); @@ -463,21 +460,9 @@ class BitcoinCashWallet extends CoinServiceAPI for (int k = 0; k < txCountBatchSize; k++) { int count = counts["${_id}_$k"]!; if (count > 0) { - final node = receivingNodes["${_id}_$k"]; - final address = node["address"] as isar_models.Address; - // add address to array - addressArray.add(address); - iterationsAddressArray.add(address.value); - // set current index - returningIndex = index + k; - // reset counter + iterationsAddressArray.add(txCountCallArgs["${_id}_$k"]!); + gapCounter = 0; - // add info to derivations - derivations[address.value] = { - "pubKey": Format.uint8listToString( - (node["node"] as bip32.BIP32).publicKey), - "wif": (node["node"] as bip32.BIP32).toWIF(), - }; } // increase counter when no tx history found @@ -488,11 +473,7 @@ class BitcoinCashWallet extends CoinServiceAPI // cache all the transactions while waiting for the current function to finish. unawaited(getTransactionCacheEarly(iterationsAddressArray)); } - return { - "addressArray": addressArray, - "index": returningIndex, - "derivations": derivations - }; + return Tuple2(addressArray, type); } Future getTransactionCacheEarly(List allAddresses) async { @@ -525,212 +506,109 @@ class BitcoinCashWallet extends CoinServiceAPI }) async { longMutex = true; - Map> bip44P2pkhReceiveDerivations = {}; - Map> bch44P2pkhReceiveDerivations = {}; - Map> p2shReceiveDerivations = {}; - Map> bip44P2pkhChangeDerivations = {}; - Map> bch44P2pkhChangeDerivations = {}; - Map> p2shChangeDerivations = {}; - final root = await Bip32Utils.getBip32Root( mnemonic, mnemonicPassphrase, _network, ); - List bip44P2pkhReceiveAddressArray = []; - List bch44P2pkhReceiveAddressArray = []; - List p2shReceiveAddressArray = []; - int bch44P2pkhReceiveIndex = -1; - int bip44P2pkhReceiveIndex = -1; - int p2shReceiveIndex = -1; + final deriveTypes = [ + DerivePathType.bip44, + DerivePathType.bip49, + ]; - List bip44P2pkhChangeAddressArray = []; - List bch44P2pkhChangeAddressArray = []; - List p2shChangeAddressArray = []; - int bch44P2pkhChangeIndex = -1; - int bip44P2pkhChangeIndex = -1; - int p2shChangeIndex = -1; + if (coin != Coin.bitcoincashTestnet) { + deriveTypes.add(DerivePathType.bch44); + } - // The gap limit will be capped at [maxUnusedAddressGap] - // int receivingGapCounter = 0; - // int changeGapCounter = 0; + final List, DerivePathType>>> + receiveFutures = []; + final List, DerivePathType>>> + changeFutures = []; + + const receiveChain = 0; + const changeChain = 1; + const indexZero = 0; // actual size is 24 due to p2pkh and p2sh so 12x2 const txCountBatchSize = 12; try { - bool testnet = ((coin) == Coin.bitcoincashTestnet) ? true : false; // receiving addresses - Logging.instance - .log("checking receiving addresses...", level: LogLevel.Info); - final resultReceiveBip44 = _checkGaps(maxNumberOfIndexesToCheck, - maxUnusedAddressGap, txCountBatchSize, root, DerivePathType.bip44, 0); + Logging.instance.log( + "checking receiving addresses...", + level: LogLevel.Info, + ); - final resultReceive49 = _checkGaps(maxNumberOfIndexesToCheck, - maxUnusedAddressGap, txCountBatchSize, root, DerivePathType.bip49, 0); + for (final type in deriveTypes) { + receiveFutures.add( + _checkGaps( + maxNumberOfIndexesToCheck, + maxUnusedAddressGap, + txCountBatchSize, + root, + type, + receiveChain, + ), + ); + } - Logging.instance - .log("checking change addresses...", level: LogLevel.Info); // change addresses - final bip44ResultChange = _checkGaps(maxNumberOfIndexesToCheck, - maxUnusedAddressGap, txCountBatchSize, root, DerivePathType.bip44, 1); + Logging.instance.log( + "checking change addresses...", + level: LogLevel.Info, + ); + for (final type in deriveTypes) { + changeFutures.add( + _checkGaps( + maxNumberOfIndexesToCheck, + maxUnusedAddressGap, + txCountBatchSize, + root, + type, + changeChain, + ), + ); + } - final resultChange49 = _checkGaps(maxNumberOfIndexesToCheck, - maxUnusedAddressGap, txCountBatchSize, root, DerivePathType.bip49, 1); - - await Future.wait([ - resultReceiveBip44, - resultReceive49, - bip44ResultChange, - resultChange49, + // io limitations may require running these linearly instead + final futuresResult = await Future.wait([ + Future.wait(receiveFutures), + Future.wait(changeFutures), ]); - bip44P2pkhReceiveAddressArray = (await resultReceiveBip44)['addressArray'] - as List; - bip44P2pkhReceiveIndex = (await resultReceiveBip44)['index'] as int; - bip44P2pkhReceiveDerivations = (await resultReceiveBip44)['derivations'] - as Map>; - - p2shReceiveAddressArray = - (await resultReceive49)['addressArray'] as List; - p2shReceiveIndex = (await resultReceive49)['index'] as int; - p2shReceiveDerivations = (await resultReceive49)['derivations'] - as Map>; - - bip44P2pkhChangeAddressArray = (await bip44ResultChange)['addressArray'] - as List; - bip44P2pkhChangeIndex = (await bip44ResultChange)['index'] as int; - bip44P2pkhChangeDerivations = (await bip44ResultChange)['derivations'] - as Map>; - - p2shChangeAddressArray = - (await resultChange49)['addressArray'] as List; - p2shChangeIndex = (await resultChange49)['index'] as int; - p2shChangeDerivations = (await resultChange49)['derivations'] - as Map>; - - // save the derivations (if any) - if (bip44P2pkhReceiveDerivations.isNotEmpty) { - await addDerivations( - chain: 0, - derivePathType: DerivePathType.bip44, - derivationsToAdd: bip44P2pkhReceiveDerivations); - } - if (p2shReceiveDerivations.isNotEmpty) { - await addDerivations( - chain: 0, - derivePathType: DerivePathType.bip49, - derivationsToAdd: p2shReceiveDerivations); - } - if (bip44P2pkhChangeDerivations.isNotEmpty) { - await addDerivations( - chain: 1, - derivePathType: DerivePathType.bip44, - derivationsToAdd: bip44P2pkhChangeDerivations); - } - if (p2shChangeDerivations.isNotEmpty) { - await addDerivations( - chain: 1, - derivePathType: DerivePathType.bip49, - derivationsToAdd: p2shChangeDerivations); - } + final receiveResults = futuresResult[0]; + final changeResults = futuresResult[1]; + final List addressesToStore = []; // 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 - if (bip44P2pkhReceiveIndex == -1) { - final address = - await _generateAddressForChain(0, 0, DerivePathType.bip44); - bip44P2pkhReceiveAddressArray.add(address); - } - if (p2shReceiveIndex == -1) { - final address = - await _generateAddressForChain(0, 0, DerivePathType.bip49); - p2shReceiveAddressArray.add(address); + for (final tuple in receiveResults) { + if (tuple.item1.isEmpty) { + final address = await _generateAddressForChain( + receiveChain, + indexZero, + tuple.item2, + ); + addressesToStore.add(address); + } else { + addressesToStore.addAll(tuple.item1); + } } // 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. - if (bip44P2pkhChangeIndex == -1) { - final address = - await _generateAddressForChain(1, 0, DerivePathType.bip44); - bip44P2pkhChangeAddressArray.add(address); - } - if (p2shChangeIndex == -1) { - final address = - await _generateAddressForChain(1, 0, DerivePathType.bip49); - p2shChangeAddressArray.add(address); - } - - final addressesToStore = [ - ...bip44P2pkhReceiveAddressArray, - ...bip44P2pkhChangeAddressArray, - ...p2shReceiveAddressArray, - ...p2shChangeAddressArray, - ]; - - if (!testnet) { - final resultReceiveBch44 = _checkGaps( - maxNumberOfIndexesToCheck, - maxUnusedAddressGap, - txCountBatchSize, - root, - DerivePathType.bch44, - 0); - final Future> bch44ResultChange = _checkGaps( - maxNumberOfIndexesToCheck, - maxUnusedAddressGap, - txCountBatchSize, - root, - DerivePathType.bch44, - 1); - await Future.wait([ - resultReceiveBch44, - bch44ResultChange, - ]); - - bch44P2pkhReceiveAddressArray = - (await resultReceiveBch44)['addressArray'] - as List; - bch44P2pkhReceiveIndex = (await resultReceiveBch44)['index'] as int; - bch44P2pkhReceiveDerivations = (await resultReceiveBch44)['derivations'] - as Map>; - - bch44P2pkhChangeAddressArray = (await bch44ResultChange)['addressArray'] - as List; - bch44P2pkhChangeIndex = (await bch44ResultChange)['index'] as int; - bch44P2pkhChangeDerivations = (await bch44ResultChange)['derivations'] - as Map>; - - if (bch44P2pkhReceiveDerivations.isNotEmpty) { - await addDerivations( - chain: 0, - derivePathType: DerivePathType.bch44, - derivationsToAdd: bch44P2pkhReceiveDerivations); + for (final tuple in changeResults) { + if (tuple.item1.isEmpty) { + final address = await _generateAddressForChain( + changeChain, + indexZero, + tuple.item2, + ); + addressesToStore.add(address); + } else { + addressesToStore.addAll(tuple.item1); } - if (bch44P2pkhChangeDerivations.isNotEmpty) { - await addDerivations( - chain: 1, - derivePathType: DerivePathType.bch44, - derivationsToAdd: bch44P2pkhChangeDerivations); - } - - if (bch44P2pkhReceiveIndex == -1) { - final address = - await _generateAddressForChain(0, 0, DerivePathType.bch44); - bch44P2pkhReceiveAddressArray.add(address); - } - - if (bch44P2pkhChangeIndex == -1) { - final address = - await _generateAddressForChain(1, 0, DerivePathType.bch44); - bch44P2pkhChangeAddressArray.add(address); - } - - addressesToStore.addAll([ - ...bch44P2pkhReceiveAddressArray, - ...bch44P2pkhChangeAddressArray, - ]); } if (isRescan) {