Remove the 'pending transactions' from the address transaction page.

* The pending transactions query is taking too long to some address, this count will change after #60 is resolved.
pull/1063/head
Amanda Sposito 6 years ago
parent 67565e6927
commit 20f56810a3
  1. 3
      apps/block_scout_web/lib/block_scout_web/controllers/address_transaction_controller.ex
  2. 17
      apps/block_scout_web/lib/block_scout_web/templates/address_transaction/index.html.eex
  3. 16
      apps/block_scout_web/test/block_scout_web/controllers/address_transaction_controller_test.exs
  4. 31
      apps/block_scout_web/test/block_scout_web/features/viewing_addresses_test.exs
  5. 38
      apps/explorer/lib/explorer/chain.ex
  6. 69
      apps/explorer/test/explorer/chain_test.exs

@ -91,8 +91,6 @@ defmodule BlockScoutWeb.AddressTransactionController do
{transactions, next_page} = get_transactions_and_next_page(address, full_options) {transactions, next_page} = get_transactions_and_next_page(address, full_options)
pending_transactions = Chain.address_to_pending_transactions(address, pending_options)
render( render(
conn, conn,
"index.html", "index.html",
@ -100,7 +98,6 @@ defmodule BlockScoutWeb.AddressTransactionController do
next_page_params: next_page_params(next_page, transactions, params), next_page_params: next_page_params(next_page, transactions, params),
exchange_rate: Market.get_exchange_rate(Explorer.coin()) || Token.null(), exchange_rate: Market.get_exchange_rate(Explorer.coin()) || Token.null(),
filter: params["filter"], filter: params["filter"],
pending_transactions: pending_transactions,
transactions: transactions, transactions: transactions,
transaction_count: transaction_count(address), transaction_count: transaction_count(address),
validation_count: validation_count(address) validation_count: validation_count(address)

@ -51,23 +51,6 @@
</div> </div>
</div> </div>
<h2 class="card-title"><%= gettext "Transactions" %></h2> <h2 class="card-title"><%= gettext "Transactions" %></h2>
<div data-selector="pending-transactions-toggle">
<%= link to: "#pending-transactions-container", class: "d-inline-block mb-3", "data-toggle": "collapse" do %>
<span data-selector="pending-transactions-open">
<%= gettext("Show") %></span>
<span data-selector="pending-transactions-close" class="d-none"><%= gettext("Hide") %></span>
<span data-selector="pending-transactions-count"><%= length(@pending_transactions) %></span>
<%= gettext("Pending Transactions") %>
<% end %>
<div class="mb-3 collapse" id="pending-transactions-container">
<div data-selector="pending-transactions-list">
<%= for pending_transaction <- @pending_transactions do %>
<%= render(BlockScoutWeb.TransactionView, "_tile.html", current_address: @address, transaction: pending_transaction) %>
<% end %>
</div>
<hr />
</div>
</div>
<%= if Enum.count(@transactions) > 0 do %> <%= if Enum.count(@transactions) > 0 do %>
<span data-selector="transactions-list"> <span data-selector="transactions-list">
<%= for transaction <- @transactions do %> <%= for transaction <- @transactions do %>

@ -45,22 +45,6 @@ defmodule BlockScoutWeb.AddressTransactionControllerTest do
assert Enum.member?(actual_transaction_hashes, to_transaction.hash) assert Enum.member?(actual_transaction_hashes, to_transaction.hash)
end end
test "returns pending related transactions", %{conn: conn} do
address = insert(:address)
pending = insert(:transaction, from_address: address, to_address: address)
conn = get(conn, address_transaction_path(BlockScoutWeb.Endpoint, :index, address))
actual_pending_transaction_hashes =
conn.assigns.pending_transactions
|> Enum.map(& &1.hash)
assert html_response(conn, 200)
assert conn.status == 200
assert Enum.member?(actual_pending_transaction_hashes, pending.hash)
end
test "includes USD exchange rate value for address in assigns", %{conn: conn} do test "includes USD exchange rate value for address in assigns", %{conn: conn} do
address = insert(:address) address = insert(:address)

@ -123,37 +123,6 @@ defmodule BlockScoutWeb.ViewingAddressesTest do
|> assert_has(AddressPage.transaction_status(transactions.from_lincoln)) |> assert_has(AddressPage.transaction_status(transactions.from_lincoln))
end end
test "sees pending transactions", %{
addresses: addresses,
session: session,
transactions: transactions
} do
pending = insert(:transaction, to_address: addresses.lincoln)
session
|> AddressPage.visit_page(addresses.lincoln)
|> AddressPage.click_show_pending_transactions()
|> assert_has(AddressPage.pending_transaction(pending))
|> assert_has(AddressPage.transaction(transactions.from_taft))
|> assert_has(AddressPage.transaction(transactions.from_lincoln))
|> assert_has(AddressPage.transaction_status(transactions.from_lincoln))
end
test "viewing new pending transactions via live update", %{addresses: addresses, session: session} do
pending = insert(:transaction, from_address: addresses.lincoln)
session
|> AddressPage.visit_page(addresses.lincoln)
|> AddressPage.click_show_pending_transactions()
|> assert_has(AddressPage.pending_transaction(pending))
new_pending = insert(:transaction, from_address: addresses.lincoln)
Notifier.handle_event({:chain_event, :transactions, :realtime, [new_pending.hash]})
assert_has(session, AddressPage.pending_transaction(new_pending))
end
test "can filter to only see transactions from an address", %{ test "can filter to only see transactions from an address", %{
addresses: addresses, addresses: addresses,
session: session, session: session,

@ -141,44 +141,6 @@ defmodule Explorer.Chain do
|> Repo.all() |> Repo.all()
end end
@doc """
Pending `t:Explorer.Chain.Transaction/0`s from `address`.
## Options
* `:necessity_by_association` - use to load `t:association/0` as `:required` or `:optional`. If an association is
`:required`, and the `t:Explorer.Chain.Transaction.t/0` has no associated record for that association, then the
`t:Explorer.Chain.Transaction.t/0` will not be included in the page `entries`.
"""
@spec address_to_pending_transactions(Address.t(), [necessity_by_association_option]) :: [Transaction.t()]
def address_to_pending_transactions(
%Address{hash: %Hash{byte_count: unquote(Hash.Address.byte_count())} = address_hash},
options \\ []
)
when is_list(options) do
necessity_by_association = Keyword.get(options, :necessity_by_association, %{})
options
|> Keyword.get(:direction)
|> case do
:from -> [:from_address_hash]
:to -> [:to_address_hash]
_ -> [:from_address_hash, :to_address_hash]
end
|> Enum.map(fn address_field ->
Transaction
|> Transaction.where_address_fields_match(address_hash, address_field)
|> join_associations(necessity_by_association)
|> where([transaction], is_nil(transaction.block_number))
|> order_by([transaction], desc: transaction.inserted_at, desc: transaction.hash)
|> Repo.all()
|> MapSet.new()
end)
|> Enum.reduce(MapSet.new(), &MapSet.union/2)
|> MapSet.to_list()
end
@doc """ @doc """
Get the total number of transactions sent by the given address according to the last block indexed. Get the total number of transactions sent by the given address according to the last block indexed.

@ -34,70 +34,6 @@ defmodule Explorer.ChainTest do
end end
end end
describe "address_to_pending_transactions/2" do
test "without pending transactions" do
address = insert(:address)
assert Repo.aggregate(Transaction, :count, :hash) == 0
assert [] == Chain.address_to_pending_transactions(address)
end
test "with from pending transactions" do
address = insert(:address)
transaction = insert(:transaction, from_address: address)
assert [transaction] ==
Chain.address_to_pending_transactions(address, direction: :from)
|> Repo.preload([:to_address, :from_address])
end
test "with to transactions" do
address = insert(:address)
transaction = insert(:transaction, to_address: address)
assert [transaction] ==
Chain.address_to_pending_transactions(address, direction: :to)
|> Repo.preload([:to_address, :from_address])
end
test "with to and from transactions and direction: :from" do
address = insert(:address)
transaction = insert(:transaction, from_address: address)
insert(:transaction, to_address: address)
# only contains "from" transaction
assert [transaction] ==
Chain.address_to_pending_transactions(address, direction: :from)
|> Repo.preload([:to_address, :from_address])
end
test "with to and from transactions and direction: :to" do
address = insert(:address)
transaction = insert(:transaction, to_address: address)
insert(:transaction, from_address: address)
assert [transaction] ==
Chain.address_to_pending_transactions(address, direction: :to)
|> Repo.preload([:to_address, :from_address])
end
test "with to and from transactions and no :direction option" do
address = insert(:address)
transaction1 = insert(:transaction, from_address: address)
transaction2 = insert(:transaction, to_address: address)
assert [transaction1, transaction2] ==
Chain.address_to_pending_transactions(address)
|> Repo.preload([:to_address, :from_address])
end
end
describe "address_to_transactions/2" do describe "address_to_transactions/2" do
test "without transactions" do test "without transactions" do
address = insert(:address) address = insert(:address)
@ -355,9 +291,6 @@ defmodule Explorer.ChainTest do
test "returns results in reverse chronological order by block number and transaction index" do test "returns results in reverse chronological order by block number and transaction index" do
address = insert(:address) address = insert(:address)
%Transaction{hash: first_pending} = insert(:transaction, to_address: address)
%Transaction{hash: second_pending} = insert(:transaction, to_address: address)
a_block = insert(:block, number: 6000) a_block = insert(:block, number: 6000)
%Transaction{hash: first} = %Transaction{hash: first} =
@ -397,7 +330,7 @@ defmodule Explorer.ChainTest do
|> Chain.address_to_transactions() |> Chain.address_to_transactions()
|> Enum.map(& &1.hash) |> Enum.map(& &1.hash)
assert [first_pending, second_pending, fourth, third, second, first, sixth, fifth] == result assert [fourth, third, second, first, sixth, fifth] == result
end end
end end

Loading…
Cancel
Save