public async Task Should_Not_Retrieve_Receipt_When_Disabled() { var blockToCrawl = new BigInteger(1); var mockRpcResponses = new BlockProcessingRpcMock(Web3Mock); mockRpcResponses.AddToGetBlockNumberRequestQueue(100); mockRpcResponses.SetupTransactionsWithReceipts(blockNumber: blockToCrawl, numberOfTransactions: 2, logsPerTransaction: 2); var processedData = new ProcessedBlockchainData(); var blockProcessor = Web3.Processing.Blocks.CreateBlockProcessor(steps => { steps.BlockStep.AddSynchronousProcessorHandler((block) => processedData.Blocks.Add(block)); steps.TransactionStep.AddSynchronousProcessorHandler((tx) => processedData.Transactions.Add(tx)); steps.TransactionReceiptStep.AddSynchronousProcessorHandler((tx) => processedData.TransactionsWithReceipt.Add(tx)); steps.ContractCreationStep.AddSynchronousProcessorHandler((c) => processedData.ContractCreations.Add(c)); steps.FilterLogStep.AddSynchronousProcessorHandler((filterLog) => processedData.FilterLogs.Add(filterLog)); }); blockProcessor.Orchestrator.TransactionWithReceiptCrawlerStep.Enabled = false; var cancellationTokenSource = new CancellationTokenSource(); await blockProcessor.ExecuteAsync(blockToCrawl, cancellationTokenSource.Token, blockToCrawl); Assert.Single(processedData.Blocks); Assert.Equal(2, processedData.Transactions.Count); Assert.Equal(0, processedData.TransactionsWithReceipt.Count); Assert.Equal(0, processedData.FilterLogs.Count); }
public async Task Should_Not_Retrieve_Receipt_When_Tx_Does_Not_Meet_Handler_Criteria() { var blockToCrawl = new BigInteger(1); var mockRpcResponses = new BlockProcessingRpcMock(Web3Mock); mockRpcResponses.AddToGetBlockNumberRequestQueue(100); mockRpcResponses.SetupTransactionsWithReceipts(blockNumber: blockToCrawl, numberOfTransactions: 2, logsPerTransaction: 2); var processedData = new ProcessedBlockchainData(); var blockProcessor = Web3.Processing.Blocks.CreateBlockProcessor(steps => { steps.BlockStep.AddSynchronousProcessorHandler((block) => processedData.Blocks.Add(block)); steps.TransactionStep.SetMatchCriteria((tx) => false); steps.TransactionReceiptStep.AddSynchronousProcessorHandler((tx) => processedData.TransactionsWithReceipt.Add(tx)); }); var cancellationTokenSource = new CancellationTokenSource(); await blockProcessor.ExecuteAsync(blockToCrawl, cancellationTokenSource.Token, blockToCrawl); Assert.Single(processedData.Blocks); Assert.Empty(processedData.Transactions); Assert.Empty(processedData.TransactionsWithReceipt); Assert.Equal(0, mockRpcResponses.ReceiptRequestCount); }
public async Task When_There_Is_Prior_Progress_A_Minimum_Starting_Block_Number_Will_Prevent_Processing_Earlier_Blocks() { var lastBlockProcessed = new BigInteger(5); var minBlock = new BigInteger(10); var progressRepository = new InMemoryBlockchainProgressRepository(lastBlockProcessed); var mockRpcResponses = new BlockProcessingRpcMock(Web3Mock); mockRpcResponses.AddToGetBlockNumberRequestQueue(100); mockRpcResponses.SetupTransactionsWithReceipts(blockNumber: minBlock, numberOfTransactions: 2, logsPerTransaction: 2); var cancellationTokenSource = new CancellationTokenSource(); var processedData = new ProcessedBlockchainData(); var blockProcessor = Web3.Processing.Blocks.CreateBlockProcessor(progressRepository, steps => { //capture a block and then cancel steps.BlockStep.AddSynchronousProcessorHandler((block) => { processedData.Blocks.Add(block); cancellationTokenSource.Cancel(); }); } ); await blockProcessor.ExecuteAsync(cancellationTokenSource.Token, minBlock); Assert.Single(processedData.Blocks); // one block processed Assert.Equal(minBlock, processedData.Blocks[0].Number.Value); // should have been the next block Assert.Equal(minBlock, await progressRepository.GetLastBlockNumberProcessedAsync()); // should have updated progress }
public async Task When_There_Is_Prior_Progress_Processing_Should_Pick_Up_From_Where_It_Left_Off() { //pretend we have already completed block 1 var lastBlockProcessed = new BigInteger(1); var nextBlockExpected = lastBlockProcessed + 1; var progressRepository = new InMemoryBlockchainProgressRepository(lastBlockProcessed); var mockRpcResponses = new BlockProcessingRpcMock(Web3Mock); mockRpcResponses.AddToGetBlockNumberRequestQueue(100); mockRpcResponses.SetupTransactionsWithReceipts(blockNumber: nextBlockExpected, numberOfTransactions: 2, logsPerTransaction: 2); var processedData = new ProcessedBlockchainData(); var cancellationTokenSource = new CancellationTokenSource(); var blockProcessor = Web3.Processing.Blocks.CreateBlockProcessor(progressRepository, steps => { //capture a block and then cancel steps.BlockStep.AddSynchronousProcessorHandler((block) => { processedData.Blocks.Add(block); cancellationTokenSource.Cancel(); }); } ); await blockProcessor.ExecuteAsync(cancellationTokenSource.Token); Assert.Single(processedData.Blocks); // one block processed Assert.Equal(nextBlockExpected, processedData.Blocks[0].Number.Value); // should have been the next block Assert.Equal(nextBlockExpected, await progressRepository.GetLastBlockNumberProcessedAsync()); // should have updated progress }
public async Task When_Step_Criteria_Is_Set_Should_Invoke_Handler_If_Matched() { var blockToCrawl = new BigInteger(1); var mockRpcResponses = new BlockProcessingRpcMock(Web3Mock); mockRpcResponses.AddToGetBlockNumberRequestQueue(100); mockRpcResponses.SetupTransactionsWithReceipts(blockNumber: blockToCrawl, numberOfTransactions: 2, logsPerTransaction: 2); var processedData = new ProcessedBlockchainData(); var blockProcessor = Web3.Processing.Blocks.CreateBlockProcessor(steps => { steps.TransactionStep.SetMatchCriteria(tx => true); //create some criteria to prevent handling unwanted transactions //this rule will match the first transaction steps.TransactionReceiptStep.SetMatchCriteria(tx => tx.Transaction.TransactionIndex.Value == 0); steps.TransactionReceiptStep.AddSynchronousProcessorHandler((tx) => processedData.TransactionsWithReceipt.Add(tx)); }); var cancellationTokenSource = new CancellationTokenSource(); await blockProcessor.ExecuteAsync(blockToCrawl, cancellationTokenSource.Token, blockToCrawl); //we should have captured the first tx in the block Assert.Single(processedData.TransactionsWithReceipt); }
public async Task Will_Wait_For_Block_Confirmations_Before_Processing() { var blockLastProcessed = new BigInteger(100); var nextBlock = blockLastProcessed + 1; const uint MIN_CONFIRMATIONS = 12; var progressRepository = new InMemoryBlockchainProgressRepository(blockLastProcessed); var mockRpcResponses = new BlockProcessingRpcMock(Web3Mock); //when first asked - pretend the current block is behind the required confirmations mockRpcResponses.AddToGetBlockNumberRequestQueue(blockLastProcessed + MIN_CONFIRMATIONS); //the next time return an incremented block which is under the confirmation limit mockRpcResponses.AddToGetBlockNumberRequestQueue(nextBlock + MIN_CONFIRMATIONS); mockRpcResponses.SetupTransactionsWithReceipts(blockNumber: nextBlock, numberOfTransactions: 2, logsPerTransaction: 2); var cancellationTokenSource = new CancellationTokenSource(); var processedData = new ProcessedBlockchainData(); var blockProcessor = Web3.Processing.Blocks.CreateBlockProcessor(progressRepository, steps => { //capture a block and then cancel steps.BlockStep.AddSynchronousProcessorHandler((block) => { processedData.Blocks.Add(block); cancellationTokenSource.Cancel(); }); } , MIN_CONFIRMATIONS); await blockProcessor.ExecuteAsync(cancellationTokenSource.Token); Assert.Single(processedData.Blocks); //should have processed a single block before cancellation Assert.Equal(2, mockRpcResponses.BlockNumberRequestCount); //should have asked for latest block twice Assert.Equal(nextBlock, processedData.Blocks[0].Number.Value); // should have handled the expected block Assert.Equal(nextBlock, await progressRepository.GetLastBlockNumberProcessedAsync()); // should have updated progress }