Add TokenTotalSupplyUpdater

token-total-supply-updater
Qwerty5Uiop 1 year ago
parent 97b512d8b8
commit a8d1eaa983
  1. 1
      CHANGELOG.md
  2. 69
      apps/indexer/lib/indexer/fetcher/token_total_supply_updater.ex
  3. 2
      apps/indexer/lib/indexer/supervisor.ex
  4. 27
      apps/indexer/lib/indexer/transform/token_transfers.ex

@ -12,6 +12,7 @@
- [#7784](https://github.com/blockscout/blockscout/pull/7784) - Search improvements: Add new fields, light refactoring
- [#7811](https://github.com/blockscout/blockscout/pull/7811) - Filter addresses before insertion
- [#7895](https://github.com/blockscout/blockscout/pull/7895) - API v2: Add sorting to tokens page
- [#7859](https://github.com/blockscout/blockscout/pull/7859) - Add TokenTotalSupplyUpdater
### Fixes

@ -0,0 +1,69 @@
defmodule Indexer.Fetcher.TokenTotalSupplyUpdater do
@moduledoc """
Periodically updates tokens total_supply
"""
use GenServer
alias Explorer.{Chain, Repo}
alias Explorer.Chain.Token
alias Explorer.Counters.AverageBlockTime
alias Explorer.Token.MetadataRetriever
alias Timex.Duration
@default_update_interval :timer.seconds(10)
def start_link(_) do
GenServer.start_link(__MODULE__, :ok, name: __MODULE__)
end
def init(_) do
schedule_next_update()
{:ok, []}
end
def add_tokens(contract_address_hashes) do
GenServer.cast(__MODULE__, {:add_tokens, contract_address_hashes})
end
def handle_cast({:add_tokens, contract_address_hashes}, state) do
{:noreply, Enum.uniq(List.wrap(contract_address_hashes) ++ state)}
end
def handle_info(:update, contract_address_hashes) do
Enum.each(contract_address_hashes, &update_token/1)
schedule_next_update()
{:noreply, []}
end
defp schedule_next_update do
update_interval =
case AverageBlockTime.average_block_time() do
{:error, :disabled} -> @default_update_interval
block_time -> round(Duration.to_milliseconds(block_time))
end
Process.send_after(self(), :update, update_interval)
end
defp update_token(nil), do: :ok
defp update_token(address_hash_string) do
{:ok, address_hash} = Chain.string_to_address_hash(address_hash_string)
token = Repo.get_by(Token, contract_address_hash: address_hash)
if token && !token.skip_metadata do
token_params = MetadataRetriever.get_total_supply_of(address_hash_string)
if token_params !== %{} do
{:ok, _} = Chain.update_token(token, token_params)
end
end
:ok
end
end

@ -28,6 +28,7 @@ defmodule Indexer.Supervisor do
ReplacedTransaction,
Token,
TokenBalance,
TokenTotalSupplyUpdater,
TokenUpdater,
TransactionAction,
UncleBlock,
@ -125,6 +126,7 @@ defmodule Indexer.Supervisor do
# Out-of-band fetchers
{EmptyBlocksSanitizer.Supervisor, [[json_rpc_named_arguments: json_rpc_named_arguments]]},
{PendingTransactionsSanitizer, [[json_rpc_named_arguments: json_rpc_named_arguments]]},
{TokenTotalSupplyUpdater, [[]]},
# Temporary workers
{UncatalogedTokenTransfers.Supervisor, [[]]},

@ -9,6 +9,7 @@ defmodule Indexer.Transform.TokenTransfers do
alias Explorer.{Chain, Repo}
alias Explorer.Chain.{Token, TokenTransfer}
alias Explorer.Token.MetadataRetriever
alias Indexer.Fetcher.TokenTotalSupplyUpdater
@burn_address "0x0000000000000000000000000000000000000000"
@ -57,7 +58,7 @@ defmodule Indexer.Transform.TokenTransfers do
token_transfer.token_contract_address_hash
end)
|> Enum.uniq()
|> Enum.each(&update_token/1)
|> TokenTotalSupplyUpdater.add_tokens()
tokens_uniq = tokens |> Enum.uniq()
@ -260,30 +261,6 @@ defmodule Indexer.Transform.TokenTransfers do
{token, token_transfer}
end
defp update_token(nil), do: :ok
defp update_token(address_hash_string) do
{:ok, address_hash} = Chain.string_to_address_hash(address_hash_string)
token = Repo.get_by(Token, contract_address_hash: address_hash)
if token && !token.skip_metadata do
token_params =
address_hash_string
|> MetadataRetriever.get_total_supply_of()
token_to_update =
token
|> Repo.preload([:contract_address])
if token_params !== %{} do
{:ok, _} = Chain.update_token(token_to_update, token_params)
end
end
:ok
end
def parse_erc1155_params(
%{
first_topic: unquote(TokenTransfer.erc1155_batch_transfer_signature()),

Loading…
Cancel
Save