protected ConsensusBehaviourProviderBase(Round currentRound, string pubkey, int maximumBlocksCount,
                                                     Timestamp currentBlockTime)
            {
                CurrentRound       = currentRound;
                Pubkey             = pubkey;
                MaximumBlocksCount = maximumBlocksCount;
                CurrentBlockTime   = currentBlockTime;

                IsTimeSlotPassed = CurrentRound.IsTimeSlotPassed(Pubkey, CurrentBlockTime);
                MinerInRound     = CurrentRound.RealTimeMinersInformation[Pubkey];
            }
Beispiel #2
0
        /// <summary>
        /// Get next consensus behaviour of the provided public key based on current state.
        /// </summary>
        /// <param name="currentRound"></param>
        /// <param name="publicKey"></param>
        /// <returns></returns>
        private AElfConsensusBehaviour GetConsensusBehaviour(Round currentRound, string publicKey)
        {
            if (!IsInCurrentMinerList(currentRound, publicKey))
            {
                return(AElfConsensusBehaviour.Nothing);
            }

            var isFirstRoundOfCurrentTerm = IsFirstRoundOfCurrentTerm(out var termNumber);
            var isTimeSlotPassed          = currentRound.IsTimeSlotPassed(publicKey, Context.CurrentBlockTime);

            var minerInRound = currentRound.RealTimeMinersInformation[publicKey];

            if (!minerInRound.IsMinedBlockForCurrentRound())
            {
                var behaviour =
                    GetBehaviourIfMinerDidNotMineBlockForCurrentRound(currentRound, publicKey,
                                                                      isFirstRoundOfCurrentTerm);

                if (!isTimeSlotPassed && behaviour == AElfConsensusBehaviour.Nothing)
                {
                    Context.LogDebug(() => "Directly go to next round.");
                    behaviour = AElfConsensusBehaviour.UpdateValue;
                }

                if (behaviour != AElfConsensusBehaviour.Nothing)
                {
                    return(behaviour);
                }
            }
            else if (!isTimeSlotPassed)
            {
                if (minerInRound.ProducedTinyBlocks < AEDPoSContractConstants.TinyBlocksNumber)
                {
                    return(AElfConsensusBehaviour.TinyBlock);
                }

                if (currentRound.ExtraBlockProducerOfPreviousRound == publicKey &&
                    !isFirstRoundOfCurrentTerm &&
                    minerInRound.ProducedTinyBlocks < AEDPoSContractConstants.TinyBlocksNumber.Mul(2))
                {
                    return(AElfConsensusBehaviour.TinyBlock);
                }
            }

            // Side chain will go next round directly.
            return(State.TimeEachTerm.Value == int.MaxValue
                ? AElfConsensusBehaviour.NextRound
                : GetBehaviourForChainAbleToChangeTerm(currentRound, termNumber));
        }