chore: Reindex incorrect internal transactions migration (#10654)

pull/10844/head
Qwerty5Uiop 2 months ago committed by GitHub
parent 435bba786f
commit cffc5360ba
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 1
      apps/explorer/config/config.exs
  2. 1
      apps/explorer/config/runtime/test.exs
  3. 3
      apps/explorer/lib/explorer/application.ex
  4. 83
      apps/explorer/lib/explorer/migrator/reindex_internal_transactions_with_incompatible_status.ex
  5. 73
      apps/explorer/test/explorer/migrator/reindex_internal_transactions_with_incompatible_status_test.exs

@ -130,6 +130,7 @@ config :explorer, Explorer.Migrator.TokenTransferBlockConsensus, enabled: true
config :explorer, Explorer.Migrator.RestoreOmittedWETHTransfers, enabled: true
config :explorer, Explorer.Migrator.SanitizeMissingTokenBalances, enabled: true
config :explorer, Explorer.Migrator.SanitizeReplacedTransactions, enabled: true
config :explorer, Explorer.Migrator.ReindexInternalTransactionsWithIncompatibleStatus, enabled: true
config :explorer, Explorer.Chain.Fetcher.CheckBytecodeMatchingOnDemand, enabled: true

@ -51,6 +51,7 @@ config :explorer, Explorer.Migrator.ShrinkInternalTransactions, enabled: false
config :explorer, Explorer.Migrator.RestoreOmittedWETHTransfers, enabled: false
config :explorer, Explorer.Migrator.SanitizeMissingTokenBalances, enabled: false
config :explorer, Explorer.Migrator.SanitizeReplacedTransactions, enabled: false
config :explorer, Explorer.Migrator.ReindexInternalTransactionsWithIncompatibleStatus, enabled: false
config :explorer,
realtime_events_sender: Explorer.Chain.Events.SimpleSender

@ -147,7 +147,8 @@ defmodule Explorer.Application do
configure_chain_type_dependent_process(Explorer.Chain.Cache.BlackfortValidatorsCounters, :blackfort),
configure_chain_type_dependent_process(Explorer.Chain.Cache.StabilityValidatorsCounters, :stability),
configure_mode_dependent_process(Explorer.Migrator.SanitizeMissingTokenBalances, :indexer),
configure_mode_dependent_process(Explorer.Migrator.SanitizeReplacedTransactions, :indexer)
configure_mode_dependent_process(Explorer.Migrator.SanitizeReplacedTransactions, :indexer),
configure_mode_dependent_process(Explorer.Migrator.ReindexInternalTransactionsWithIncompatibleStatus, :indexer)
]
|> List.flatten()

@ -0,0 +1,83 @@
defmodule Explorer.Migrator.ReindexInternalTransactionsWithIncompatibleStatus do
@moduledoc """
Searches for all failed transactions for which all internal transactions are successful
and adds block numbers of these transactions to pending_block_operations.
"""
use Explorer.Migrator.FillingMigration
import Ecto.Query
alias Explorer.Chain.{Block, InternalTransaction, PendingBlockOperation, Transaction}
alias Explorer.Migrator.FillingMigration
alias Explorer.Repo
@migration_name "reindex_internal_transactions_with_incompatible_status"
@impl FillingMigration
def migration_name, do: @migration_name
@impl FillingMigration
def last_unprocessed_identifiers(state) do
limit = batch_size() * concurrency()
ids =
unprocessed_data_query()
|> select([t], t.block_number)
|> distinct(true)
|> limit(^limit)
|> Repo.all(timeout: :infinity)
{ids, state}
end
@impl FillingMigration
def unprocessed_data_query do
pbo_query =
from(
pbo in PendingBlockOperation,
where: pbo.block_number == parent_as(:transaction).block_number
)
it_query =
from(
it in InternalTransaction,
where: parent_as(:transaction).hash == it.transaction_hash and it.index > 0,
select: 1
)
it_error_query =
from(
it in InternalTransaction,
where: parent_as(:transaction).hash == it.transaction_hash and not is_nil(it.error) and it.index > 0,
select: 1
)
from(
t in Transaction,
as: :transaction,
where: t.status == ^:error,
where: not exists(pbo_query),
where: exists(it_query),
where: not exists(it_error_query)
)
end
@impl FillingMigration
def update_batch(block_numbers) do
now = DateTime.utc_now()
params =
Block
|> where([b], b.number in ^block_numbers)
|> select([b], %{block_hash: b.hash, block_number: b.number})
|> Repo.all()
|> Enum.uniq_by(& &1.block_number)
|> Enum.map(&Map.merge(&1, %{inserted_at: now, updated_at: now}))
Repo.insert_all(PendingBlockOperation, params, on_conflict: :nothing)
end
@impl FillingMigration
def update_cache, do: :ok
end

@ -0,0 +1,73 @@
defmodule Explorer.Migrator.ReindexInternalTransactionsWithIncompatibleStatusTest do
use Explorer.DataCase, async: false
alias Explorer.Chain.PendingBlockOperation
alias Explorer.Migrator.{ReindexInternalTransactionsWithIncompatibleStatus, MigrationStatus}
alias Explorer.Repo
describe "Migrate incorrect internal transactions" do
test "Adds new pbo for incorrect internal transactions" do
incorrect_block_numbers =
Enum.map(1..5, fn i ->
block = insert(:block)
transaction = :transaction |> insert() |> with_block(block, status: :error)
insert(:internal_transaction,
index: 10,
transaction: transaction,
block: block,
block_number: block.number,
block_index: i,
error: nil
)
block.number
end)
Enum.each(1..5, fn i ->
block = insert(:block)
transaction = :transaction |> insert() |> with_block(block, status: :error)
insert(:internal_transaction,
index: 10,
transaction: transaction,
block: block,
block_number: block.number,
block_index: i,
error: "error",
output: nil
)
end)
Enum.each(1..5, fn i ->
block = insert(:block)
transaction = :transaction |> insert() |> with_block(block, status: :ok)
insert(:internal_transaction,
index: 10,
transaction: transaction,
block: block,
block_number: block.number,
block_index: i,
error: nil
)
end)
assert MigrationStatus.get_status("reindex_internal_transactions_with_incompatible_status") == nil
assert Repo.all(PendingBlockOperation) == []
ReindexInternalTransactionsWithIncompatibleStatus.start_link([])
Process.sleep(100)
pbo_block_numbers =
PendingBlockOperation
|> Repo.all()
|> Enum.map(& &1.block_number)
|> Enum.sort()
assert incorrect_block_numbers == pbo_block_numbers
assert MigrationStatus.get_status("reindex_internal_transactions_with_incompatible_status") == "completed"
end
end
end
Loading…
Cancel
Save