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(); }
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); } }
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."); } }
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()); }