From ec7aac2e00e5e91bc9e73d938533cdfcfbfb8802 Mon Sep 17 00:00:00 2001 From: Reckless_Satoshi Date: Sat, 5 Mar 2022 12:51:16 -0800 Subject: [PATCH] Implement give rewards scheduler --- api/logics.py | 25 +++++++++++++++++-------- api/tasks.py | 22 ++++++++++++++++++++++ robosats/celery/__init__.py | 8 ++++++-- 3 files changed, 45 insertions(+), 10 deletions(-) diff --git a/api/logics.py b/api/logics.py index 7d43a92a..2356551a 100644 --- a/api/logics.py +++ b/api/logics.py @@ -384,8 +384,10 @@ class Logics: fee_sats = order.last_satoshis * fee_fraction + reward_tip = int(config('REWARD_TIP')) if user.profile.is_referred else 0 + if cls.is_buyer(order, user): - invoice_amount = round(order.last_satoshis - fee_sats) # Trading fee to buyer is charged here. + invoice_amount = round(order.last_satoshis - fee_sats - reward_tip) # Trading fee to buyer is charged here. return True, {"invoice_amount": invoice_amount} @@ -399,10 +401,12 @@ class Logics: elif user == order.taker: fee_fraction = FEE * (1 - MAKER_FEE_SPLIT) - fee_sats = order.last_satoshis * fee_fraction + fee_sats = order.last_satoshis * fee_fraction + + reward_tip = int(config('REWARD_TIP')) if user.profile.is_referred else 0 if cls.is_seller(order, user): - escrow_amount = round(order.last_satoshis + fee_sats) # Trading fee to seller is charged here. + escrow_amount = round(order.last_satoshis + fee_sats + reward_tip) # Trading fee to seller is charged here. return True, {"escrow_amount": escrow_amount} @@ -1092,14 +1096,19 @@ class Logics: @classmethod def add_rewards(cls, order): ''' - This order is called after a trade is finished. - If order participants were referred, we add the reward to the referees. + This function is called when a trade is finished. + If participants of the order were referred, the reward is given to the referees. ''' - + if order.maker.profile.is_referred: - order.maker.profile.referred_by.pending_rewards += int(config('REWARD_TIP')) + profile = order.maker.profile.referred_by + profile.pending_rewards += int(config('REWARD_TIP')) + profile.save() + if order.taker.profile.is_referred: - order.taker.profile.referred_by.pending_rewards += int(config('REWARD_TIP')) + profile = order.taker.profile.referred_by + profile.pending_rewards += int(config('REWARD_TIP')) + profile.save() return diff --git a/api/tasks.py b/api/tasks.py index 6e22aa2d..8decf569 100644 --- a/api/tasks.py +++ b/api/tasks.py @@ -35,6 +35,28 @@ def users_cleansing(): } return results +@shared_task(name="give_rewards") +def users_cleansing(): + """ + Referral rewards go from pending to earned. + Happens asynchronously so the referral program cannot be easily used to spy. + """ + from api.models import Profile + + # Users who's last login has not been in the last 6 hours + queryset = Profile.objects.filter(pending_rewards__gt=0) + + # And do not have an active trade, any past contract or any reward. + results = {} + for profile in queryset: + given_reward = profile.pending_rewards + profile.earned_rewards += given_reward + profile.pending_rewards = 0 + profile.save() + + results[profile.user.username] = {'given_reward':given_reward,'earned_rewards':profile.earned_rewards} + + return results @shared_task(name="follow_send_payment") def follow_send_payment(lnpayment): diff --git a/robosats/celery/__init__.py b/robosats/celery/__init__.py index e3e730ec..b059b0d8 100644 --- a/robosats/celery/__init__.py +++ b/robosats/celery/__init__.py @@ -31,9 +31,13 @@ app.conf.beat_scheduler = "django_celery_beat.schedulers:DatabaseScheduler" # Configure the periodic tasks app.conf.beat_schedule = { - "users-cleansing": { # Cleans abandoned users every 6 hours + "users-cleansing": { # Cleans abandoned users at midnight "task": "users_cleansing", - "schedule": timedelta(hours=6), + "schedule": crontab(hour=0, minute=0), + }, + "give-rewards": { # Referral rewards go from 'pending' to 'earned' at midnight + "task": "give_rewards", + "schedule": crontab(hour=0, minute=0), }, "cache-market-prices": { # Cache market prices every minutes for now. "task": "cache_external_market_prices",