code.vegaprotocol.io/vega@v0.79.0/datanode/sqlstore/teams_helper_for_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 "fmt" 21 "strings" 22 "testing" 23 "time" 24 25 "code.vegaprotocol.io/vega/datanode/entities" 26 "code.vegaprotocol.io/vega/datanode/sqlstore" 27 28 "github.com/stretchr/testify/require" 29 "golang.org/x/exp/maps" 30 "golang.org/x/exp/slices" 31 ) 32 33 func setupTeamsTest(t *testing.T) (*sqlstore.Blocks, *sqlstore.Teams, *sqlstore.Parties) { 34 t.Helper() 35 36 bs := sqlstore.NewBlocks(connectionSource) 37 ts := sqlstore.NewTeams(connectionSource) 38 ps := sqlstore.NewParties(connectionSource) 39 40 return bs, ts, ps 41 } 42 43 func setupTeams(t *testing.T, ctx context.Context, bs *sqlstore.Blocks, ps *sqlstore.Parties, ts *sqlstore.Teams) ([]entities.Team, []entities.TeamMember) { 44 t.Helper() 45 46 teams := make([]entities.Team, 0, 10) 47 teamsHistory := []entities.TeamMember{} 48 49 for i := 0; i < 10; i++ { 50 block := addTestBlock(t, ctx, bs) 51 referrer := addTestParty(t, ctx, ps, block) 52 team := entities.Team{ 53 ID: entities.TeamID(GenerateID()), 54 Referrer: referrer.ID, 55 Name: fmt.Sprintf("Test Team %02d", i+1), 56 TotalMembers: 1, // The referrer. 57 CreatedAt: block.VegaTime, 58 CreatedAtEpoch: 1, 59 VegaTime: block.VegaTime, 60 } 61 err := ts.AddTeam(ctx, &team) 62 require.NoError(t, err) 63 teams = append(teams, team) 64 teamsHistory = append(teamsHistory, entities.TeamMember{ 65 TeamID: team.ID, 66 PartyID: referrer.ID, 67 JoinedAtEpoch: 1, 68 JoinedAt: block.VegaTime, 69 VegaTime: block.VegaTime, 70 }) 71 72 time.Sleep(10 * time.Millisecond) 73 } 74 75 for iTeam, team := range teams { 76 block := addTestBlock(t, ctx, bs) 77 for i := 0; i < 10; i++ { 78 referee := addTestParty(t, ctx, ps, block) 79 teamReferee := entities.TeamMember{ 80 TeamID: team.ID, 81 PartyID: referee.ID, 82 JoinedAt: block.VegaTime, 83 JoinedAtEpoch: 2, 84 VegaTime: block.VegaTime, 85 } 86 err := ts.RefereeJoinedTeam(ctx, &teamReferee) 87 require.NoError(t, err) 88 teamsHistory = append(teamsHistory, teamReferee) 89 90 team.TotalMembers += 1 91 teams[iTeam] = team 92 } 93 time.Sleep(10 * time.Millisecond) 94 } 95 96 switchingReferee := teamsHistory[len(teams)].PartyID 97 98 for i, toTeam := range teams { 99 if i == 0 { 100 continue 101 } 102 103 fromTeam := teams[i-1] 104 105 block := addTestBlock(t, ctx, bs) 106 switchTeam := entities.RefereeTeamSwitch{ 107 FromTeamID: fromTeam.ID, 108 ToTeamID: toTeam.ID, 109 PartyID: switchingReferee, 110 SwitchedAtEpoch: uint64(3 + i), 111 SwitchedAt: block.VegaTime, 112 VegaTime: block.VegaTime, 113 } 114 115 require.NoError(t, ts.RefereeSwitchedTeam(ctx, &switchTeam)) 116 117 teamsHistory = append(teamsHistory, entities.TeamMember{ 118 TeamID: toTeam.ID, 119 PartyID: switchingReferee, 120 JoinedAtEpoch: uint64(3 + i), 121 JoinedAt: block.VegaTime, 122 VegaTime: block.VegaTime, 123 }) 124 125 fromTeam.TotalMembers -= 1 126 teams[i-1] = fromTeam 127 128 toTeam.TotalMembers += 1 129 teams[i] = toTeam 130 131 time.Sleep(10 * time.Millisecond) 132 } 133 134 block := addTestBlock(t, ctx, bs) 135 for i, team := range teams { 136 if i%2 != 0 { 137 continue 138 } 139 140 teamDup := team 141 teamDup.Closed = true 142 teamDup.AllowList = []string{GenerateID(), GenerateID()} 143 teams[i] = teamDup 144 145 require.NoError(t, ts.UpdateTeam(ctx, &entities.TeamUpdated{ 146 ID: teamDup.ID, 147 Name: teamDup.Name, 148 Closed: teamDup.Closed, 149 AllowList: teamDup.AllowList, 150 VegaTime: block.VegaTime, 151 })) 152 } 153 154 return teams, teamsHistory 155 } 156 157 func historyForReferee(teamsHistory []entities.TeamMember, party entities.PartyID) []entities.TeamMemberHistory { 158 var refereeHistory []entities.TeamMemberHistory 159 160 for _, referee := range teamsHistory { 161 if referee.PartyID == party { 162 refereeHistory = append(refereeHistory, entities.TeamMemberHistory{ 163 TeamID: referee.TeamID, 164 JoinedAt: referee.JoinedAt, 165 JoinedAtEpoch: referee.JoinedAtEpoch, 166 }) 167 } 168 } 169 slices.SortStableFunc(refereeHistory, func(a, b entities.TeamMemberHistory) int { 170 return compareUint64(a.JoinedAtEpoch, b.JoinedAtEpoch) 171 }) 172 173 return refereeHistory 174 } 175 176 func currentRefereesForTeam(teamsHistory []entities.TeamMember, teamID entities.TeamID) []entities.TeamMember { 177 currentReferees := currentReferees(teamsHistory) 178 179 currentTeamReferees := []entities.TeamMember{} 180 for _, referee := range currentReferees { 181 if referee.TeamID == teamID { 182 currentTeamReferees = append(currentTeamReferees, referee) 183 } 184 } 185 186 slices.SortStableFunc(currentTeamReferees, func(a, b entities.TeamMember) int { 187 return strings.Compare(string(a.PartyID), string(b.PartyID)) 188 }) 189 190 return currentTeamReferees 191 } 192 193 func currentReferees(teamsHistory []entities.TeamMember) []entities.TeamMember { 194 currentReferees := map[entities.PartyID]entities.TeamMember{} 195 196 for _, teamMember := range teamsHistory { 197 // teamMember.JoinedAtEpoch != 1 is a ugly hack to exclude the referrer. 198 if teamMember.JoinedAtEpoch == 1 { 199 continue 200 } 201 202 previousMembership, ok := currentReferees[teamMember.PartyID] 203 if ok { 204 if previousMembership.JoinedAtEpoch < teamMember.JoinedAtEpoch { 205 currentReferees[teamMember.PartyID] = teamMember 206 } 207 } else { 208 currentReferees[teamMember.PartyID] = teamMember 209 } 210 } 211 212 return maps.Values(currentReferees) 213 }