From 54a1010a1116cfe957aa7630433fd49e36912b32 Mon Sep 17 00:00:00 2001 From: pasqu4le Date: Fri, 5 Jul 2019 17:57:57 +0200 Subject: [PATCH 1/7] Improve Address controllers This is yet another step in checking controllers for improvements. In particular this time Address controllers were checked and this (mostly refactoring) changes were made: - a few calls to `Explorer.Chain.hash_to_address` were modified to avoid useless preloads where possible - `Explorer.Chain.find_or_insert_address_from_hash` was modified for the very same reason, because it calls the previous function - `Explorer.Chain.address_to_logs` has been modified to have a more legible where clause - both `Explorer.Chain.hash_to_address` and `Explorer.Chain.token_from_address_hash` were modified to support `necessity_by_association_option`s for consistency --- CHANGELOG.md | 1 + .../address_coin_balance_controller.ex | 2 +- ...address_internal_transaction_controller.ex | 2 +- .../controllers/address_logs_controller.ex | 4 +- .../controllers/address_token_controller.ex | 2 +- .../address_transaction_controller.ex | 4 +- .../address_validation_controller.ex | 2 +- .../controllers/tokens/holder_controller.ex | 4 +- .../tokens/inventory_controller.ex | 4 +- .../tokens/read_contract_controller.ex | 4 +- .../controllers/tokens/transfer_controller.ex | 4 +- apps/explorer/lib/explorer/chain.ex | 95 +++++++++++++------ apps/explorer/test/explorer/chain_test.exs | 4 +- apps/indexer/lib/indexer/fetcher/token.ex | 4 +- .../lib/indexer/fetcher/token_updater.ex | 4 +- 15 files changed, 98 insertions(+), 42 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fdf79338cd..b5a83d3e09 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ - [#2291](https://github.com/poanetwork/blockscout/pull/2291) - dashboard fix for md resolution, transactions load fix, block info row fix, addresses page issue, check mark issue ### Chore +- [#2305](https://github.com/poanetwork/blockscout/pull/2305) - Improve Address controllers - [#2289](https://github.com/poanetwork/blockscout/pull/2289) - Optional websockets for dev environment diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/address_coin_balance_controller.ex b/apps/block_scout_web/lib/block_scout_web/controllers/address_coin_balance_controller.ex index 312edffcca..d43f99a382 100644 --- a/apps/block_scout_web/lib/block_scout_web/controllers/address_coin_balance_controller.ex +++ b/apps/block_scout_web/lib/block_scout_web/controllers/address_coin_balance_controller.ex @@ -16,7 +16,7 @@ defmodule BlockScoutWeb.AddressCoinBalanceController do def index(conn, %{"address_id" => address_hash_string, "type" => "JSON"} = params) do with {:ok, address_hash} <- Chain.string_to_address_hash(address_hash_string), - {:ok, address} <- Chain.hash_to_address(address_hash) do + {:ok, address} <- Chain.hash_to_address(address_hash, [], false) do full_options = paging_options(params) coin_balances_plus_one = Chain.address_to_coin_balances(address_hash, full_options) diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/address_internal_transaction_controller.ex b/apps/block_scout_web/lib/block_scout_web/controllers/address_internal_transaction_controller.ex index c4f9b11c3b..fd5813a1d4 100644 --- a/apps/block_scout_web/lib/block_scout_web/controllers/address_internal_transaction_controller.ex +++ b/apps/block_scout_web/lib/block_scout_web/controllers/address_internal_transaction_controller.ex @@ -16,7 +16,7 @@ defmodule BlockScoutWeb.AddressInternalTransactionController do def index(conn, %{"address_id" => address_hash_string, "type" => "JSON"} = params) do with {:ok, address_hash} <- Chain.string_to_address_hash(address_hash_string), - {:ok, address} <- Chain.hash_to_address(address_hash) do + {:ok, address} <- Chain.hash_to_address(address_hash, [], false) do full_options = [ necessity_by_association: %{ diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/address_logs_controller.ex b/apps/block_scout_web/lib/block_scout_web/controllers/address_logs_controller.ex index db76b9d447..55070b4cd8 100644 --- a/apps/block_scout_web/lib/block_scout_web/controllers/address_logs_controller.ex +++ b/apps/block_scout_web/lib/block_scout_web/controllers/address_logs_controller.ex @@ -16,7 +16,7 @@ defmodule BlockScoutWeb.AddressLogsController do def index(conn, %{"address_id" => address_hash_string, "type" => "JSON"} = params) do with {:ok, address_hash} <- Chain.string_to_address_hash(address_hash_string), - {:ok, address} <- Chain.hash_to_address(address_hash) do + {:ok, address} <- Chain.hash_to_address(address_hash, [], false) do logs_plus_one = Chain.address_to_logs(address, paging_options(params)) {results, next_page} = split_list_by_page(logs_plus_one) @@ -74,7 +74,7 @@ defmodule BlockScoutWeb.AddressLogsController do def search_logs(conn, %{"topic" => topic, "address_id" => address_hash_string} = params) do with {:ok, address_hash} <- Chain.string_to_address_hash(address_hash_string), - {:ok, address} <- Chain.hash_to_address(address_hash) do + {:ok, address} <- Chain.hash_to_address(address_hash, [], false) do topic = String.trim(topic) formatted_topic = if String.starts_with?(topic, "0x"), do: topic, else: "0x" <> topic diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/address_token_controller.ex b/apps/block_scout_web/lib/block_scout_web/controllers/address_token_controller.ex index 312b90176b..8d5a60a1ac 100644 --- a/apps/block_scout_web/lib/block_scout_web/controllers/address_token_controller.ex +++ b/apps/block_scout_web/lib/block_scout_web/controllers/address_token_controller.ex @@ -12,7 +12,7 @@ defmodule BlockScoutWeb.AddressTokenController do def index(conn, %{"address_id" => address_hash_string, "type" => "JSON"} = params) do with {:ok, address_hash} <- Chain.string_to_address_hash(address_hash_string), - {:ok, address} <- Chain.hash_to_address(address_hash) do + {:ok, address} <- Chain.hash_to_address(address_hash, [], false) do tokens_plus_one = Chain.address_tokens_with_balance(address_hash, paging_options(params)) {tokens, next_page} = split_list_by_page(tokens_plus_one) 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 51503fd7c1..f0ff5f3f12 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 @@ -28,8 +28,10 @@ defmodule BlockScoutWeb.AddressTransactionController do ] def index(conn, %{"address_id" => address_hash_string, "type" => "JSON"} = params) do + address_options = [necessity_by_association: %{:names => :optional}] + with {:ok, address_hash} <- Chain.string_to_address_hash(address_hash_string), - {:ok, address} <- Chain.hash_to_address(address_hash, [:names], false) 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) diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/address_validation_controller.ex b/apps/block_scout_web/lib/block_scout_web/controllers/address_validation_controller.ex index 42170cbfc9..84036923de 100644 --- a/apps/block_scout_web/lib/block_scout_web/controllers/address_validation_controller.ex +++ b/apps/block_scout_web/lib/block_scout_web/controllers/address_validation_controller.ex @@ -17,7 +17,7 @@ defmodule BlockScoutWeb.AddressValidationController do def index(conn, %{"address_id" => address_hash_string, "type" => "JSON"} = params) do with {:ok, address_hash} <- Chain.string_to_address_hash(address_hash_string), - {:ok, address} <- Chain.find_or_insert_address_from_hash(address_hash) do + {:ok, address} <- Chain.find_or_insert_address_from_hash(address_hash, [], false) do full_options = Keyword.merge( [ diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/tokens/holder_controller.ex b/apps/block_scout_web/lib/block_scout_web/controllers/tokens/holder_controller.ex index 3b23d4099a..4de35fc012 100644 --- a/apps/block_scout_web/lib/block_scout_web/controllers/tokens/holder_controller.ex +++ b/apps/block_scout_web/lib/block_scout_web/controllers/tokens/holder_controller.ex @@ -43,8 +43,10 @@ defmodule BlockScoutWeb.Tokens.HolderController do end def index(conn, %{"token_id" => address_hash_string}) do + options = [necessity_by_association: %{[contract_address: :smart_contract] => :optional}] + with {:ok, address_hash} <- Chain.string_to_address_hash(address_hash_string), - {:ok, token} <- Chain.token_from_address_hash(address_hash, [{:contract_address, :smart_contract}]) do + {:ok, token} <- Chain.token_from_address_hash(address_hash, options) do render( conn, "index.html", diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/tokens/inventory_controller.ex b/apps/block_scout_web/lib/block_scout_web/controllers/tokens/inventory_controller.ex index bc9111a34d..b9783b2c63 100644 --- a/apps/block_scout_web/lib/block_scout_web/controllers/tokens/inventory_controller.ex +++ b/apps/block_scout_web/lib/block_scout_web/controllers/tokens/inventory_controller.ex @@ -60,8 +60,10 @@ defmodule BlockScoutWeb.Tokens.InventoryController do end def index(conn, %{"token_id" => address_hash_string}) do + options = [necessity_by_association: %{[contract_address: :smart_contract] => :optional}] + with {:ok, address_hash} <- Chain.string_to_address_hash(address_hash_string), - {:ok, token} <- Chain.token_from_address_hash(address_hash, [{:contract_address, :smart_contract}]) do + {:ok, token} <- Chain.token_from_address_hash(address_hash, options) do render( conn, "index.html", diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/tokens/read_contract_controller.ex b/apps/block_scout_web/lib/block_scout_web/controllers/tokens/read_contract_controller.ex index 050802da54..f6ae63f537 100644 --- a/apps/block_scout_web/lib/block_scout_web/controllers/tokens/read_contract_controller.ex +++ b/apps/block_scout_web/lib/block_scout_web/controllers/tokens/read_contract_controller.ex @@ -4,8 +4,10 @@ defmodule BlockScoutWeb.Tokens.ReadContractController do alias Explorer.{Chain, Market} def index(conn, %{"token_id" => address_hash_string}) do + options = [necessity_by_association: %{[contract_address: :smart_contract] => :optional}] + with {:ok, address_hash} <- Chain.string_to_address_hash(address_hash_string), - {:ok, token} <- Chain.token_from_address_hash(address_hash, [{:contract_address, :smart_contract}]) do + {:ok, token} <- Chain.token_from_address_hash(address_hash, options) do render( conn, "index.html", diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/tokens/transfer_controller.ex b/apps/block_scout_web/lib/block_scout_web/controllers/tokens/transfer_controller.ex index f92bcf2ff1..9b75087c45 100644 --- a/apps/block_scout_web/lib/block_scout_web/controllers/tokens/transfer_controller.ex +++ b/apps/block_scout_web/lib/block_scout_web/controllers/tokens/transfer_controller.ex @@ -44,8 +44,10 @@ defmodule BlockScoutWeb.Tokens.TransferController do end def index(conn, %{"token_id" => address_hash_string}) do + options = [necessity_by_association: %{[contract_address: :smart_contract] => :optional}] + with {:ok, address_hash} <- Chain.string_to_address_hash(address_hash_string), - {:ok, token} <- Chain.token_from_address_hash(address_hash, [{:contract_address, :smart_contract}]) do + {:ok, token} <- Chain.token_from_address_hash(address_hash, options) do render( conn, "index.html", diff --git a/apps/explorer/lib/explorer/chain.ex b/apps/explorer/lib/explorer/chain.ex index fcad694a58..8a7a9151b3 100644 --- a/apps/explorer/lib/explorer/chain.ex +++ b/apps/explorer/lib/explorer/chain.ex @@ -273,12 +273,12 @@ defmodule Explorer.Chain do inner_join: transaction in assoc(log, :transaction), order_by: [desc: transaction.block_number, desc: transaction.index], preload: [:transaction], - where: - log.address_hash == ^address_hash and - (transaction.block_number < ^block_number or - (transaction.block_number == ^block_number and transaction.index > ^transaction_index) or - (transaction.block_number == ^block_number and transaction.index == ^transaction_index and - log.index > ^log_index)), + where: transaction.block_number < ^block_number, + or_where: transaction.block_number == ^block_number and transaction.index > ^transaction_index, + or_where: + transaction.block_number == ^block_number and transaction.index == ^transaction_index and + log.index > ^log_index, + where: log.address_hash == ^address_hash, limit: ^paging_options.page_size, select: log ) @@ -676,31 +676,40 @@ defmodule Explorer.Chain do iex> Explorer.Chain.hash_to_address(hash) {:error, :not_found} - Optionally accepts: - - a list of bindings to preload, just like `Ecto.Query.preload/3` - - a boolean to also fetch the `has_decompiled_code?` virtual field or not + ## Options + + * `:necessity_by_association` - use to load `t:association/0` as `:required` or `:optional`. If an association is + `:required`, and the `t:Explorer.Chain.Address.t/0` has no associated record for that association, + then the `t:Explorer.Chain.Address.t/0` will not be included in the list. + + Optionally it also accepts a boolean to fetch the `has_decompiled_code?` virtual field or not """ - @spec hash_to_address(Hash.Address.t(), [Macro.t()], boolean()) :: {:ok, Address.t()} | {:error, :not_found} + @spec hash_to_address(Hash.Address.t(), [necessity_by_association_option], boolean()) :: + {:ok, Address.t()} | {:error, :not_found} def hash_to_address( %Hash{byte_count: unquote(Hash.Address.byte_count())} = hash, - preloads \\ [ - :contracts_creation_internal_transaction, - :names, - :smart_contract, - :token, - :contracts_creation_transaction + options \\ [ + necessity_by_association: %{ + :contracts_creation_internal_transaction => :optional, + :names => :optional, + :smart_contract => :optional, + :token => :optional, + :contracts_creation_transaction => :optional + } ], query_decompiled_code_flag \\ true ) do + necessity_by_association = Keyword.get(options, :necessity_by_association, %{}) + query = from( address in Address, - preload: ^preloads, where: address.hash == ^hash ) query + |> join_associations(necessity_by_association) |> with_decompiled_code_flag(hash, query_decompiled_code_flag) |> Repo.one() |> case do @@ -772,16 +781,39 @@ defmodule Explorer.Chain do iex> {:ok, %Explorer.Chain.Address{hash: found_hash}} = Explorer.Chain.hash_to_address(hash) iex> found_hash == hash true + + + ## Options + + * `:necessity_by_association` - use to load `t:association/0` as `:required` or `:optional`. If an association is + `:required`, and the `t:Explorer.Chain.Address.t/0` has no associated record for that association, + then the `t:Explorer.Chain.Address.t/0` will not be included in the list. + + Optionally it also accepts a boolean to fetch the `has_decompiled_code?` virtual field or not + """ - @spec find_or_insert_address_from_hash(Hash.Address.t()) :: {:ok, Address.t()} - def find_or_insert_address_from_hash(%Hash{byte_count: unquote(Hash.Address.byte_count())} = hash) do - case hash_to_address(hash) do + @spec find_or_insert_address_from_hash(Hash.Address.t(), [necessity_by_association_option], boolean()) :: + {:ok, Address.t()} + def find_or_insert_address_from_hash( + %Hash{byte_count: unquote(Hash.Address.byte_count())} = hash, + options \\ [ + necessity_by_association: %{ + :contracts_creation_internal_transaction => :optional, + :names => :optional, + :smart_contract => :optional, + :token => :optional, + :contracts_creation_transaction => :optional + } + ], + query_decompiled_code_flag \\ true + ) do + case hash_to_address(hash, options, query_decompiled_code_flag) do {:ok, address} -> {:ok, address} {:error, :not_found} -> create_address(%{hash: to_string(hash)}) - hash_to_address(hash) + hash_to_address(hash, options, query_decompiled_code_flag) end end @@ -2715,21 +2747,30 @@ defmodule Explorer.Chain do @doc """ Fetches a `t:Token.t/0` by an address hash. - Optionally accepts a list of bindings to preload, just like `Ecto.Query.preload/3` + ## Options + + * `:necessity_by_association` - use to load `t:association/0` as `:required` or `:optional`. If an association is + `:required`, and the `t:Token.t/0` has no associated record for that association, + then the `t:Token.t/0` will not be included in the list. """ - @spec token_from_address_hash(Hash.Address.t(), [Macro.t()]) :: {:ok, Token.t()} | {:error, :not_found} + @spec token_from_address_hash(Hash.Address.t(), [necessity_by_association_option]) :: + {:ok, Token.t()} | {:error, :not_found} def token_from_address_hash( %Hash{byte_count: unquote(Hash.Address.byte_count())} = hash, - preloads \\ [] + options \\ [] ) do + necessity_by_association = Keyword.get(options, :necessity_by_association, %{}) + query = from( token in Token, - where: token.contract_address_hash == ^hash, - preload: ^preloads + where: token.contract_address_hash == ^hash ) - case Repo.one(query) do + query + |> join_associations(necessity_by_association) + |> Repo.one() + |> case do nil -> {:error, :not_found} diff --git a/apps/explorer/test/explorer/chain_test.exs b/apps/explorer/test/explorer/chain_test.exs index cfb8b5ab14..bcc3843102 100644 --- a/apps/explorer/test/explorer/chain_test.exs +++ b/apps/explorer/test/explorer/chain_test.exs @@ -3456,9 +3456,9 @@ defmodule Explorer.ChainTest do smart_contract = build(:smart_contract) address = insert(:address, smart_contract: smart_contract) token = insert(:token, contract_address: address) + options = [necessity_by_association: %{[contract_address: :smart_contract] => :optional}] - assert {:ok, result} = - Chain.token_from_address_hash(token.contract_address_hash, [{:contract_address, :smart_contract}]) + assert {:ok, result} = Chain.token_from_address_hash(token.contract_address_hash, options) assert smart_contract = result.contract_address.smart_contract end diff --git a/apps/indexer/lib/indexer/fetcher/token.ex b/apps/indexer/lib/indexer/fetcher/token.ex index e0992a450f..8c924e2ad2 100644 --- a/apps/indexer/lib/indexer/fetcher/token.ex +++ b/apps/indexer/lib/indexer/fetcher/token.ex @@ -52,7 +52,9 @@ defmodule Indexer.Fetcher.Token do @impl BufferedTask @decorate trace(name: "fetch", resource: "Indexer.Fetcher.Token.run/2", service: :indexer, tracer: Tracer) def run([token_contract_address], _json_rpc_named_arguments) do - case Chain.token_from_address_hash(token_contract_address, [{:contract_address, :smart_contract}]) do + options = [necessity_by_association: %{[contract_address: :smart_contract] => :optional}] + + case Chain.token_from_address_hash(token_contract_address, options) do {:ok, %Token{} = token} -> catalog_token(token) end diff --git a/apps/indexer/lib/indexer/fetcher/token_updater.ex b/apps/indexer/lib/indexer/fetcher/token_updater.ex index 304f2f068c..f596687ff8 100644 --- a/apps/indexer/lib/indexer/fetcher/token_updater.ex +++ b/apps/indexer/lib/indexer/fetcher/token_updater.ex @@ -36,8 +36,10 @@ defmodule Indexer.Fetcher.TokenUpdater do @doc false def update_metadata(token_addresses) when is_list(token_addresses) do + options = [necessity_by_association: %{[contract_address: :smart_contract] => :optional}] + Enum.each(token_addresses, fn address -> - case Chain.token_from_address_hash(address, [{:contract_address, :smart_contract}]) do + case Chain.token_from_address_hash(address, options) do {:ok, %Token{cataloged: true} = token} -> update_metadata(token) end From e16ef8420d092753b3a83993af7ec4c345f02737 Mon Sep 17 00:00:00 2001 From: Andrew Cravenho Date: Sat, 6 Jul 2019 23:48:43 -0400 Subject: [PATCH 2/7] Add GoJoy Chain to README --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 5dc91fb8ef..3c95a5d125 100644 --- a/README.md +++ b/README.md @@ -41,6 +41,7 @@ Currently available full-featured block explorers (Etherscan, Etherchain, Blockc | | | [Kotti Testnet](https://kottiexplorer.ethernode.io/) | | | | [Loom](http://plasma-blockexplorer.dappchains.com/) | | | | [Tenda](https://tenda.network) | +| | | [GoJoy Chain](https://gojoychain.com/) | Current BlockScout versions for hosted projects are available [on the forum](https://forum.poa.network/t/deployed-instances-on-blockscout-com/1938). From 5f57d05951303a4752ea78d4a50497355f9cf0de Mon Sep 17 00:00:00 2001 From: Andrew Cravenho Date: Sun, 7 Jul 2019 00:06:29 -0400 Subject: [PATCH 3/7] Update Changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3d4e6f755f..48f8b3045f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ ### Chore - [#2302](https://github.com/poanetwork/blockscout/pull/2302) - fix names for xDai source - [#2289](https://github.com/poanetwork/blockscout/pull/2289) - Optional websockets for dev environment +- [#2307](https://github.com/poanetwork/blockscout/pull/2307) - add GoJoy to README ## 2.0.1-beta From 137dc813d9da683e9bf055948d92cb54d021a1ab Mon Sep 17 00:00:00 2001 From: Ayrat Badykov Date: Mon, 8 Jul 2019 09:56:47 +0300 Subject: [PATCH 4/7] parse url for api docs --- .../lib/block_scout_web/views/api_docs_view.ex | 4 +++- .../block_scout_web/views/api_docs_view_test.exs | 14 ++++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) create mode 100644 apps/block_scout_web/test/block_scout_web/views/api_docs_view_test.exs diff --git a/apps/block_scout_web/lib/block_scout_web/views/api_docs_view.ex b/apps/block_scout_web/lib/block_scout_web/views/api_docs_view.ex index f9c280925a..aca1ba558d 100644 --- a/apps/block_scout_web/lib/block_scout_web/views/api_docs_view.ex +++ b/apps/block_scout_web/lib/block_scout_web/views/api_docs_view.ex @@ -36,7 +36,9 @@ defmodule BlockScoutWeb.APIDocsView do def blockscout_url do if System.get_env("BLOCKSCOUT_HOST") do - "http://" <> System.get_env("BLOCKSCOUT_HOST") + %URI{host: host, scheme: scheme} = URI.parse(Endpoint.url()) + + scheme <> "://" <> host else Endpoint.url() end diff --git a/apps/block_scout_web/test/block_scout_web/views/api_docs_view_test.exs b/apps/block_scout_web/test/block_scout_web/views/api_docs_view_test.exs new file mode 100644 index 0000000000..3c2634d22b --- /dev/null +++ b/apps/block_scout_web/test/block_scout_web/views/api_docs_view_test.exs @@ -0,0 +1,14 @@ +defmodule BlockScoutWeb.ApiDocsViewTest do + use BlockScoutWeb.ConnCase, async: true + + alias BlockScoutWeb.{APIDocsView, Endpoint} + + describe "blockscout_url/0" do + test "returns url with scheme and host without port" do + System.put_env("BLOCKSCOUT_HOST", "localhost") + + assert APIDocsView.blockscout_url() == "http://localhost" + assert Endpoint.url() == "http://localhost:4002" + end + end +end From d6de19938c7cdc4d6cc4d87232387e82f2964c9b Mon Sep 17 00:00:00 2001 From: Ayrat Badykov Date: Mon, 8 Jul 2019 10:47:33 +0300 Subject: [PATCH 5/7] add CHANGELOG entry --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3d4e6f755f..aefbeda489 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ - [#2294](https://github.com/poanetwork/blockscout/pull/2294) - add healthy block period checking endpoint ### Fixes +- [#2310](https://github.com/poanetwork/blockscout/pull/2310) - parse url for api docs - [#2299](https://github.com/poanetwork/blockscout/pull/2299) - fix interpolation in error message - [#2303](https://github.com/poanetwork/blockscout/pull/2303) - fix transaction csv download link - [#2304](https://github.com/poanetwork/blockscout/pull/2304) - footer grid fix for md resolution From 23a23293d17d5789a9d2a5cc138bb1477a266e99 Mon Sep 17 00:00:00 2001 From: Ayrat Badykov Date: Mon, 8 Jul 2019 17:16:01 +0300 Subject: [PATCH 6/7] add path --- .../lib/block_scout_web/views/api_docs_view.ex | 3 ++- .../block_scout_web/views/api_docs_view_test.exs | 12 +++++++++++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/apps/block_scout_web/lib/block_scout_web/views/api_docs_view.ex b/apps/block_scout_web/lib/block_scout_web/views/api_docs_view.ex index aca1ba558d..40860e37bb 100644 --- a/apps/block_scout_web/lib/block_scout_web/views/api_docs_view.ex +++ b/apps/block_scout_web/lib/block_scout_web/views/api_docs_view.ex @@ -37,8 +37,9 @@ defmodule BlockScoutWeb.APIDocsView do def blockscout_url do if System.get_env("BLOCKSCOUT_HOST") do %URI{host: host, scheme: scheme} = URI.parse(Endpoint.url()) + path = System.get_env("NETWORK_PATH") || "/" - scheme <> "://" <> host + scheme <> "://" <> host <> path else Endpoint.url() end diff --git a/apps/block_scout_web/test/block_scout_web/views/api_docs_view_test.exs b/apps/block_scout_web/test/block_scout_web/views/api_docs_view_test.exs index 3c2634d22b..7005798c7b 100644 --- a/apps/block_scout_web/test/block_scout_web/views/api_docs_view_test.exs +++ b/apps/block_scout_web/test/block_scout_web/views/api_docs_view_test.exs @@ -7,8 +7,18 @@ defmodule BlockScoutWeb.ApiDocsViewTest do test "returns url with scheme and host without port" do System.put_env("BLOCKSCOUT_HOST", "localhost") - assert APIDocsView.blockscout_url() == "http://localhost" + assert APIDocsView.blockscout_url() == "http://localhost/" assert Endpoint.url() == "http://localhost:4002" end + + test "returns url with scheme and host with path" do + System.put_env("BLOCKSCOUT_HOST", "localhost/chain/dog") + System.put_env("NETWORK_PATH", "/chain/dog") + + assert APIDocsView.blockscout_url() == "http://localhost/chain/dog" + assert Endpoint.url() == "http://localhost:4002" + + System.put_env("NETWORK_PATH", "") + end end end From 8489c6db5b8c7da18a02ba38467f1a9b5de6a7f4 Mon Sep 17 00:00:00 2001 From: Ayrat Badykov Date: Mon, 8 Jul 2019 17:24:24 +0300 Subject: [PATCH 7/7] fix tests --- .../test/block_scout_web/views/api_docs_view_test.exs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/block_scout_web/test/block_scout_web/views/api_docs_view_test.exs b/apps/block_scout_web/test/block_scout_web/views/api_docs_view_test.exs index 7005798c7b..8501f27abc 100644 --- a/apps/block_scout_web/test/block_scout_web/views/api_docs_view_test.exs +++ b/apps/block_scout_web/test/block_scout_web/views/api_docs_view_test.exs @@ -6,8 +6,9 @@ defmodule BlockScoutWeb.ApiDocsViewTest do describe "blockscout_url/0" do test "returns url with scheme and host without port" do System.put_env("BLOCKSCOUT_HOST", "localhost") + System.put_env("NETWORK_PATH", "") - assert APIDocsView.blockscout_url() == "http://localhost/" + assert APIDocsView.blockscout_url() == "http://localhost" assert Endpoint.url() == "http://localhost:4002" end