/// <summary> /// Tries to get and remove the next block from pending storage. If it exists /// then add it to <see cref="ProcessPendingStorageContext.PendingBlockPairsToStore"/>. /// This will also check if the next block can be processed. /// </summary> /// <param name="context"><see cref="ProcessPendingStorageContext"/></param> private StepResult PrepareNextBlockFromPendingStorage(ProcessPendingStorageContext context) { var blockIsInPendingStorage = this.BlockStoreLoop.PendingStorage.TryRemove(context.NextChainedBlock.HashBlock, out context.PendingBlockPairToStore); if (blockIsInPendingStorage) { context.PendingBlockPairsToStore.Push(context.PendingBlockPairToStore); context.PendingStorageBatchSize += context.PendingBlockPairToStore.Block.GetSerializedSize(); } return(context.CanProcessNextBlock() ? StepResult.Next : StepResult.Stop); }
/// <summary> /// Store missing blocks and remove them from pending blocks and set the Store's tip to <see cref="ProcessPendingStorageContext.NextChainedBlock"/> /// </summary> /// <param name="context"><see cref="ProcessPendingStorageContext"/></param> private async Task PushBlocksToRepositoryAsync(ProcessPendingStorageContext context) { this.logger.LogDebug(context.ToString()); await this.BlockStoreLoop.BlockRepository.PutAsync(context.PendingBlockPairsToStore.First().ChainedBlock.HashBlock, context.PendingBlockPairsToStore.Select(b => b.Block).ToList()); this.BlockStoreLoop.SetStoreTip(context.PendingBlockPairsToStore.First().ChainedBlock); context.PendingBlockPairToStore = null; context.PendingBlockPairsToStore.Clear(); context.PendingStorageBatchSize = 0; }
/// <inheritdoc/> internal override async Task <StepResult> ExecuteAsync(ChainedBlock nextChainedBlock, CancellationToken cancellationToken, bool disposeMode) { this.logger.LogTrace("({0}:'{1}',{2}:{3})", nameof(nextChainedBlock), nextChainedBlock, nameof(disposeMode), disposeMode); var context = new ProcessPendingStorageContext(this.logger, this.BlockStoreLoop, nextChainedBlock, cancellationToken); // Next block does not exist in pending storage, continue onto the download blocks step. if (!this.BlockStoreLoop.PendingStorage.ContainsKey(context.NextChainedBlock.HashBlock)) { this.logger.LogTrace("(-)[NOT_FOUND]:{0}", StepResult.Next); return(StepResult.Next); } // In case of IBD do not save every single block- persist them in batches. if (this.BlockStoreLoop.PendingStorage.Count < BlockStoreLoop.PendingStorageBatchThreshold && !disposeMode && this.BlockStoreLoop.InitialBlockDownloadState.IsInitialBlockDownload()) { return(StepResult.Stop); } while (!context.CancellationToken.IsCancellationRequested) { StepResult result = this.PrepareNextBlockFromPendingStorage(context); if (result == StepResult.Stop) { break; } if (context.PendingStorageBatchSize > BlockStoreLoop.MaxPendingInsertBlockSize) { await this.PushBlocksToRepositoryAsync(context).ConfigureAwait(false); } } if (context.PendingBlockPairsToStore.Any()) { await this.PushBlocksToRepositoryAsync(context).ConfigureAwait(false); } return(StepResult.Continue); }