From a8823abe17242509cf16bccc79e1a457b847e133 Mon Sep 17 00:00:00 2001 From: pasqu4le Date: Fri, 12 Jul 2019 15:55:49 +0200 Subject: [PATCH 1/3] Fetch rewards in parallel with transactions Problem: the Address main page is too slow. Part of the reason is that it has to execute 3 queries. Solution: since 2 of these queries are unrelated to each other (transactions and rewards) they will be executed in parallel. --- CHANGELOG.md | 1 + .../address_transaction_controller.ex | 4 +- apps/explorer/lib/explorer/chain.ex | 39 +++++++++++-------- 3 files changed, 26 insertions(+), 18 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7a8a58beef..b1bdf3a3d5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ ## Current ### Features +- [#2352](https://github.com/poanetwork/blockscout/pull/2352) - Fetch rewards in parallel with transactions - [#2294](https://github.com/poanetwork/blockscout/pull/2294) - add healthy block period checking endpoint ### Fixes diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/address_transaction_controller.ex b/apps/block_scout_web/lib/block_scout_web/controllers/address_transaction_controller.ex index dc71bed50b..f6d9b8a30f 100644 --- a/apps/block_scout_web/lib/block_scout_web/controllers/address_transaction_controller.ex +++ b/apps/block_scout_web/lib/block_scout_web/controllers/address_transaction_controller.ex @@ -23,7 +23,8 @@ defmodule BlockScoutWeb.AddressTransactionController do [token_transfers: :token] => :optional, [token_transfers: :to_address] => :optional, [token_transfers: :from_address] => :optional, - [token_transfers: :token_contract_address] => :optional + [token_transfers: :token_contract_address] => :optional, + :block => :required } ] @@ -34,7 +35,6 @@ defmodule BlockScoutWeb.AddressTransactionController do {:ok, address} <- Chain.hash_to_address(address_hash, address_options, false) do options = @transaction_necessity_by_association - |> put_in([:necessity_by_association, :block], :required) |> Keyword.merge(paging_options(params)) |> Keyword.merge(current_filter(params)) diff --git a/apps/explorer/lib/explorer/chain.ex b/apps/explorer/lib/explorer/chain.ex index 05d6407dfb..17116658bf 100644 --- a/apps/explorer/lib/explorer/chain.ex +++ b/apps/explorer/lib/explorer/chain.ex @@ -222,25 +222,17 @@ defmodule Explorer.Chain do Transaction.t() ] def address_to_transactions_with_rewards(address_hash, options \\ []) when is_list(options) do - direction = Keyword.get(options, :direction) - necessity_by_association = Keyword.get(options, :necessity_by_association, %{}) paging_options = Keyword.get(options, :paging_options, @default_paging_options) - transaction_hashes_from_token_transfers = - TokenTransfer.where_any_address_fields_match(direction, address_hash, paging_options) - - transactions_list = - paging_options - |> fetch_transactions() - |> Transaction.where_transaction_matches(transaction_hashes_from_token_transfers, direction, address_hash) - |> join_associations(necessity_by_association) - |> Transaction.preload_token_transfers(address_hash) - |> Repo.all() - if Application.get_env(:block_scout_web, BlockScoutWeb.Chain)[:has_emission_funds] do + rewards_task = + Task.async(fn -> + Reward.fetch_emission_rewards_tuples(address_hash, paging_options) + end) + address_hash - |> Reward.fetch_emission_rewards_tuples(paging_options) - |> Enum.concat(transactions_list) + |> address_to_transactions_without_rewards(paging_options, options) + |> Enum.concat(Task.await(rewards_task)) |> Enum.sort_by(fn item -> case item do {%Reward{} = emission_reward, _} -> @@ -252,10 +244,25 @@ defmodule Explorer.Chain do end) |> Enum.take(paging_options.page_size) else - transactions_list + address_to_transactions_without_rewards(address_hash, paging_options, options) end end + defp address_to_transactions_without_rewards(address_hash, paging_options, options) do + direction = Keyword.get(options, :direction) + necessity_by_association = Keyword.get(options, :necessity_by_association, %{}) + + transaction_hashes_from_token_transfers = + TokenTransfer.where_any_address_fields_match(direction, address_hash, paging_options) + + paging_options + |> fetch_transactions() + |> Transaction.where_transaction_matches(transaction_hashes_from_token_transfers, direction, address_hash) + |> join_associations(necessity_by_association) + |> Transaction.preload_token_transfers(address_hash) + |> Repo.all() + end + @spec address_to_logs(Hash.Address.t(), Keyword.t()) :: [Log.t()] def address_to_logs(address_hash, options \\ []) when is_list(options) do paging_options = Keyword.get(options, :paging_options) || %PagingOptions{page_size: 50} From e03de6f659984874c7d5ebe7064b0d77add6c6c4 Mon Sep 17 00:00:00 2001 From: Ayrat Badykov Date: Mon, 15 Jul 2019 16:37:16 +0300 Subject: [PATCH 2/3] add parameters example for eth rpc --- .../block_scout_web/controllers/api/rpc/eth_controller.ex | 6 ++++++ .../lib/block_scout_web/templates/api_docs/eth_rpc.html.eex | 2 ++ 2 files changed, 8 insertions(+) diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/api/rpc/eth_controller.ex b/apps/block_scout_web/lib/block_scout_web/controllers/api/rpc/eth_controller.ex index bb386940b1..028084e73f 100644 --- a/apps/block_scout_web/lib/block_scout_web/controllers/api/rpc/eth_controller.ex +++ b/apps/block_scout_web/lib/block_scout_web/controllers/api/rpc/eth_controller.ex @@ -12,12 +12,18 @@ defmodule BlockScoutWeb.API.RPC.EthController do notes: """ the `earliest` parameter will not work as expected currently, because genesis block balances are not currently imported + """, + example: """ + {"id": 0, "jsonrpc": "2.0", "method": "eth_getBalance", "params": ["0x0000000000000000000000000000000000000007", "2"]} """ }, "eth_getLogs" => %{ action: :eth_get_logs, notes: """ Will never return more than 1000 log entries. + """, + example: """ + {"id": 0, "jsonrpc": "2.0", "method": "eth_getLogs", "params": [{"address": "0x0000000000000000000000000000000000000026","topics": ["0x01"]}]} """ } } diff --git a/apps/block_scout_web/lib/block_scout_web/templates/api_docs/eth_rpc.html.eex b/apps/block_scout_web/lib/block_scout_web/templates/api_docs/eth_rpc.html.eex index ba6be00103..134b3e13e1 100644 --- a/apps/block_scout_web/lib/block_scout_web/templates/api_docs/eth_rpc.html.eex +++ b/apps/block_scout_web/lib/block_scout_web/templates/api_docs/eth_rpc.html.eex @@ -22,11 +22,13 @@ Supported Method Notes + Parameters example <%= for {method, info} <- Map.to_list(@documentation) do %> <%= method %> <%= Map.get(info, :notes, "N/A") %> + <%= Map.get(info, :example, "N/A") %> <% end %> From 873a730aed29e815dcbd10ac9cf8b3da4733cb74 Mon Sep 17 00:00:00 2001 From: Ayrat Badykov Date: Mon, 15 Jul 2019 16:42:30 +0300 Subject: [PATCH 3/3] add CHANGELOG entry --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7a8a58beef..ad3f98f921 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,7 @@ - [#2326](https://github.com/poanetwork/blockscout/pull/2326) - fix nested constructor arguments ### Chore +- [#2363](https://github.com/poanetwork/blockscout/pull/2363) - add parameters example for eth rpc - [#2342](https://github.com/poanetwork/blockscout/pull/2342) - Upgrade Postgres image version in Docker setup - [#2325](https://github.com/poanetwork/blockscout/pull/2325) - Reduce function input to address' hash only where possible - [#2323](https://github.com/poanetwork/blockscout/pull/2323) - Group Explorer caches