Skip to content

Commit

Permalink
fix: Add the ability to allow empty traces (blockscout#10200)
Browse files Browse the repository at this point in the history
  • Loading branch information
Qwerty5Uiop authored Jun 6, 2024
1 parent 646a343 commit b5780d3
Show file tree
Hide file tree
Showing 4 changed files with 25 additions and 3 deletions.
15 changes: 14 additions & 1 deletion apps/ethereum_jsonrpc/lib/ethereum_jsonrpc/geth.ex
Original file line number Diff line number Diff line change
Expand Up @@ -389,6 +389,7 @@ defmodule EthereumJSONRPC.Geth do
[Map.put(last, "error", "execution stopped") | acc]
end

# credo:disable-for-next-line /Complexity/
defp parse_call_tracer_calls({%{"type" => upcase_type, "from" => from} = call, index}, acc, trace_address, inner?) do
case String.downcase(upcase_type) do
type when type in ~w(call callcode delegatecall staticcall create create2 selfdestruct revert stop invalid) ->
Expand Down Expand Up @@ -427,8 +428,12 @@ defmodule EthereumJSONRPC.Geth do
if(inner?, do: new_trace_address, else: [])
)

"" ->
unless allow_empty_traces?(), do: log_unknown_type(call)
acc

_unknown_type ->
Logger.warning("Call from a callTracer with an unknown type: #{inspect(call)}")
log_unknown_type(call)
acc
end
end
Expand All @@ -439,6 +444,10 @@ defmodule EthereumJSONRPC.Geth do
|> Enum.reduce(acc, &parse_call_tracer_calls(&1, &2, trace_address))
end

defp log_unknown_type(call) do
Logger.warning("Call from a callTracer with an unknown type: #{inspect(call)}")
end

@spec reduce_internal_transactions_params(list()) :: {:ok, list()} | {:error, list()}
def reduce_internal_transactions_params(internal_transactions_params) when is_list(internal_transactions_params) do
internal_transactions_params
Expand Down Expand Up @@ -475,4 +484,8 @@ defmodule EthereumJSONRPC.Geth do
defp tracer_type do
Application.get_env(:ethereum_jsonrpc, __MODULE__)[:tracer]
end

defp allow_empty_traces? do
Application.get_env(:ethereum_jsonrpc, __MODULE__)[:allow_empty_traces?]
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -333,7 +333,8 @@ defmodule Explorer.Chain.Import.Runner.InternalTransactions do
# common_tuples = MapSet.intersection(required_tuples, candidate_tuples) #should be added
# |> MapSet.difference(internal_transactions_tuples) should be replaced with |> MapSet.difference(common_tuples)

# Note: for zetachain, the case "# - there are no internal txs for some transactions" is removed since
# Note: for zetachain or if empty traces are explicitly allowed,
# the case "# - there are no internal txs for some transactions" is removed since
# there are may be non-traceable transactions

transactions_tuples = MapSet.new(transactions, &{&1.hash, &1.block_number})
Expand All @@ -343,7 +344,7 @@ defmodule Explorer.Chain.Import.Runner.InternalTransactions do
all_tuples = MapSet.union(transactions_tuples, internal_transactions_tuples)

invalid_block_numbers =
if Application.get_env(:explorer, :chain_type) == :zetachain do
if allow_non_traceable_transactions?() do
Enum.reduce(internal_transactions_tuples, [], fn {transaction_hash, block_number}, acc ->
# credo:disable-for-next-line
case Enum.find(transactions_tuples, fn {t_hash, _block_number} -> t_hash == transaction_hash end) do
Expand All @@ -362,6 +363,12 @@ defmodule Explorer.Chain.Import.Runner.InternalTransactions do
{:ok, invalid_block_numbers}
end

defp allow_non_traceable_transactions? do
Application.get_env(:explorer, :chain_type) == :zetachain or
(Application.get_env(:explorer, :json_rpc_named_arguments)[:variant] == EthereumJSONRPC.Geth and
Application.get_env(:ethereum_jsonrpc, EthereumJSONRPC.Geth)[:allow_empty_traces?])
end

defp valid_internal_transactions(transactions, internal_transactions_params, invalid_block_numbers) do
if Enum.empty?(transactions) do
{:ok, []}
Expand Down
1 change: 1 addition & 0 deletions config/runtime.exs
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,7 @@ config :ethereum_jsonrpc, EthereumJSONRPC.HTTP,

config :ethereum_jsonrpc, EthereumJSONRPC.Geth,
block_traceable?: ConfigHelper.parse_bool_env_var("ETHEREUM_JSONRPC_GETH_TRACE_BY_BLOCK"),
allow_empty_traces?: ConfigHelper.parse_bool_env_var("ETHEREUM_JSONRPC_GETH_ALLOW_EMPTY_TRACES"),
debug_trace_timeout: System.get_env("ETHEREUM_JSONRPC_DEBUG_TRACE_TRANSACTION_TIMEOUT", "5s"),
tracer:
if(ConfigHelper.chain_type() == :polygon_edge,
Expand Down
1 change: 1 addition & 0 deletions docker-compose/envs/common-blockscout.env
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ ETHEREUM_JSONRPC_DISABLE_ARCHIVE_BALANCES=false
# ETHEREUM_JSONRPC_HTTP_HEADERS=
# ETHEREUM_JSONRPC_WAIT_PER_TIMEOUT=
# ETHEREUM_JSONRPC_GETH_TRACE_BY_BLOCK=
# ETHEREUM_JSONRPC_GETH_ALLOW_EMPTY_TRACES=
IPC_PATH=
NETWORK_PATH=/
BLOCKSCOUT_HOST=
Expand Down

0 comments on commit b5780d3

Please sign in to comment.