private void GetScheduleForNextRound(Round currentRound, string publicKey, out int nextBlockMiningLeftMilliseconds, out Timestamp expectedMiningTime) { var minerInRound = currentRound.RealTimeMinersInformation[publicKey]; if (currentRound.RoundNumber == 1) { nextBlockMiningLeftMilliseconds = minerInRound.Order.Add(currentRound.RealTimeMinersInformation.Count) .Sub(1) .Mul(currentRound.GetMiningInterval()); expectedMiningTime = Context.CurrentBlockTime.AddMilliseconds(nextBlockMiningLeftMilliseconds); } else { expectedMiningTime = currentRound.ArrangeAbnormalMiningTime(minerInRound.Pubkey, Context.CurrentBlockTime); nextBlockMiningLeftMilliseconds = (int)(expectedMiningTime - Context.CurrentBlockTime).Milliseconds(); } }
/// <summary> /// AElf Consensus Behaviour is changeable in this method. /// It's the situation this miner should skip his time slot more precisely. /// </summary> /// <param name="behaviour"></param> /// <param name="currentRound"></param> /// <param name="publicKey"></param> /// <returns></returns> private ConsensusCommand GetConsensusCommand(AElfConsensusBehaviour behaviour, Round currentRound, string publicKey) { var miningInterval = currentRound.GetMiningInterval(); while (true) { var isAlone = CheckLonelyMiner(publicKey); if (behaviour == AElfConsensusBehaviour.TinyBlock && isAlone && currentRound.RealTimeMinersInformation.Count > 2 // There are more than 1 miner possible to save him. ) { behaviour = AElfConsensusBehaviour.Nothing; } var currentBlockTime = Context.CurrentBlockTime; Timestamp expectedMiningTime; int nextBlockMiningLeftMilliseconds; switch (behaviour) { case AElfConsensusBehaviour.UpdateValueWithoutPreviousInValue: GetScheduleForUpdateValueWithoutPreviousInValue(currentRound, publicKey, out nextBlockMiningLeftMilliseconds, out expectedMiningTime); break; case AElfConsensusBehaviour.UpdateValue: expectedMiningTime = currentRound.GetExpectedMiningTime(publicKey); nextBlockMiningLeftMilliseconds = (int)(expectedMiningTime - currentBlockTime).Milliseconds(); break; case AElfConsensusBehaviour.TinyBlock: GetScheduleForTinyBlock(currentRound, publicKey, out nextBlockMiningLeftMilliseconds, out expectedMiningTime); if (nextBlockMiningLeftMilliseconds < 0) { Context.LogDebug(() => "Next block mining left milliseconds is less than 0 for tiny block."); behaviour = AElfConsensusBehaviour.NextRound; continue; } break; case AElfConsensusBehaviour.NextRound: GetScheduleForNextRound(currentRound, publicKey, out nextBlockMiningLeftMilliseconds, out expectedMiningTime); break; case AElfConsensusBehaviour.NextTerm: expectedMiningTime = currentRound.ArrangeAbnormalMiningTime(publicKey, currentBlockTime); if (currentRound.RealTimeMinersInformation.Single(m => m.Value.IsExtraBlockProducer).Key != publicKey) { expectedMiningTime.AddMilliseconds(miningInterval); } nextBlockMiningLeftMilliseconds = (int)(expectedMiningTime - currentBlockTime).Milliseconds(); break; case AElfConsensusBehaviour.Nothing: return(GetInvalidConsensusCommand()); default: return(GetInvalidConsensusCommand()); } AdjustLimitMillisecondsOfMiningBlock(currentRound, publicKey, nextBlockMiningLeftMilliseconds, out var limitMillisecondsOfMiningBlock); var milliseconds = nextBlockMiningLeftMilliseconds; Context.LogDebug(() => $"NextBlockMiningLeftMilliseconds: {milliseconds}"); // Produce tiny blocks as fast as one can. if (behaviour == AElfConsensusBehaviour.TinyBlock) { nextBlockMiningLeftMilliseconds = AEDPoSContractConstants.MinimumIntervalOfProducingBlocks; } return(new ConsensusCommand { ExpectedMiningTime = expectedMiningTime, NextBlockMiningLeftMilliseconds = nextBlockMiningLeftMilliseconds < 0 ? 0 : nextBlockMiningLeftMilliseconds, LimitMillisecondsOfMiningBlock = isAlone ? currentRound.GetMiningInterval() : behaviour == AElfConsensusBehaviour.NextTerm ? miningInterval : limitMillisecondsOfMiningBlock, Hint = new AElfConsensusHint { Behaviour = behaviour }.ToByteString() }); } }
public static Timestamp ArrangeExtraBlockMiningTime(Round round, string pubkey, Timestamp currentBlockTime) { return(round.ArrangeAbnormalMiningTime(pubkey, currentBlockTime)); }