private async Task UpdateUTXO(UpdatePSBTRequest update, Repository repo, BitcoinDWaiter rpc) { AnnotatedTransactionCollection txs = null; // First, we check for data in our history foreach (var input in update.PSBT.Inputs.Where(NeedUTXO)) { txs = txs ?? await GetAnnotatedTransactions(repo, ChainProvider.GetChain(repo.Network), new DerivationSchemeTrackedSource(update.DerivationScheme)); if (txs.GetByTxId(input.PrevOut.Hash) is AnnotatedTransaction tx) { if (!tx.Record.Key.IsPruned) { input.NonWitnessUtxo = tx.Record.Transaction; } else { input.WitnessUtxo = tx.Record.ReceivedCoins.FirstOrDefault(c => c.Outpoint.N == input.Index)?.TxOut; } } } // then, we search data in the saved transactions await Task.WhenAll(update.PSBT.Inputs .Where(NeedUTXO) .Select(async(input) => { // If this is not segwit, or we are unsure of it, let's try to grab from our saved transactions if (input.NonWitnessUtxo == null) { var prev = await repo.GetSavedTransactions(input.PrevOut.Hash); if (prev.FirstOrDefault() is Repository.SavedTransaction saved) { input.NonWitnessUtxo = saved.Transaction; } } }).ToArray()); // finally, we check with rpc's txindex if (rpc?.RPCAvailable is true && rpc?.HasTxIndex is true) { var batch = rpc.RPC.PrepareBatch(); var getTransactions = Task.WhenAll(update.PSBT.Inputs .Where(NeedUTXO) .Where(input => input.NonWitnessUtxo == null) .Select(async input => { var tx = await batch.GetRawTransactionAsync(input.PrevOut.Hash, false); if (tx != null) { input.NonWitnessUtxo = tx; } }).ToArray()); await batch.SendBatchAsync(); await getTransactions; } }
private static async Task UpdateInputsUTXO(UpdatePSBTRequest update, Repository repo, BitcoinDWaiter rpc) { await Task.WhenAll(update.PSBT.Inputs .Where(NeedNonWitnessUtxo) .Where(NotFinalized) .Select(async(input) => { // If this is not segwit, or we are unsure of it, let's try to grab from our saved transactions if (input.NonWitnessUtxo == null) { var prev = await repo.GetSavedTransactions(input.PrevOut.Hash); if (prev.FirstOrDefault() is Repository.SavedTransaction saved) { input.NonWitnessUtxo = saved.Transaction; } } // Maybe we don't have the saved transaction, but we have the WitnessUTXO from the derivation scheme UTXOs if (input.NonWitnessUtxo == null) { var tx = (await repo.GetTransactions(new DerivationSchemeTrackedSource(update.DerivationScheme), input.PrevOut.Hash)).FirstOrDefault(); if (tx != null) { input.NonWitnessUtxo = tx.Transaction; } } }).ToArray()); if (rpc?.RPCAvailable is true && rpc?.HasTxIndex is true) { var batch = rpc.RPC.PrepareBatch(); var getTransactions = Task.WhenAll(update.PSBT.Inputs .Where(NeedNonWitnessUtxo) .Where(NotFinalized) .Where(input => input.NonWitnessUtxo == null) .Select(async input => { var tx = await batch.GetRawTransactionAsync(input.PrevOut.Hash, false); if (tx != null) { input.NonWitnessUtxo = tx; } }).ToArray()); await batch.SendBatchAsync(); await getTransactions; } }