private async Task IndexBlocksAsync(long blockNumber, long lastConfirmedBlockNumber)
        {
            var batchSize = _blockBatchSize ?? 1000;

            var processEventsTasks = new List <Task>();

            for (var i = blockNumber; i <= lastConfirmedBlockNumber; i += batchSize)
            {
                var batchTo = Math.Min(i + batchSize, lastConfirmedBlockNumber);

                var transactionLogs = await _ethereumNodeJobClient.GetTransactionsLogs(blockNumber, batchTo);

                var processLogsTask = ProcessEventLogs(transactionLogs);

                processEventsTasks.Add(processLogsTask);
            }

            await Task.WhenAll(processEventsTasks);

            await _indexingStateRepository.SaveLastIndexedBlockNumber(lastConfirmedBlockNumber);

            _lastIndexedBlock = lastConfirmedBlockNumber;

            _log.Info($"Blocks from [{blockNumber}] to [{lastConfirmedBlockNumber}] has been indexed.");
        }
        private async Task <IndexedBlock> IndexBlockAsync(
            long blockNumber)
        {
            var block = await _web3.Eth.Blocks.GetBlockWithTransactionsHashesByNumber.SendRequestAsync(blockNumber);

            #region Logging

            _log.Debug
            (
                $"Got block [{blockNumber}] from RPC node.",
                new { BlockNumber = blockNumber }
            );

            #endregion

            // workaround to decrease the num,ber of parallel calls to blockchain node
            var transactions = await _web3.Eth.Transactions.GetTransactionsAsync(block.TransactionHashes);

            var receipts = await _web3.Eth.Transactions.GetReceiptsAsync(block.TransactionHashes);

            #region Logging

            _log.Debug
            (
                $"Got {block.TransactionHashes.Length} transactions and receipts for block [{blockNumber}] from RPC node.",
                new { BlockNumber = blockNumber }
            );

            #endregion

            var indexedBlock = NethereumBlockMapper.MapBlock(block, transactions, receipts);

            await Task.WhenAll(
                _transactionRepository.SaveBlockTransactionsAsync(indexedBlock),
                _indexingStateRepository.SaveLastIndexedBlockNumber(indexedBlock.Number));

            #region Logging

            _log.Debug
            (
                $"Block [{blockNumber}] has been saved to DB.",
                new { BlockNumber = blockNumber }
            );

            #endregion

            return(indexedBlock);
        }
示例#3
0
        private async Task <bool> IndexBlockAsync(long blockNumber, string context)
        {
            _log.Info($"Block {blockNumber} indexing started", context: context);

            var blockWithTransactions =
                await _retryPolicy.ExecuteAsync(() => _ethNodeClient.GetBlockWithTransactionHashesAsync(blockNumber));

            if (blockWithTransactions == null)
            {
                return(false);
            }

            var transactionReceipts =
                await _retryPolicy.ExecuteAsync(() => _ethNodeClient.GetTransactionReceiptsAsync(blockWithTransactions));

            if (transactionReceipts.Any(receipts => receipts == null))
            {
                return(false);
            }

            _log.Info($"Info about block", context: new
            {
                blockNumber,
                blockWithTransactions.Number,
                Count = blockWithTransactions.TransactionHashes?.Length,
                blockWithTransactions.Timestamp,
                blockWithTransactions.Nonce,
                blockWithTransactions.Author
            });

            foreach (var transactionReceipt in transactionReceipts)
            {
                if (transactionReceipt.Status.Value == 1)
                {
                    var undecodedEvents                 = ProcessUndecodedEvents(transactionReceipt);
                    var collectedFeesEvents             = ProcessFeeCollectedEvents(transactionReceipt);
                    var completedTransactionEvents      = ProcessCompletedTransactionAsync(transactionReceipt);
                    var processCustomerRegisteredEvents = ProcessCustomerRegisteredEvents(transactionReceipt);
                    var processMintEvents               = ProcessMintEvents(transactionReceipt);
                    var processTransferEvents           = ProcessTransferEvents(transactionReceipt);
                    var processStakeIncreasedEvents     = ProcessStakeIncreasedEvents(transactionReceipt);
                    var processStakeDecreasedEvents     = ProcessStakeDecreasedEvents(transactionReceipt);
                    var processSeizedFromEvents         = ProcessSeizedEvents(transactionReceipt);

                    await Task.WhenAll(
                        completedTransactionEvents,
                        processCustomerRegisteredEvents,
                        processMintEvents,
                        processTransferEvents,
                        undecodedEvents,
                        processStakeDecreasedEvents,
                        processStakeIncreasedEvents,
                        collectedFeesEvents,
                        processSeizedFromEvents);
                }
                else
                {
                    await ProcessFailedTransactionAsync(transactionReceipt);
                }
            }

            await _indexingStateRepository.SaveLastIndexedBlockNumber(blockNumber);

            _lastIndexedBlock = blockNumber;

            #region Logging

            _log.Info(
                $"Block [{blockNumber}] has been indexed.",
                new { blockNumber, blockHash = blockWithTransactions.BlockHash, context });

            #endregion

            return(true);
        }