/// <summary>
        /// If current miner mined blocks only himself for 2 rounds,
        /// just stop and waiting to execute other miners' blocks.
        /// </summary>
        /// <param name="currentRound"></param>
        /// <param name="pubkey"></param>
        /// <returns></returns>
        private bool SolitaryMinerDetection(Round currentRound, string pubkey)
        {
            var isAlone = false;

            // Skip this detection until 4th round.
            if (currentRound.RoundNumber > 3 && currentRound.RealTimeMinersInformation.Count > 2)
            {
                // Not single node.

                var minedMinersOfCurrentRound = currentRound.GetMinedMiners();
                isAlone = minedMinersOfCurrentRound.Count == 0;

                // If only this node mined during previous round, stop mining.
                if (TryToGetPreviousRoundInformation(out var previousRound) && isAlone)
                {
                    var minedMiners = previousRound.GetMinedMiners();
                    isAlone = minedMiners.Count == 1 &&
                              minedMiners.Select(m => m.Pubkey).Contains(pubkey);
                }

                // check one further round.
                if (isAlone && TryToGetRoundInformation(previousRound.RoundNumber.Sub(1),
                                                        out var previousPreviousRound))
                {
                    var minedMiners = previousPreviousRound.GetMinedMiners();
                    isAlone = minedMiners.Count == 1 &&
                              minedMiners.Select(m => m.Pubkey).Contains(pubkey);
                }
            }

            return(isAlone);
        }
Example #2
0
            public void Deconstruct(out long libHeight)
            {
                if (_currentRound.IsEmpty || _previousRound.IsEmpty)
                {
                    libHeight = 0;
                }

                var minedMiners = _currentRound.GetMinedMiners().Select(m => m.Pubkey).ToList();
                var impliedIrreversibleHeights = _previousRound.GetSortedImpliedIrreversibleBlockHeights(minedMiners);

                if (impliedIrreversibleHeights.Count < _currentRound.MinersCountOfConsent)
                {
                    libHeight = 0;
                    return;
                }

                libHeight = impliedIrreversibleHeights[impliedIrreversibleHeights.Count.Sub(1).Div(3)];
            }