From ae47e8f6dc8f97c385f27fa75fac90818c2e2ebb Mon Sep 17 00:00:00 2001 From: Stamates Date: Wed, 22 Aug 2018 17:13:02 -0400 Subject: [PATCH] Token transfers shown for all transactions tiles (preload not working in chain queries) --- .../templates/address/_link.html.eex | 2 +- .../address/_responsive_hash.html.eex | 4 +- .../templates/address/overview.html.eex | 2 +- .../_token_transfer.html.eex | 8 +- .../address_transaction/_transaction.html.eex | 3 - .../templates/transaction/_tile.html.eex | 30 +++++- .../views/address_transaction_view.ex | 2 + .../lib/block_scout_web/views/address_view.ex | 14 ++- .../block_scout_web/views/transaction_view.ex | 5 +- .../features/pages/address_page.ex | 27 ++--- .../features/pages/block_page.ex | 8 ++ .../features/pages/chain_page.ex | 8 ++ .../features/viewing_addresses_test.exs | 41 +++---- .../features/viewing_blocks_test.exs | 102 +++++++++++------- .../features/viewing_chain_test.exs | 26 +++++ apps/explorer/lib/explorer/chain.ex | 4 + apps/explorer/test/explorer/chain_test.exs | 99 +++++++++++++++++ 17 files changed, 287 insertions(+), 98 deletions(-) diff --git a/apps/block_scout_web/lib/block_scout_web/templates/address/_link.html.eex b/apps/block_scout_web/lib/block_scout_web/templates/address/_link.html.eex index 553771596b..05b2b46b01 100644 --- a/apps/block_scout_web/lib/block_scout_web/templates/address/_link.html.eex +++ b/apps/block_scout_web/lib/block_scout_web/templates/address/_link.html.eex @@ -1,5 +1,5 @@ <%= if @address_hash do %> - <%= link to: address_path(BlockScoutWeb.Endpoint, :show, @locale, @address_hash), "data-address-hash": @address_hash, "data-test": "address_hash_link" do %> + <%= link to: address_path(BlockScoutWeb.Endpoint, :show, @locale, @address_hash), "data-test": "address_hash_link" do %> <%= render BlockScoutWeb.AddressView, "_responsive_hash.html", address_hash: @address_hash, contract: @contract, truncate: assigns[:truncate] %> <% end %> <% end %> diff --git a/apps/block_scout_web/lib/block_scout_web/templates/address/_responsive_hash.html.eex b/apps/block_scout_web/lib/block_scout_web/templates/address/_responsive_hash.html.eex index e619d80026..6458246219 100644 --- a/apps/block_scout_web/lib/block_scout_web/templates/address/_responsive_hash.html.eex +++ b/apps/block_scout_web/lib/block_scout_web/templates/address/_responsive_hash.html.eex @@ -1,8 +1,8 @@ - + <%= if assigns[:truncate] do %> <%= BlockScoutWeb.AddressView.trimmed_hash(@address_hash) %> <% else %> <%= @address_hash %> - <%= BlockScoutWeb.AddressView.trimmed_hash(@address_hash) %> + <%= BlockScoutWeb.AddressView.trimmed_hash(@address_hash) %> <% end%> 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 8f0931273c..d2e28ece6e 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 @@ -16,7 +16,7 @@

<%= address_title(@address) %> Details

-

<%= @address %>

+

<%= @address.hash %>

<%= Cldr.Number.to_string!(@transaction_count, format: "#,###") %> <%= gettext "Transactions" %> diff --git a/apps/block_scout_web/lib/block_scout_web/templates/address_transaction/_token_transfer.html.eex b/apps/block_scout_web/lib/block_scout_web/templates/address_transaction/_token_transfer.html.eex index a216f2c035..704b90e30f 100644 --- a/apps/block_scout_web/lib/block_scout_web/templates/address_transaction/_token_transfer.html.eex +++ b/apps/block_scout_web/lib/block_scout_web/templates/address_transaction/_token_transfer.html.eex @@ -2,13 +2,9 @@ <%= token_transfer_amount(@token_transfer) %> <%= link(token_symbol(@token_transfer.token), to: token_path(BlockScoutWeb.Endpoint, :show, @locale, @token_transfer.token.contract_address_hash)) %> - - <%= BlockScoutWeb.AddressView.display_address_hash(@address, @token_transfer.from_address, @locale, true) %> - + <%= BlockScoutWeb.AddressView.display_address_hash(@address, @token_transfer.from_address, @locale, true) %> → - - <%= BlockScoutWeb.AddressView.display_address_hash(@address, @token_transfer.to_address, @locale, true) %> - + <%= BlockScoutWeb.AddressView.display_address_hash(@address, @token_transfer.to_address, @locale, true) %> <%= if from_or_to_address?(@token_transfer, @address) do %> <%= if @token_transfer.from_address_hash == @address.hash do %> diff --git a/apps/block_scout_web/lib/block_scout_web/templates/address_transaction/_transaction.html.eex b/apps/block_scout_web/lib/block_scout_web/templates/address_transaction/_transaction.html.eex index 245a66d486..6721968011 100644 --- a/apps/block_scout_web/lib/block_scout_web/templates/address_transaction/_transaction.html.eex +++ b/apps/block_scout_web/lib/block_scout_web/templates/address_transaction/_transaction.html.eex @@ -4,7 +4,6 @@ <%= BlockScoutWeb.TransactionView.transaction_display_type(@transaction) %> - <%= BlockScoutWeb.TransactionView.formatted_status(@transaction) %> @@ -13,9 +12,7 @@ <%= render BlockScoutWeb.TransactionView, "_link.html", locale: @locale, transaction_hash: @transaction.hash %> <%= BlockScoutWeb.AddressView.display_address_hash(@address, @transaction.from_address, @locale) %> - → - <%= if @address.hash == BlockScoutWeb.TransactionView.to_address_hash(@transaction) do %> <%= render BlockScoutWeb.AddressView, "_responsive_hash.html", address_hash: BlockScoutWeb.TransactionView.to_address_hash(@transaction), contract: BlockScoutWeb.AddressView.contract?(@transaction.to_address) %> <% else %> diff --git a/apps/block_scout_web/lib/block_scout_web/templates/transaction/_tile.html.eex b/apps/block_scout_web/lib/block_scout_web/templates/transaction/_tile.html.eex index 9b2bdff14c..abac47a236 100644 --- a/apps/block_scout_web/lib/block_scout_web/templates/transaction/_tile.html.eex +++ b/apps/block_scout_web/lib/block_scout_web/templates/transaction/_tile.html.eex @@ -1,4 +1,4 @@ -
+
@@ -19,11 +19,13 @@ <%= BlockScoutWeb.TransactionView.value(@transaction, include_label: false) %> <%= gettext "Ether" %> - <%= BlockScoutWeb.TransactionView.formatted_fee(@transaction, denomination: :ether, include_label: false) %> <%= gettext "TX Fee" %> + + <%= BlockScoutWeb.TransactionView.formatted_fee(@transaction, denomination: :ether, include_label: false) %> <%= gettext "TX Fee" %> +
-
- +
+ <%= link( gettext("Block #%{number}", number: to_string(@transaction.block.number)), to: block_path(BlockScoutWeb.Endpoint, :show, @locale, @transaction.block) @@ -31,5 +33,25 @@
+ + <%= if BlockScoutWeb.TransactionView.involves_token_transfers?(@transaction) do %> +
+ <% [first_token_transfer | tail]= @transaction.token_transfers %> + <%= render BlockScoutWeb.AddressTransactionView, "_token_transfer.html", address: assigns[:address], locale: @locale, token_transfer: first_token_transfer %> + +
+ <%= for token_transfer <- tail do %> + <%= render BlockScoutWeb.AddressTransactionView, "_token_transfer.html", address: assigns[:address], locale: @locale, token_transfer: token_transfer %> + <% end %> +
+
+ <%= if length(tail) != 0 do %> +
+ <%= link to: "##{@transaction.hash}", "data-toggle": "collapse", "data-test": "token_transfers_expansion" do %> + <%= gettext "See More" %> + <% end %> +
+ <% end %> + <% end %>
diff --git a/apps/block_scout_web/lib/block_scout_web/views/address_transaction_view.ex b/apps/block_scout_web/lib/block_scout_web/views/address_transaction_view.ex index 2ec049f262..cb427a3ae2 100644 --- a/apps/block_scout_web/lib/block_scout_web/views/address_transaction_view.ex +++ b/apps/block_scout_web/lib/block_scout_web/views/address_transaction_view.ex @@ -14,6 +14,8 @@ defmodule BlockScoutWeb.AddressTransactionView do end end + def from_or_to_address?(_token_transfer, nil), do: false + def from_or_to_address?(%{from_address_hash: from_hash, to_address_hash: to_hash}, %Address{hash: hash}) do from_hash == hash || to_hash == hash end 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 798fa92784..b6ffb578cf 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 @@ -79,7 +79,19 @@ defmodule BlockScoutWeb.AddressView do def smart_contract_with_read_only_functions?(%Address{smart_contract: nil}), do: false - def display_address_hash(current_address, target_address, locale, truncate \\ false) do + def display_address_hash(current_address, target_address, locale, truncate \\ false) + + def display_address_hash(nil, target_address, locale, truncate) do + render( + "_link.html", + address_hash: target_address.hash, + contract: contract?(target_address), + locale: locale, + truncate: truncate + ) + end + + def display_address_hash(current_address, target_address, locale, truncate) do if current_address.hash == target_address.hash do render( "_responsive_hash.html", diff --git a/apps/block_scout_web/lib/block_scout_web/views/transaction_view.ex b/apps/block_scout_web/lib/block_scout_web/views/transaction_view.ex index a8cb4ddbc4..dc6198163b 100644 --- a/apps/block_scout_web/lib/block_scout_web/views/transaction_view.ex +++ b/apps/block_scout_web/lib/block_scout_web/views/transaction_view.ex @@ -45,9 +45,8 @@ defmodule BlockScoutWeb.TransactionView do AddressView.contract?(from_address) || AddressView.contract?(to_address) end - def involves_token_transfers?(%Transaction{} = transaction) do - Ecto.assoc_loaded?(transaction.token_transfers) && Enum.any?(transaction.token_transfers) - end + def involves_token_transfers?(%Transaction{token_transfers: []}), do: false + def involves_token_transfers?(%Transaction{token_transfers: transfers}) when is_list(transfers), do: true def contract_creation?(%Transaction{to_address: nil}), do: true diff --git a/apps/block_scout_web/test/block_scout_web/features/pages/address_page.ex b/apps/block_scout_web/test/block_scout_web/features/pages/address_page.ex index 684cb46320..dd3a854d4c 100644 --- a/apps/block_scout_web/test/block_scout_web/features/pages/address_page.ex +++ b/apps/block_scout_web/test/block_scout_web/features/pages/address_page.ex @@ -36,11 +36,11 @@ defmodule BlockScoutWeb.AddressPage do end def internal_transaction_address_link(%InternalTransaction{id: id, to_address_hash: address_hash}, :to) do - css("[data-internal-transaction-id='#{id}'] [data-address-hash='#{address_hash}'][data-test='address_hash_link']") + css("[data-internal-transaction-id='#{id}'] [data-test='address_hash_link'] [data-address-hash='#{address_hash}']") end def internal_transaction_address_link(%InternalTransaction{id: id, from_address_hash: address_hash}, :from) do - css("[data-internal-transaction-id='#{id}'] [data-address-hash='#{address_hash}'][data-test='address_hash_link']") + css("[data-internal-transaction-id='#{id}'] [data-test='address_hash_link'] [data-address-hash='#{address_hash}']") end def transaction(%Transaction{hash: transaction_hash}), do: transaction(transaction_hash) @@ -56,11 +56,11 @@ defmodule BlockScoutWeb.AddressPage do end def transaction_address_link(%Transaction{hash: hash, to_address_hash: address_hash}, :to) do - css("[data-transaction-hash='#{hash}'] [data-address-hash='#{address_hash}'][data-test='address_hash_link']") + css("[data-transaction-hash='#{hash}'] [data-test='address_hash_link'] [data-address-hash='#{address_hash}']") end def transaction_address_link(%Transaction{hash: hash, from_address_hash: address_hash}, :from) do - css("[data-transaction-hash='#{hash}'] [data-address-hash='#{address_hash}'][data-test='address_hash_link']") + css("[data-transaction-hash='#{hash}'] [data-test='address_hash_link'] [data-address-hash='#{address_hash}']") end def transaction_count do @@ -77,19 +77,22 @@ defmodule BlockScoutWeb.AddressPage do visit(session, "/en/addresses/#{address_hash}") end - def token_transfers(count: count) do - css("[data-test='token_transfer']", count: count) + def token_transfer(%Transaction{hash: transaction_hash}, %Address{hash: address_hash}, count: count) do + css( + "[data-transaction-hash='#{transaction_hash}'] [data-test='token_transfer'] [data-address-hash='#{address_hash}']", + count: count + ) end - def token_transfer(%Address{hash: address_hash}, count: count) do - css("[data-test='token_transfer_address_hash'][data-address_hash='#{address_hash}']", count: count) - end - - def transaction_type do - css("[data-test='transaction_type']") + def token_transfers(%Transaction{hash: transaction_hash}, count: count) do + css("[data-transaction-hash='#{transaction_hash}'] [data-test='token_transfer']", count: count) end def token_transfers_expansion(%Transaction{hash: transaction_hash}) do css("[data-transaction-hash='#{transaction_hash}'] [data-test='token_transfers_expansion']") end + + def transaction_type do + css("[data-test='transaction_type']") + end end diff --git a/apps/block_scout_web/test/block_scout_web/features/pages/block_page.ex b/apps/block_scout_web/test/block_scout_web/features/pages/block_page.ex index 507b9b41eb..c80a30c213 100644 --- a/apps/block_scout_web/test/block_scout_web/features/pages/block_page.ex +++ b/apps/block_scout_web/test/block_scout_web/features/pages/block_page.ex @@ -15,6 +15,14 @@ defmodule BlockScoutWeb.BlockPage do css("[data-test='block_detail_number']", text: to_string(block_number)) end + def token_transfers(%Transaction{hash: transaction_hash}, count: count) do + css("[data-transaction-hash='#{transaction_hash}'] [data-test='token_transfer']", count: count) + end + + def token_transfers_expansion(%Transaction{hash: transaction_hash}) do + css("[data-transaction-hash='#{transaction_hash}'] [data-test='token_transfers_expansion']") + end + def transaction(%Transaction{hash: transaction_hash}) do css("[data-transaction-hash='#{transaction_hash}']") end diff --git a/apps/block_scout_web/test/block_scout_web/features/pages/chain_page.ex b/apps/block_scout_web/test/block_scout_web/features/pages/chain_page.ex index 995d3bea71..6f92efcd37 100644 --- a/apps/block_scout_web/test/block_scout_web/features/pages/chain_page.ex +++ b/apps/block_scout_web/test/block_scout_web/features/pages/chain_page.ex @@ -30,6 +30,14 @@ defmodule BlockScoutWeb.ChainPage do |> send_keys([:enter]) end + def token_transfers(%Transaction{hash: transaction_hash}, count: count) do + css("[data-transaction-hash='#{transaction_hash}'] [data-test='token_transfer']", count: count) + end + + def token_transfers_expansion(%Transaction{hash: transaction_hash}) do + css("[data-transaction-hash='#{transaction_hash}'] [data-test='token_transfers_expansion']") + end + def transactions(count: count) do css("[data-test='chain_transaction']", count: count) end diff --git a/apps/block_scout_web/test/block_scout_web/features/viewing_addresses_test.exs b/apps/block_scout_web/test/block_scout_web/features/viewing_addresses_test.exs index a5b18d3f0b..3af69b1ff7 100644 --- a/apps/block_scout_web/test/block_scout_web/features/viewing_addresses_test.exs +++ b/apps/block_scout_web/test/block_scout_web/features/viewing_addresses_test.exs @@ -261,12 +261,7 @@ defmodule BlockScoutWeb.ViewingAddressesTest do lincoln = addresses.lincoln taft = addresses.taft - contract_token_address = - insert( - :address, - contract_code: Explorer.Factory.data("contract_code") - ) - + contract_token_address = insert(:contract_address) insert(:token, contract_address: contract_token_address) transaction = @@ -284,9 +279,9 @@ defmodule BlockScoutWeb.ViewingAddressesTest do session |> AddressPage.visit_page(lincoln) - |> assert_has(AddressPage.token_transfers(count: 1)) - |> assert_has(AddressPage.token_transfer(lincoln, count: 1)) - |> assert_has(AddressPage.token_transfer(taft, count: 1)) + |> assert_has(AddressPage.token_transfers(transaction, count: 1)) + |> assert_has(AddressPage.token_transfer(transaction, lincoln, count: 1)) + |> assert_has(AddressPage.token_transfer(transaction, taft, count: 1)) |> refute_has(AddressPage.token_transfers_expansion(transaction)) end @@ -299,12 +294,7 @@ defmodule BlockScoutWeb.ViewingAddressesTest do taft = addresses.taft morty = build(:address) - contract_token_address = - insert( - :address, - contract_code: Explorer.Factory.data("contract_code") - ) - + contract_token_address = insert(:contract_address) insert(:token, contract_address: contract_token_address) transaction = @@ -330,10 +320,10 @@ defmodule BlockScoutWeb.ViewingAddressesTest do session |> AddressPage.visit_page(morty) - |> assert_has(AddressPage.token_transfers(count: 1)) - |> assert_has(AddressPage.token_transfer(lincoln, count: 1)) - |> assert_has(AddressPage.token_transfer(morty, count: 1)) - |> refute_has(AddressPage.token_transfer(taft, count: 1)) + |> assert_has(AddressPage.token_transfers(transaction, count: 1)) + |> assert_has(AddressPage.token_transfer(transaction, lincoln, count: 1)) + |> assert_has(AddressPage.token_transfer(transaction, morty, count: 1)) + |> refute_has(AddressPage.token_transfer(transaction, taft, count: 1)) end test "transactions with multiple token transfers shows only the first one by default", %{ @@ -368,10 +358,10 @@ defmodule BlockScoutWeb.ViewingAddressesTest do session |> AddressPage.visit_page(lincoln) - |> assert_has(AddressPage.token_transfer(lincoln, count: 1)) + |> assert_has(AddressPage.token_transfers(transaction, count: 1)) end - test "transactions with multiple token transfers shows all transferrs if expanded", %{ + test "transaction with multiple token transfers shows all transfers if expanded", %{ addresses: addresses, block: block, session: session @@ -379,12 +369,7 @@ defmodule BlockScoutWeb.ViewingAddressesTest do lincoln = addresses.lincoln taft = addresses.taft - contract_token_address = - insert( - :address, - contract_code: Explorer.Factory.data("contract_code") - ) - + contract_token_address = insert(:contract_address) insert(:token, contract_address: contract_token_address) transaction = @@ -404,7 +389,7 @@ defmodule BlockScoutWeb.ViewingAddressesTest do session |> AddressPage.visit_page(lincoln) |> click(AddressPage.token_transfers_expansion(transaction)) - |> assert_has(AddressPage.token_transfer(lincoln, count: 3)) + |> assert_has(AddressPage.token_transfers(transaction, count: 3)) end end end diff --git a/apps/block_scout_web/test/block_scout_web/features/viewing_blocks_test.exs b/apps/block_scout_web/test/block_scout_web/features/viewing_blocks_test.exs index bc82cb7cc1..274a79298a 100644 --- a/apps/block_scout_web/test/block_scout_web/features/viewing_blocks_test.exs +++ b/apps/block_scout_web/test/block_scout_web/features/viewing_blocks_test.exs @@ -20,53 +20,81 @@ defmodule BlockScoutWeb.ViewingBlocksTest do {:ok, first_shown_block: newest_block, last_shown_block: oldest_block} end - test "show block detail page", %{session: session} do - block = insert(:block, number: 42) - + test "viewing the blocks index page", %{first_shown_block: block, session: session} do session - |> BlockPage.visit_page(block) - |> assert_has(BlockPage.detail_number(block)) + |> BlockListPage.visit_page() + |> assert_has(BlockListPage.block(block)) end - test "block detail page has transactions", %{session: session} do - block = insert(:block, number: 42) + describe "block details page" do + test "show block detail page", %{session: session} do + block = insert(:block, number: 42) - transaction = - :transaction - |> insert() - |> with_block(block) + session + |> BlockPage.visit_page(block) + |> assert_has(BlockPage.detail_number(block)) + end - session - |> BlockPage.visit_page(block) - |> assert_has(BlockPage.detail_number(block)) - |> assert_has(BlockPage.transaction(transaction)) - |> assert_has(BlockPage.transaction_status(transaction)) - end + test "block detail page has transactions", %{session: session} do + block = insert(:block, number: 42) - test "contract creation is shown for to_address in transaction list", %{session: session} do - block = insert(:block, number: 42) + transaction = + :transaction + |> insert() + |> with_block(block) - contract_address = insert(:contract_address) + session + |> BlockPage.visit_page(block) + |> assert_has(BlockPage.detail_number(block)) + |> assert_has(BlockPage.transaction(transaction)) + |> assert_has(BlockPage.transaction_status(transaction)) + end - transaction = - :transaction - |> insert(to_address: nil) - |> with_contract_creation(contract_address) - |> with_block(block) + test "contract creation is shown for to_address in transaction list", %{session: session} do + block = insert(:block, number: 42) - internal_transaction = - :internal_transaction_create - |> insert(transaction: transaction, index: 0) - |> with_contract_creation(contract_address) + contract_address = insert(:contract_address) - session - |> BlockPage.visit_page(block) - |> assert_has(BlockPage.contract_creation(internal_transaction)) - end + transaction = + :transaction + |> insert(to_address: nil) + |> with_contract_creation(contract_address) + |> with_block(block) - test "viewing the blocks index page", %{first_shown_block: block, session: session} do - session - |> BlockListPage.visit_page() - |> assert_has(BlockListPage.block(block)) + internal_transaction = + :internal_transaction_create + |> insert(transaction: transaction, index: 0) + |> with_contract_creation(contract_address) + + session + |> BlockPage.visit_page(block) + |> assert_has(BlockPage.contract_creation(internal_transaction)) + end + + test "transaction with multiple token transfers shows all transfers if expanded", %{ + first_shown_block: block, + session: session + } do + contract_token_address = insert(:contract_address) + insert(:token, contract_address: contract_token_address) + + transaction = + :transaction + |> insert(to_address: contract_token_address) + |> with_block(block) + + insert_list( + 3, + :token_transfer, + transaction: transaction, + token_contract_address: contract_token_address + ) + + session + |> BlockPage.visit_page(block) + |> assert_has(BlockPage.token_transfers(transaction, count: 1)) + |> click(BlockPage.token_transfers_expansion(transaction)) + |> assert_has(BlockPage.token_transfers(transaction, count: 3)) + end end end diff --git a/apps/block_scout_web/test/block_scout_web/features/viewing_chain_test.exs b/apps/block_scout_web/test/block_scout_web/features/viewing_chain_test.exs index 0022ba7dae..ac24752573 100644 --- a/apps/block_scout_web/test/block_scout_web/features/viewing_chain_test.exs +++ b/apps/block_scout_web/test/block_scout_web/features/viewing_chain_test.exs @@ -81,5 +81,31 @@ defmodule BlockScoutWeb.ViewingChainTest do |> ChainPage.visit_page() |> assert_has(ChainPage.contract_creation(transaction)) end + + test "transaction with multiple token transfers shows all transfers if expanded", %{ + block: block, + session: session + } do + contract_token_address = insert(:contract_address) + insert(:token, contract_address: contract_token_address) + + transaction = + :transaction + |> insert(to_address: contract_token_address) + |> with_block(block) + + insert_list( + 3, + :token_transfer, + transaction: transaction, + token_contract_address: contract_token_address + ) + + session + |> ChainPage.visit_page() + |> assert_has(ChainPage.token_transfers(transaction, count: 1)) + |> click(ChainPage.token_transfers_expansion(transaction)) + |> assert_has(ChainPage.token_transfers(transaction, count: 3)) + end end end diff --git a/apps/explorer/lib/explorer/chain.ex b/apps/explorer/lib/explorer/chain.ex index daeb77e060..1138a59ee1 100644 --- a/apps/explorer/lib/explorer/chain.ex +++ b/apps/explorer/lib/explorer/chain.ex @@ -324,6 +324,7 @@ defmodule Explorer.Chain do |> join(:inner, [transaction], block in assoc(transaction, :block)) |> where([_, block], block.hash == ^block_hash) |> join_associations(necessity_by_association) + |> preload([{:token_transfers, [:token, :from_address, :to_address]}]) |> Repo.all() end @@ -641,6 +642,7 @@ defmodule Explorer.Chain do fetch_transactions() |> where([transaction], transaction.hash in ^hashes) |> join_associations(necessity_by_association) + |> preload([{:token_transfers, [:token, :from_address, :to_address]}]) |> Repo.all() end @@ -1070,6 +1072,7 @@ defmodule Explorer.Chain do |> where([transaction], not is_nil(transaction.block_number) and not is_nil(transaction.index)) |> order_by([transaction], desc: transaction.block_number, desc: transaction.index) |> join_associations(necessity_by_association) + |> preload([{:token_transfers, [:token, :from_address, :to_address]}]) |> Repo.all() end @@ -1108,6 +1111,7 @@ defmodule Explorer.Chain do |> where([transaction], is_nil(transaction.block_hash)) |> order_by([transaction], desc: transaction.inserted_at, desc: transaction.hash) |> join_associations(necessity_by_association) + |> preload([{:token_transfers, [:token, :from_address, :to_address]}]) |> Repo.all() end diff --git a/apps/explorer/test/explorer/chain_test.exs b/apps/explorer/test/explorer/chain_test.exs index b5b91ad826..ecab0f936e 100644 --- a/apps/explorer/test/explorer/chain_test.exs +++ b/apps/explorer/test/explorer/chain_test.exs @@ -326,6 +326,31 @@ defmodule Explorer.ChainTest do |> Enum.map(& &1.hash) |> Enum.reverse() end + + test "returns transactions with token_transfers preloaded" do + address = insert(:address) + block = insert(:block) + token_contract_address = insert(:contract_address) + token = insert(:token, contract_address: token_contract_address) + + transaction = + :transaction + |> insert() + |> with_block(block) + + insert_list( + 2, + :token_transfer, + to_address: address, + transaction: transaction, + token_contract_address: token_contract_address, + token: token + ) + + fetched_transaction = List.first(Explorer.Chain.block_to_transactions(block)) + assert fetched_transaction.hash == transaction.hash + assert length(fetched_transaction.token_transfers) == 2 + end end describe "block_to_transaction_count/1" do @@ -528,6 +553,41 @@ defmodule Explorer.ChainTest do |> Chain.hashes_to_transactions(necessity_by_association: %{block: :optional}) |> Enum.all?(&(&1.hash in [hash_without_index1, hash_without_index2])) end + + test "returns transactions with token_transfers preloaded" do + address = insert(:address) + token_contract_address = insert(:contract_address) + token = insert(:token, contract_address: token_contract_address) + + [transaction1, transaction2] = + 2 + |> insert_list(:transaction) + |> with_block() + + %TokenTransfer{id: id1} = + insert( + :token_transfer, + to_address: address, + transaction: transaction1, + token_contract_address: token_contract_address, + token: token + ) + + %TokenTransfer{id: id2} = + insert( + :token_transfer, + to_address: address, + transaction: transaction2, + token_contract_address: token_contract_address, + token: token + ) + + fetched_transactions = Explorer.Chain.hashes_to_transactions([transaction1.hash, transaction2.hash]) + + assert Enum.all?(fetched_transactions, fn transaction -> + hd(transaction.token_transfers).id in [id1, id2] + end) + end end describe "list_blocks/2" do @@ -1106,6 +1166,45 @@ defmodule Explorer.ChainTest do insert(:transaction) assert [] == Explorer.Chain.recent_collated_transactions() end + + test "returns a list of recent collated transactions" do + newest_first_transactions = + 50 + |> insert_list(:transaction) + |> with_block() + |> Enum.reverse() + + oldest_seen = Enum.at(newest_first_transactions, 9) + paging_options = %Explorer.PagingOptions{page_size: 10, key: {oldest_seen.block_number, oldest_seen.index}} + recent_collated_transactions = Explorer.Chain.recent_collated_transactions(paging_options: paging_options) + + assert length(recent_collated_transactions) == 10 + assert hd(recent_collated_transactions).hash == Enum.at(newest_first_transactions, 10).hash + end + + test "returns transactions with token_transfers preloaded" do + address = insert(:address) + token_contract_address = insert(:contract_address) + token = insert(:token, contract_address: token_contract_address) + + transaction = + :transaction + |> insert() + |> with_block() + + insert_list( + 2, + :token_transfer, + to_address: address, + transaction: transaction, + token_contract_address: token_contract_address, + token: token + ) + + fetched_transaction = List.first(Explorer.Chain.recent_collated_transactions()) + assert fetched_transaction.hash == transaction.hash + assert length(fetched_transaction.token_transfers) == 2 + end end describe "smart_contract_bytecode/1" do