add chain height update and refactor balance update

This commit is contained in:
julian 2023-10-31 10:06:35 -06:00
parent 405e432d12
commit 6db89bb18f
6 changed files with 123 additions and 64 deletions

View file

@ -115,6 +115,23 @@ class WalletInfo {
}
}
/// copies this with a new chain height and updates the db
Future<void> 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({

View file

@ -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<T extends Bip39HDCurrency> extends Bip39Wallet<T> {
// ========== Overrides ======================================================
@override
Future<void> 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<TxData> confirmSend({required TxData txData}) {
// TODO: implement confirmSend

View file

@ -47,12 +47,6 @@ class BitcoinWallet extends Bip39HDWallet with ElectrumXMixin {
throw UnimplementedError();
}
@override
Future<void> updateBalance() {
// TODO: implement updateBalance
throw UnimplementedError();
}
@override
Future<void> updateTransactions() async {
final currentChainHeight = await fetchChainHeight();
@ -102,4 +96,13 @@ class BitcoinWallet extends Bip39HDWallet with ElectrumXMixin {
return false;
}
}
@override
Future<void> updateChainHeight() async {
final height = await fetchChainHeight();
await walletInfo.updateCachedChainHeight(
newHeight: height,
isar: mainDB.isar,
);
}
}

View file

@ -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<void> 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<void> updateTransactions() async {
List<Address> allAddressesOld = await _fetchAllOwnAddresses();
@ -431,4 +374,13 @@ class BitcoincashWallet extends Bip39HDWallet with ElectrumXMixin {
return false;
}
}
@override
Future<void> updateChainHeight() async {
final height = await fetchChainHeight();
await walletInfo.updateCachedChainHeight(
newHeight: height,
isar: mainDB.isar,
);
}
}

View file

@ -77,4 +77,13 @@ class EpiccashWallet extends Bip39Wallet {
return false;
}
}
@override
Future<void> updateChainHeight() async {
// final height = await fetchChainHeight();
// await walletInfo.updateCachedChainHeight(
// newHeight: height,
// isar: mainDB.isar,
// );
}
}

View file

@ -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<T extends CryptoCurrency> {
// default to Transaction class. For TransactionV2 set to 2
int get isarTransactionVersion => 1;
Wallet(this.cryptoCurrency);
@ -75,6 +76,22 @@ abstract class Wallet<T extends CryptoCurrency> {
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<int> 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<T extends CryptoCurrency> {
}
return await _construct(
walletInfo: walletInfo!,
walletInfo: walletInfo,
mainDB: mainDB,
secureStorageInterface: secureStorageInterface,
nodeService: nodeService,
@ -315,6 +332,9 @@ abstract class Wallet<T extends CryptoCurrency> {
Future<void> updateUTXOs();
Future<void> updateBalance();
/// updates the wallet info's cachedChainHeight
Future<void> updateChainHeight();
//===========================================
// Should fire events
@ -339,6 +359,7 @@ abstract class Wallet<T extends CryptoCurrency> {
);
GlobalEventBus.instance.fire(RefreshPercentChangedEvent(0.0, walletId));
await updateChainHeight();
GlobalEventBus.instance.fire(RefreshPercentChangedEvent(0.1, walletId));