Beispiel #1
0
        public async Task IndexingAdditionalInformationPerEvent()
        {
            using (var processor =
                       new AzureEventIndexingProcessor(AzureSearchServiceName, _azureSearchApiKey, BlockchainUrl))
            {
                await ClearDown(processor);

                try
                {
                    var transferEventProcessor = await processor.AddAsync <TransferEvent_Extended>(AzureTransferIndexName);

                    await processor.ProcessAsync(3146684, 3146694);

                    await Task.Delay(5000); // leave time for index

                    var customIndexer = transferEventProcessor.Indexer as IAzureIndex;

                    var searchByMachineNameQuery = Environment.MachineName;
                    var searchResult             = await customIndexer.SearchAsync(searchByMachineNameQuery);

                    Assert.Equal(19, searchResult.Count);

                    //all should have our custom metadata which is not provided by the blockchain
                    foreach (var result in searchResult.Results)
                    {
                        var indexedOnTimestamp = result.Document["metadata_indexedon"];
                        Assert.NotNull(indexedOnTimestamp);
                    }
                }
                finally
                {
                    await ClearDown(processor);
                }
            }
        }
Beispiel #2
0
        public async Task WithAFilter()
        {
            var filter = new FilterInputBuilder <TransferEvent_ERC20>()
                         .AddTopic(tfr => tfr.To, "0xdfa70b70b41d77a7cdd8b878f57521d47c064d8c")
                         .Build(contractAddress: "0x3678FbEFC663FC28336b93A1FA397B67ae42114d",
                                blockRange: new BlockRange(3860820, 3860820));

            using (var processor =
                       new AzureEventIndexingProcessor(
                           AzureSearchServiceName,
                           _azureSearchApiKey,
                           BlockchainUrl,
                           filters: new[] { filter }))
            {
                await ClearDown(processor);

                try
                {
                    await processor.AddAsync <TransferEvent_ERC20>(AzureTransferIndexName);

                    var blocksProcessed = await processor.ProcessAsync(3860820, 3860820);

                    Assert.Equal((ulong)1, blocksProcessed);
                    Assert.Equal(1, processor.Indexers[0].Indexed);
                }
                finally
                {
                    await ClearDown(processor);
                }
            }
        }
Beispiel #3
0
        public async Task StoringCustomSearchDocuments_UsingMapper()
        {
            using (var processor =
                       new AzureEventIndexingProcessor(AzureSearchServiceName, _azureSearchApiKey, BlockchainUrl))
            {
                await ClearDown(processor);

                //create an azure index definition based on a custom Dto
                //the processor will create the index if it does not already exist
                var index = CreateAzureIndexDefinition();

                var mapper = new CustomEventToSearchDocumentMapper();

                try
                {
                    //inject a mapping func to translate our event to a doc to store in the index
                    await processor.AddAsync <TransferEvent_ERC20, CustomTransferSearchDocumentDto>(index, mapper);

                    var blocksProcessed = await processor.ProcessAsync(3146684, 3146694);

                    Assert.Equal((ulong)11, blocksProcessed);
                    Assert.Equal(1, processor.Indexers.Count);
                    Assert.Equal(19, processor.Indexers[0].Indexed);
                }
                finally
                {
                    await ClearDown(processor);
                }
            }
        }
Beispiel #4
0
        public async Task StartHere()
        {
            using (var processor =
                       new AzureEventIndexingProcessor(AzureSearchServiceName, _azureSearchApiKey, BlockchainUrl))
            {
                #region test preparation
                await processor.ClearProgress();

                await processor.SearchService.DeleteIndexAsync(AzureTransferIndexName);

                #endregion

                await processor.AddEventAsync <TransferEvent_ERC20>(AzureTransferIndexName);

                var blocksProcessed = await processor.ProcessAsync(3146684, 3146694);

                Assert.Equal((ulong)11, blocksProcessed);
                Assert.Equal(1, processor.Indexers.Count);
                Assert.Equal(6, processor.Indexers[0].Indexed);

                #region test clean up
                await processor.ClearProgress();

                await processor.SearchService.DeleteIndexAsync(AzureTransferIndexName);

                #endregion
            }
        }
Beispiel #5
0
        public async Task IndexTransferEventAndFunction()
        {
            using (var processor =
                       new AzureEventIndexingProcessor(AzureSearchServiceName, _azureSearchApiKey, BlockchainUrl))
            {
                await ClearDown(processor);

                try
                {
                    //reusable function handler which incorporates a function indexer
                    //the function indexer won't do anything yet
                    //it must be linked to an event processor before functions are indexed
                    var transferFunctionHandler =
                        await processor.CreateFunctionHandlerAsync <TransferFunction>(TransferFunctionIndexName);

                    //reusable function handler which incorporates a function indexer
                    //the function indexer won't do anything yet
                    //it must be linked to an event processor before functions are indexed
                    var transferFromFunctionHandler =
                        await processor.CreateFunctionHandlerAsync <TransferFromFunction>(TransferFromFunctionIndexName);

                    //create an indexer for the transfer event
                    //link our function handlers so that functions related to the event are indexed
                    await processor.AddAsync <TransferEvent_ERC20>(TransferEventIndexName, new ITransactionHandler[]
                    {
                        transferFunctionHandler, transferFromFunctionHandler
                    });

                    //process the range
                    await processor.ProcessAsync(3900007, 3900030);

                    //allow time for azure indexing to finish
                    await Task.Delay(TimeSpan.FromSeconds(5));

                    //ensure we have written to the expected indexes
                    long transferEventCount = await processor.SearchService.CountDocumentsAsync(TransferEventIndexName);

                    long transferFunctionCount =
                        await processor.SearchService.CountDocumentsAsync(TransferFunctionIndexName);

                    long transferFromFunctionCount =
                        await processor.SearchService.CountDocumentsAsync(TransferFromFunctionIndexName);

                    Assert.Equal(32, transferEventCount);
                    Assert.Equal(1, transferFunctionCount);
                    Assert.Equal(3, transferFromFunctionCount);
                }
                finally
                {
                    await ClearDown(processor);
                }
            }
        }
Beispiel #6
0
        public async Task RunContinually()
        {
            var web3 = new Web3.Web3(BlockchainUrl);
            var currentBlockNumber = (ulong)(await web3.Eth.Blocks.GetBlockNumber.SendRequestAsync()).Value;
            var startingBlock      = currentBlockNumber - 10;
            var maxBlock           = currentBlockNumber + 1;

            const ulong expectedBlocks = 12;  // current block + 10 + 1

            using (var processor =
                       new AzureEventIndexingProcessor(
                           AzureSearchServiceName, _azureSearchApiKey, BlockchainUrl, maxBlocksPerBatch: 1, minBlockConfirmations: 0))
            {
                #region test preparation
                await processor.ClearProgress();

                await processor.SearchService.DeleteIndexAsync(AzureTransferIndexName);

                #endregion

                await processor.AddEventAsync <TransferEvent_ERC20>(AzureTransferIndexName);

                var cancellationToken = new CancellationTokenSource();
                var escapeHatch       = new Action <uint, BlockRange>((rangesProcessed, lastRange) =>
                {
                    if (lastRange.To >= maxBlock) // escape hatch!
                    {
                        cancellationToken.Cancel();
                    }
                });

                var blocksProcessed = await processor.ProcessAsync(startingBlock,
                                                                   ctx : cancellationToken, rangeProcessedCallback : escapeHatch);

                Assert.Equal(expectedBlocks, blocksProcessed);

                #region test clean up
                await processor.ClearProgress();

                await processor.SearchService.DeleteIndexAsync(AzureTransferIndexName);

                #endregion
            }
        }
Beispiel #7
0
        public async Task IndexingTransferEventsWithDifferingSignatures()
        {
            using (var processor =
                       new AzureEventIndexingProcessor(AzureSearchServiceName, _azureSearchApiKey, BlockchainUrl))
            {
                #region test preparation
                await processor.ClearProgress();

                await processor.SearchService.DeleteIndexAsync(AzureTransferIndexName);

                #endregion

                await processor.AddEventAsync <TransferEvent_With3Indexes>(AzureTransferIndexName);

                await processor.AddEventAsync <TransferEvent_ERC20>(AzureTransferIndexName);

                var blocksProcessed = await processor.ProcessAsync(3146684, 3146694);

                Assert.Equal((ulong)11, blocksProcessed);
                Assert.Equal(2, processor.Indexers.Count);
                Assert.Equal(6, processor.Indexers[0].Indexed);
                Assert.Equal(19, processor.Indexers[1].Indexed);

                await Task.Delay(5000); // leave time for index

                var customIndexer = processor.Indexers[0] as IAzureSearchIndex;
                var erc20Indexer  = processor.Indexers[1] as IAzureSearchIndex;

                //the indexers wrap the same underlying azure index
                //this azure index should have documents for both transfer event types
                Assert.Equal(25, await erc20Indexer.DocumentCountAsync());
                Assert.Equal(25, await customIndexer.DocumentCountAsync());

                #region test clean up
                await processor.ClearProgress();

                await processor.SearchService.DeleteIndexAsync(AzureTransferIndexName);

                #endregion
            }
        }
Beispiel #8
0
        public async Task RunContinually()
        {
            var web3 = new Web3.Web3(BlockchainUrl);
            var currentBlockNumber = (ulong)(await web3.Eth.Blocks.GetBlockNumber.SendRequestAsync()).Value;
            var startingBlock      = currentBlockNumber - 9;
            var maxBlock           = currentBlockNumber;

            const ulong expectedBlocks = 10;

            using (var processor =
                       new AzureEventIndexingProcessor(
                           AzureSearchServiceName, _azureSearchApiKey, BlockchainUrl, maxBlocksPerBatch: 1, minBlockConfirmations: 0))
            {
                await ClearDown(processor);

                try
                {
                    await processor.AddAsync <TransferEvent_ERC20>(AzureTransferIndexName);

                    var cancellationToken = new CancellationTokenSource();
                    var shortCircuit      = new Action <LogBatchProcessedArgs>((args) =>
                    {
                        if (args.LastRangeProcessed.To.Value >= maxBlock) // escape hatch!
                        {
                            cancellationToken.Cancel();
                        }
                    });

                    var blocksProcessed = await processor.ProcessAsync(startingBlock,
                                                                       ctx : cancellationToken, logBatchProcessedCallback : shortCircuit);

                    Assert.Equal(expectedBlocks, blocksProcessed);
                }
                finally
                {
                    await ClearDown(processor);
                }
            }
        }
Beispiel #9
0
        public async Task StoringCustomSearchDocuments_UsingMapping()
        {
            using (var processor =
                       new AzureEventIndexingProcessor(AzureSearchServiceName, _azureSearchApiKey, BlockchainUrl))
            {
                await ClearDown(processor);

                //create an azure index definition based on a custom Dto
                //the processor will create the index if it does not already exist
                Index index = CreateAzureIndexDefinition();

                try
                {
                    //inject a mapping func to translate our event to a doc to store in the index
                    await processor.AddAsync <TransferEvent_ERC20, CustomTransferSearchDocumentDto>(index, (e) =>
                                                                                                    new CustomTransferSearchDocumentDto
                    {
                        From        = e.Event.From,
                        To          = e.Event.To,
                        Value       = e.Event.Value.ToString(),
                        BlockNumber = e.Log.BlockNumber.Value.ToString(),
                        TxHash      = e.Log.TransactionHash,
                        LogAddress  = e.Log.Address,
                        LogIndex    = (int)e.Log.LogIndex.Value,
                        DocumentKey = $"{e.Log.TransactionHash}_{e.Log.LogIndex.Value}"
                    });

                    var blocksProcessed = await processor.ProcessAsync(3146684, 3146694);

                    Assert.Equal((ulong)11, blocksProcessed);
                    Assert.Equal(1, processor.Indexers.Count);
                    Assert.Equal(19, processor.Indexers[0].Indexed);
                }
                finally
                {
                    await ClearDown(processor);
                }
            }
        }
Beispiel #10
0
        public async Task StartHere()
        {
            using (var processor =
                       new AzureEventIndexingProcessor(AzureSearchServiceName, _azureSearchApiKey, BlockchainUrl))
            {
                await ClearDown(processor);

                try
                {
                    var transferEventProcessor = await processor.AddAsync <TransferEvent_ERC20>(AzureTransferIndexName);

                    var blocksProcessed = await processor.ProcessAsync(3146684, 3146694);

                    Assert.Equal((ulong)11, blocksProcessed);
                    Assert.Equal(19, transferEventProcessor.Indexer.Indexed);
                }
                finally
                {
                    await ClearDown(processor);
                }
            }
        }
Beispiel #11
0
        public async Task IndexingAdditionalInformationPerEvent()
        {
            using (var processor =
                       new AzureEventIndexingProcessor(AzureSearchServiceName, _azureSearchApiKey, BlockchainUrl))
            {
                #region test preparation
                await processor.ClearProgress();

                await processor.SearchService.DeleteIndexAsync(AzureTransferIndexName);

                #endregion

                await processor.AddEventAsync <TransferEvent_Extended>(AzureTransferIndexName);

                await processor.ProcessAsync(3146684, 3146694);

                await Task.Delay(5000); // leave time for index

                var customIndexer = processor.Indexers[0] as IAzureSearchIndex;

                var query        = "0x90df9bcd9608696df90c0baf5faefd2399bba0d2";
                var searchResult = await customIndexer.SearchAsync(query, new List <string>());

                Assert.Equal(1, searchResult.Count);

                //all should have our custom metadata which is not provided by the blockchain
                foreach (var result in searchResult.Results)
                {
                    Assert.Equal(Environment.MachineName, result.Document["metadata_indexingmachinename"]);
                }

                #region test clean up
                await processor.ClearProgress();

                await processor.SearchService.DeleteIndexAsync(AzureTransferIndexName);

                #endregion
            }
        }
Beispiel #12
0
        public async Task IndexingTransferEventsWithDifferingSignatures()
        {
            using (var processor =
                       new AzureEventIndexingProcessor(AzureSearchServiceName, _azureSearchApiKey, BlockchainUrl))
            {
                await ClearDown(processor);

                try
                {
                    await processor.AddAsync <TransferEvent_With3Indexes>(AzureTransferIndexName);

                    await processor.AddAsync <TransferEvent_ERC20>(AzureTransferIndexName);

                    var blocksProcessed = await processor.ProcessAsync(3146684, 3146694);

                    Assert.Equal((ulong)11, blocksProcessed);
                    Assert.Equal(2, processor.Indexers.Count);
                    Assert.Equal(6, processor.Indexers[0].Indexed);
                    Assert.Equal(19, processor.Indexers[1].Indexed);

                    await Task.Delay(5000); // leave time for index

                    var customIndexer = processor.Indexers[0] as IIndexer;
                    var erc20Indexer  = processor.Indexers[1] as IIndexer;

                    //the indexers wrap the same underlying azure index
                    //this azure index should have documents for both transfer event types
                    Assert.Equal(25, await erc20Indexer.DocumentCountAsync());
                    Assert.Equal(25, await customIndexer.DocumentCountAsync());
                }
                finally
                {
                    await ClearDown(processor);
                }
            }
        }
Beispiel #13
0
        public async Task WithAFilter()
        {
            var filter = new NewFilterInputBuilder <TransferEvent_ERC20>()
                         .AddTopic(tfr => tfr.To, "0xdfa70b70b41d77a7cdd8b878f57521d47c064d8c")
                         .Build(contractAddress: "0x3678FbEFC663FC28336b93A1FA397B67ae42114d",
                                blockRange: new BlockRange(3860820, 3860820));

            using (var processor =
                       new AzureEventIndexingProcessor(
                           AzureSearchServiceName,
                           _azureSearchApiKey,
                           BlockchainUrl,
                           filters: new[] { filter }))
            {
                #region test preparation
                await processor.ClearProgress();

                await processor.SearchService.DeleteIndexAsync(AzureTransferIndexName);

                #endregion

                await processor.AddEventAsync <TransferEvent_ERC20>(AzureTransferIndexName);

                var blocksProcessed = await processor.ProcessAsync(3860820, 3860820);

                Assert.Equal((ulong)1, blocksProcessed);
                Assert.Equal(1, processor.Indexers[0].Indexed);

                #region test clean up
                await processor.ClearProgress();

                await processor.SearchService.DeleteIndexAsync(AzureTransferIndexName);

                #endregion
            }
        }
Beispiel #14
0
        public async Task StoringCustomSearchDocuments()
        {
            using (var processor =
                       new AzureEventIndexingProcessor(AzureSearchServiceName, _azureSearchApiKey, BlockchainUrl))
            {
                await ClearDown(processor);

                try
                {
                    //define our azure index for transfer function data
                    var transferFunctionIndex = new Index
                    {
                        Name   = TransferFunctionIndexName,
                        Fields =
                            new List <Field>
                        {
                            new Field("TransactionHash", DataType.String)
                            {
                                IsKey = true, IsSearchable = true
                            },
                            new Field("BlockNumber", DataType.String)
                            {
                                IsSearchable = true
                            },
                            new Field("BlockTimestamp", DataType.String),
                            new Field("To", DataType.String),
                            new Field("Value", DataType.String)
                        }
                    };

                    //define azure index for transfer event data
                    var transferEventIndex = new Index
                    {
                        Name   = TransferEventIndexName,
                        Fields = new List <Field>
                        {
                            new Field("DocumentKey", DataType.String)
                            {
                                IsKey = true
                            },
                            new Field("From", DataType.String)
                            {
                                IsSearchable = true, IsFacetable = true
                            },
                            new Field("To", DataType.String)
                            {
                                IsSearchable = true, IsFacetable = true
                            },
                            new Field("Value", DataType.String)
                        }
                    };

                    //reusable function handler which incorporates a function indexer
                    //the function indexer won't do anything yet
                    //it must be linked to an event processor before functions are indexed
                    var transferFunctionHandler =
                        await processor
                        .CreateFunctionHandlerAsync <TransferFunction, CustomTransferFunctionSearchDocument>(
                            transferFunctionIndex, (tx) => new CustomTransferFunctionSearchDocument
                    {
                        TransactionHash = tx.Tx.TransactionHash,
                        BlockNumber     = tx.Tx.BlockNumber.Value.ToString(),
                        BlockTimestamp  = tx.Tx.BlockTimestamp.ToString(),
                        To    = tx.Dto.To,
                        Value = tx.Dto.Value.ToString()
                    });


                    //create an indexer for the transfer event
                    //link our function handlers so that functions related to the event are indexed
                    await processor.AddAsync <TransferEvent_ERC20, CustomTransferEventSearchDocument>(
                        transferEventIndex, (eventLog) => new CustomTransferEventSearchDocument
                    {
                        From        = eventLog.Event.From,
                        To          = eventLog.Event.To,
                        Value       = eventLog.Event.Value.ToString(),
                        DocumentKey = $"{eventLog.Log.TransactionHash}_{eventLog.Log.LogIndex.Value}"
                    }
                        , new ITransactionHandler[]
                    {
                        transferFunctionHandler
                    });

                    //process the range
                    await processor.ProcessAsync(3146684, 3146694);

                    //allow time for azure indexing to finish
                    await Task.Delay(TimeSpan.FromSeconds(5));

                    //ensure we have written to the expected indexes
                    long transferEventCount = await processor.SearchService.CountDocumentsAsync(TransferEventIndexName);

                    long transferFunctionCount =
                        await processor.SearchService.CountDocumentsAsync(TransferFunctionIndexName);

                    Assert.Equal(19, transferEventCount);
                    Assert.Equal(2, transferFunctionCount);
                }
                finally
                {
                    await ClearDown(processor);
                }
            }
        }