private async Task TransactionsDSCheckAsync(NBitcoin.Block block, long blockInternalId) { // Inputs are flattened along with transactionId so they can be checked for double spends. var allTransactionInputs = block.Transactions.SelectMany(x => x.Inputs.AsIndexedInputs(), (tx, txIn) => new { TxId = tx.GetHash().ToBytes(), TxInput = txIn }).Select(x => new TxWithInput { TxExternalId = x.TxId, PrevTxId = x.TxInput.PrevOut.Hash.ToBytes(), Prev_N = x.TxInput.PrevOut.N }); // Insert raw data and let the database queries find double spends await txRepository.CheckAndInsertBlockDoubleSpendAsync(allTransactionInputs, appSettings.DeltaBlockHeightForDoubleSpendCheck, blockInternalId); // If any new double spend records were generated we need to update them with transaction payload // and trigger notification events var dsTxIds = await txRepository.GetDSTxWithoutPayloadAsync(); foreach (var(dsTxId, TxId) in dsTxIds) { var payload = block.Transactions.Single(x => x.GetHash() == new uint256(dsTxId)).ToBytes(); await txRepository.UpdateDsTxPayloadAsync(dsTxId, payload); var notificationEvent = new NewNotificationEvent() { CreationDate = clock.UtcNow(), NotificationType = CallbackReason.DoubleSpend, TransactionId = TxId }; eventBus.Publish(notificationEvent); } await txRepository.SetBlockParsedForDoubleSpendDateAsync(blockInternalId); }