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)))); }
/// <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 )); }