/// <summary> /// Same process for every behaviour. /// </summary> /// <param name="input"></param> /// <param name="callerMethodName"></param> private void ProcessConsensusInformation(dynamic input, [CallerMemberName] string callerMethodName = null) { Context.LogDebug(() => $"Processing {callerMethodName}"); /* Privilege check. */ if (!PreCheck()) { return; } State.RoundBeforeLatestExecution.Value = GetCurrentRoundInformation(new Empty()); // The only difference. switch (input) { case Round round when callerMethodName == nameof(NextRound): ProcessNextRound(round); break; case Round round when callerMethodName == nameof(NextTerm): ProcessNextTerm(round); break; case UpdateValueInput updateValueInput: ProcessUpdateValue(updateValueInput); break; case TinyBlockInput tinyBlockInput: ProcessTinyBlock(tinyBlockInput); break; } var miningInformationUpdated = new MiningInformationUpdated { // _processingBlockMinerPubkey is set during above process. Pubkey = _processingBlockMinerPubkey, Behaviour = callerMethodName, MiningTime = Context.CurrentBlockTime, BlockHeight = Context.CurrentHeight, PreviousBlockHash = Context.PreviousBlockHash }; Context.Fire(miningInformationUpdated); Context.LogDebug(() => $"Synced mining information: {miningInformationUpdated}"); // Make sure the method GetMaximumBlocksCount executed no matter what consensus behaviour is. var minersCountInTheory = GetMaximumBlocksCount(); ResetLatestProviderToTinyBlocksCount(minersCountInTheory); if (TryToGetCurrentRoundInformation(out var currentRound)) { Context.LogDebug(() => $"Current round information:\n{currentRound.ToString(_processingBlockMinerPubkey)}"); } // Clear cache. _processingBlockMinerPubkey = null; }
/// <summary> /// Same process for every behaviour. /// </summary> /// <param name="input"></param> /// <param name="callerMethodName"></param> private void ProcessConsensusInformation(dynamic input, [CallerMemberName] string callerMethodName = null) { EnsureTransactionOnlyExecutedOnceInOneBlock(); Context.LogDebug(() => $"Processing {callerMethodName}"); /* Privilege check. */ if (!PreCheck()) { return; } State.RoundBeforeLatestExecution.Value = GetCurrentRoundInformation(new Empty()); // The only difference. switch (input) { case Round round when callerMethodName == nameof(NextRound): ProcessNextRound(round); break; case Round round when callerMethodName == nameof(NextTerm): ProcessNextTerm(round); break; case UpdateValueInput updateValueInput: ProcessUpdateValue(updateValueInput); break; case TinyBlockInput tinyBlockInput: ProcessTinyBlock(tinyBlockInput); break; } var miningInformationUpdated = new MiningInformationUpdated { // _processingBlockMinerPubkey is set during PreCheck. Pubkey = _processingBlockMinerPubkey, Behaviour = callerMethodName, MiningTime = Context.CurrentBlockTime, BlockHeight = Context.CurrentHeight, PreviousBlockHash = Context.PreviousBlockHash }; Context.LogDebug(() => $"Synced mining information: {miningInformationUpdated}"); // Make sure the method GetMaximumBlocksCount executed no matter what consensus behaviour is. var minersCountInTheory = GetMaximumBlocksCount(); ResetLatestProviderToTinyBlocksCount(minersCountInTheory); if (TryToGetCurrentRoundInformation(out var currentRound)) { Context.LogDebug(() => $"Current round information:\n{currentRound.ToString(_processingBlockMinerPubkey)}"); } var latestSignature = GetLatestSignature(currentRound); var previousRandomHash = State.RandomHashes[Context.CurrentHeight.Sub(1)]; var randomHash = previousRandomHash == null ? latestSignature : HashHelper.Xor(previousRandomHash, latestSignature); State.RandomHashes[Context.CurrentHeight] = randomHash; Context.LogDebug(() => $"New random hash generated: {randomHash} - height {Context.CurrentHeight}"); if (!State.IsMainChain.Value && currentRound.RoundNumber > 1) { ReleaseSideChainDividendsPool(); } // Clear cache. _processingBlockMinerPubkey = null; }