public static bool IsExpired(this VotingRecord votingRecord, long currentAge) { var lockExpiredAge = votingRecord.VoteAge; foreach (var day in votingRecord.LockDaysList) { lockExpiredAge += day; } return(lockExpiredAge <= currentAge); }
public override Hash Vote(VoteInput input) { var candidatePublicKey = input.CandidatePublicKey; var amount = input.Amount; var lockTime = input.LockTime; Assert(lockTime.InRange(90, 1095), ContractErrorCode.GetErrorMessage(ContractErrorCode.InvalidOperation, "Lock days is illegal.")); // Cannot vote to non-candidate. var candidates = State.CandidatesField.Value; Assert(candidates != null, ContractErrorCode.GetErrorMessage(ContractErrorCode.NotFound, "No candidate.")); Assert(candidates != null && candidates.PublicKeys.Contains(candidatePublicKey), ContractErrorCode.GetErrorMessage(ContractErrorCode.InvalidOperation, "Target didn't announce election.")); var voterPublicKey = Context.RecoverPublicKey().ToHex(); // A candidate cannot vote to anybody. Assert(candidates != null && !candidates.PublicKeys.Contains(voterPublicKey), ContractErrorCode.GetErrorMessage(ContractErrorCode.InvalidOperation, "Candidate can't vote.")); // Transfer the tokens to Consensus Contract address. State.TokenContract.Lock.Send(new LockInput { From = Context.Sender, To = Context.Self, Symbol = Context.Variables.NativeSymbol, Amount = amount, LockId = Context.TransactionId, Usage = "Lock for getting tickets." }); var currentTermNumber = State.CurrentTermNumberField.Value; var currentRoundNumber = State.CurrentRoundNumberField.Value; // To make up a VotingRecord instance. TryToGetBlockchainStartTimestamp(out var blockchainStartTimestamp); var votingRecord = new VotingRecord { Count = amount, From = voterPublicKey, To = candidatePublicKey, RoundNumber = currentRoundNumber, TransactionId = Context.TransactionId, VoteAge = CurrentAge, UnlockAge = CurrentAge + (long)lockTime, TermNumber = currentTermNumber, VoteTimestamp = blockchainStartTimestamp.ToDateTime().AddMinutes(CurrentAge).ToTimestamp(), UnlockTimestamp = blockchainStartTimestamp.ToDateTime().AddMinutes(CurrentAge + (long)lockTime) .ToTimestamp() }; votingRecord.LockDaysList.Add(lockTime); // Add the transaction id of this voting record to the tickets information of the voter. var tickets = State.TicketsMap[voterPublicKey.ToStringValue()]; if (tickets != null) { tickets.VoteToTransactions.Add(votingRecord.TransactionId); } else { tickets = new Tickets { PublicKey = voterPublicKey }; tickets.VoteToTransactions.Add(votingRecord.TransactionId); } tickets.VotedTickets += votingRecord.Count; tickets.HistoryVotedTickets += votingRecord.Count; State.TicketsMap[voterPublicKey.ToStringValue()] = tickets; // Add the transaction id of this voting record to the tickets information of the candidate. var candidateTickets = State.TicketsMap[candidatePublicKey.ToStringValue()]; if (candidateTickets != null) { candidateTickets.VoteFromTransactions.Add(votingRecord.TransactionId); } else { candidateTickets = new Tickets { PublicKey = candidatePublicKey }; candidateTickets.VoteFromTransactions.Add(votingRecord.TransactionId); } candidateTickets.ObtainedTickets += votingRecord.Count; candidateTickets.HistoryObtainedTickets += votingRecord.Count; State.TicketsMap[candidatePublicKey.ToStringValue()] = candidateTickets; // Update the amount of votes (voting records of whole system). State.VotesCountField.Value += 1; // Update the amount of tickets. State.TicketsCountField.Value += votingRecord.Count; // Add this voting record to voting records map. State.VotingRecordsMap[votingRecord.TransactionId] = votingRecord; // Tell Dividends Contract to add weights for this voting record. State.DividendContract.AddWeights.Send(new Dividend.WeightsInfo() { TermNumber = currentTermNumber + 1, Weights = votingRecord.Weight }); Context.LogDebug(() => $"Weights of vote {votingRecord.TransactionId.ToHex()}: {votingRecord.Weight}"); return(Context.TransactionId); }