computeMissingUTXODetails function
Implementation
Future<Iterable<UTXOTransaction>> computeMissingUTXODetails({
required Iterable<ElectrumTransactionInfo> txList,
required Iterable<NodeWithAddress> nodes,
required Iterable<AddressType> addressTypes,
required UTXONetworkType type,
required List<(String, int)> endpoints,
}) async {
final coin = type.coin;
if (txList.isEmpty) return [];
final watch = Stopwatch()..start();
final clients = await createClients(endpoints: endpoints, token: coin);
final batchSize = clients.length;
if (batchSize == 0) {
throw Exception(
"No clients available for fetching UTXO details. for token: ${coin.symbol}",
);
}
final pool = List<ElectrumTransactionInfo>.from(txList);
final nodeMap = <String, int>{};
Future<Iterable<UTXOTransaction>> fetchFromPool(
ElectrumXClient initalClient,
) async {
final txs = <UTXOTransaction>[];
var client = initalClient;
while (pool.isNotEmpty) {
final txInfo = pool.removeLast();
final (tx, newClient, _) = await fetchFromRandomElectrumXNode(
(client) {
return client.getTransaction(
txHash: txInfo.hash,
addressTypes: addressTypes,
nodes: nodes,
type: type,
);
},
client: client,
endpoints: endpoints,
token: coin,
timeout: Duration(seconds: 5),
);
if (tx == null) {
Logger.logWarning(
"Failed to fetch TX ${txInfo.hash} from ${client.host}");
txs.add(txInfo.getNotAvailableUTXOTransaction(type.coin));
continue;
}
if (newClient != null) client = newClient;
nodeMap[client.host] = (nodeMap[client.host] ?? 0) + 1;
txs.add(tx);
}
return txs;
}
final futures = [
for (final client in clients) fetchFromPool(client),
];
final results = await Future.wait(futures);
final txs = results.expand((e) => e).toList();
watch.stop();
Logger.logFetch(
"Fetched ${txs.length} transactions in ${watch.elapsed}",
);
///
/// Disconnect Clients
///
await Future.wait([
for (final client in clients) client.disconnect(),
]);
return txs;
}