diff --git a/apps/block_scout_web/lib/block_scout_web/templates/address/overview.html.eex b/apps/block_scout_web/lib/block_scout_web/templates/address/overview.html.eex index 66c61b4957..01b8929d58 100644 --- a/apps/block_scout_web/lib/block_scout_web/templates/address/overview.html.eex +++ b/apps/block_scout_web/lib/block_scout_web/templates/address/overview.html.eex @@ -35,10 +35,18 @@ <% end %> - - <%= Cldr.Number.to_string!(@transaction_count, format: "#,###") %> - - <%= gettext("Transactions Sent") %> + <%= if contract?(@address) do %> + <%= gettext(">=") %> + + <%= incoming_transaction_count(@address) %> + + <%= gettext("Incoming Transactions") %> + <% else %> + + <%= Cldr.Number.to_string!(@transaction_count, format: "#,###") %> + + <%= gettext("Transactions Sent") %> + <% end %> <%= gettext("Last Balance Update: Block #") %><%= @address.fetched_coin_balance_block_number %> 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 0fc50bef3a..fe6245ec54 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 @@ -213,6 +213,12 @@ defmodule BlockScoutWeb.AddressView do def token_title(%Token{name: name, symbol: symbol}), do: "#{name} (#{symbol})" + def incoming_transaction_count(%Address{} = address) do + count = Chain.address_to_incoming_transaction_count(address) + + Cldr.Number.to_string!(count, format: "#,###") + end + def trimmed_hash(%Hash{} = hash) do string_hash = to_string(hash) "#{String.slice(string_hash, 0..5)}–#{String.slice(string_hash, -6..-1)}" diff --git a/apps/block_scout_web/priv/gettext/default.pot b/apps/block_scout_web/priv/gettext/default.pot index 700b8eab0b..ad9661a722 100644 --- a/apps/block_scout_web/priv/gettext/default.pot +++ b/apps/block_scout_web/priv/gettext/default.pot @@ -189,10 +189,10 @@ msgstr "" #, elixir-format #: lib/block_scout_web/templates/address/_tabs.html.eex:40 #: lib/block_scout_web/templates/address/_tabs.html.eex:103 -#: lib/block_scout_web/templates/address/overview.html.eex:51 +#: lib/block_scout_web/templates/address/overview.html.eex:59 #: lib/block_scout_web/templates/address_validation/index.html.eex:30 #: lib/block_scout_web/templates/address_validation/index.html.eex:57 -#: lib/block_scout_web/views/address_view.ex:287 +#: lib/block_scout_web/views/address_view.ex:293 msgid "Blocks Validated" msgstr "" @@ -209,8 +209,8 @@ msgstr "" #, elixir-format #: lib/block_scout_web/templates/address/_validator_metadata_modal.html.eex:37 -#: lib/block_scout_web/templates/address/overview.html.eex:95 #: lib/block_scout_web/templates/address/overview.html.eex:103 +#: lib/block_scout_web/templates/address/overview.html.eex:111 #: lib/block_scout_web/templates/tokens/overview/_details.html.eex:91 #: lib/block_scout_web/templates/tokens/overview/_details.html.eex:99 msgid "Close" @@ -222,7 +222,7 @@ msgstr "" #: lib/block_scout_web/templates/address_validation/index.html.eex:39 #: lib/block_scout_web/templates/api_docs/_action_tile.html.eex:119 #: lib/block_scout_web/templates/api_docs/_action_tile.html.eex:141 -#: lib/block_scout_web/views/address_view.ex:284 +#: lib/block_scout_web/views/address_view.ex:290 msgid "Code" msgstr "" @@ -328,7 +328,7 @@ msgid "Copy Txn Hash" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address/overview.html.eex:61 +#: lib/block_scout_web/templates/address/overview.html.eex:69 msgid "Created by" msgstr "" @@ -494,7 +494,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:283 +#: lib/block_scout_web/views/address_view.ex:289 #: lib/block_scout_web/views/transaction_view.ex:258 msgid "Internal Transactions" msgstr "" @@ -685,7 +685,7 @@ msgstr "" #, elixir-format #: lib/block_scout_web/templates/address/overview.html.eex:13 -#: lib/block_scout_web/templates/address/overview.html.eex:94 +#: lib/block_scout_web/templates/address/overview.html.eex:102 #: lib/block_scout_web/templates/tokens/overview/_details.html.eex:13 #: lib/block_scout_web/templates/tokens/overview/_details.html.eex:13 #: lib/block_scout_web/templates/tokens/overview/_details.html.eex:90 @@ -702,7 +702,7 @@ msgstr "" #: lib/block_scout_web/templates/address/_tabs.html.eex:122 #: 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:285 +#: lib/block_scout_web/views/address_view.ex:291 #: lib/block_scout_web/views/tokens/overview_view.ex:37 msgid "Read Contract" msgstr "" @@ -901,7 +901,7 @@ msgstr "" #: lib/block_scout_web/templates/address_token_transfer/index.html.eex:12 #: lib/block_scout_web/templates/address_validation/index.html.eex:11 #: lib/block_scout_web/templates/address_validation/index.html.eex:19 -#: lib/block_scout_web/views/address_view.ex:281 +#: lib/block_scout_web/views/address_view.ex:287 msgid "Tokens" msgstr "" @@ -962,7 +962,7 @@ msgstr "" #: lib/block_scout_web/templates/block_transaction/index.html.eex:35 #: lib/block_scout_web/templates/chain/show.html.eex:93 #: lib/block_scout_web/templates/layout/_topnav.html.eex:35 -#: lib/block_scout_web/views/address_view.ex:282 +#: lib/block_scout_web/views/address_view.ex:288 msgid "Transactions" msgstr "" @@ -1094,7 +1094,7 @@ msgid "Yes" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address/overview.html.eex:67 +#: lib/block_scout_web/templates/address/overview.html.eex:75 msgid "at" msgstr "" @@ -1405,7 +1405,7 @@ msgstr "" #, elixir-format #: lib/block_scout_web/templates/address/_tabs.html.eex:30 #: lib/block_scout_web/templates/address/_tabs.html.eex:96 -#: lib/block_scout_web/views/address_view.ex:286 +#: lib/block_scout_web/views/address_view.ex:292 msgid "Coin Balance History" msgstr "" @@ -1647,12 +1647,12 @@ msgid "Enter contructor arguments if the contract had any" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address/overview.html.eex:44 +#: lib/block_scout_web/templates/address/overview.html.eex:52 msgid "Last Balance Update: Block #" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address/overview.html.eex:41 +#: lib/block_scout_web/templates/address/overview.html.eex:48 msgid "Transactions Sent" msgstr "" @@ -1688,6 +1688,16 @@ msgid "EVM Vesion" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address/overview.html.eex:75 +#: lib/block_scout_web/templates/address/overview.html.eex:39 +msgid ">=" +msgstr "" + +#, elixir-format +#: lib/block_scout_web/templates/address/overview.html.eex:43 +msgid "Incoming Transactions" +msgstr "" + +#, elixir-format +#: lib/block_scout_web/templates/address/overview.html.eex:83 msgid "Error: Could not determine contract creator." 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 60adf4683e..5528ff7001 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 @@ -189,10 +189,10 @@ msgstr "" #, elixir-format #: lib/block_scout_web/templates/address/_tabs.html.eex:40 #: lib/block_scout_web/templates/address/_tabs.html.eex:103 -#: lib/block_scout_web/templates/address/overview.html.eex:51 +#: lib/block_scout_web/templates/address/overview.html.eex:59 #: lib/block_scout_web/templates/address_validation/index.html.eex:30 #: lib/block_scout_web/templates/address_validation/index.html.eex:57 -#: lib/block_scout_web/views/address_view.ex:287 +#: lib/block_scout_web/views/address_view.ex:293 msgid "Blocks Validated" msgstr "" @@ -209,8 +209,8 @@ msgstr "" #, elixir-format #: lib/block_scout_web/templates/address/_validator_metadata_modal.html.eex:37 -#: lib/block_scout_web/templates/address/overview.html.eex:95 #: lib/block_scout_web/templates/address/overview.html.eex:103 +#: lib/block_scout_web/templates/address/overview.html.eex:111 #: lib/block_scout_web/templates/tokens/overview/_details.html.eex:91 #: lib/block_scout_web/templates/tokens/overview/_details.html.eex:99 msgid "Close" @@ -222,7 +222,7 @@ msgstr "" #: lib/block_scout_web/templates/address_validation/index.html.eex:39 #: lib/block_scout_web/templates/api_docs/_action_tile.html.eex:119 #: lib/block_scout_web/templates/api_docs/_action_tile.html.eex:141 -#: lib/block_scout_web/views/address_view.ex:284 +#: lib/block_scout_web/views/address_view.ex:290 msgid "Code" msgstr "" @@ -328,7 +328,7 @@ msgid "Copy Txn Hash" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address/overview.html.eex:61 +#: lib/block_scout_web/templates/address/overview.html.eex:69 msgid "Created by" msgstr "" @@ -494,7 +494,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:283 +#: lib/block_scout_web/views/address_view.ex:289 #: lib/block_scout_web/views/transaction_view.ex:258 msgid "Internal Transactions" msgstr "" @@ -685,7 +685,7 @@ msgstr "" #, elixir-format #: lib/block_scout_web/templates/address/overview.html.eex:13 -#: lib/block_scout_web/templates/address/overview.html.eex:94 +#: lib/block_scout_web/templates/address/overview.html.eex:102 #: lib/block_scout_web/templates/tokens/overview/_details.html.eex:13 #: lib/block_scout_web/templates/tokens/overview/_details.html.eex:13 #: lib/block_scout_web/templates/tokens/overview/_details.html.eex:90 @@ -702,7 +702,7 @@ msgstr "" #: lib/block_scout_web/templates/address/_tabs.html.eex:122 #: 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:285 +#: lib/block_scout_web/views/address_view.ex:291 #: lib/block_scout_web/views/tokens/overview_view.ex:37 msgid "Read Contract" msgstr "" @@ -901,7 +901,7 @@ msgstr "" #: lib/block_scout_web/templates/address_token_transfer/index.html.eex:12 #: lib/block_scout_web/templates/address_validation/index.html.eex:11 #: lib/block_scout_web/templates/address_validation/index.html.eex:19 -#: lib/block_scout_web/views/address_view.ex:281 +#: lib/block_scout_web/views/address_view.ex:287 msgid "Tokens" msgstr "" @@ -962,7 +962,7 @@ msgstr "" #: lib/block_scout_web/templates/block_transaction/index.html.eex:35 #: lib/block_scout_web/templates/chain/show.html.eex:93 #: lib/block_scout_web/templates/layout/_topnav.html.eex:35 -#: lib/block_scout_web/views/address_view.ex:282 +#: lib/block_scout_web/views/address_view.ex:288 msgid "Transactions" msgstr "" @@ -1094,7 +1094,7 @@ msgid "Yes" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address/overview.html.eex:67 +#: lib/block_scout_web/templates/address/overview.html.eex:75 msgid "at" msgstr "" @@ -1405,7 +1405,7 @@ msgstr "" #, elixir-format #: lib/block_scout_web/templates/address/_tabs.html.eex:30 #: lib/block_scout_web/templates/address/_tabs.html.eex:96 -#: lib/block_scout_web/views/address_view.ex:286 +#: lib/block_scout_web/views/address_view.ex:292 msgid "Coin Balance History" msgstr "" @@ -1647,12 +1647,12 @@ msgid "Enter contructor arguments if the contract had any" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address/overview.html.eex:44 +#: lib/block_scout_web/templates/address/overview.html.eex:52 msgid "Last Balance Update: Block #" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address/overview.html.eex:41 +#: lib/block_scout_web/templates/address/overview.html.eex:48 msgid "Transactions Sent" msgstr "" @@ -1688,6 +1688,16 @@ msgid "EVM Vesion" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/address/overview.html.eex:75 +#: lib/block_scout_web/templates/address/overview.html.eex:39 +msgid ">=" +msgstr "" + +#, elixir-format +#: lib/block_scout_web/templates/address/overview.html.eex:43 +msgid "Incoming Transactions" +msgstr "" + +#, elixir-format +#: lib/block_scout_web/templates/address/overview.html.eex:83 msgid "Error: Could not determine contract creator." msgstr "" diff --git a/apps/explorer/lib/explorer/chain.ex b/apps/explorer/lib/explorer/chain.ex index b40af9a343..33a84bc0c9 100644 --- a/apps/explorer/lib/explorer/chain.ex +++ b/apps/explorer/lib/explorer/chain.ex @@ -51,6 +51,8 @@ defmodule Explorer.Chain do @default_paging_options %PagingOptions{page_size: 50} + @max_incoming_transactions_count 10_000 + @typedoc """ The name of an association on the `t:Ecto.Schema.t/0` """ @@ -417,6 +419,24 @@ defmodule Explorer.Chain do Repo.aggregate(query, :count, :hash) end + @spec address_to_incoming_transaction_count(Address.t()) :: non_neg_integer() + def address_to_incoming_transaction_count(%Address{hash: address_hash}) do + paging_options = %PagingOptions{page_size: @max_incoming_transactions_count} + + base_query = + paging_options + |> fetch_transactions() + + to_address_query = + base_query + |> where([t], t.to_address_hash == ^address_hash) + + Repo.aggregate(to_address_query, :count, :hash, timeout: :infinity) + end + + @spec max_incoming_transactions_count() :: non_neg_integer() + def max_incoming_transactions_count, do: @max_incoming_transactions_count + @doc """ How many blocks have confirmed `block` based on the current `max_block_number` diff --git a/apps/explorer/priv/repo/migrations/20190314084907_add_index_to_to_address_hash.exs b/apps/explorer/priv/repo/migrations/20190314084907_add_index_to_to_address_hash.exs new file mode 100644 index 0000000000..a46822a17c --- /dev/null +++ b/apps/explorer/priv/repo/migrations/20190314084907_add_index_to_to_address_hash.exs @@ -0,0 +1,7 @@ +defmodule Explorer.Repo.Migrations.AddIndexToToAddressHash do + use Ecto.Migration + + def change do + create(index(:transactions, [:to_address_hash])) + end +end diff --git a/apps/explorer/test/explorer/chain_test.exs b/apps/explorer/test/explorer/chain_test.exs index 77fcb4b2e8..accc733181 100644 --- a/apps/explorer/test/explorer/chain_test.exs +++ b/apps/explorer/test/explorer/chain_test.exs @@ -597,6 +597,20 @@ defmodule Explorer.ChainTest do end end + describe "address_to_incoming_transaction_count/1" do + test "without transactions" do + address = insert(:address) + + assert Chain.address_to_incoming_transaction_count(address) == 0 + end + + test "with transactions" do + %Transaction{to_address: to_address} = insert(:transaction) + + assert Chain.address_to_incoming_transaction_count(to_address) == 1 + end + end + describe "confirmations/1" do test "with block.number == block_height " do block = insert(:block)