From 2ab81936602a45721a548a1c73297b07f5f26c79 Mon Sep 17 00:00:00 2001 From: Victor Baranov Date: Thu, 24 Dec 2020 11:33:16 +0300 Subject: [PATCH 1/3] Improve speed od loading of tokens dropdown at owner address page --- CHANGELOG.md | 1 + .../address_token_balance_controller.ex | 19 ++++++++---- .../chain/cache/token_exchange_rate.ex | 30 +++++++++++-------- .../lib/explorer/chain/supply/token_bridge.ex | 14 +++++---- apps/explorer/lib/explorer/counters/bridge.ex | 6 ++-- apps/explorer/lib/explorer/market/market.ex | 4 +-- 6 files changed, 46 insertions(+), 28 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 98d4b2b441..283881e628 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ - [#3462](https://github.com/poanetwork/blockscout/pull/3462) - Display price for bridged tokens ### Fixes +- [#3535](https://github.com/poanetwork/blockscout/pull/3535) - Improve speed of tokens dropdown loading at owner address page - [#3530](https://github.com/poanetwork/blockscout/pull/3530) - Allow trailing/leading whitespaces for inputs for contract read methods - [#3526](https://github.com/poanetwork/blockscout/pull/3526) - Order staking pools - [#3525](https://github.com/poanetwork/blockscout/pull/3525), [#3533](https://github.com/poanetwork/blockscout/pull/3533) - Address token balance on demand fetcher diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/address_token_balance_controller.ex b/apps/block_scout_web/lib/block_scout_web/controllers/address_token_balance_controller.ex index 4ba7e84cbf..dc28b01a23 100644 --- a/apps/block_scout_web/lib/block_scout_web/controllers/address_token_balance_controller.ex +++ b/apps/block_scout_web/lib/block_scout_web/controllers/address_token_balance_controller.ex @@ -12,7 +12,6 @@ defmodule BlockScoutWeb.AddressTokenBalanceController do token_balances = address_hash |> Chain.fetch_last_token_balances() - |> Market.add_price() Task.start_link(fn -> TokenBalanceOnDemand.trigger_fetch(address_hash, token_balances) @@ -20,15 +19,25 @@ defmodule BlockScoutWeb.AddressTokenBalanceController do circles_addresses_list = CustomContractsHelpers.get_custom_addresses_list(:circles_addresses) + token_balances_with_price = + token_balances + |> Market.add_price() + + token_balances_except_bridged = + token_balances + |> Enum.filter(fn token_balance -> !token_balance.token.bridged end) + circles_total_balance = if Enum.count(circles_addresses_list) > 0 do - token_balances + token_balances_except_bridged |> Enum.reduce(Decimal.new(0), fn token_balance, acc_balance -> {:ok, token_address} = Chain.hash_to_address(token_balance.address_hash) + from_address = from_address_hash(token_address) + created_from_address_hash = - if from_address_hash(token_address), - do: "0x" <> Base.encode16(from_address_hash(token_address).bytes, case: :lower), + if from_address, + do: "0x" <> Base.encode16(from_address.bytes, case: :lower), else: nil if Enum.member?(circles_addresses_list, created_from_address_hash) && token_balance.token.name == "Circles" && @@ -49,7 +58,7 @@ defmodule BlockScoutWeb.AddressTokenBalanceController do |> put_layout(false) |> render("_token_balances.html", address_hash: address_hash, - token_balances: token_balances, + token_balances: token_balances_with_price, circles_total_balance: circles_total_balance ) diff --git a/apps/explorer/lib/explorer/chain/cache/token_exchange_rate.ex b/apps/explorer/lib/explorer/chain/cache/token_exchange_rate.ex index e1295151b4..0afc6988a7 100644 --- a/apps/explorer/lib/explorer/chain/cache/token_exchange_rate.ex +++ b/apps/explorer/lib/explorer/chain/cache/token_exchange_rate.ex @@ -47,24 +47,28 @@ defmodule Explorer.Chain.Cache.TokenExchangeRate do {:noreply, state} end - def cache_key(symbol) do - "token_symbol_exchange_rate_#{symbol}" + def cache_key(symbol, address_hash) do + "token_symbol_exchange_rate_#{symbol}_#{address_hash_str_key(address_hash)}" end - def fetch(symbol) do - if cache_expired?(symbol) || value_is_empty?(symbol) do + defp address_hash_str_key(address_hash) do + Base.encode16(address_hash.bytes, case: :lower) + end + + def fetch(symbol, address_hash) do + if cache_expired?(symbol, address_hash) || value_is_empty?(symbol, address_hash) do Task.start_link(fn -> - update_cache(symbol) + update_cache(symbol, address_hash) end) end - fetch_from_cache(cache_key(symbol)) + fetch_from_cache(cache_key(symbol, address_hash)) end def cache_name, do: @cache_name - defp cache_expired?(symbol) do - updated_at = fetch_from_cache("#{cache_key(symbol)}_#{@last_update_key}") + defp cache_expired?(symbol, address_hash) do + updated_at = fetch_from_cache("#{cache_key(symbol, address_hash)}_#{@last_update_key}") cond do is_nil(updated_at) -> true @@ -73,17 +77,17 @@ defmodule Explorer.Chain.Cache.TokenExchangeRate do end end - defp value_is_empty?(symbol) do - value = fetch_from_cache(cache_key(symbol)) + defp value_is_empty?(symbol, address_hash) do + value = fetch_from_cache(cache_key(symbol, address_hash)) is_nil(value) || value == 0 end - defp update_cache(symbol) do - put_into_cache("#{cache_key(symbol)}_#{@last_update_key}", current_time()) + defp update_cache(symbol, address_hash) do + put_into_cache("#{cache_key(symbol, address_hash)}_#{@last_update_key}", current_time()) exchange_rate = fetch_token_exchange_rate(symbol) - put_into_cache(cache_key(symbol), exchange_rate) + put_into_cache(cache_key(symbol, address_hash), exchange_rate) end def fetch_token_exchange_rate(symbol) do diff --git a/apps/explorer/lib/explorer/chain/supply/token_bridge.ex b/apps/explorer/lib/explorer/chain/supply/token_bridge.ex index 1b03e60228..ff1634c728 100644 --- a/apps/explorer/lib/explorer/chain/supply/token_bridge.ex +++ b/apps/explorer/lib/explorer/chain/supply/token_bridge.ex @@ -194,12 +194,14 @@ defmodule Explorer.Chain.Supply.TokenBridge do omni_bridge_market_cap end - def get_current_price_for_bridged_token(symbol) when is_nil(symbol), do: nil + def get_current_price_for_bridged_token(symbol, _address_hash) when is_nil(symbol), do: nil - def get_current_price_for_bridged_token(symbol) do + def get_current_price_for_bridged_token(_symbol, address_hash) when is_nil(address_hash), do: nil + + def get_current_price_for_bridged_token(symbol, address_hash) do bridged_token_symbol_for_price_fetching = bridged_token_symbol_mapping_to_get_price(symbol) - TokenExchangeRateCache.fetch(bridged_token_symbol_for_price_fetching) + TokenExchangeRateCache.fetch(bridged_token_symbol_for_price_fetching, address_hash) end def get_bridged_mainnet_tokens_list do @@ -219,9 +221,11 @@ defmodule Explorer.Chain.Supply.TokenBridge do bridged_mainnet_tokens_with_supply = bridged_mainnet_tokens_list |> Enum.map(fn {bridged_token_hash, bridged_token_symbol} -> + bridged_token_price_from_cache = TokenExchangeRateCache.fetch(bridged_token_symbol, bridged_token_hash) + bridged_token_price = - if TokenExchangeRateCache.fetch(bridged_token_symbol) > 0 do - TokenExchangeRateCache.fetch(bridged_token_symbol) + if bridged_token_price_from_cache > 0 do + bridged_token_price_from_cache else TokenExchangeRateCache.fetch_token_exchange_rate(bridged_token_symbol) end diff --git a/apps/explorer/lib/explorer/counters/bridge.ex b/apps/explorer/lib/explorer/counters/bridge.ex index 0309369eec..1d0221b3cb 100644 --- a/apps/explorer/lib/explorer/counters/bridge.ex +++ b/apps/explorer/lib/explorer/counters/bridge.ex @@ -161,9 +161,9 @@ defmodule Explorer.Counters.Bridge do bridged_mainnet_tokens_list = TokenBridge.get_bridged_mainnet_tokens_list() bridged_mainnet_tokens_list - |> Enum.each(fn {_bridged_token_hash, bridged_token_symbol} -> - bridged_token_price = TokenBridge.get_current_price_for_bridged_token(bridged_token_symbol) - cache_key = TokenExchangeRate.cache_key(bridged_token_symbol) + |> Enum.each(fn {bridged_token_hash, bridged_token_symbol} -> + bridged_token_price = TokenBridge.get_current_price_for_bridged_token(bridged_token_symbol, bridged_token_hash) + cache_key = TokenExchangeRate.cache_key(bridged_token_symbol, bridged_token_hash) TokenExchangeRate.put_into_cache(cache_key, bridged_token_price) end) diff --git a/apps/explorer/lib/explorer/market/market.ex b/apps/explorer/lib/explorer/market/market.ex index 3a8bf50933..8def537751 100644 --- a/apps/explorer/lib/explorer/market/market.ex +++ b/apps/explorer/lib/explorer/market/market.ex @@ -52,7 +52,7 @@ defmodule Explorer.Market do Repo.insert_all(MarketHistory, records_without_zeroes, on_conflict: :nothing, conflict_target: [:date]) end - def add_price(%{symbol: symbol} = token) do + def add_price(%{symbol: symbol, contract_address_hash: contract_address_hash} = token) do known_address = get_known_address(symbol) matches_known_address = known_address && known_address == token.contract_address_hash @@ -63,7 +63,7 @@ defmodule Explorer.Market do fetch_token_usd_value(matches_known_address, symbol) mainnet_bridged_token?(token) -> - TokenBridge.get_current_price_for_bridged_token(symbol) + TokenBridge.get_current_price_for_bridged_token(symbol, contract_address_hash) true -> nil From 86cf6d2204285438c09f7b79c3ecf623592d96b8 Mon Sep 17 00:00:00 2001 From: Victor Baranov Date: Thu, 24 Dec 2020 12:05:32 +0300 Subject: [PATCH 2/3] Remove address_hash from cache for token exchange rate --- .../chain/cache/token_exchange_rate.ex | 30 ++++++++----------- .../lib/explorer/chain/supply/token_bridge.ex | 10 +++---- apps/explorer/lib/explorer/counters/bridge.ex | 6 ++-- apps/explorer/lib/explorer/market/market.ex | 4 +-- 4 files changed, 22 insertions(+), 28 deletions(-) diff --git a/apps/explorer/lib/explorer/chain/cache/token_exchange_rate.ex b/apps/explorer/lib/explorer/chain/cache/token_exchange_rate.ex index 0afc6988a7..e1295151b4 100644 --- a/apps/explorer/lib/explorer/chain/cache/token_exchange_rate.ex +++ b/apps/explorer/lib/explorer/chain/cache/token_exchange_rate.ex @@ -47,28 +47,24 @@ defmodule Explorer.Chain.Cache.TokenExchangeRate do {:noreply, state} end - def cache_key(symbol, address_hash) do - "token_symbol_exchange_rate_#{symbol}_#{address_hash_str_key(address_hash)}" + def cache_key(symbol) do + "token_symbol_exchange_rate_#{symbol}" end - defp address_hash_str_key(address_hash) do - Base.encode16(address_hash.bytes, case: :lower) - end - - def fetch(symbol, address_hash) do - if cache_expired?(symbol, address_hash) || value_is_empty?(symbol, address_hash) do + def fetch(symbol) do + if cache_expired?(symbol) || value_is_empty?(symbol) do Task.start_link(fn -> - update_cache(symbol, address_hash) + update_cache(symbol) end) end - fetch_from_cache(cache_key(symbol, address_hash)) + fetch_from_cache(cache_key(symbol)) end def cache_name, do: @cache_name - defp cache_expired?(symbol, address_hash) do - updated_at = fetch_from_cache("#{cache_key(symbol, address_hash)}_#{@last_update_key}") + defp cache_expired?(symbol) do + updated_at = fetch_from_cache("#{cache_key(symbol)}_#{@last_update_key}") cond do is_nil(updated_at) -> true @@ -77,17 +73,17 @@ defmodule Explorer.Chain.Cache.TokenExchangeRate do end end - defp value_is_empty?(symbol, address_hash) do - value = fetch_from_cache(cache_key(symbol, address_hash)) + defp value_is_empty?(symbol) do + value = fetch_from_cache(cache_key(symbol)) is_nil(value) || value == 0 end - defp update_cache(symbol, address_hash) do - put_into_cache("#{cache_key(symbol, address_hash)}_#{@last_update_key}", current_time()) + defp update_cache(symbol) do + put_into_cache("#{cache_key(symbol)}_#{@last_update_key}", current_time()) exchange_rate = fetch_token_exchange_rate(symbol) - put_into_cache(cache_key(symbol, address_hash), exchange_rate) + put_into_cache(cache_key(symbol), exchange_rate) end def fetch_token_exchange_rate(symbol) do diff --git a/apps/explorer/lib/explorer/chain/supply/token_bridge.ex b/apps/explorer/lib/explorer/chain/supply/token_bridge.ex index ff1634c728..051da64076 100644 --- a/apps/explorer/lib/explorer/chain/supply/token_bridge.ex +++ b/apps/explorer/lib/explorer/chain/supply/token_bridge.ex @@ -194,14 +194,12 @@ defmodule Explorer.Chain.Supply.TokenBridge do omni_bridge_market_cap end - def get_current_price_for_bridged_token(symbol, _address_hash) when is_nil(symbol), do: nil + def get_current_price_for_bridged_token(symbol) when is_nil(symbol), do: nil - def get_current_price_for_bridged_token(_symbol, address_hash) when is_nil(address_hash), do: nil - - def get_current_price_for_bridged_token(symbol, address_hash) do + def get_current_price_for_bridged_token(symbol) do bridged_token_symbol_for_price_fetching = bridged_token_symbol_mapping_to_get_price(symbol) - TokenExchangeRateCache.fetch(bridged_token_symbol_for_price_fetching, address_hash) + TokenExchangeRateCache.fetch(bridged_token_symbol_for_price_fetching) end def get_bridged_mainnet_tokens_list do @@ -221,7 +219,7 @@ defmodule Explorer.Chain.Supply.TokenBridge do bridged_mainnet_tokens_with_supply = bridged_mainnet_tokens_list |> Enum.map(fn {bridged_token_hash, bridged_token_symbol} -> - bridged_token_price_from_cache = TokenExchangeRateCache.fetch(bridged_token_symbol, bridged_token_hash) + bridged_token_price_from_cache = TokenExchangeRateCache.fetch(bridged_token_symbol) bridged_token_price = if bridged_token_price_from_cache > 0 do diff --git a/apps/explorer/lib/explorer/counters/bridge.ex b/apps/explorer/lib/explorer/counters/bridge.ex index 1d0221b3cb..0309369eec 100644 --- a/apps/explorer/lib/explorer/counters/bridge.ex +++ b/apps/explorer/lib/explorer/counters/bridge.ex @@ -161,9 +161,9 @@ defmodule Explorer.Counters.Bridge do bridged_mainnet_tokens_list = TokenBridge.get_bridged_mainnet_tokens_list() bridged_mainnet_tokens_list - |> Enum.each(fn {bridged_token_hash, bridged_token_symbol} -> - bridged_token_price = TokenBridge.get_current_price_for_bridged_token(bridged_token_symbol, bridged_token_hash) - cache_key = TokenExchangeRate.cache_key(bridged_token_symbol, bridged_token_hash) + |> Enum.each(fn {_bridged_token_hash, bridged_token_symbol} -> + bridged_token_price = TokenBridge.get_current_price_for_bridged_token(bridged_token_symbol) + cache_key = TokenExchangeRate.cache_key(bridged_token_symbol) TokenExchangeRate.put_into_cache(cache_key, bridged_token_price) end) diff --git a/apps/explorer/lib/explorer/market/market.ex b/apps/explorer/lib/explorer/market/market.ex index 8def537751..3a8bf50933 100644 --- a/apps/explorer/lib/explorer/market/market.ex +++ b/apps/explorer/lib/explorer/market/market.ex @@ -52,7 +52,7 @@ defmodule Explorer.Market do Repo.insert_all(MarketHistory, records_without_zeroes, on_conflict: :nothing, conflict_target: [:date]) end - def add_price(%{symbol: symbol, contract_address_hash: contract_address_hash} = token) do + def add_price(%{symbol: symbol} = token) do known_address = get_known_address(symbol) matches_known_address = known_address && known_address == token.contract_address_hash @@ -63,7 +63,7 @@ defmodule Explorer.Market do fetch_token_usd_value(matches_known_address, symbol) mainnet_bridged_token?(token) -> - TokenBridge.get_current_price_for_bridged_token(symbol, contract_address_hash) + TokenBridge.get_current_price_for_bridged_token(symbol) true -> nil From 685e2f5aabf665f7d5392e68bfac2a7a0debe2f7 Mon Sep 17 00:00:00 2001 From: Victor Baranov Date: Thu, 24 Dec 2020 12:07:31 +0300 Subject: [PATCH 3/3] Update get_bridged_mainnet_tokens_supply method --- apps/explorer/lib/explorer/chain/supply/token_bridge.ex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/explorer/lib/explorer/chain/supply/token_bridge.ex b/apps/explorer/lib/explorer/chain/supply/token_bridge.ex index 051da64076..09d229760c 100644 --- a/apps/explorer/lib/explorer/chain/supply/token_bridge.ex +++ b/apps/explorer/lib/explorer/chain/supply/token_bridge.ex @@ -222,7 +222,7 @@ defmodule Explorer.Chain.Supply.TokenBridge do bridged_token_price_from_cache = TokenExchangeRateCache.fetch(bridged_token_symbol) bridged_token_price = - if bridged_token_price_from_cache > 0 do + if bridged_token_price_from_cache && Decimal.cmp(bridged_token_price_from_cache, 0) == :gt do bridged_token_price_from_cache else TokenExchangeRateCache.fetch_token_exchange_rate(bridged_token_symbol)