public override Empty ConfigStrategy(DPoSStrategyInput input) { Assert(!State.IsStrategyConfigured.Value, ContractErrorCode.GetErrorMessage(ContractErrorCode.InvalidOperation, "Already configured.")); State.IsVerbose.Value = input.IsVerbose; State.IsStrategyConfigured.Value = true; LogVerbose("Consensus log level: Verbose"); return(new Empty()); }
public override Empty InitialConsensus(Round firstRound) { Assert(firstRound.RoundNumber == 1, ContractErrorCode.GetErrorMessage(ContractErrorCode.InvalidField, "Invalid round number.")); Assert(firstRound.RealTimeMinersInformation.Any(), ContractErrorCode.GetErrorMessage(ContractErrorCode.InvalidField, "No miner in input data.")); InitialSettings(firstRound); Assert(TryToAddRoundInformation(firstRound), ContractErrorCode.GetErrorMessage(ContractErrorCode.AttemptFailed, "Failed to add round information.")); return(new Empty()); }
public override DPoSHeaderInformation GetInformationToUpdateConsensus(DPoSTriggerInformation input) { // Some basic checks. Assert(input.PublicKey.Any(), "Invalid public key."); var publicKey = input.PublicKey; var currentBlockTime = Context.CurrentBlockTime; var behaviour = input.Behaviour; Assert(TryToGetCurrentRoundInformation(out var currentRound), ContractErrorCode.GetErrorMessage(ContractErrorCode.AttemptFailed, "Failed to get current round information.")); switch (behaviour) { case DPoSBehaviour.UpdateValueWithoutPreviousInValue: case DPoSBehaviour.UpdateValue: Assert(input.RandomHash != null, "Random hash should not be null."); var inValue = currentRound.CalculateInValue(input.RandomHash); var outValue = Hash.FromMessage(inValue); var signature = Hash.FromTwoHashes(outValue, input.RandomHash); // Just initial signature value. var previousInValue = Hash.Empty; // Just initial previous in value. if (TryToGetPreviousRoundInformation(out var previousRound)) { signature = previousRound.CalculateSignature(inValue); LogVerbose($"Previous random hash: {input.PreviousRandomHash.ToHex()}"); if (input.PreviousRandomHash != Hash.Empty) { // If PreviousRandomHash is Hash.Empty, it means the sender unable or unwilling to publish his previous in value. previousInValue = previousRound.CalculateInValue(input.PreviousRandomHash); } } var updatedRound = currentRound.ApplyNormalConsensusData(publicKey.ToHex(), previousInValue, outValue, signature, currentBlockTime); ShareAndRecoverInValue(updatedRound, previousRound, inValue, publicKey.ToHex()); // To publish Out Value. return(new DPoSHeaderInformation { SenderPublicKey = publicKey, Round = updatedRound, Behaviour = behaviour, }); case DPoSBehaviour.NextRound: Assert( GenerateNextRoundInformation(currentRound, currentBlockTime, out var nextRound), "Failed to generate next round information."); nextRound.RealTimeMinersInformation[publicKey.ToHex()].ProducedBlocks += 1; Context.LogDebug(() => $"Mined blocks: {nextRound.GetMinedBlocks()}"); nextRound.ExtraBlockProducerOfPreviousRound = publicKey.ToHex(); return(new DPoSHeaderInformation { SenderPublicKey = publicKey, Round = nextRound, Behaviour = behaviour }); default: return(new DPoSHeaderInformation()); } }