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]; }
/// <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)); }