private void TryToBecomeAValidationDataCenter(VoteMinerInput input, long candidateVotesAmount, DataCenterRankingList rankingList) { var minimumVotes = candidateVotesAmount; var minimumVotesCandidate = input.CandidatePubkey; bool replaceWillHappen = false; foreach (var pubkeyToVotesAmount in rankingList.DataCenters.OrderBy(x => x.Value)) { if (pubkeyToVotesAmount.Value < minimumVotes) { replaceWillHappen = true; minimumVotesCandidate = pubkeyToVotesAmount.Key; break; } } if (replaceWillHappen) { State.DataCentersRankingList.Value.DataCenters.Remove(minimumVotesCandidate); State.DataCentersRankingList.Value.DataCenters.Add(input.CandidatePubkey, candidateVotesAmount); NotifyProfitReplaceCandidateInDataCenter(minimumVotesCandidate, input.CandidatePubkey); } }
private Hash GenerateVoteId(VoteMinerInput voteMinerInput) { if (voteMinerInput.Token != null) { return(Context.GenerateId(Context.Self, voteMinerInput.Token)); } var candidateVotesCount = State.CandidateVotes[voteMinerInput.CandidatePubkey]?.ObtainedActiveVotedVotesAmount ?? 0; return(Context.GenerateId(Context.Self, ByteArrayHelper.ConcatArrays(voteMinerInput.CandidatePubkey.GetBytes(), candidateVotesCount.ToBytes(false)))); }
/// <summary> /// Call the Vote function of VoteContract to do a voting. /// </summary> /// <param name="input"></param> /// <returns></returns> public override Empty Vote(VoteMinerInput input) { // Check candidate information map instead of candidates. var targetInformation = State.CandidateInformationMap[input.CandidatePubkey]; AssertValidCandidateInformation(targetInformation); var lockSeconds = (input.EndTimestamp - Context.CurrentBlockTime).Seconds; AssertValidLockSeconds(lockSeconds); State.LockTimeMap[Context.TransactionId] = lockSeconds; var recoveredPublicKey = Context.RecoverPublicKey(); UpdateElectorInformation(recoveredPublicKey, input.Amount); var candidateVotesAmount = UpdateCandidateInformation(input.CandidatePubkey, input.Amount); CallTokenContractLock(input.Amount); CallTokenContractIssue(input.Amount); CallVoteContractVote(input.Amount, input.CandidatePubkey); var votesWeight = GetVotesWeight(input.Amount, lockSeconds); CallProfitContractAddBeneficiary(votesWeight, lockSeconds); var rankingList = State.DataCentersRankingList.Value; if (State.DataCentersRankingList.Value.DataCenters.ContainsKey(input.CandidatePubkey)) { rankingList.DataCenters[input.CandidatePubkey] = rankingList.DataCenters[input.CandidatePubkey].Add(input.Amount); State.DataCentersRankingList.Value = rankingList; } if (State.Candidates.Value.Value.Count > GetValidationDataCenterCount() && !State.DataCentersRankingList.Value.DataCenters.ContainsKey(input.CandidatePubkey)) { TryToBecomeAValidationDataCenter(input, candidateVotesAmount, rankingList); } return(new Empty()); }
/// <summary> /// Call the Vote function of VoteContract to do a voting. /// </summary> /// <param name="input"></param> /// <returns></returns> public override Hash Vote(VoteMinerInput input) { // Check candidate information map instead of candidates. var targetInformation = State.CandidateInformationMap[input.CandidatePubkey]; AssertValidCandidateInformation(targetInformation); var lockSeconds = (input.EndTimestamp - Context.CurrentBlockTime).Seconds; AssertValidLockSeconds(lockSeconds); var voteId = GenerateVoteId(input); Assert(State.LockTimeMap[voteId] == 0, "Vote already exists."); State.LockTimeMap[voteId] = lockSeconds; var recoveredPublicKey = Context.RecoverPublicKey(); UpdateElectorInformation(recoveredPublicKey, input.Amount, voteId); var candidateVotesAmount = UpdateCandidateInformation(input.CandidatePubkey, input.Amount, voteId); LockTokensOfVoter(input.Amount, voteId); IssueOrTransferTokensToVoter(input.Amount); CallVoteContractVote(input.Amount, input.CandidatePubkey, voteId); AddBeneficiaryToVoter(GetVotesWeight(input.Amount, lockSeconds), lockSeconds); var rankingList = State.DataCentersRankingList.Value; if (State.DataCentersRankingList.Value.DataCenters.ContainsKey(input.CandidatePubkey)) { rankingList.DataCenters[input.CandidatePubkey] = rankingList.DataCenters[input.CandidatePubkey].Add(input.Amount); State.DataCentersRankingList.Value = rankingList; } if (State.Candidates.Value.Value.Count > GetValidationDataCenterCount() && !State.DataCentersRankingList.Value.DataCenters.ContainsKey(input.CandidatePubkey)) { TryToBecomeAValidationDataCenter(input, candidateVotesAmount, rankingList); } return(voteId); }
private void TryToBecomeAValidationDataCenter(VoteMinerInput input, long candidateVotesAmount, DataCenterRankingList rankingList) { var minimumVotes = candidateVotesAmount; var minimumVotesCandidate = input.CandidatePubkey; bool replaceWillHappen = false; foreach (var pubkeyToVotesAmount in rankingList.DataCenters.Reverse()) { if (pubkeyToVotesAmount.Value < minimumVotes) { replaceWillHappen = true; minimumVotesCandidate = pubkeyToVotesAmount.Key; break; } } if (replaceWillHappen) { State.DataCentersRankingList.Value.DataCenters.Remove(minimumVotesCandidate); State.DataCentersRankingList.Value.DataCenters.Add(input.CandidatePubkey, candidateVotesAmount); State.ProfitContract.RemoveBeneficiary.Send(new RemoveBeneficiaryInput { SchemeId = State.SubsidyHash.Value, Beneficiary = Address.FromPublicKey(ByteArrayHelper.HexStringToByteArray(minimumVotesCandidate)) }); State.ProfitContract.AddBeneficiary.Send(new AddBeneficiaryInput { SchemeId = State.SubsidyHash.Value, BeneficiaryShare = new BeneficiaryShare { Beneficiary = Address.FromPublicKey(ByteArrayHelper.HexStringToByteArray(input.CandidatePubkey)), Shares = 1 } }); } }
public override Empty Vote(VoteMinerInput input) { var lockTime = input.LockTimeUnit == LockTimeUnit.Days ? input.LockTime : input.LockTime * 30; Assert(lockTime >= 90, "Should lock token for at least 90 days."); State.LockTimeMap[Context.TransactionId] = lockTime; State.TokenContract.Transfer.Send(new TransferInput { Symbol = ElectionContractConsts.VoteSymbol, To = Context.Sender, Amount = input.Amount, Memo = "Get VOTEs." }); State.TokenContract.Lock.Send(new LockInput { From = Context.Sender, Symbol = Context.Variables.NativeSymbol, LockId = Context.TransactionId, Amount = input.Amount, To = Context.Self, Usage = $"Voting for {ElectionContractConsts.Topic}" }); State.VoteContract.Vote.Send(new VoteInput { Topic = ElectionContractConsts.Topic, Sponsor = Context.Self, Amount = input.Amount, Option = input.CandidatePublicKey, Voter = Context.Sender, VoteId = Context.TransactionId }); return(new Empty()); }
/// <summary> /// Call the Vote function of VoteContract to do a voting. /// </summary> /// <param name="input"></param> /// <returns></returns> public override Empty Vote(VoteMinerInput input) { // Check candidate information map instead of candidates. var targetInformation = State.CandidateInformationMap[input.CandidatePubkey]; Assert(targetInformation != null, "Candidate not found."); if (targetInformation == null) { return(new Empty()); // Just to avoid IDE warning. } Assert(targetInformation.IsCurrentCandidate, "Candidate quited election."); var lockSeconds = (input.EndTimestamp - Context.CurrentBlockTime).Seconds; Assert(lockSeconds >= State.MinimumLockTime.Value, $"Invalid lock time. At least {State.MinimumLockTime.Value.Div(60).Div(60).Div(24)} days"); Assert(lockSeconds <= State.MaximumLockTime.Value, $"Invalid lock time. At most {State.MaximumLockTime.Value.Div(60).Div(60).Div(24)} days"); State.LockTimeMap[Context.TransactionId] = lockSeconds; var recoveredPublicKey = Context.RecoverPublicKey(); UpdateElectorInformation(recoveredPublicKey, input.Amount); var candidateVotesAmount = UpdateCandidateInformation(input.CandidatePubkey, input.Amount); State.TokenContract.Lock.Send(new LockInput { Address = Context.Sender, Symbol = Context.Variables.NativeSymbol, LockId = Context.TransactionId, Amount = GetElfAmount(input.Amount), Usage = "Voting for Main Chain Miner Election." }); State.TokenContract.Issue.Send(new IssueInput { Symbol = ElectionContractConstants.VoteSymbol, To = Context.Sender, Amount = input.Amount, Memo = "Issue VOTEs." }); State.VoteContract.Vote.Send(new VoteInput { Voter = Context.Sender, VotingItemId = State.MinerElectionVotingItemId.Value, Amount = input.Amount, Option = input.CandidatePubkey, VoteId = Context.TransactionId }); var votesWeight = GetVotesWeight(input.Amount, lockSeconds); State.ProfitContract.AddBeneficiary.Send(new AddBeneficiaryInput { SchemeId = State.WelfareHash.Value, BeneficiaryShare = new BeneficiaryShare { Beneficiary = Context.Sender, Shares = votesWeight }, EndPeriod = GetEndPeriod(lockSeconds) }); var rankingList = State.DataCentersRankingList.Value; if (State.DataCentersRankingList.Value.DataCenters.ContainsKey(input.CandidatePubkey)) { rankingList.DataCenters[input.CandidatePubkey] = rankingList.DataCenters[input.CandidatePubkey].Add(input.Amount); State.DataCentersRankingList.Value = rankingList; } if (State.Candidates.Value.Value.Count > GetValidationDataCenterCount() && !State.DataCentersRankingList.Value.DataCenters.ContainsKey(input.CandidatePubkey)) { TryToBecomeAValidationDataCenter(input, candidateVotesAmount, rankingList); } return(new Empty()); }