private async Task InsertTxBlockLinkAsync(NBitcoin.Block block, long blockInternalId) { var txsToCheck = await txRepository.GetTxsNotInCurrentBlockChainAsync(blockInternalId); var txIdsFromBlock = new HashSet <uint256>(block.Transactions.Select(x => x.GetHash())); // Generate a list of transactions that are present in the last block and are also present in our database without a link to existing block var transactionsForMerkleProofCheck = txsToCheck.Where(x => txIdsFromBlock.Contains(x.TxExternalId)).ToArray(); await txRepository.InsertTxBlockAsync(transactionsForMerkleProofCheck.Select(x => x.TxInternalId).ToList(), blockInternalId); foreach (var transaction in transactionsForMerkleProofCheck) { var notificationEvent = new NewNotificationEvent() { CreationDate = clock.UtcNow(), NotificationType = CallbackReason.MerkleProof, TransactionId = transaction.TxExternalIdBytes }; eventBus.Publish(notificationEvent); } }
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); }