Beispiel #1
0
        /// <inheritdoc/>
        internal override async Task <BlockStoreLoopStepResult> ExecuteAsync(ChainedBlock nextChainedBlock, CancellationToken cancellationToken, bool disposeMode)
        {
            if (await this.BlockStoreLoop.BlockRepository.ExistAsync(nextChainedBlock.HashBlock))
            {
                await this.BlockStoreLoop.BlockRepository.SetBlockHash(nextChainedBlock.HashBlock);

                this.BlockStoreLoop.SetStoreTip(nextChainedBlock);

                return(BlockStoreLoopStepResult.Continue());
            }

            return(BlockStoreLoopStepResult.Next());
        }
Beispiel #2
0
        /// <inheritdoc/>
        internal override async Task <BlockStoreLoopStepResult> ExecuteAsync(ChainedBlock nextChainedBlock, CancellationToken cancellationToken, bool disposeMode)
        {
            if (!this.BlockStoreLoop.PendingStorage.TryRemove(nextChainedBlock.HashBlock, out this.pendingBlockPairToStore))
            {
                return(BlockStoreLoopStepResult.Next());
            }

            if (this.BlockStoreLoop.ChainState.IsInitialBlockDownload && !disposeMode)
            {
                if (this.BlockStoreLoop.PendingStorage.Skip(0).Count() < this.BlockStoreLoop.PendingStorageBatchThreshold)
                {
                    return(BlockStoreLoopStepResult.Break());
                }
            }

            var pendingBlockPairsToStore = new List <BlockPair>();

            pendingBlockPairsToStore.Add(this.pendingBlockPairToStore);
            var pendingStorageBatchSize = this.pendingBlockPairToStore.Block.GetSerializedSize();

            var lastFoundChainedBlock = nextChainedBlock;

            while (!cancellationToken.IsCancellationRequested)
            {
                var inputChainedBlock = nextChainedBlock;
                nextChainedBlock = this.BlockStoreLoop.Chain.GetBlock(nextChainedBlock.Height + 1);

                var breakExecution = ShouldBreakExecution(inputChainedBlock, nextChainedBlock);

                if (!breakExecution && !this.BlockStoreLoop.PendingStorage.TryRemove(nextChainedBlock.HashBlock, out this.pendingBlockPairToStore))
                {
                    breakExecution = true;
                }

                if (breakExecution)
                {
                    if (!pendingBlockPairsToStore.Any())
                    {
                        break;
                    }
                }
                else
                {
                    pendingBlockPairsToStore.Add(this.pendingBlockPairToStore);
                    pendingStorageBatchSize += this.pendingBlockPairToStore.Block.GetSerializedSize(); // TODO: add the size to the result coming from the signaler
                    lastFoundChainedBlock    = nextChainedBlock;
                }

                if (pendingStorageBatchSize > this.BlockStoreLoop.InsertBlockSizeThreshold || breakExecution)
                {
                    var result = await PushPendingBlocksToRepository(pendingStorageBatchSize, pendingBlockPairsToStore, lastFoundChainedBlock, cancellationToken, breakExecution);

                    if (result.ShouldBreak)
                    {
                        break;
                    }

                    pendingBlockPairsToStore.Clear();
                    pendingStorageBatchSize = 0;

                    if (this.BlockStoreLoop.ChainState.IsInitialBlockDownload) // this can be tweaked if insert is effecting the consensus speed
                    {
                        await Task.Delay(this.BlockStoreLoop.PushIntervalIBD, cancellationToken);
                    }
                }
            }

            pendingBlockPairsToStore.Clear();
            pendingBlockPairsToStore = null;

            this.pendingBlockPairToStore = null;

            return(BlockStoreLoopStepResult.Continue());
        }