def fix_uniswap_pool_tokens_task() -> Optional[int]: ethereum_client = EthereumClientProvider() ethereum_network = ethereum_client.get_network() if ethereum_network == EthereumNetwork.MAINNET: try: number = Token.objects.fix_uniswap_pool_tokens() if number: logger.info('%d uniswap pool token names were fixed', number) return number finally: close_gevent_db_connection()
def send_notification_task(address: Optional[str], payload: Dict[str, Any]) -> Tuple[int, int]: """ :param address: :param payload: :return: Tuple with the number of successful and failed notifications sent """ if not (address and payload): # Both must be present return 0, 0 try: firebase_devices = FirebaseDevice.objects.filter( safes__address=address).exclude( cloud_messaging_token=None) # TODO Use cache tokens = [ firebase_device.cloud_messaging_token for firebase_device in firebase_devices ] if is_pending_multisig_transaction(payload): send_notification_owner_task.delay(address, payload['safeTxHash']) if not (tokens and filter_notification(payload)): return 0, 0 # Make sure notification has not been sent before duplicate_notification = DuplicateNotification(address, payload) if duplicate_notification.is_duplicated(): logger.info( 'Duplicated notification about Safe=%s with payload=%s to tokens=%s', address, payload, tokens) return 0, 0 duplicate_notification.set_duplicated() with FirebaseClientPool() as firebase_client: logger.info( 'Sending notification about Safe=%s with payload=%s to tokens=%s', address, payload, tokens) success_count, failure_count, invalid_tokens = firebase_client.send_message( tokens, payload) if invalid_tokens: logger.info('Removing invalid tokens for safe=%s. Tokens=%s', address, invalid_tokens) FirebaseDevice.objects.filter( cloud_messaging_token__in=invalid_tokens).update( cloud_messaging_token=None) return success_count, failure_count finally: close_gevent_db_connection()
def fix_pool_tokens_task() -> Optional[int]: """ Fix names for generic pool tokens, like Balancer or Uniswap :return: Number of pool token names updated """ ethereum_client = EthereumClientProvider() ethereum_network = ethereum_client.get_network() if ethereum_network == EthereumNetwork.MAINNET: try: number = Token.pool_tokens.fix_all_pool_tokens() if number: logger.info('%d pool token names were fixed', number) return number finally: close_gevent_db_connection()
def send_notification_owner_task(address: str, safe_tx_hash: str): """ Send a confirmation request to an owner :param address: Safe address :param safe_tx_hash: Hash of the safe tx :return: Tuple with the number of successful and failed notifications sent """ assert safe_tx_hash, 'Safe tx hash was not provided' try: confirmed_owners = MultisigConfirmation.objects.filter( multisig_transaction_id=safe_tx_hash).values_list('owner', flat=True) safe_status = SafeStatus.objects.last_for_address(address) if not safe_status: logger.info('Cannot find threshold information for safe=%s', address) return 0, 0 if safe_status.threshold <= len(confirmed_owners): # No need for more confirmations logger.info( 'Multisig transaction with safe-tx-hash=%s for safe=%s does not require more confirmations', safe_tx_hash, address) return 0, 0 # Get cloud messaging token for missing owners owners_to_notify = set(safe_status.owners) - set(confirmed_owners) tokens = list( FirebaseDeviceOwner.objects.filter( owner__in=owners_to_notify).values_list( 'firebase_device__cloud_messaging_token', flat=True)) if not tokens: logger.info( 'No cloud messaging tokens found for needed owners %s to sign safe-tx-hash=%s for safe=%s', owners_to_notify, safe_tx_hash, address) return 0, 0 payload = { 'type': WebHookType.CONFIRMATION_REQUEST.name, 'address': address, 'safeTxHash': safe_tx_hash, } # Make sure notification has not been sent before duplicate_notification = DuplicateNotification(address, payload) if duplicate_notification.is_duplicated(): logger.info( 'Duplicated notification about Safe=%s with payload=%s to tokens=%s', address, payload, tokens) return 0, 0 duplicate_notification.set_duplicated() with FirebaseClientPool() as firebase_client: logger.info( 'Sending notification about Safe=%s with payload=%s to tokens=%s', address, payload, tokens) success_count, failure_count, invalid_tokens = firebase_client.send_message( tokens, payload) if invalid_tokens: logger.info('Removing invalid tokens for safe=%s', address) FirebaseDevice.objects.filter( cloud_messaging_token__in=invalid_tokens).update( cloud_messaging_token=None) return success_count, failure_count finally: close_gevent_db_connection()
from gnosis.eth import EthereumClientProvider from safe_transaction_service.history.utils import close_gevent_db_connection from .models import Contract logger = get_task_logger(__name__) @app.shared_task() def index_contracts_metadata_task(addresses: Sequence[str]): ethereum_client = EthereumClientProvider() ethereum_network = ethereum_client.get_network() try: for address in addresses: try: with transaction.atomic(): if contract := Contract.objects.create_from_address( address, network_id=ethereum_network.value): logger.info( 'Indexed contract with address=%s name=%s abi-present=%s', address, contract.name, bool(contract.contract_abi.abi)) else: Contract.objects.create(address=address) except IntegrityError: logger.warning('Contract with address=%s was already created', address) finally: close_gevent_db_connection()