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