From e2a7d22a7cd196bcee6059a5934ee9676cd00c89 Mon Sep 17 00:00:00 2001 From: Shayan Shiravani Date: Sat, 16 Dec 2023 17:03:08 +0330 Subject: [PATCH] Move NetworkTypes to core --- authentication/models.py | 31 +++------ core/constraints.py | 14 ++-- faucet/faucet_manager/claim_manager.py | 7 +- faucet/models.py | 4 +- faucet/tasks.py | 89 +++++++++++++++++++------- prizetap/models.py | 4 +- tokenTap/helpers.py | 3 +- tokenTap/models.py | 4 +- tokenTap/tests.py | 4 +- 9 files changed, 98 insertions(+), 62 deletions(-) diff --git a/authentication/models.py b/authentication/models.py index 77c3653e..88413bc3 100644 --- a/authentication/models.py +++ b/authentication/models.py @@ -1,9 +1,11 @@ -from django.db import models from django.contrib.auth.models import User -from authentication.helpers import BRIGHTID_SOULDBOUND_INTERFACE -from django.utils import timezone -from django.core.validators import RegexValidator from django.core.cache import cache +from django.core.validators import RegexValidator +from django.db import models +from django.utils import timezone + +from authentication.helpers import BRIGHTID_SOULDBOUND_INTERFACE +from core.models import NetworkTypes class ProfileManager(models.Manager): @@ -83,22 +85,6 @@ def user_count(): return count -class NetworkTypes: - EVM = "EVM" - SOLANA = "Solana" - LIGHTNING = "Lightning" - NONEVM = "NONEVM" - NONEVMXDC = "NONEVMXDC" - - networks = ( - (EVM, "EVM"), - (SOLANA, "Solana"), - (LIGHTNING, "Lightning"), - (NONEVM, "NONEVM"), - (NONEVMXDC, "NONEVMXDC"), - ) - - class Wallet(models.Model): wallet_type = models.CharField(choices=NetworkTypes.networks, max_length=10) user_profile = models.ForeignKey( @@ -110,4 +96,7 @@ class Meta: unique_together = (("wallet_type", "user_profile"),) def __str__(self): - return f"{self.wallet_type} Wallet for profile with contextId {self.user_profile.initial_context_id}" + return ( + f"{self.wallet_type} Wallet for profile with contextId " + f"{self.user_profile.initial_context_id}" + ) diff --git a/core/constraints.py b/core/constraints.py index b85ba92a..1193ceb2 100644 --- a/core/constraints.py +++ b/core/constraints.py @@ -5,8 +5,6 @@ from django.core.exceptions import ImproperlyConfigured -from authentication.models import UserProfile - class ConstraintParam(Enum): CHAIN = "chain" @@ -25,7 +23,7 @@ class ConstraintVerification(ABC): _param_keys = [] __response_text = "" - def __init__(self, user_profile: UserProfile) -> None: + def __init__(self, user_profile) -> None: self.user_profile = user_profile self._param_values = {} @@ -61,7 +59,9 @@ def is_valid_param_keys(cls, keys): @property def response(self) -> str: - return self.__response_text or f"{self.__class__.__name__} constraint is violated" + return ( + self.__response_text or f"{self.__class__.__name__} constraint is violated" + ) @response.setter def response(self, text: str): @@ -81,7 +81,7 @@ def is_observed(self, *args, **kwargs): class HasNFTVerification(ConstraintVerification): _param_keys = [ConstraintParam.CHAIN, ConstraintParam.ADDRESS, ConstraintParam.ID] - def __init__(self, user_profile: UserProfile, response: str = None) -> None: + def __init__(self, user_profile, response: str = None) -> None: super().__init__(user_profile, response) def is_observed(self, *args, **kwargs): @@ -98,4 +98,6 @@ def get_constraint(constraint_label: str) -> ConstraintVerification: constraint_class = getattr(constraints_module, constraint_name) return constraint_class except (ModuleNotFoundError, AttributeError): - raise ImproperlyConfigured(f"Constraint '{constraint_name}' not found in any app.") + raise ImproperlyConfigured( + f"Constraint '{constraint_name}' not found in any app." + ) diff --git a/faucet/faucet_manager/claim_manager.py b/faucet/faucet_manager/claim_manager.py index d445dc07..f0ee45de 100644 --- a/faucet/faucet_manager/claim_manager.py +++ b/faucet/faucet_manager/claim_manager.py @@ -5,7 +5,8 @@ from django.db import transaction from django.utils import timezone -from authentication.models import NetworkTypes, UserProfile +from authentication.models import UserProfile +from core.models import NetworkTypes from faucet.faucet_manager.credit_strategy import ( CreditStrategy, CreditStrategyFactory, @@ -36,7 +37,9 @@ def fund_manager(self): def claim(self, amount, passive_address=None): with transaction.atomic(): - user_profile = UserProfile.objects.select_for_update().get(pk=self.credit_strategy.user_profile.pk) + user_profile = UserProfile.objects.select_for_update().get( + pk=self.credit_strategy.user_profile.pk + ) self.assert_pre_claim_conditions(amount, user_profile) return self.create_pending_claim_receipt( amount, passive_address diff --git a/faucet/models.py b/faucet/models.py index 2831a87a..61365d73 100644 --- a/faucet/models.py +++ b/faucet/models.py @@ -12,9 +12,9 @@ from solders.keypair import Keypair from solders.pubkey import Pubkey -from authentication.models import NetworkTypes, UserProfile +from authentication.models import UserProfile from brightIDfaucet.settings import BRIGHT_ID_INTERFACE -from core.models import BigNumField +from core.models import BigNumField, NetworkTypes from faucet.faucet_manager.lnpay_client import LNPayClient diff --git a/faucet/tasks.py b/faucet/tasks.py index 4ab889d4..04f29d1c 100644 --- a/faucet/tasks.py +++ b/faucet/tasks.py @@ -13,8 +13,8 @@ from django.utils import timezone from sentry_sdk import capture_exception -from authentication.models import NetworkTypes, Wallet -from core.models import TokenPrice +from authentication.models import Wallet +from core.models import NetworkTypes, TokenPrice from core.utils import Web3Utils from tokenTap.models import TokenDistributionClaim @@ -46,7 +46,9 @@ def memcache_lock(lock_id, oid, lock_expire=60): def has_pending_batch(chain): - return TransactionBatch.objects.filter(chain=chain, _status=ClaimReceipt.PENDING).exists() + return TransactionBatch.objects.filter( + chain=chain, _status=ClaimReceipt.PENDING + ).exists() def passive_address_is_not_none(address): @@ -101,10 +103,16 @@ def process_batch(self, batch_pk): manager = SolanaFundManager(batch.chain) elif batch.chain.chain_type == NetworkTypes.LIGHTNING: manager = LightningFundManager(batch.chain) - elif batch.chain.chain_type == NetworkTypes.EVM or batch.chain.chain_type == NetworkTypes.NONEVMXDC: + elif ( + batch.chain.chain_type == NetworkTypes.EVM + or batch.chain.chain_type == NetworkTypes.NONEVMXDC + ): manager = EVMFundManager(batch.chain) else: - raise Exception(f"Invalid chain type to process batch, chain type {batch.chain.chain_type}") + raise Exception( + "Invalid chain type to process batch, chain type " + f"{batch.chain.chain_type}" + ) tx_hash = manager.multi_transfer(data) batch.tx_hash = tx_hash batch.save() @@ -123,7 +131,9 @@ def process_batch(self, batch_pk): @shared_task def process_pending_batches(): - batches = TransactionBatch.objects.filter(_status=ClaimReceipt.PENDING, tx_hash=None) + batches = TransactionBatch.objects.filter( + _status=ClaimReceipt.PENDING, tx_hash=None + ) for _batch in batches: process_batch.delay(_batch.pk) @@ -148,10 +158,16 @@ def update_pending_batch_with_tx_hash(self, batch_pk): manager = SolanaFundManager(batch.chain) elif batch.chain.chain_type == NetworkTypes.LIGHTNING: manager = LightningFundManager(batch.chain) - elif batch.chain.chain_type == NetworkTypes.EVM or batch.chain.chain_type == NetworkTypes.NONEVMXDC: + elif ( + batch.chain.chain_type == NetworkTypes.EVM + or batch.chain.chain_type == NetworkTypes.NONEVMXDC + ): manager = EVMFundManager(batch.chain) else: - raise Exception(f"Invalid chain type to update pending batch, chain type {batch.chain.chain_type}") + raise Exception( + "Invalid chain type to update pending batch, chain type " + f"{batch.chain.chain_type}" + ) if manager.is_tx_verified(batch.tx_hash): batch._status = ClaimReceipt.VERIFIED @@ -174,14 +190,17 @@ def reject_expired_pending_claims(): ClaimReceipt.objects.filter( batch=None, _status=ClaimReceipt.PENDING, - datetime__lte=timezone.now() - timezone.timedelta(minutes=ClaimReceipt.MAX_PENDING_DURATION), + datetime__lte=timezone.now() + - timezone.timedelta(minutes=ClaimReceipt.MAX_PENDING_DURATION), ).update(_status=ClaimReceipt.REJECTED) @shared_task def update_pending_batches_with_tx_hash_status(): batches_queryset = ( - TransactionBatch.objects.filter(_status=ClaimReceipt.PENDING).exclude(tx_hash=None).exclude(updating=True) + TransactionBatch.objects.filter(_status=ClaimReceipt.PENDING) + .exclude(tx_hash=None) + .exclude(updating=True) ) for _batch in batches_queryset: update_pending_batch_with_tx_hash.delay(_batch.pk) @@ -190,7 +209,9 @@ def update_pending_batches_with_tx_hash_status(): @shared_task def process_chain_pending_claims(chain_id): # locks chain with transaction.atomic(): - chain = Chain.objects.select_for_update().get(pk=chain_id) # lock based on chain + chain = Chain.objects.select_for_update().get( + pk=chain_id + ) # lock based on chain # all pending batches must be resolved before new transactions can be made if has_pending_batch(chain): @@ -198,7 +219,9 @@ def process_chain_pending_claims(chain_id): # locks chain # get all pending receipts for this chain # pending receipts are receipts that have not been batched yet - receipts = ClaimReceipt.objects.filter(chain=chain, _status=ClaimReceipt.PENDING, batch=None) + receipts = ClaimReceipt.objects.filter( + chain=chain, _status=ClaimReceipt.PENDING, batch=None + ) if receipts.count() == 0: return @@ -334,30 +357,39 @@ def update_tokens_price(): update token.usd_price for all TokenPrice records in DB """ - # TODO: we can make this function performance better by using aiohttp and asyncio or Threads + # TODO: we can make this function performance better + # by using aiohttp and asyncio or Threads tokens = TokenPrice.objects.exclude(price_url__isnull=True).exclude(price_url="") - res_gen = map(lambda token: (token, requests.get(token.price_url, timeout=5)), tokens) + res_gen = map( + lambda token: (token, requests.get(token.price_url, timeout=5)), tokens + ) def parse_request(token: TokenPrice, request_res: requests.Response): try: request_res.raise_for_status() json_data = request_res.json() token.usd_price = json_data["data"]["rates"]["USD"] - # TODO: save all change when this function ended for all url done for better performance + # TODO: save all change when this function ended for + # all url done for better performance token.save() except requests.HTTPError as e: logging.exception( - f"requests for url: {request_res.url} can not fetched with status_code: {request_res.status_code}. \ + f"requests for url: {request_res.url} can not fetched with " + f"status_code: {request_res.status_code}. \ {str(e)}" ) except KeyError as e: logging.exception( - f"requests for url: {request_res.url} data do not have property keys for loading data. {str(e)}" + f"requests for url: {request_res.url} data do not have property " + f"keys for loading data. {str(e)}" ) except Exception as e: - logging.exception(f"requests for url: {request_res.url} got error {type(e).__name__}. {str(e)}") + logging.exception( + f"requests for url: {request_res.url} got error " + f"{type(e).__name__}. {str(e)}" + ) [parse_request(*res) for res in res_gen] @@ -383,18 +415,27 @@ def process_donation_receipt(self, donation_receipt_pk): ).values_list("lower_address", flat=True): donation_receipt.delete() return - if Web3Utils.to_checksum_address(tx.get("to")) != evm_fund_manager.get_fund_manager_checksum_address(): + if ( + Web3Utils.to_checksum_address(tx.get("to")) + != evm_fund_manager.get_fund_manager_checksum_address() + ): donation_receipt.delete() return donation_receipt.value = str(evm_fund_manager.from_wei(tx.get("value"))) if donation_receipt.chain.is_testnet is False: try: - token_price = TokenPrice.objects.get(symbol=donation_receipt.chain.symbol) + token_price = TokenPrice.objects.get( + symbol=donation_receipt.chain.symbol + ) donation_receipt.total_price = str( - decimal.Decimal(donation_receipt.value) * decimal.Decimal(token_price.usd_price) + decimal.Decimal(donation_receipt.value) + * decimal.Decimal(token_price.usd_price) ) except TokenPrice.DoesNotExist: - logging.error(f"TokenPrice for Chain: {donation_receipt.chain.chain_name} did not defined") + logging.error( + f"TokenPrice for Chain: {donation_receipt.chain.chain_name} " + "did not defined" + ) donation_receipt.status = ClaimReceipt.REJECTED donation_receipt.save() return @@ -412,6 +453,8 @@ def update_donation_receipt_pending_status(): """ update status of pending donation receipt """ - pending_donation_receipts = DonationReceipt.objects.filter(status=ClaimReceipt.PENDING) + pending_donation_receipts = DonationReceipt.objects.filter( + status=ClaimReceipt.PENDING + ) for pending_donation_receipt in pending_donation_receipts: process_donation_receipt.delay(pending_donation_receipt.pk) diff --git a/prizetap/models.py b/prizetap/models.py index 9d39fa16..763a180b 100644 --- a/prizetap/models.py +++ b/prizetap/models.py @@ -3,8 +3,8 @@ from django.utils import timezone from django.utils.translation import gettext_lazy as _ -from authentication.models import NetworkTypes, UserProfile -from core.models import BigNumField, Chain, UserConstraint +from authentication.models import UserProfile +from core.models import BigNumField, Chain, NetworkTypes, UserConstraint from faucet.constraints import OptimismClaimingGasConstraint, OptimismDonationConstraint from .constraints import HaveUnitapPass, NotHaveUnitapPass diff --git a/tokenTap/helpers.py b/tokenTap/helpers.py index 132e5e05..5736268c 100644 --- a/tokenTap/helpers.py +++ b/tokenTap/helpers.py @@ -3,8 +3,7 @@ from eth_account.messages import encode_defunct from web3 import Account, Web3 -from authentication.models import NetworkTypes -from core.models import WalletAccount +from core.models import NetworkTypes, WalletAccount from faucet.faucet_manager.credit_strategy import RoundCreditStrategy from faucet.models import GlobalSettings diff --git a/tokenTap/models.py b/tokenTap/models.py index 7541e889..ffca4e3b 100644 --- a/tokenTap/models.py +++ b/tokenTap/models.py @@ -2,8 +2,8 @@ from django.db import models from django.utils import timezone -from authentication.models import NetworkTypes, UserProfile -from core.models import Chain, UserConstraint +from authentication.models import UserProfile +from core.models import Chain, NetworkTypes, UserConstraint from faucet.constraints import OptimismHasClaimedGasInThisRound from faucet.models import ClaimReceipt diff --git a/tokenTap/tests.py b/tokenTap/tests.py index 35a66efa..69d41f53 100644 --- a/tokenTap/tests.py +++ b/tokenTap/tests.py @@ -6,8 +6,8 @@ from django.utils import timezone from rest_framework.test import APITestCase, override_settings -from authentication.models import NetworkTypes, UserProfile, Wallet -from core.models import Chain, WalletAccount +from authentication.models import UserProfile, Wallet +from core.models import Chain, NetworkTypes, WalletAccount from faucet.models import Chain as FaucetChain from faucet.models import ClaimReceipt, GlobalSettings, TransactionBatch from faucet.models import WalletAccount as FaucetWalletAccount