private Round GenerateFirstRoundOfNewTerm(MinerList minerList, int miningInterval,
                                                  Timestamp currentBlockTime, long currentRoundNumber = 0, long currentTermNumber = 0)
        {
            var sortedMiners = minerList.Pubkeys.Select(x => x.ToHex()).ToList();
            var round        = new Round();

            for (var i = 0; i < sortedMiners.Count; i++)
            {
                var minerInRound = new MinerInRound();

                // The third miner will be the extra block producer of first round of each term.
                if (i == 0)
                {
                    minerInRound.IsExtraBlockProducer = true;
                }

                minerInRound.Pubkey             = sortedMiners[i];
                minerInRound.Order              = i + 1;
                minerInRound.ExpectedMiningTime = currentBlockTime.AddMilliseconds(i * miningInterval + miningInterval);
                // Should be careful during validation.
                minerInRound.PreviousInValue = Hash.Empty;
                round.RealTimeMinersInformation.Add(sortedMiners[i], minerInRound);
            }

            round.RoundNumber                       = currentRoundNumber + 1;
            round.TermNumber                        = currentTermNumber + 1;
            round.IsMinerListJustChanged            = true;
            round.ExtraBlockProducerOfPreviousRound = sortedMiners[0];

            return(round);
        }
Exemplo n.º 2
0
        GenerateConsensusInitializationCallList()
        {
            var aelfConsensusMethodCallList = new SystemContractDeploymentInput.Types.SystemTransactionMethodCallList();

            aelfConsensusMethodCallList.Add(
                nameof(AEDPoSContractContainer.AEDPoSContractStub.InitialAElfConsensusContract),
                new InitialAElfConsensusContractInput
            {
                PeriodSeconds         = _consensusOptions.PeriodSeconds,
                MinerIncreaseInterval = _consensusOptions.MinerIncreaseInterval,
                IsTermStayOne         = true
            });
            var firstRound = new MinerList
            {
                Pubkeys =
                {
                    _consensusOptions.InitialMinerList.Select(p => p.ToByteString())
                }
            }.GenerateFirstRoundOfNewTerm(_consensusOptions.MiningInterval,
                                          _consensusOptions.StartTimestamp.ToDateTime());

            aelfConsensusMethodCallList.Add(nameof(AEDPoSContractContainer.AEDPoSContractStub.FirstRound),
                                            firstRound);
            return(aelfConsensusMethodCallList);
        }
Exemplo n.º 3
0
        private void InitialConsensus(DateTime currentBlockTime)
        {
            _contractStubs.First().InitialAElfConsensusContract.SendAsync(new InitialAElfConsensusContractInput
            {
                MinerIncreaseInterval = AEDPoSExtensionConstants.MinerIncreaseInterval,
                TimeEachTerm          = AEDPoSExtensionConstants.TimeEachTerm
            });

            var initialMinerList = new MinerList
            {
                Pubkeys = { MissionedECKeyPairs.InitialKeyPairs.Select(p => ByteString.CopyFrom(p.PublicKey)) }
            };

            _currentRound =
                initialMinerList.GenerateFirstRoundOfNewTerm(AEDPoSExtensionConstants.MiningInterval,
                                                             currentBlockTime);
            _contractStubs.First().FirstRound.SendAsync(_currentRound);
        }
Exemplo n.º 4
0
        private async Task InitialConsensus(DateTime currentBlockTime)
        {
            // InitialAElfConsensusContract
            {
                var executionResult = await _contractStubs.First().InitialAElfConsensusContract.SendAsync(
                    new InitialAElfConsensusContractInput
                {
                    MinerIncreaseInterval = AEDPoSExtensionConstants.MinerIncreaseInterval,
                    TimeEachTerm          = AEDPoSExtensionConstants.TimeEachTerm
                });

                if (executionResult.TransactionResult.Status != TransactionResultStatus.Mined)
                {
                    throw new InitializationFailedException("Failed to execute InitialAElfConsensusContract.",
                                                            executionResult.TransactionResult.Error);
                }
            }

            var initialMinerList = new MinerList
            {
                Pubkeys = { MissionedECKeyPairs.InitialKeyPairs.Select(p => ByteString.CopyFrom(p.PublicKey)) }
            };

            _currentRound =
                initialMinerList.GenerateFirstRoundOfNewTerm(AEDPoSExtensionConstants.MiningInterval,
                                                             currentBlockTime);
            _testDataProvider.SetBlockTime(currentBlockTime.ToTimestamp());

            // FirstRound
            {
                var executionResult = await _contractStubs.First().FirstRound.SendAsync(_currentRound);

                if (executionResult.TransactionResult.Status != TransactionResultStatus.Mined)
                {
                    throw new InitializationFailedException("Failed to execute FirstRound.",
                                                            executionResult.TransactionResult.Error);
                }
            }
            _testDataProvider.SetBlockTime(currentBlockTime.AddMilliseconds(AEDPoSExtensionConstants.MiningInterval)
                                           .ToTimestamp());
        }
Exemplo n.º 5
0
        protected async Task NextTerm(ECKeyPair keyPair)
        {
            var miner = GetConsensusContractTester(keyPair);
            var round = await miner.GetCurrentRoundInformation.CallAsync(new Empty());

            var victories = await ElectionContractStub.GetVictories.CallAsync(new Empty());

            var miners = new MinerList
            {
                Pubkeys =
                {
                    victories.Value
                }
            };
            var firstRoundOfNextTerm =
                miners.GenerateFirstRoundOfNewTerm(EconomicContractsTestConstants.MiningInterval,
                                                   BlockTimeProvider.GetBlockTime(), round.RoundNumber, round.TermNumber);
            var executionResult = (await miner.NextTerm.SendAsync(firstRoundOfNextTerm)).TransactionResult;

            executionResult.Status.ShouldBe(TransactionResultStatus.Mined);
        }
        internal static Round GenerateFirstRoundOfNewTerm(this MinerList miners, int miningInterval,
                                                          DateTime currentBlockTime, long currentRoundNumber = 0, long currentTermNumber = 0)
        {
            var sortedMiners =
                (from obj in miners.Pubkeys.Distinct()
                 .ToDictionary <ByteString, string, int>(miner => miner.ToHex(), miner => miner[0])
                 orderby obj.Value descending
                 select obj.Key).ToList();

            var round = new Round();

            for (var i = 0; i < sortedMiners.Count; i++)
            {
                var minerInRound = new MinerInRound();

                // The first miner will be the extra block producer of first round of each term.
                if (i == 0)
                {
                    minerInRound.IsExtraBlockProducer = true;
                }

                minerInRound.Pubkey             = sortedMiners[i];
                minerInRound.Order              = i + 1;
                minerInRound.ExpectedMiningTime =
                    currentBlockTime.AddMilliseconds((i * miningInterval) + miningInterval).ToTimestamp();
                // Should be careful during validation.
                minerInRound.PreviousInValue = Hash.Empty;

                round.RealTimeMinersInformation.Add(sortedMiners[i], minerInRound);
            }

            round.RoundNumber            = currentRoundNumber + 1;
            round.TermNumber             = currentTermNumber + 1;
            round.IsMinerListJustChanged = true;

            return(round);
        }