From c00dfbc4d936859c880d7cc3864bd3fa40758aa0 Mon Sep 17 00:00:00 2001 From: Viktor Baranov Date: Thu, 18 Mar 2021 16:15:36 +0300 Subject: [PATCH] Remove pending transactions from DB which are dropped from the node --- apps/explorer/lib/explorer/chain.ex | 2 +- .../indexer/pending_transactions_sanitizer.ex | 44 +++++++++++++++++-- 2 files changed, 42 insertions(+), 4 deletions(-) diff --git a/apps/explorer/lib/explorer/chain.ex b/apps/explorer/lib/explorer/chain.ex index b1c074a297..522ba634b7 100644 --- a/apps/explorer/lib/explorer/chain.ex +++ b/apps/explorer/lib/explorer/chain.ex @@ -2759,7 +2759,7 @@ defmodule Explorer.Chain do ) query - |> Repo.all() + |> Repo.all(timeout: :infinity) end @doc """ diff --git a/apps/indexer/lib/indexer/pending_transactions_sanitizer.ex b/apps/indexer/lib/indexer/pending_transactions_sanitizer.ex index 74a47232a9..574f4b7bfa 100644 --- a/apps/indexer/lib/indexer/pending_transactions_sanitizer.ex +++ b/apps/indexer/lib/indexer/pending_transactions_sanitizer.ex @@ -10,6 +10,7 @@ defmodule Indexer.PendingTransactionsSanitizer do import EthereumJSONRPC, only: [json_rpc: 2, request: 1] + alias Ecto.Changeset alias Explorer.{Chain, Repo} alias Explorer.Chain.Import.Runner.Blocks @@ -70,18 +71,32 @@ defmodule Indexer.PendingTransactionsSanitizer do pending_tx_hash_str = "0x" <> Base.encode16(pending_tx.hash.bytes, case: :lower) with {:ok, result} <- - %{id: ind, method: "eth_getTransactionReceipt", params: [pending_tx_hash_str]} + %{id: ind, method: "eth_getTransactionByHash", params: [pending_tx_hash_str]} |> request() |> json_rpc(json_rpc_named_arguments) do if result do block_hash = Map.get(result, "blockHash") + if block_hash do + Logger.debug( + "Transaction with hash #{pending_tx_hash_str} already included into the block #{block_hash}. We should invalidate consensus for it in order to re-fetch transactions", + fetcher: :pending_transactions_to_refetch + ) + + fetch_block_and_invalidate(block_hash) + else + Logger.debug( + "Transaction with hash #{pending_tx_hash_str} is still pending. Do nothing.", + fetcher: :pending_transactions_to_refetch + ) + end + else Logger.debug( - "Transaction #{pending_tx_hash_str} already included into the block #{block_hash}. We should invalidate consensus for it in order to re-fetch transactions", + "Transaction with hash #{pending_tx_hash_str} doesn't exist in the node anymore. We should remove it from Blockscout DB.", fetcher: :pending_transactions_to_refetch ) - fetch_block_and_invalidate(block_hash) + fetch_pending_transaction_and_delete(pending_tx) end end end) @@ -91,6 +106,29 @@ defmodule Indexer.PendingTransactionsSanitizer do ) end + defp fetch_pending_transaction_and_delete(transaction) do + pending_tx_hash_str = "0x" <> Base.encode16(transaction.hash.bytes, case: :lower) + + case transaction + |> Changeset.change() + |> Repo.delete() do + {:ok, _transaction} -> + Logger.debug( + "Transaction with hash #{pending_tx_hash_str} successfully deleted from Blockscout DB because it doesn't exist in the archive node anymore", + fetcher: :pending_transactions_to_refetch + ) + + {:error, changeset} -> + Logger.debug( + [ + "Deletion of pending transaction with hash #{pending_tx_hash_str} from Blockscout DB failed", + inspect(changeset) + ], + fetcher: :pending_transactions_to_refetch + ) + end + end + defp fetch_block_and_invalidate(block_hash) do case Chain.fetch_block_by_hash(block_hash) do %{number: number, consensus: consensus} ->