private async Task AEDPoSContract_FirstRound_SecondMiner_Test()
        {
            var transaction =
                (await AEDPoSContract_GenerateConsensusTransactions_FirstRound_SecondMiner_Test()).Transactions.First();

            var usingKeyPair = InitialCoreDataCenterKeyPairs[1];

            KeyPairProvider.SetKeyPair(usingKeyPair);

            BlockTimeProvider.SetBlockTime(BlockchainStartTimestamp + new Duration
            {
                Seconds = AEDPoSContractTestConstants.MiningInterval.Mul(2).Div(1000)
            });

            var updateValueInput = new UpdateValueInput();

            updateValueInput.MergeFrom(transaction.Params);

            var stub = GetAEDPoSContractStub(usingKeyPair);
            await stub.UpdateValue.SendAsync(updateValueInput);

            var currentRound = await stub.GetCurrentRoundInformation.CallAsync(new Empty());

            currentRound.RoundNumber.ShouldBe(1);
            currentRound.RealTimeMinersInformation[usingKeyPair.PublicKey.ToHex()].OutValue.ShouldNotBeNull();
        }
示例#2
0
 private static void PerformSecretSharing(UpdateValueInput input, MinerInRound minerInRound, Round round,
                                          string publicKey)
 {
     minerInRound.EncryptedInValues.Add(input.EncryptedInValues);
     foreach (var decryptedPreviousInValue in input.DecryptedPreviousInValues)
     {
         round.RealTimeMinersInformation[decryptedPreviousInValue.Key].DecryptedPreviousInValues
         .Add(publicKey, decryptedPreviousInValue.Value);
     }
 }
示例#3
0
        public override Empty UpdateValue(UpdateValueInput input)
        {
            Assert(TryToGetCurrentRoundInformation(out var round), "Round information not found.");
            Assert(input.RoundId == round.RoundId, "Round Id not matched.");

            var publicKey = Context.RecoverPublicKey().ToHex();

            if (!round.RealTimeMinersInformation.Keys.Contains(publicKey))
            {
                return(new Empty());
            }

            var minerInRound = round.RealTimeMinersInformation[publicKey];

            minerInRound.ActualMiningTimes.Add(input.ActualMiningTime);
            minerInRound.ProducedBlocks                 = input.ProducedBlocks;
            minerInRound.ProducedTinyBlocks             = round.RealTimeMinersInformation[publicKey].ProducedTinyBlocks.Add(1);
            minerInRound.Signature                      = input.Signature;
            minerInRound.OutValue                       = input.OutValue;
            minerInRound.SupposedOrderOfNextRound       = input.SupposedOrderOfNextRound;
            minerInRound.FinalOrderOfNextRound          = input.SupposedOrderOfNextRound;
            minerInRound.ImpliedIrreversibleBlockHeight = input.ImpliedIrreversibleBlockHeight;

            PerformSecretSharing(input, minerInRound, round, publicKey);

            UpdatePreviousInValues(input, publicKey, round);

            foreach (var tuneOrder in input.TuneOrderInformation)
            {
                round.RealTimeMinersInformation[tuneOrder.Key].FinalOrderOfNextRound = tuneOrder.Value;
            }

            // For first round of each term, no one need to publish in value.
            if (input.PreviousInValue != Hash.Empty)
            {
                minerInRound.PreviousInValue = input.PreviousInValue;
            }

            if (!TryToUpdateRoundInformation(round))
            {
                Assert(false, "Failed to update round information.");
            }

            var irreversibleBlockHeight = CalculateLastIrreversibleBlockHeight();

            if (irreversibleBlockHeight != 0)
            {
                Context.Fire(new IrreversibleBlockFound
                {
                    IrreversibleBlockHeight = irreversibleBlockHeight
                });
            }

            return(new Empty());
        }
        private void ProcessUpdateValue(UpdateValueInput updateValueInput)
        {
            TryToGetCurrentRoundInformation(out var currentRound, true);

            var minerInRound = currentRound.RealTimeMinersInformation[_processingBlockMinerPubkey];

            minerInRound.ActualMiningTimes.Add(updateValueInput.ActualMiningTime);
            minerInRound.ProducedBlocks     = updateValueInput.ProducedBlocks;
            minerInRound.ProducedTinyBlocks =
                currentRound.RealTimeMinersInformation[_processingBlockMinerPubkey].ProducedTinyBlocks.Add(1);
            minerInRound.Signature = updateValueInput.Signature;
            minerInRound.OutValue  = updateValueInput.OutValue;
            minerInRound.SupposedOrderOfNextRound       = updateValueInput.SupposedOrderOfNextRound;
            minerInRound.FinalOrderOfNextRound          = updateValueInput.SupposedOrderOfNextRound;
            minerInRound.ImpliedIrreversibleBlockHeight = updateValueInput.ImpliedIrreversibleBlockHeight;

            PerformSecretSharing(updateValueInput, minerInRound, currentRound, _processingBlockMinerPubkey);

            UpdatePreviousInValues(updateValueInput, _processingBlockMinerPubkey, currentRound);

            foreach (var tuneOrder in updateValueInput.TuneOrderInformation)
            {
                currentRound.RealTimeMinersInformation[tuneOrder.Key].FinalOrderOfNextRound = tuneOrder.Value;
            }

            // It is permissible for miners not publish their in values.
            if (updateValueInput.PreviousInValue != Hash.Empty)
            {
                minerInRound.PreviousInValue = updateValueInput.PreviousInValue;
            }

            if (TryToGetPreviousRoundInformation(out var previousRound))
            {
                new LastIrreversibleBlockHeightCalculator(currentRound, previousRound).Deconstruct(
                    out var libHeight);
                Context.LogDebug(() => $"Finished calculation of lib height: {libHeight}");
                // LIB height can't be available if it is lower than last time.
                if (currentRound.ConfirmedIrreversibleBlockHeight < libHeight)
                {
                    Context.LogDebug(() => $"New lib height: {libHeight}");
                    Context.Fire(new IrreversibleBlockFound
                    {
                        IrreversibleBlockHeight = libHeight
                    });
                    currentRound.ConfirmedIrreversibleBlockHeight      = libHeight;
                    currentRound.ConfirmedIrreversibleBlockRoundNumber = currentRound.RoundNumber.Sub(1);
                }
            }

            if (!TryToUpdateRoundInformation(currentRound))
            {
                Assert(false, "Failed to update round information.");
            }
        }
示例#5
0
        private void UpdatePreviousInValues(UpdateValueInput input, string publicKey, Round round)
        {
            foreach (var previousInValue in input.MinersPreviousInValues)
            {
                if (previousInValue.Key == publicKey)
                {
                    continue;
                }

                var filledValue = round.RealTimeMinersInformation[previousInValue.Key].PreviousInValue;
                if (filledValue != null && filledValue != previousInValue.Value)
                {
                    Context.LogDebug(() => $"Something wrong happened to previous in value of {previousInValue.Key}.");
                    State.ElectionContract.UpdateCandidateInformation.Send(new UpdateCandidateInformationInput
                    {
                        Pubkey     = publicKey,
                        IsEvilNode = true
                    });
                }

                round.RealTimeMinersInformation[previousInValue.Key].PreviousInValue = previousInValue.Value;
            }
        }
 public override Empty UpdateValue(UpdateValueInput input)
 {
     ProcessConsensusInformation(input);
     return(new Empty());
 }