Esempio n. 1
0
        private AElfConsensusHeaderInformation GetConsensusExtraDataToPublishOutValue(Round currentRound,
                                                                                      string pubkey, AElfConsensusTriggerInformation triggerInformation)
        {
            currentRound.RealTimeMinersInformation[pubkey].ProducedTinyBlocks = currentRound
                                                                                .RealTimeMinersInformation[pubkey].ProducedTinyBlocks.Add(1);
            currentRound.RealTimeMinersInformation[pubkey].ProducedBlocks =
                currentRound.RealTimeMinersInformation[pubkey].ProducedBlocks.Add(1);
            currentRound.RealTimeMinersInformation[pubkey].ActualMiningTimes
            .Add(Context.CurrentBlockTime);

            Assert(triggerInformation.InValue != null, "In value should not be null.");

            var outValue  = Hash.FromMessage(triggerInformation.InValue);
            var signature =
                Hash.FromTwoHashes(outValue, triggerInformation.InValue); // Just initial signature value.
            var previousInValue = Hash.Empty;                             // Just initial previous in value.

            if (TryToGetPreviousRoundInformation(out var previousRound) && !IsFirstRoundOfCurrentTerm(out _))
            {
                signature = previousRound.CalculateSignature(triggerInformation.InValue);
                Context.LogDebug(
                    () => $"Previous in value in trigger information: {triggerInformation.PreviousInValue}");
                if (triggerInformation.PreviousInValue != null &&
                    triggerInformation.PreviousInValue != Hash.Empty)
                {
                    // Self check.
                    if (Hash.FromMessage(triggerInformation.PreviousInValue) !=
                        previousRound.RealTimeMinersInformation[pubkey].OutValue)
                    {
                        Context.LogDebug(() => "Failed to produce block at previous round?");
                        previousInValue = Hash.Empty;
                    }
                    else
                    {
                        previousInValue = triggerInformation.PreviousInValue;
                    }
                }
            }

            var updatedRound = currentRound.ApplyNormalConsensusData(pubkey, previousInValue,
                                                                     outValue, signature);

            Context.LogDebug(
                () => $"Previous in value after ApplyNormalConsensusData: " +
                $"{updatedRound.RealTimeMinersInformation[pubkey].PreviousInValue}");

            updatedRound.RealTimeMinersInformation[pubkey].ImpliedIrreversibleBlockHeight = Context.CurrentHeight;

            // Update secret pieces of latest in value.
            UpdateLatestSecretPieces(updatedRound, pubkey, triggerInformation);

            // To publish Out Value.
            return(new AElfConsensusHeaderInformation
            {
                SenderPubkey = pubkey.ToByteString(),
                Round = updatedRound,
                Behaviour = triggerInformation.Behaviour
            });
        }
Esempio n. 2
0
        private AElfConsensusHeaderInformation GetConsensusExtraDataToPublishOutValue(Round currentRound,
                                                                                      string publicKey, AElfConsensusTriggerInformation triggerInformation)
        {
            currentRound.RealTimeMinersInformation[publicKey].ProducedTinyBlocks = currentRound
                                                                                   .RealTimeMinersInformation[publicKey].ProducedTinyBlocks.Add(1);
            currentRound.RealTimeMinersInformation[publicKey].ProducedBlocks =
                currentRound.RealTimeMinersInformation[publicKey].ProducedBlocks.Add(1);
            currentRound.RealTimeMinersInformation[publicKey].ActualMiningTimes
            .Add(Context.CurrentBlockTime);

            Assert(triggerInformation.RandomHash != null, "Random hash should not be null.");

            var inValue   = currentRound.CalculateInValue(triggerInformation.RandomHash);
            var outValue  = Hash.FromMessage(inValue);
            var signature =
                Hash.FromTwoHashes(outValue, triggerInformation.RandomHash); // Just initial signature value.
            var previousInValue = Hash.Empty;                                // Just initial previous in value.

            if (TryToGetPreviousRoundInformation(out var previousRound) && !IsFirstRoundOfCurrentTerm(out _))
            {
                signature = previousRound.CalculateSignature(inValue);
                if (triggerInformation.PreviousRandomHash != null &&
                    triggerInformation.PreviousRandomHash != Hash.Empty)
                {
                    // If PreviousRandomHash is null or Hash.Empty, it means the sender unable or unwilling to publish his previous in value.
                    previousInValue = previousRound.CalculateInValue(triggerInformation.PreviousRandomHash);
                    // Self check.
                    if (Hash.FromMessage(previousInValue) !=
                        previousRound.RealTimeMinersInformation[publicKey].OutValue)
                    {
                        Context.LogDebug(() => "Failed to produce block at previous round?");
                        previousInValue = Hash.Empty;
                    }
                }
            }

            var updatedRound = currentRound.ApplyNormalConsensusData(publicKey, previousInValue,
                                                                     outValue, signature);

            updatedRound.RealTimeMinersInformation[publicKey].ImpliedIrreversibleBlockHeight = Context.CurrentHeight;

            ShareInValueOfCurrentRound(updatedRound, previousRound, inValue, publicKey);

            // To publish Out Value.
            return(new AElfConsensusHeaderInformation
            {
                SenderPubkey = publicKey.ToByteString(),
                Round = updatedRound,
                Behaviour = triggerInformation.Behaviour
            });
        }
        private AElfConsensusHeaderInformation GetConsensusExtraDataToPublishOutValue(Round currentRound,
                                                                                      string pubkey, AElfConsensusTriggerInformation triggerInformation)
        {
            currentRound.RealTimeMinersInformation[pubkey].ProducedTinyBlocks = currentRound
                                                                                .RealTimeMinersInformation[pubkey].ProducedTinyBlocks.Add(1);
            currentRound.RealTimeMinersInformation[pubkey].ProducedBlocks =
                currentRound.RealTimeMinersInformation[pubkey].ProducedBlocks.Add(1);
            currentRound.RealTimeMinersInformation[pubkey].ActualMiningTimes
            .Add(Context.CurrentBlockTime);

            Assert(triggerInformation.InValue != null, "In value should not be null.");

            var outValue  = HashHelper.ComputeFrom(triggerInformation.InValue);
            var signature =
                HashHelper.ConcatAndCompute(outValue, triggerInformation.InValue); // Just initial signature value.
            var previousInValue = Hash.Empty;                                      // Just initial previous in value.

            if (TryToGetPreviousRoundInformation(out var previousRound) && !IsFirstRoundOfCurrentTerm(out _))
            {
                if (triggerInformation.PreviousInValue != null &&
                    triggerInformation.PreviousInValue != Hash.Empty)
                {
                    Context.LogDebug(
                        () => $"Previous in value in trigger information: {triggerInformation.PreviousInValue}");
                    // Self check.
                    if (previousRound.RealTimeMinersInformation.ContainsKey(pubkey) &&
                        HashHelper.ComputeFrom(triggerInformation.PreviousInValue) !=
                        previousRound.RealTimeMinersInformation[pubkey].OutValue)
                    {
                        Context.LogDebug(() => "Failed to produce block at previous round?");
                        previousInValue = Hash.Empty;
                    }
                    else
                    {
                        previousInValue = triggerInformation.PreviousInValue;
                    }
                    signature = previousRound.CalculateSignature(triggerInformation.PreviousInValue);
                }
                else
                {
                    var fakePreviousInValue = HashHelper.ComputeFrom(pubkey.Append(Context.CurrentHeight.ToString()));
                    if (previousRound.RealTimeMinersInformation.ContainsKey(pubkey) && previousRound.RoundNumber != 1)
                    {
                        var appointedPreviousInValue = previousRound.RealTimeMinersInformation[pubkey].InValue;
                        if (appointedPreviousInValue != null)
                        {
                            fakePreviousInValue = appointedPreviousInValue;
                        }

                        Context.LogDebug(() => $"TEST:\n{previousRound.ToString(pubkey)}\nInValue: {fakePreviousInValue}");
                        signature = previousRound.CalculateSignature(fakePreviousInValue);
                    }
                    else
                    {
                        // This miner appears first time in current round, like as a replacement of evil miner.
                        signature = previousRound.CalculateSignature(fakePreviousInValue);
                    }
                }
            }

            var updatedRound = currentRound.ApplyNormalConsensusData(pubkey, previousInValue,
                                                                     outValue, signature);

            Context.LogDebug(
                () => $"Previous in value after ApplyNormalConsensusData: " +
                $"{updatedRound.RealTimeMinersInformation[pubkey].PreviousInValue}");

            updatedRound.RealTimeMinersInformation[pubkey].ImpliedIrreversibleBlockHeight = Context.CurrentHeight;

            // Update secret pieces of latest in value.
            UpdateLatestSecretPieces(updatedRound, pubkey, triggerInformation);

            // To publish Out Value.
            return(new AElfConsensusHeaderInformation
            {
                SenderPubkey = ByteStringHelper.FromHexString(pubkey),
                Round = updatedRound,
                Behaviour = triggerInformation.Behaviour
            });
        }