Merge pull request #9340 from blockscout/ap-token-transfers-denormalization

Token transfers denormalization
pull/9439/head
nikitosing 9 months ago committed by GitHub
commit f554b0d3f5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 106
      apps/block_scout_web/lib/block_scout_web/views/tokens/helper.ex
  2. 3
      apps/block_scout_web/lib/block_scout_web/views/transaction_view.ex
  3. 48
      apps/block_scout_web/priv/gettext/default.pot
  4. 48
      apps/block_scout_web/priv/gettext/en/LC_MESSAGES/default.po
  5. 3
      apps/block_scout_web/test/block_scout_web/channels/websocket_v2_test.exs
  6. 25
      apps/block_scout_web/test/block_scout_web/controllers/api/v2/address_controller_test.exs
  7. 26
      apps/block_scout_web/test/block_scout_web/controllers/api/v2/token_controller_test.exs
  8. 21
      apps/block_scout_web/test/block_scout_web/controllers/api/v2/transaction_controller_test.exs
  9. 4
      apps/block_scout_web/test/block_scout_web/views/tokens/helper_test.exs
  10. 1
      apps/explorer/config/config.exs
  11. 1
      apps/explorer/config/runtime/test.exs
  12. 3
      apps/explorer/lib/explorer/application.ex
  13. 4
      apps/explorer/lib/explorer/chain.ex
  14. 4
      apps/explorer/lib/explorer/chain/beacon/reader.ex
  15. 18
      apps/explorer/lib/explorer/chain/cache/background_migrations.ex
  16. 2
      apps/explorer/lib/explorer/chain/cache/gas_price_oracle.ex
  17. 12
      apps/explorer/lib/explorer/chain/denormalization_helper.ex
  18. 80
      apps/explorer/lib/explorer/chain/import/runner/blocks.ex
  19. 28
      apps/explorer/lib/explorer/chain/import/runner/internal_transactions.ex
  20. 8
      apps/explorer/lib/explorer/chain/import/runner/token_transfers.ex
  21. 12
      apps/explorer/lib/explorer/chain/import/runner/transactions.ex
  22. 2
      apps/explorer/lib/explorer/chain/search.ex
  23. 61
      apps/explorer/lib/explorer/chain/token_transfer.ex
  24. 6
      apps/explorer/lib/explorer/chain/transaction/history/historian.ex
  25. 17
      apps/explorer/lib/explorer/etherscan.ex
  26. 4
      apps/explorer/lib/explorer/etherscan/logs.ex
  27. 80
      apps/explorer/lib/explorer/migrator/token_transfer_token_type.ex
  28. 2
      apps/explorer/lib/explorer/migrator/transactions_denormalization.ex
  29. 13
      apps/explorer/priv/repo/migrations/20240122102141_add_token_type_to_token_transfers.exs
  30. 13
      apps/explorer/priv/repo/migrations/20240219152810_add_block_consensus_to_token_transfers.exs
  31. 5
      apps/explorer/test/explorer/chain/import/runner/blocks_test.exs
  32. 4
      apps/explorer/test/explorer/chain/import_test.exs
  33. 1
      apps/explorer/test/explorer/chain_test.exs
  34. 82
      apps/explorer/test/explorer/migrator/token_transfer_token_type_test.exs
  35. 6
      apps/explorer/test/support/factory.ex
  36. 18
      apps/indexer/lib/indexer/transform/token_transfers.ex
  37. 4
      apps/indexer/test/indexer/transform/token_transfers_test.exs

@ -16,31 +16,66 @@ defmodule BlockScoutWeb.Tokens.Helper do
When the token's type is ERC-721, the function will return a string with the token_id that
represents the ERC-721 token since this kind of token doesn't have amount and decimals.
"""
def token_transfer_amount(%{token: token, amount: amount, amounts: amounts, token_ids: token_ids}) do
do_token_transfer_amount(token, amount, amounts, token_ids)
def token_transfer_amount(%{
token: token,
token_type: token_type,
amount: amount,
amounts: amounts,
token_ids: token_ids
}) do
do_token_transfer_amount(token, token_type, amount, amounts, token_ids)
end
def token_transfer_amount(%{token: token, amount: amount, token_ids: token_ids}) do
do_token_transfer_amount(token, amount, nil, token_ids)
def token_transfer_amount(%{token: token, token_type: token_type, amount: amount, token_ids: token_ids}) do
do_token_transfer_amount(token, token_type, amount, nil, token_ids)
end
defp do_token_transfer_amount(%Token{type: "ERC-20"}, nil, nil, _token_ids) do
# TODO: remove this clause along with token transfer denormalization
defp do_token_transfer_amount(%Token{type: "ERC-20"}, nil, nil, nil, _token_ids) do
{:ok, "--"}
end
defp do_token_transfer_amount(%Token{type: "ERC-20", decimals: nil}, amount, _amounts, _token_ids) do
defp do_token_transfer_amount(_token, "ERC-20", nil, nil, _token_ids) do
{:ok, "--"}
end
# TODO: remove this clause along with token transfer denormalization
defp do_token_transfer_amount(%Token{type: "ERC-20", decimals: nil}, nil, amount, _amounts, _token_ids) do
{:ok, CurrencyHelper.format_according_to_decimals(amount, Decimal.new(0))}
end
defp do_token_transfer_amount(%Token{decimals: nil}, "ERC-20", amount, _amounts, _token_ids) do
{:ok, CurrencyHelper.format_according_to_decimals(amount, Decimal.new(0))}
end
defp do_token_transfer_amount(%Token{type: "ERC-20", decimals: decimals}, amount, _amounts, _token_ids) do
# TODO: remove this clause along with token transfer denormalization
defp do_token_transfer_amount(%Token{type: "ERC-20", decimals: decimals}, nil, amount, _amounts, _token_ids) do
{:ok, CurrencyHelper.format_according_to_decimals(amount, decimals)}
end
defp do_token_transfer_amount(%Token{type: "ERC-721"}, _amount, _amounts, _token_ids) do
defp do_token_transfer_amount(%Token{decimals: decimals}, "ERC-20", amount, _amounts, _token_ids) do
{:ok, CurrencyHelper.format_according_to_decimals(amount, decimals)}
end
# TODO: remove this clause along with token transfer denormalization
defp do_token_transfer_amount(%Token{type: "ERC-721"}, nil, _amount, _amounts, _token_ids) do
{:ok, :erc721_instance}
end
defp do_token_transfer_amount(_token, "ERC-721", _amount, _amounts, _token_ids) do
{:ok, :erc721_instance}
end
defp do_token_transfer_amount(%Token{type: "ERC-1155", decimals: decimals}, amount, amounts, token_ids) do
# TODO: remove this clause along with token transfer denormalization
defp do_token_transfer_amount(%Token{type: "ERC-1155", decimals: decimals}, nil, amount, amounts, token_ids) do
if amount do
{:ok, :erc1155_instance, CurrencyHelper.format_according_to_decimals(amount, decimals)}
else
{:ok, :erc1155_instance, amounts, token_ids, decimals}
end
end
defp do_token_transfer_amount(%Token{decimals: decimals}, "ERC-1155", amount, amounts, token_ids) do
if amount do
{:ok, :erc1155_instance, CurrencyHelper.format_according_to_decimals(amount, decimals)}
else
@ -48,29 +83,37 @@ defmodule BlockScoutWeb.Tokens.Helper do
end
end
defp do_token_transfer_amount(_token, _amount, _amounts, _token_ids) do
defp do_token_transfer_amount(_token, _token_type, _amount, _amounts, _token_ids) do
nil
end
def token_transfer_amount_for_api(%{
token: token,
token_type: token_type,
amount: amount,
amounts: amounts,
token_ids: token_ids
}) do
do_token_transfer_amount_for_api(token, amount, amounts, token_ids)
do_token_transfer_amount_for_api(token, token_type, amount, amounts, token_ids)
end
def token_transfer_amount_for_api(%{token: token, token_type: token_type, amount: amount, token_ids: token_ids}) do
do_token_transfer_amount_for_api(token, token_type, amount, nil, token_ids)
end
def token_transfer_amount_for_api(%{token: token, amount: amount, token_ids: token_ids}) do
do_token_transfer_amount_for_api(token, amount, nil, token_ids)
# TODO: remove this clause along with token transfer denormalization
defp do_token_transfer_amount_for_api(%Token{type: "ERC-20"}, nil, nil, nil, _token_ids) do
{:ok, nil}
end
defp do_token_transfer_amount_for_api(%Token{type: "ERC-20"}, nil, nil, _token_ids) do
defp do_token_transfer_amount_for_api(_token, "ERC-20", nil, nil, _token_ids) do
{:ok, nil}
end
# TODO: remove this clause along with token transfer denormalization
defp do_token_transfer_amount_for_api(
%Token{type: "ERC-20", decimals: decimals},
nil,
amount,
_amounts,
_token_ids
@ -78,12 +121,43 @@ defmodule BlockScoutWeb.Tokens.Helper do
{:ok, amount, decimals}
end
defp do_token_transfer_amount_for_api(%Token{type: "ERC-721"}, _amount, _amounts, _token_ids) do
defp do_token_transfer_amount_for_api(
%Token{decimals: decimals},
"ERC-20",
amount,
_amounts,
_token_ids
) do
{:ok, amount, decimals}
end
# TODO: remove this clause along with token transfer denormalization
defp do_token_transfer_amount_for_api(%Token{type: "ERC-721"}, nil, _amount, _amounts, _token_ids) do
{:ok, :erc721_instance}
end
defp do_token_transfer_amount_for_api(_token, "ERC-721", _amount, _amounts, _token_ids) do
{:ok, :erc721_instance}
end
# TODO: remove this clause along with token transfer denormalization
defp do_token_transfer_amount_for_api(
%Token{type: "ERC-1155", decimals: decimals},
nil,
amount,
amounts,
token_ids
) do
if amount do
{:ok, :erc1155_instance, amount, decimals}
else
{:ok, :erc1155_instance, amounts, token_ids, decimals}
end
end
defp do_token_transfer_amount_for_api(
%Token{decimals: decimals},
"ERC-1155",
amount,
amounts,
token_ids
@ -95,7 +169,7 @@ defmodule BlockScoutWeb.Tokens.Helper do
end
end
defp do_token_transfer_amount_for_api(_token, _amount, _amounts, _token_ids) do
defp do_token_transfer_amount_for_api(_token, _token_type, _amount, _amounts, _token_ids) do
nil
end

@ -148,6 +148,7 @@ defmodule BlockScoutWeb.TransactionView do
amount: nil,
amounts: [],
token_ids: token_transfer.token_ids,
token_type: token_transfer.token_type,
to_address_hash: token_transfer.to_address_hash,
from_address_hash: token_transfer.from_address_hash
}
@ -162,6 +163,7 @@ defmodule BlockScoutWeb.TransactionView do
amount: nil,
amounts: amounts,
token_ids: token_transfer.token_ids,
token_type: token_transfer.token_type,
to_address_hash: token_transfer.to_address_hash,
from_address_hash: token_transfer.from_address_hash
}
@ -175,6 +177,7 @@ defmodule BlockScoutWeb.TransactionView do
amount: token_transfer.amount,
amounts: [],
token_ids: token_transfer.token_ids,
token_type: token_transfer.token_type,
to_address_hash: token_transfer.to_address_hash,
from_address_hash: token_transfer.from_address_hash
}

@ -68,7 +68,7 @@ msgstr ""
msgid "%{subnetwork} Explorer - BlockScout"
msgstr ""
#: lib/block_scout_web/views/transaction_view.ex:371
#: lib/block_scout_web/views/transaction_view.ex:374
#, elixir-autogen, elixir-format
msgid "(Awaiting internal transactions for status)"
msgstr ""
@ -698,7 +698,7 @@ msgstr ""
msgid "Compiler version"
msgstr ""
#: lib/block_scout_web/views/transaction_view.ex:364
#: lib/block_scout_web/views/transaction_view.ex:367
#, elixir-autogen, elixir-format
msgid "Confirmed"
msgstr ""
@ -783,12 +783,12 @@ msgstr ""
msgid "Contract Address Pending"
msgstr ""
#: lib/block_scout_web/views/transaction_view.ex:480
#: lib/block_scout_web/views/transaction_view.ex:483
#, elixir-autogen, elixir-format
msgid "Contract Call"
msgstr ""
#: lib/block_scout_web/views/transaction_view.ex:477
#: lib/block_scout_web/views/transaction_view.ex:480
#, elixir-autogen, elixir-format
msgid "Contract Creation"
msgstr ""
@ -1186,12 +1186,12 @@ msgstr ""
msgid "EIP-1167"
msgstr ""
#: lib/block_scout_web/views/transaction_view.ex:222
#: lib/block_scout_web/views/transaction_view.ex:225
#, elixir-autogen, elixir-format
msgid "ERC-1155 "
msgstr ""
#: lib/block_scout_web/views/transaction_view.ex:220
#: lib/block_scout_web/views/transaction_view.ex:223
#, elixir-autogen, elixir-format
msgid "ERC-20 "
msgstr ""
@ -1201,7 +1201,7 @@ msgstr ""
msgid "ERC-20 tokens (beta)"
msgstr ""
#: lib/block_scout_web/views/transaction_view.ex:221
#: lib/block_scout_web/views/transaction_view.ex:224
#, elixir-autogen, elixir-format
msgid "ERC-721 "
msgstr ""
@ -1292,12 +1292,12 @@ msgstr ""
msgid "Error trying to fetch balances."
msgstr ""
#: lib/block_scout_web/views/transaction_view.ex:375
#: lib/block_scout_web/views/transaction_view.ex:378
#, elixir-autogen, elixir-format
msgid "Error: %{reason}"
msgstr ""
#: lib/block_scout_web/views/transaction_view.ex:373
#: lib/block_scout_web/views/transaction_view.ex:376
#, elixir-autogen, elixir-format
msgid "Error: (Awaiting internal transactions for reason)"
msgstr ""
@ -1602,7 +1602,7 @@ msgstr ""
#: lib/block_scout_web/templates/transaction/_tabs.html.eex:11
#: lib/block_scout_web/templates/transaction_internal_transaction/index.html.eex:6
#: lib/block_scout_web/views/address_view.ex:376
#: lib/block_scout_web/views/transaction_view.ex:535
#: lib/block_scout_web/views/transaction_view.ex:538
#, elixir-autogen, elixir-format
msgid "Internal Transactions"
msgstr ""
@ -1719,7 +1719,7 @@ msgstr ""
#: lib/block_scout_web/templates/transaction/_tabs.html.eex:17
#: lib/block_scout_web/templates/transaction_log/index.html.eex:8
#: lib/block_scout_web/views/address_view.ex:387
#: lib/block_scout_web/views/transaction_view.ex:536
#: lib/block_scout_web/views/transaction_view.ex:539
#, elixir-autogen, elixir-format
msgid "Logs"
msgstr ""
@ -1752,7 +1752,7 @@ msgstr ""
msgid "Max Priority Fee per Gas"
msgstr ""
#: lib/block_scout_web/views/transaction_view.ex:327
#: lib/block_scout_web/views/transaction_view.ex:330
#, elixir-autogen, elixir-format
msgid "Max of"
msgstr ""
@ -2064,8 +2064,8 @@ msgid "Parent Hash"
msgstr ""
#: lib/block_scout_web/templates/layout/_topnav.html.eex:63
#: lib/block_scout_web/views/transaction_view.ex:370
#: lib/block_scout_web/views/transaction_view.ex:409
#: lib/block_scout_web/views/transaction_view.ex:373
#: lib/block_scout_web/views/transaction_view.ex:412
#, elixir-autogen, elixir-format
msgid "Pending"
msgstr ""
@ -2201,7 +2201,7 @@ msgstr ""
#: lib/block_scout_web/templates/transaction/_tabs.html.eex:24
#: lib/block_scout_web/templates/transaction_raw_trace/_card_body.html.eex:1
#: lib/block_scout_web/views/transaction_view.ex:537
#: lib/block_scout_web/views/transaction_view.ex:540
#, elixir-autogen, elixir-format
msgid "Raw Trace"
msgstr ""
@ -2514,7 +2514,7 @@ msgstr ""
#: lib/block_scout_web/templates/transaction/_tabs.html.eex:29
#: lib/block_scout_web/templates/transaction_state/index.html.eex:6
#: lib/block_scout_web/views/transaction_view.ex:538
#: lib/block_scout_web/views/transaction_view.ex:541
#, elixir-autogen, elixir-format
msgid "State changes"
msgstr ""
@ -2540,7 +2540,7 @@ msgid "Submit an Issue"
msgstr ""
#: lib/block_scout_web/templates/transaction/_emission_reward_tile.html.eex:8
#: lib/block_scout_web/views/transaction_view.ex:372
#: lib/block_scout_web/views/transaction_view.ex:375
#, elixir-autogen, elixir-format
msgid "Success"
msgstr ""
@ -2849,13 +2849,13 @@ msgid "Token"
msgstr ""
#: lib/block_scout_web/templates/common_components/_token_transfer_type_display_name.html.eex:3
#: lib/block_scout_web/views/transaction_view.ex:471
#: lib/block_scout_web/views/transaction_view.ex:474
#, elixir-autogen, elixir-format
msgid "Token Burning"
msgstr ""
#: lib/block_scout_web/templates/common_components/_token_transfer_type_display_name.html.eex:7
#: lib/block_scout_web/views/transaction_view.ex:472
#: lib/block_scout_web/views/transaction_view.ex:475
#, elixir-autogen, elixir-format
msgid "Token Creation"
msgstr ""
@ -2883,14 +2883,14 @@ msgid "Token ID"
msgstr ""
#: lib/block_scout_web/templates/common_components/_token_transfer_type_display_name.html.eex:5
#: lib/block_scout_web/views/transaction_view.ex:470
#: lib/block_scout_web/views/transaction_view.ex:473
#, elixir-autogen, elixir-format
msgid "Token Minting"
msgstr ""
#: lib/block_scout_web/templates/common_components/_token_transfer_type_display_name.html.eex:9
#: lib/block_scout_web/templates/common_components/_token_transfer_type_display_name.html.eex:11
#: lib/block_scout_web/views/transaction_view.ex:473
#: lib/block_scout_web/views/transaction_view.ex:476
#, elixir-autogen, elixir-format
msgid "Token Transfer"
msgstr ""
@ -2906,7 +2906,7 @@ msgstr ""
#: lib/block_scout_web/views/address_view.ex:378
#: lib/block_scout_web/views/tokens/instance/overview_view.ex:114
#: lib/block_scout_web/views/tokens/overview_view.ex:40
#: lib/block_scout_web/views/transaction_view.ex:534
#: lib/block_scout_web/views/transaction_view.ex:537
#, elixir-autogen, elixir-format
msgid "Token Transfers"
msgstr ""
@ -3022,7 +3022,7 @@ msgstr ""
#: lib/block_scout_web/templates/account/tag_transaction/form.html.eex:11
#: lib/block_scout_web/templates/account/tag_transaction/index.html.eex:23
#: lib/block_scout_web/templates/address_logs/_logs.html.eex:19
#: lib/block_scout_web/views/transaction_view.ex:483
#: lib/block_scout_web/views/transaction_view.ex:486
#, elixir-autogen, elixir-format
msgid "Transaction"
msgstr ""
@ -3177,7 +3177,7 @@ msgstr ""
msgid "Uncles"
msgstr ""
#: lib/block_scout_web/views/transaction_view.ex:363
#: lib/block_scout_web/views/transaction_view.ex:366
#, elixir-autogen, elixir-format
msgid "Unconfirmed"
msgstr ""

@ -68,7 +68,7 @@ msgstr ""
msgid "%{subnetwork} Explorer - BlockScout"
msgstr ""
#: lib/block_scout_web/views/transaction_view.ex:371
#: lib/block_scout_web/views/transaction_view.ex:374
#, elixir-autogen, elixir-format
msgid "(Awaiting internal transactions for status)"
msgstr ""
@ -698,7 +698,7 @@ msgstr ""
msgid "Compiler version"
msgstr ""
#: lib/block_scout_web/views/transaction_view.ex:364
#: lib/block_scout_web/views/transaction_view.ex:367
#, elixir-autogen, elixir-format
msgid "Confirmed"
msgstr ""
@ -783,12 +783,12 @@ msgstr ""
msgid "Contract Address Pending"
msgstr ""
#: lib/block_scout_web/views/transaction_view.ex:480
#: lib/block_scout_web/views/transaction_view.ex:483
#, elixir-autogen, elixir-format
msgid "Contract Call"
msgstr ""
#: lib/block_scout_web/views/transaction_view.ex:477
#: lib/block_scout_web/views/transaction_view.ex:480
#, elixir-autogen, elixir-format
msgid "Contract Creation"
msgstr ""
@ -1186,12 +1186,12 @@ msgstr ""
msgid "EIP-1167"
msgstr ""
#: lib/block_scout_web/views/transaction_view.ex:222
#: lib/block_scout_web/views/transaction_view.ex:225
#, elixir-autogen, elixir-format
msgid "ERC-1155 "
msgstr ""
#: lib/block_scout_web/views/transaction_view.ex:220
#: lib/block_scout_web/views/transaction_view.ex:223
#, elixir-autogen, elixir-format
msgid "ERC-20 "
msgstr ""
@ -1201,7 +1201,7 @@ msgstr ""
msgid "ERC-20 tokens (beta)"
msgstr ""
#: lib/block_scout_web/views/transaction_view.ex:221
#: lib/block_scout_web/views/transaction_view.ex:224
#, elixir-autogen, elixir-format
msgid "ERC-721 "
msgstr ""
@ -1292,12 +1292,12 @@ msgstr ""
msgid "Error trying to fetch balances."
msgstr ""
#: lib/block_scout_web/views/transaction_view.ex:375
#: lib/block_scout_web/views/transaction_view.ex:378
#, elixir-autogen, elixir-format
msgid "Error: %{reason}"
msgstr ""
#: lib/block_scout_web/views/transaction_view.ex:373
#: lib/block_scout_web/views/transaction_view.ex:376
#, elixir-autogen, elixir-format
msgid "Error: (Awaiting internal transactions for reason)"
msgstr ""
@ -1602,7 +1602,7 @@ msgstr ""
#: lib/block_scout_web/templates/transaction/_tabs.html.eex:11
#: lib/block_scout_web/templates/transaction_internal_transaction/index.html.eex:6
#: lib/block_scout_web/views/address_view.ex:376
#: lib/block_scout_web/views/transaction_view.ex:535
#: lib/block_scout_web/views/transaction_view.ex:538
#, elixir-autogen, elixir-format
msgid "Internal Transactions"
msgstr ""
@ -1719,7 +1719,7 @@ msgstr ""
#: lib/block_scout_web/templates/transaction/_tabs.html.eex:17
#: lib/block_scout_web/templates/transaction_log/index.html.eex:8
#: lib/block_scout_web/views/address_view.ex:387
#: lib/block_scout_web/views/transaction_view.ex:536
#: lib/block_scout_web/views/transaction_view.ex:539
#, elixir-autogen, elixir-format
msgid "Logs"
msgstr ""
@ -1752,7 +1752,7 @@ msgstr ""
msgid "Max Priority Fee per Gas"
msgstr ""
#: lib/block_scout_web/views/transaction_view.ex:327
#: lib/block_scout_web/views/transaction_view.ex:330
#, elixir-autogen, elixir-format
msgid "Max of"
msgstr ""
@ -2064,8 +2064,8 @@ msgid "Parent Hash"
msgstr ""
#: lib/block_scout_web/templates/layout/_topnav.html.eex:63
#: lib/block_scout_web/views/transaction_view.ex:370
#: lib/block_scout_web/views/transaction_view.ex:409
#: lib/block_scout_web/views/transaction_view.ex:373
#: lib/block_scout_web/views/transaction_view.ex:412
#, elixir-autogen, elixir-format
msgid "Pending"
msgstr ""
@ -2201,7 +2201,7 @@ msgstr ""
#: lib/block_scout_web/templates/transaction/_tabs.html.eex:24
#: lib/block_scout_web/templates/transaction_raw_trace/_card_body.html.eex:1
#: lib/block_scout_web/views/transaction_view.ex:537
#: lib/block_scout_web/views/transaction_view.ex:540
#, elixir-autogen, elixir-format
msgid "Raw Trace"
msgstr ""
@ -2514,7 +2514,7 @@ msgstr ""
#: lib/block_scout_web/templates/transaction/_tabs.html.eex:29
#: lib/block_scout_web/templates/transaction_state/index.html.eex:6
#: lib/block_scout_web/views/transaction_view.ex:538
#: lib/block_scout_web/views/transaction_view.ex:541
#, elixir-autogen, elixir-format
msgid "State changes"
msgstr ""
@ -2540,7 +2540,7 @@ msgid "Submit an Issue"
msgstr ""
#: lib/block_scout_web/templates/transaction/_emission_reward_tile.html.eex:8
#: lib/block_scout_web/views/transaction_view.ex:372
#: lib/block_scout_web/views/transaction_view.ex:375
#, elixir-autogen, elixir-format
msgid "Success"
msgstr ""
@ -2849,13 +2849,13 @@ msgid "Token"
msgstr ""
#: lib/block_scout_web/templates/common_components/_token_transfer_type_display_name.html.eex:3
#: lib/block_scout_web/views/transaction_view.ex:471
#: lib/block_scout_web/views/transaction_view.ex:474
#, elixir-autogen, elixir-format
msgid "Token Burning"
msgstr ""
#: lib/block_scout_web/templates/common_components/_token_transfer_type_display_name.html.eex:7
#: lib/block_scout_web/views/transaction_view.ex:472
#: lib/block_scout_web/views/transaction_view.ex:475
#, elixir-autogen, elixir-format
msgid "Token Creation"
msgstr ""
@ -2883,14 +2883,14 @@ msgid "Token ID"
msgstr ""
#: lib/block_scout_web/templates/common_components/_token_transfer_type_display_name.html.eex:5
#: lib/block_scout_web/views/transaction_view.ex:470
#: lib/block_scout_web/views/transaction_view.ex:473
#, elixir-autogen, elixir-format
msgid "Token Minting"
msgstr ""
#: lib/block_scout_web/templates/common_components/_token_transfer_type_display_name.html.eex:9
#: lib/block_scout_web/templates/common_components/_token_transfer_type_display_name.html.eex:11
#: lib/block_scout_web/views/transaction_view.ex:473
#: lib/block_scout_web/views/transaction_view.ex:476
#, elixir-autogen, elixir-format
msgid "Token Transfer"
msgstr ""
@ -2906,7 +2906,7 @@ msgstr ""
#: lib/block_scout_web/views/address_view.ex:378
#: lib/block_scout_web/views/tokens/instance/overview_view.ex:114
#: lib/block_scout_web/views/tokens/overview_view.ex:40
#: lib/block_scout_web/views/transaction_view.ex:534
#: lib/block_scout_web/views/transaction_view.ex:537
#, elixir-autogen, elixir-format
msgid "Token Transfers"
msgstr ""
@ -3022,7 +3022,7 @@ msgstr ""
#: lib/block_scout_web/templates/account/tag_transaction/form.html.eex:11
#: lib/block_scout_web/templates/account/tag_transaction/index.html.eex:23
#: lib/block_scout_web/templates/address_logs/_logs.html.eex:19
#: lib/block_scout_web/views/transaction_view.ex:483
#: lib/block_scout_web/views/transaction_view.ex:486
#, elixir-autogen, elixir-format
msgid "Transaction"
msgstr ""
@ -3177,7 +3177,7 @@ msgstr ""
msgid "Uncles"
msgstr ""
#: lib/block_scout_web/views/transaction_view.ex:363
#: lib/block_scout_web/views/transaction_view.ex:366
#, elixir-autogen, elixir-format
msgid "Unconfirmed"
msgstr ""

@ -190,6 +190,7 @@ defmodule BlockScoutWeb.WebsocketV2Test do
from_address_hash: "0xe8ddc5c7a2d2f0d7a9798459c0104fdf5e987aca",
to_address_hash: "0x515c09c5bba1ed566b02a5b0599ec5d5d0aee73d",
token_contract_address_hash: "0x8bf38d4764929064f2d4d3a56520a76ab3df415b",
token_type: "ERC-20",
transaction_hash: "0x53bd884872de3e488692881baeec262e7b95234d3965248c39fe992fffd433e5"
},
%{
@ -200,6 +201,7 @@ defmodule BlockScoutWeb.WebsocketV2Test do
from_address_hash: "0xe8ddc5c7a2d2f0d7a9798459c0104fdf5e987aca",
to_address_hash: "0x515c09c5bba1ed566b02a5b0599ec5d5d0aee73d",
token_contract_address_hash: "0x8bf38d4764929064f2d4d3a56520a76ab3df415b",
token_type: "ERC-20",
transaction_hash: "0x53bd884872de3e488692881baeec262e7b95234d3965248c39fe992fffd433e5"
},
%{
@ -210,6 +212,7 @@ defmodule BlockScoutWeb.WebsocketV2Test do
from_address_hash: "0xe8ddc5c7a2d2f0d7a9798459c0104fdf5e987aca",
to_address_hash: "0x515c09c5bba1ed566b02a5b0599ec5d5d0aee73d",
token_contract_address_hash: "0x00f38d4764929064f2d4d3a56520a76ab3df4151",
token_type: "ERC-20",
transaction_hash: "0x53bd884872de3e488692881baeec262e7b95234d3965248c39fe992fffd433e5"
}
],

@ -961,7 +961,8 @@ defmodule BlockScoutWeb.API.V2.AddressControllerTest do
block: tx.block,
block_number: tx.block_number,
from_address: address,
token_contract_address: erc_20_token.contract_address
token_contract_address: erc_20_token.contract_address,
token_type: "ERC-20"
)
end
@ -977,7 +978,8 @@ defmodule BlockScoutWeb.API.V2.AddressControllerTest do
block_number: tx.block_number,
from_address: address,
token_contract_address: erc_721_token.contract_address,
token_ids: [x]
token_ids: [x],
token_type: "ERC-721"
)
end
@ -993,7 +995,8 @@ defmodule BlockScoutWeb.API.V2.AddressControllerTest do
block_number: tx.block_number,
from_address: address,
token_contract_address: erc_1155_token.contract_address,
token_ids: [x]
token_ids: [x],
token_type: "ERC-1155"
)
end
@ -1086,7 +1089,8 @@ defmodule BlockScoutWeb.API.V2.AddressControllerTest do
block: tx.block,
block_number: tx.block_number,
from_address: address,
token_contract_address: erc_20_token.contract_address
token_contract_address: erc_20_token.contract_address,
token_type: "ERC-20"
)
end
@ -1102,7 +1106,8 @@ defmodule BlockScoutWeb.API.V2.AddressControllerTest do
block_number: tx.block_number,
to_address: address,
token_contract_address: erc_721_token.contract_address,
token_ids: [x]
token_ids: [x],
token_type: "ERC-721"
)
end
@ -1166,6 +1171,7 @@ defmodule BlockScoutWeb.API.V2.AddressControllerTest do
block_number: tx.block_number,
token_contract_address: token.contract_address,
token_ids: Enum.map(0..50, fn _x -> id end),
token_type: "ERC-1155",
amounts: Enum.map(0..50, fn x -> x end)
)
end
@ -1200,7 +1206,8 @@ defmodule BlockScoutWeb.API.V2.AddressControllerTest do
block: tx.block,
block_number: tx.block_number,
token_contract_address: token.contract_address,
token_ids: [i]
token_ids: [i],
token_type: "ERC-721"
)
end
@ -1228,6 +1235,7 @@ defmodule BlockScoutWeb.API.V2.AddressControllerTest do
block_number: tx.block_number,
token_contract_address: token.contract_address,
token_ids: Enum.map(0..50, fn x -> x end),
token_type: "ERC-1155",
amounts: Enum.map(0..50, fn x -> x end)
)
@ -1270,6 +1278,7 @@ defmodule BlockScoutWeb.API.V2.AddressControllerTest do
block_number: tx_1.block_number,
token_contract_address: token.contract_address,
token_ids: Enum.map(0..24, fn x -> x end),
token_type: "ERC-1155",
amounts: Enum.map(0..24, fn x -> x end)
)
@ -1288,6 +1297,7 @@ defmodule BlockScoutWeb.API.V2.AddressControllerTest do
block_number: tx_2.block_number,
token_contract_address: token.contract_address,
token_ids: Enum.map(25..49, fn x -> x end),
token_type: "ERC-1155",
amounts: Enum.map(25..49, fn x -> x end)
)
@ -1304,6 +1314,7 @@ defmodule BlockScoutWeb.API.V2.AddressControllerTest do
block_number: tx_2.block_number,
token_contract_address: token.contract_address,
token_ids: [50],
token_type: "ERC-1155",
amounts: [50]
)
@ -1332,6 +1343,7 @@ defmodule BlockScoutWeb.API.V2.AddressControllerTest do
block_number: tx_1.block_number,
token_contract_address: token.contract_address,
token_ids: Enum.map(0..24, fn x -> x end),
token_type: "ERC-1155",
amounts: Enum.map(0..24, fn x -> x end)
)
@ -1350,6 +1362,7 @@ defmodule BlockScoutWeb.API.V2.AddressControllerTest do
block_number: tx_2.block_number,
token_contract_address: token.contract_address,
token_ids: Enum.map(25..50, fn x -> x end),
token_type: "ERC-1155",
amounts: Enum.map(25..50, fn x -> x end)
)

@ -160,6 +160,7 @@ defmodule BlockScoutWeb.API.V2.TokenControllerTest do
block_number: tx.block_number,
token_contract_address: token.contract_address,
token_ids: Enum.map(0..50, fn _x -> id end),
token_type: "ERC-1155",
amounts: Enum.map(0..50, fn x -> x end)
)
end
@ -192,7 +193,8 @@ defmodule BlockScoutWeb.API.V2.TokenControllerTest do
block: tx.block,
block_number: tx.block_number,
token_contract_address: token.contract_address,
token_ids: [i]
token_ids: [i],
token_type: "ERC-721"
)
end
@ -218,6 +220,7 @@ defmodule BlockScoutWeb.API.V2.TokenControllerTest do
block_number: tx.block_number,
token_contract_address: token.contract_address,
token_ids: Enum.map(0..50, fn x -> x end),
token_type: "ERC-1155",
amounts: Enum.map(0..50, fn x -> x end)
)
@ -250,6 +253,7 @@ defmodule BlockScoutWeb.API.V2.TokenControllerTest do
block_number: tx_1.block_number,
token_contract_address: token.contract_address,
token_ids: Enum.map(0..24, fn x -> x end),
token_type: "ERC-1155",
amounts: Enum.map(0..24, fn x -> x end)
)
@ -267,6 +271,7 @@ defmodule BlockScoutWeb.API.V2.TokenControllerTest do
block_number: tx_2.block_number,
token_contract_address: token.contract_address,
token_ids: Enum.map(25..49, fn x -> x end),
token_type: "ERC-1155",
amounts: Enum.map(25..49, fn x -> x end)
)
@ -282,6 +287,7 @@ defmodule BlockScoutWeb.API.V2.TokenControllerTest do
block_number: tx_2.block_number,
token_contract_address: token.contract_address,
token_ids: [50],
token_type: "ERC-1155",
amounts: [50]
)
@ -308,6 +314,7 @@ defmodule BlockScoutWeb.API.V2.TokenControllerTest do
block_number: tx_1.block_number,
token_contract_address: token.contract_address,
token_ids: Enum.map(0..24, fn x -> x end),
token_type: "ERC-1155",
amounts: Enum.map(0..24, fn x -> x end)
)
@ -325,6 +332,7 @@ defmodule BlockScoutWeb.API.V2.TokenControllerTest do
block_number: tx_2.block_number,
token_contract_address: token.contract_address,
token_ids: Enum.map(25..50, fn x -> x end),
token_type: "ERC-1155",
amounts: Enum.map(25..50, fn x -> x end)
)
@ -997,7 +1005,8 @@ defmodule BlockScoutWeb.API.V2.TokenControllerTest do
insert(:token_transfer,
token_contract_address: token.contract_address,
transaction: transaction,
token_ids: [0]
token_ids: [0],
token_type: "ERC-721"
)
for _ <- 1..50 do
@ -1067,6 +1076,7 @@ defmodule BlockScoutWeb.API.V2.TokenControllerTest do
token_contract_address: token.contract_address,
transaction: transaction,
token_ids: [id + 1],
token_type: "ERC-1155",
amounts: [1]
)
@ -1075,6 +1085,7 @@ defmodule BlockScoutWeb.API.V2.TokenControllerTest do
token_contract_address: token.contract_address,
transaction: transaction,
token_ids: [id, id + 1],
token_type: "ERC-1155",
amounts: [1, 2]
)
@ -1088,7 +1099,8 @@ defmodule BlockScoutWeb.API.V2.TokenControllerTest do
insert(:token_transfer,
token_contract_address: token.contract_address,
transaction: transaction,
token_ids: [id]
token_ids: [id],
token_type: "ERC-1155"
)
end
@ -1120,7 +1132,8 @@ defmodule BlockScoutWeb.API.V2.TokenControllerTest do
block: tx.block,
block_number: tx.block_number,
token_contract_address: token.contract_address,
token_ids: [id]
token_ids: [id],
token_type: "ERC-721"
)
end
@ -1155,6 +1168,7 @@ defmodule BlockScoutWeb.API.V2.TokenControllerTest do
block_number: tx.block_number,
token_contract_address: token.contract_address,
token_ids: Enum.map(0..50, fn _x -> id end),
token_type: "ERC-1155",
amounts: Enum.map(0..50, fn x -> x end)
)
@ -1183,6 +1197,7 @@ defmodule BlockScoutWeb.API.V2.TokenControllerTest do
block_number: tx.block_number,
token_contract_address: token.contract_address,
token_ids: Enum.map(0..50, fn x -> x end) ++ [id],
token_type: "ERC-1155",
amounts: Enum.map(1..51, fn x -> x end) ++ [amount]
)
end
@ -1312,7 +1327,8 @@ defmodule BlockScoutWeb.API.V2.TokenControllerTest do
insert_list(count, :token_transfer,
token_contract_address: token.contract_address,
transaction: transaction,
token_ids: [0]
token_ids: [0],
token_type: "ERC-721"
)
request = get(conn, "/api/v2/tokens/#{token.contract_address.hash}/instances/0/transfers-count")

@ -245,6 +245,7 @@ defmodule BlockScoutWeb.API.V2.TransactionControllerTest do
block_number: tx.block_number,
token_contract_address: token.contract_address,
token_ids: Enum.map(0..50, fn x -> x end),
token_type: "ERC-1155",
amounts: Enum.map(0..50, fn x -> x end)
)
@ -271,6 +272,7 @@ defmodule BlockScoutWeb.API.V2.TransactionControllerTest do
block_number: tx.block_number,
token_contract_address: token.contract_address,
token_ids: [1],
token_type: "ERC-1155",
amounts: [2],
amount: nil
)
@ -581,7 +583,8 @@ defmodule BlockScoutWeb.API.V2.TransactionControllerTest do
block: tx.block,
block_number: tx.block_number,
token_contract_address: erc_1155_token.contract_address,
token_ids: [x]
token_ids: [x],
token_type: "ERC-1155"
)
end
|> Enum.reverse()
@ -595,7 +598,8 @@ defmodule BlockScoutWeb.API.V2.TransactionControllerTest do
block: tx.block,
block_number: tx.block_number,
token_contract_address: erc_721_token.contract_address,
token_ids: [x]
token_ids: [x],
token_type: "ERC-721"
)
end
|> Enum.reverse()
@ -608,7 +612,8 @@ defmodule BlockScoutWeb.API.V2.TransactionControllerTest do
transaction: tx,
block: tx.block,
block_number: tx.block_number,
token_contract_address: erc_20_token.contract_address
token_contract_address: erc_20_token.contract_address,
token_type: "ERC-20"
)
end
|> Enum.reverse()
@ -723,6 +728,7 @@ defmodule BlockScoutWeb.API.V2.TransactionControllerTest do
block_number: tx.block_number,
token_contract_address: token.contract_address,
token_ids: Enum.map(0..50, fn _x -> id end),
token_type: "ERC-1155",
amounts: Enum.map(0..50, fn x -> x end)
)
end
@ -758,7 +764,8 @@ defmodule BlockScoutWeb.API.V2.TransactionControllerTest do
block: tx.block,
block_number: tx.block_number,
token_contract_address: token.contract_address,
token_ids: [i]
token_ids: [i],
token_type: "ERC-721"
)
end
@ -788,6 +795,7 @@ defmodule BlockScoutWeb.API.V2.TransactionControllerTest do
block_number: tx.block_number,
token_contract_address: token.contract_address,
token_ids: Enum.map(0..50, fn x -> x end),
token_type: "ERC-1155",
amounts: Enum.map(0..50, fn x -> x end)
)
@ -823,6 +831,7 @@ defmodule BlockScoutWeb.API.V2.TransactionControllerTest do
block_number: tx.block_number,
token_contract_address: token.contract_address,
token_ids: Enum.map(0..24, fn x -> x end),
token_type: "ERC-1155",
amounts: Enum.map(0..24, fn x -> x end)
)
@ -838,6 +847,7 @@ defmodule BlockScoutWeb.API.V2.TransactionControllerTest do
block_number: tx.block_number,
token_contract_address: token.contract_address,
token_ids: Enum.map(25..49, fn x -> x end),
token_type: "ERC-1155",
amounts: Enum.map(25..49, fn x -> x end)
)
@ -853,6 +863,7 @@ defmodule BlockScoutWeb.API.V2.TransactionControllerTest do
block_number: tx.block_number,
token_contract_address: token.contract_address,
token_ids: [50],
token_type: "ERC-1155",
amounts: [50]
)
@ -879,6 +890,7 @@ defmodule BlockScoutWeb.API.V2.TransactionControllerTest do
block_number: tx.block_number,
token_contract_address: token.contract_address,
token_ids: Enum.map(0..24, fn x -> x end),
token_type: "ERC-1155",
amounts: Enum.map(0..24, fn x -> x end)
)
@ -894,6 +906,7 @@ defmodule BlockScoutWeb.API.V2.TransactionControllerTest do
block_number: tx.block_number,
token_contract_address: token.contract_address,
token_ids: Enum.map(25..50, fn x -> x end),
token_type: "ERC-1155",
amounts: Enum.map(25..50, fn x -> x end)
)

@ -27,14 +27,14 @@ defmodule BlockScoutWeb.Tokens.HelperTest do
test "returns a string with the token_id with ERC-721 token" do
token = build(:token, type: "ERC-721", decimals: nil)
token_transfer = build(:token_transfer, token: token, amount: nil, token_ids: [1])
token_transfer = build(:token_transfer, token: token, amount: nil, token_ids: [1], token_type: "ERC-721")
assert Helper.token_transfer_amount(token_transfer) == {:ok, :erc721_instance}
end
test "returns nothing for unknown token's type" do
token = build(:token, type: "unknown")
token_transfer = build(:token_transfer, token: token)
token_transfer = build(:token_transfer, token: token, token_type: "unknown")
assert Helper.token_transfer_amount(token_transfer) == nil
end

@ -116,6 +116,7 @@ config :explorer, Explorer.Migrator.AddressCurrentTokenBalanceTokenType, enabled
config :explorer, Explorer.Migrator.AddressTokenBalanceTokenType, enabled: true
config :explorer, Explorer.Migrator.SanitizeMissingBlockRanges, enabled: true
config :explorer, Explorer.Migrator.SanitizeIncorrectNFTTokenTransfers, enabled: true
config :explorer, Explorer.Migrator.TokenTransferTokenType, enabled: true
config :explorer, Explorer.Chain.Fetcher.CheckBytecodeMatchingOnDemand, enabled: true

@ -40,6 +40,7 @@ config :explorer, Explorer.Migrator.AddressCurrentTokenBalanceTokenType, enabled
config :explorer, Explorer.Migrator.AddressTokenBalanceTokenType, enabled: false
config :explorer, Explorer.Migrator.SanitizeMissingBlockRanges, enabled: false
config :explorer, Explorer.Migrator.SanitizeIncorrectNFTTokenTransfers, enabled: false
config :explorer, Explorer.Migrator.TokenTransferTokenType, enabled: false
config :explorer,
realtime_events_sender: Explorer.Chain.Events.SimpleSender

@ -130,7 +130,8 @@ defmodule Explorer.Application do
configure(Explorer.Migrator.AddressCurrentTokenBalanceTokenType),
configure(Explorer.Migrator.AddressTokenBalanceTokenType),
configure(Explorer.Migrator.SanitizeMissingBlockRanges),
configure(Explorer.Migrator.SanitizeIncorrectNFTTokenTransfers)
configure(Explorer.Migrator.SanitizeIncorrectNFTTokenTransfers),
configure(Explorer.Migrator.TokenTransferTokenType)
]
|> List.flatten()

@ -352,7 +352,7 @@ defmodule Explorer.Chain do
to_block = to_block(options)
base =
if DenormalizationHelper.denormalization_finished?() do
if DenormalizationHelper.transactions_denormalization_finished?() do
from(log in Log,
order_by: [desc: log.block_number, desc: log.index],
where: log.address_hash == ^address_hash,
@ -482,7 +482,7 @@ defmodule Explorer.Chain do
@spec gas_payment_by_block_hash([Hash.Full.t()]) :: %{Hash.Full.t() => Wei.t()}
def gas_payment_by_block_hash(block_hashes) when is_list(block_hashes) do
query =
if DenormalizationHelper.denormalization_finished?() do
if DenormalizationHelper.transactions_denormalization_finished?() do
from(
transaction in Transaction,
where: transaction.block_hash in ^block_hashes and transaction.block_consensus == true,

@ -126,7 +126,7 @@ defmodule Explorer.Chain.Beacon.Reader do
|> limit(10)
query_with_denormalization =
if DenormalizationHelper.denormalization_finished?() do
if DenormalizationHelper.transactions_denormalization_finished?() do
query
|> order_by([bt, transaction], desc: transaction.block_consensus, desc: transaction.block_number)
|> select([bt, transaction], %{
@ -181,7 +181,7 @@ defmodule Explorer.Chain.Beacon.Reader do
)
query_with_denormalization =
if DenormalizationHelper.denormalization_finished?() do
if DenormalizationHelper.transactions_denormalization_finished?() do
query
|> distinct([transaction_blob, transaction, blob], transaction.block_timestamp)
|> select([transaction_blob, transaction, blob], transaction.block_timestamp)

@ -7,21 +7,23 @@ defmodule Explorer.Chain.Cache.BackgroundMigrations do
use Explorer.Chain.MapCache,
name: :background_migrations_status,
key: :denormalization_finished,
key: :transactions_denormalization_finished,
key: :tb_token_type_finished,
key: :ctb_token_type_finished
key: :ctb_token_type_finished,
key: :tt_denormalization_finished
@dialyzer :no_match
alias Explorer.Migrator.{
AddressCurrentTokenBalanceTokenType,
AddressTokenBalanceTokenType,
TokenTransferTokenType,
TransactionsDenormalization
}
defp handle_fallback(:denormalization_finished) do
defp handle_fallback(:transactions_denormalization_finished) do
Task.start(fn ->
set_denormalization_finished(TransactionsDenormalization.migration_finished?())
set_transactions_denormalization_finished(TransactionsDenormalization.migration_finished?())
end)
{:return, false}
@ -42,4 +44,12 @@ defmodule Explorer.Chain.Cache.BackgroundMigrations do
{:return, false}
end
defp handle_fallback(:tt_denormalization_finished) do
Task.start(fn ->
set_tt_denormalization_finished(TokenTransferTokenType.migration_finished?())
end)
{:return, false}
end
end

@ -99,7 +99,7 @@ defmodule Explorer.Chain.Cache.GasPriceOracle do
end
fee_query =
if DenormalizationHelper.denormalization_finished?() do
if DenormalizationHelper.transactions_denormalization_finished?() do
from(
transaction in Transaction,
where: transaction.block_consensus == true,

@ -7,7 +7,7 @@ defmodule Explorer.Chain.DenormalizationHelper do
@spec extend_block_necessity(keyword(), :optional | :required) :: keyword()
def extend_block_necessity(opts, necessity \\ :optional) do
if denormalization_finished?() do
if transactions_denormalization_finished?() do
opts
else
Keyword.update(opts, :necessity_by_association, %{:block => necessity}, &Map.put(&1, :block, necessity))
@ -16,7 +16,7 @@ defmodule Explorer.Chain.DenormalizationHelper do
@spec extend_transaction_block_necessity(keyword(), :optional | :required) :: keyword()
def extend_transaction_block_necessity(opts, necessity \\ :optional) do
if denormalization_finished?() do
if transactions_denormalization_finished?() do
opts
else
Keyword.update(
@ -30,7 +30,7 @@ defmodule Explorer.Chain.DenormalizationHelper do
@spec extend_transaction_preload(list()) :: list()
def extend_transaction_preload(preloads) do
if denormalization_finished?() do
if transactions_denormalization_finished?() do
preloads
else
[transaction: :block] ++ (preloads -- [:transaction])
@ -39,12 +39,14 @@ defmodule Explorer.Chain.DenormalizationHelper do
@spec extend_block_preload(list()) :: list()
def extend_block_preload(preloads) do
if denormalization_finished?() do
if transactions_denormalization_finished?() do
preloads
else
[:block | preloads]
end
end
def denormalization_finished?, do: BackgroundMigrations.get_denormalization_finished()
def transactions_denormalization_finished?, do: BackgroundMigrations.get_transactions_denormalization_finished()
def tt_denormalization_finished?, do: BackgroundMigrations.get_tt_denormalization_finished()
end

@ -15,6 +15,7 @@ defmodule Explorer.Chain.Import.Runner.Blocks do
Address,
Block,
BlockNumberHelper,
DenormalizationHelper,
Import,
PendingBlockOperation,
Token,
@ -408,6 +409,18 @@ defmodule Explorer.Chain.Import.Runner.Blocks do
timeout: timeout
)
repo.update_all(
from(
token_transfer in TokenTransfer,
join: s in subquery(acquire_query),
on: token_transfer.block_hash == s.hash,
# we don't want to remove consensus from blocks that will be upserted
where: token_transfer.block_hash not in ^hashes
),
[set: [block_consensus: false, updated_at: updated_at]],
timeout: timeout
)
removed_consensus_block_hashes
|> Enum.map(fn {number, _hash} -> number end)
|> Enum.reject(&Enum.member?(consensus_block_numbers, &1))
@ -710,28 +723,51 @@ defmodule Explorer.Chain.Import.Runner.Blocks do
end
defp forked_token_transfers_query(forked_transaction_hashes) do
from(token_transfer in TokenTransfer,
where: token_transfer.transaction_hash in ^forked_transaction_hashes,
inner_join: token in Token,
on: token.contract_address_hash == token_transfer.token_contract_address_hash,
where: token.type == "ERC-721",
inner_join: instance in Instance,
on:
fragment("? @> ARRAY[?::decimal]", token_transfer.token_ids, instance.token_id) and
instance.token_contract_address_hash == token_transfer.token_contract_address_hash,
# per one token instance we will have only one token transfer
where:
token_transfer.block_number == instance.owner_updated_at_block and
token_transfer.log_index == instance.owner_updated_at_log_index,
select: %{
from: token_transfer.from_address_hash,
to: token_transfer.to_address_hash,
token_id: instance.token_id,
token_contract_address_hash: token_transfer.token_contract_address_hash,
block_number: token_transfer.block_number,
log_index: token_transfer.log_index
}
)
if DenormalizationHelper.tt_denormalization_finished?() do
from(token_transfer in TokenTransfer,
where: token_transfer.transaction_hash in ^forked_transaction_hashes,
where: token_transfer.token_type == "ERC-721",
inner_join: instance in Instance,
on:
fragment("? @> ARRAY[?::decimal]", token_transfer.token_ids, instance.token_id) and
instance.token_contract_address_hash == token_transfer.token_contract_address_hash,
# per one token instance we will have only one token transfer
where:
token_transfer.block_number == instance.owner_updated_at_block and
token_transfer.log_index == instance.owner_updated_at_log_index,
select: %{
from: token_transfer.from_address_hash,
to: token_transfer.to_address_hash,
token_id: instance.token_id,
token_contract_address_hash: token_transfer.token_contract_address_hash,
block_number: token_transfer.block_number,
log_index: token_transfer.log_index
}
)
else
from(token_transfer in TokenTransfer,
where: token_transfer.transaction_hash in ^forked_transaction_hashes,
inner_join: token in Token,
on: token.contract_address_hash == token_transfer.token_contract_address_hash,
where: token.type == "ERC-721",
inner_join: instance in Instance,
on:
fragment("? @> ARRAY[?::decimal]", token_transfer.token_ids, instance.token_id) and
instance.token_contract_address_hash == token_transfer.token_contract_address_hash,
# per one token instance we will have only one token transfer
where:
token_transfer.block_number == instance.owner_updated_at_block and
token_transfer.log_index == instance.owner_updated_at_log_index,
select: %{
from: token_transfer.from_address_hash,
to: token_transfer.to_address_hash,
token_id: instance.token_id,
token_contract_address_hash: token_transfer.token_contract_address_hash,
block_number: token_transfer.block_number,
log_index: token_transfer.log_index
}
)
end
end
defp token_instances_on_conflict do

@ -9,7 +9,7 @@ defmodule Explorer.Chain.Import.Runner.InternalTransactions do
alias Ecto.Adapters.SQL
alias Ecto.{Changeset, Multi, Repo}
alias EthereumJSONRPC.Utility.RangesHelper
alias Explorer.Chain.{Block, Hash, Import, InternalTransaction, PendingBlockOperation, Transaction}
alias Explorer.Chain.{Block, Hash, Import, InternalTransaction, PendingBlockOperation, TokenTransfer, Transaction}
alias Explorer.Chain.Events.Publisher
alias Explorer.Chain.Import.Runner
alias Explorer.Prometheus.Instrumenter
@ -147,7 +147,7 @@ defmodule Explorer.Chain.Import.Runner.InternalTransactions do
end)
|> Multi.run(:remove_consensus_of_invalid_blocks, fn repo, %{invalid_block_numbers: invalid_block_numbers} ->
Instrumenter.block_import_stage_runner(
fn -> remove_consensus_of_invalid_blocks(repo, invalid_block_numbers) end,
fn -> remove_consensus_of_invalid_blocks(repo, invalid_block_numbers, timestamps) end,
:block_pending,
:internal_transactions,
:remove_consensus_of_invalid_blocks
@ -705,7 +705,7 @@ defmodule Explorer.Chain.Import.Runner.InternalTransactions do
end
end
defp remove_consensus_of_invalid_blocks(repo, invalid_block_numbers) do
defp remove_consensus_of_invalid_blocks(repo, invalid_block_numbers, %{updated_at: updated_at}) do
if Enum.count(invalid_block_numbers) > 0 do
update_block_query =
from(
@ -714,21 +714,31 @@ defmodule Explorer.Chain.Import.Runner.InternalTransactions do
where: ^traceable_blocks_dynamic_query(),
select: block.hash,
# ShareLocks order already enforced by `acquire_blocks` (see docs: sharelocks.md)
update: [set: [consensus: false]]
update: [set: [consensus: false, updated_at: ^updated_at]]
)
update_transaction_query =
from(
transaction in Transaction,
where: transaction.block_number in ^invalid_block_numbers and transaction.block_consensus,
where: ^traceable_transactions_dynamic_query(),
where: ^traceable_block_number_dynamic_query(),
# ShareLocks order already enforced by `acquire_blocks` (see docs: sharelocks.md)
update: [set: [block_consensus: false]]
update: [set: [block_consensus: false, updated_at: ^updated_at]]
)
update_token_transfers_query =
from(
token_transfer in TokenTransfer,
where: token_transfer.block_number in ^invalid_block_numbers and token_transfer.block_consensus,
where: ^traceable_block_number_dynamic_query(),
# ShareLocks order already enforced by `acquire_blocks` (see docs: sharelocks.md)
update: [set: [block_consensus: false, updated_at: ^updated_at]]
)
try do
{_num, result} = repo.update_all(update_block_query, [])
{_num, _result} = repo.update_all(update_transaction_query, [])
{_num, _result} = repo.update_all(update_token_transfers_query, [])
MissingRangesManipulator.add_ranges_by_block_numbers(invalid_block_numbers)
@ -787,13 +797,13 @@ defmodule Explorer.Chain.Import.Runner.InternalTransactions do
end
end
defp traceable_transactions_dynamic_query do
defp traceable_block_number_dynamic_query do
if RangesHelper.trace_ranges_present?() do
block_ranges = RangesHelper.get_trace_block_ranges()
Enum.reduce(block_ranges, dynamic([_], false), fn
_from.._to = range, acc -> dynamic([transaction], ^acc or transaction.block_number in ^range)
num_to_latest, acc -> dynamic([transaction], ^acc or transaction.block_number >= ^num_to_latest)
_from.._to = range, acc -> dynamic([transaction_or_tt], ^acc or transaction_or_tt.block_number in ^range)
num_to_latest, acc -> dynamic([transaction_or_tt], ^acc or transaction_or_tt.block_number >= ^num_to_latest)
end)
else
dynamic([_], true)

@ -90,18 +90,22 @@ defmodule Explorer.Chain.Import.Runner.TokenTransfers do
to_address_hash: fragment("EXCLUDED.to_address_hash"),
token_contract_address_hash: fragment("EXCLUDED.token_contract_address_hash"),
token_ids: fragment("EXCLUDED.token_ids"),
token_type: fragment("EXCLUDED.token_type"),
block_consensus: fragment("EXCLUDED.block_consensus"),
inserted_at: fragment("LEAST(?, EXCLUDED.inserted_at)", token_transfer.inserted_at),
updated_at: fragment("GREATEST(?, EXCLUDED.updated_at)", token_transfer.updated_at)
]
],
where:
fragment(
"(EXCLUDED.amount, EXCLUDED.from_address_hash, EXCLUDED.to_address_hash, EXCLUDED.token_contract_address_hash, EXCLUDED.token_ids) IS DISTINCT FROM (?, ? ,? , ?, ?)",
"(EXCLUDED.amount, EXCLUDED.from_address_hash, EXCLUDED.to_address_hash, EXCLUDED.token_contract_address_hash, EXCLUDED.token_ids, EXCLUDED.token_type, EXCLUDED.block_consensus) IS DISTINCT FROM (?, ?, ?, ?, ?, ?, ?)",
token_transfer.amount,
token_transfer.from_address_hash,
token_transfer.to_address_hash,
token_transfer.token_contract_address_hash,
token_transfer.token_ids
token_transfer.token_ids,
token_transfer.token_type,
token_transfer.block_consensus
)
)
end

@ -8,7 +8,7 @@ defmodule Explorer.Chain.Import.Runner.Transactions do
import Ecto.Query, only: [from: 2]
alias Ecto.{Multi, Repo}
alias Explorer.Chain.{Block, Hash, Import, Transaction}
alias Explorer.Chain.{Block, Hash, Import, TokenTransfer, Transaction}
alias Explorer.Chain.Import.Runner.TokenTransfers
alias Explorer.Prometheus.Instrumenter
alias Explorer.Utility.MissingRangesManipulator
@ -392,6 +392,16 @@ defmodule Explorer.Chain.Import.Runner.Transactions do
timeout: timeout
)
{_, _result} =
repo.update_all(
from(token_transfer in TokenTransfer,
join: s in subquery(query),
on: token_transfer.transaction_hash == s.hash
),
[set: [block_consensus: false, updated_at: updated_at]],
timeout: timeout
)
{:ok, result}
rescue
postgrex_error in Postgrex.Error ->

@ -403,7 +403,7 @@ defmodule Explorer.Chain.Search do
end
defp search_tx_query(term) do
if DenormalizationHelper.denormalization_finished?() do
if DenormalizationHelper.transactions_denormalization_finished?() do
transaction_search_fields =
search_fields()
|> Map.put(:tx_hash, dynamic([transaction], transaction.hash))

@ -59,6 +59,7 @@ defmodule Explorer.Chain.TokenTransfer do
* `:log_index` - Index of the corresponding `t:Explorer.Chain.Log.t/0` in the block.
* `:amounts` - Tokens transferred amounts in case of batched transfer in ERC-1155
* `:token_ids` - IDs of the tokens (applicable to ERC-1155 tokens)
* `:block_consensus` - Consensus of the block that the transfer took place
"""
@primary_key false
typed_schema "token_transfers" do
@ -68,6 +69,8 @@ defmodule Explorer.Chain.TokenTransfer do
field(:amounts, {:array, :decimal})
field(:token_ids, {:array, :decimal})
field(:index_in_batch, :integer, virtual: true)
field(:token_type, :string)
field(:block_consensus, :boolean)
belongs_to(:from_address, Address,
foreign_key: :from_address_hash,
@ -115,8 +118,8 @@ defmodule Explorer.Chain.TokenTransfer do
timestamps()
end
@required_attrs ~w(block_number log_index from_address_hash to_address_hash token_contract_address_hash transaction_hash block_hash)a
@optional_attrs ~w(amount amounts token_ids)a
@required_attrs ~w(block_number log_index from_address_hash to_address_hash token_contract_address_hash transaction_hash block_hash token_type)a
@optional_attrs ~w(amount amounts token_ids block_consensus)a
@doc false
def changeset(%TokenTransfer{} = struct, params \\ %{}) do
@ -150,15 +153,10 @@ defmodule Explorer.Chain.TokenTransfer do
paging_options = Keyword.get(options, :paging_options, @default_paging_options)
preloads = DenormalizationHelper.extend_transaction_preload([:transaction, :token, :from_address, :to_address])
query =
from(
tt in TokenTransfer,
where: tt.token_contract_address_hash == ^token_address_hash and not is_nil(tt.block_number),
preload: ^preloads,
order_by: [desc: tt.block_number, desc: tt.log_index]
)
query
only_consensus_transfers_query()
|> where([tt], tt.token_contract_address_hash == ^token_address_hash and not is_nil(tt.block_number))
|> preload(^preloads)
|> order_by([tt], desc: tt.block_number, desc: tt.log_index)
|> page_token_transfer(paging_options)
|> limit(^paging_options.page_size)
|> Chain.select_repo(options).all()
@ -169,17 +167,12 @@ defmodule Explorer.Chain.TokenTransfer do
paging_options = Keyword.get(options, :paging_options, @default_paging_options)
preloads = DenormalizationHelper.extend_transaction_preload([:transaction, :token, :from_address, :to_address])
query =
from(
tt in TokenTransfer,
where: tt.token_contract_address_hash == ^token_address_hash,
where: fragment("? @> ARRAY[?::decimal]", tt.token_ids, ^Decimal.new(token_id)),
where: not is_nil(tt.block_number),
preload: ^preloads,
order_by: [desc: tt.block_number, desc: tt.log_index]
)
query
only_consensus_transfers_query()
|> where([tt], tt.token_contract_address_hash == ^token_address_hash)
|> where([tt], fragment("? @> ARRAY[?::decimal]", tt.token_ids, ^Decimal.new(token_id)))
|> where([tt], not is_nil(tt.block_number))
|> preload(^preloads)
|> order_by([tt], desc: tt.block_number, desc: tt.log_index)
|> page_token_transfer(paging_options)
|> limit(^paging_options.page_size)
|> Chain.select_repo(options).all()
@ -312,14 +305,14 @@ defmodule Explorer.Chain.TokenTransfer do
end
def token_transfers_by_address_hash_and_token_address_hash(address_hash, token_address_hash) do
TokenTransfer
only_consensus_transfers_query()
|> where([tt], tt.from_address_hash == ^address_hash or tt.to_address_hash == ^address_hash)
|> where([tt], tt.token_contract_address_hash == ^token_address_hash)
|> order_by([tt], desc: tt.block_number, desc: tt.log_index)
end
def token_transfers_by_address_hash(direction, address_hash, token_types) do
TokenTransfer
only_consensus_transfers_query()
|> filter_by_direction(direction, address_hash)
|> order_by([tt], desc: tt.block_number, desc: tt.log_index)
|> join(:inner, [tt], token in assoc(tt, :token), as: :token)
@ -345,7 +338,11 @@ defmodule Explorer.Chain.TokenTransfer do
def filter_by_type(query, []), do: query
def filter_by_type(query, token_types) when is_list(token_types) do
where(query, [token: token], token.type in ^token_types)
if DenormalizationHelper.tt_denormalization_finished?() do
where(query, [tt], tt.token_type in ^token_types)
else
where(query, [token: token], token.type in ^token_types)
end
end
def filter_by_type(query, _), do: query
@ -355,11 +352,15 @@ defmodule Explorer.Chain.TokenTransfer do
"""
@spec only_consensus_transfers_query() :: Ecto.Query.t()
def only_consensus_transfers_query do
from(token_transfer in __MODULE__,
inner_join: block in assoc(token_transfer, :block),
as: :block,
where: block.consensus == true
)
if DenormalizationHelper.tt_denormalization_finished?() do
from(token_transfer in __MODULE__, where: token_transfer.block_consensus == true)
else
from(token_transfer in __MODULE__,
inner_join: block in assoc(token_transfer, :block),
as: :block,
where: block.consensus == true
)
end
end
@doc """

@ -89,7 +89,7 @@ defmodule Explorer.Chain.Transaction.History.Historian do
Logger.info("tx/per day chart: min/max block numbers [#{min_block}, #{max_block}]")
all_transactions_query =
if DenormalizationHelper.denormalization_finished?() do
if DenormalizationHelper.transactions_denormalization_finished?() do
from(
transaction in Transaction,
where: transaction.block_number >= ^min_block and transaction.block_number <= ^max_block,
@ -112,7 +112,7 @@ defmodule Explorer.Chain.Transaction.History.Historian do
)
query =
if DenormalizationHelper.denormalization_finished?() do
if DenormalizationHelper.transactions_denormalization_finished?() do
all_transactions_query
else
from(transaction in subquery(all_transactions_query),
@ -128,7 +128,7 @@ defmodule Explorer.Chain.Transaction.History.Historian do
Logger.info("tx/per day chart: total gas used #{gas_used}")
total_fee_query =
if DenormalizationHelper.denormalization_finished?() do
if DenormalizationHelper.transactions_denormalization_finished?() do
from(transaction in subquery(all_transactions_query),
select: fragment("SUM(? * ?)", transaction.gas_price, transaction.gas_used)
)

@ -103,7 +103,7 @@ defmodule Explorer.Etherscan do
@spec list_internal_transactions(Hash.Full.t()) :: [map()]
def list_internal_transactions(%Hash{byte_count: unquote(Hash.Full.byte_count())} = transaction_hash) do
query =
if DenormalizationHelper.denormalization_finished?() do
if DenormalizationHelper.transactions_denormalization_finished?() do
from(
it in InternalTransaction,
inner_join: transaction in assoc(it, :transaction),
@ -229,7 +229,7 @@ defmodule Explorer.Etherscan do
|> Repo.replica().all()
else
query =
if DenormalizationHelper.denormalization_finished?() do
if DenormalizationHelper.transactions_denormalization_finished?() do
from(
it in InternalTransaction,
inner_join: transaction in assoc(it, :transaction),
@ -472,7 +472,7 @@ defmodule Explorer.Etherscan do
defp list_transactions(address_hash, max_block_number, options) do
query =
if DenormalizationHelper.denormalization_finished?() do
if DenormalizationHelper.transactions_denormalization_finished?() do
from(
t in Transaction,
where: not is_nil(t.block_hash),
@ -530,6 +530,7 @@ defmodule Explorer.Etherscan do
@token_transfer_fields ~w(
block_number
block_hash
block_consensus
token_contract_address_hash
transaction_hash
from_address_hash
@ -566,7 +567,7 @@ defmodule Explorer.Etherscan do
|> where_contract_address_match(contract_address_hash)
wrapped_query =
if DenormalizationHelper.denormalization_finished?() do
if DenormalizationHelper.transactions_denormalization_finished?() do
from(
tt in subquery(tt_specific_token_query),
inner_join: t in Transaction,
@ -655,7 +656,7 @@ defmodule Explorer.Etherscan do
defp where_start_transaction_block_match(query, %{startblock: nil}), do: query
defp where_start_transaction_block_match(query, %{startblock: start_block} = params) do
if DenormalizationHelper.denormalization_finished?() do
if DenormalizationHelper.transactions_denormalization_finished?() do
where(query, [transaction], transaction.block_number >= ^start_block)
else
where_start_block_match(query, params)
@ -665,7 +666,7 @@ defmodule Explorer.Etherscan do
defp where_end_transaction_block_match(query, %{endblock: nil}), do: query
defp where_end_transaction_block_match(query, %{endblock: end_block} = params) do
if DenormalizationHelper.denormalization_finished?() do
if DenormalizationHelper.transactions_denormalization_finished?() do
where(query, [transaction], transaction.block_number <= ^end_block)
else
where_end_block_match(query, params)
@ -687,7 +688,7 @@ defmodule Explorer.Etherscan do
defp where_start_timestamp_match(query, %{start_timestamp: nil}), do: query
defp where_start_timestamp_match(query, %{start_timestamp: start_timestamp}) do
if DenormalizationHelper.denormalization_finished?() do
if DenormalizationHelper.transactions_denormalization_finished?() do
where(query, [transaction], ^start_timestamp <= transaction.block_timestamp)
else
where(query, [..., block], ^start_timestamp <= block.timestamp)
@ -697,7 +698,7 @@ defmodule Explorer.Etherscan do
defp where_end_timestamp_match(query, %{end_timestamp: nil}), do: query
defp where_end_timestamp_match(query, %{end_timestamp: end_timestamp}) do
if DenormalizationHelper.denormalization_finished?() do
if DenormalizationHelper.transactions_denormalization_finished?() do
where(query, [transaction], transaction.block_timestamp <= ^end_timestamp)
else
where(query, [..., block], block.timestamp <= ^end_timestamp)

@ -75,7 +75,7 @@ defmodule Explorer.Etherscan.Logs do
paging_options = if is_nil(paging_options), do: @default_paging_options, else: paging_options
prepared_filter = Map.merge(@base_filter, filter)
if DenormalizationHelper.denormalization_finished?() do
if DenormalizationHelper.transactions_denormalization_finished?() do
logs_query =
Log
|> where_topic_match(prepared_filter)
@ -206,7 +206,7 @@ defmodule Explorer.Etherscan.Logs do
prepared_filter = Map.merge(@base_filter, filter)
logs_query = where_topic_match(Log, prepared_filter)
if DenormalizationHelper.denormalization_finished?() do
if DenormalizationHelper.transactions_denormalization_finished?() do
block_transaction_query =
from(transaction in Transaction,
where: transaction.block_number >= ^prepared_filter.from_block,

@ -0,0 +1,80 @@
defmodule Explorer.Migrator.TokenTransferTokenType do
@moduledoc """
Migrates all token_transfers to have set token_type
"""
use Explorer.Migrator.FillingMigration
import Ecto.Query
alias Explorer.Chain.Cache.BackgroundMigrations
alias Explorer.Chain.TokenTransfer
alias Explorer.Migrator.FillingMigration
alias Explorer.Repo
@migration_name "tt_denormalization"
@impl FillingMigration
def migration_name, do: @migration_name
@impl FillingMigration
def last_unprocessed_identifiers do
limit = batch_size() * concurrency()
unprocessed_data_query()
|> select([tt], {tt.transaction_hash, tt.block_hash, tt.log_index})
|> limit(^limit)
|> Repo.all(timeout: :infinity)
end
@impl FillingMigration
def unprocessed_data_query do
from(tt in TokenTransfer, where: is_nil(tt.token_type))
end
@impl FillingMigration
def update_batch(token_transfer_ids) do
token_transfer_ids
|> build_update_query()
|> Repo.query!([], timeout: :infinity)
end
@impl FillingMigration
def update_cache do
BackgroundMigrations.set_tt_denormalization_finished(true)
end
defp build_update_query(token_transfer_ids) do
"""
UPDATE token_transfers tt
SET token_type = CASE WHEN t.type = 'ERC-1155' AND token_ids IS NULL THEN 'ERC-20'
ELSE t.type
END,
block_consensus = b.consensus
FROM tokens t, blocks b
WHERE tt.block_hash = b.hash
AND tt.token_contract_address_hash = t.contract_address_hash
AND (tt.transaction_hash, tt.block_hash, tt.log_index) IN #{encode_token_transfer_ids(token_transfer_ids)};
"""
end
defp encode_token_transfer_ids(ids) do
encoded_values =
ids
|> Enum.reduce("", fn {t_hash, b_hash, log_index}, acc ->
acc <> "('#{hash_to_query_string(t_hash)}', '#{hash_to_query_string(b_hash)}', #{log_index}),"
end)
|> String.trim_trailing(",")
"(#{encoded_values})"
end
defp hash_to_query_string(hash) do
s_hash =
hash
|> to_string()
|> String.trim_leading("0")
"\\#{s_hash}"
end
end

@ -48,6 +48,6 @@ defmodule Explorer.Migrator.TransactionsDenormalization do
@impl FillingMigration
def update_cache do
BackgroundMigrations.set_denormalization_finished(true)
BackgroundMigrations.set_transactions_denormalization_finished(true)
end
end

@ -0,0 +1,13 @@
defmodule Explorer.Repo.Migrations.AddTokenTypeToTokenTransfers do
use Ecto.Migration
@disable_ddl_transaction true
@disable_migration_lock true
def change do
alter table(:token_transfers) do
add_if_not_exists(:token_type, :string)
end
create_if_not_exists(index(:token_transfers, :token_type, concurrently: true))
end
end

@ -0,0 +1,13 @@
defmodule Explorer.Repo.Migrations.AddBlockConsensusToTokenTransfers do
use Ecto.Migration
@disable_ddl_transaction true
@disable_migration_lock true
def change do
alter table(:token_transfers) do
add_if_not_exists(:block_consensus, :boolean, default: true)
end
create_if_not_exists(index(:token_transfers, :block_consensus, concurrently: true))
end
end

@ -386,6 +386,7 @@ defmodule Explorer.Chain.Import.Runner.BlocksTest do
tt =
insert(:token_transfer,
token_ids: [id],
token_type: "ERC-721",
transaction: transaction,
token_contract_address: token_address,
block_number: block_number,
@ -404,6 +405,7 @@ defmodule Explorer.Chain.Import.Runner.BlocksTest do
for _ <- 0..10 do
insert(:token_transfer,
token_ids: [id],
token_type: "ERC-721",
transaction: transaction,
token_contract_address: tt.token_contract_address,
block_number: consensus_block_1.number,
@ -414,6 +416,7 @@ defmodule Explorer.Chain.Import.Runner.BlocksTest do
tt_1 =
insert(:token_transfer,
token_ids: [id],
token_type: "ERC-721",
transaction: transaction,
token_contract_address: tt.token_contract_address,
block_number: consensus_block_1.number,
@ -431,6 +434,7 @@ defmodule Explorer.Chain.Import.Runner.BlocksTest do
insert(:token_transfer,
token_ids: [id],
token_type: "ERC-721",
transaction: tx,
token_contract_address: tt.token_contract_address,
block_number: consensus_block_2.number,
@ -490,6 +494,7 @@ defmodule Explorer.Chain.Import.Runner.BlocksTest do
tt =
insert(:token_transfer,
token_ids: [id],
token_type: "ERC-721",
transaction: transaction,
token_contract_address: token_address,
block_number: block_number,

@ -163,6 +163,7 @@ defmodule Explorer.Chain.ImportTest do
from_address_hash: "0xe8ddc5c7a2d2f0d7a9798459c0104fdf5e987aca",
to_address_hash: "0x515c09c5bba1ed566b02a5b0599ec5d5d0aee73d",
token_contract_address_hash: "0x8bf38d4764929064f2d4d3a56520a76ab3df415b",
token_type: "ERC-20",
transaction_hash: "0x53bd884872de3e488692881baeec262e7b95234d3965248c39fe992fffd433e5"
}
],
@ -352,7 +353,8 @@ defmodule Explorer.Chain.ImportTest do
101, 36, 140, 57, 254, 153, 47, 255, 212, 51, 229>>
},
inserted_at: %{},
updated_at: %{}
updated_at: %{},
token_type: "ERC-20"
}
]
}} = Import.all(@import_data)

@ -1376,6 +1376,7 @@ defmodule Explorer.ChainTest do
from_address_hash: "0xe8ddc5c7a2d2f0d7a9798459c0104fdf5e987aca",
to_address_hash: "0x515c09c5bba1ed566b02a5b0599ec5d5d0aee73d",
token_contract_address_hash: "0x8bf38d4764929064f2d4d3a56520a76ab3df415b",
token_type: "ERC-20",
transaction_hash: "0x53bd884872de3e488692881baeec262e7b95234d3965248c39fe992fffd433e5"
}
]

@ -0,0 +1,82 @@
defmodule Explorer.Migrator.TokenTransferTokenTypeTest do
use Explorer.DataCase, async: false
import Ecto.Query
alias Explorer.Chain.Cache.BackgroundMigrations
alias Explorer.Chain.TokenTransfer
alias Explorer.Migrator.{TokenTransferTokenType, MigrationStatus}
alias Explorer.Repo
describe "Migrate token transfers" do
test "Set token_type and block_consensus for not processed token transfers" do
%{contract_address_hash: regular_token_hash} = regular_token = insert(:token)
Enum.each(0..4, fn _x ->
token_transfer =
insert(:token_transfer,
from_address: insert(:address),
token_contract_address: regular_token.contract_address,
token_type: nil,
block_consensus: nil
)
assert %{token_type: nil, block_consensus: nil} = token_transfer
end)
%{contract_address_hash: erc1155_token_hash} = erc1155_token = insert(:token, type: "ERC-1155")
Enum.each(0..4, fn _x ->
token_transfer =
insert(:token_transfer,
from_address: insert(:address),
token_contract_address: erc1155_token.contract_address,
token_type: nil,
block_consensus: nil,
token_ids: nil
)
assert %{token_type: nil, block_consensus: nil, token_ids: nil} = token_transfer
end)
assert MigrationStatus.get_status("tt_denormalization") == nil
TokenTransferTokenType.start_link([])
Process.sleep(100)
TokenTransfer
|> where([tt], tt.token_contract_address_hash == ^regular_token_hash)
|> Repo.all()
|> Repo.preload([:token, :block])
|> Enum.each(fn tt ->
assert %{
token_type: token_type,
token: %{type: token_type},
block_consensus: consensus,
block: %{consensus: consensus}
} = tt
assert not is_nil(token_type)
assert not is_nil(consensus)
end)
TokenTransfer
|> where([tt], tt.token_contract_address_hash == ^erc1155_token_hash)
|> Repo.all()
|> Repo.preload([:token, :block])
|> Enum.each(fn tt ->
assert %{
token_type: "ERC-20",
token: %{type: "ERC-1155"},
block_consensus: consensus,
block: %{consensus: consensus}
} = tt
assert not is_nil(consensus)
end)
assert MigrationStatus.get_status("tt_denormalization") == "completed"
assert BackgroundMigrations.get_tt_denormalization_finished() == true
end
end
end

@ -748,7 +748,7 @@ defmodule Explorer.Factory do
contract_code = Map.fetch!(contract_code_info(), :bytecode)
token_address = insert(:contract_address, contract_code: contract_code)
insert(:token, contract_address: token_address)
token = insert(:token, contract_address: token_address)
%TokenTransfer{
block: build(:block),
@ -757,8 +757,10 @@ defmodule Explorer.Factory do
from_address: from_address,
to_address: to_address,
token_contract_address: token_address,
token_type: token.type,
transaction: log.transaction,
log_index: log.index
log_index: log.index,
block_consensus: true
}
end

@ -47,8 +47,8 @@ defmodule Indexer.Transform.TokenTransfers do
erc1155_token_transfers.token_transfers ++
erc20_and_erc721_token_transfers.token_transfers ++ weth_transfers.token_transfers
{tokens, sanitized_token_transfers} = sanitize_token_types(rough_tokens, rough_token_transfers)
token_transfers = sanitize_weth_transfers(tokens, sanitized_token_transfers, weth_transfers.token_transfers)
tokens = sanitize_token_types(rough_tokens, rough_token_transfers)
token_transfers = sanitize_weth_transfers(tokens, rough_token_transfers, weth_transfers.token_transfers)
token_transfers
|> Enum.filter(fn token_transfer ->
@ -129,17 +129,9 @@ defmodule Indexer.Transform.TokenTransfers do
if token_type_priority(old_type) > token_type_priority(new_type), do: old_type, else: new_type
end)
actual_tokens =
Enum.map(tokens, fn %{contract_address_hash: hash} = token ->
Map.put(token, :type, actual_token_types_map[hash])
end)
actual_token_transfers =
Enum.map(token_transfers, fn %{token_contract_address_hash: hash} = tt ->
Map.put(tt, :token_type, actual_token_types_map[hash])
end)
{actual_tokens, actual_token_transfers}
Enum.map(tokens, fn %{contract_address_hash: hash} = token ->
Map.put(token, :type, actual_token_types_map[hash])
end)
end
defp define_token_type(token_transfers) do

@ -313,7 +313,7 @@ defmodule Indexer.Transform.TokenTransfersTest do
}
assert %{
token_transfers: [%{token_contract_address_hash: ^contract_address_hash, token_type: "ERC-1155"}],
token_transfers: [%{token_contract_address_hash: ^contract_address_hash, token_type: "ERC-20"}],
tokens: [%{contract_address_hash: ^contract_address_hash, type: "ERC-1155"}]
} = TokenTransfers.parse([log])
end
@ -352,7 +352,7 @@ defmodule Indexer.Transform.TokenTransfersTest do
assert %{
token_transfers: [
%{token_contract_address_hash: ^contract_address_hash, token_type: "ERC-1155"},
%{token_contract_address_hash: ^contract_address_hash, token_type: "ERC-1155"}
%{token_contract_address_hash: ^contract_address_hash, token_type: "ERC-20"}
],
tokens: [%{contract_address_hash: ^contract_address_hash, type: "ERC-1155"}]
} = TokenTransfers.parse(logs)

Loading…
Cancel
Save