diff --git a/go.mod b/go.mod index e1bbf59..2769155 100644 --- a/go.mod +++ b/go.mod @@ -15,17 +15,17 @@ require ( github.com/redis/go-redis/v9 v9.2.1 github.com/stretchr/testify v1.8.4 github.com/swaggo/swag v1.16.2 - github.com/testcontainers/testcontainers-go v0.25.0 + github.com/testcontainers/testcontainers-go v0.26.0 go.uber.org/zap v1.26.0 ) require ( cloud.google.com/go v0.110.9 // indirect - cloud.google.com/go/compute v1.23.1 // indirect + cloud.google.com/go/compute v1.23.2 // indirect cloud.google.com/go/compute/metadata v0.2.3 // indirect cloud.google.com/go/firestore v1.14.0 // indirect - cloud.google.com/go/iam v1.1.3 // indirect - cloud.google.com/go/longrunning v0.5.2 // indirect + cloud.google.com/go/iam v1.1.4 // indirect + cloud.google.com/go/longrunning v0.5.3 // indirect cloud.google.com/go/storage v1.33.0 // indirect cosmossdk.io/math v1.1.2 // indirect dario.cat/mergo v1.0.0 // indirect @@ -42,14 +42,14 @@ require ( github.com/chenzhuoyu/iasm v0.9.0 // indirect github.com/cloudflare/circl v1.3.5 // indirect github.com/containerd/cgroups v1.1.0 // indirect - github.com/containerd/containerd v1.7.7 // indirect + github.com/containerd/containerd v1.7.8 // indirect github.com/containerd/continuity v0.4.3 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect github.com/distribution/reference v0.5.0 // indirect github.com/dmarkham/enumer v1.5.9 // indirect github.com/docker/distribution v2.8.3+incompatible // indirect - github.com/docker/docker v24.0.6+incompatible // indirect + github.com/docker/docker v24.0.7+incompatible // indirect github.com/docker/go-connections v0.4.0 // indirect github.com/docker/go-units v0.5.0 // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect @@ -60,7 +60,7 @@ require ( github.com/gin-gonic/gin v1.9.1 // indirect github.com/go-faster/city v1.0.1 // indirect github.com/go-faster/errors v0.6.1 // indirect - github.com/go-logr/logr v1.2.4 // indirect + github.com/go-logr/logr v1.3.0 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-openapi/jsonpointer v0.20.0 // indirect github.com/go-openapi/jsonreference v0.20.2 // indirect @@ -78,7 +78,7 @@ require ( github.com/golang/protobuf v1.5.3 // indirect github.com/google/pprof v0.0.0-20231023181126-ff6d637d2a7b // indirect github.com/google/s2a-go v0.1.7 // indirect - github.com/google/uuid v1.3.1 // indirect + github.com/google/uuid v1.4.0 // indirect github.com/googleapis/enterprise-certificate-proxy v0.3.2 // indirect github.com/googleapis/gax-go/v2 v2.12.0 // indirect github.com/gorilla/mux v1.8.0 // indirect @@ -118,7 +118,7 @@ require ( github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/quic-go/qpack v0.4.0 // indirect github.com/quic-go/qtls-go1-20 v0.4.1 // indirect - github.com/quic-go/quic-go v0.39.2 // indirect + github.com/quic-go/quic-go v0.39.3 // indirect github.com/refraction-networking/utls v1.5.4 // indirect github.com/rs/zerolog v1.31.0 // indirect github.com/sagikazarmark/locafero v0.3.0 // indirect @@ -138,7 +138,7 @@ require ( github.com/twmb/franz-go/pkg/kadm v1.10.0 // indirect github.com/twmb/franz-go/pkg/kmsg v1.7.0 // indirect github.com/ugorji/go/codec v1.2.11 // indirect - github.com/vmihailenco/msgpack/v5 v5.4.0 // indirect + github.com/vmihailenco/msgpack/v5 v5.4.1 // indirect github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect go.opencensus.io v0.24.0 // indirect go.opentelemetry.io/otel v1.19.0 // indirect diff --git a/go.sum b/go.sum index 1f06076..df25727 100644 --- a/go.sum +++ b/go.sum @@ -25,18 +25,18 @@ cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvf cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= -cloud.google.com/go/compute v1.23.1 h1:V97tBoDaZHb6leicZ1G6DLK2BAaZLJ/7+9BB/En3hR0= -cloud.google.com/go/compute v1.23.1/go.mod h1:CqB3xpmPKKt3OJpW2ndFIXnA9A4xAy/F3Xp1ixncW78= +cloud.google.com/go/compute v1.23.2 h1:nWEMDhgbBkBJjfpVySqU4jgWdc22PLR0o4vEexZHers= +cloud.google.com/go/compute v1.23.2/go.mod h1:JJ0atRC0J/oWYiiVBmsSsrRnh92DhZPG4hFDcR04Rns= cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY= cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= cloud.google.com/go/firestore v1.14.0 h1:8aLcKnMPoldYU3YHgu4t2exrKhLQkqaXAGqT0ljrFVw= cloud.google.com/go/firestore v1.14.0/go.mod h1:96MVaHLsEhbvkBEdZgfN+AS/GIkco1LRpH9Xp9YZfzQ= -cloud.google.com/go/iam v1.1.3 h1:18tKG7DzydKWUnLjonWcJO6wjSCAtzh4GcRKlH/Hrzc= -cloud.google.com/go/iam v1.1.3/go.mod h1:3khUlaBXfPKKe7huYgEpDn6FtgRyMEqbkvBxrQyY5SE= -cloud.google.com/go/longrunning v0.5.2 h1:u+oFqfEwwU7F9dIELigxbe0XVnBAo9wqMuQLA50CZ5k= -cloud.google.com/go/longrunning v0.5.2/go.mod h1:nqo6DQbNV2pXhGDbDMoN2bWz68MjZUzqv2YttZiveCs= +cloud.google.com/go/iam v1.1.4 h1:K6n/GZHFTtEoKT5aUG3l9diPi0VduZNQ1PfdnpkkIFk= +cloud.google.com/go/iam v1.1.4/go.mod h1:l/rg8l1AaA+VFMho/HYx2Vv6xinPSLMF8qfhRPIZ0L8= +cloud.google.com/go/longrunning v0.5.3 h1:maKa7O9YTzmVzwdlRKr981U1Ys2auup6rpeMt8y3+RU= +cloud.google.com/go/longrunning v0.5.3/go.mod h1:y/0ga59EYu58J6SHmmQOvekvND2qODbu8ywBBW7EK7Y= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= @@ -160,8 +160,8 @@ github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9 github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ= -github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.3.0 h1:2y3SDp0ZXuc6/cjLSZ+Q3ir+QB9T/iG5yYRXqsagWSY= +github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= @@ -276,8 +276,8 @@ github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm4 github.com/google/s2a-go v0.1.7 h1:60BLSyTrOV4/haCDW4zb1guZItoSq8foHCXrAnjBo/o= github.com/google/s2a-go v0.1.7/go.mod h1:50CgR4k1jNlWBu4UfS4AcfhVe1r6pdZPygJ3R8F0Qdw= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4= -github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.4.0 h1:MtMxsa51/r9yyhkyLsVeVt0B+BGQZzpQiTQ4eHZ8bc4= +github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/enterprise-certificate-proxy v0.3.2 h1:Vie5ybvEvT75RniqhfFxPRy3Bf7vr3h0cechB90XaQs= github.com/googleapis/enterprise-certificate-proxy v0.3.2/go.mod h1:VLSiSSBs/ksPL8kq3OBOQ6WRI2QnaFynd1DCjZ62+V0= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= @@ -403,8 +403,8 @@ github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo= github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A= github.com/quic-go/qtls-go1-20 v0.4.1 h1:D33340mCNDAIKBqXuAvexTNMUByrYmFYVfKfDN5nfFs= github.com/quic-go/qtls-go1-20 v0.4.1/go.mod h1:X9Nh97ZL80Z+bX/gUXMbipO6OxdiDi58b/fMC9mAL+k= -github.com/quic-go/quic-go v0.39.2 h1:hmwAf8zAHlvan0Y5PXxeeBFZEW17IW99sXLry8I2kjk= -github.com/quic-go/quic-go v0.39.2/go.mod h1:T09QsDQWjLiQ74ZmacDfqZmhY/NLnw5BC40MANNNZ1Q= +github.com/quic-go/quic-go v0.39.3 h1:o3YB6t2SR+HU/pgwF29kJ6g4jJIJEwEZ8CKia1h1TKg= +github.com/quic-go/quic-go v0.39.3/go.mod h1:T09QsDQWjLiQ74ZmacDfqZmhY/NLnw5BC40MANNNZ1Q= github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 h1:N/ElC8H3+5XpJzTSTfLsJV/mx9Q9g7kxmchpfZyxgzM= github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/redis/go-redis/v9 v9.0.5 h1:CuQcn5HIEeK7BgElubPP8CGtE0KakrnbBSTLjathl5o= @@ -470,8 +470,8 @@ github.com/twmb/franz-go/pkg/kmsg v1.7.0 h1:a457IbvezYfA5UkiBvyV3zj0Is3y1i8EJgqj github.com/twmb/franz-go/pkg/kmsg v1.7.0/go.mod h1:se9Mjdt0Nwzc9lnjJ0HyDtLyBnaBDAd7pCje47OhSyw= github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU= github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= -github.com/vmihailenco/msgpack/v5 v5.4.0 h1:hRM0digJwyR6vll33NNAwCFguy5JuBD6jxDmQP3l608= -github.com/vmihailenco/msgpack/v5 v5.4.0/go.mod h1:GaZTsDaehaPpQVyxrf5mtQlH+pc21PIudVV/E3rRQok= +github.com/vmihailenco/msgpack/v5 v5.4.1 h1:cQriyiUvjTwOHg8QZaPihLWeRAAVoCpE00IUPn0Bjt8= +github.com/vmihailenco/msgpack/v5 v5.4.1/go.mod h1:GaZTsDaehaPpQVyxrf5mtQlH+pc21PIudVV/E3rRQok= github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g= github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= diff --git a/miner/contract.go b/miner/contract.go index c0dcd30..07fee45 100644 --- a/miner/contract.go +++ b/miner/contract.go @@ -59,6 +59,7 @@ type ( model.ExtraBonusStartedAtField model.LatestDeviceField model.UserIDField + model.UsernameField UpdatedUser model.BalanceSoloPendingField model.BalanceT1PendingField @@ -110,6 +111,7 @@ type ( backupUserUpdated struct { model.DeserializedBackupUsersKey + model.UserIDField model.BalanceT1Field model.BalanceT2Field model.SlashingRateT1Field @@ -122,6 +124,7 @@ type ( model.FirstRecalculatedActiveT2ReferralsField model.FirstRecalculatedSlashingRateT1Field model.FirstRecalculatedSlashingRateT2Field + model.BalancesBackupUsedAtField } referral struct { diff --git a/miner/miner.go b/miner/miner.go index 3fd1d15..7a75b9a 100644 --- a/miner/miner.go +++ b/miner/miner.go @@ -347,8 +347,9 @@ func (m *miner) mine(ctx context.Context, workerNumber int64) { if usr.UserID == "" { continue } + backupedUsr, backupExists := backupedUsers[usr.ID] if balanceBackupMode { - if backupedUsr, ok := backupedUsers[usr.ID]; ok { + if backupExists { diffT1ActiveValue := backupedUsr.ActiveT1Referrals - usr.ActiveT1Referrals diffT2ActiveValue := backupedUsr.ActiveT2Referrals - usr.ActiveT2Referrals if diffT1ActiveValue < 0 && diffT1ActiveValue*-1 > usr.ActiveT1Referrals { @@ -365,6 +366,11 @@ func (m *miner) mine(ctx context.Context, workerNumber int64) { usr.SlashingRateT1 = backupedUsr.SlashingRateT1 usr.SlashingRateT2 = backupedUsr.SlashingRateT2 + + backupUsersUpdated = append(backupUsersUpdated, &backupUserUpdated{ + DeserializedBackupUsersKey: model.DeserializedBackupUsersKey{ID: usr.ID}, + BalancesBackupUsedAtField: model.BalancesBackupUsedAtField{BalancesBackupUsedAt: time.Now()}, + }) } } else { if recalculatedUsr, ok := recalculatedTiersBalancesUsers[usr.ID]; ok { @@ -391,19 +397,20 @@ func (m *miner) mine(ctx context.Context, workerNumber int64) { usr.SlashingRateT1 = recalculatedUsr.SlashingRateT1 usr.SlashingRateT2 = recalculatedUsr.SlashingRateT2 - if _, ok := backupedUsers[usr.ID]; !ok { + if !backupExists { backupUsersUpdated = append(backupUsersUpdated, &backupUserUpdated{ DeserializedBackupUsersKey: model.DeserializedBackupUsersKey{ID: usr.ID}, + UserIDField: usr.UserIDField, BalanceT1Field: model.BalanceT1Field{BalanceT1: oldBalanceT1}, BalanceT2Field: model.BalanceT2Field{BalanceT2: oldBalanceT2}, SlashingRateT1Field: model.SlashingRateT1Field{SlashingRateT1: oldSlashingT1Rate}, SlashingRateT2Field: model.SlashingRateT2Field{SlashingRateT2: oldSlashingT2Rate}, ActiveT1ReferralsField: model.ActiveT1ReferralsField{ActiveT1Referrals: usr.ActiveT1Referrals}, ActiveT2ReferralsField: model.ActiveT2ReferralsField{ActiveT2Referrals: usr.ActiveT2Referrals}, - FirstRecalculatedBalanceT1Field: model.FirstRecalculatedBalanceT1Field{FirstRecalculatedBalanceT1: usr.BalanceT1}, - FirstRecalculatedBalanceT2Field: model.FirstRecalculatedBalanceT2Field{FirstRecalculatedBalanceT2: usr.BalanceT2}, - FirstRecalculatedSlashingRateT1Field: model.FirstRecalculatedSlashingRateT1Field{FirstRecalculatedSlashingRateT1: usr.SlashingRateT1}, - FirstRecalculatedSlashingRateT2Field: model.FirstRecalculatedSlashingRateT2Field{FirstRecalculatedSlashingRateT2: usr.SlashingRateT2}, + FirstRecalculatedBalanceT1Field: model.FirstRecalculatedBalanceT1Field{FirstRecalculatedBalanceT1: recalculatedUsr.BalanceT1}, + FirstRecalculatedBalanceT2Field: model.FirstRecalculatedBalanceT2Field{FirstRecalculatedBalanceT2: recalculatedUsr.BalanceT2}, + FirstRecalculatedSlashingRateT1Field: model.FirstRecalculatedSlashingRateT1Field{FirstRecalculatedSlashingRateT1: recalculatedUsr.SlashingRateT1}, + FirstRecalculatedSlashingRateT2Field: model.FirstRecalculatedSlashingRateT2Field{FirstRecalculatedSlashingRateT2: recalculatedUsr.SlashingRateT2}, FirstRecalculatedActiveT1ReferralsField: model.FirstRecalculatedActiveT1ReferralsField{FirstRecalculatedActiveT1Referrals: usr.ActiveT1Referrals + diffT1ActiveValue}, FirstRecalculatedActiveT2ReferralsField: model.FirstRecalculatedActiveT2ReferralsField{FirstRecalculatedActiveT2Referrals: usr.ActiveT2Referrals + diffT2ActiveValue}, }) @@ -440,8 +447,10 @@ func (m *miner) mine(ctx context.Context, workerNumber int64) { updatedUser.ExtraBonusDaysClaimNotAvailable = 0 updatedUser.ExtraBonusLastClaimAvailableAt = nil } - if userStoppedMining := didReferralJustStopMining(now, usr, t0Ref, tMinus1Ref); userStoppedMining != nil { - referralsThatStoppedMining = append(referralsThatStoppedMining, userStoppedMining) + if balanceBackupMode || !backupExists { + if userStoppedMining := didReferralJustStopMining(now, usr, t0Ref, tMinus1Ref); userStoppedMining != nil { + referralsThatStoppedMining = append(referralsThatStoppedMining, userStoppedMining) + } } if dayOffStarted := didANewDayOffJustStart(now, usr); dayOffStarted != nil { msgs = append(msgs, dayOffStartedMessage(reqCtx, dayOffStarted)) diff --git a/miner/recalculate_balance.go b/miner/recalculate_balance.go index 1644d98..1977115 100644 --- a/miner/recalculate_balance.go +++ b/miner/recalculate_balance.go @@ -75,7 +75,7 @@ func (m *miner) getUsers(ctx context.Context, users []*user) (map[int64]*pgUserC LIMIT $2 OFFSET $3` rows, err := storagePG.Select[pgUserCreated](ctx, m.dbPG, sql, userIDs, maxLimit, offset) if err != nil { - return nil, errors.Wrap(err, "can't get users from pg") + return nil, errors.Wrapf(err, "can't get users from pg for: %#v", userIDs) } if len(rows) == 0 { break @@ -100,7 +100,7 @@ func (m *miner) collectTiers(ctx context.Context, users []*user) (map[int64][]in referredByIDs []string offset int64 = 0 now = time.Now() - t1ActiveCounts, t2ActiveCounts = make(map[int64]uint64), make(map[int64]uint64) + t1ActiveCounts, t2ActiveCounts = make(map[int64]uint64, len(users)), make(map[int64]uint64, len(users)) t1Referrals, t2Referrals = make(map[int64][]int64), make(map[int64][]int64) ) for _, val := range users { @@ -276,7 +276,7 @@ func (m *miner) recalculateTiersBalances(ctx context.Context, users []*user, tMi return nil, errors.Wrapf(err, "can't get CreatedAt information for users:%#v", usrs) } for _, usr := range users { - if usr.UserID == "" { + if usr.UserID == "" || usr.Username == "" { continue } if _, ok := usrs[usr.ID]; ok { @@ -288,13 +288,14 @@ func (m *miner) recalculateTiersBalances(ctx context.Context, users []*user, tMi actualBalancesT1[usr.ID] = usr.BalanceT1 actualBalancesT2[usr.ID] = usr.BalanceT2 } + if len(users) == 0 { + return nil, nil + } t1Referrals, t2Referrals, t1ActiveCounts, t2ActiveCounts, err := m.collectTiers(ctx, needToBeRecalculatedUsers) if err != nil { return nil, errors.Wrap(err, "can't get active users for users") } if len(t1Referrals) == 0 && len(t2Referrals) == 0 { - log.Debug("No t1/t2 referrals gathered") - return nil, nil } @@ -321,8 +322,6 @@ func (m *miner) recalculateTiersBalances(ctx context.Context, users []*user, tMi usrIDs[usr.ID] = struct{}{} } if len(usrIDs) == 0 { - log.Debug("no user ids to be recalculated") - return nil, nil } adoptions, err := tokenomics.GetAllAdoptions[float64](ctx, m.db) diff --git a/model/model.go b/model/model.go index 92d3ed3..07e1899 100644 --- a/model/model.go +++ b/model/model.go @@ -96,6 +96,9 @@ type ( ExtraBonusLastClaimAvailableAtField struct { ExtraBonusLastClaimAvailableAt *time.Time `redis:"extra_bonus_last_claim_available_at,omitempty"` } + BalancesBackupUsedAtField struct { + BalancesBackupUsedAt *time.Time `redis:"balance_backup_used_at,omitempty"` + } UserIDField struct { UserID string `redis:"user_id,omitempty"` } diff --git a/tokenomics/mining_sessions.go b/tokenomics/mining_sessions.go index 5beebbf..e2b64cf 100644 --- a/tokenomics/mining_sessions.go +++ b/tokenomics/mining_sessions.go @@ -251,6 +251,15 @@ func (s *miningSessionsTableSource) Process(ctx context.Context, msg *messagebro ).ErrorOrNil() } +func mustGetBalancesBackupMode(ctx context.Context, db storage.DB) (result bool, err error) { + balancesBackupModeString, err := db.Get(ctx, "balances_backup_mode").Result() + if err != nil && errors.Is(err, redis.Nil) { + err = nil + } + + return balancesBackupModeString == "true", err +} + //nolint:funlen,revive,gocognit // . func (s *miningSessionsTableSource) incrementActiveReferralCountForT0AndTMinus1(ctx context.Context, ms *MiningSession) (err error) { if ctx.Err() != nil || !ms.LastNaturalMiningStartedAt.Equal(*ms.StartedAt.Time) { @@ -278,6 +287,20 @@ func (s *miningSessionsTableSource) incrementActiveReferralCountForT0AndTMinus1( if err != nil { return errors.Wrapf(err, "failed to getOrInitInternalID for userID:%v", *ms.UserID) } + backupUsr, err := storage.Get[struct { + model.DeserializedBackupUsersKey + model.UserIDField + }](ctx, s.db, model.SerializedBackupUsersKey(id)) + if err != nil { + return errors.Wrapf(err, "failed to get backupUser for id:%v, userID:%v", id, *ms.UserID) + } + balanceBackupMode, err := mustGetBalancesBackupMode(ctx, s.db) + if err != nil { + return errors.Wrapf(err, "failed to get backup flag for id:%v", id) + } + if !balanceBackupMode && backupUsr != nil { + return nil + } referees, err := storage.Get[struct { model.UserIDField model.DeserializedUsersKey diff --git a/tokenomics/users.go b/tokenomics/users.go index ebc7546..045ad52 100644 --- a/tokenomics/users.go +++ b/tokenomics/users.go @@ -172,7 +172,9 @@ func (s *usersTableSource) replaceUser(ctx context.Context, usr *users.User) err model.BlockchainAccountAddressField model.DeserializedUsersKey model.IDT0Field + model.IDTMinus1Field model.HideRankingField + model.BalanceForTMinus1Field } ) dbUser, err := storage.Get[user](ctx, s.db, model.SerializedUsersKey(internalID)) @@ -200,12 +202,12 @@ func (s *usersTableSource) replaceUser(ctx context.Context, usr *users.User) err return multierror.Append( //nolint:wrapcheck // Not Needed. errors.Wrapf(err, "failed to replace user:%#v", usr), - errors.Wrapf(s.updateReferredBy(ctx, internalID, dbUser[0].IDT0, usr.ID, usr.ReferredBy), "failed to updateReferredBy for user:%#v", usr), + errors.Wrapf(s.updateReferredBy(ctx, internalID, dbUser[0].IDT0, dbUser[0].IDTMinus1, usr.ID, usr.ReferredBy, dbUser[0].BalanceForTMinus1), "failed to updateReferredBy for user:%#v", usr), errors.Wrapf(s.updateUsernameKeywords(ctx, internalID, dbUser[0].Username, usr.Username), "failed to updateUsernameKeywords for oldUser:%#v, user:%#v", dbUser, usr), //nolint:lll // . ).ErrorOrNil() } -func (s *usersTableSource) updateReferredBy(ctx context.Context, id, oldIDT0 int64, userID, referredBy string) error { +func (s *usersTableSource) updateReferredBy(ctx context.Context, id, oldIDT0, oldTMinus1 int64, userID, referredBy string, balanceForTMinus1 float64) error { if referredBy == userID || referredBy == "" || referredBy == "bogus" || @@ -239,6 +241,34 @@ func (s *usersTableSource) updateReferredBy(ctx context.Context, id, oldIDT0 int return errors.Wrapf(err3, "failed to get users entry for tMinus1ID:%v", t0Referral[0].IDT0) } else if len(tMinus1Referral) == 1 { newPartialState.IDTMinus1 = -tMinus1Referral[0].ID + if balanceForTMinus1 > 0.0 { + results, err4 := s.db.TxPipelined(ctx, func(pipeliner redis.Pipeliner) error { + if oldIdTMinus1Key := model.SerializedUsersKey(oldTMinus1); oldIdTMinus1Key != "" { + if err = pipeliner.HIncrByFloat(ctx, oldIdTMinus1Key, "balance_t2_pending", -balanceForTMinus1).Err(); err != nil { + return err + } + } + if newIdTMinus1Key := model.SerializedUsersKey(tMinus1Referral[0].ID); newIdTMinus1Key != "" { + if err = pipeliner.HIncrByFloat(ctx, newIdTMinus1Key, "balance_t2_pending", balanceForTMinus1).Err(); err != nil { + return err + } + } + + return nil + }) + if err4 != nil { + return errors.Wrapf(err4, "failed to move t2 balance from:%v to:%v", oldTMinus1, newPartialState.IDTMinus1) + } + errs := make([]error, 0, len(results)) + for _, result := range results { + if err = result.Err(); err != nil { + errs = append(errs, errors.Wrapf(err, "failed to run `%#v`", result.FullName())) + } + } + if errs := multierror.Append(nil, errs...); errs.ErrorOrNil() != nil { + return errors.Wrapf(errs.ErrorOrNil(), "failed to move t2 balances for id:%v,id:%v", userID, id) + } + } } } }