Пример #1
0
        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);
        }