Log tokens that gave errors interacting with their functions

pull/1078/head
Felipe Renan 6 years ago
parent 0fbda6c72f
commit 43b55ef688
  1. 2
      apps/explorer/config/config.exs
  2. 5
      apps/explorer/config/dev.exs
  3. 6
      apps/explorer/config/prod.exs
  4. 66
      apps/explorer/lib/explorer/token/functions_reader.ex
  5. 3
      config/config.exs

@ -11,7 +11,7 @@ config :ecto, json_library: Jason
config :explorer,
ecto_repos: [Explorer.Repo],
coin: System.get_env("COIN") || "POA",
token_functions_reader_retry: 3
token_functions_reader_max_retries: 3
config :explorer, Explorer.Integrations.EctoLogger, query_time_ms_threshold: 2_000

@ -13,6 +13,11 @@ config :logger, :explorer,
level: :debug,
path: Path.absname("logs/dev/explorer.log")
config :logger, :reading_token_functions,
level: :debug,
path: Path.absname("logs/dev/explorer/tokens/reading_functions.log"),
metadata_filter: [fetcher: :token_functions]
import_config "dev.secret.exs"
variant =

@ -14,6 +14,12 @@ config :logger, :explorer,
path: Path.absname("logs/prod/explorer.log"),
rotate: %{max_bytes: 52_428_800, keep: 19}
config :logger, :reading_token_functions,
level: :debug,
path: Path.absname("logs/prod/explorer/tokens/reading_functions.log"),
metadata_filter: [fetcher: :token_functions],
rotate: %{max_bytes: 52_428_800, keep: 19}
variant =
if is_nil(System.get_env("ETHEREUM_JSONRPC_VARIANT")) do
"parity"

@ -3,6 +3,8 @@ defmodule Explorer.Token.FunctionsReader do
Reads Token's fields using Smart Contract functions from the blockchain.
"""
require Logger
alias Explorer.Chain.Hash
alias Explorer.SmartContract.Reader
@ -92,7 +94,7 @@ defmodule Explorer.Token.FunctionsReader do
decimals: 18
}
It will retry to fetch each function in the Smart Contract according to :token_fetcher_retry
It will retry to fetch each function in the Smart Contract according to :token_functions_reader_max_retries
configured in the application env case one of them raised error.
"""
@spec get_functions_of(Hash.t()) :: Map.t()
@ -110,39 +112,65 @@ defmodule Explorer.Token.FunctionsReader do
end
defp fetch_functions_from_contract(contract_address_hash, contract_functions) do
retry = Application.get_env(:explorer, :token_functions_reader_retry)
max_retries = Application.get_env(:explorer, :token_functions_reader_max_retries)
functions_fetched = %{}
fetch_functions_from_contract(contract_address_hash, contract_functions, max_retries, functions_fetched)
end
fetch_functions_from_contract(contract_address_hash, contract_functions, retry)
defp fetch_functions_from_contract(contract_address_hash, contract_functions, retries_left, functions_fetched)
when retries_left == 0 do
contract_functions_result = Reader.query_contract(contract_address_hash, @contract_abi, contract_functions)
Map.merge(functions_fetched, contract_functions_result)
end
defp fetch_functions_from_contract(contract_address_hash, contract_functions, retry, result \\ %{}) do
defp fetch_functions_from_contract(contract_address_hash, contract_functions, retries_left, functions_fetched)
when retries_left > 0 do
contract_functions_result = Reader.query_contract(contract_address_hash, @contract_abi, contract_functions)
contract_functions_with_errors = contract_functions_with_errors(contract_functions_result)
functions_with_errors =
Enum.filter(contract_functions_result, fn function ->
case function do
{_, {:error, _}} -> true
{_, {:ok, _}} -> false
end
end)
if Enum.any?(functions_with_errors) do
log_functions_with_errors(contract_address_hash, functions_with_errors, retries_left)
contract_functions_with_errors =
Map.take(
contract_functions,
Enum.map(functions_with_errors, fn {function, _} -> function end)
)
if Enum.any?(contract_functions_with_errors) && retry > 0 do
fetch_functions_from_contract(
contract_address_hash,
contract_functions_with_errors,
retry - 1,
Map.merge(result, contract_functions_result)
retries_left - 1,
Map.merge(functions_fetched, contract_functions_result)
)
else
Map.merge(result, contract_functions_result)
Map.merge(functions_fetched, contract_functions_result)
end
end
defp contract_functions_with_errors(contract_functions) do
contract_functions
|> Enum.filter(fn function ->
case function do
{_, {:error, _}} -> true
{_, {:ok, _}} -> false
end
end)
|> Enum.reduce(%{}, fn {name, _error}, acc ->
Map.put(acc, name, [])
defp log_functions_with_errors(contract_address_hash, functions_with_errors, retries_left) do
error_messages =
Enum.map(functions_with_errors, fn {function, {:error, error_message}} ->
"function: #{function} - error: #{error_message} \n"
end)
Logger.debug(
[
"<Token contract hash: #{contract_address_hash}> error while fetching metadata: \n",
error_messages,
"Retries left: #{retries_left}"
],
fetcher: :token_functions
)
end
defp format_contract_functions_result(contract_functions, contract_address_hash) do

@ -25,7 +25,8 @@ config :logger,
{LoggerFileBackend, :explorer},
# only :indexer, but all levels
{LoggerFileBackend, :indexer},
{LoggerFileBackend, :indexer_token_balances}
{LoggerFileBackend, :indexer_token_balances},
{LoggerFileBackend, :reading_token_functions}
]
config :logger, :console,

Loading…
Cancel
Save