diff --git a/apps/block_scout_web/lib/block_scout_web/templates/address_token/_tokens.html.eex b/apps/block_scout_web/lib/block_scout_web/templates/address_token/_tokens.html.eex index c54b7db2f5..a40f23f2c7 100644 --- a/apps/block_scout_web/lib/block_scout_web/templates/address_token/_tokens.html.eex +++ b/apps/block_scout_web/lib/block_scout_web/templates/address_token/_tokens.html.eex @@ -8,7 +8,7 @@ ) do %> <%= token_name(@token) %> <% end %> - <%= @token.type %> - <%= number_of_transfers(@token) %> + <%= @token.type %> - <%= @token.contract_address_hash %>
diff --git a/apps/block_scout_web/lib/block_scout_web/views/address_token_view.ex b/apps/block_scout_web/lib/block_scout_web/views/address_token_view.ex index 527391e0ad..bf41494b38 100644 --- a/apps/block_scout_web/lib/block_scout_web/views/address_token_view.ex +++ b/apps/block_scout_web/lib/block_scout_web/views/address_token_view.ex @@ -1,7 +1,3 @@ defmodule BlockScoutWeb.AddressTokenView do use BlockScoutWeb, :view - - def number_of_transfers(token) do - ngettext("%{count} transfer", "%{count} transfers", token.transfers_count) - end end diff --git a/apps/block_scout_web/priv/gettext/default.pot b/apps/block_scout_web/priv/gettext/default.pot index 9f4f876e59..103cd20b78 100644 --- a/apps/block_scout_web/priv/gettext/default.pot +++ b/apps/block_scout_web/priv/gettext/default.pot @@ -12,13 +12,6 @@ msgid_plural "%{count} transactions" msgstr[0] "" msgstr[1] "" -#, elixir-format -#: lib/block_scout_web/views/address_token_view.ex:5 -msgid "%{count} transfer" -msgid_plural "%{count} transfers" -msgstr[0] "" -msgstr[1] "" - #, elixir-format #: lib/block_scout_web/templates/address/_metatags.html.eex:3 msgid "%{address} - %{subnetwork} Explorer" diff --git a/apps/block_scout_web/priv/gettext/en/LC_MESSAGES/default.po b/apps/block_scout_web/priv/gettext/en/LC_MESSAGES/default.po index cb1e883553..ab95f607a1 100644 --- a/apps/block_scout_web/priv/gettext/en/LC_MESSAGES/default.po +++ b/apps/block_scout_web/priv/gettext/en/LC_MESSAGES/default.po @@ -12,13 +12,6 @@ msgid_plural "%{count} transactions" msgstr[0] "" msgstr[1] "" -#, elixir-format -#: lib/block_scout_web/views/address_token_view.ex:5 -msgid "%{count} transfer" -msgid_plural "%{count} transfers" -msgstr[0] "" -msgstr[1] "" - #, elixir-format #: lib/block_scout_web/templates/address/_metatags.html.eex:3 msgid "%{address} - %{subnetwork} Explorer" diff --git a/apps/block_scout_web/test/block_scout_web/controllers/address_token_controller_test.exs b/apps/block_scout_web/test/block_scout_web/controllers/address_token_controller_test.exs index 20e386f530..5efd4b3edd 100644 --- a/apps/block_scout_web/test/block_scout_web/controllers/address_token_controller_test.exs +++ b/apps/block_scout_web/test/block_scout_web/controllers/address_token_controller_test.exs @@ -33,14 +33,14 @@ defmodule BlockScoutWeb.AddressTokenControllerTest do |> insert(name: "token2") insert( - :token_balance, + :address_current_token_balance, address: address, token_contract_address_hash: token1.contract_address_hash, value: 1000 ) insert( - :token_balance, + :address_current_token_balance, address: address, token_contract_address_hash: token2.contract_address_hash, value: 0 @@ -82,13 +82,12 @@ defmodule BlockScoutWeb.AddressTokenControllerTest do token = insert(:token, name: "A Token#{i}", type: "ERC-20") insert( - :token_balance, + :address_current_token_balance, token_contract_address_hash: token.contract_address_hash, address: address, value: 1000 ) - insert(:token_transfer, token_contract_address: token.contract_address, from_address: address) acc ++ [token.name] end) |> Enum.sort() @@ -96,21 +95,21 @@ defmodule BlockScoutWeb.AddressTokenControllerTest do token = insert(:token, name: "Another Token", type: "ERC-721") insert( - :token_balance, + :address_current_token_balance, token_contract_address_hash: token.contract_address_hash, address: address, value: 1000 ) - insert(:token_transfer, token: token, from_address: address) - %Token{name: name, type: type} = token + %Token{name: name, type: type, inserted_at: inserted_at} = token start_supervised!(BlockValidationCounter) conn = get(conn, address_token_path(BlockScoutWeb.Endpoint, :index, address.hash), %{ - "name" => name, - "type" => type + "token_name" => name, + "token_type" => type, + "token_inserted_at" => inserted_at }) actual_tokens = @@ -128,7 +127,7 @@ defmodule BlockScoutWeb.AddressTokenControllerTest do token = insert(:token, name: "A Token#{i}", type: "ERC-20") insert( - :token_balance, + :address_current_token_balance, token_contract_address_hash: token.contract_address_hash, address: address, value: 1000 diff --git a/apps/block_scout_web/test/block_scout_web/features/viewing_addresses_test.exs b/apps/block_scout_web/test/block_scout_web/features/viewing_addresses_test.exs index 32c01e0af1..8821e42122 100644 --- a/apps/block_scout_web/test/block_scout_web/features/viewing_addresses_test.exs +++ b/apps/block_scout_web/test/block_scout_web/features/viewing_addresses_test.exs @@ -429,7 +429,7 @@ defmodule BlockScoutWeb.ViewingAddressesTest do token_contract_address: contract_address ) - insert(:token_balance, address: lincoln, token_contract_address_hash: contract_address.hash) + insert(:address_current_token_balance, address: lincoln, token_contract_address_hash: contract_address.hash) start_supervised!(BlockValidationCounter) BlockValidationCounter.consolidate_blocks() diff --git a/apps/block_scout_web/test/block_scout_web/views/address_token_view_test.exs b/apps/block_scout_web/test/block_scout_web/views/address_token_view_test.exs deleted file mode 100644 index 89f0baa20d..0000000000 --- a/apps/block_scout_web/test/block_scout_web/views/address_token_view_test.exs +++ /dev/null @@ -1,25 +0,0 @@ -defmodule BlockScoutWeb.AddressTokenViewTest do - use BlockScoutWeb.ConnCase, async: true - - alias BlockScoutWeb.AddressTokenView - - describe "number_of_transfers/1" do - test "returns the singular form when there is only one transfer" do - token = %{transfers_count: 1} - - assert AddressTokenView.number_of_transfers(token) == "1 transfer" - end - - test "returns the plural form when there is more than one transfer" do - token = %{transfers_count: 2} - - assert AddressTokenView.number_of_transfers(token) == "2 transfers" - end - - test "returns the plural form when there are 0 transfers" do - token = %{transfers_count: 0} - - assert AddressTokenView.number_of_transfers(token) == "0 transfers" - end - end -end diff --git a/apps/explorer/lib/explorer/chain/address/token.ex b/apps/explorer/lib/explorer/chain/address/token.ex index 1ca29bff94..1dd167b779 100644 --- a/apps/explorer/lib/explorer/chain/address/token.ex +++ b/apps/explorer/lib/explorer/chain/address/token.ex @@ -16,9 +16,10 @@ defmodule Explorer.Chain.Address.Token do import Ecto.Query alias Explorer.{Chain, PagingOptions} - alias Explorer.Chain.{Address, Address.TokenBalance, Hash} + alias Explorer.Chain.{Address, Hash} + alias Explorer.Chain.Address.CurrentTokenBalance - @enforce_keys [:contract_address_hash, :inserted_at, :name, :symbol, :balance, :decimals, :type, :transfers_count] + @enforce_keys [:contract_address_hash, :inserted_at, :name, :symbol, :balance, :decimals, :type] defstruct @enforce_keys @default_paging_options %PagingOptions{page_size: 50} @@ -31,20 +32,18 @@ defmodule Explorer.Chain.Address.Token do def list_address_tokens_with_balance(address_hash, options \\ []) do paging_options = Keyword.get(options, :paging_options, @default_paging_options) - Chain.Token - |> Chain.Token.join_with_transfers() - |> join_with_last_balance(address_hash) - |> order_filter_and_group(address_hash) + address_hash + |> join_with_last_balance() + |> order_filter_and_group() |> page_tokens(paging_options) |> limit(^paging_options.page_size) end - defp order_filter_and_group(query, address_hash) do + defp order_filter_and_group(query) do from( - [token, transfer, balance] in query, + [token, balance] in query, order_by: fragment("? DESC, LOWER(?) ASC NULLS LAST", token.type, token.name), - where: - (transfer.to_address_hash == ^address_hash or transfer.from_address_hash == ^address_hash) and balance.value > 0, + where: balance.value > 0, group_by: [token.name, token.symbol, balance.value, token.type, token.contract_address_hash], select: %Address.Token{ contract_address_hash: token.contract_address_hash, @@ -53,24 +52,21 @@ defmodule Explorer.Chain.Address.Token do symbol: token.symbol, balance: balance.value, decimals: max(token.decimals), - type: token.type, - transfers_count: count(token.contract_address_hash) + type: token.type } ) end - defp join_with_last_balance(queryable, address_hash) do + defp join_with_last_balance(address_hash) do last_balance_query = from( - tb in TokenBalance, + tb in CurrentTokenBalance, where: tb.address_hash == ^address_hash, - distinct: :token_contract_address_hash, - order_by: [desc: :block_number], select: %{value: tb.value, token_contract_address_hash: tb.token_contract_address_hash} ) from( - t in queryable, + t in Chain.Token, join: tb in subquery(last_balance_query), on: tb.token_contract_address_hash == t.contract_address_hash ) diff --git a/apps/explorer/lib/explorer/chain/token.ex b/apps/explorer/lib/explorer/chain/token.ex index 65a03caf52..1d5513affd 100644 --- a/apps/explorer/lib/explorer/chain/token.ex +++ b/apps/explorer/lib/explorer/chain/token.ex @@ -22,7 +22,7 @@ defmodule Explorer.Chain.Token do import Ecto.{Changeset, Query} alias Ecto.Changeset - alias Explorer.Chain.{Address, Hash, Token, TokenTransfer} + alias Explorer.Chain.{Address, Hash, Token} @typedoc """ * `:name` - Name of the token @@ -87,14 +87,6 @@ defmodule Explorer.Chain.Token do end end - def join_with_transfers(queryable \\ Token) do - from( - t in queryable, - join: tt in TokenTransfer, - on: tt.token_contract_address_hash == t.contract_address_hash - ) - end - @doc """ Builds an `Ecto.Query` to fetch the cataloged tokens. diff --git a/apps/explorer/test/explorer/chain/address/token_test.exs b/apps/explorer/test/explorer/chain/address/token_test.exs index 3fa903444d..501afcc77e 100644 --- a/apps/explorer/test/explorer/chain/address/token_test.exs +++ b/apps/explorer/test/explorer/chain/address/token_test.exs @@ -16,26 +16,12 @@ defmodule Explorer.Chain.Address.TokenTest do |> Repo.preload(:contract_address) insert( - :token_balance, + :address_current_token_balance, address: address, token_contract_address_hash: token.contract_address_hash, value: 1000 ) - insert( - :token_transfer, - token_contract_address: token.contract_address, - from_address: address, - to_address: build(:address) - ) - - insert( - :token_transfer, - token_contract_address: token.contract_address, - from_address: build(:address), - to_address: address - ) - fetched_token = address.hash |> Address.Token.list_address_tokens_with_balance() @@ -49,8 +35,7 @@ defmodule Explorer.Chain.Address.TokenTest do symbol: "TC", balance: Decimal.new(1000), decimals: Decimal.new(0), - type: "ERC-721", - transfers_count: 2 + type: "ERC-721" } end @@ -63,7 +48,7 @@ defmodule Explorer.Chain.Address.TokenTest do |> Repo.preload(:contract_address) insert( - :token_balance, + :address_current_token_balance, address: address, token_contract_address_hash: token.contract_address_hash, value: 1000 @@ -82,7 +67,7 @@ defmodule Explorer.Chain.Address.TokenTest do |> Repo.preload(:contract_address) insert( - :token_balance, + :address_current_token_balance, address: address, token_contract_address_hash: token2.contract_address_hash, value: 1000 @@ -113,7 +98,7 @@ defmodule Explorer.Chain.Address.TokenTest do |> Repo.preload(:contract_address) insert( - :token_balance, + :address_current_token_balance, address: address, token_contract_address_hash: token.contract_address_hash, value: 1000 @@ -132,7 +117,7 @@ defmodule Explorer.Chain.Address.TokenTest do |> Repo.preload(:contract_address) insert( - :token_balance, + :address_current_token_balance, address: address, token_contract_address_hash: token2.contract_address_hash, value: 1000 @@ -151,7 +136,7 @@ defmodule Explorer.Chain.Address.TokenTest do |> Repo.preload(:contract_address) insert( - :token_balance, + :address_current_token_balance, address: address, token_contract_address_hash: token3.contract_address_hash, value: 1000 @@ -182,7 +167,7 @@ defmodule Explorer.Chain.Address.TokenTest do |> Repo.preload(:contract_address) insert( - :token_balance, + :address_current_token_balance, address: address, token_contract_address_hash: token.contract_address_hash, value: 1000 @@ -201,7 +186,7 @@ defmodule Explorer.Chain.Address.TokenTest do |> Repo.preload(:contract_address) insert( - :token_balance, + :address_current_token_balance, address: address, token_contract_address_hash: token2.contract_address_hash, value: 1000 @@ -220,7 +205,7 @@ defmodule Explorer.Chain.Address.TokenTest do |> Repo.preload(:contract_address) insert( - :token_balance, + :address_current_token_balance, address: address, token_contract_address_hash: token3.contract_address_hash, value: 1000 @@ -267,44 +252,6 @@ defmodule Explorer.Chain.Address.TokenTest do assert fetched_token == nil end - test "brings the value of the last balance" do - address = insert(:address) - - token = - :token - |> insert(name: "atoken", type: "ERC-721", decimals: 0, symbol: "AT") - |> Repo.preload(:contract_address) - - insert( - :token_balance, - address: address, - token_contract_address_hash: token.contract_address_hash, - value: 1000 - ) - - insert( - :token_balance, - address: address, - token_contract_address_hash: token.contract_address_hash, - value: 1234 - ) - - insert( - :token_transfer, - token_contract_address: token.contract_address, - from_address: address, - to_address: build(:address) - ) - - fetched_token = - address.hash - |> Address.Token.list_address_tokens_with_balance() - |> Repo.all() - |> List.first() - - assert fetched_token.balance == Decimal.new(1234) - end - test "ignores token if the last balance is zero" do address = insert(:address)