Bridged tokens price feed improvement

pull/3707/head
Viktor Baranov 4 years ago
parent 4ff75f8e5f
commit 66719fb215
  1. 1
      CHANGELOG.md
  2. 3
      apps/block_scout_web/config/config.exs
  3. 4
      apps/block_scout_web/lib/block_scout_web/controllers/address_token_balance_controller.ex
  4. 4
      apps/block_scout_web/lib/block_scout_web/views/address_view.ex
  5. 4
      apps/block_scout_web/lib/block_scout_web/views/layout_view.ex
  6. 4
      apps/block_scout_web/lib/block_scout_web/views/tokens/overview_view.ex
  7. 4
      apps/block_scout_web/lib/block_scout_web/views/transaction_view.ex
  8. 28
      apps/explorer/lib/explorer/chain/cache/token_exchange_rate.ex
  9. 21
      apps/explorer/lib/explorer/chain/supply/token_bridge.ex
  10. 2
      apps/explorer/lib/explorer/custom_contracts_helpers.ex
  11. 3
      docker/Makefile

@ -13,6 +13,7 @@
- [#3564](https://github.com/poanetwork/blockscout/pull/3564) - Staking welcome message
### Fixes
- [#3707](https://github.com/poanetwork/blockscout/pull/3707) - Fetch bridged token price by address of foreign token, not by symbol
- [#3686](https://github.com/poanetwork/blockscout/pull/3686) - BSC bridged tokens detection fix
- [#3683](https://github.com/poanetwork/blockscout/pull/3683) - Token instance image IPFS link display fix
- [#3655](https://github.com/poanetwork/blockscout/pull/3655) - Handle absence of readAll function in some old/legacy browsers

@ -44,7 +44,8 @@ config :block_scout_web,
restricted_list_key: System.get_env("RESTRICTED_LIST_KEY", nil),
dark_forest_addresses: System.get_env("CUSTOM_CONTRACT_ADDRESSES_DARK_FOREST"),
dark_forest_addresses_v_0_5: System.get_env("CUSTOM_CONTRACT_ADDRESSES_DARK_FOREST_V_0_5"),
circles_addresses: System.get_env("CUSTOM_CONTRACT_ADDRESSES_CIRCLES")
circles_addresses: System.get_env("CUSTOM_CONTRACT_ADDRESSES_CIRCLES"),
test_tokens_addresses: System.get_env("CUSTOM_CONTRACT_ADDRESSES_TEST_TOKEN")
config :block_scout_web, BlockScoutWeb.Counters.BlocksIndexedCounter, enabled: true

@ -2,8 +2,8 @@ defmodule BlockScoutWeb.AddressTokenBalanceController do
use BlockScoutWeb, :controller
import BlockScoutWeb.AddressView, only: [from_address_hash: 1]
alias BlockScoutWeb.{AccessHelpers, CustomContractsHelpers}
alias Explorer.{Chain, Market}
alias BlockScoutWeb.AccessHelpers
alias Explorer.{Chain, CustomContractsHelpers, Market}
alias Indexer.Fetcher.TokenBalanceOnDemand
def index(conn, %{"address_id" => address_hash_string} = params) do

@ -3,8 +3,8 @@ defmodule BlockScoutWeb.AddressView do
require Logger
alias BlockScoutWeb.{AccessHelpers, CustomContractsHelpers, LayoutView}
alias Explorer.Chain
alias BlockScoutWeb.{AccessHelpers, LayoutView}
alias Explorer.{Chain, CustomContractsHelpers}
alias Explorer.Chain.{Address, Hash, InternalTransaction, SmartContract, Token, TokenTransfer, Transaction, Wei}
alias Explorer.Chain.Block.Reward
alias Explorer.ExchangeRates.Token, as: TokenExchangeRate

@ -1,7 +1,7 @@
defmodule BlockScoutWeb.LayoutView do
use BlockScoutWeb, :view
alias Explorer.Chain
alias Explorer.{Chain, CustomContractsHelpers}
alias Plug.Conn
alias Poison.Parser
@ -34,7 +34,7 @@ defmodule BlockScoutWeb.LayoutView do
}
]
alias BlockScoutWeb.{CustomContractsHelpers, SocialMedia}
alias BlockScoutWeb.SocialMedia
def logo do
Keyword.get(application_config(), :logo) || "/images/blockscout_logo.svg"

@ -1,10 +1,10 @@
defmodule BlockScoutWeb.Tokens.OverviewView do
use BlockScoutWeb, :view
alias Explorer.Chain
alias Explorer.{Chain, CustomContractsHelpers}
alias Explorer.Chain.{Address, SmartContract, Token}
alias BlockScoutWeb.{AccessHelpers, CurrencyHelpers, CustomContractsHelpers, LayoutView}
alias BlockScoutWeb.{AccessHelpers, CurrencyHelpers, LayoutView}
import BlockScoutWeb.AddressView, only: [from_address_hash: 1]

@ -1,9 +1,9 @@
defmodule BlockScoutWeb.TransactionView do
use BlockScoutWeb, :view
alias BlockScoutWeb.{AccessHelpers, AddressView, BlockView, CustomContractsHelpers, TabHelpers}
alias BlockScoutWeb.{AccessHelpers, AddressView, BlockView, TabHelpers}
alias BlockScoutWeb.Cldr.Number
alias Explorer.{Chain, Repo}
alias Explorer.{Chain, CustomContractsHelpers, Repo}
alias Explorer.Chain.Block.Reward
alias Explorer.Chain.{Address, Block, InternalTransaction, Transaction, Wei}
alias Explorer.Counters.AverageBlockTime

@ -51,18 +51,18 @@ defmodule Explorer.Chain.Cache.TokenExchangeRate do
{:noreply, state}
end
def cache_key(symbol) do
"token_symbol_exchange_rate_#{symbol}"
def cache_key(symbol_or_address_hash_str) do
"token_symbol_exchange_rate_#{symbol_or_address_hash_str}"
end
def fetch(token_hash, symbol) do
if cache_expired?(symbol) || value_is_empty?(symbol) do
def fetch(token_hash, symbol_or_address_hash_str) do
if cache_expired?(symbol_or_address_hash_str) || value_is_empty?(symbol_or_address_hash_str) do
Task.start_link(fn ->
update_cache(token_hash, symbol)
update_cache(token_hash, symbol_or_address_hash_str)
end)
end
cached_value = fetch_from_cache(cache_key(symbol))
cached_value = fetch_from_cache(cache_key(symbol_or_address_hash_str))
if is_nil(cached_value) || Decimal.cmp(cached_value, 0) == :eq do
fetch_from_db(token_hash)
@ -73,9 +73,9 @@ defmodule Explorer.Chain.Cache.TokenExchangeRate do
def cache_name, do: @cache_name
defp cache_expired?(symbol) do
defp cache_expired?(symbol_or_address_hash_str) do
cache_period = token_exchange_rate_cache_period()
updated_at = fetch_from_cache("#{cache_key(symbol)}_#{@last_update_key}")
updated_at = fetch_from_cache("#{cache_key(symbol_or_address_hash_str)}_#{@last_update_key}")
cond do
is_nil(updated_at) -> true
@ -84,18 +84,18 @@ 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_or_address_hash_str) do
value = fetch_from_cache(cache_key(symbol_or_address_hash_str))
is_nil(value) || value == 0
end
defp update_cache(token_hash, symbol) do
put_into_cache("#{cache_key(symbol)}_#{@last_update_key}", current_time())
defp update_cache(token_hash, symbol_or_address_hash_str) do
put_into_cache("#{cache_key(symbol_or_address_hash_str)}_#{@last_update_key}", current_time())
exchange_rate = fetch_token_exchange_rate(symbol)
exchange_rate = fetch_token_exchange_rate(symbol_or_address_hash_str)
put_into_db(token_hash, exchange_rate)
put_into_cache(cache_key(symbol), exchange_rate)
put_into_cache(cache_key(symbol_or_address_hash_str), exchange_rate)
end
def fetch_token_exchange_rate(symbol) do

@ -14,7 +14,7 @@ defmodule Explorer.Chain.Supply.TokenBridge do
alias Explorer.Chain.Cache.TokenExchangeRate, as: TokenExchangeRateCache
alias Explorer.Counters.Bridge
alias Explorer.ExchangeRates.Source
alias Explorer.Repo
alias Explorer.{CustomContractsHelpers, Repo}
alias Explorer.SmartContract.Reader
@token_bridge_contract_address "0x7301CFA0e1756B71869E93d4e4Dca5c7d0eb0AA6"
@ -210,7 +210,7 @@ defmodule Explorer.Chain.Supply.TokenBridge do
on: t.contract_address_hash == bt.home_token_contract_address_hash,
where: bt.foreign_chain_id == ^1,
where: t.bridged == true,
select: {bt.home_token_contract_address_hash, t.symbol, bt.custom_cap},
select: {bt.home_token_contract_address_hash, t.symbol, bt.custom_cap, bt.foreign_token_contract_address_hash},
order_by: [desc: t.holder_count]
)
@ -221,17 +221,19 @@ defmodule Explorer.Chain.Supply.TokenBridge do
defp get_bridged_mainnet_tokens_supply(bridged_mainnet_tokens_list) do
bridged_mainnet_tokens_with_supply =
bridged_mainnet_tokens_list
|> Enum.map(fn {bridged_token_hash, bridged_token_symbol, bridged_token_custom_cap} ->
|> Enum.map(fn {bridged_token_hash, _bridged_token_symbol, bridged_token_custom_cap,
foreign_token_contract_address_hash} ->
if bridged_token_custom_cap do
{bridged_token_hash, Decimal.new(0), Decimal.new(0), bridged_token_custom_cap}
else
bridged_token_price_from_cache = TokenExchangeRateCache.fetch(bridged_token_hash, bridged_token_symbol)
bridged_token_price_from_cache =
TokenExchangeRateCache.fetch(bridged_token_hash, foreign_token_contract_address_hash)
bridged_token_price =
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)
TokenExchangeRateCache.fetch_token_exchange_rate_by_address(foreign_token_contract_address_hash)
end
query =
@ -266,11 +268,17 @@ defmodule Explorer.Chain.Supply.TokenBridge do
end
defp calc_omni_bridge_market_cap(bridged_mainnet_tokens_with_supply) do
test_token_addresses = CustomContractsHelpers.get_custom_addresses_list(:test_tokens_addresses)
config = Application.get_env(:explorer, Explorer.Counters.Bridge)
disable_lp_tokens_in_market_cap = Keyword.get(config, :disable_lp_tokens_in_market_cap)
omni_bridge_market_cap =
bridged_mainnet_tokens_with_supply
|> Enum.filter(fn {bridged_token_hash, _, _, _} ->
bridged_token_hash_str = "0x" <> Base.encode16(bridged_token_hash.bytes, case: :lower)
!Enum.member?(test_token_addresses, bridged_token_hash_str)
end)
|> Enum.reduce(Decimal.new(0), fn {_bridged_token_hash, bridged_token_price, bridged_token_balance,
bridged_token_custom_cap},
acc ->
@ -278,7 +286,8 @@ defmodule Explorer.Chain.Supply.TokenBridge do
Decimal.add(acc, bridged_token_custom_cap)
else
if bridged_token_price do
Decimal.add(acc, Decimal.mult(bridged_token_price, bridged_token_balance))
bridged_token_cap = Decimal.mult(bridged_token_price, bridged_token_balance)
Decimal.add(acc, bridged_token_cap)
else
acc
end

@ -1,4 +1,4 @@
defmodule BlockScoutWeb.CustomContractsHelpers do
defmodule Explorer.CustomContractsHelpers do
@moduledoc """
Helpers to enable custom contracts themes
"""

@ -275,6 +275,9 @@ endif
ifdef DISABLE_LP_TOKENS_IN_MARKET_CAP
BLOCKSCOUT_CONTAINER_PARAMS += -e 'DISABLE_LP_TOKENS_IN_MARKET_CAP=$(DISABLE_LP_TOKENS_IN_MARKET_CAP)'
endif
ifdef CUSTOM_CONTRACT_ADDRESSES_TEST_TOKEN
BLOCKSCOUT_CONTAINER_PARAMS += -e 'CUSTOM_CONTRACT_ADDRESSES_TEST_TOKEN=$(CUSTOM_CONTRACT_ADDRESSES_TEST_TOKEN)'
endif
HAS_BLOCKSCOUT_IMAGE := $(shell docker images | grep -sw ${DOCKER_IMAGE})
build:

Loading…
Cancel
Save