Skip to content

Commit

Permalink
Distribution changes. (#225)
Browse files Browse the repository at this point in the history
  • Loading branch information
ice-myles authored Dec 5, 2024
1 parent c53aac4 commit 128a55e
Show file tree
Hide file tree
Showing 13 changed files with 321 additions and 161 deletions.
11 changes: 11 additions & 0 deletions application.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,7 @@ miner:
t1LimitCount: 2
welcomeBonusV2Amount: 500
t1ReferralsAllowedWithoutAnyMiningBoostLevel: false
dryRunDistribution: false
kyc/quiz:
maxResetCount: 0
maxAttemptsAllowed: 3
Expand Down Expand Up @@ -302,6 +303,16 @@ extra-bonus-notifier:
balance-synchronizer:
workers: 1
batchSize: 100
users: &users
wintr/connectors/storage/v2: &usersdb
runDDL: false
primaryURL: postgresql://root:pass@localhost:5433/eskimo
timeout: 90s
credentials:
user: root
password: pass
replicaURLs:
- postgresql://root:pass@localhost:5433/eskimo
tokenomics_test:
<<: *tokenomics
messageBroker:
Expand Down
26 changes: 16 additions & 10 deletions coin-distribution/DDL.sql
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,10 @@ CREATE TABLE IF NOT EXISTS coin_distributions_by_earner (
user_id text NOT NULL,
earner_user_id text NOT NULL,
eth_address text NOT NULL,
verified boolean NOT NULL DEFAULT FALSE,
PRIMARY KEY(day, user_id, earner_user_id))
WITH (FILLFACTOR = 70);
ALTER TABLE coin_distributions_by_earner ADD COLUMN IF NOT EXISTS verified boolean NOT NULL DEFAULT FALSE;

CREATE TABLE IF NOT EXISTS coin_distributions_pending_review (
created_at timestamp ,
Expand All @@ -77,7 +79,9 @@ CREATE TABLE IF NOT EXISTS coin_distributions_pending_review (
referred_by_username text NOT NULL,
user_id text NOT NULL,
eth_address text NOT NULL,
verified boolean NOT NULL DEFAULT FALSE,
PRIMARY KEY(day, user_id));
ALTER TABLE coin_distributions_pending_review ADD COLUMN IF NOT EXISTS verified boolean NOT NULL DEFAULT FALSE;

CREATE INDEX IF NOT EXISTS coin_distributions_pending_review_internal_id_ix ON coin_distributions_pending_review (internal_id NULLS FIRST);
CREATE INDEX IF NOT EXISTS coin_distributions_pending_review_created_at_ix ON coin_distributions_pending_review (created_at);
Expand Down Expand Up @@ -105,8 +109,9 @@ CREATE TABLE IF NOT EXISTS reviewed_coin_distributions (
eth_address text NOT NULL,
reviewer_user_id text NOT NULL,
decision text NOT NULL,
verified boolean NOT NULL DEFAULT FALSE,
PRIMARY KEY(user_id, day, review_day));

ALTER TABLE reviewed_coin_distributions ADD COLUMN IF NOT EXISTS verified boolean NOT NULL DEFAULT FALSE;
create or replace function approve_coin_distributions(reviewer_user_id text, process_immediately boolean, nested boolean)
returns RECORD
language plpgsql
Expand All @@ -119,8 +124,8 @@ BEGIN
select created_at, internal_id, day, iceflakes, user_id, eth_address
from coin_distributions_pending_review;

insert into reviewed_coin_distributions(reviewed_at, created_at, internal_id, ice, day, review_day, iceflakes, username, referred_by_username, user_id, eth_address, reviewer_user_id, decision)
select now, created_at, internal_id, ice, day, now::date, iceflakes, username, referred_by_username, user_id, eth_address, reviewer_user_id, (case when process_immediately is true then 'approve-and-process-immediately' else 'approve' end) AS reason
insert into reviewed_coin_distributions(reviewed_at, created_at, internal_id, ice, day, review_day, iceflakes, username, referred_by_username, user_id, eth_address, reviewer_user_id, decision, verified)
select now, created_at, internal_id, ice, day, now::date, iceflakes, username, referred_by_username, user_id, eth_address, reviewer_user_id, (case when process_immediately is true then 'approve-and-process-immediately' else 'approve' end) AS reason, verified
from coin_distributions_pending_review;

IF process_immediately is true THEN
Expand Down Expand Up @@ -148,8 +153,8 @@ language plpgsql
declare
now timestamp := current_timestamp;
BEGIN
insert into reviewed_coin_distributions(reviewed_at, created_at, internal_id, ice, day, review_day, iceflakes, username, referred_by_username, user_id, eth_address, reviewer_user_id, decision)
select now, created_at, internal_id, ice, day, now::date, iceflakes, username, referred_by_username, user_id, eth_address, reviewer_user_id, 'deny'
insert into reviewed_coin_distributions(reviewed_at, created_at, internal_id, ice, day, review_day, iceflakes, username, referred_by_username, user_id, eth_address, reviewer_user_id, decision, verified)
select now, created_at, internal_id, ice, day, now::date, iceflakes, username, referred_by_username, user_id, eth_address, reviewer_user_id, 'deny', verified
from coin_distributions_pending_review;

delete from coin_distributions_pending_review where 1=1;
Expand All @@ -175,8 +180,8 @@ declare
BEGIN
delete from coin_distributions_by_earner WHERE balance = 0;

insert into coin_distributions_pending_review(created_at, internal_id, ice, day, iceflakes, username, referred_by_username, user_id, eth_address)
SELECT created_at, internal_id, ice, day, (ice::text||zeros)::uint256 AS iceflakes, username, referred_by_username, user_id, eth_address
insert into coin_distributions_pending_review(created_at, internal_id, ice, day, iceflakes, username, referred_by_username, user_id, eth_address, verified)
SELECT created_at, internal_id, ice, day, (ice::text||zeros)::uint256 AS iceflakes, username, referred_by_username, user_id, eth_address, verified
FROM (select
min (created_at) filter ( where user_id=earner_user_id or internal_id = reward_pool_internal_id) AS created_at,
min (internal_id) filter ( where user_id=earner_user_id or internal_id = reward_pool_internal_id) AS internal_id,
Expand All @@ -185,7 +190,8 @@ BEGIN
string_agg(distinct username,'') AS username,
string_agg(distinct referred_by_username,'') AS referred_by_username,
user_id,
string_agg(distinct eth_address,'') AS eth_address
string_agg(distinct eth_address,'') AS eth_address,
verified
from coin_distributions_by_earner
group by day,user_id) AS X;

Expand All @@ -194,8 +200,8 @@ BEGIN
WITH del as (
DELETE FROM coin_distributions_pending_review WHERE internal_id IS NULL RETURNING *
)
insert into reviewed_coin_distributions(reviewed_at, created_at, internal_id, ice, day, review_day, iceflakes, username, referred_by_username, user_id, eth_address, reviewer_user_id, decision)
select now, COALESCE(created_at,to_timestamp(0)), COALESCE(internal_id,0), ice, day, now::date, iceflakes, username, referred_by_username, user_id, eth_address, 'system', 'deny due to incomplete data'
insert into reviewed_coin_distributions(reviewed_at, created_at, internal_id, ice, day, review_day, iceflakes, username, referred_by_username, user_id, eth_address, reviewer_user_id, decision, verified)
select now, COALESCE(created_at,to_timestamp(0)), COALESCE(internal_id,0), ice, day, now::date, iceflakes, username, referred_by_username, user_id, eth_address, 'system', 'deny due to incomplete data', verified
from del;

IF nested is false THEN
Expand Down
2 changes: 2 additions & 0 deletions coin-distribution/contract.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ type (
EthAddress string `json:"ethAddress" swaggertype:"string" example:"0x43...."`
Ice float64 `json:"ice" db:"-" example:"1000"`
IceInternal int64 `json:"-" db:"ice" swaggerignore:"true"`
Verified bool `json:"verified" db:"verified" swaggerignore:"true"`
}

ByEarnerForReview struct {
Expand All @@ -88,6 +89,7 @@ type (
EthAddress string
InternalID int64
Balance float64
Verified bool
}
)

Expand Down
5 changes: 1 addition & 4 deletions coin-distribution/eligibility.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import (

"github.com/ethereum/go-ethereum/common"

"github.com/ice-blockchain/eskimo/users"
"github.com/ice-blockchain/freezer/model"
"github.com/ice-blockchain/wintr/time"
)
Expand Down Expand Up @@ -47,7 +46,6 @@ func IsEligibleForEthereumDistribution(
ethAddress, country string,
distributionDeniedCountries map[string]struct{},
now, collectingEndedAt, miningSessionSoloStartedAt, miningSessionSoloEndedAt, ethereumDistributionEndDate *time.Time,
kycState model.KYCState,
miningSessionDuration, ethereumDistributionFrequencyMin, ethereumDistributionFrequencyMax stdlibtime.Duration) bool {
var countryAllowed bool
if _, countryDenied := distributionDeniedCountries[strings.ToLower(country)]; len(distributionDeniedCountries) == 0 || (country != "" && !countryDenied) {
Expand All @@ -59,8 +57,7 @@ func IsEligibleForEthereumDistribution(
!miningSessionSoloEndedAt.IsNil() && (miningSessionSoloEndedAt.After(*collectingEndedAt.Time) || AllowInactiveUsers) &&
isEthereumAddressValid(ethAddress) &&
((minEthereumDistributionICEBalanceRequired > 0 && distributedBalance >= minEthereumDistributionICEBalanceRequired) || (minEthereumDistributionICEBalanceRequired == 0 && distributedBalance > 0)) && //nolint:lll // .
model.CalculateMiningStreak(now, miningSessionSoloStartedAt, miningSessionSoloEndedAt, miningSessionDuration) >= minMiningStreaksRequired &&
kycState.KYCStepPassedCorrectly(users.QuizKYCStep)
model.CalculateMiningStreak(now, miningSessionSoloStartedAt, miningSessionSoloEndedAt, miningSessionDuration) >= minMiningStreaksRequired
}

func IsEligibleForEthereumDistributionNow(id int64,
Expand Down
18 changes: 8 additions & 10 deletions coin-distribution/eligibility_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,25 +89,23 @@ func TestFinalDistribution(t *testing.T) {
assert.False(t, IsEligibleForEthereumDistributionNow(5, now, userAlreadyProcessedLastEthereumProcessedAt, coinDistributionStartDate, lastCollectingProcessedAt, 24*stdlibtime.Hour, 24*28*stdlibtime.Hour))

balanceRequired := float64(0)
var kycPassed model.KYCState = buildKYC(true, now)
var kycNotPassed model.KYCState = buildKYC(false, now)
var collectingEndedAt *time.Time
if lastCollectingProcessedAt.IsNil() {
collectingEndedAt = time.New(time.Now().Add(-1 * stdlibtime.Millisecond).Add(20 * stdlibtime.Minute))
}
miningSessionDuration := 24 * stdlibtime.Hour
activeMiningSessionStarted := time.New(stdlibtime.Date(2024, 2, 25, 0, 0, 0, 0, stdlibtime.UTC))
nonActiveMiningSessionEnded := time.New(stdlibtime.Date(2024, 2, 26, 0, 0, 0, 0, stdlibtime.UTC))
assert.True(t, IsEligibleForEthereumDistribution(uint64(0), 0.1, balanceRequired, "skip", "US", make(map[string]struct{}), now, collectingEndedAt, activeMiningSessionStarted, nonActiveMiningSessionEnded, coinDistributionEndDate, kycPassed, miningSessionDuration, 24*stdlibtime.Hour, 24*28*stdlibtime.Hour))
assert.True(t, IsEligibleForEthereumDistribution(uint64(0), 1, balanceRequired, "skip", "US", make(map[string]struct{}), now, collectingEndedAt, activeMiningSessionStarted, nonActiveMiningSessionEnded, coinDistributionEndDate, kycNotPassed, miningSessionDuration, 24*stdlibtime.Hour, 24*28*stdlibtime.Hour))
assert.False(t, IsEligibleForEthereumDistribution(uint64(0), 1, balanceRequired, "bogusInvalidAddress", "US", make(map[string]struct{}), now, collectingEndedAt, activeMiningSessionStarted, nonActiveMiningSessionEnded, coinDistributionEndDate, kycPassed, miningSessionDuration, 24*stdlibtime.Hour, 24*28*stdlibtime.Hour))
assert.False(t, IsEligibleForEthereumDistribution(uint64(0), 1, balanceRequired, "", "US", make(map[string]struct{}), now, collectingEndedAt, activeMiningSessionStarted, nonActiveMiningSessionEnded, coinDistributionEndDate, kycPassed, miningSessionDuration, 24*stdlibtime.Hour, 24*28*stdlibtime.Hour))
assert.True(t, IsEligibleForEthereumDistribution(uint64(0), 0.1, balanceRequired, "skip", "US", make(map[string]struct{}), now, collectingEndedAt, activeMiningSessionStarted, nonActiveMiningSessionEnded, coinDistributionEndDate, miningSessionDuration, 24*stdlibtime.Hour, 24*28*stdlibtime.Hour))
assert.True(t, IsEligibleForEthereumDistribution(uint64(0), 1, balanceRequired, "skip", "US", make(map[string]struct{}), now, collectingEndedAt, activeMiningSessionStarted, nonActiveMiningSessionEnded, coinDistributionEndDate, miningSessionDuration, 24*stdlibtime.Hour, 24*28*stdlibtime.Hour))
assert.False(t, IsEligibleForEthereumDistribution(uint64(0), 1, balanceRequired, "bogusInvalidAddress", "US", make(map[string]struct{}), now, collectingEndedAt, activeMiningSessionStarted, nonActiveMiningSessionEnded, coinDistributionEndDate, miningSessionDuration, 24*stdlibtime.Hour, 24*28*stdlibtime.Hour))
assert.False(t, IsEligibleForEthereumDistribution(uint64(0), 1, balanceRequired, "", "US", make(map[string]struct{}), now, collectingEndedAt, activeMiningSessionStarted, nonActiveMiningSessionEnded, coinDistributionEndDate, miningSessionDuration, 24*stdlibtime.Hour, 24*28*stdlibtime.Hour))

activeMiningSessionEnded := time.New(stdlibtime.Date(2024, 2, 29, 0, 0, 0, 0, stdlibtime.UTC))
assert.True(t, IsEligibleForEthereumDistribution(uint64(0), 0.1, balanceRequired, "skip", "US", make(map[string]struct{}), now, collectingEndedAt, activeMiningSessionStarted, activeMiningSessionEnded, coinDistributionEndDate, kycPassed, miningSessionDuration, 24*stdlibtime.Hour, 24*28*stdlibtime.Hour))
assert.True(t, IsEligibleForEthereumDistribution(uint64(0), 1, balanceRequired, "skip", "US", make(map[string]struct{}), now, collectingEndedAt, activeMiningSessionStarted, activeMiningSessionEnded, coinDistributionEndDate, kycNotPassed, miningSessionDuration, 24*stdlibtime.Hour, 24*28*stdlibtime.Hour))
assert.False(t, IsEligibleForEthereumDistribution(uint64(0), 1, balanceRequired, "bogusInvalidAddress", "US", make(map[string]struct{}), now, collectingEndedAt, activeMiningSessionEnded, nonActiveMiningSessionEnded, coinDistributionEndDate, kycPassed, miningSessionDuration, 24*stdlibtime.Hour, 24*28*stdlibtime.Hour))
assert.False(t, IsEligibleForEthereumDistribution(uint64(0), 1, balanceRequired, "", "US", make(map[string]struct{}), now, collectingEndedAt, activeMiningSessionStarted, activeMiningSessionEnded, coinDistributionEndDate, kycPassed, miningSessionDuration, 24*stdlibtime.Hour, 24*28*stdlibtime.Hour))
assert.True(t, IsEligibleForEthereumDistribution(uint64(0), 0.1, balanceRequired, "skip", "US", make(map[string]struct{}), now, collectingEndedAt, activeMiningSessionStarted, activeMiningSessionEnded, coinDistributionEndDate, miningSessionDuration, 24*stdlibtime.Hour, 24*28*stdlibtime.Hour))
assert.True(t, IsEligibleForEthereumDistribution(uint64(0), 1, balanceRequired, "skip", "US", make(map[string]struct{}), now, collectingEndedAt, activeMiningSessionStarted, activeMiningSessionEnded, coinDistributionEndDate, miningSessionDuration, 24*stdlibtime.Hour, 24*28*stdlibtime.Hour))
assert.False(t, IsEligibleForEthereumDistribution(uint64(0), 1, balanceRequired, "bogusInvalidAddress", "US", make(map[string]struct{}), now, collectingEndedAt, activeMiningSessionEnded, nonActiveMiningSessionEnded, coinDistributionEndDate, miningSessionDuration, 24*stdlibtime.Hour, 24*28*stdlibtime.Hour))
assert.False(t, IsEligibleForEthereumDistribution(uint64(0), 1, balanceRequired, "", "US", make(map[string]struct{}), now, collectingEndedAt, activeMiningSessionStarted, activeMiningSessionEnded, coinDistributionEndDate, miningSessionDuration, 24*stdlibtime.Hour, 24*28*stdlibtime.Hour))

assert.Equal(t, float64(0), CalculateEthereumDistributionICEBalance(0, 24*stdlibtime.Hour, 24*28*stdlibtime.Hour, now, coinDistributionEndDate))
assert.Equal(t, float64(100), CalculateEthereumDistributionICEBalance(100, 24*stdlibtime.Hour, 24*28*stdlibtime.Hour, now, coinDistributionEndDate))
Expand Down
10 changes: 6 additions & 4 deletions coin-distribution/pending_review.go
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,7 @@ func (r *repository) CollectCoinDistributionsForReview(ctx context.Context, reco
log.Warn(fmt.Sprintf("(%#v) is a duplicate of (%#v)", record, otherRecord))
}
}
const columns = 9
const columns = 10
values := make([]string, 0, len(records))
args := make([]any, 0, len(records)*columns)
ix := 0
Expand All @@ -261,18 +261,20 @@ func (r *repository) CollectCoinDistributionsForReview(ctx context.Context, reco
record.ReferredByUsername,
record.UserID,
record.EarnerUserID,
record.EthAddress)
record.EthAddress,
record.Verified)
ix++
}
sql := fmt.Sprintf(`INSERT INTO coin_distributions_by_earner(created_at,day,internal_id,balance,username,referred_by_username,user_id,earner_user_id,eth_address)
sql := fmt.Sprintf(`INSERT INTO coin_distributions_by_earner(created_at,day,internal_id,balance,username,referred_by_username,user_id,earner_user_id,eth_address,verified)
VALUES %v
ON CONFLICT (day, user_id, earner_user_id) DO UPDATE
SET
created_at = EXCLUDED.created_at,
balance = EXCLUDED.balance,
username = EXCLUDED.username,
referred_by_username = EXCLUDED.referred_by_username,
eth_address = EXCLUDED.eth_address`, strings.Join(values, ",\n"))
eth_address = EXCLUDED.eth_address,
verified = EXCLUDED.verified`, strings.Join(values, ",\n"))
_, err := storage.Exec(ctx, r.db, sql, args...)

return errors.Wrapf(err, "failed to insert into coin_distributions_by_earner [%v]", len(records))
Expand Down
20 changes: 10 additions & 10 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -22,19 +22,19 @@ require (
github.com/swaggo/swag v1.16.4
github.com/testcontainers/testcontainers-go v0.34.0
go.uber.org/zap v1.27.0
golang.org/x/exp v0.0.0-20241108190413-2d47ceb2692f
golang.org/x/exp v0.0.0-20241204233417-43b7b7cde48d
)

require (
cel.dev/expr v0.19.0 // indirect
cloud.google.com/go v0.116.0 // indirect
cloud.google.com/go/auth v0.11.0 // indirect
cloud.google.com/go/auth v0.12.0 // indirect
cloud.google.com/go/auth/oauth2adapt v0.2.6 // indirect
cloud.google.com/go/compute/metadata v0.5.2 // indirect
cloud.google.com/go/firestore v1.17.0 // indirect
cloud.google.com/go/iam v1.2.2 // indirect
cloud.google.com/go/iam v1.3.0 // indirect
cloud.google.com/go/longrunning v0.6.3 // indirect
cloud.google.com/go/monitoring v1.21.2 // indirect
cloud.google.com/go/monitoring v1.22.0 // indirect
cloud.google.com/go/storage v1.47.0 // indirect
cosmossdk.io/math v1.4.0 // indirect
dario.cat/mergo v1.0.1 // indirect
Expand Down Expand Up @@ -203,21 +203,21 @@ require (
go.uber.org/mock v0.5.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
golang.org/x/arch v0.12.0 // indirect
golang.org/x/crypto v0.29.0 // indirect
golang.org/x/crypto v0.30.0 // indirect
golang.org/x/mod v0.22.0 // indirect
golang.org/x/net v0.31.0 // indirect
golang.org/x/net v0.32.0 // indirect
golang.org/x/oauth2 v0.24.0 // indirect
golang.org/x/sync v0.10.0 // indirect
golang.org/x/sys v0.28.0 // indirect
golang.org/x/text v0.20.0 // indirect
golang.org/x/text v0.21.0 // indirect
golang.org/x/time v0.8.0 // indirect
golang.org/x/tools v0.27.0 // indirect
google.golang.org/api v0.209.0 // indirect
golang.org/x/tools v0.28.0 // indirect
google.golang.org/api v0.210.0 // indirect
google.golang.org/appengine/v2 v2.0.6 // indirect
google.golang.org/genproto v0.0.0-20241202173237-19429a94021a // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20241202173237-19429a94021a // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20241202173237-19429a94021a // indirect
google.golang.org/grpc v1.68.0 // indirect
google.golang.org/grpc v1.68.1 // indirect
google.golang.org/grpc/stats/opentelemetry v0.0.0-20241028142157-ada6787961b3 // indirect
google.golang.org/protobuf v1.35.2 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
Expand Down
Loading

0 comments on commit 128a55e

Please sign in to comment.