Skip to content

Commit

Permalink
(feat) Improved markets and tokens parsing to ensure there are no dup…
Browse files Browse the repository at this point in the history
…licates
  • Loading branch information
abel committed Nov 22, 2023
1 parent c57e1ce commit f5d44a5
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 40 deletions.
81 changes: 43 additions & 38 deletions pyinjective/async_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,17 +120,18 @@ def __init__(
self._initialize_timeout_height_sync_task()

self._tokens_and_markets_initialization_lock = asyncio.Lock()
self._tokens: Optional[Dict[str, Token]] = None
self._tokens_by_denom: Optional[Dict[str, Token]] = None
self._tokens_by_symbol: Optional[Dict[str, Token]] = None
self._spot_markets: Optional[Dict[str, SpotMarket]] = None
self._derivative_markets: Optional[Dict[str, DerivativeMarket]] = None
self._binary_option_markets: Optional[Dict[str, BinaryOptionMarket]] = None

async def all_tokens(self) -> Dict[str, Token]:
if self._tokens is None:
if self._tokens_by_symbol is None:
async with self._tokens_and_markets_initialization_lock:
if self._tokens is None:
if self._tokens_by_symbol is None:
await self._initialize_tokens_and_markets()
return deepcopy(self._tokens)
return deepcopy(self._tokens_by_symbol)

async def all_spot_markets(self) -> Dict[str, SpotMarket]:
if self._spot_markets is None:
Expand Down Expand Up @@ -968,7 +969,7 @@ async def _initialize_tokens_and_markets(self):
spot_markets = dict()
derivative_markets = dict()
binary_option_markets = dict()
tokens = dict()
tokens_by_symbol = dict()
tokens_by_denom = dict()
markets_info = (await self.get_spot_markets(market_status="active")).markets
valid_markets = (
Expand All @@ -989,19 +990,16 @@ async def _initialize_tokens_and_markets(self):
symbol=base_token_symbol,
token_meta=market_info.base_token_meta,
denom=market_info.base_denom,
all_tokens=tokens,
tokens_by_denom=tokens_by_denom,
tokens_by_symbol=tokens_by_symbol,
)
if base_token.denom not in tokens_by_denom:
tokens_by_denom[base_token.denom] = base_token

quote_token = self._token_representation(
symbol=quote_token_symbol,
token_meta=market_info.quote_token_meta,
denom=market_info.quote_denom,
all_tokens=tokens,
tokens_by_denom=tokens_by_denom,
tokens_by_symbol=tokens_by_symbol,
)
if quote_token.denom not in tokens_by_denom:
tokens_by_denom[quote_token.denom] = quote_token

market = SpotMarket(
id=market_info.market_id,
Expand Down Expand Up @@ -1029,10 +1027,9 @@ async def _initialize_tokens_and_markets(self):
symbol=quote_token_symbol,
token_meta=market_info.quote_token_meta,
denom=market_info.quote_denom,
all_tokens=tokens,
tokens_by_denom=tokens_by_denom,
tokens_by_symbol=tokens_by_symbol,
)
if quote_token.denom not in tokens_by_denom:
tokens_by_denom[quote_token.denom] = quote_token

market = DerivativeMarket(
id=market_info.market_id,
Expand Down Expand Up @@ -1078,33 +1075,41 @@ async def _initialize_tokens_and_markets(self):

binary_option_markets[market.id] = market

self._tokens = tokens
self._tokens_by_denom = tokens_by_denom
self._tokens_by_symbol = tokens_by_symbol
self._spot_markets = spot_markets
self._derivative_markets = derivative_markets
self._binary_option_markets = binary_option_markets

def _token_representation(self, symbol: str, token_meta, denom: str, all_tokens: Dict[str, Token]) -> Token:
token = Token(
name=token_meta.name,
symbol=symbol,
denom=denom,
address=token_meta.address,
decimals=token_meta.decimals,
logo=token_meta.logo,
updated=token_meta.updated_at,
)

existing_token = all_tokens.get(token.symbol, None)
if existing_token is None:
all_tokens[token.symbol] = token
existing_token = token
elif existing_token.denom != denom:
existing_token = all_tokens.get(token.name, None)
if existing_token is None:
all_tokens[token.name] = token
existing_token = token

return existing_token
def _token_representation(
self,
symbol: str,
token_meta,
denom: str,
tokens_by_denom: Dict[str, Token],
tokens_by_symbol: Dict[str, Token],
) -> Token:
if denom not in tokens_by_denom:
unique_symbol = denom
for symbol_candidate in [symbol, token_meta.symbol, token_meta.name]:
if symbol_candidate not in tokens_by_symbol:
unique_symbol = symbol_candidate
break

token = Token(
name=token_meta.name,
symbol=symbol,
denom=denom,
address=token_meta.address,
decimals=token_meta.decimals,
logo=token_meta.logo,
updated=token_meta.updated_at,
)

tokens_by_denom[denom] = token
tokens_by_symbol[unique_symbol] = token

return tokens_by_denom[denom]

def _chain_cookie_metadata_requestor(self) -> Coroutine:
request = tendermint_query.GetLatestBlockRequest()
Expand Down
2 changes: 1 addition & 1 deletion tests/model_fixtures/markets_fixtures.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ def inj_token():
token = Token(
name="Injective Protocol",
symbol="INJ",
denom="peggy0x44C21afAaF20c270EBbF5914Cfc3b5022173FEB7",
denom="inj",
address="0xe28b3B32B6c345A34Ff64674606124Dd5Aceca30",
decimals=18,
logo="https://static.alchemyapi.io/images/assets/7226.png",
Expand Down
2 changes: 1 addition & 1 deletion tests/rpc_fixtures/markets_fixtures.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ def inj_usdt_spot_market_meta(inj_token_meta, usdt_token_meta):
market_id="0x7a57e705bb4e09c88aecfc295569481dbf2fe1d5efe364651fbe72385938e9b0",
market_status="active",
ticker="INJ/USDT",
base_denom="peggy0x44C21afAaF20c270EBbF5914Cfc3b5022173FEB7",
base_denom="inj",
base_token_meta=inj_token_meta,
quote_denom="peggy0x87aB3B4C8661e07D6372361211B96ed4Dc36B1B5",
quote_token_meta=usdt_token_meta,
Expand Down

0 comments on commit f5d44a5

Please sign in to comment.