code.vegaprotocol.io/vega@v0.79.0/datanode/sqlstore/game_scores_test.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 sqlstore_test 17 18 import ( 19 "context" 20 "sort" 21 "testing" 22 "time" 23 24 "code.vegaprotocol.io/vega/datanode/entities" 25 "code.vegaprotocol.io/vega/datanode/sqlstore" 26 "code.vegaprotocol.io/vega/libs/num" 27 28 "github.com/stretchr/testify/assert" 29 "github.com/stretchr/testify/require" 30 ) 31 32 type gameScoresTestStore struct { 33 gs *sqlstore.GameScores 34 } 35 36 func newGameScoresTestStore(t *testing.T) *gameScoresTestStore { 37 t.Helper() 38 return &gameScoresTestStore{ 39 gs: sqlstore.NewGameScores(connectionSource), 40 } 41 } 42 43 func TestInsertPartyScores(t *testing.T) { 44 ctx := tempTransaction(t) 45 store := newGameScoresTestStore(t) 46 now := time.Now() 47 gps := entities.GamePartyScore{ 48 GameID: "FFFF", 49 EpochID: 1, 50 PartyID: "EEEE", 51 Score: num.DecimalOne(), 52 StakingBalance: num.DecimalTwo(), 53 OpenVolume: num.DecimalZero(), 54 TotalFeesPaid: num.DecimalFromInt64(4), 55 IsEligible: true, 56 VegaTime: now, 57 } 58 59 t.Run("can insert successfully", func(t *testing.T) { 60 assert.NoError(t, store.gs.AddPartyScore(ctx, gps)) 61 }) 62 63 team := entities.TeamID("AAAA") 64 gps.GameID = "BBBB" 65 gps.TeamID = &team 66 t.Run("can insert successfully with team", func(t *testing.T) { 67 assert.NoError(t, store.gs.AddPartyScore(ctx, gps)) 68 }) 69 70 rank := uint64(2) 71 gps.PartyID = "BBBB" 72 gps.Rank = &rank 73 t.Run("can insert successfully with rank", func(t *testing.T) { 74 assert.NoError(t, store.gs.AddPartyScore(ctx, gps)) 75 }) 76 } 77 78 func TestInsertTeamScores(t *testing.T) { 79 ctx := tempTransaction(t) 80 store := newGameScoresTestStore(t) 81 now := time.Now() 82 gts := entities.GameTeamScore{ 83 GameID: "FFFF", 84 EpochID: 1, 85 TeamID: "EEEE", 86 Score: num.DecimalOne(), 87 VegaTime: now, 88 } 89 90 t.Run("can insert successfully", func(t *testing.T) { 91 require.NoError(t, store.gs.AddTeamScore(ctx, gts)) 92 }) 93 } 94 95 func prepopoulatePartyScores(t *testing.T, ctx context.Context, gs *gameScoresTestStore, now time.Time) []entities.GamePartyScore { 96 t.Helper() 97 team1 := entities.TeamID("AAAA") 98 team2 := entities.TeamID("BBBB") 99 team3 := entities.TeamID("CCCC") 100 gps := []entities.GamePartyScore{ 101 { 102 GameID: "EEEE", 103 EpochID: 1, 104 PartyID: "FFFE", 105 TeamID: &team3, 106 Score: num.DecimalFromFloat(0.1), 107 StakingBalance: num.DecimalFromInt64(1), 108 OpenVolume: num.DecimalFromInt64(2), 109 TotalFeesPaid: num.DecimalFromInt64(3), 110 IsEligible: true, 111 VegaTime: now, 112 }, 113 { 114 GameID: "FFFF", 115 EpochID: 1, 116 PartyID: "FFFE", 117 TeamID: &team1, 118 Score: num.DecimalFromFloat(0.1), 119 StakingBalance: num.DecimalFromInt64(1), 120 OpenVolume: num.DecimalFromInt64(2), 121 TotalFeesPaid: num.DecimalFromInt64(3), 122 IsEligible: true, 123 VegaTime: now, 124 }, 125 { 126 GameID: "EEFF", 127 EpochID: 1, 128 PartyID: "FFFD", 129 TeamID: &team2, 130 Score: num.DecimalFromFloat(0.2), 131 StakingBalance: num.DecimalFromInt64(11), 132 OpenVolume: num.DecimalFromInt64(22), 133 TotalFeesPaid: num.DecimalFromInt64(33), 134 IsEligible: true, 135 VegaTime: now, 136 }, 137 { 138 GameID: "FFFF", 139 EpochID: 1, 140 PartyID: "FFFD", 141 Score: num.DecimalFromFloat(0.2), 142 StakingBalance: num.DecimalFromInt64(111), 143 OpenVolume: num.DecimalFromInt64(222), 144 TotalFeesPaid: num.DecimalFromInt64(333), 145 IsEligible: true, 146 VegaTime: now, 147 }, 148 { 149 GameID: "FFFF", 150 EpochID: 1, 151 PartyID: "FFFC", 152 TeamID: &team3, 153 Score: num.DecimalFromFloat(0.3), 154 StakingBalance: num.DecimalFromInt64(1111), 155 OpenVolume: num.DecimalFromInt64(2222), 156 TotalFeesPaid: num.DecimalFromInt64(3333), 157 IsEligible: true, 158 VegaTime: now, 159 }, 160 { 161 GameID: "FFFF", 162 EpochID: 1, 163 PartyID: "FFFB", 164 TeamID: &team3, 165 Score: num.DecimalFromFloat(0.4), 166 StakingBalance: num.DecimalFromInt64(11111), 167 OpenVolume: num.DecimalFromInt64(22222), 168 TotalFeesPaid: num.DecimalFromInt64(33333), 169 IsEligible: true, 170 VegaTime: now, 171 }, 172 { 173 GameID: "FFFF", 174 EpochID: 1, 175 PartyID: "FFFA", 176 Score: num.DecimalFromFloat(0.5), 177 StakingBalance: num.DecimalTwo(), 178 OpenVolume: num.DecimalZero(), 179 TotalFeesPaid: num.DecimalFromInt64(4), 180 IsEligible: true, 181 VegaTime: now, 182 }, 183 { 184 GameID: "FFFF", 185 EpochID: 2, 186 PartyID: "FFFA", 187 Score: num.DecimalFromFloat(0.8), 188 StakingBalance: num.DecimalFromInt64(6), 189 OpenVolume: num.DecimalFromInt64(3), 190 TotalFeesPaid: num.DecimalFromInt64(1), 191 IsEligible: true, 192 VegaTime: now.Add(1 * time.Second), 193 }, 194 { 195 GameID: "FFFF", 196 EpochID: 2, 197 PartyID: "FFFA", 198 Score: num.DecimalFromFloat(0.7), 199 StakingBalance: num.DecimalFromInt64(9), 200 OpenVolume: num.DecimalFromInt64(8), 201 TotalFeesPaid: num.DecimalFromInt64(7), 202 IsEligible: true, 203 VegaTime: now.Add(2 * time.Second), 204 }, 205 } 206 for _, gps1 := range gps { 207 require.NoError(t, gs.gs.AddPartyScore(ctx, gps1)) 208 } 209 sort.Slice(gps, func(i, j int) bool { 210 if gps[i].GameID == gps[j].GameID { 211 return gps[i].PartyID > gps[j].PartyID 212 } 213 return gps[i].GameID > gps[j].GameID 214 }) 215 216 return gps 217 } 218 219 func TestListPartyScoresNoFilters(t *testing.T) { 220 ctx := tempTransaction(t) 221 store := newGameScoresTestStore(t) 222 now := time.Now() 223 pagination, _ := entities.NewCursorPagination(nil, nil, nil, nil, true) 224 partyScores := prepopoulatePartyScores(t, ctx, store, now) 225 scores, _, err := store.gs.ListPartyScores(ctx, nil, nil, nil, nil, nil, pagination) 226 require.NoError(t, err) 227 // as we're not filtering by epochs we're getting the current scores so that's equal to all the ones from epoch 1 (which are all distinct) 228 require.Equal(t, len(partyScores)-2, len(scores)) 229 230 // now insert a fresh score for an existing party for the same game 231 now = now.Add(time.Hour) 232 partyScores[0].VegaTime = now 233 partyScores[0].Score = num.DecimalE() 234 require.NoError(t, store.gs.AddPartyScore(ctx, partyScores[0])) 235 require.Equal(t, len(partyScores)-2, len(scores)) 236 } 237 238 func TestListPartyScoresPartyFilters(t *testing.T) { 239 ctx := tempTransaction(t) 240 store := newGameScoresTestStore(t) 241 now := time.Now() 242 pagination, _ := entities.NewCursorPagination(nil, nil, nil, nil, true) 243 prepopoulatePartyScores(t, ctx, store, now) 244 scores, _, err := store.gs.ListPartyScores(ctx, nil, []entities.PartyID{"FFFD"}, nil, nil, nil, pagination) 245 require.NoError(t, err) 246 require.Equal(t, 2, len(scores)) 247 248 scores, _, err = store.gs.ListPartyScores(ctx, nil, []entities.PartyID{"FFFD", "FFFE"}, nil, nil, nil, pagination) 249 require.NoError(t, err) 250 require.Equal(t, 4, len(scores)) 251 } 252 253 func TestListPartyScoresGameFilters(t *testing.T) { 254 ctx := tempTransaction(t) 255 store := newGameScoresTestStore(t) 256 now := time.Now() 257 pagination, _ := entities.NewCursorPagination(nil, nil, nil, nil, true) 258 ps := prepopoulatePartyScores(t, ctx, store, now) 259 scores, _, err := store.gs.ListPartyScores(ctx, []entities.GameID{"EEFF"}, nil, nil, nil, nil, pagination) 260 require.NoError(t, err) 261 require.Equal(t, 1, len(scores)) 262 263 scores, _, err = store.gs.ListPartyScores(ctx, []entities.GameID{"FFFF", "EEEE"}, nil, nil, nil, nil, pagination) 264 require.NoError(t, err) 265 require.Equal(t, len(ps)-3, len(scores)) 266 } 267 268 func TestListPartyScoresTeamFilters(t *testing.T) { 269 ctx := tempTransaction(t) 270 store := newGameScoresTestStore(t) 271 now := time.Now() 272 pagination, _ := entities.NewCursorPagination(nil, nil, nil, nil, true) 273 prepopoulatePartyScores(t, ctx, store, now) 274 scores, _, err := store.gs.ListPartyScores(ctx, nil, nil, []entities.TeamID{"AAAA"}, nil, nil, pagination) 275 require.NoError(t, err) 276 require.Equal(t, 1, len(scores)) 277 scores, _, err = store.gs.ListPartyScores(ctx, nil, nil, []entities.TeamID{"AAAA", "BBBB"}, nil, nil, pagination) 278 require.NoError(t, err) 279 require.Equal(t, 2, len(scores)) 280 } 281 282 func TestListPartyScoresAllFilters(t *testing.T) { 283 ctx := tempTransaction(t) 284 store := newGameScoresTestStore(t) 285 now := time.Now() 286 pagination, _ := entities.NewCursorPagination(nil, nil, nil, nil, true) 287 prepopoulatePartyScores(t, ctx, store, now) 288 289 // all filters populated 290 scores, _, err := store.gs.ListPartyScores(ctx, []entities.GameID{"FFFF"}, []entities.PartyID{"FFFB"}, []entities.TeamID{"CCCC"}, nil, nil, pagination) 291 require.NoError(t, err) 292 require.Equal(t, 1, len(scores)) 293 require.Equal(t, num.DecimalFromFloat(0.4), scores[0].Score) 294 require.Equal(t, num.DecimalFromInt64(11111), scores[0].StakingBalance) 295 require.Equal(t, num.DecimalFromInt64(22222), scores[0].OpenVolume) 296 require.Equal(t, num.DecimalFromInt64(33333), scores[0].TotalFeesPaid) 297 } 298 299 func TestListPartyScoresEpochFilter(t *testing.T) { 300 ctx := tempTransaction(t) 301 store := newGameScoresTestStore(t) 302 now := time.Now() 303 pagination, _ := entities.NewCursorPagination(nil, nil, nil, nil, true) 304 prepopoulatePartyScores(t, ctx, store, now) 305 306 // all filters populated 307 from := uint64(1) 308 to := uint64(2) 309 // provide to and from 310 scores, _, err := store.gs.ListPartyScores(ctx, []entities.GameID{"FFFF"}, []entities.PartyID{"FFFA"}, nil, &from, &to, pagination) 311 require.NoError(t, err) 312 require.Equal(t, 2, len(scores)) 313 require.Equal(t, num.DecimalFromFloat(0.5), scores[0].Score) 314 require.Equal(t, num.DecimalFromInt64(2), scores[0].StakingBalance) 315 require.Equal(t, num.DecimalFromInt64(0), scores[0].OpenVolume) 316 require.Equal(t, num.DecimalFromInt64(4), scores[0].TotalFeesPaid) 317 require.Equal(t, num.DecimalFromFloat(0.7), scores[1].Score) 318 require.Equal(t, num.DecimalFromInt64(9), scores[1].StakingBalance) 319 require.Equal(t, num.DecimalFromInt64(8), scores[1].OpenVolume) 320 require.Equal(t, num.DecimalFromInt64(7), scores[1].TotalFeesPaid) 321 322 // do not provide from, expect the same result as we should get basically all epochs 323 scores, _, err = store.gs.ListPartyScores(ctx, []entities.GameID{"FFFF"}, []entities.PartyID{"FFFA"}, nil, nil, &to, pagination) 324 require.NoError(t, err) 325 require.Equal(t, 2, len(scores)) 326 require.Equal(t, num.DecimalFromFloat(0.5), scores[0].Score) 327 require.Equal(t, num.DecimalFromInt64(2), scores[0].StakingBalance) 328 require.Equal(t, num.DecimalFromInt64(0), scores[0].OpenVolume) 329 require.Equal(t, num.DecimalFromInt64(4), scores[0].TotalFeesPaid) 330 require.Equal(t, num.DecimalFromFloat(0.7), scores[1].Score) 331 require.Equal(t, num.DecimalFromInt64(9), scores[1].StakingBalance) 332 require.Equal(t, num.DecimalFromInt64(8), scores[1].OpenVolume) 333 require.Equal(t, num.DecimalFromInt64(7), scores[1].TotalFeesPaid) 334 335 // do not provide to, expect the same result as we should get basically all epochs 336 scores, _, err = store.gs.ListPartyScores(ctx, []entities.GameID{"FFFF"}, []entities.PartyID{"FFFA"}, nil, &from, nil, pagination) 337 require.NoError(t, err) 338 require.Equal(t, 2, len(scores)) 339 require.Equal(t, num.DecimalFromFloat(0.5), scores[0].Score) 340 require.Equal(t, num.DecimalFromInt64(2), scores[0].StakingBalance) 341 require.Equal(t, num.DecimalFromInt64(0), scores[0].OpenVolume) 342 require.Equal(t, num.DecimalFromInt64(4), scores[0].TotalFeesPaid) 343 require.Equal(t, num.DecimalFromFloat(0.7), scores[1].Score) 344 require.Equal(t, num.DecimalFromInt64(9), scores[1].StakingBalance) 345 require.Equal(t, num.DecimalFromInt64(8), scores[1].OpenVolume) 346 require.Equal(t, num.DecimalFromInt64(7), scores[1].TotalFeesPaid) 347 348 // set from to the second (and last) epoch 349 from = 2 350 scores, _, err = store.gs.ListPartyScores(ctx, []entities.GameID{"FFFF"}, []entities.PartyID{"FFFA"}, nil, &from, nil, pagination) 351 require.NoError(t, err) 352 require.Equal(t, 1, len(scores)) 353 require.Equal(t, num.DecimalFromFloat(0.7), scores[0].Score) 354 require.Equal(t, num.DecimalFromInt64(9), scores[0].StakingBalance) 355 require.Equal(t, num.DecimalFromInt64(8), scores[0].OpenVolume) 356 require.Equal(t, num.DecimalFromInt64(7), scores[0].TotalFeesPaid) 357 358 // set to to 1 so we get only the first epoch 359 to = 1 360 scores, _, err = store.gs.ListPartyScores(ctx, []entities.GameID{"FFFF"}, []entities.PartyID{"FFFA"}, nil, nil, &to, pagination) 361 require.NoError(t, err) 362 require.Equal(t, 1, len(scores)) 363 require.Equal(t, num.DecimalFromFloat(0.5), scores[0].Score) 364 require.Equal(t, num.DecimalFromInt64(2), scores[0].StakingBalance) 365 require.Equal(t, num.DecimalFromInt64(0), scores[0].OpenVolume) 366 require.Equal(t, num.DecimalFromInt64(4), scores[0].TotalFeesPaid) 367 368 // now set both to and from to 1 369 to = 1 370 from = 1 371 scores, _, err = store.gs.ListPartyScores(ctx, []entities.GameID{"FFFF"}, []entities.PartyID{"FFFA"}, nil, &from, &to, pagination) 372 require.NoError(t, err) 373 require.Equal(t, 1, len(scores)) 374 require.Equal(t, num.DecimalFromFloat(0.5), scores[0].Score) 375 require.Equal(t, num.DecimalFromInt64(2), scores[0].StakingBalance) 376 require.Equal(t, num.DecimalFromInt64(0), scores[0].OpenVolume) 377 require.Equal(t, num.DecimalFromInt64(4), scores[0].TotalFeesPaid) 378 379 // and to 2 380 to = 2 381 from = 2 382 scores, _, err = store.gs.ListPartyScores(ctx, []entities.GameID{"FFFF"}, []entities.PartyID{"FFFA"}, nil, &from, &to, pagination) 383 require.NoError(t, err) 384 require.Equal(t, num.DecimalFromFloat(0.7), scores[0].Score) 385 require.Equal(t, num.DecimalFromInt64(9), scores[0].StakingBalance) 386 require.Equal(t, num.DecimalFromInt64(8), scores[0].OpenVolume) 387 require.Equal(t, num.DecimalFromInt64(7), scores[0].TotalFeesPaid) 388 }