From 6db89bb18f36a9f4e8a35abefe9f0713c1404def Mon Sep 17 00:00:00 2001 From: julian Date: Tue, 31 Oct 2023 10:06:35 -0600 Subject: [PATCH] add chain height update and refactor balance update --- lib/wallets/isar_models/wallet_info.dart | 17 +++++ lib/wallets/wallet/bip39_hd_wallet.dart | 57 ++++++++++++++++ lib/wallets/wallet/impl/bitcoin_wallet.dart | 15 +++-- .../wallet/impl/bitcoincash_wallet.dart | 66 +++---------------- lib/wallets/wallet/impl/epiccash_wallet.dart | 9 +++ lib/wallets/wallet/wallet.dart | 23 ++++++- 6 files changed, 123 insertions(+), 64 deletions(-) diff --git a/lib/wallets/isar_models/wallet_info.dart b/lib/wallets/isar_models/wallet_info.dart index 38e5a6da5..1eae508db 100644 --- a/lib/wallets/isar_models/wallet_info.dart +++ b/lib/wallets/isar_models/wallet_info.dart @@ -115,6 +115,23 @@ class WalletInfo { } } + /// copies this with a new chain height and updates the db + Future updateCachedChainHeight({ + required int newHeight, + required Isar isar, + }) async { + // only update if there were changes to the height + if (cachedChainHeight != newHeight) { + final updated = copyWith( + cachedChainHeight: newHeight, + ); + await isar.writeTxn(() async { + await isar.walletInfo.delete(id); + await isar.walletInfo.put(updated); + }); + } + } + //============================================================================ WalletInfo({ diff --git a/lib/wallets/wallet/bip39_hd_wallet.dart b/lib/wallets/wallet/bip39_hd_wallet.dart index a87f91054..e317e03d0 100644 --- a/lib/wallets/wallet/bip39_hd_wallet.dart +++ b/lib/wallets/wallet/bip39_hd_wallet.dart @@ -1,7 +1,9 @@ import 'package:bip39/bip39.dart' as bip39; import 'package:coinlib_flutter/coinlib_flutter.dart' as coinlib; import 'package:isar/isar.dart'; +import 'package:stackwallet/models/balance.dart'; import 'package:stackwallet/models/isar/models/isar_models.dart'; +import 'package:stackwallet/utilities/amount/amount.dart'; import 'package:stackwallet/utilities/enums/derive_path_type_enum.dart'; import 'package:stackwallet/wallets/crypto_currency/bip39_hd_currency.dart'; import 'package:stackwallet/wallets/models/tx_data.dart'; @@ -113,6 +115,61 @@ abstract class Bip39HDWallet extends Bip39Wallet { // ========== Overrides ====================================================== + @override + Future updateBalance() async { + final utxos = await mainDB.getUTXOs(walletId).findAll(); + + final currentChainHeight = await chainHeight; + + Amount satoshiBalanceTotal = Amount( + rawValue: BigInt.zero, + fractionDigits: cryptoCurrency.fractionDigits, + ); + Amount satoshiBalancePending = Amount( + rawValue: BigInt.zero, + fractionDigits: cryptoCurrency.fractionDigits, + ); + Amount satoshiBalanceSpendable = Amount( + rawValue: BigInt.zero, + fractionDigits: cryptoCurrency.fractionDigits, + ); + Amount satoshiBalanceBlocked = Amount( + rawValue: BigInt.zero, + fractionDigits: cryptoCurrency.fractionDigits, + ); + + for (final utxo in utxos) { + final utxoAmount = Amount( + rawValue: BigInt.from(utxo.value), + fractionDigits: cryptoCurrency.fractionDigits, + ); + + satoshiBalanceTotal += utxoAmount; + + if (utxo.isBlocked) { + satoshiBalanceBlocked += utxoAmount; + } else { + if (utxo.isConfirmed( + currentChainHeight, + cryptoCurrency.minConfirms, + )) { + satoshiBalanceSpendable += utxoAmount; + } else { + satoshiBalancePending += utxoAmount; + } + } + } + + final balance = Balance( + total: satoshiBalanceTotal, + spendable: satoshiBalanceSpendable, + blockedTotal: satoshiBalanceBlocked, + pendingSpendable: satoshiBalancePending, + ); + + await walletInfo.updateBalance(newBalance: balance, isar: mainDB.isar); + } + @override Future confirmSend({required TxData txData}) { // TODO: implement confirmSend diff --git a/lib/wallets/wallet/impl/bitcoin_wallet.dart b/lib/wallets/wallet/impl/bitcoin_wallet.dart index 1e903312e..d9ba37010 100644 --- a/lib/wallets/wallet/impl/bitcoin_wallet.dart +++ b/lib/wallets/wallet/impl/bitcoin_wallet.dart @@ -47,12 +47,6 @@ class BitcoinWallet extends Bip39HDWallet with ElectrumXMixin { throw UnimplementedError(); } - @override - Future updateBalance() { - // TODO: implement updateBalance - throw UnimplementedError(); - } - @override Future updateTransactions() async { final currentChainHeight = await fetchChainHeight(); @@ -102,4 +96,13 @@ class BitcoinWallet extends Bip39HDWallet with ElectrumXMixin { return false; } } + + @override + Future updateChainHeight() async { + final height = await fetchChainHeight(); + await walletInfo.updateCachedChainHeight( + newHeight: height, + isar: mainDB.isar, + ); + } } diff --git a/lib/wallets/wallet/impl/bitcoincash_wallet.dart b/lib/wallets/wallet/impl/bitcoincash_wallet.dart index ec9e1948f..bd3ab927f 100644 --- a/lib/wallets/wallet/impl/bitcoincash_wallet.dart +++ b/lib/wallets/wallet/impl/bitcoincash_wallet.dart @@ -1,6 +1,5 @@ import 'package:bitbox/bitbox.dart' as bitbox; import 'package:isar/isar.dart'; -import 'package:stackwallet/models/balance.dart'; import 'package:stackwallet/models/isar/models/blockchain_data/address.dart'; import 'package:stackwallet/models/isar/models/blockchain_data/transaction.dart'; import 'package:stackwallet/models/isar/models/blockchain_data/utxo.dart'; @@ -11,7 +10,6 @@ import 'package:stackwallet/services/coins/bitcoincash/bch_utils.dart'; import 'package:stackwallet/services/coins/bitcoincash/cashtokens.dart' as cash_tokens; import 'package:stackwallet/services/node_service.dart'; -import 'package:stackwallet/utilities/amount/amount.dart'; import 'package:stackwallet/utilities/enums/derive_path_type_enum.dart'; import 'package:stackwallet/utilities/extensions/extensions.dart'; import 'package:stackwallet/utilities/logger.dart'; @@ -52,61 +50,6 @@ class BitcoincashWallet extends Bip39HDWallet with ElectrumXMixin { // =========================================================================== - @override - Future updateBalance() async { - final utxos = await mainDB.getUTXOs(walletId).findAll(); - - final currentChainHeight = await fetchChainHeight(); - - Amount satoshiBalanceTotal = Amount( - rawValue: BigInt.zero, - fractionDigits: cryptoCurrency.fractionDigits, - ); - Amount satoshiBalancePending = Amount( - rawValue: BigInt.zero, - fractionDigits: cryptoCurrency.fractionDigits, - ); - Amount satoshiBalanceSpendable = Amount( - rawValue: BigInt.zero, - fractionDigits: cryptoCurrency.fractionDigits, - ); - Amount satoshiBalanceBlocked = Amount( - rawValue: BigInt.zero, - fractionDigits: cryptoCurrency.fractionDigits, - ); - - for (final utxo in utxos) { - final utxoAmount = Amount( - rawValue: BigInt.from(utxo.value), - fractionDigits: cryptoCurrency.fractionDigits, - ); - - satoshiBalanceTotal += utxoAmount; - - if (utxo.isBlocked) { - satoshiBalanceBlocked += utxoAmount; - } else { - if (utxo.isConfirmed( - currentChainHeight, - cryptoCurrency.minConfirms, - )) { - satoshiBalanceSpendable += utxoAmount; - } else { - satoshiBalancePending += utxoAmount; - } - } - } - - final balance = Balance( - total: satoshiBalanceTotal, - spendable: satoshiBalanceSpendable, - blockedTotal: satoshiBalanceBlocked, - pendingSpendable: satoshiBalancePending, - ); - - await walletInfo.updateBalance(newBalance: balance, isar: mainDB.isar); - } - @override Future updateTransactions() async { List
allAddressesOld = await _fetchAllOwnAddresses(); @@ -431,4 +374,13 @@ class BitcoincashWallet extends Bip39HDWallet with ElectrumXMixin { return false; } } + + @override + Future updateChainHeight() async { + final height = await fetchChainHeight(); + await walletInfo.updateCachedChainHeight( + newHeight: height, + isar: mainDB.isar, + ); + } } diff --git a/lib/wallets/wallet/impl/epiccash_wallet.dart b/lib/wallets/wallet/impl/epiccash_wallet.dart index 01bab7a92..31df3594f 100644 --- a/lib/wallets/wallet/impl/epiccash_wallet.dart +++ b/lib/wallets/wallet/impl/epiccash_wallet.dart @@ -77,4 +77,13 @@ class EpiccashWallet extends Bip39Wallet { return false; } } + + @override + Future updateChainHeight() async { + // final height = await fetchChainHeight(); + // await walletInfo.updateCachedChainHeight( + // newHeight: height, + // isar: mainDB.isar, + // ); + } } diff --git a/lib/wallets/wallet/wallet.dart b/lib/wallets/wallet/wallet.dart index 16dd2ab52..a155b6f41 100644 --- a/lib/wallets/wallet/wallet.dart +++ b/lib/wallets/wallet/wallet.dart @@ -25,6 +25,7 @@ import 'package:stackwallet/wallets/wallet/impl/epiccash_wallet.dart'; import 'package:stackwallet/wallets/wallet/mixins/electrumx_mixin.dart'; abstract class Wallet { + // default to Transaction class. For TransactionV2 set to 2 int get isarTransactionVersion => 1; Wallet(this.cryptoCurrency); @@ -75,6 +76,22 @@ abstract class Wallet { String get walletId => walletInfo.walletId; WalletType get walletType => walletInfo.walletType; + /// Attempt to fetch the most recent chain height. + /// On failure return the last cached height. + Future get chainHeight async { + try { + // attempt updating the walletInfo's cached height + await updateChainHeight(); + } catch (e, s) { + // do nothing on failure (besides logging) + Logging.instance.log("$e\n$s", level: LogLevel.Warning); + } + + // return regardless of whether it was updated or not as we want a + // number even if it isn't the most recent + return walletInfo.cachedChainHeight; + } + //============================================================================ // ========== Static Main ==================================================== @@ -143,7 +160,7 @@ abstract class Wallet { } return await _construct( - walletInfo: walletInfo!, + walletInfo: walletInfo, mainDB: mainDB, secureStorageInterface: secureStorageInterface, nodeService: nodeService, @@ -315,6 +332,9 @@ abstract class Wallet { Future updateUTXOs(); Future updateBalance(); + /// updates the wallet info's cachedChainHeight + Future updateChainHeight(); + //=========================================== // Should fire events @@ -339,6 +359,7 @@ abstract class Wallet { ); GlobalEventBus.instance.fire(RefreshPercentChangedEvent(0.0, walletId)); + await updateChainHeight(); GlobalEventBus.instance.fire(RefreshPercentChangedEvent(0.1, walletId));