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  }