github.com/mavryk-network/mvgo@v1.19.9/rpc/votes.go (about)

     1  // Copyright (c) 2020-2021 Blockwatch Data Inc.
     2  // Author: alex@blockwatch.cc
     3  
     4  package rpc
     5  
     6  import (
     7  	"bytes"
     8  	"context"
     9  	"encoding/json"
    10  	"fmt"
    11  	"strconv"
    12  
    13  	"github.com/mavryk-network/mvgo/mavryk"
    14  )
    15  
    16  // Voter holds information about a vote listing
    17  type Voter struct {
    18  	Delegate mavryk.Address `json:"pkh"`
    19  	Rolls    int64          `json:"rolls"`
    20  	Power    int64          `json:"voting_power,string"`
    21  }
    22  
    23  // VoterList contains a list of voters
    24  type VoterList []Voter
    25  
    26  // BallotInfo holds information about a vote listing
    27  type BallotInfo struct {
    28  	Delegate mavryk.Address    `json:"pkh"`
    29  	Ballot   mavryk.BallotVote `json:"ballot"`
    30  }
    31  
    32  // BallotList contains a list of voters
    33  type BallotList []BallotInfo
    34  
    35  // Ballots holds the current summary of a vote
    36  type BallotSummary struct {
    37  	Yay  Int64orString `json:"yay"`
    38  	Nay  Int64orString `json:"nay"`
    39  	Pass Int64orString `json:"pass"`
    40  }
    41  
    42  // Proposal holds information about a vote listing
    43  type Proposal struct {
    44  	Proposal mavryk.ProtocolHash `json:"proposal"`
    45  	Upvotes  int64               `json:"upvotes,string"`
    46  }
    47  
    48  func (p *Proposal) UnmarshalJSON(data []byte) error {
    49  	if len(data) == 0 || bytes.Equal(data, null) || len(data) == 2 {
    50  		return nil
    51  	}
    52  	if data[0] != '[' {
    53  		return fmt.Errorf("rpc: proposal: expected JSON array")
    54  	}
    55  	dec := json.NewDecoder(bytes.NewReader(data))
    56  	dec.UseNumber()
    57  	unpacked := make([]interface{}, 0)
    58  	err := dec.Decode(&unpacked)
    59  	if err != nil {
    60  		return fmt.Errorf("rpc: proposal: %v", err)
    61  	}
    62  	if len(unpacked) != 2 {
    63  		return fmt.Errorf("rpc: proposal: invalid JSON array")
    64  	}
    65  	if err := p.Proposal.UnmarshalText([]byte(unpacked[0].(string))); err != nil {
    66  		return fmt.Errorf("rpc: proposal: %v", err)
    67  	}
    68  	switch v := unpacked[1].(type) {
    69  	case json.Number:
    70  		p.Upvotes, err = strconv.ParseInt(v.String(), 10, 64)
    71  	case string:
    72  		p.Upvotes, err = strconv.ParseInt(v, 10, 64)
    73  	}
    74  	if err != nil {
    75  		return fmt.Errorf("rpc: proposal: %v", err)
    76  	}
    77  	return nil
    78  }
    79  
    80  // ProposalList contains a list of voters
    81  type ProposalList []Proposal
    82  
    83  // ListVoters returns information about all eligible voters for an election
    84  // at block id.
    85  func (c *Client) ListVoters(ctx context.Context, id BlockID) (VoterList, error) {
    86  	voters := make(VoterList, 0)
    87  	u := fmt.Sprintf("chains/main/blocks/%s/votes/listings", id)
    88  	if err := c.Get(ctx, u, &voters); err != nil {
    89  		return nil, err
    90  	}
    91  	return voters, nil
    92  }
    93  
    94  // GetVoteQuorum returns information about the current voring quorum at block id.
    95  // Returned value is percent * 10000 i.e. 5820 for 58.20%.
    96  func (c *Client) GetVoteQuorum(ctx context.Context, id BlockID) (int, error) {
    97  	var quorum int
    98  	u := fmt.Sprintf("chains/main/blocks/%s/votes/current_quorum", id)
    99  	if err := c.Get(ctx, u, &quorum); err != nil {
   100  		return 0, err
   101  	}
   102  	return quorum, nil
   103  }
   104  
   105  // GetVoteProposal returns the hash of the current voring proposal at block id.
   106  func (c *Client) GetVoteProposal(ctx context.Context, id BlockID) (mavryk.ProtocolHash, error) {
   107  	var proposal mavryk.ProtocolHash
   108  	u := fmt.Sprintf("chains/main/blocks/%s/votes/current_proposal", id)
   109  	err := c.Get(ctx, u, &proposal)
   110  	return proposal, err
   111  }
   112  
   113  // ListBallots returns information about all eligible voters for an election at block id.
   114  func (c *Client) ListBallots(ctx context.Context, id BlockID) (BallotList, error) {
   115  	ballots := make(BallotList, 0)
   116  	u := fmt.Sprintf("chains/main/blocks/%s/votes/ballot_list", id)
   117  	if err := c.Get(ctx, u, &ballots); err != nil {
   118  		return nil, err
   119  	}
   120  	return ballots, nil
   121  }
   122  
   123  // GetVoteResult returns a summary of the current voting result at block id.
   124  func (c *Client) GetVoteResult(ctx context.Context, id BlockID) (BallotSummary, error) {
   125  	summary := BallotSummary{}
   126  	u := fmt.Sprintf("chains/main/blocks/%s/votes/ballots", id)
   127  	err := c.Get(ctx, u, &summary)
   128  	return summary, err
   129  }
   130  
   131  // ListProposals returns a list of all submitted proposals and their upvote count at block id.
   132  // This call only returns results when block is within a proposal vote period.
   133  func (c *Client) ListProposals(ctx context.Context, id BlockID) (ProposalList, error) {
   134  	proposals := make(ProposalList, 0)
   135  	u := fmt.Sprintf("chains/main/blocks/%s/votes/proposals", id)
   136  	if err := c.Get(ctx, u, &proposals); err != nil {
   137  		return nil, err
   138  	}
   139  	return proposals, nil
   140  }