Skip to content

Commit

Permalink
Merge pull request blockscout#4544 from blockscout/vb-indexer-reduce-…
Browse files Browse the repository at this point in the history
…tokens-update

Indexer performance update: Add skip_metadata flag for token if indexer failed to get any of [name, symbol, decimals, totalSupply]
  • Loading branch information
vbaranov authored and jagdeep sidhu committed Aug 27, 2021
1 parent 21e803b commit fc56785
Show file tree
Hide file tree
Showing 7 changed files with 59 additions and 13 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

### Fixes
- [#4553](https://github.com/blockscout/blockscout/pull/4553) - Indexer performance update: skip genesis block in requesting of trace_block API endpoint
- [#4544](https://github.com/blockscout/blockscout/pull/4544) - Indexer performance update: Add skip_metadata flag for token if indexer failed to get any of [name, symbol, decimals, totalSupply]
- [#4542](https://github.com/blockscout/blockscout/pull/4542) - Indexer performance update: Deduplicate tokens in the indexer token transfers transformer
- [#4535](https://github.com/blockscout/blockscout/pull/4535) - Indexer performance update:: Eliminate multiple updates of the same token while parsing mint/burn token transfers batch
- [#4527](https://github.com/blockscout/blockscout/pull/4527) - Indexer performance update: refactor coin balance daily fetcher
Expand Down
8 changes: 6 additions & 2 deletions apps/explorer/lib/explorer/chain/import/runner/tokens.ex
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,8 @@ defmodule Explorer.Chain.Import.Runner.Tokens do
decimals: fragment("EXCLUDED.decimals"),
type: fragment("EXCLUDED.type"),
cataloged: fragment("EXCLUDED.cataloged"),
bridged: fragment("EXCLUDED.bridged"),
skip_metadata: fragment("EXCLUDED.skip_metadata"),
# `holder_count` is not updated as a pre-existing token means the `holder_count` is already initialized OR
# need to be migrated with `priv/repo/migrations/scripts/update_new_tokens_holder_count_in_batches.sql.exs`
# Don't update `contract_address_hash` as it is the primary key and used for the conflict target
Expand All @@ -157,13 +159,15 @@ defmodule Explorer.Chain.Import.Runner.Tokens do
],
where:
fragment(
"(EXCLUDED.name, EXCLUDED.symbol, EXCLUDED.total_supply, EXCLUDED.decimals, EXCLUDED.type, EXCLUDED.cataloged) IS DISTINCT FROM (?, ?, ?, ?, ?, ?)",
"(EXCLUDED.name, EXCLUDED.symbol, EXCLUDED.total_supply, EXCLUDED.decimals, EXCLUDED.type, EXCLUDED.cataloged, EXCLUDED.bridged, EXCLUDED.skip_metadata) IS DISTINCT FROM (?, ?, ?, ?, ?, ?, ?, ?)",
token.name,
token.symbol,
token.total_supply,
token.decimals,
token.type,
token.cataloged
token.cataloged,
token.bridged,
token.skip_metadata
)
)
end
Expand Down
6 changes: 4 additions & 2 deletions apps/explorer/lib/explorer/chain/token.ex
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@ defmodule Explorer.Chain.Token do
contract_address: %Ecto.Association.NotLoaded{} | Address.t(),
contract_address_hash: Hash.Address.t(),
holder_count: non_neg_integer() | nil,
bridged: boolean()
bridged: boolean(),
skip_metadata: boolean()
}

@derive {Poison.Encoder,
Expand Down Expand Up @@ -76,6 +77,7 @@ defmodule Explorer.Chain.Token do
field(:cataloged, :boolean)
field(:holder_count, :integer)
field(:bridged, :boolean)
field(:skip_metadata, :boolean)

belongs_to(
:contract_address,
Expand All @@ -90,7 +92,7 @@ defmodule Explorer.Chain.Token do
end

@required_attrs ~w(contract_address_hash type)a
@optional_attrs ~w(cataloged decimals name symbol total_supply)a
@optional_attrs ~w(cataloged decimals name symbol total_supply bridged skip_metadata)a

@doc false
def changeset(%Token{} = token, params \\ %{}) do
Expand Down
32 changes: 30 additions & 2 deletions apps/explorer/lib/explorer/token/metadata_retriever.ex
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ defmodule Explorer.Token.MetadataRetriever do

require Logger

alias Explorer.Chain.Hash
alias Explorer.{Chain, Repo}
alias Explorer.Chain.{Hash, Token}
alias Explorer.SmartContract.Reader

@contract_abi [
Expand Down Expand Up @@ -97,6 +98,11 @@ defmodule Explorer.Token.MetadataRetriever do
"95d89b41" => []
}

# 18160ddd = keccak256(totalSupply())
@total_supply_function %{
"18160ddd" => []
}

@doc """
Read functions below in the Smart Contract given the Contract's address hash.
Expand Down Expand Up @@ -163,8 +169,30 @@ defmodule Explorer.Token.MetadataRetriever do
end

def get_functions_of(contract_address_hash) when is_binary(contract_address_hash) do
res =
contract_address_hash
|> fetch_functions_from_contract(@contract_functions)
|> format_contract_functions_result(contract_address_hash)

if res == %{} do
token_to_update =
Token
|> Repo.get_by(contract_address_hash: contract_address_hash)
|> Repo.preload([:contract_address])

set_skip_metadata(token_to_update)
end

res
end

def set_skip_metadata(token_to_update) do
Chain.update_token(%{token_to_update | updated_at: DateTime.utc_now()}, %{skip_metadata: true})
end

def get_total_supply_of(contract_address_hash) when is_binary(contract_address_hash) do
contract_address_hash
|> fetch_functions_from_contract(@contract_functions)
|> fetch_functions_from_contract(@total_supply_function)
|> format_contract_functions_result(contract_address_hash)
end

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
defmodule Explorer.Repo.Migrations.TokensAddMetadataFetchFlag do
use Ecto.Migration

def change do
alter table(:tokens) do
add(:skip_metadata, :boolean, null: true)
end
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ defmodule Indexer.Fetcher.TokenTotalSupplyOnDemand do

token_params =
token_address_hash
|> MetadataRetriever.get_functions_of()
|> MetadataRetriever.get_total_supply_of()

token =
Token
Expand Down
14 changes: 8 additions & 6 deletions apps/indexer/lib/indexer/transform/token_transfers.ex
Original file line number Diff line number Diff line change
Expand Up @@ -138,18 +138,20 @@ defmodule Indexer.Transform.TokenTransfers do
defp update_token(address_hash_string) do
{:ok, address_hash} = Chain.string_to_address_hash(address_hash_string)

token_params =
address_hash_string
|> MetadataRetriever.get_functions_of()

token = Repo.get_by(Token, contract_address_hash: address_hash)

if token do
if token && !token.skip_metadata do
token_params =
address_hash_string
|> MetadataRetriever.get_total_supply_of()

token_to_update =
token
|> Repo.preload([:contract_address])

{:ok, _} = Chain.update_token(%{token_to_update | updated_at: DateTime.utc_now()}, token_params)
if token_params !== %{} do
{:ok, _} = Chain.update_token(%{token_to_update | updated_at: DateTime.utc_now()}, token_params)
end
end

:ok
Expand Down

0 comments on commit fc56785

Please sign in to comment.