Add callTracer support for geth

mf-implement-fetching-internal-txs-using-call-tracer
sl1depengwyn 2 years ago
parent 308ef02d93
commit 498ca30253
  1. 68
      apps/ethereum_jsonrpc/lib/ethereum_jsonrpc/geth.ex
  2. 5
      config/runtime.exs
  3. 1
      docker-compose/envs/common-blockscout.env
  4. 3
      docker/Makefile

@ -73,10 +73,16 @@ defmodule EthereumJSONRPC.Geth do
debug_trace_transaction_timeout =
Application.get_env(:ethereum_jsonrpc, __MODULE__)[:debug_trace_transaction_timeout]
tracer =
case Application.get_env(:ethereum_jsonrpc, __MODULE__)[:tracer] do
"js" -> @tracer
"call_tracer" -> "callTracer"
end
request(%{
id: id,
method: "debug_traceTransaction",
params: [hash_data, %{tracer: @tracer, timeout: debug_trace_transaction_timeout}]
params: [hash_data, %{tracer: tracer, timeout: debug_trace_transaction_timeout}]
})
end
@ -169,6 +175,7 @@ defmodule EthereumJSONRPC.Geth do
internal_transaction_params =
calls
|> prepare_calls()
|> Stream.with_index()
|> Enum.map(fn {trace, index} ->
Map.merge(trace, %{
@ -215,6 +222,65 @@ defmodule EthereumJSONRPC.Geth do
{:error, annotated_error}
end
defp prepare_calls(calls) do
case Application.get_env(:ethereum_jsonrpc, __MODULE__)[:tracer] do
"call_tracer" -> {calls, 0} |> parse_call_tracer_calls([], [], false) |> Enum.reverse()
"js" -> calls
end
end
defp parse_call_tracer_calls(calls, acc, trace_address, inner? \\ true)
defp parse_call_tracer_calls([], acc, _trace_address, _inner?), do: acc
defp parse_call_tracer_calls({%{"type" => 0}, _}, acc, _trace_address, _inner?), do: acc
defp parse_call_tracer_calls(
{%{"type" => type, "from" => from} = call, index},
acc,
trace_address,
inner?
) do
new_trace_address = [index | trace_address]
formatted_call =
%{
"type" => if(type in ~w(CALL CALLCODE DELEGATECALL STATICCALL), do: "call", else: String.downcase(type)),
"callType" => String.downcase(type),
"from" => from,
"to" => Map.get(call, "to", "0x"),
"createdContractAddressHash" => Map.get(call, "to", "0x"),
"value" => Map.get(call, "value", "0x0"),
"gas" => Map.get(call, "gas", "0x0"),
"gasUsed" => Map.get(call, "gasUsed", "0x0"),
"input" => Map.get(call, "input", "0x"),
"init" => Map.get(call, "input", "0x"),
"createdContractCode" => Map.get(call, "output", "0x"),
"traceAddress" => if(inner?, do: Enum.reverse(new_trace_address), else: []),
"error" => call["error"]
}
|> case do
%{"error" => nil} = ok_call ->
ok_call
|> Map.delete("error")
# to handle staticcall, all other cases handled by EthereumJSONRPC.Geth.Call.elixir_to_internal_transaction_params/1
|> Map.put("output", Map.get(call, "output", "0x"))
error_call ->
error_call
end
parse_call_tracer_calls(
Map.get(call, "calls", []),
[formatted_call | acc],
if(inner?, do: new_trace_address, else: [])
)
end
defp parse_call_tracer_calls(calls, acc, trace_address, _inner) when is_list(calls) do
calls
|> Stream.with_index()
|> Enum.reduce(acc, &parse_call_tracer_calls(&1, &2, trace_address))
end
defp reduce_internal_transactions_params(internal_transactions_params) when is_list(internal_transactions_params) do
internal_transactions_params
|> Enum.reduce({:ok, []}, &internal_transactions_params_reducer/2)

@ -180,7 +180,10 @@ config :ethereum_jsonrpc,
disable_archive_balances?: System.get_env("ETHEREUM_JSONRPC_DISABLE_ARCHIVE_BALANCES", "false") == "true"
debug_trace_transaction_timeout = System.get_env("ETHEREUM_JSONRPC_DEBUG_TRACE_TRANSACTION_TIMEOUT", "5s")
config :ethereum_jsonrpc, EthereumJSONRPC.Geth, debug_trace_transaction_timeout: debug_trace_transaction_timeout
config :ethereum_jsonrpc, EthereumJSONRPC.Geth,
debug_trace_transaction_timeout: debug_trace_transaction_timeout,
tracer: System.get_env("INDEXER_INTERNAL_TRANSACTIONS_TRACER_TYPE", "call_tracer")
config :ethereum_jsonrpc, EthereumJSONRPC.PendingTransaction,
type: System.get_env("ETHEREUM_JSONRPC_PENDING_TRANSACTIONS_TYPE", "default")

@ -93,6 +93,7 @@ INDEXER_DISABLE_INTERNAL_TRANSACTIONS_FETCHER=false
# TOKEN_ID_MIGRATION_FIRST_BLOCK=
# TOKEN_ID_MIGRATION_CONCURRENCY=
# TOKEN_ID_MIGRATION_BATCH_SIZE=
# INDEXER_INTERNAL_TRANSACTIONS_TRACER_TYPE=
# WEBAPP_URL=
# API_URL=
WOBSERVER_ENABLED=false

@ -475,6 +475,9 @@ endif
ifdef INDEXER_EMPTY_BLOCKS_SANITIZER_BATCH_SIZE
BLOCKSCOUT_CONTAINER_PARAMS += -e 'INDEXER_EMPTY_BLOCKS_SANITIZER_BATCH_SIZE=$(INDEXER_EMPTY_BLOCKS_SANITIZER_BATCH_SIZE)'
endif
ifdef INDEXER_INTERNAL_TRANSACTIONS_TRACER_TYPE
BLOCKSCOUT_CONTAINER_PARAMS += -e 'INDEXER_INTERNAL_TRANSACTIONS_TRACER_TYPE=$(INDEXER_INTERNAL_TRANSACTIONS_TRACER_TYPE)'
endif
ifdef TOKEN_ID_MIGRATION_FIRST_BLOCK
BLOCKSCOUT_CONTAINER_PARAMS += -e 'INDEXER_EMPTY_BLOCKS_SANITIZER_BATCH_SIZE=$(INDEXER_EMPTY_BLOCKS_SANITIZER_BATCH_SIZE)'
endif

Loading…
Cancel
Save