This commit is contained in:
Matthew Fosse 2024-08-23 15:17:28 -04:00
parent dc699af49c
commit 527983af4f
3 changed files with 110 additions and 115 deletions

View file

@ -424,9 +424,7 @@ abstract class ElectrumWalletBase
@override
Future<void> startSync() async {
try {
if (this is! LitecoinWallet) {
syncStatus = SyncronizingSyncStatus();
}
syncStatus = SyncronizingSyncStatus();
if (hasSilentPaymentsScanning) {
await _setInitialHeight();
@ -1262,69 +1260,51 @@ abstract class ElectrumWalletBase
updatedUnspentCoins.addAll(await fetchUnspent(address));
}));
unspentCoins = updatedUnspentCoins;
}
Future<void> updateUnspent() async {
await updateAllUnspents();
if (unspentCoinsInfo.length != unspentCoins.length) {
unspentCoins.forEach((coin) => addCoinInfo(coin));
return;
}
if (unspentCoins.isNotEmpty) {
unspentCoins.forEach((coin) {
final coinInfoList = unspentCoinsInfo.values.where((element) =>
element.walletId.contains(id) &&
element.hash.contains(coin.hash) &&
element.vout == coin.vout);
if (coinInfoList.isNotEmpty) {
final coinInfo = coinInfoList.first;
coin.isFrozen = coinInfo.isFrozen;
coin.isSending = coinInfo.isSending;
coin.note = coinInfo.note;
if (coin.bitcoinAddressRecord is! BitcoinSilentPaymentAddressRecord)
coin.bitcoinAddressRecord.balance += coinInfo.value;
} else {
addCoinInfo(coin);
}
});
if (unspentCoinsInfo.length != updatedUnspentCoins.length) {
updatedUnspentCoins.forEach((coin) => addCoinInfo(coin));
}
await updateCoins(updatedUnspentCoins, set: true);
await _refreshUnspentCoinsInfo();
}
@action
Future<void> updateUnspents(BitcoinAddressRecord address) async {
final newUnspentCoins = await fetchUnspent(address);
if (newUnspentCoins.isNotEmpty) {
unspentCoins.addAll(newUnspentCoins);
newUnspentCoins.forEach((coin) {
final coinInfoList = unspentCoinsInfo.values.where(
(element) =>
element.walletId.contains(id) &&
element.hash.contains(coin.hash) &&
element.vout == coin.vout,
);
if (coinInfoList.isNotEmpty) {
final coinInfo = coinInfoList.first;
coin.isFrozen = coinInfo.isFrozen;
coin.isSending = coinInfo.isSending;
coin.note = coinInfo.note;
if (coin.bitcoinAddressRecord is! BitcoinSilentPaymentAddressRecord)
coin.bitcoinAddressRecord.balance += coinInfo.value;
} else {
addCoinInfo(coin);
}
});
Future<void> updateCoins(List<BitcoinUnspent> newUnspentCoins, {bool set = false}) async {
if (newUnspentCoins.isEmpty) {
return;
}
if (set) {
unspentCoins = newUnspentCoins;
} else {
unspentCoins.addAll(newUnspentCoins);
}
newUnspentCoins.forEach((coin) {
final coinInfoList = unspentCoinsInfo.values.where(
(element) =>
element.walletId.contains(id) &&
element.hash.contains(coin.hash) &&
element.vout == coin.vout,
);
if (coinInfoList.isNotEmpty) {
final coinInfo = coinInfoList.first;
coin.isFrozen = coinInfo.isFrozen;
coin.isSending = coinInfo.isSending;
coin.note = coinInfo.note;
if (coin.bitcoinAddressRecord is! BitcoinSilentPaymentAddressRecord)
coin.bitcoinAddressRecord.balance += coinInfo.value;
} else {
addCoinInfo(coin);
}
});
}
@action
Future<void> updateUnspentsForAddress(BitcoinAddressRecord address) async {
final newUnspentCoins = await fetchUnspent(address);
await updateCoins(newUnspentCoins);
}
@action
@ -1819,7 +1799,7 @@ abstract class ElectrumWalletBase
_scripthashesUpdateSubject[sh] = await electrumClient.scripthashUpdate(sh);
_scripthashesUpdateSubject[sh]?.listen((event) async {
try {
await updateUnspents(address);
await updateUnspentsForAddress(address);
await updateBalance();

View file

@ -202,14 +202,7 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
@override
Future<void> startSync() async {
print("STARTING SYNC");
if (!mwebEnabled) {
syncStatus = SyncronizingSyncStatus();
await subscribeForUpdates();
await updateTransactions();
syncStatus = SyncedSyncStatus();
return;
}
syncStatus = SyncronizingSyncStatus();
await subscribeForUpdates();
await updateTransactions();
await updateFeeRates();
@ -218,6 +211,16 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
_feeRatesTimer =
Timer.periodic(const Duration(minutes: 1), (timer) async => await updateFeeRates());
if (!mwebEnabled) {
await super.updateAllUnspents();
await updateBalance();
syncStatus = SyncedSyncStatus();
return;
}
await updateUnspent();
await updateBalance();
_stub = await CwMweb.stub();
_syncTimer?.cancel();
_syncTimer = Timer.periodic(const Duration(milliseconds: 1500), (timer) async {
@ -255,8 +258,6 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
}
}
});
updateUnspent();
fetchBalances();
// this runs in the background and processes new utxos as they come in:
processMwebUtxos();
}
@ -538,62 +539,60 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
return true;
}
@override
Future<void> updateUnspent() async {
await super.updateUnspent();
await checkMwebUtxosSpent();
await updateAllUnspents();
}
@override
@action
Future<void> updateAllUnspents() async {
List<BitcoinUnspent> updatedUnspentCoins = [];
// get ltc unspents:
await super.updateAllUnspents();
await Future.wait(walletAddresses.allAddresses.map((address) async {
updatedUnspentCoins.addAll(await fetchUnspent(address));
}));
if (mwebEnabled) {
// update mweb unspents:
final mwebAddrs = (walletAddresses as LitecoinWalletAddresses).mwebAddrs;
mwebUtxosBox.keys.forEach((dynamic oId) {
final String outputId = oId as String;
final utxo = mwebUtxosBox.get(outputId);
if (utxo == null) {
return;
}
if (utxo.address.isEmpty) {
// not sure if a bug or a special case but we definitely ignore these
return;
}
final addressRecord = walletAddresses.allAddresses
.firstWhereOrNull((addressRecord) => addressRecord.address == utxo.address);
if (addressRecord == null) {
print("utxo contains an address that is not in the wallet: ${utxo.address}");
return;
}
final unspent = BitcoinUnspent(
addressRecord,
outputId,
utxo.value.toInt(),
mwebAddrs.indexOf(utxo.address),
);
if (unspent.vout == 0) {
unspent.isChange = true;
}
updatedUnspentCoins.add(unspent);
});
if (!mwebEnabled) {
return;
}
// add the mweb unspents to the list:
List<BitcoinUnspent> mwebUnspentCoins = [];
// update mweb unspents:
final mwebAddrs = (walletAddresses as LitecoinWalletAddresses).mwebAddrs;
mwebUtxosBox.keys.forEach((dynamic oId) {
final String outputId = oId as String;
final utxo = mwebUtxosBox.get(outputId);
if (utxo == null) {
return;
}
if (utxo.address.isEmpty) {
// not sure if a bug or a special case but we definitely ignore these
return;
}
final addressRecord = walletAddresses.allAddresses
.firstWhereOrNull((addressRecord) => addressRecord.address == utxo.address);
unspentCoins = updatedUnspentCoins;
if (addressRecord == null) {
print("utxo contains an address that is not in the wallet: ${utxo.address}");
return;
}
final unspent = BitcoinUnspent(
addressRecord,
outputId,
utxo.value.toInt(),
mwebAddrs.indexOf(utxo.address),
);
if (unspent.vout == 0) {
unspent.isChange = true;
}
mwebUnspentCoins.add(unspent);
});
unspentCoins.addAll(mwebUnspentCoins);
}
@override
Future<ElectrumBalance> fetchBalances() async {
final balance = await super.fetchBalances();
var confirmed = balance.confirmed;
var unconfirmed = balance.unconfirmed;
int confirmed = balance.confirmed;
int unconfirmed = balance.unconfirmed;
mwebUtxosBox.values.forEach((utxo) {
if (utxo.height > 0) {
confirmed += utxo.value.toInt();
@ -640,6 +639,9 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
// to have an accurate count, we should just keep it in sync with what we know from the tx history:
for (final tx in transactionHistory.transactions.values) {
// if (tx.isPending) continue;
if (tx.inputAddresses == null || tx.outputAddresses == null) {
continue;
}
final txAddresses = tx.inputAddresses! + tx.outputAddresses!;
for (final address in txAddresses) {
final addressRecord = walletAddresses.allAddresses

View file

@ -38,6 +38,10 @@ abstract class UnspentCoinsListViewModelBase with Store {
final info =
getUnspentCoinInfo(item.hash, item.address, item.amountRaw, item.vout, item.keyImage);
if (info == null) {
return;
}
info.isFrozen = item.isFrozen;
info.isSending = item.isSending;
info.note = item.note;
@ -50,15 +54,21 @@ abstract class UnspentCoinsListViewModelBase with Store {
}
}
UnspentCoinsInfo getUnspentCoinInfo(
String hash, String address, int value, int vout, String? keyImage) =>
_unspentCoinsInfo.values.firstWhere((element) =>
UnspentCoinsInfo? getUnspentCoinInfo(
String hash, String address, int value, int vout, String? keyImage) {
try {
return _unspentCoinsInfo.values.firstWhere((element) =>
element.walletId == wallet.id &&
element.hash == hash &&
element.address == address &&
element.value == value &&
element.vout == vout &&
element.keyImage == keyImage);
} catch (e) {
print("UnspentCoinsInfo not found for coin: $e");
return null;
}
}
String formatAmountToString(int fullBalance) {
if (wallet.type == WalletType.monero)
@ -108,6 +118,9 @@ abstract class UnspentCoinsListViewModelBase with Store {
try {
final info =
getUnspentCoinInfo(elem.hash, elem.address, elem.value, elem.vout, elem.keyImage);
if (info == null) {
return;
}
unspents.add(UnspentCoinsItem(
address: elem.address,