Fix after review; Add test

np-addresses-endpoint-performance
Nikita Pozdniakov 1 year ago
parent aee725b151
commit 98210e4bf1
No known key found for this signature in database
GPG Key ID: F344106F9804FE5F
  1. 10
      apps/block_scout_web/lib/block_scout_web/controllers/api/v2/address_controller.ex
  2. 62
      apps/block_scout_web/test/block_scout_web/controllers/api/v2/address_controller_test.exs
  3. 11
      apps/explorer/lib/explorer/chain/address.ex

@ -16,7 +16,7 @@ defmodule BlockScoutWeb.API.V2.AddressController do
alias BlockScoutWeb.AccessHelper alias BlockScoutWeb.AccessHelper
alias BlockScoutWeb.API.V2.{BlockView, TransactionView, WithdrawalView} alias BlockScoutWeb.API.V2.{BlockView, TransactionView, WithdrawalView}
alias Explorer.{Chain, Market, Repo} alias Explorer.{Chain, Market}
alias Explorer.Chain.Address alias Explorer.Chain.Address
alias Explorer.Chain.Address.Counters alias Explorer.Chain.Address.Counters
alias Explorer.Chain.Token.Instance alias Explorer.Chain.Token.Instance
@ -71,7 +71,8 @@ defmodule BlockScoutWeb.API.V2.AddressController do
def address(conn, %{"address_hash_param" => address_hash_string} = params) do def address(conn, %{"address_hash_param" => address_hash_string} = params) do
with {:ok, _address_hash, address} <- validate_address(address_hash_string, params, @address_options), with {:ok, _address_hash, address} <- validate_address(address_hash_string, params, @address_options),
fully_preloaded_address <- maybe_preload_smart_contract_associations(address) do fully_preloaded_address <-
Address.maybe_preload_smart_contract_associations(address, @contract_address_preloads, @api_true) do
CoinBalanceOnDemand.trigger_fetch(fully_preloaded_address) CoinBalanceOnDemand.trigger_fetch(fully_preloaded_address)
conn conn
@ -482,9 +483,4 @@ defmodule BlockScoutWeb.API.V2.AddressController do
{:ok, address_hash, address} {:ok, address_hash, address}
end end
end end
defp maybe_preload_smart_contract_associations(%Address{contract_code: nil} = address), do: address
defp maybe_preload_smart_contract_associations(%Address{contract_code: _} = address),
do: Repo.replica().preload(address, @contract_address_preloads)
end end

@ -1,5 +1,6 @@
defmodule BlockScoutWeb.API.V2.AddressControllerTest do defmodule BlockScoutWeb.API.V2.AddressControllerTest do
use BlockScoutWeb.ConnCase use BlockScoutWeb.ConnCase
use EthereumJSONRPC.Case, async: false
alias BlockScoutWeb.Models.UserFromAuth alias BlockScoutWeb.Models.UserFromAuth
alias Explorer.{Chain, Repo} alias Explorer.{Chain, Repo}
@ -22,6 +23,9 @@ defmodule BlockScoutWeb.API.V2.AddressControllerTest do
alias Explorer.Chain.Address.CurrentTokenBalance alias Explorer.Chain.Address.CurrentTokenBalance
import Explorer.Chain, only: [hash_to_lower_case_string: 1] import Explorer.Chain, only: [hash_to_lower_case_string: 1]
import Mox
setup :set_mox_global
describe "/addresses/{address_hash}" do describe "/addresses/{address_hash}" do
test "get 404 on non existing address", %{conn: conn} do test "get 404 on non existing address", %{conn: conn} do
@ -44,7 +48,7 @@ defmodule BlockScoutWeb.API.V2.AddressControllerTest do
correct_response = %{ correct_response = %{
"hash" => Address.checksum(address.hash), "hash" => Address.checksum(address.hash),
"is_contract" => false, "is_contract" => false,
"is_verified" => false, "is_verified" => nil,
"name" => nil, "name" => nil,
"private_tags" => [], "private_tags" => [],
"public_tags" => [], "public_tags" => [],
@ -79,6 +83,47 @@ defmodule BlockScoutWeb.API.V2.AddressControllerTest do
assert ^correct_response = json_response(request, 200) assert ^correct_response = json_response(request, 200)
end end
test "get contract info", %{conn: conn} do
smart_contract = insert(:smart_contract)
tx =
insert(:transaction,
to_address_hash: nil,
to_address: nil,
created_contract_address_hash: smart_contract.address_hash,
created_contract_address: smart_contract.address
)
insert(:address_name,
address: smart_contract.address,
primary: true,
name: smart_contract.name,
address_hash: smart_contract.address_hash
)
name = smart_contract.name
from = Address.checksum(tx.from_address_hash)
tx_hash = to_string(tx.hash)
address_hash = Address.checksum(smart_contract.address_hash)
get_eip1967_implementation_non_zero_address()
request = get(conn, "/api/v2/addresses/#{Address.checksum(smart_contract.address_hash)}")
assert %{
"hash" => ^address_hash,
"is_contract" => true,
"is_verified" => true,
"name" => ^name,
"private_tags" => [],
"public_tags" => [],
"watchlist_names" => [],
"creator_address_hash" => ^from,
"creation_tx_hash" => ^tx_hash,
"implementation_address" => "0x0000000000000000000000000000000000000001"
} = json_response(request, 200)
end
test "get watchlist id", %{conn: conn} do test "get watchlist id", %{conn: conn} do
auth = build(:auth) auth = build(:auth)
address = insert(:address) address = insert(:address)
@ -2622,4 +2667,19 @@ defmodule BlockScoutWeb.API.V2.AddressControllerTest do
end end
def check_total(_, _, _), do: true def check_total(_, _, _), do: true
def get_eip1967_implementation_non_zero_address do
expect(EthereumJSONRPC.Mox, :json_rpc, fn %{
id: 0,
method: "eth_getStorageAt",
params: [
_,
"0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc",
"latest"
]
},
_options ->
{:ok, "0x0000000000000000000000000000000000000000000000000000000000000001"}
end)
end
end end

@ -8,6 +8,7 @@ defmodule Explorer.Chain.Address do
use Explorer.Schema use Explorer.Schema
alias Ecto.Changeset alias Ecto.Changeset
alias Explorer.Chain
alias Explorer.Chain.{ alias Explorer.Chain.{
Address, Address,
@ -252,6 +253,16 @@ defmodule Explorer.Chain.Address do
end) end)
end end
@doc """
Preloads provided contracts associations if address has contract_code which is not nil
"""
@spec maybe_preload_smart_contract_associations(Address.t(), list, list) :: Address.t()
def maybe_preload_smart_contract_associations(%Address{contract_code: nil} = address, _associations, _options),
do: address
def maybe_preload_smart_contract_associations(%Address{contract_code: _} = address, associations, options),
do: Chain.select_repo(options).preload(address, associations)
@doc """ @doc """
Counts all the addresses where the `fetched_coin_balance` is > 0. Counts all the addresses where the `fetched_coin_balance` is > 0.
""" """

Loading…
Cancel
Save