Beispiel #1
0
        /// <summary>Checks if <paramref name="tip"/> violates the max reorg rule for POS networks.</summary>
        /// <param name="tip">The tip.</param>
        /// <returns><c>true</c> if maximum reorg rule violated, <c>false</c> otherwise.</returns>
        private bool IsMaxReorgRuleViolated(ChainedBlock tip)
        {
            this.logger.LogTrace("({0}:'{1}')", nameof(tip), tip);

            uint         maxReorgLength = this.chainState.MaxReorgLength;
            ChainedBlock consensusTip   = this.chainState.ConsensusTip;

            if ((maxReorgLength != 0) && (consensusTip != null))
            {
                ChainedBlock fork = tip.FindFork(consensusTip);

                if ((fork != null) && (fork != consensusTip))
                {
                    int reorgLength = consensusTip.Height - fork.Height;

                    if (reorgLength > maxReorgLength)
                    {
                        this.logger.LogTrace("Reorganization of length {0} prevented, maximal reorganization length is {1}, consensus tip is '{2}'.", reorgLength, maxReorgLength, consensusTip);
                        this.logger.LogTrace("(-):true");
                        return(true);
                    }

                    this.logger.LogTrace("Reorganization of length {0} accepted, consensus tip is '{1}'.", reorgLength, consensusTip);
                }
            }

            this.logger.LogTrace("(-):false");
            return(false);
        }
        /// <summary>
        /// Prepares and invokes download tasks from peer nodes for blocks the node is missing.
        /// </summary>
        /// <remarks>TODO: Comment is missing here about the details of the logic in this method.</remarks>
        private void AskBlocks()
        {
            this.logger.LogTrace("()");

            if (this.location == null)
            {
                throw new InvalidOperationException("SetLocation should have been called");
            }

            if ((this.lookaheadLocation != null) && (this.location != null) && (this.lookaheadLocation.Height < this.location.Height))
            {
                this.lookaheadLocation = this.location;
            }

            if ((this.lookaheadLocation == null) && !this.Chain.Contains(this.location.HashBlock))
            {
                this.logger.LogTrace("(-)[REORG]");
                return;
            }

            if ((this.lookaheadLocation != null) && !this.Chain.Contains(this.lookaheadLocation.HashBlock))
            {
                this.lookaheadLocation = null;
            }

            ChainedBlock lookaheadBlock     = this.lookaheadLocation ?? this.location;
            ChainedBlock nextLookaheadBlock = this.Chain.GetBlock(Math.Min(lookaheadBlock.Height + this.ActualLookahead, this.Chain.Height));

            if (nextLookaheadBlock == null)
            {
                return;
            }

            ChainedBlock fork = nextLookaheadBlock.FindFork(lookaheadBlock);

            this.lookaheadLocation = nextLookaheadBlock;

            int requestsCount = nextLookaheadBlock.Height - fork.Height;

            if (requestsCount > 0)
            {
                ChainedBlock[] downloadRequests = new ChainedBlock[requestsCount];
                for (int i = 0; i < requestsCount; i++)
                {
                    downloadRequests[requestsCount - i - 1] = nextLookaheadBlock;
                    nextLookaheadBlock = nextLookaheadBlock.Previous;
                }

                this.QueueRequests(downloadRequests);
            }

            // Process the queue even if we haven't added anything now
            // because there can be tasks waiting from previous rounds.
            this.ProcessQueue();

            this.logger.LogTrace("(-)");
        }
Beispiel #3
0
        /// <summary>
        /// Prepares and invokes download tasks from peer nodes for blocks the node is missing.
        /// </summary>
        /// <remarks>TODO: Comment is missing here about the details of the logic in this method.</remarks>
        private void AskBlocks()
        {
            this.logger.LogTrace("()");

            if (this.location == null)
            {
                throw new InvalidOperationException("SetLocation should have been called");
            }

            if (this.lookaheadLocation == null && !this.Chain.Contains(this.location))
            {
                this.logger.LogTrace("(-)[REORG]");
                return;
            }

            if (this.lookaheadLocation != null && !this.Chain.Contains(this.lookaheadLocation))
            {
                this.lookaheadLocation = null;
            }

            ChainedBlock[] downloadRequests = null;

            ChainedBlock lookaheadBlock     = this.lookaheadLocation ?? this.location;
            ChainedBlock nextLookaheadBlock = this.Chain.GetBlock(Math.Min(lookaheadBlock.Height + this.ActualLookahead, this.Chain.Height));

            if (nextLookaheadBlock == null)
            {
                return;
            }

            ChainedBlock fork = nextLookaheadBlock.FindFork(lookaheadBlock);

            this.lookaheadLocation = nextLookaheadBlock;

            downloadRequests = new ChainedBlock[nextLookaheadBlock.Height - fork.Height];
            if (downloadRequests.Length == 0)
            {
                return;
            }

            for (int i = 0; i < downloadRequests.Length; i++)
            {
                downloadRequests[downloadRequests.Length - i - 1] = nextLookaheadBlock;
                nextLookaheadBlock = nextLookaheadBlock.Previous;
            }

            AskBlocks(downloadRequests);

            this.logger.LogTrace("(-)");
        }
        private void AskBlocks()
        {
            if (_Location == null)
            {
                throw new InvalidOperationException("SetLocation should have been called");
            }
            if (_LookaheadLocation == null && !Chain.Contains(_Location))
            {
                return;
            }
            if (_LookaheadLocation != null && !Chain.Contains(_LookaheadLocation))
            {
                _LookaheadLocation = null;
            }

            ChainedBlock[] downloadRequests = null;

            ChainedBlock lookaheadBlock     = _LookaheadLocation ?? _Location;
            ChainedBlock nextLookaheadBlock = Chain.GetBlock(Math.Min(lookaheadBlock.Height + ActualLookahead, Chain.Height));

            if (nextLookaheadBlock == null)
            {
                return;
            }
            var fork = nextLookaheadBlock.FindFork(lookaheadBlock);

            _LookaheadLocation = nextLookaheadBlock;

            downloadRequests = new ChainedBlock[nextLookaheadBlock.Height - fork.Height];
            if (downloadRequests.Length == 0)
            {
                return;
            }
            for (int i = 0; i < downloadRequests.Length; i++)
            {
                downloadRequests[downloadRequests.Length - i - 1] = nextLookaheadBlock;
                nextLookaheadBlock = nextLookaheadBlock.Previous;
            }

            AskBlocks(downloadRequests);
        }
Beispiel #5
0
 private ChainedBlock FindFork(ChainedBlock newTip, ChainedBlock tip)
 {
     return(newTip.FindFork(tip));
 }