code.vegaprotocol.io/vega@v0.79.0/datanode/entities/game.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 22 "code.vegaprotocol.io/vega/libs/num" 23 v2 "code.vegaprotocol.io/vega/protos/data-node/api/v2" 24 "code.vegaprotocol.io/vega/protos/vega" 25 ) 26 27 type _Game struct{} 28 29 type GameID = ID[_Game] 30 31 type Game struct { 32 ID GameID 33 Epoch uint64 34 Participants uint64 35 Entities []GameEntity 36 RewardAssetID AssetID 37 } 38 39 func (g Game) Cursor() *Cursor { 40 gc := GameCursor{ 41 EpochID: g.Epoch, 42 GameID: g.ID, 43 } 44 return NewCursor(gc.String()) 45 } 46 47 func (g Game) ToProtoEdge(_ ...any) (*v2.GameEdge, error) { 48 return &v2.GameEdge{ 49 Node: g.ToProto(), 50 Cursor: g.Cursor().Encode(), 51 }, nil 52 } 53 54 type GameCursor struct { 55 EpochID uint64 56 GameID GameID 57 } 58 59 func (gc GameCursor) String() string { 60 bs, err := json.Marshal(gc) 61 if err != nil { 62 panic(fmt.Errorf("could not marshal game cursor %v", err)) 63 } 64 return string(bs) 65 } 66 67 func (gc *GameCursor) Parse(cursorString string) error { 68 if cursorString == "" { 69 return nil 70 } 71 return json.Unmarshal([]byte(cursorString), gc) 72 } 73 74 type GameEntity interface { 75 IsGameEntity() 76 } 77 78 type TeamGameParticipation struct { 79 TeamID TeamID 80 MembersParticipating []*IndividualGameEntity 81 } 82 83 func (t TeamGameParticipation) ToProto() *v2.TeamGameParticipation { 84 members := make([]*v2.IndividualGameEntity, len(t.MembersParticipating)) 85 for i, member := range t.MembersParticipating { 86 members[i] = member.ToProto() 87 } 88 return &v2.TeamGameParticipation{ 89 TeamId: t.TeamID.String(), 90 MembersParticipating: members, 91 } 92 } 93 94 type TeamGameEntity struct { 95 Team TeamGameParticipation 96 Rank uint64 97 Volume num.Decimal 98 RewardMetric vega.DispatchMetric 99 RewardEarned *num.Uint 100 RewardEarnedQuantum *num.Uint 101 TotalRewardsEarned *num.Uint 102 TotalRewardsEarnedQuantum *num.Uint 103 } 104 105 func (*TeamGameEntity) IsGameEntity() {} 106 func (t *TeamGameEntity) ToProto() *v2.TeamGameEntity { 107 return &v2.TeamGameEntity{ 108 Team: t.Team.ToProto(), 109 Rank: t.Rank, 110 Volume: t.Volume.String(), 111 RewardMetric: t.RewardMetric, 112 RewardEarned: t.RewardEarned.String(), 113 TotalRewardsEarned: t.TotalRewardsEarned.String(), 114 RewardEarnedQuantum: t.RewardEarnedQuantum.String(), 115 TotalRewardsEarnedQuantum: t.TotalRewardsEarnedQuantum.String(), 116 } 117 } 118 119 type IndividualGameEntity struct { 120 Individual string 121 Rank uint64 122 Volume num.Decimal 123 RewardMetric vega.DispatchMetric 124 RewardEarned *num.Uint 125 RewardEarnedQuantum *num.Uint 126 TotalRewardsEarned *num.Uint 127 TotalRewardsEarnedQuantum *num.Uint 128 } 129 130 func (*IndividualGameEntity) IsGameEntity() {} 131 132 func (i *IndividualGameEntity) ToProto() *v2.IndividualGameEntity { 133 return &v2.IndividualGameEntity{ 134 Individual: i.Individual, 135 Rank: i.Rank, 136 Volume: i.Volume.String(), 137 RewardMetric: i.RewardMetric, 138 RewardEarned: i.RewardEarned.String(), 139 TotalRewardsEarned: i.TotalRewardsEarned.String(), 140 RewardEarnedQuantum: i.RewardEarnedQuantum.String(), 141 TotalRewardsEarnedQuantum: i.TotalRewardsEarnedQuantum.String(), 142 } 143 } 144 145 func (g Game) ToProto() *v2.Game { 146 gg := &v2.Game{ 147 Id: g.ID.String(), 148 RewardAssetId: g.RewardAssetID.String(), 149 Epoch: g.Epoch, 150 Participants: g.Participants, 151 Entities: nil, 152 } 153 teamEntities := make([]*v2.TeamGameEntity, 0) 154 individualEntities := make([]*v2.IndividualGameEntity, 0) 155 for _, e := range g.Entities { 156 switch entity := e.(type) { 157 case *TeamGameEntity: 158 teamEntities = append(teamEntities, entity.ToProto()) 159 case *IndividualGameEntity: 160 individualEntities = append(individualEntities, entity.ToProto()) 161 } 162 } 163 if len(teamEntities) > 0 { 164 gg.Entities = &v2.Game_Team{ 165 Team: &v2.TeamGameEntities{ 166 Team: teamEntities, 167 }, 168 } 169 return gg 170 } 171 gg.Entities = &v2.Game_Individual{ 172 Individual: &v2.IndividualGameEntities{ 173 Individual: individualEntities, 174 }, 175 } 176 return gg 177 }