diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/address_controller.ex b/apps/block_scout_web/lib/block_scout_web/controllers/address_controller.ex index 3c29ffa4f3..22825ae63a 100644 --- a/apps/block_scout_web/lib/block_scout_web/controllers/address_controller.ex +++ b/apps/block_scout_web/lib/block_scout_web/controllers/address_controller.ex @@ -7,9 +7,10 @@ defmodule BlockScoutWeb.AddressController do def index(conn, _params) do render(conn, "index.html", - addresses: Chain.list_top_addresses(), + address_tx_count_pairs: Chain.list_top_addresses(), address_estimated_count: Chain.address_estimated_count(), - exchange_rate: Market.get_exchange_rate(Explorer.coin()) || Token.null() + exchange_rate: Market.get_exchange_rate(Explorer.coin()) || Token.null(), + total_supply: Chain.total_supply() ) end diff --git a/apps/block_scout_web/lib/block_scout_web/templates/address/_tile.html.eex b/apps/block_scout_web/lib/block_scout_web/templates/address/_tile.html.eex index 8963b44a54..eddf794799 100644 --- a/apps/block_scout_web/lib/block_scout_web/templates/address/_tile.html.eex +++ b/apps/block_scout_web/lib/block_scout_web/templates/address/_tile.html.eex @@ -15,7 +15,7 @@ - <%= transaction_count(@address) %> + <%= @tx_count %> <%= gettext "Transactions sent" %> <% if validator?(@address) do %> @@ -36,7 +36,7 @@ data-usd-exchange-rate="<%= @exchange_rate.usd_value %>"> - (<%= balance_percentage(@address) %>) + (<%= balance_percentage(@address, @total_supply) %>) diff --git a/apps/block_scout_web/lib/block_scout_web/templates/address/index.html.eex b/apps/block_scout_web/lib/block_scout_web/templates/address/index.html.eex index 13db6de433..851aa9a0d7 100644 --- a/apps/block_scout_web/lib/block_scout_web/templates/address/index.html.eex +++ b/apps/block_scout_web/lib/block_scout_web/templates/address/index.html.eex @@ -9,9 +9,10 @@

- <%= for {address, index} <- Enum.with_index(@addresses, 1) do %> + <%= for {{address, tx_count}, index} <- Enum.with_index(@address_tx_count_pairs, 1) do %> <%= render "_tile.html", address: address, index: index, exchange_rate: @exchange_rate, + total_supply: @total_supply, tx_count: tx_count, validation_count: validation_count(address) %> <% end %> diff --git a/apps/block_scout_web/lib/block_scout_web/views/address_view.ex b/apps/block_scout_web/lib/block_scout_web/views/address_view.ex index 041d1e9aa7..a9fdfbc746 100644 --- a/apps/block_scout_web/lib/block_scout_web/views/address_view.ex +++ b/apps/block_scout_web/lib/block_scout_web/views/address_view.ex @@ -1,7 +1,7 @@ defmodule BlockScoutWeb.AddressView do use BlockScoutWeb, :view - import BlockScoutWeb.AddressController, only: [transaction_count: 1, validation_count: 1] + import BlockScoutWeb.AddressController, only: [validation_count: 1] alias BlockScoutWeb.LayoutView alias Explorer.Chain @@ -94,16 +94,20 @@ defmodule BlockScoutWeb.AddressView do format_wei_value(balance, :ether) end - def balance_percentage(%Address{fetched_coin_balance: balance}) do + def balance_percentage(%Address{fetched_coin_balance: balance}, total_supply) do balance |> Wei.to(:ether) - |> Decimal.div(Decimal.new(Chain.total_supply())) + |> Decimal.div(Decimal.new(total_supply)) |> Decimal.mult(100) |> Decimal.round(4) |> Decimal.to_string(:normal) |> Kernel.<>("% #{gettext("Market Cap")}") end + def balance_percentage(%Address{fetched_coin_balance: _} = address) do + balance_percentage(address, Chain.total_supply()) + end + def balance_block_number(%Address{fetched_coin_balance_block_number: nil}), do: "" def balance_block_number(%Address{fetched_coin_balance_block_number: fetched_coin_balance_block_number}) do diff --git a/apps/block_scout_web/priv/gettext/default.pot b/apps/block_scout_web/priv/gettext/default.pot index 9ae0e22d88..761c33ba42 100644 --- a/apps/block_scout_web/priv/gettext/default.pot +++ b/apps/block_scout_web/priv/gettext/default.pot @@ -227,7 +227,7 @@ msgstr "" #: lib/block_scout_web/templates/address_validation/index.html.eex:90 #: lib/block_scout_web/templates/api_docs/_action_tile.html.eex:122 #: lib/block_scout_web/templates/api_docs/_action_tile.html.eex:141 -#: lib/block_scout_web/views/address_view.ex:210 +#: lib/block_scout_web/views/address_view.ex:214 msgid "Code" msgstr "" @@ -508,7 +508,7 @@ msgstr "" #: lib/block_scout_web/templates/transaction/_tabs.html.eex:14 #: lib/block_scout_web/templates/transaction/_tabs.html.eex:43 #: lib/block_scout_web/templates/transaction_internal_transaction/index.html.eex:10 -#: lib/block_scout_web/views/address_view.ex:209 +#: lib/block_scout_web/views/address_view.ex:213 #: lib/block_scout_web/views/transaction_view.ex:176 msgid "Internal Transactions" msgstr "" @@ -725,7 +725,7 @@ msgstr "" #: lib/block_scout_web/templates/address_validation/index.html.eex:53 #: lib/block_scout_web/templates/tokens/overview/_tabs.html.eex:33 #: lib/block_scout_web/templates/tokens/overview/_tabs.html.eex:75 -#: lib/block_scout_web/views/address_view.ex:211 +#: lib/block_scout_web/views/address_view.ex:215 #: lib/block_scout_web/views/tokens/overview_view.ex:37 msgid "Read Contract" msgstr "" @@ -930,7 +930,7 @@ msgstr "" #: lib/block_scout_web/templates/address_validation/index.html.eex:18 #: lib/block_scout_web/templates/address_validation/index.html.eex:62 #: lib/block_scout_web/templates/address_validation/index.html.eex:70 -#: lib/block_scout_web/views/address_view.ex:207 +#: lib/block_scout_web/views/address_view.ex:211 msgid "Tokens" msgstr "" @@ -991,7 +991,7 @@ msgstr "" #: lib/block_scout_web/templates/block_transaction/index.html.eex:35 #: lib/block_scout_web/templates/chain/show.html.eex:71 #: lib/block_scout_web/templates/layout/_topnav.html.eex:35 -#: lib/block_scout_web/views/address_view.ex:208 +#: lib/block_scout_web/views/address_view.ex:212 msgid "Transactions" msgstr "" 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 d55c8e73de..14a11d48f5 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 @@ -227,7 +227,7 @@ msgstr "" #: lib/block_scout_web/templates/address_validation/index.html.eex:90 #: lib/block_scout_web/templates/api_docs/_action_tile.html.eex:122 #: lib/block_scout_web/templates/api_docs/_action_tile.html.eex:141 -#: lib/block_scout_web/views/address_view.ex:210 +#: lib/block_scout_web/views/address_view.ex:214 msgid "Code" msgstr "" @@ -508,7 +508,7 @@ msgstr "" #: lib/block_scout_web/templates/transaction/_tabs.html.eex:14 #: lib/block_scout_web/templates/transaction/_tabs.html.eex:43 #: lib/block_scout_web/templates/transaction_internal_transaction/index.html.eex:10 -#: lib/block_scout_web/views/address_view.ex:209 +#: lib/block_scout_web/views/address_view.ex:213 #: lib/block_scout_web/views/transaction_view.ex:176 msgid "Internal Transactions" msgstr "" @@ -725,7 +725,7 @@ msgstr "" #: lib/block_scout_web/templates/address_validation/index.html.eex:53 #: lib/block_scout_web/templates/tokens/overview/_tabs.html.eex:33 #: lib/block_scout_web/templates/tokens/overview/_tabs.html.eex:75 -#: lib/block_scout_web/views/address_view.ex:211 +#: lib/block_scout_web/views/address_view.ex:215 #: lib/block_scout_web/views/tokens/overview_view.ex:37 msgid "Read Contract" msgstr "" @@ -930,7 +930,7 @@ msgstr "" #: lib/block_scout_web/templates/address_validation/index.html.eex:18 #: lib/block_scout_web/templates/address_validation/index.html.eex:62 #: lib/block_scout_web/templates/address_validation/index.html.eex:70 -#: lib/block_scout_web/views/address_view.ex:207 +#: lib/block_scout_web/views/address_view.ex:211 msgid "Tokens" msgstr "" @@ -991,7 +991,7 @@ msgstr "" #: lib/block_scout_web/templates/block_transaction/index.html.eex:35 #: lib/block_scout_web/templates/chain/show.html.eex:71 #: lib/block_scout_web/templates/layout/_topnav.html.eex:35 -#: lib/block_scout_web/views/address_view.ex:208 +#: lib/block_scout_web/views/address_view.ex:212 msgid "Transactions" msgstr "" diff --git a/apps/block_scout_web/test/block_scout_web/controllers/address_controller_test.exs b/apps/block_scout_web/test/block_scout_web/controllers/address_controller_test.exs index 1ad14d2952..071667cf77 100644 --- a/apps/block_scout_web/test/block_scout_web/controllers/address_controller_test.exs +++ b/apps/block_scout_web/test/block_scout_web/controllers/address_controller_test.exs @@ -10,7 +10,9 @@ defmodule BlockScoutWeb.AddressControllerTest do conn = get(conn, address_path(conn, :index)) - assert conn.assigns.addresses |> Enum.map(& &1.hash) == address_hashes + assert conn.assigns.address_tx_count_pairs + |> Enum.map(fn {address, _transaction_count} -> address end) + |> Enum.map(& &1.hash) == address_hashes end end diff --git a/apps/explorer/lib/explorer/chain.ex b/apps/explorer/lib/explorer/chain.ex index 51eac0ed1a..8cfb97bfcf 100644 --- a/apps/explorer/lib/explorer/chain.ex +++ b/apps/explorer/lib/explorer/chain.ex @@ -920,13 +920,20 @@ defmodule Explorer.Chain do Lists the top 250 `t:Explorer.Chain.Address.t/0`'s' in descending order based on coin balance. """ - @spec list_top_addresses :: [Address.t()] + @spec list_top_addresses :: [{Address.t(), non_neg_integer()}] def list_top_addresses do - Address - |> limit(250) - |> order_by(desc: :fetched_coin_balance, asc: :hash) - |> where([address], address.fetched_coin_balance > ^0) - |> Repo.all() + query = + from(a in Address, + left_join: t in Transaction, + on: a.hash == t.from_address_hash, + where: a.fetched_coin_balance > ^0, + group_by: [a.hash, a.fetched_coin_balance], + order_by: [desc: a.fetched_coin_balance, asc: a.hash], + select: {a, fragment("coalesce(1 + max(?), 0)", t.nonce)}, + limit: 250 + ) + + Repo.all(query) end @doc """ diff --git a/apps/explorer/test/explorer/chain_test.exs b/apps/explorer/test/explorer/chain_test.exs index 0634f02bf0..0ed17acb4e 100644 --- a/apps/explorer/test/explorer/chain_test.exs +++ b/apps/explorer/test/explorer/chain_test.exs @@ -1182,7 +1182,10 @@ defmodule Explorer.ChainTest do |> Enum.map(&insert(:address, fetched_coin_balance: &1)) |> Enum.map(& &1.hash) - assert address_hashes == Enum.map(Chain.list_top_addresses(), & &1.hash) + assert address_hashes == + Chain.list_top_addresses() + |> Enum.map(fn {address, _transaction_count} -> address end) + |> Enum.map(& &1.hash) end test "with top addresses in order with matching value" do @@ -1201,7 +1204,10 @@ defmodule Explorer.ChainTest do |> insert(fetched_coin_balance: 4, hash: Enum.fetch!(test_hashes, 4)) |> Map.fetch!(:hash) - assert [first_result_hash | tail] == Enum.map(Chain.list_top_addresses(), & &1.hash) + assert [first_result_hash | tail] == + Chain.list_top_addresses() + |> Enum.map(fn {address, _transaction_count} -> address end) + |> Enum.map(& &1.hash) end end