public async Task <IEnumerable <Coin> > FilterAsync(IList <Coin> coins)
        {
            var spentOutputs = new HashSet <OutPoint>(
                (await _spentOutputRepository.GetSpentOutputsAsync(coins.Select(o => new Output(o.Outpoint))))
                .Select(o => new OutPoint(uint256.Parse(o.TransactionHash), o.N)));

            return(coins.Where(c => !spentOutputs.Contains(c.Outpoint)));
        }
        private async Task <IEnumerable <Coin> > FilterSpentCoinsAsync(IList <Coin> coins)
        {
            var spentOutputs = new HashSet <Output>(
                (await _spentOutputRepository.GetSpentOutputsAsync(coins.Select(o => new Output(o.Reference)))),
                Output.TransactionHashNComparer);

            return(coins.Where(c => !spentOutputs.Contains(new Output(c.Reference))));
        }
Example #3
0
        /// <summary>
        /// Retrieves all utxos for a single address found in dcrdata's db + mempool.
        /// Performs basic checking to prevent double-spending of mempool transactions.
        /// </summary>
        /// <param name="address"></param>
        /// <returns></returns>
        private async Task <IEnumerable <Transaction.Input> > GetUtxosForAddress(string address)
        {
            const uint sequence = uint.MaxValue;

            // Grab transactions from dcrdata + the mempool.
            var confirmedResults = await _txRepo.GetConfirmedUtxos(address);

            var mempoolResults = await _txRepo.GetMempoolUtxos(address);

            // Remove duplicate outpoints.
            var allUtxos = confirmedResults.Concat(mempoolResults)
                           .OrderBy(r => r.BlockHeight)
                           .GroupBy(r => new { r.Hash, r.OutputIndex })
                           .Select(g => g.First())
                           .ToArray();

            // Remove already spent outputs (based on db storage)
            var spentoutputs = (await
                                _spentOutputRepository.GetSpentOutputsAsync(allUtxos.Select(p => new Output(p.Hash, p.OutputIndex)))).ToDictionary(p => p, Output.HashOutputIndexComparer);
            var notSpentUtxos = allUtxos.Where(p => !spentoutputs.ContainsKey(new Output(p.Hash, p.OutputIndex))).ToList();

            // Get all unspent transaction outputs to address
            // and map as inputs to new transaction
            return
                (from output in notSpentUtxos
                 let txHash = new Blake256Hash(HexUtil.ToByteArray(output.Hash).Reverse().ToArray())
                              let outpoint = new Transaction.OutPoint(txHash, output.OutputIndex, output.Tree)
                                             group new { outpoint, output }
                 by outpoint.ToString() into outpointGroup
                 let element = outpointGroup.First()
                               let outpoint = element.outpoint
                                              let output = element.output
                                                           select new Transaction.Input(
                     outpoint,
                     sequence,
                     output.OutputValue,
                     output.BlockHeight,
                     output.BlockIndex,
                     output.PkScript
                     ));
        }