From 6465faa4e1355911df7d0d2db26b9f8031706f98 Mon Sep 17 00:00:00 2001 From: julian Date: Tue, 7 Mar 2023 09:00:00 -0600 Subject: [PATCH] btc update utxo set --- lib/db/main_db.dart | 22 +++++++ .../isar/models/blockchain_data/utxo.dart | 14 +++- .../coins/bitcoin/bitcoin_wallet.dart | 66 ++++++++++--------- 3 files changed, 70 insertions(+), 32 deletions(-) diff --git a/lib/db/main_db.dart b/lib/db/main_db.dart index 26464df17..717b68390 100644 --- a/lib/db/main_db.dart +++ b/lib/db/main_db.dart @@ -160,6 +160,28 @@ class MainDB { await isar.utxos.putAll(utxos); }); + Future updateUTXOs(String walletId, List utxos) async { + await isar.writeTxn(() async { + final set = utxos.toSet(); + for (final utxo in utxos) { + // check if utxo exists in db and update accordingly + final storedUtxo = await isar.utxos + .where() + .txidWalletIdVoutEqualTo(utxo.txid, utxo.walletId, utxo.vout) + .findFirst(); + + if (storedUtxo != null) { + // update + set.remove(utxo); + set.add(storedUtxo); + } + } + + await isar.utxos.where().walletIdEqualTo(walletId).deleteAll(); + await isar.utxos.putAll(set.toList()); + }); + } + // transaction notes QueryBuilder getTransactionNotes(String walletId) => diff --git a/lib/models/isar/models/blockchain_data/utxo.dart b/lib/models/isar/models/blockchain_data/utxo.dart index 4bea68d72..df7fb93db 100644 --- a/lib/models/isar/models/blockchain_data/utxo.dart +++ b/lib/models/isar/models/blockchain_data/utxo.dart @@ -4,7 +4,7 @@ import 'package:isar/isar.dart'; part 'utxo.g.dart'; -@Collection(accessor: "utxos") +@Collection(accessor: "utxos", inheritance: false) class UTXO { UTXO({ required this.walletId, @@ -84,4 +84,16 @@ class UTXO { "address: $address, " "otherData: $otherData, " "}"; + + @override + bool operator ==(Object other) { + return other is UTXO && + other.walletId == walletId && + other.txid == txid && + other.vout == vout; + } + + @override + @ignore + int get hashCode => Object.hashAll([walletId, txid, vout]); } diff --git a/lib/services/coins/bitcoin/bitcoin_wallet.dart b/lib/services/coins/bitcoin/bitcoin_wallet.dart index c8600544e..f9dd1cb0c 100644 --- a/lib/services/coins/bitcoin/bitcoin_wallet.dart +++ b/lib/services/coins/bitcoin/bitcoin_wallet.dart @@ -1796,13 +1796,7 @@ class BitcoinWallet extends CoinServiceAPI } } - final currentChainHeight = await chainHeight; - final List outputArray = []; - int satoshiBalanceTotal = 0; - int satoshiBalancePending = 0; - int satoshiBalanceSpendable = 0; - int satoshiBalanceBlocked = 0; for (int i = 0; i < fetchedUtxoList.length; i++) { for (int j = 0; j < fetchedUtxoList[i].length; j++) { @@ -1863,18 +1857,6 @@ class BitcoinWallet extends CoinServiceAPI address: utxoOwnerAddress, ); - satoshiBalanceTotal += utxo.value; - - if (utxo.isBlocked) { - satoshiBalanceBlocked += utxo.value; - } else { - if (utxo.isConfirmed(currentChainHeight, MINIMUM_CONFIRMATIONS)) { - satoshiBalanceSpendable += utxo.value; - } else { - satoshiBalancePending += utxo.value; - } - } - outputArray.add(utxo); } } @@ -1882,27 +1864,49 @@ class BitcoinWallet extends CoinServiceAPI Logging.instance .log('Outputs fetched: $outputArray', level: LogLevel.Info); - // TODO move this out of here and into IDB - await db.isar.writeTxn(() async { - await db.isar.utxos.where().walletIdEqualTo(walletId).deleteAll(); - await db.isar.utxos.putAll(outputArray); - }); + await db.updateUTXOs(walletId, outputArray); // finally update balance - _balance = Balance( - coin: coin, - total: satoshiBalanceTotal, - spendable: satoshiBalanceSpendable, - blockedTotal: satoshiBalanceBlocked, - pendingSpendable: satoshiBalancePending, - ); - await updateCachedBalance(_balance!); + await _updateBalance(); } catch (e, s) { Logging.instance .log("Output fetch unsuccessful: $e\n$s", level: LogLevel.Error); } } + Future _updateBalance() async { + final utxos = await db.getUTXOs(walletId).findAll(); + final currentChainHeight = await chainHeight; + + int satoshiBalanceTotal = 0; + int satoshiBalancePending = 0; + int satoshiBalanceSpendable = 0; + int satoshiBalanceBlocked = 0; + + for (final utxo in utxos) { + satoshiBalanceTotal += utxo.value; + + if (utxo.isBlocked) { + satoshiBalanceBlocked += utxo.value; + } else { + if (utxo.isConfirmed(currentChainHeight, MINIMUM_CONFIRMATIONS)) { + satoshiBalanceSpendable += utxo.value; + } else { + satoshiBalancePending += utxo.value; + } + } + } + + _balance = Balance( + coin: coin, + total: satoshiBalanceTotal, + spendable: satoshiBalanceSpendable, + blockedTotal: satoshiBalanceBlocked, + pendingSpendable: satoshiBalancePending, + ); + await updateCachedBalance(_balance!); + } + @override Balance get balance => _balance ??= getCachedBalance(); Balance? _balance;