mirror of
https://github.com/Such-Software/hash-wallet.git
synced 2026-10-26 06:08:40 +01:00
fix balance being stale cuz it's overriden by an old value
This commit is contained in:
@@ -36,6 +36,14 @@ class ElectrumBalance extends Balance {
|
||||
@override
|
||||
Money frozen;
|
||||
|
||||
ElectrumBalance copy() => ElectrumBalance(
|
||||
confirmed: confirmed,
|
||||
unconfirmed: unconfirmed,
|
||||
frozen: frozen,
|
||||
secondConfirmed: secondConfirmed,
|
||||
secondUnconfirmed: secondUnconfirmed,
|
||||
);
|
||||
|
||||
static ElectrumBalance? fromJSON(String? jsonSource, Currency currency) {
|
||||
if (jsonSource == null) return null;
|
||||
|
||||
|
||||
@@ -428,7 +428,7 @@ abstract class ElectrumWalletBase
|
||||
return;
|
||||
}
|
||||
|
||||
balance[currency] = newBalance;
|
||||
balance[currency] = newBalance.copy();
|
||||
}
|
||||
|
||||
Map<int, Set<String>> get addressesSetByAccount {
|
||||
@@ -1845,8 +1845,8 @@ abstract class ElectrumWalletBase
|
||||
isViewOnly: false,
|
||||
)..addListener((transaction) async {
|
||||
transactionHistory.addOne(transaction);
|
||||
await updateBalance();
|
||||
await updateAllUnspents();
|
||||
await updateBalance();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1950,8 +1950,8 @@ abstract class ElectrumWalletBase
|
||||
unspentCoins
|
||||
.removeWhere((utxo) => estimatedTx.utxos.any((e) => e.utxo.txHash == utxo.hash));
|
||||
|
||||
await updateBalance();
|
||||
await updateAllUnspents();
|
||||
await updateBalance();
|
||||
});
|
||||
} catch (e) {
|
||||
throw e;
|
||||
@@ -2736,8 +2736,8 @@ abstract class ElectrumWalletBase
|
||||
}
|
||||
});
|
||||
transactionHistory.addOne(transaction);
|
||||
await updateBalance();
|
||||
await updateAllUnspents();
|
||||
await updateBalance();
|
||||
});
|
||||
} catch (e) {
|
||||
throw e;
|
||||
@@ -4037,6 +4037,10 @@ abstract class ElectrumWalletBase
|
||||
var totalConfirmed = 0;
|
||||
var totalUnconfirmed = 0;
|
||||
|
||||
final confirmedByAccount = <int, int>{};
|
||||
final unconfirmedByAccount = <int, int>{};
|
||||
final frozenByAccount = <int, int>{};
|
||||
|
||||
if (hasSilentPaymentsScanning) {
|
||||
// Add values from unspent coins that are not fetched by the address list
|
||||
// i.e. scanned silent payments
|
||||
@@ -4044,8 +4048,13 @@ abstract class ElectrumWalletBase
|
||||
if (tx.unspents != null) {
|
||||
tx.unspents!.forEach((unspent) {
|
||||
if (unspent.bitcoinAddressRecord is BitcoinSilentPaymentAddressRecord) {
|
||||
if (unspent.isFrozen) totalFrozen += unspent.value;
|
||||
final account = unspent.bitcoinAddressRecord.accountIndex;
|
||||
if (unspent.isFrozen) {
|
||||
totalFrozen += unspent.value;
|
||||
frozenByAccount[account] = (frozenByAccount[account] ?? 0) + unspent.value;
|
||||
}
|
||||
totalConfirmed += unspent.value;
|
||||
confirmedByAccount[account] = (confirmedByAccount[account] ?? 0) + unspent.value;
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -4062,6 +4071,8 @@ abstract class ElectrumWalletBase
|
||||
element.value == info.value) {
|
||||
if (info.isFrozen) {
|
||||
totalFrozen += element.value;
|
||||
final account = element.bitcoinAddressRecord.accountIndex;
|
||||
frozenByAccount[account] = (frozenByAccount[account] ?? 0) + element.value;
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -4089,6 +4100,10 @@ abstract class ElectrumWalletBase
|
||||
totalConfirmed += confirmed;
|
||||
totalUnconfirmed += unconfirmed;
|
||||
|
||||
final account = addressRecord.accountIndex;
|
||||
confirmedByAccount[account] = (confirmedByAccount[account] ?? 0) + confirmed;
|
||||
unconfirmedByAccount[account] = (unconfirmedByAccount[account] ?? 0) + unconfirmed;
|
||||
|
||||
addressRecord.balance = confirmed + unconfirmed;
|
||||
if (confirmed > 0 || unconfirmed > 0) {
|
||||
addressRecord.setAsUsed();
|
||||
@@ -4096,6 +4111,26 @@ abstract class ElectrumWalletBase
|
||||
}
|
||||
}
|
||||
|
||||
if (hasAccountsSupport) {
|
||||
final perAccount = <int, ElectrumBalance>{};
|
||||
final accounts = <int>{
|
||||
...confirmedByAccount.keys,
|
||||
...unconfirmedByAccount.keys,
|
||||
...frozenByAccount.keys,
|
||||
...walletAddresses.accountIndexes,
|
||||
};
|
||||
|
||||
for (final account in accounts) {
|
||||
perAccount[account] = ElectrumBalance(
|
||||
confirmed: Money.fromInt(confirmedByAccount[account] ?? 0, currency),
|
||||
unconfirmed: Money.fromInt(unconfirmedByAccount[account] ?? 0, currency),
|
||||
frozen: Money.fromInt(frozenByAccount[account] ?? 0, currency),
|
||||
);
|
||||
}
|
||||
|
||||
accountBalances = ObservableMap<int, ElectrumBalance>.of(perAccount);
|
||||
}
|
||||
|
||||
return ElectrumBalance(
|
||||
confirmed: Money.fromInt(totalConfirmed, currency),
|
||||
unconfirmed: Money.fromInt(totalUnconfirmed, currency),
|
||||
@@ -4138,13 +4173,19 @@ abstract class ElectrumWalletBase
|
||||
try {
|
||||
final fetchedTotal = await fetchBalances();
|
||||
|
||||
if (!electrumClient.isConnected || syncStatus is LostConnectionSyncStatus) {
|
||||
printV("updateBalance: connection lost during fetch, keeping existing balance");
|
||||
return;
|
||||
}
|
||||
|
||||
if (type == WalletType.bitcoin && hasAccountsSupport) {
|
||||
// If the wallet has accounts support, we only want to update the balance for the current account.
|
||||
final accountBalance = accountBalances[currentAccountIndex];
|
||||
if (accountBalance == null) {
|
||||
return;
|
||||
if (accountBalance != null) {
|
||||
balance[currency] = accountBalance.copy();
|
||||
} else {
|
||||
printV("updateBalance: no balance for account $currentAccountIndex, keeping existing");
|
||||
}
|
||||
balance[currency] = accountBalance;
|
||||
} else {
|
||||
balance[currency] = fetchedTotal;
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import 'dart:async' show Zone;
|
||||
import 'dart:io' show Platform;
|
||||
import 'dart:math';
|
||||
import "package:collection/collection.dart";
|
||||
@@ -425,7 +426,7 @@ abstract class ElectrumWalletAddressesBase extends WalletAddresses with Store {
|
||||
updateAddressesByMatch();
|
||||
updateReceiveAddresses();
|
||||
updateChangeAddresses();
|
||||
_validateAddresses();
|
||||
await _validateAddresses();
|
||||
await updateAddressesInBox();
|
||||
|
||||
if (currentReceiveAddressIndex >= receiveAddresses.length) {
|
||||
@@ -506,7 +507,7 @@ abstract class ElectrumWalletAddressesBase extends WalletAddresses with Store {
|
||||
if (shouldSkipHardwareWalletType) continue;
|
||||
|
||||
await _generateInitialAddresses(accountIndex: accountIndex, type: type);
|
||||
|
||||
|
||||
// Legacy derivation for these types is identical to the standard one.
|
||||
if (includeLegacy && !LEGACY_DUPLICATE_ADDRESS_TYPES.contains(type)) {
|
||||
await _generateInitialAddresses(
|
||||
@@ -1001,13 +1002,32 @@ abstract class ElectrumWalletAddressesBase extends WalletAddresses with Store {
|
||||
updateAddressesByMatch();
|
||||
}
|
||||
|
||||
void _validateAddresses() {
|
||||
_addresses.forEach((element) async {
|
||||
if (element.type == SegwitAddresType.mweb) {
|
||||
// this would add a ton of startup lag for mweb addresses since we have 1000 of them
|
||||
return;
|
||||
static const _validationTimeSlice = Duration(milliseconds: 16);
|
||||
|
||||
Future<void> _validateAddresses() async {
|
||||
final addresses = _addresses.toList();
|
||||
final slice = Stopwatch()..start();
|
||||
|
||||
for (final element in addresses) {
|
||||
try {
|
||||
await _validateAddress(element);
|
||||
} catch (e, s) {
|
||||
Zone.current.handleUncaughtError(e, s);
|
||||
}
|
||||
|
||||
if (slice.elapsed >= _validationTimeSlice) {
|
||||
await Future<void>.delayed(Duration.zero);
|
||||
slice.reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _validateAddress(BitcoinAddressRecord element) async {
|
||||
if (element.type == SegwitAddresType.mweb) {
|
||||
// this would add a ton of startup lag for mweb addresses since we have 1000 of them
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
final mainHd = _hdForAddressGeneration(
|
||||
isHidden: false,
|
||||
|
||||
Reference in New Issue
Block a user