Skip to content

Commit

Permalink
feat(docs): document _loaders.token_transfer (#121)
Browse files Browse the repository at this point in the history
  • Loading branch information
BobTheBuidler authored Nov 9, 2024
1 parent 79a35ae commit be68cba
Showing 1 changed file with 53 additions and 0 deletions.
53 changes: 53 additions & 0 deletions eth_portfolio/_loaders/token_transfer.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
"""
This module orchestrates the process of loading and processing token transfers within the eth_portfolio ecosystem.
"""

import decimal
import logging
from typing import Optional
Expand Down Expand Up @@ -25,12 +29,35 @@
token_transfer_semaphore = dank_mids.BlockSemaphore(
10_000, name="eth_portfolio.token_transfers"
) # Some arbitrary number
"""A semaphore that regulates the concurrent processing of token transfers by processing lower blocks first."""


@stuck_coro_debugger
async def load_token_transfer(
transfer_log: "Log", load_prices: bool
) -> Optional[TokenTransfer]: # sourcery skip: simplify-boolean-comparison
"""
Processes and loads a token transfer from a log entry, with comprehensive error handling and optional price fetching.
This function employs a multi-step process:
1. Validates the transfer against a known set of 'shitcoins', skipping processing if matched.
2. Checks for existing database entries, potentially deleting and reprocessing if price data is requested but missing.
3. Decodes the transfer log and retrieves associated metadata (e.g., token scale, symbol, transaction index).
4. Optionally fetches the token price at the time of the transaction.
5. Constructs and persists a :class:`~eth_portfolio.structs.TokenTransfer` object in the database.
The function handles various exceptions, including :class:`~y.exceptions.NonStandardERC20` for non-compliant tokens and :class:`decimal.InvalidOperation` for extreme :class:`~Decimal` values.
Args:
transfer_log: A dictionary containing the raw log entry of the token transfer.
load_prices: A flag indicating whether to fetch and include price data for the token at the time of transfer.
Returns:
A processed TokenTransfer object if successful, or None if the transfer cannot be processed due to various constraints or errors.
Note:
This function employs caching mechanisms and database operations to optimize performance.
"""
if transfer_log.removed:
if transfer := await db.get_token_transfer(transfer_log):
await db.delete_token_transfer(transfer)
Expand Down Expand Up @@ -105,6 +132,19 @@ async def _insert_to_db(transfer: TokenTransfer, load_prices: bool) -> None:

@stuck_coro_debugger
async def get_symbol(token: ERC20) -> Optional[str]:
"""
Retrieves the symbol of a given ERC20 token, with error handling for non-standard implementations.
This function attempts to access the token's symbol through the standard ERC20 symbol method. If the token contract
does not adhere to the standard ERC20 interface, indicated by a :class:`~y.exceptions.NonStandardERC20` exception, the function
returns `None` instead of propagating the error.
Args:
token: An ERC20 token object representing the token whose symbol is to be retrieved.
Returns:
The token's symbol as a string if successfully retrieved, or None if the token does not implement a standard symbol method.
"""
try:
return await token.__symbol__
except NonStandardERC20:
Expand All @@ -114,6 +154,19 @@ async def get_symbol(token: ERC20) -> Optional[str]:
@stuck_coro_debugger
@cache_to_disk
async def get_transaction_index(hash: str) -> int:
"""
Retrieves the transaction index for a given transaction hash, with results cached to disk.
This function fetches the transaction receipt corresponding to the provided hash and extracts the transaction index,
which represents the position of the transaction within its containing block. The result is cached to disk to
optimize performance for future runs.
Args:
hash: The hexadecimal string representation of the transaction hash.
Returns:
The zero-based index of the transaction within its block.
"""
receipt_bytes = await get_transaction_receipt(hash)
return msgspec.json.decode(
receipt_bytes, type=HasTxIndex, dec_hook=TransactionIndex._decode_hook
Expand Down

0 comments on commit be68cba

Please sign in to comment.