From 5ee4df3714b132d1386c70ffb73a35a7bfc18990 Mon Sep 17 00:00:00 2001 From: Amanda Sposito Date: Wed, 17 Oct 2018 11:06:02 -0300 Subject: [PATCH] Alter 'Chain.address_to_internal_transactions' query * The query was taking too long and one of the reasons was because it was performing a sub-query in the internal_transactions table to identify if the transaction had siblings. This was made because for every parent transactions there is one equal internal_transaction, so this check was made to only show internal transactions that are different from the parent transaction. * There is another way to check this that removes the need to perform a sub-query in the internal transactions table. We need to check the indexes >`0` for `type`=`call`. * Also created new indexes to improve the 'where' match and the 'order by' clause. --- .../features/viewing_addresses_test.exs | 16 +++--- apps/explorer/lib/explorer/chain.ex | 2 +- .../explorer/chain/internal_transaction.ex | 8 +++ ...dd_index_to_internal_transaction_table.exs | 21 +------ apps/explorer/test/explorer/chain_test.exs | 56 ++++--------------- 5 files changed, 29 insertions(+), 74 deletions(-) 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 8cb719bb34..8bf9d851a2 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 @@ -62,7 +62,7 @@ defmodule BlockScoutWeb.ViewingAddressesTest do internal_transaction = insert( :internal_transaction_create, - index: 0, + index: 1, transaction: transaction, from_address: address, created_contract_address: contract @@ -84,7 +84,7 @@ defmodule BlockScoutWeb.ViewingAddressesTest do insert( :internal_transaction, - index: 0, + index: 1, transaction: transaction, from_address: lincoln, to_address: contract, @@ -95,7 +95,7 @@ defmodule BlockScoutWeb.ViewingAddressesTest do internal_transaction = insert( :internal_transaction_create, - index: 1, + index: 2, transaction: transaction, from_address: contract, created_contract_address: another_contract @@ -198,7 +198,7 @@ defmodule BlockScoutWeb.ViewingAddressesTest do |> insert( transaction: from_lincoln, from_address: lincoln, - index: 0 + index: 1 ) |> with_contract_creation(contract_address) @@ -225,9 +225,9 @@ defmodule BlockScoutWeb.ViewingAddressesTest do transaction = transactions.from_lincoln internal_transaction_lincoln_to_address = - insert(:internal_transaction, transaction: transaction, to_address: address, index: 0) + insert(:internal_transaction, transaction: transaction, to_address: address, index: 1) - insert(:internal_transaction, transaction: transaction, from_address: address, index: 1) + insert(:internal_transaction, transaction: transaction, from_address: address, index: 2) {:ok, %{internal_transaction_lincoln_to_address: internal_transaction_lincoln_to_address}} end @@ -278,7 +278,7 @@ defmodule BlockScoutWeb.ViewingAddressesTest do |> assert_has(AddressPage.internal_transactions(count: 2)) internal_transaction = - insert(:internal_transaction, transaction: transaction, index: 0, from_address: addresses.lincoln) + insert(:internal_transaction, transaction: transaction, index: 2, from_address: addresses.lincoln) Notifier.handle_event({:chain_event, :internal_transactions, :realtime, [internal_transaction]}) @@ -307,7 +307,7 @@ defmodule BlockScoutWeb.ViewingAddressesTest do |> insert( transaction: from_lincoln, from_address: lincoln, - index: 0 + index: 1 ) |> with_contract_creation(contract_address) diff --git a/apps/explorer/lib/explorer/chain.ex b/apps/explorer/lib/explorer/chain.ex index 48c787a190..d671181600 100644 --- a/apps/explorer/lib/explorer/chain.ex +++ b/apps/explorer/lib/explorer/chain.ex @@ -123,7 +123,7 @@ defmodule Explorer.Chain do InternalTransaction |> InternalTransaction.where_address_fields_match(hash, direction) - |> where_transaction_has_multiple_internal_transactions() + |> InternalTransaction.where_is_different_from_parent_transaction() |> page_internal_transaction(paging_options) |> limit(^paging_options.page_size) |> order_by( diff --git a/apps/explorer/lib/explorer/chain/internal_transaction.ex b/apps/explorer/lib/explorer/chain/internal_transaction.ex index f6dd866377..d57ea5a1d1 100644 --- a/apps/explorer/lib/explorer/chain/internal_transaction.ex +++ b/apps/explorer/lib/explorer/chain/internal_transaction.ex @@ -468,4 +468,12 @@ defmodule Explorer.Chain.InternalTransaction do it.created_contract_address_hash == ^address_hash ) end + + def where_is_different_from_parent_transaction(query) do + where( + query, + [it], + (it.type == ^:call and it.index > 0) or it.type != ^:call + ) + end end diff --git a/apps/explorer/priv/repo/migrations/20181017141409_add_index_to_internal_transaction_table.exs b/apps/explorer/priv/repo/migrations/20181017141409_add_index_to_internal_transaction_table.exs index 541cf4794c..0f7e6c1837 100644 --- a/apps/explorer/priv/repo/migrations/20181017141409_add_index_to_internal_transaction_table.exs +++ b/apps/explorer/priv/repo/migrations/20181017141409_add_index_to_internal_transaction_table.exs @@ -1,7 +1,7 @@ defmodule Explorer.Repo.Migrations.AddIndexToInternalTransactionTable do use Ecto.Migration - def up do + def change do create( index("internal_transactions", [ :to_address_hash, @@ -12,23 +12,6 @@ defmodule Explorer.Repo.Migrations.AddIndexToInternalTransactionTable do ]) ) - execute(""" - CREATE INDEX itx_transactions_block_number_tx_index_index - ON internal_transactions (block_number DESC, transaction_index DESC, "index" DESC); - """) - end - - def down do - drop( - index("internal_transactions", [ - :to_address_hash, - :from_address_hash, - :created_contract_address_hash, - :type, - :index - ]) - ) - - execute("DROP INDEX itx_transactions_block_number_tx_index_index;") + create(index(:internal_transactions, ["block_number DESC, transaction_index DESC, index DESC"])) end end diff --git a/apps/explorer/test/explorer/chain_test.exs b/apps/explorer/test/explorer/chain_test.exs index 4cdb777c54..3c0fd8bc9b 100644 --- a/apps/explorer/test/explorer/chain_test.exs +++ b/apps/explorer/test/explorer/chain_test.exs @@ -1266,7 +1266,7 @@ defmodule Explorer.ChainTest do %InternalTransaction{id: first_id} = insert(:internal_transaction, - index: 0, + index: 1, transaction: transaction, to_address: address, block_number: transaction.block_number, @@ -1275,14 +1275,18 @@ defmodule Explorer.ChainTest do %InternalTransaction{id: second_id} = insert(:internal_transaction, - index: 1, + index: 2, transaction: transaction, to_address: address, block_number: transaction.block_number, transaction_index: transaction.index ) - result = address |> Chain.address_to_internal_transactions() |> Enum.map(& &1.id) + result = + address + |> Chain.address_to_internal_transactions() + |> Enum.map(& &1.id) + assert Enum.member?(result, first_id) assert Enum.member?(result, second_id) end @@ -1433,15 +1437,9 @@ defmodule Explorer.ChainTest do :internal_transaction, transaction: first_b_transaction, to_address: address, -<<<<<<< HEAD - index: 1, - transaction_index: first_b_transaction.index, - block_number: first_b_transaction.block_number -======= index: 2, block_number: first_b_transaction.block_number, transaction_index: first_b_transaction.index ->>>>>>> c06b04ad... fixup! Add 'block_number' and 'transaction_index' in 'internal_transaction' ) result = @@ -1461,24 +1459,14 @@ defmodule Explorer.ChainTest do :internal_transaction, transaction: pending_transaction, to_address: address, -<<<<<<< HEAD - index: 0, - transaction_index: pending_transaction.index -======= - index: 1, ->>>>>>> c06b04ad... fixup! Add 'block_number' and 'transaction_index' in 'internal_transaction' + index: 1 ) insert( :internal_transaction, transaction: pending_transaction, to_address: address, -<<<<<<< HEAD - index: 1, - transaction_index: pending_transaction.index -======= - index: 2, ->>>>>>> c06b04ad... fixup! Add 'block_number' and 'transaction_index' in 'internal_transaction' + index: 2 ) a_block = insert(:block, number: 2000) @@ -1493,15 +1481,9 @@ defmodule Explorer.ChainTest do :internal_transaction, transaction: first_a_transaction, to_address: address, -<<<<<<< HEAD - index: 0, - transaction_index: first_a_transaction.index, - block_number: first_a_transaction.block_number -======= index: 1, block_number: first_a_transaction.block_number, transaction_index: first_a_transaction.index ->>>>>>> c06b04ad... fixup! Add 'block_number' and 'transaction_index' in 'internal_transaction' ) %InternalTransaction{id: second} = @@ -1509,15 +1491,9 @@ defmodule Explorer.ChainTest do :internal_transaction, transaction: first_a_transaction, to_address: address, -<<<<<<< HEAD - index: 1, - transaction_index: first_a_transaction.index, - block_number: first_a_transaction.block_number -======= index: 2, block_number: first_a_transaction.block_number, transaction_index: first_a_transaction.index ->>>>>>> c06b04ad... fixup! Add 'block_number' and 'transaction_index' in 'internal_transaction' ) second_a_transaction = @@ -1530,15 +1506,9 @@ defmodule Explorer.ChainTest do :internal_transaction, transaction: second_a_transaction, to_address: address, -<<<<<<< HEAD - index: 0, - transaction_index: second_a_transaction.index, - block_number: second_a_transaction.block_number -======= index: 1, block_number: second_a_transaction.block_number, transaction_index: second_a_transaction.index ->>>>>>> c06b04ad... fixup! Add 'block_number' and 'transaction_index' in 'internal_transaction' ) %InternalTransaction{id: fourth} = @@ -1546,15 +1516,9 @@ defmodule Explorer.ChainTest do :internal_transaction, transaction: second_a_transaction, to_address: address, -<<<<<<< HEAD - index: 1, - transaction_index: second_a_transaction.index, - block_number: second_a_transaction.block_number -======= index: 2, block_number: second_a_transaction.block_number, transaction_index: second_a_transaction.index ->>>>>>> c06b04ad... fixup! Add 'block_number' and 'transaction_index' in 'internal_transaction' ) b_block = insert(:block, number: 6000) @@ -1594,7 +1558,7 @@ defmodule Explorer.ChainTest do |> Enum.map(& &1.id) # block number ==, transaction index ==, internal transaction index < - assert [fifth, fourth, third, second, first] == + assert [fourth, third, second, first] == address |> Chain.address_to_internal_transactions( paging_options: %PagingOptions{key: {6000, 0, 1}, page_size: 8}