public async Task When_Reprocessing_The_Previous_Block_Will_Ignore_Transactions_Already_Processed()
            {
                //execute same block twice
                await BlockProcessor.ProcessBlockAsync(BlockNumber);

                await BlockProcessor.ProcessBlockAsync(BlockNumber);

                //assert
                MockTransactionProcessor
                .Verify(b => b.ProcessTransactionAsync(_stubBlock, It.IsAny <Transaction>()),
                        Times.Exactly(_stubBlock.TransactionCount()));
            }
            public async Task Invokes_BlockHandler_And_TransactionProcessor()
            {
                //execute
                await BlockProcessor.ProcessBlockAsync(BlockNumber);

                //assert
                MockBlockHandler.Verify(b => b.HandleAsync(_stubBlock), Times.Once);

                foreach (var txn in _stubBlock.Transactions)
                {
                    MockTransactionProcessor
                    .Verify(t => t.ProcessTransactionAsync(_stubBlock, txn), Times.Once);
                }
            }
            public async Task When_Filter_Does_Not_Match_Ignores_Block()
            {
                var nonMatchingFilter = new Moq.Mock <IBlockFilter>();

                nonMatchingFilter.Setup(b => b.IsMatchAsync(_stubBlock)).ReturnsAsync(false);
                BlockFilters.Add(nonMatchingFilter.Object);

                //execute
                await BlockProcessor.ProcessBlockAsync(BlockNumber);

                //assert
                nonMatchingFilter.Verify(b => b.IsMatchAsync(_stubBlock), Times.Once);

                MockBlockHandler.Verify(b => b.HandleAsync(_stubBlock), Times.Never);

                MockTransactionProcessor
                .Verify(t => t.ProcessTransactionAsync(
                            It.IsAny <Block>(), It.IsAny <Transaction>()), Times.Never);
            }
            public async Task Processes_Blocks_Which_Match_Filter()
            {
                var matchingBlockFilter = new Mock <IBlockFilter>();

                matchingBlockFilter.Setup(b => b.IsMatchAsync(_stubBlock)).ReturnsAsync(true);
                BlockFilters.Add(matchingBlockFilter.Object);

                //execute
                await BlockProcessor.ProcessBlockAsync(BlockNumber);

                //assert
                matchingBlockFilter.Verify(b => b.IsMatchAsync(_stubBlock), Times.Once);

                MockBlockHandler.Verify(b => b.HandleAsync(_stubBlock), Times.Once);

                foreach (var txn in _stubBlock.Transactions)
                {
                    MockTransactionProcessor
                    .Verify(t => t.ProcessTransactionAsync(_stubBlock, txn), Times.Once);
                }
            }