/// <summary>
            /// If this miner come to a new round, normally, there are three possible behaviour:
            /// UpdateValue (most common)
            /// UpdateValueWithoutPreviousInValue (happens if current round is the first round of current term)
            /// TinyBlock (happens if this miner is mining blocks for extra block time slot of previous round)
            /// NextRound (only happens in first round)
            /// </summary>
            /// <returns></returns>
            private AElfConsensusBehaviour HandleMinerInNewRound()
            {
                if (
                    // For first round, the expected mining time is incorrect (due to configuration),
                    CurrentRound.RoundNumber == 1 &&
                    // so we'd better prevent miners' ain't first order (meanwhile he isn't boot miner) from mining fork blocks
                    MinerInRound.Order != 1 &&
                    // by postpone their mining time
                    CurrentRound.FirstMiner().OutValue == null
                    )
                {
                    return(AElfConsensusBehaviour.NextRound);
                }

                if (
                    // If this miner is extra block producer of previous round,
                    CurrentRound.ExtraBlockProducerOfPreviousRound == Pubkey &&
                    // and currently the time is ahead of current round,
                    CurrentBlockTime < CurrentRound.GetRoundStartTime() &&
                    // make this miner produce some tiny blocks.
                    MinerInRound.ProducedTinyBlocks < MaximumBlocksCount
                    )
                {
                    return(AElfConsensusBehaviour.TinyBlock);
                }

                if (CurrentRound.IsMinerListJustChanged)
                {
                    return(AElfConsensusBehaviour.UpdateValueWithoutPreviousInValue);
                }

                return(!IsTimeSlotPassed ? AElfConsensusBehaviour.UpdateValue : AElfConsensusBehaviour.Nothing);
            }
Esempio n. 2
0
        /// <summary>
        /// Get consensus behaviour if miner didn't mine block for current round.
        /// </summary>
        /// <param name="currentRound"></param>
        /// <param name="publicKey"></param>
        /// <param name="isFirstRoundOfCurrentTerm"></param>
        /// <returns></returns>
        private AElfConsensusBehaviour GetBehaviourIfMinerDidNotMineBlockForCurrentRound(Round currentRound,
                                                                                         string publicKey, bool isFirstRoundOfCurrentTerm)
        {
            var minerInRound = currentRound.RealTimeMinersInformation[publicKey];

            if (currentRound.RoundNumber == 1 &&           // For first round, the expected mining time is incorrect,
                minerInRound.Order != 1 &&                 // so we'd better prevent miners' ain't first order (meanwhile isn't boot miner) from mining fork blocks
                currentRound.FirstMiner().OutValue == null // by postpone their mining time
                )
            {
                return(AElfConsensusBehaviour.NextRound);
            }

            if (currentRound.ExtraBlockProducerOfPreviousRound == publicKey &&             // If this miner is extra block producer of previous round,
                Context.CurrentBlockTime < currentRound.GetStartTime() &&                  // and currently the time is ahead of current round,
                minerInRound.ProducedTinyBlocks < AEDPoSContractConstants.TinyBlocksNumber // make this miner produce some tiny blocks.
                )
            {
                return(AElfConsensusBehaviour.TinyBlock);
            }

            return(isFirstRoundOfCurrentTerm
                ? AElfConsensusBehaviour.UpdateValueWithoutPreviousInValue
                : AElfConsensusBehaviour.Nothing);
        }