public void DownloadBlocks_CanBreakExecutionOnStallCountReached() { // Create 3 blocks List <Block> blocks = CreateBlocks(3); // The repository has 3 blocks stored using (var blockRepository = new BlockRepository(Network.Main, TestBase.AssureEmptyDirAsDataFolder(@"BlockStore\DownloadBlocks_EnsureNextChainedBlockIsAskedForOnStartUp"))) { blockRepository.PutAsync(blocks.Last().GetHash(), blocks.Take(3).ToList()).GetAwaiter().GetResult(); // The chain has 3 blocks appended var chain = new ConcurrentChain(blocks[0].Header); AppendBlocks(chain, blocks.Skip(1).Take(2)); // Create block store loop var blockStoreLoop = CreateBlockStoreLoop(chain, blockRepository, @"BlockStore\DownloadBlocks_EnsureNextChainedBlockIsAskedForOnStartUp"); //Start finding blocks from Block[1] var nextChainedBlock = blockStoreLoop.Chain.GetBlock(blocks[1].GetHash()); // Create Task Context var context = new BlockStoreInnerStepContext(new CancellationToken(), blockStoreLoop).Initialize(nextChainedBlock); context.StallCount = 10001; var task = new BlockStoreInnerStepDownloadBlocks(); var result = task.ExecuteAsync(context).GetAwaiter().GetResult(); Assert.True(result.ShouldBreak); } }
public void DownloadBlocks_EnsureNextChainedBlockIsAskedForOnStartUp() { var blocks = CreateBlocks(3); using (var blockRepository = new BlockRepository(Network.Main, TestBase.AssureEmptyDirAsDataFolder(@"BlockStore\DownloadBlocks_EnsureNextChainedBlockIsAskedForOnStartUp"))) { // The chain has 3 blocks appended var chain = new ConcurrentChain(blocks[0].Header); AppendBlocks(chain, blocks.Skip(1).Take(2)); var blockStoreLoop = CreateBlockStoreLoop(chain, blockRepository, @"BlockStore\DownloadBlocks_EnsureNextChainedBlockIsAskedForOnStartUp"); var nextChainedBlock = blockStoreLoop.Chain.GetBlock(blocks[1].GetHash()); var context = new BlockStoreInnerStepContext(new CancellationToken(), blockStoreLoop).Initialize(nextChainedBlock); Assert.Equal(1, context.DownloadStack.Count()); Assert.True(context.DownloadStack.Any(cb => cb.HashBlock == nextChainedBlock.HashBlock)); // Push blocks[1] to the downloaded blocks collection blockStoreLoop.BlockPuller.InjectBlock(blocks[1].GetHash(), new DownloadedBlock() { Length = blocks[1].GetSerializedSize(), Block = blocks[1] }, new CancellationToken()); Assert.Equal(1, context.BlockStoreLoop.BlockPuller.DownloadedBlocksCount); // TryGetBlock should return NextChainedBlock DownloadedBlock downloadedBlock = null; context.BlockStoreLoop.BlockPuller.TryGetBlock(context.DownloadStack.Peek(), out downloadedBlock); Assert.NotNull(downloadedBlock); Assert.Equal(downloadedBlock.Block.GetHash(), nextChainedBlock.HashBlock); } }
public void BlockStoreInnerStepFindBlocks_CanRemoveTaskFromRoutine_BlockExistsInRepository() { var blocks = this.CreateBlocks(3); using (var fluent = new FluentBlockStoreLoop()) { // Push 3 blocks to the repository fluent.BlockRepository.PutAsync(blocks.Last().GetHash(), blocks).GetAwaiter().GetResult(); // The chain has 3 blocks appended var chain = new ConcurrentChain(blocks[0].Header); this.AppendBlocksToChain(chain, blocks.Skip(1).Take(2)); // Create block store loop fluent.Create(chain); // Start finding blocks from Block[1] var nextChainedBlock = fluent.Loop.Chain.GetBlock(blocks[1].GetHash()); // Create Task Context var context = new BlockStoreInnerStepContext(new CancellationToken(), fluent.Loop, nextChainedBlock, this.loggerFactory, DateTimeProvider.Default); var task = new BlockStoreInnerStepFindBlocks(this.loggerFactory); task.ExecuteAsync(context).GetAwaiter().GetResult(); // DownloadStack should only contain Block[1] Assert.Empty(context.DownloadStack); // The FindBlocks() task should be removed from the routine // as the next chained block exist in the BlockRepository // causing a stop condition Assert.Single(context.InnerSteps); Assert.False(context.InnerSteps.OfType <BlockStoreInnerStepFindBlocks>().Any()); } }
public void BlockStoreInnerStepFindBlocks_CanRemoveTaskFromRoutine_NextChainedBlockIsNull() { var blocks = CreateBlocks(3); using (var fluent = new FluentBlockStoreLoop()) { // Push 2 blocks to the repository fluent.BlockRepository.PutAsync(blocks.Take(2).Last().GetHash(), blocks.Take(2).ToList()).GetAwaiter().GetResult(); // The chain has 3 blocks appended var chain = new ConcurrentChain(blocks[0].Header); AppendBlocksToChain(chain, blocks.Skip(1).Take(2)); // Create block store loop fluent.Create(chain); // Start finding blocks from Block[2] var nextChainedBlock = fluent.Loop.Chain.GetBlock(blocks[2].GetHash()); // Create Task Context var context = new BlockStoreInnerStepContext(new CancellationToken(), fluent.Loop, nextChainedBlock, this.loggerFactory, DateTimeProvider.Default); var task = new BlockStoreInnerStepFindBlocks(this.loggerFactory); task.ExecuteAsync(context).GetAwaiter().GetResult(); // DownloadStack should only contain nextChainedBlock Assert.Equal(1, context.DownloadStack.Count()); Assert.True(context.DownloadStack.Any(cb => cb.HashBlock == nextChainedBlock.HashBlock)); // The FindBlocks() task should be removed from the routine // as the next chained block is null Assert.Equal(1, context.InnerSteps.Count()); Assert.False(context.InnerSteps.OfType <BlockStoreInnerStepFindBlocks>().Any()); } }
public void BlockStoreInnerStepReadBlocks_CanBreakExecution_DownloadStackIsEmpty() { var blocks = this.CreateBlocks(2); using (var fluent = new FluentBlockStoreLoop()) { // Push 2 blocks to the repository fluent.BlockRepository.PutAsync(blocks.Last().GetHash(), blocks).GetAwaiter().GetResult(); // The chain has 2 blocks appended var chain = new ConcurrentChain(blocks[0].Header); this.AppendBlocksToChain(chain, blocks.Skip(1).Take(1)); // Create block store loop fluent.Create(chain); //Start finding blocks from Block[1] var nextChainedBlock = fluent.Loop.Chain.GetBlock(blocks[1].GetHash()); // Create Task Context var context = new BlockStoreInnerStepContext(new CancellationToken(), fluent.Loop, nextChainedBlock, this.loggerFactory, DateTimeProvider.Default); context.StallCount = 10001; var task = new BlockStoreInnerStepReadBlocks(this.loggerFactory); var result = task.ExecuteAsync(context).GetAwaiter().GetResult(); Assert.Equal(InnerStepResult.Stop, result); } }
public void BlockStoreInnerStepFindBlocks_WithBlocksFound_AddToDownloadStack() { var blocks = CreateBlocks(10); using (var fluent = new FluentBlockStoreLoop()) { // Push 5 blocks to the repository fluent.BlockRepository.PutAsync(blocks.Take(5).Last().GetHash(), blocks.Take(5).ToList()).GetAwaiter().GetResult(); // The chain has 10 blocks appended var chain = new ConcurrentChain(blocks[0].Header); AppendBlocksToChain(chain, blocks.Skip(1).Take(9)); // Create block store loop fluent.Create(chain); // Push blocks[5] - [9] to the downloaded blocks collection fluent.Loop.BlockPuller.InjectBlock(blocks[5].GetHash(), new DownloadedBlock() { Length = blocks[5].GetSerializedSize(), Block = blocks[5] }, new CancellationToken()); fluent.Loop.BlockPuller.InjectBlock(blocks[6].GetHash(), new DownloadedBlock() { Length = blocks[6].GetSerializedSize(), Block = blocks[6] }, new CancellationToken()); fluent.Loop.BlockPuller.InjectBlock(blocks[7].GetHash(), new DownloadedBlock() { Length = blocks[7].GetSerializedSize(), Block = blocks[7] }, new CancellationToken()); fluent.Loop.BlockPuller.InjectBlock(blocks[8].GetHash(), new DownloadedBlock() { Length = blocks[8].GetSerializedSize(), Block = blocks[8] }, new CancellationToken()); fluent.Loop.BlockPuller.InjectBlock(blocks[9].GetHash(), new DownloadedBlock() { Length = blocks[9].GetSerializedSize(), Block = blocks[9] }, new CancellationToken()); // Start finding blocks from block[5] var nextChainedBlock = fluent.Loop.Chain.GetBlock(blocks[5].GetHash()); // Create Task Context var context = new BlockStoreInnerStepContext(new CancellationToken(), fluent.Loop, nextChainedBlock, this.loggerFactory, DateTimeProvider.Default); var task = new BlockStoreInnerStepFindBlocks(this.loggerFactory); task.ExecuteAsync(context).GetAwaiter().GetResult(); // Block[5] through Block[9] should be in the DownloadStack Assert.Equal(5, context.DownloadStack.Count()); Assert.True(context.DownloadStack.Any(cb => cb.HashBlock == blocks[5].GetHash())); Assert.True(context.DownloadStack.Any(cb => cb.HashBlock == blocks[6].GetHash())); Assert.True(context.DownloadStack.Any(cb => cb.HashBlock == blocks[7].GetHash())); Assert.True(context.DownloadStack.Any(cb => cb.HashBlock == blocks[8].GetHash())); Assert.True(context.DownloadStack.Any(cb => cb.HashBlock == blocks[9].GetHash())); } }
public void FindBlocks_CanFind() { // Create 10 blocks List <Block> blocks = CreateBlocks(10); using (var blockRepository = new BlockRepository(Network.Main, TestBase.AssureEmptyDirAsDataFolder(@"BlockStore\FindBlocks_CanFind"))) { // Push 5 blocks to the repository blockRepository.PutAsync(blocks.Take(5).Last().GetHash(), blocks.Take(5).ToList()).GetAwaiter().GetResult(); // The chain has 10 blocks appended var chain = new ConcurrentChain(blocks[0].Header); AppendBlocks(chain, blocks.Skip(1).Take(9)); // Create block store loop var blockStoreLoop = CreateBlockStoreLoop(chain, blockRepository, @"BlockStore\FindBlocks_CanFind"); // Push blocks 5 - 9 to the downloaded blocks collection blockStoreLoop.BlockPuller.InjectBlock(blocks[5].GetHash(), new DownloadedBlock() { Length = blocks[5].GetSerializedSize(), Block = blocks[5] }, new CancellationToken()); blockStoreLoop.BlockPuller.InjectBlock(blocks[6].GetHash(), new DownloadedBlock() { Length = blocks[6].GetSerializedSize(), Block = blocks[6] }, new CancellationToken()); blockStoreLoop.BlockPuller.InjectBlock(blocks[7].GetHash(), new DownloadedBlock() { Length = blocks[7].GetSerializedSize(), Block = blocks[7] }, new CancellationToken()); blockStoreLoop.BlockPuller.InjectBlock(blocks[8].GetHash(), new DownloadedBlock() { Length = blocks[8].GetSerializedSize(), Block = blocks[8] }, new CancellationToken()); blockStoreLoop.BlockPuller.InjectBlock(blocks[9].GetHash(), new DownloadedBlock() { Length = blocks[9].GetSerializedSize(), Block = blocks[9] }, new CancellationToken()); //Start processing blocks to download from block 5 var nextChainedBlock = blockStoreLoop.Chain.GetBlock(blocks[5].GetHash()); // Create Task Context var context = new BlockStoreInnerStepContext(new CancellationToken(), blockStoreLoop).Initialize(nextChainedBlock); var task = new BlockStoreInnerStepFindBlocks(); task.ExecuteAsync(context).GetAwaiter().GetResult(); //Block[5] and Block[6] in the DownloadStack Assert.Equal(2, context.DownloadStack.Count()); Assert.True(context.DownloadStack.Any(cb => cb.HashBlock == blocks[5].GetHash())); Assert.True(context.DownloadStack.Any(cb => cb.HashBlock == blocks[6].GetHash())); } }
public void BlockStoreInnerStepFindBlocks_CanRemoveTaskFromRoutine_DownloadStackSizeReached() { var blocks = this.CreateBlocks(55); using (var fluent = new FluentBlockStoreLoop()) { // Push 45 blocks to the repository fluent.BlockRepository.PutAsync(blocks.Take(45).Last().GetHash(), blocks.Take(45).ToList()).GetAwaiter().GetResult(); // The chain has 55 blocks appended var chain = new ConcurrentChain(blocks[0].Header); this.AppendBlocksToChain(chain, blocks.Skip(1).Take(54).ToList()); // Create block store loop fluent.Create(chain); // Start finding blocks from Block[45] var nextChainedBlock = fluent.Loop.Chain.GetBlock(blocks[45].GetHash()); // Create Task Context var context = new BlockStoreInnerStepContext(new CancellationToken(), fluent.Loop, nextChainedBlock, this.loggerFactory, DateTimeProvider.Default); var task = new BlockStoreInnerStepFindBlocks(this.loggerFactory); task.ExecuteAsync(context).GetAwaiter().GetResult(); // Block[45] through Block[50] should be in the DownloadStack Assert.Equal(10, context.DownloadStack.Count()); Assert.Contains(context.DownloadStack, cb => cb.HashBlock == blocks[45].GetHash()); Assert.Contains(context.DownloadStack, cb => cb.HashBlock == blocks[46].GetHash()); Assert.Contains(context.DownloadStack, cb => cb.HashBlock == blocks[47].GetHash()); Assert.Contains(context.DownloadStack, cb => cb.HashBlock == blocks[48].GetHash()); Assert.Contains(context.DownloadStack, cb => cb.HashBlock == blocks[49].GetHash()); Assert.Contains(context.DownloadStack, cb => cb.HashBlock == blocks[50].GetHash()); Assert.Contains(context.DownloadStack, cb => cb.HashBlock == blocks[51].GetHash()); Assert.Contains(context.DownloadStack, cb => cb.HashBlock == blocks[52].GetHash()); Assert.Contains(context.DownloadStack, cb => cb.HashBlock == blocks[53].GetHash()); Assert.Contains(context.DownloadStack, cb => cb.HashBlock == blocks[54].GetHash()); // The FindBlocks() task should be removed from the routine // as the batch download size is reached Assert.Single(context.InnerSteps); Assert.False(context.InnerSteps.OfType <BlockStoreInnerStepFindBlocks>().Any()); } }
public void FindBlocks_CanRemoveTaskFromRoutine_BlockExistsInPendingStorage() { // Create 3 blocks List <Block> blocks = CreateBlocks(3); // The repository has 3 blocks stored using (var blockRepository = new BlockRepository(Network.Main, TestBase.AssureEmptyDirAsDataFolder(@"BlockStore\FindBlocks_CanRemoveTaskFromRoutine_BlockExistsInPendingStorage"))) { blockRepository.PutAsync(blocks.Last().GetHash(), blocks).GetAwaiter().GetResult(); // The chain has 3 blocks appended var chain = new ConcurrentChain(blocks[0].Header); AppendBlocks(chain, blocks.Skip(1).Take(2)); // Create block store loop var blockStoreLoop = CreateBlockStoreLoop(chain, blockRepository, @"BlockStore\FindBlocks_CanRemoveTaskFromRoutine_BlockExistsInPendingStorage"); //Start finding blocks from Block[1] var nextChainedBlock = blockStoreLoop.Chain.GetBlock(blocks[1].GetHash()); //Add nextChainedBlock to Pending Storage blockStoreLoop.PendingStorage.TryAdd(blocks[2].GetHash(), new BlockPair(blocks[2], nextChainedBlock)); // Create Task Context var context = new BlockStoreInnerStepContext(new CancellationToken(), blockStoreLoop).Initialize(nextChainedBlock); var task = new BlockStoreInnerStepFindBlocks(); task.ExecuteAsync(context).GetAwaiter().GetResult(); //DownloadStack should only contain nextChainedBlock Assert.Equal(1, context.DownloadStack.Count()); Assert.True(context.DownloadStack.Any(cb => cb.HashBlock == nextChainedBlock.HashBlock)); //The FindBlocks() task should be removed from the routine //as the next chained block exists in PendingStorage Assert.Equal(1, context.Routine.Count()); Assert.False(context.Routine.OfType <BlockStoreInnerStepFindBlocks>().Any()); } }
public void BlockStoreInnerStepFindBlocks_CanRemoveTaskFromRoutine_BlockExistsInPendingStorage() { var blocks = this.CreateBlocks(3); using (var fluent = new FluentBlockStoreLoop(CreateDataFolder(this))) { // Push 2 blocks to the repository fluent.BlockRepository.PutAsync(blocks.Take(1).Last().GetHash(), blocks.Take(1).ToList()).GetAwaiter().GetResult(); // The chain has 3 blocks appended var chain = new ConcurrentChain(blocks[0].Header); this.AppendBlocksToChain(chain, blocks.Skip(1).Take(2)); // Create block store loop fluent.Create(chain); // Add block[2] to Pending Storage fluent.Loop.PendingStorage.TryAdd(blocks[2].GetHash(), new BlockPair(blocks[2], fluent.Loop.Chain.GetBlock(blocks[2].GetHash()))); // Start finding blocks from Block[1] var nextChainedBlock = fluent.Loop.Chain.GetBlock(blocks[1].GetHash()); // Create Task Context var context = new BlockStoreInnerStepContext(new CancellationToken(), fluent.Loop, nextChainedBlock, this.LoggerFactory.Object, DateTimeProvider.Default); var task = new BlockStoreInnerStepFindBlocks(this.LoggerFactory.Object); task.ExecuteAsync(context).GetAwaiter().GetResult(); // DownloadStack should only contain Block[1] Assert.Single(context.DownloadStack); Assert.Contains(context.DownloadStack, cb => cb.HashBlock == nextChainedBlock.HashBlock); // The FindBlocks() task should be removed from the routine // as the next chained block exists in PendingStorage Assert.Single(context.InnerSteps); Assert.False(context.InnerSteps.OfType <BlockStoreInnerStepFindBlocks>().Any()); } }
public void FindBlocks_CanRemoveTaskFromRoutine_BatchDownloadSizeReached() { // Create 3 blocks List <Block> blocks = CreateBlocks(3); // The repository has 3 blocks stored using (var blockRepository = new BlockRepository(Network.Main, TestBase.AssureEmptyDirAsDataFolder(@"BlockStore\FindBlocks_CanRemoveTaskFromRoutine_BatchDownloadSizeReached"))) { blockRepository.PutAsync(blocks.Last().GetHash(), blocks.Take(2).ToList()).GetAwaiter().GetResult(); // The chain has 2 blocks appended var chain = new ConcurrentChain(blocks[0].Header); AppendBlocks(chain, blocks.Skip(1).Take(2).ToList()); // Create block store loop var blockStoreLoop = CreateBlockStoreLoop(chain, blockRepository, @"BlockStore\FindBlocks_CanRemoveTaskFromRoutine_BatchDownloadSizeReached"); blockStoreLoop.BatchDownloadSize = 2; //Start finding blocks from Block[1] var nextChainedBlock = blockStoreLoop.Chain.GetBlock(blocks[1].GetHash()); // Create Task Context var context = new BlockStoreInnerStepContext(new CancellationToken(), blockStoreLoop).Initialize(nextChainedBlock); var task = new BlockStoreInnerStepFindBlocks(); task.ExecuteAsync(context).GetAwaiter().GetResult(); //Block[1] and Block[2] in the DownloadStack Assert.Equal(2, context.DownloadStack.Count()); Assert.True(context.DownloadStack.Any(cb => cb.HashBlock == blocks[1].GetHash())); Assert.True(context.DownloadStack.Any(cb => cb.HashBlock == blocks[2].GetHash())); //The FindBlocks() task should be removed from the routine //as the batch download size is reached Assert.Equal(1, context.Routine.Count()); Assert.False(context.Routine.OfType <BlockStoreInnerStepFindBlocks>().Any()); } }