From c89696b41226e211222b1a2d4bc3fc2fc28055d2 Mon Sep 17 00:00:00 2001 From: Kirill Fedoseev Date: Fri, 5 Jul 2024 15:19:52 +0400 Subject: [PATCH] fix: empty revert reasons in geth variant (#10243) --- .../lib/ethereum_jsonrpc/geth.ex | 42 ++--- .../lib/ethereum_jsonrpc/geth/call.ex | 164 +++++------------- 2 files changed, 56 insertions(+), 150 deletions(-) diff --git a/apps/ethereum_jsonrpc/lib/ethereum_jsonrpc/geth.ex b/apps/ethereum_jsonrpc/lib/ethereum_jsonrpc/geth.ex index 01c7ca4871..2033f5f95f 100644 --- a/apps/ethereum_jsonrpc/lib/ethereum_jsonrpc/geth.ex +++ b/apps/ethereum_jsonrpc/lib/ethereum_jsonrpc/geth.ex @@ -400,32 +400,22 @@ defmodule EthereumJSONRPC.Geth do type when type in ~w(call callcode delegatecall staticcall create create2 selfdestruct revert stop invalid) -> new_trace_address = [index | trace_address] - formatted_call = - %{ - "type" => if(type in ~w(call callcode delegatecall staticcall), do: "call", else: type), - "callType" => 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 + formatted_call = %{ + "type" => if(type in ~w(call callcode delegatecall staticcall), do: "call", else: type), + "callType" => 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"), + "output" => Map.get(call, "output", "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"] + } parse_call_tracer_calls( Map.get(call, "calls", []), diff --git a/apps/ethereum_jsonrpc/lib/ethereum_jsonrpc/geth/call.ex b/apps/ethereum_jsonrpc/lib/ethereum_jsonrpc/geth/call.ex index a76a0dd955..d019e0210e 100644 --- a/apps/ethereum_jsonrpc/lib/ethereum_jsonrpc/geth/call.ex +++ b/apps/ethereum_jsonrpc/lib/ethereum_jsonrpc/geth/call.ex @@ -4,6 +4,7 @@ defmodule EthereumJSONRPC.Geth.Call do using a custom tracer (`priv/js/ethereum_jsonrpc/geth/debug_traceTransaction/tracer.js`). """ import EthereumJSONRPC, only: [quantity_to_integer: 1] + import EthereumJSONRPC.Transaction, only: [put_if_present: 3] @doc """ A call can call another another contract: @@ -75,7 +76,9 @@ defmodule EthereumJSONRPC.Geth.Call do from_address_hash: "0x8ec75ef3adf6c953775d0738e0e7bd60e647e5ef", to_address_hash: "0xaae465ad04b12e90c32291e59b65ca781c57e361", gas: 1225, + gas_used: 1225, input: "0xa83627de", + output: nil, value: 0 } @@ -110,9 +113,11 @@ defmodule EthereumJSONRPC.Geth.Call do from_address_hash: "0xaf7cf620c3df1b9ccbc640be903d5ea6cea7bc96", to_address_hash: "0x80629758f88b3f30b7f1244e4588444d6276eef0", input: "0x49b46d5d", + output: nil, error: "stack limit reached 1024 (1024)", gas: 1445580, - value: 0 + gas_used: 1445580, + value: 0, } A contract creation: @@ -179,6 +184,7 @@ defmodule EthereumJSONRPC.Geth.Call do init: "0xf49e4745", error: "stack underflow (0 <=> 6)", gas: 540776, + gas_used: 540776, value: 5287885714285715 } @@ -254,8 +260,7 @@ defmodule EthereumJSONRPC.Geth.Call do gas_used: 1040, input: "0x0f370699", output: "0x", - value: 0, - error: nil + value: 0 } A selfdestruct destroys the calling contract and sends any left over balance to the to address. @@ -300,6 +305,8 @@ defmodule EthereumJSONRPC.Geth.Call do Enum.into(call, %{}, &entry_to_elixir/1) end + defp entry_to_elixir({"error", nil} = entry), do: entry + defp entry_to_elixir({key, value} = entry) when key in ~w(callType createdContractAddressHash createdContractCode error from init input output to transactionHash type) and is_binary(value), @@ -318,74 +325,6 @@ defmodule EthereumJSONRPC.Geth.Call do entry end - defp elixir_to_internal_transaction_params(%{ - "blockNumber" => block_number, - "transactionIndex" => transaction_index, - "transactionHash" => transaction_hash, - "index" => index, - "traceAddress" => trace_address, - "type" => type, - "callType" => call_type, - "from" => from_address_hash, - "to" => to_address_hash, - "gas" => gas, - "input" => input, - "error" => error, - "value" => value - }) - when type in ~w(call invalid) and call_type in ~w(call callcode delegatecall invalid) do - %{ - block_number: block_number, - transaction_index: transaction_index, - transaction_hash: transaction_hash, - index: index, - trace_address: trace_address, - type: "call", - call_type: call_type, - from_address_hash: from_address_hash, - to_address_hash: to_address_hash, - gas: gas, - input: input, - error: error, - value: value - } - end - - defp elixir_to_internal_transaction_params(%{ - "blockNumber" => block_number, - "transactionIndex" => transaction_index, - "transactionHash" => transaction_hash, - "index" => index, - "traceAddress" => trace_address, - "type" => type, - "callType" => call_type, - "from" => from_address_hash, - "to" => to_address_hash, - "gas" => gas, - "gasUsed" => gas_used, - "input" => input, - "output" => output, - "value" => value - }) - when type in ~w(call invalid) and call_type in ~w(call callcode delegatecall invalid) do - %{ - block_number: block_number, - transaction_index: transaction_index, - transaction_hash: transaction_hash, - index: index, - trace_address: trace_address, - type: "call", - call_type: call_type, - from_address_hash: from_address_hash, - to_address_hash: to_address_hash, - gas: gas, - gas_used: gas_used, - input: input, - output: output, - value: value - } - end - defp elixir_to_internal_transaction_params( %{ "blockNumber" => block_number, @@ -393,23 +332,24 @@ defmodule EthereumJSONRPC.Geth.Call do "transactionHash" => transaction_hash, "index" => index, "traceAddress" => trace_address, - "type" => "call" = type, - "callType" => "staticcall" = call_type, + "type" => type, + "callType" => call_type, "from" => from_address_hash, "to" => to_address_hash, - "input" => input, "gas" => gas, "gasUsed" => gas_used, - "value" => 0 = value + "input" => input, + "value" => value } = params - ) do + ) + when type in ~w(call invalid) and call_type in ~w(call callcode delegatecall staticcall invalid) do %{ block_number: block_number, transaction_index: transaction_index, transaction_hash: transaction_hash, index: index, trace_address: trace_address, - type: type, + type: "call", call_type: call_type, from_address_hash: from_address_hash, to_address_hash: to_address_hash, @@ -417,55 +357,28 @@ defmodule EthereumJSONRPC.Geth.Call do gas_used: gas_used, input: input, output: params["output"], - value: value, - error: params["error"] - } - end - - defp elixir_to_internal_transaction_params(%{ - "blockNumber" => block_number, - "transactionIndex" => transaction_index, - "transactionHash" => transaction_hash, - "index" => index, - "traceAddress" => trace_address, - "type" => type, - "from" => from_address_hash, - "error" => error, - "gas" => gas, - "init" => init, - "value" => value - }) - when type in ~w(create create2) do - %{ - block_number: block_number, - transaction_index: transaction_index, - transaction_hash: transaction_hash, - index: index, - trace_address: trace_address, - type: type, - from_address_hash: from_address_hash, - gas: gas, - error: error, - init: init, value: value } + |> put_if_present(params, [ + {"error", :error} + ]) end - defp elixir_to_internal_transaction_params(%{ - "blockNumber" => block_number, - "transactionIndex" => transaction_index, - "transactionHash" => transaction_hash, - "index" => index, - "traceAddress" => trace_address, - "type" => type, - "from" => from_address_hash, - "createdContractAddressHash" => created_contract_address_hash, - "gas" => gas, - "gasUsed" => gas_used, - "init" => init, - "createdContractCode" => created_contract_code, - "value" => value - }) + defp elixir_to_internal_transaction_params( + %{ + "blockNumber" => block_number, + "transactionIndex" => transaction_index, + "transactionHash" => transaction_hash, + "index" => index, + "traceAddress" => trace_address, + "type" => type, + "from" => from_address_hash, + "gas" => gas, + "gasUsed" => gas_used, + "init" => init, + "value" => value + } = params + ) when type in ~w(create create2) do %{ block_number: block_number, @@ -477,11 +390,14 @@ defmodule EthereumJSONRPC.Geth.Call do from_address_hash: from_address_hash, gas: gas, gas_used: gas_used, - created_contract_address_hash: created_contract_address_hash, init: init, - created_contract_code: created_contract_code, value: value } + |> put_if_present(params, [ + {"error", :error}, + {"createdContractAddressHash", :created_contract_address_hash}, + {"createdContractCode", :created_contract_code} + ]) end defp elixir_to_internal_transaction_params(%{