github.com/decred/politeia@v1.4.0/politeiawww/cmd/pictl/ticketvote.go (about) 1 // Copyright (c) 2020-2021 The Decred developers 2 // Use of this source code is governed by an ISC 3 // license that can be found in the LICENSE file. 4 5 package main 6 7 import ( 8 "fmt" 9 "sort" 10 "strings" 11 12 tkv1 "github.com/decred/politeia/politeiawww/api/ticketvote/v1" 13 ) 14 15 const ( 16 // defaultDuration is the default duration, in blocks, of a DCR ticket vote. 17 defaultDuration uint32 = 6 18 19 // defaultQuorum is the default percent of total votes required for a quorum. 20 defaultQuorum uint32 = 0 21 22 // defaultPassing is the default percent of cast votes required for a vote 23 // option to be considered as passing. 24 defaultPassing uint32 = 60 25 ) 26 27 func printAuthDetails(a tkv1.AuthDetails) { 28 printf("Token : %v\n", a.Token) 29 printf("Action : %v\n", a.Action) 30 printf("Timestamp: %v\n", dateAndTimeFromUnix(a.Timestamp)) 31 printf("Receipt : %v\n", a.Receipt) 32 } 33 34 func printVoteDetails(v tkv1.VoteDetails) { 35 printf("Token : %v\n", v.Params.Token) 36 printf("Type : %v\n", tkv1.VoteTypes[v.Params.Type]) 37 if v.Params.Type == tkv1.VoteTypeRunoff { 38 printf("Parent : %v\n", v.Params.Parent) 39 } 40 printf("Pass Percentage : %v%%\n", v.Params.PassPercentage) 41 printf("Quorum Percentage : %v%%\n", v.Params.QuorumPercentage) 42 printf("Duration : %v blocks\n", v.Params.Duration) 43 printf("Start Block Hash : %v\n", v.StartBlockHash) 44 printf("Start Block Height: %v\n", v.StartBlockHeight) 45 printf("End Block Height : %v\n", v.EndBlockHeight) 46 printf("Vote options\n") 47 for _, v := range v.Params.Options { 48 printf(" %v %v %v\n", v.Bit, v.ID, v.Description) 49 } 50 } 51 52 func printVoteResults(votes []tkv1.CastVoteDetails) { 53 if len(votes) == 0 { 54 return 55 } 56 57 // Tally results 58 results := make(map[string]int) 59 for _, v := range votes { 60 results[v.VoteBit]++ 61 } 62 63 // Order results 64 r := make([]string, 0, len(results)) 65 for k := range results { 66 r = append(r, k) 67 } 68 sort.SliceStable(r, func(i, j int) bool { 69 return r[i] < r[j] 70 }) 71 72 // Print results 73 printf("Token: %v\n", votes[0].Token) 74 printf("Results\n") 75 for _, v := range r { 76 printf(" %v: %v\n", v, results[v]) 77 } 78 } 79 80 // voteSummaryString returns a string that contains the pretty printed vote 81 // summary. 82 // 83 // Example output: 84 // Token : db9b06f36c21991c 85 // Status : rejected 86 // Type : standard 87 // Quorum Percentage : 1% of eligible votes (46 votes) 88 // Pass Percentage : 50% of cast votes (30 votes) 89 // Duration : 1 blocks 90 // Start Block Hash : 000000007f1cacdef29710d0f95457364a9e4649904a0655d6ae9cec 91 // Start Block Height: 800034 92 // End Block Height : 800051 93 // Eligible Tickets : 4638 tickets 94 // Best Block : 800051 95 // Results 96 // 97 // 1 yes 0 votes 98 // 2 no 60 votes 99 // 100 // indentInSpaces can be used to add indentation to each line of the string. 101 // The provided number of spaces will be inserted at the beginning of each 102 // line. 103 func voteSummaryString(token string, s tkv1.Summary, indentInSpaces uint) string { 104 var sb strings.Builder 105 106 sb.WriteString(fmt.Sprintf("Token : %v\n", 107 token)) 108 sb.WriteString(fmt.Sprintf("Status : %v\n", 109 tkv1.VoteStatuses[s.Status])) 110 switch s.Status { 111 case tkv1.VoteStatusUnauthorized, tkv1.VoteStatusAuthorized, 112 tkv1.VoteStatusIneligible: 113 // Nothing else to print 114 return addIndent(sb.String(), indentInSpaces) 115 } 116 117 var ( 118 total uint64 // Total votes cast 119 quorum int // Votes required to reach a quorum 120 pass int // Votes required to pass 121 ) 122 for _, v := range s.Results { 123 total += v.Votes 124 } 125 quorum = int(float64(s.QuorumPercentage) / 100 * float64(s.EligibleTickets)) 126 pass = int(float64(s.PassPercentage) / 100 * float64(total)) 127 128 sb.WriteString(fmt.Sprintf("Type : %v\n", 129 tkv1.VoteTypes[s.Type])) 130 sb.WriteString(fmt.Sprintf("Quorum Percentage : %v%% of eligible votes "+ 131 "(%v votes)\n", 132 s.QuorumPercentage, quorum)) 133 sb.WriteString(fmt.Sprintf("Pass Percentage : %v%% of cast votes "+ 134 "(%v votes)\n", 135 s.PassPercentage, pass)) 136 sb.WriteString(fmt.Sprintf("Duration : %v blocks\n", 137 s.Duration)) 138 sb.WriteString(fmt.Sprintf("Start Block Hash : %v\n", 139 s.StartBlockHash)) 140 sb.WriteString(fmt.Sprintf("Start Block Height: %v\n", 141 s.StartBlockHeight)) 142 sb.WriteString(fmt.Sprintf("End Block Height : %v\n", 143 s.EndBlockHeight)) 144 sb.WriteString(fmt.Sprintf("Eligible Tickets : %v tickets\n", 145 s.EligibleTickets)) 146 sb.WriteString(fmt.Sprintf("Best Block : %v\n", 147 s.BestBlock)) 148 sb.WriteString("Results\n") 149 for _, v := range s.Results { 150 sb.WriteString(fmt.Sprintf(" %v %-3v %v votes\n", 151 v.VoteBit, v.ID, v.Votes)) 152 } 153 154 return addIndent(sb.String(), indentInSpaces) 155 }