CW-193 Fixes for fetching of electrum transactions.

This commit is contained in:
M 2022-10-17 16:55:41 -04:00
parent 067d720cf3
commit 902935bc16
3 changed files with 56 additions and 32 deletions

View file

@ -65,8 +65,9 @@ class ElectrumClient {
socket!.listen((Uint8List event) { socket!.listen((Uint8List event) {
try { try {
final msg = utf8.decode(event.toList());
final response = final response =
json.decode(utf8.decode(event.toList())) as Map<String, dynamic>; json.decode(msg) as Map<String, dynamic>;
_handleResponse(response); _handleResponse(response);
} on FormatException catch (e) { } on FormatException catch (e) {
final msg = e.message.toLowerCase(); final msg = e.message.toLowerCase();
@ -136,14 +137,14 @@ class ElectrumClient {
return []; return [];
}); });
Future<Map<String, Object>> getBalance(String scriptHash) => Future<Map<String, dynamic>> getBalance(String scriptHash) =>
call(method: 'blockchain.scripthash.get_balance', params: [scriptHash]) call(method: 'blockchain.scripthash.get_balance', params: [scriptHash])
.then((dynamic result) { .then((dynamic result) {
if (result is Map<String, Object>) { if (result is Map<String, dynamic>) {
return result; return result;
} }
return <String, Object>{}; return <String, dynamic>{};
}); });
Future<List<Map<String, dynamic>>> getHistory(String scriptHash) => Future<List<Map<String, dynamic>>> getHistory(String scriptHash) =>
@ -151,11 +152,11 @@ class ElectrumClient {
.then((dynamic result) { .then((dynamic result) {
if (result is List) { if (result is List) {
return result.map((dynamic val) { return result.map((dynamic val) {
if (val is Map<String, Object>) { if (val is Map<String, dynamic>) {
return val; return val;
} }
return <String, Object>{}; return <String, dynamic>{};
}).toList(); }).toList();
} }
@ -170,12 +171,12 @@ class ElectrumClient {
.then((dynamic result) { .then((dynamic result) {
if (result is List) { if (result is List) {
return result.map((dynamic val) { return result.map((dynamic val) {
if (val is Map<String, Object>) { if (val is Map<String, dynamic>) {
val['address'] = address; val['address'] = address;
return val; return val;
} }
return <String, Object>{}; return <String, dynamic>{};
}).toList(); }).toList();
} }
@ -187,11 +188,11 @@ class ElectrumClient {
.then((dynamic result) { .then((dynamic result) {
if (result is List) { if (result is List) {
return result.map((dynamic val) { return result.map((dynamic val) {
if (val is Map<String, Object>) { if (val is Map<String, dynamic>) {
return val; return val;
} }
return <String, Object>{}; return <String, dynamic>{};
}).toList(); }).toList();
} }
@ -203,26 +204,26 @@ class ElectrumClient {
.then((dynamic result) { .then((dynamic result) {
if (result is List) { if (result is List) {
return result.map((dynamic val) { return result.map((dynamic val) {
if (val is Map<String, Object>) { if (val is Map<String, dynamic>) {
return val; return val;
} }
return <String, Object>{}; return <String, dynamic>{};
}).toList(); }).toList();
} }
return []; return [];
}); });
Future<Map<String, Object>> getTransactionRaw( Future<Map<String, dynamic>> getTransactionRaw(
{required String hash}) async => {required String hash}) async =>
call(method: 'blockchain.transaction.get', params: [hash, true]) call(method: 'blockchain.transaction.get', params: [hash, true])
.then((dynamic result) { .then((dynamic result) {
if (result is Map<String, Object>) { if (result is Map<String, dynamic>) {
return result; return result;
} }
return <String, Object>{}; return <String, dynamic>{};
}); });
Future<String> getTransactionHex( Future<String> getTransactionHex(

View file

@ -455,7 +455,13 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
.addresses.map((address) => electrumClient .addresses.map((address) => electrumClient
.getListUnspentWithAddress(address.address, networkType) .getListUnspentWithAddress(address.address, networkType)
.then((unspent) => unspent .then((unspent) => unspent
.map((unspent) => BitcoinUnspent.fromJSON(address, unspent))))); .map((unspent) {
try {
return BitcoinUnspent.fromJSON(address, unspent);
} catch(_) {
return null;
}
}).whereNotNull())));
unspentCoins = unspent.expand((e) => e).toList(); unspentCoins = unspent.expand((e) => e).toList();
if (unspentCoinsInfo.isEmpty) { if (unspentCoinsInfo.isEmpty) {
@ -542,8 +548,9 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
confirmations: confirmations); confirmations: confirmations);
} }
Future<ElectrumTransactionInfo> fetchTransactionInfo( Future<ElectrumTransactionInfo?> fetchTransactionInfo(
{required String hash, required int height}) async { {required String hash, required int height}) async {
try {
final tx = await getTransactionExpanded(hash: hash, height: height); final tx = await getTransactionExpanded(hash: hash, height: height);
final addresses = walletAddresses.addresses.map((addr) => addr.address).toSet(); final addresses = walletAddresses.addresses.map((addr) => addr.address).toSet();
return ElectrumTransactionInfo.fromElectrumBundle( return ElectrumTransactionInfo.fromElectrumBundle(
@ -552,6 +559,9 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
networkType, networkType,
addresses: addresses, addresses: addresses,
height: height); height: height);
} catch(_) {
return null;
}
} }
@override @override
@ -578,12 +588,20 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
}); });
final historiesWithDetails = await Future.wait( final historiesWithDetails = await Future.wait(
normalizedHistories normalizedHistories
.map((transaction) => fetchTransactionInfo( .map((transaction) {
hash: transaction['tx_hash'] as String, try {
height: transaction['height'] as int))); return fetchTransactionInfo(
hash: transaction['tx_hash'] as String,
height: transaction['height'] as int);
} catch(_) {
return Future.value(null);
}
}));
return historiesWithDetails.fold<Map<String, ElectrumTransactionInfo>>( return historiesWithDetails.fold<Map<String, ElectrumTransactionInfo>>(
<String, ElectrumTransactionInfo>{}, (acc, tx) { <String, ElectrumTransactionInfo>{}, (acc, tx) {
if (tx == null) {
return acc;
}
acc[tx.id] = acc[tx.id]?.updated(tx) ?? tx; acc[tx.id] = acc[tx.id]?.updated(tx) ?? tx;
return acc; return acc;
}); });
@ -601,7 +619,8 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
walletAddresses.updateReceiveAddresses(); walletAddresses.updateReceiveAddresses();
await transactionHistory.save(); await transactionHistory.save();
_isTransactionUpdating = false; _isTransactionUpdating = false;
} catch (e) { } catch (e, stacktrace) {
print(stacktrace);
print(e); print(e);
_isTransactionUpdating = false; _isTransactionUpdating = false;
} }

View file

@ -21,18 +21,22 @@ void startWalletSyncStatusChangeReaction(
_onWalletSyncStatusChangeReaction?.reaction.dispose(); _onWalletSyncStatusChangeReaction?.reaction.dispose();
_onWalletSyncStatusChangeReaction = _onWalletSyncStatusChangeReaction =
reaction((_) => wallet.syncStatus, (SyncStatus status) async { reaction((_) => wallet.syncStatus, (SyncStatus status) async {
if (status is ConnectedSyncStatus) { try {
await wallet.startSync(); if (status is ConnectedSyncStatus) {
await wallet.startSync();
if (wallet.type == WalletType.haven) { if (wallet.type == WalletType.haven) {
await updateHavenRate(fiatConversionStore); await updateHavenRate(fiatConversionStore);
}
} }
} if (status is SyncingSyncStatus) {
if (status is SyncingSyncStatus) { await _wakeLock.enableWake();
await _wakeLock.enableWake(); }
} if (status is SyncedSyncStatus || status is FailedSyncStatus) {
if (status is SyncedSyncStatus || status is FailedSyncStatus) { await _wakeLock.disableWake();
await _wakeLock.disableWake(); }
} catch(e) {
print(e.toString());
} }
}); });
} }