code.vegaprotocol.io/vega@v0.79.0/datanode/entities/vote.go (about) 1 // Copyright (C) 2023 Gobalsky Labs Limited 2 // 3 // This program is free software: you can redistribute it and/or modify 4 // it under the terms of the GNU Affero General Public License as 5 // published by the Free Software Foundation, either version 3 of the 6 // License, or (at your option) any later version. 7 // 8 // This program is distributed in the hope that it will be useful, 9 // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 // GNU Affero General Public License for more details. 12 // 13 // You should have received a copy of the GNU Affero General Public License 14 // along with this program. If not, see <http://www.gnu.org/licenses/>. 15 16 package entities 17 18 import ( 19 "encoding/json" 20 "fmt" 21 "time" 22 23 v2 "code.vegaprotocol.io/vega/protos/data-node/api/v2" 24 "code.vegaprotocol.io/vega/protos/vega" 25 26 "github.com/shopspring/decimal" 27 ) 28 29 type PerMarketELSWeight struct { 30 Market string `json:"market"` 31 ELS string `json:"els"` 32 } 33 34 type Vote struct { 35 PartyID PartyID 36 ProposalID ProposalID 37 Value VoteValue 38 TotalGovernanceTokenBalance decimal.Decimal 39 TotalGovernanceTokenWeight decimal.Decimal 40 TotalEquityLikeShareWeight decimal.Decimal 41 PerMarketEquityLikeShareWeight []PerMarketELSWeight 42 InitialTime time.Time // First vote for this party/proposal 43 TxHash TxHash 44 VegaTime time.Time // Time of last vote update 45 } 46 47 func (v Vote) ToProto() *vega.Vote { 48 var perMarketELSWeight []*vega.VoteELSPair 49 50 if ln := len(v.PerMarketEquityLikeShareWeight); ln > 0 { 51 perMarketELSWeight = make([]*vega.VoteELSPair, 0, ln) 52 for _, w := range v.PerMarketEquityLikeShareWeight { 53 perMarketELSWeight = append(perMarketELSWeight, &vega.VoteELSPair{ 54 MarketId: w.Market, 55 Els: w.ELS, 56 }) 57 } 58 } 59 60 return &vega.Vote{ 61 PartyId: v.PartyID.String(), 62 ProposalId: v.ProposalID.String(), 63 Value: vega.Vote_Value(v.Value), 64 TotalGovernanceTokenBalance: v.TotalGovernanceTokenBalance.String(), 65 TotalGovernanceTokenWeight: v.TotalGovernanceTokenWeight.String(), 66 TotalEquityLikeShareWeight: v.TotalEquityLikeShareWeight.String(), 67 Timestamp: v.InitialTime.UnixNano(), 68 ElsPerMarket: perMarketELSWeight, 69 } 70 } 71 72 func VoteFromProto(pv *vega.Vote, txHash TxHash) (Vote, error) { 73 totalGovernanceTokenBalance, err := decimal.NewFromString(pv.TotalGovernanceTokenBalance) 74 if err != nil { 75 return Vote{}, err 76 } 77 78 totalGovernanceTokenWeight, err := decimal.NewFromString(pv.TotalGovernanceTokenWeight) 79 if err != nil { 80 return Vote{}, err 81 } 82 83 totalEquityLikeShareWeight, err := decimal.NewFromString(pv.TotalEquityLikeShareWeight) 84 if err != nil { 85 return Vote{}, err 86 } 87 88 // We need deterministic ordering of the share weights to prevent network history segment hashes from diverting 89 perMarketELSWeight := make([]PerMarketELSWeight, 0) 90 91 for _, pair := range pv.ElsPerMarket { 92 perMarketELSWeight = append(perMarketELSWeight, PerMarketELSWeight{ 93 Market: pair.MarketId, 94 ELS: pair.Els, 95 }) 96 } 97 98 v := Vote{ 99 PartyID: PartyID(pv.PartyId), 100 ProposalID: ProposalID(pv.ProposalId), 101 Value: VoteValue(pv.Value), 102 TotalGovernanceTokenBalance: totalGovernanceTokenBalance, 103 TotalGovernanceTokenWeight: totalGovernanceTokenWeight, 104 TotalEquityLikeShareWeight: totalEquityLikeShareWeight, 105 InitialTime: NanosToPostgresTimestamp(pv.Timestamp), 106 PerMarketEquityLikeShareWeight: perMarketELSWeight, 107 TxHash: txHash, 108 } 109 110 return v, nil 111 } 112 113 func (v Vote) ToProtoEdge(_ ...any) (*v2.VoteEdge, error) { 114 return &v2.VoteEdge{ 115 Node: v.ToProto(), 116 Cursor: v.Cursor().Encode(), 117 }, nil 118 } 119 120 func (v Vote) Cursor() *Cursor { 121 pc := VoteCursor{ 122 PartyID: v.PartyID, 123 VegaTime: v.VegaTime, 124 } 125 126 return NewCursor(pc.String()) 127 } 128 129 type VoteCursor struct { 130 PartyID PartyID `json:"party_id"` 131 VegaTime time.Time `json:"vega_time"` 132 } 133 134 func (vc VoteCursor) String() string { 135 bs, err := json.Marshal(vc) 136 if err != nil { 137 // This should never happen. 138 panic(fmt.Errorf("could not marshal order cursor: %w", err)) 139 } 140 return string(bs) 141 } 142 143 func (vc *VoteCursor) Parse(cursorString string) error { 144 if cursorString == "" { 145 return nil 146 } 147 return json.Unmarshal([]byte(cursorString), vc) 148 }