Пример #1
0
        public async Task When_Cancellation_Is_Requested_Does_Not_Call_Processor()
        {
            var eventLogProxy     = new Mock <IEventLogProxy>();
            var catchAllProcessor = new Mock <ILogProcessor>();

            var logProcessor = new BlockchainLogProcessor(
                eventLogProxy.Object, new [] { catchAllProcessor.Object });

            catchAllProcessor
            .Setup(p => p.IsLogForEvent(It.IsAny <FilterLog>()))
            .Returns(true);

            var logs = new [] { new FilterLog() };

            var cancellationToken = new CancellationTokenSource();

            //fake cancellation being raised after logs are retrieved but before processing
            eventLogProxy
            .Setup(p => p.GetLogs(It.IsAny <NewFilterInput>(), null))
            .Callback <NewFilterInput, object>((f, o) => cancellationToken.Cancel())
            .ReturnsAsync(logs);

            await logProcessor.ProcessAsync(new BlockRange(0, 10), cancellationToken.Token);

            catchAllProcessor
            .Verify(p => p.IsLogForEvent(It.IsAny <FilterLog>()), Times.Never);
        }
Пример #2
0
        public async Task Dedupes_Logs_Matching_Multiple_Filters()
        {
            var eventLogProxy     = new Mock <IEventLogProxy>();
            var catchAllProcessor = new Mock <ILogProcessor>();

            var filter1 = new NewFilterInput();
            var filter2 = new NewFilterInput();
            var filters = new[] { filter1, filter2 };

            var mockProcessors = new[] { catchAllProcessor };

            var logProcessor = new BlockchainLogProcessor(
                eventLogProxy.Object, mockProcessors.Select(p => p.Object), filters);

            var log1 = new FilterLog()
            {
                TransactionHash = "x", LogIndex = new HexBigInteger(0)
            };
            var duplicateLog = new FilterLog()
            {
                TransactionHash = "x", LogIndex = new HexBigInteger(0)
            };
            var log2 = new FilterLog()
            {
                TransactionHash = "y", LogIndex = new HexBigInteger(0)
            };

            var logsFromFilter1 = new [] { log1, duplicateLog };
            var logsFromFilter2 = new [] { log2, duplicateLog };

            catchAllProcessor
            .Setup(p => p.IsLogForEvent(It.IsAny <FilterLog>()))
            .Returns(true);

            eventLogProxy
            .Setup(p => p.GetLogs(filter1, null))
            .ReturnsAsync(logsFromFilter1);

            eventLogProxy
            .Setup(p => p.GetLogs(filter2, null))
            .ReturnsAsync(logsFromFilter2);

            var processedLogs = new List <FilterLog>();

            catchAllProcessor.Setup(p => p.ProcessLogsAsync(It.IsAny <FilterLog[]>()))
            .Callback <FilterLog[]>(l => processedLogs.AddRange(l))
            .Returns(Task.CompletedTask);

            await logProcessor.ProcessAsync(new BlockRange(0, 0));

            Assert.Equal(2, processedLogs.Count);
            Assert.Contains(log1, processedLogs);
            Assert.Contains(log2, processedLogs);
            Assert.DoesNotContain(duplicateLog, processedLogs);
        }
Пример #3
0
        public static BlokchainBatchProcessorService InitialiseBlockchainBatchProcessorService(CloudTable workProcesssTable,
                                                                                               CloudTable workProcessRegistryTable,
                                                                                               WorkDataLogProcessor workProcessorService, TextWriter logWriter, Web3 web3)
        {
            var workProcessRepository             = new ProcessInfoRepository(workProcesssTable);
            var workRegistryProcessInfoRepository = new ProcessInfoRepository(workProcessRegistryTable);
            var blockchainLogProcessor            = new BlockchainLogProcessor(new [] { workProcessorService }, web3);
            var logger = new TextWriterLogger(logWriter);
            var childBlockchainProcessorService = new ChildBlockBlockchainProcessProgressService(workRegistryProcessInfoRepository,
                                                                                                 ConfigurationSettings.StartProcessFromBlockNumber(), workProcessRepository
                                                                                                 );

            return(new BlokchainBatchProcessorService(blockchainLogProcessor, logger, childBlockchainProcessorService,
                                                      50));
        }
Пример #4
0
        public async Task UsingTheIndividualComponents()
        {
            TransferMetadata.CurrentChainUrl = BlockchainUrl;

            var blockchainProxyService =
                new BlockchainProxyService(BlockchainUrl);

            using (var azureSearchService = new AzureSearchService(AzureSearchServiceName, _azureSearchApiKey))
            {
                await azureSearchService.DeleteIndexAsync(AzureTransferIndexName);

                try
                {
                    using (var transferIndexer =
                               await azureSearchService.CreateEventIndexer <TransferEvent_ERC20>(AzureTransferIndexName))
                    {
                        using (var transferProcessor =
                                   new EventIndexProcessor <TransferEvent_ERC20>(transferIndexer))
                        {
                            var logProcessor = new BlockchainLogProcessor(
                                blockchainProxyService,
                                new ILogProcessor[] { transferProcessor });

                            var progressRepository =
                                new JsonBlockProgressRepository(CreateJsonFileToHoldProgress());

                            var progressService = new StaticBlockRangeProgressService(
                                3146684, 3146694, progressRepository);

                            var batchProcessorService = new BlockchainBatchProcessorService(
                                logProcessor, progressService, maxNumberOfBlocksPerBatch: 2);

                            BlockRange?lastBlockRangeProcessed;
                            do
                            {
                                lastBlockRangeProcessed = await batchProcessorService.ProcessLatestBlocksAsync();
                            } while (lastBlockRangeProcessed != null);

                            Assert.Equal(19, transferIndexer.Indexed);
                        }
                    }
                }
                finally
                {
                    await azureSearchService.DeleteIndexAsync(AzureTransferIndexName);
                }
            }
        }
Пример #5
0
        public async Task Allocates_Matching_Logs_To_Processors()
        {
            var eventLogProxy     = new Mock <IEventLogProxy>();
            var log1Processor     = new Mock <ILogProcessor>();
            var log2Processor     = new Mock <ILogProcessor>();
            var catchAllProcessor = new Mock <ILogProcessor>();

            var mockProcessors = new[] { log1Processor, log2Processor, catchAllProcessor };

            var logProcessor = new BlockchainLogProcessor(
                eventLogProxy.Object, mockProcessors.Select(p => p.Object));

            var log1 = new FilterLog();
            var log2 = new FilterLog();
            var log3 = new FilterLog();

            var logs = new [] { log1, log2, log3 };

            log1Processor.Setup(p => p.IsLogForEvent(log1)).Returns(true);
            log2Processor.Setup(p => p.IsLogForEvent(log2)).Returns(true);

            catchAllProcessor
            .Setup(p => p.IsLogForEvent(It.IsAny <FilterLog>()))
            .Returns(true);

            eventLogProxy
            .Setup(p => p.GetLogs(It.IsAny <NewFilterInput>(), null))
            .ReturnsAsync(logs);

            var processedLogs = new Dictionary <Mock <ILogProcessor>, List <FilterLog> >();

            foreach (var processor in mockProcessors)
            {
                processedLogs.Add(processor, new List <FilterLog>());

                processor.Setup(p => p.ProcessLogsAsync(It.IsAny <FilterLog[]>()))
                .Callback <FilterLog[]>(l => processedLogs[processor].AddRange(l))
                .Returns(Task.CompletedTask);
            }

            await logProcessor.ProcessAsync(new BlockRange(0, 0));

            Assert.Single(processedLogs[log1Processor], log1);
            Assert.Single(processedLogs[log2Processor], log2);
            Assert.True(logs.SequenceEqual(processedLogs[catchAllProcessor]));
        }
Пример #6
0
        public async Task Checks_For_Cancellation_Before_Each_Processing_Batch()
        {
            var eventLogProxy      = new Mock <IEventLogProxy>();
            var catchAllProcessor1 = new Mock <ILogProcessor>();
            var catchAllProcessor2 = new Mock <ILogProcessor>();

            catchAllProcessor1
            .Setup(p => p.IsLogForEvent(It.IsAny <FilterLog>()))
            .Returns(true);

            catchAllProcessor2
            .Setup(p => p.IsLogForEvent(It.IsAny <FilterLog>()))
            .Returns(true);

            var logProcessor = new BlockchainLogProcessor(
                eventLogProxy.Object, new [] { catchAllProcessor1.Object, catchAllProcessor2.Object });

            var logs = new [] { new FilterLog() };

            var cancellationToken = new CancellationTokenSource();

            eventLogProxy
            .Setup(p => p.GetLogs(It.IsAny <NewFilterInput>(), null))
            .ReturnsAsync(logs);

            //cancel after processor 1 finishes
            catchAllProcessor1
            .Setup(p => p.ProcessLogsAsync(It.IsAny <FilterLog[]>()))
            .Callback <FilterLog[]>(l => cancellationToken.Cancel())
            .Returns(Task.CompletedTask);

            await logProcessor.ProcessAsync(new BlockRange(0, 10), cancellationToken.Token);

            catchAllProcessor1
            .Verify(p => p.ProcessLogsAsync(It.IsAny <FilterLog[]>()), Times.Once);

            catchAllProcessor2
            .Verify(p => p.ProcessLogsAsync(It.IsAny <FilterLog[]>()), Times.Never);
        }
Пример #7
0
        public async Task Passes_Correct_Block_Range_To_Proxy()
        {
            var eventLogProxy = new Mock <IEventLogProxy>();

            var logProcessor = new BlockchainLogProcessor(
                eventLogProxy.Object, Array.Empty <ILogProcessor>());

            var logs = Array.Empty <FilterLog>();

            NewFilterInput actualFilter = null;

            eventLogProxy
            .Setup(p => p.GetLogs(It.IsAny <NewFilterInput>(), null))
            .Callback <NewFilterInput, object>((f, o) => actualFilter = f)
            .ReturnsAsync(logs);

            await logProcessor.ProcessAsync(new BlockRange(0, 10));

            Assert.NotNull(actualFilter);
            Assert.Equal(0, actualFilter.FromBlock.BlockNumber.Value);
            Assert.Equal(10, actualFilter.ToBlock.BlockNumber.Value);
        }
Пример #8
0
        public virtual async Task <ulong> ProcessAsync(ulong from, ulong?to = null, CancellationTokenSource ctx = null, Action <uint, BlockRange> rangeProcessedCallback = null)
        {
            if (!LogProcessors.Any())
            {
                throw new InvalidOperationException("No events to capture - use AddEventAsync to add listeners for indexable events");
            }

            var logProcessor = new BlockchainLogProcessor(
                BlockchainProxyService,
                LogProcessors,
                Filters);

            IBlockProgressService progressService = CreateProgressService(from, to);

            var batchProcessorService = new BlockchainBatchProcessorService(
                logProcessor, progressService, maxNumberOfBlocksPerBatch: MaxBlocksPerBatch);

            if (to != null)
            {
                return(await ProcessRange(ctx, rangeProcessedCallback, batchProcessorService));
            }

            return(await batchProcessorService.ProcessContinuallyAsync(ctx?.Token ?? new CancellationToken(), rangeProcessedCallback));
        }