示例#1
0
        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());
        }
示例#2
0
        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());
        }
示例#3
0
        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());
            }
        }