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 }