fix: Fix internal transaction validation (#10443)

* Fix internal transaction validation

* Add parsing function clause for failed internal transaction, add logging of to internal transaction changeset validation
production-shibarium
Victor Baranov 3 months ago committed by GitHub
parent 63805dbc1b
commit 8382c357f4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 44
      apps/ethereum_jsonrpc/lib/ethereum_jsonrpc.ex
  2. 34
      apps/ethereum_jsonrpc/lib/ethereum_jsonrpc/geth/call.ex

@ -580,15 +580,43 @@ defmodule EthereumJSONRPC do
defp chunk_requests(requests, nil), do: requests
defp chunk_requests(requests, chunk_size), do: Enum.chunk_every(requests, chunk_size)
def put_if_present(result, map, keys) do
Enum.reduce(keys, result, fn {from_key, to_key}, acc ->
value = map[from_key]
def put_if_present(result, transaction, keys) do
Enum.reduce(keys, result, fn key, acc ->
key_list = key |> Tuple.to_list()
from_key = Enum.at(key_list, 0)
to_key = Enum.at(key_list, 1)
opts = if Enum.count(key_list) > 2, do: Enum.at(key_list, 2), else: %{}
if value do
Map.put(acc, to_key, value)
else
acc
end
value = transaction[from_key]
validate_key(acc, to_key, value, opts)
end)
end
defp validate_key(acc, _to_key, nil, _opts), do: acc
defp validate_key(acc, to_key, value, %{:validation => validation}) do
case validation do
:address_hash ->
if address_correct?(value), do: Map.put(acc, to_key, value), else: acc
_ ->
Map.put(acc, to_key, value)
end
end
defp validate_key(acc, to_key, value, _validation) do
Map.put(acc, to_key, value)
end
# todo: The similar function exists in Indexer application:
# Here is the room for future refactoring to keep a single function.
@spec address_correct?(binary()) :: boolean()
defp address_correct?(address) when is_binary(address) do
String.match?(address, ~r/^0x[[:xdigit:]]{40}$/i)
end
defp address_correct?(_address) do
false
end
end

@ -363,6 +363,38 @@ defmodule EthereumJSONRPC.Geth.Call do
])
end
# failed internal transaction
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,
"error" => error
})
when type in ~w(create create2) and not is_nil(error) 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,
gas_used: gas_used,
init: init,
value: value,
error: error
}
end
defp elixir_to_internal_transaction_params(
%{
"blockNumber" => block_number,
@ -394,7 +426,7 @@ defmodule EthereumJSONRPC.Geth.Call do
}
|> put_if_present(params, [
{"error", :error},
{"createdContractAddressHash", :created_contract_address_hash},
{"createdContractAddressHash", :created_contract_address_hash, %{validation: :address_hash}},
{"createdContractCode", :created_contract_code}
])
end

Loading…
Cancel
Save