Exemplo n.º 1
0
        public async Task <IEnumerable <Transaction> > GetTransactionsAsync(Network network, IEnumerable <uint256> txHashes, CancellationToken cancel)
        {
            var allTxs          = new List <Transaction>();
            var txHashesToQuery = new List <uint256>();

            lock (TransactionCacheLock)
            {
                var cachedTxs = TransactionCache.Where(x => txHashes.Contains(x.Key));
                allTxs.AddRange(cachedTxs.Select(x => x.Value));
                txHashesToQuery.AddRange(txHashes.Except(cachedTxs.Select(x => x.Key)));
            }

            foreach (IEnumerable <uint256> chunk in txHashesToQuery.ChunkBy(10))
            {
                cancel.ThrowIfCancellationRequested();

                using var response = await TorClient.SendAndRetryAsync(
                          HttpMethod.Get,
                          HttpStatusCode.OK,
                          $"/api/v{Constants.BackendMajorVersion}/btc/blockchain/transaction-hexes?&transactionIds={string.Join("&transactionIds=", chunk.Select(x => x.ToString()))}",
                          cancel : cancel);

                if (response.StatusCode != HttpStatusCode.OK)
                {
                    await response.ThrowRequestExceptionFromContentAsync();
                }

                using HttpContent content = response.Content;
                var retString = await content.ReadAsJsonAsync <IEnumerable <string> >();

                var ret = retString.Select(x => Transaction.Parse(x, network)).ToList();

                lock (TransactionCacheLock)
                {
                    foreach (var tx in ret)
                    {
                        tx.PrecomputeHash(false, true);
                        if (TransactionCache.TryAdd(tx.GetHash(), tx))
                        {
                            TransactionIdQueue.Enqueue(tx.GetHash());
                            if (TransactionCache.Count > 1000)                             // No more than 1000 txs in cache
                            {
                                var toRemove = TransactionIdQueue.Dequeue();
                                TransactionCache.Remove(toRemove);
                            }
                        }
                    }
                }
                allTxs.AddRange(ret);
            }

            return(allTxs.ToDependencyGraph().OrderByDependency());
        }