Skip to content

Commit

Permalink
Merge pull request #30 from rarimo/fix/balances
Browse files Browse the repository at this point in the history
Now init level for balance it is 0. Fix bug with adding fulfilled eve…
  • Loading branch information
Zaptoss authored Jun 19, 2024
2 parents a811cbc + 4d9dcc8 commit 9a4103b
Show file tree
Hide file tree
Showing 4 changed files with 102 additions and 66 deletions.
31 changes: 20 additions & 11 deletions internal/service/handlers/claim_event.go
Original file line number Diff line number Diff line change
Expand Up @@ -154,17 +154,9 @@ func DoClaimEventUpdates(
balance data.Balance,
reward int64) (err error) {

refsCount, level := levels.LvlUp(balance.Level, reward+balance.Amount)
if refsCount > 0 {
count, err := referralsQ.New().FilterByNullifier(balance.Nullifier).Count()
if err != nil {
return fmt.Errorf("failed to get referral count: %w", err)
}

refToAdd := prepareReferralsToAdd(balance.Nullifier, uint64(refsCount), count)
if err = referralsQ.New().Insert(refToAdd...); err != nil {
return fmt.Errorf("failed to insert referrals: %w", err)
}
level, err := doLvlUpAndReferralsUpdate(levels, referralsQ, balance, reward)
if err != nil {
return fmt.Errorf("failed to do lvlup and referrals updates: %w", err)
}

err = balancesQ.FilterByNullifier(balance.Nullifier).Update(map[string]any{
Expand All @@ -185,6 +177,23 @@ func DoClaimEventUpdates(
return nil
}

func doLvlUpAndReferralsUpdate(levels config.Levels, referralsQ data.ReferralsQ, balance data.Balance, reward int64) (level int, err error) {
refsCount, level := levels.LvlUp(balance.Level, reward+balance.Amount)
if refsCount > 0 {
count, err := referralsQ.New().FilterByNullifier(balance.Nullifier).Count()
if err != nil {
return 0, fmt.Errorf("failed to get referral count: %w", err)
}

refToAdd := prepareReferralsToAdd(balance.Nullifier, uint64(refsCount), count)
if err = referralsQ.New().Insert(refToAdd...); err != nil {
return 0, fmt.Errorf("failed to insert referrals: %w", err)
}
}

return level, nil
}

func newClaimEventResponse(
event data.Event,
meta resources.EventStaticMeta,
Expand Down
75 changes: 46 additions & 29 deletions internal/service/handlers/create_balance.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,8 @@ func CreateBalance(w http.ResponseWriter, r *http.Request) {
return
}

referrals := prepareReferralsToAdd(nullifier, 5, 0)

events := prepareEventsWithRef(nullifier, req.Data.Attributes.ReferredBy, r)
if err = createBalanceWithEventsAndReferrals(nullifier, req.Data.Attributes.ReferredBy, events, referrals, r); err != nil {
if err = createBalanceWithEventsAndReferrals(nullifier, req.Data.Attributes.ReferredBy, events, r); err != nil {
Log(r).WithError(err).Error("Failed to create balance with events")
ape.RenderErr(w, problems.InternalError())
return
Expand All @@ -71,8 +69,14 @@ func CreateBalance(w http.ResponseWriter, r *http.Request) {
return
}

for i := range referrals {
referrals[i].Status = data.StatusActive
referrals, err := ReferralsQ(r).
FilterByNullifier(nullifier).
WithStatus().
Select()
if err != nil {
Log(r).WithError(err).Error("Failed to get referrals by nullifier with rewarding field")
ape.RenderErr(w, problems.InternalError())
return
}

ape.Render(w, newBalanceResponse(*balance, referrals))
Expand Down Expand Up @@ -100,35 +104,41 @@ func prepareEventsWithRef(nullifier, refBy string, r *http.Request) []data.Event
})
}

// createBalanceWithEvents should be called in transaction to avoid database corruption
func createBalanceWithEvents(nullifier, refBy string, events []data.Event, r *http.Request) error {
return EventsQ(r).Transaction(func() error {
err := BalancesQ(r).Insert(data.Balance{
Nullifier: nullifier,
ReferredBy: sql.NullString{String: refBy, Valid: refBy != ""},
Level: Levels(r).MinLvl(),
})
balance := data.Balance{
Nullifier: nullifier,
ReferredBy: sql.NullString{String: refBy, Valid: refBy != ""},
Level: 0,
}

if err != nil {
return fmt.Errorf("add balance: %w", err)
}
err := BalancesQ(r).Insert(balance)
if err != nil {
return fmt.Errorf("add balance: %w", err)
}

Log(r).Debugf("%d events will be added for nullifier=%s", len(events), nullifier)
if err = EventsQ(r).Insert(events...); err != nil {
return fmt.Errorf("add open events: %w", err)
}
Log(r).Debugf("%d events will be added for nullifier=%s", len(events), nullifier)
if err = EventsQ(r).Insert(events...); err != nil {
return fmt.Errorf("add open events: %w", err)
}

return nil
})
Log(r).Debugf("%s referral will be consumed", refBy)
if _, err = ReferralsQ(r).Consume(refBy); err != nil {
return fmt.Errorf("consume referral: %w", err)
}

return nil
}

func createBalanceWithEventsAndReferrals(nullifier, refBy string, events []data.Event, refCodes []data.Referral, r *http.Request) error {
func createBalanceWithEventsAndReferrals(nullifier, refBy string, events []data.Event, r *http.Request) error {
return EventsQ(r).Transaction(func() error {
err := BalancesQ(r).Insert(data.Balance{
balance := data.Balance{
Nullifier: nullifier,
ReferredBy: sql.NullString{String: refBy, Valid: refBy != ""},
Level: Levels(r).MinLvl(),
})
Level: 0,
}

err := BalancesQ(r).Insert(balance)
if err != nil {
return fmt.Errorf("add balance: %w", err)
}
Expand All @@ -138,16 +148,23 @@ func createBalanceWithEventsAndReferrals(nullifier, refBy string, events []data.
return fmt.Errorf("add open events: %w", err)
}

Log(r).Debugf("%d referrals will be added for nullifier=%s", len(refCodes), nullifier)
if err = ReferralsQ(r).Insert(refCodes...); err != nil {
return fmt.Errorf("add referrals: %w", err)
}

Log(r).Debugf("%s referral will be consumed", refBy)
if _, err = ReferralsQ(r).Consume(refBy); err != nil {
return fmt.Errorf("consume referral: %w", err)
}

level, err := doLvlUpAndReferralsUpdate(Levels(r), ReferralsQ(r), balance, 0)
if err != nil {
return fmt.Errorf("failed to do lvlup and referrals update: %w", err)
}

err = BalancesQ(r).FilterByNullifier(balance.Nullifier).Update(map[string]any{
data.ColLevel: level,
})
if err != nil {
return fmt.Errorf("update balance amount and level: %w", err)
}

return nil
})
}
31 changes: 19 additions & 12 deletions internal/service/handlers/edit_referrals.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,21 +32,28 @@ func EditReferrals(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusNoContent)
return
}
events := prepareEventsWithRef(req.Nullifier, "", r)
if err = createBalanceWithEvents(req.Nullifier, "", events, r); err != nil {
Log(r).WithError(err).Error("Failed to create balance with events")
ape.RenderErr(w, problems.InternalError())
return
}

code := referralid.New(req.Nullifier, 0)
err = ReferralsQ(r).Insert(data.Referral{
ID: code,
Nullifier: req.Nullifier,
UsageLeft: int32(req.Count),
var code string
err = EventsQ(r).Transaction(func() error {
events := prepareEventsWithRef(req.Nullifier, "", r)
if err = createBalanceWithEvents(req.Nullifier, "", events, r); err != nil {
return fmt.Errorf("failed to create balance with events: %w", err)
}

code = referralid.New(req.Nullifier, 0)
err = ReferralsQ(r).Insert(data.Referral{
ID: code,
Nullifier: req.Nullifier,
UsageLeft: int32(req.Count),
})
if err != nil {
return fmt.Errorf("failed to insert referral for nullifier [%s]: %w", req.Nullifier, err)
}

return nil
})
if err != nil {
Log(r).WithError(err).Errorf("failed to insert referral for nullifier [%s]", req.Nullifier)
Log(r).WithError(err).Errorf("failed to create genesis balance [%s]", req.Nullifier)
ape.RenderErr(w, problems.InternalError())
return
}
Expand Down
31 changes: 17 additions & 14 deletions internal/service/handlers/verify_passport.go
Original file line number Diff line number Diff line change
Expand Up @@ -335,7 +335,23 @@ func addEventForReferrer(r *http.Request, evTypeRef *evtypes.EventConfig, balanc
return fmt.Errorf("critical: referred_by not null, but row in referrals absent")
}

if !evTypeRef.AutoClaim {
referrerBalance, err := BalancesQ(r).FilterByNullifier(referral.Nullifier).Get()
if err != nil {
return fmt.Errorf("failed to get referrer balance: %w", err)
}
if referrerBalance == nil {
return fmt.Errorf("critical: referrer balance not exist [%s], while referral code exist", referral.Nullifier)
}

if !referrerBalance.ReferredBy.Valid {
Log(r).Debug("Referrer is genesis balance")
return nil
}

if !evTypeRef.AutoClaim || referrerBalance.Country == nil {
if referrerBalance.Country == nil {
Log(r).Debug("Referrer not scan passport yet! Add fulfilled events")
}
err = EventsQ(r).Insert(data.Event{
Nullifier: referral.Nullifier,
Type: evTypeRef.Name,
Expand All @@ -349,19 +365,6 @@ func addEventForReferrer(r *http.Request, evTypeRef *evtypes.EventConfig, balanc
return nil
}

referrerBalance, err := BalancesQ(r).FilterByNullifier(referral.Nullifier).Get()
if err != nil {
return fmt.Errorf("failed to get referrer balance: %w", err)
}
if referrerBalance == nil {
return fmt.Errorf("critical: referrer balance not exist [%s], while referral code exist", referral.Nullifier)
}

if !referrerBalance.ReferredBy.Valid || referrerBalance.Country == nil {
Log(r).Debug("Referrer is genesis balance or not scanned passport")
return nil
}

country, err := CountriesQ(r).FilterByCodes(*referrerBalance.Country).Get()
if err != nil {
return fmt.Errorf("failed to get referrer country: %w", err)
Expand Down

0 comments on commit 9a4103b

Please sign in to comment.