Skip to content

Commit

Permalink
Merge pull request #11604 from vegaprotocol/feature/referral-set-impr…
Browse files Browse the repository at this point in the history
…ovements

feat: add ability to not create a referral set with CreateReferralSet and not join a team with ApplyReferralCode
  • Loading branch information
jeremyletang authored Aug 23, 2024
2 parents 635a7de + f868db0 commit 7156f91
Show file tree
Hide file tree
Showing 6 changed files with 240 additions and 162 deletions.
14 changes: 13 additions & 1 deletion commands/create_referral_set.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,11 @@

package commands

import commandspb "code.vegaprotocol.io/vega/protos/vega/commands/v1"
import (
"errors"

commandspb "code.vegaprotocol.io/vega/protos/vega/commands/v1"
)

func CheckCreateReferralSet(cmd *commandspb.CreateReferralSet) error {
return checkCreateReferralSet(cmd).ErrorOrNil()
Expand All @@ -28,6 +32,14 @@ func checkCreateReferralSet(cmd *commandspb.CreateReferralSet) Errors {
return errs.FinalAddForProperty("create_referral_set", ErrIsRequired)
}

// Basically this command should be rejected if we are not creating a team
// but also not creating a referral set...
// just check if this command is ineffective...
if cmd.DoNotCreateReferralSet && !cmd.IsTeam {
return errs.FinalAddForProperty("create_referral_set",
errors.New("is ineffective"))
}

if cmd.IsTeam {
if cmd.Team == nil {
return errs.FinalAddForProperty("create_referral_set.team", ErrIsRequired)
Expand Down
63 changes: 35 additions & 28 deletions core/processor/abci.go
Original file line number Diff line number Diff line change
Expand Up @@ -3024,23 +3024,6 @@ func (app *App) getMaxGas() uint64 {
return app.gastimator.maxGas
}

func (app *App) CreateReferralSet(ctx context.Context, tx abci.Tx, deterministicID string) error {
params := &commandspb.CreateReferralSet{}
if err := tx.Unmarshal(params); err != nil {
return fmt.Errorf("could not deserialize CreateReferralSet command: %w", err)
}

if err := app.referralProgram.CreateReferralSet(ctx, types.PartyID(tx.Party()), types.ReferralSetID(deterministicID)); err != nil {
return err
}

if params.IsTeam {
return app.teamsEngine.CreateTeam(ctx, types.PartyID(tx.Party()), types.TeamID(deterministicID), params.Team)
}

return nil
}

func (app *App) UpdateMarginMode(ctx context.Context, tx abci.Tx) error {
var err error
params := &commandspb.UpdateMarginMode{}
Expand Down Expand Up @@ -3087,6 +3070,25 @@ func (app *App) DeliverCancelAMM(ctx context.Context, tx abci.Tx, deterministicI
return app.exec.CancelAMM(ctx, cancel, deterministicID)
}

func (app *App) CreateReferralSet(ctx context.Context, tx abci.Tx, deterministicID string) error {
params := &commandspb.CreateReferralSet{}
if err := tx.Unmarshal(params); err != nil {
return fmt.Errorf("could not deserialize CreateReferralSet command: %w", err)
}

if !params.DoNotCreateReferralSet {
if err := app.referralProgram.CreateReferralSet(ctx, types.PartyID(tx.Party()), types.ReferralSetID(deterministicID)); err != nil {
return err
}
}

if params.IsTeam {
return app.teamsEngine.CreateTeam(ctx, types.PartyID(tx.Party()), types.TeamID(deterministicID), params.Team)
}

return nil
}

// UpdateReferralSet this is effectively Update team, but also served to create
// a team for an existing referral set...
func (app *App) UpdateReferralSet(ctx context.Context, tx abci.Tx) error {
Expand All @@ -3095,10 +3097,13 @@ func (app *App) UpdateReferralSet(ctx context.Context, tx abci.Tx) error {
return fmt.Errorf("could not deserialize UpdateReferralSet command: %w", err)
}

if err := app.referralProgram.PartyOwnsReferralSet(types.PartyID(tx.Party()), types.ReferralSetID(params.Id)); err != nil {
return fmt.Errorf("cannot update referral set: %w", err)
}
// Is this relevant at all now? With anyone able to create a team, this verification should not matter.
//
// if err := app.referralProgram.PartyOwnsReferralSet(types.PartyID(tx.Party()), types.ReferralSetID(params.Id)); err != nil {
// return fmt.Errorf("cannot update referral set: %w", err)
// }

// ultimately this has just become a createOrUpdateTeam.
if params.IsTeam {
teamID := types.TeamID(params.Id)
if app.teamsEngine.TeamExists(teamID) {
Expand Down Expand Up @@ -3128,14 +3133,16 @@ func (app *App) ApplyReferralCode(ctx context.Context, tx abci.Tx) error {
return fmt.Errorf("could not apply the referral code: %w", err)
}

teamID := types.TeamID(params.Id)
joinTeam := &commandspb.JoinTeam{
Id: params.Id,
}
err = app.teamsEngine.JoinTeam(ctx, partyID, joinTeam)
// This is ok as well, as not all referral sets are teams as well.
if err != nil && err.Error() != teams.ErrNoTeamMatchesID(teamID).Error() {
return fmt.Errorf("couldn't join team: %w", err)
if !params.DoNotJoinTeam {
teamID := types.TeamID(params.Id)
joinTeam := &commandspb.JoinTeam{
Id: params.Id,
}
err = app.teamsEngine.JoinTeam(ctx, partyID, joinTeam)
// This is ok as well, as not all referral sets are teams as well.
if err != nil && err.Error() != teams.ErrNoTeamMatchesID(teamID).Error() {
return fmt.Errorf("couldn't join team: %w", err)
}
}

return nil
Expand Down
24 changes: 22 additions & 2 deletions core/teams/engine.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,14 +73,34 @@ func (e *Engine) CreateTeam(ctx context.Context, referrer types.PartyID, determi
return err
}

if _, alreadyMember := e.allTeamMembers[referrer]; alreadyMember {
return ErrPartyAlreadyBelongsToTeam(referrer)
// are we already a team owner? in which case
// it's not allowed to create a team
for _, team := range e.teams {
if team.Referrer.PartyID == referrer {
return ErrPartyAlreadyBelongsToTeam(referrer)
}
}

if len(params.Name) <= 0 {
return errors.New("missing required team name parameter")
}

// if the party is a member of a team but not a referrer
// then we need to move it from the previous one, and get
// and create it.
prevTeamID, isAlreadyMember := e.allTeamMembers[referrer]

// here just removing them from the team would be enough
// to have the correct step
//
// the notify create team event later will in the DN:
// - create the new team
// - update the membership informations for the party
// - all is fine
if isAlreadyMember {
e.teams[prevTeamID].RemoveReferee(referrer)
}

now := e.timeService.GetTimeNow()

teamToAdd := &types.Team{
Expand Down
10 changes: 8 additions & 2 deletions datanode/sqlstore/teams.go
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,13 @@ func (t *Teams) AddTeam(ctx context.Context, team *entities.Team) error {
return err
}

// in case the party already was in a team?
_, _ = t.Exec(
ctx,
"DELETE FROM team_members WHERE party_id = $1",
team.Referrer,
)

if _, err := t.Exec(
ctx,
"INSERT INTO team_members(team_id, party_id, joined_at_epoch, joined_at, vega_time) VALUES ($1, $2, $3, $4, $5)",
Expand Down Expand Up @@ -247,7 +254,7 @@ func (t *Teams) RefereeJoinedTeam(ctx context.Context, referee *entities.TeamMem
}

func (t *Teams) RefereeSwitchedTeam(ctx context.Context, referee *entities.RefereeTeamSwitch) error {
defer metrics.StartSQLQuery("Teams", "RefereeJoinedTeam")()
defer metrics.StartSQLQuery("Teams", "RefereeSwitchedTeam")()

_, err := t.Exec(ctx,
`INSERT INTO team_members(team_id, party_id, joined_at, joined_at_epoch, vega_time) VALUES ($1, $2, $3, $4, $5)`,
Expand Down Expand Up @@ -353,7 +360,6 @@ func (t *Teams) ListTeams(ctx context.Context, pagination entities.CursorPaginat
SELECT teams.*, members_stats.total_members
FROM teams
LEFT JOIN members_stats on teams.id = members_stats.team_id`

query, args, err := PaginateQuery[entities.TeamCursor](query, args, teamsOrdering, pagination)
if err != nil {
return nil, pageInfo, err
Expand Down
6 changes: 6 additions & 0 deletions protos/sources/vega/commands/v1/commands.proto
Original file line number Diff line number Diff line change
Expand Up @@ -366,6 +366,9 @@ message CreateReferralSet {
bool is_team = 1;
// Team details, if the referral set is to be considered a team.
optional Team team = 2;
// Should a referral set be created as well or only a team.
// the default is false so the existing behaviour is kept if older versions of the protobufs are used.
bool do_not_create_referral_set = 3;

message Team {
// Name of the team.
Expand Down Expand Up @@ -416,6 +419,9 @@ message UpdateReferralSet {
message ApplyReferralCode {
// Referral code, normally the referral set ID, for the party to join.
string id = 1;
// Should the key applying the referral code also join the team.
// the default is false so the existing behaviour is kept if older versions of the protobufs are used.
bool do_not_join_team = 2;
}

// Command that allows the submitter to join a team or change teams if they are already a member of a team.
Expand Down
Loading

0 comments on commit 7156f91

Please sign in to comment.