From f86fad6e2a365ccf753d8ea98100092a7918afde Mon Sep 17 00:00:00 2001 From: nessshon Date: Thu, 13 Jun 2024 19:01:31 +0500 Subject: [PATCH] Refactor: Improve handling of token holder checks to reduce potential errors. --- app/scheduler/tasks/check_chats_members.py | 12 +++++++++++ app/scheduler/tasks/update_token_holders.py | 23 ++++++++++++++++++++- 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/app/scheduler/tasks/check_chats_members.py b/app/scheduler/tasks/check_chats_members.py index 24f345b..7192c03 100644 --- a/app/scheduler/tasks/check_chats_members.py +++ b/app/scheduler/tasks/check_chats_members.py @@ -41,6 +41,10 @@ async def process_and_kick_members( ) for member in members: + if is_any_empty_token_holders(tokens): + logging.warning(f"Skipping check members for {chat.name} because of empty token holders!") + break + if await user_is_holder(member.user, tokens): continue @@ -55,6 +59,14 @@ async def process_and_kick_members( logging.error(e) +def is_any_empty_token_holders(tokens: Sequence[TokenDB]) -> bool: + for token in tokens: + if not token.holders: + logging.warning(f"Found empty token holders on {token.name} [{token.address}]!") + return True + return False + + async def send_notification_to_chat(bot: Bot, chat: ChatDB, user: UserDB) -> None: user_link = hlink( title=user.full_name, diff --git a/app/scheduler/tasks/update_token_holders.py b/app/scheduler/tasks/update_token_holders.py index c0c27f1..7067959 100644 --- a/app/scheduler/tasks/update_token_holders.py +++ b/app/scheduler/tasks/update_token_holders.py @@ -1,7 +1,9 @@ import asyncio +import logging from aiogram import Bot from pytonapi import AsyncTonapi +from pytonapi.exceptions import TONAPIInternalServerError from pytonapi.utils import nano_to_amount from sqlalchemy.ext.asyncio import async_sessionmaker @@ -20,22 +22,41 @@ async def update_token_holders() -> None: tokens = await TokenDB.all(sessionmaker) for token in tokens: holders = {} + try: if token.type == TokenDB.Type.NFTCollection: request = await tonapi.nft.get_all_items_by_collection_address(account_id=token.address) + collection = await tonapi.nft.get_collection_by_collection_address(account_id=token.address) + total_holders, found_holders = collection.next_item_index, 0 + for nft in request.nft_items: if nft.owner.address.to_raw() in holders: holders[nft.owner.address.to_raw()] += 1 else: holders[nft.owner.address.to_raw()] = 1 + found_holders += 1 + else: request = await tonapi.jettons.get_all_holders(account_id=token.address) + total_holders, found_holders = request.total, 0 + for address in request.addresses: holders[address.owner.address.to_raw()] = nano_to_amount(int(address.balance), 9) + found_holders += 1 + + except TONAPIInternalServerError as e: + logging.error(f"{e.__class__.__name__}: {e}") + logging.error(f"Failed to update holders for {token.name} [{token.address}]") + continue except Exception as e: await send_message(bot, config.bot.DEV_ID, text=f"{e.__class__.__name__}: {e}") + logging.error(f"{e.__class__.__name__}: {e}") + logging.error(f"Failed to update holders for {token.name} [{token.address}]") continue - if holders: + if holders and total_holders == found_holders: await TokenDB.update(sessionmaker, primary_key=token.id, holders=holders) + else: + logging.error(f"Failed to update holders for {token.name} [{token.address}]") + logging.error(f"Found holders: {found_holders}, Total Holders: {total_holders}")