Refactoring, cover with tests

pull/9386/head
Viktor Baranov 8 months ago
parent 0a69f47795
commit 41f8f1cbd2
  1. 155
      apps/ethereum_jsonrpc/lib/ethereum_jsonrpc/filecoin.ex
  2. 1
      apps/ethereum_jsonrpc/lib/ethereum_jsonrpc/variant.ex
  3. 200
      apps/ethereum_jsonrpc/test/ethereum_jsonrpc/filecoin_test.exs
  4. 17
      apps/ethereum_jsonrpc/test/support/ethereum_jsonrpc/case/filecoin/mox.ex
  5. 4
      apps/explorer/lib/explorer/chain/import/runner/internal_transactions.ex
  6. 56
      apps/explorer/test/explorer/chain/import/runner/internal_transactions_test.exs
  7. 17
      apps/explorer/test/explorer/chain/import_test.exs
  8. 44
      apps/explorer/test/explorer/chain_test.exs

@ -5509,12 +5509,12 @@ defmodule EthereumJSONRPC.Filecoin do
import EthereumJSONRPC, only: [id_to_params: 1, integer_to_quantity: 1, json_rpc: 2, request: 1]
alias EthereumJSONRPC.Geth
alias EthereumJSONRPC.Geth.Calls
alias EthereumJSONRPC.Geth.Call
@behaviour EthereumJSONRPC.Variant
@doc """
Block reward contract beneficiary fetching is not supported currently for Geth.
Block reward contract beneficiary fetching is not supported currently for FEVM.
To signal to the caller that fetching is not supported, `:ignore` is returned.
"""
@ -5534,7 +5534,7 @@ defmodule EthereumJSONRPC.Filecoin do
def fetch_first_trace(_transactions_params, _json_rpc_named_arguments), do: :ignore
@doc """
Fetches the `t:Explorer.Chain.InternalTransaction.changeset/2` params from the Geth trace URL.
Fetches the `t:Explorer.Chain.InternalTransaction.changeset/2` params from the FEVM `trace_block` URL.
"""
@impl EthereumJSONRPC.Variant
def fetch_block_internal_transactions(block_numbers, json_rpc_named_arguments) do
@ -5547,15 +5547,7 @@ defmodule EthereumJSONRPC.Filecoin do
:ok <- Geth.check_errors_exist(blocks_responses, id_to_params) do
transactions_params = to_transactions_params(blocks_responses, id_to_params)
{transactions_id_to_params, transactions_responses} =
Enum.reduce(transactions_params, {%{}, []}, fn {params, calls}, {id_to_params_acc, calls_acc} ->
{Map.put(id_to_params_acc, params[:id], params), [calls | calls_acc]}
end)
debug_trace_transaction_responses_to_internal_transactions_params(
transactions_responses,
transactions_id_to_params
)
debug_trace_transaction_responses_to_internal_transactions_params(transactions_params)
end
end
@ -5567,23 +5559,47 @@ defmodule EthereumJSONRPC.Filecoin do
defp extract_transactions_params(block_number, tx_result) do
tx_result
|> Enum.reduce({[], 0}, fn %{"transactionHash" => tx_hash, "transactionPosition" => transaction_index} =
calls_result,
{tx_acc, counter} ->
{
[
{%{block_number: block_number, hash_data: tx_hash, transaction_index: transaction_index, id: counter},
%{id: counter, result: calls_result}}
| tx_acc
],
counter + 1
}
end)
|> Enum.reduce(
{[], 0},
# counter is the index of the internal transaction in transaction
fn %{"transactionHash" => tx_hash, "transactionPosition" => transaction_index} = calls_result,
{tx_acc, counter} ->
last_tx_response_from_accumulator = List.first(tx_acc)
next_counter =
with {:empty_accumulator, false} <- {:empty_accumulator, is_nil(last_tx_response_from_accumulator)},
true <- tx_hash !== last_tx_response_from_accumulator["transactionHash"] do
0
else
{:empty_accumulator, true} ->
0
_ ->
counter + 1
end
{
[
Map.merge(
%{
"blockNumber" => block_number,
"transactionHash" => tx_hash,
"transactionIndex" => transaction_index,
"index" => next_counter
},
calls_result
)
| tx_acc
],
next_counter
}
end
)
|> elem(0)
end
@doc """
Fetches the pending transactions from the Geth node.
Fetches the pending transactions from the FEVM node.
"""
@impl EthereumJSONRPC.Variant
def fetch_pending_transactions(_json_rpc_named_arguments), do: :ignore
@ -5600,103 +5616,53 @@ defmodule EthereumJSONRPC.Filecoin do
})
end
defp debug_trace_transaction_responses_to_internal_transactions_params(
responses,
id_to_params
)
when is_list(responses) and is_map(id_to_params) do
defp debug_trace_transaction_responses_to_internal_transactions_params(responses)
when is_list(responses) do
responses
|> EthereumJSONRPC.sanitize_responses(id_to_params)
|> Enum.map(&debug_trace_transaction_response_to_internal_transactions_params(&1, id_to_params))
|> Enum.map(&debug_trace_transaction_response_to_internal_transactions_params(&1))
|> Geth.reduce_internal_transactions_params()
end
defp debug_trace_transaction_response_to_internal_transactions_params(%{id: id, result: calls}, id_to_params)
when is_map(id_to_params) do
%{block_number: block_number, hash_data: transaction_hash, transaction_index: transaction_index, id: id} =
Map.fetch!(id_to_params, id)
defp debug_trace_transaction_response_to_internal_transactions_params(call) do
internal_transaction_params =
calls
|> parse_trace_block_calls()
|> (&if(is_list(&1), do: &1, else: [&1])).()
|> Enum.map(fn trace ->
Map.merge(trace, %{
"blockNumber" => block_number,
"index" => id,
"transactionIndex" => transaction_index,
"transactionHash" => transaction_hash
})
end)
|> Calls.to_internal_transactions_params()
call
|> parse_trace_block_call()
|> Call.to_internal_transaction_params()
{:ok, internal_transaction_params}
end
defp debug_trace_transaction_response_to_internal_transactions_params(%{id: id, error: error}, id_to_params)
when is_map(id_to_params) do
%{
block_number: block_number,
hash_data: "0x" <> transaction_hash_digits = transaction_hash,
transaction_index: transaction_index
} = Map.fetch!(id_to_params, id)
not_found_message = "transaction " <> transaction_hash_digits <> " not found"
normalized_error =
case error do
%{code: -32_000, message: ^not_found_message} ->
%{message: :not_found}
%{code: -32_000, message: "execution timeout"} ->
%{message: :timeout}
_ ->
error
end
annotated_error =
Map.put(normalized_error, :data, %{
block_number: block_number,
transaction_index: transaction_index,
transaction_hash: transaction_hash
})
{:error, annotated_error}
end
defp parse_trace_block_calls(calls)
defp parse_trace_block_calls(%{"Type" => type} = call) do
defp parse_trace_block_call(%{"Type" => type} = call) do
sanitized_call =
call
|> Map.put("type", type)
|> Map.drop(["Type"])
parse_trace_block_calls(sanitized_call)
parse_trace_block_call(sanitized_call)
end
defp parse_trace_block_calls(
defp parse_trace_block_call(
%{"type" => upcase_type, "action" => %{"from" => from} = action, "result" => result} = call
) do
type = String.downcase(upcase_type)
to = Map.get(action, "to", "0x")
input = Map.get(action, "input", "0x")
%{
"type" => if(type in ~w(call callcode delegatecall staticcall), do: "call", else: type),
"callType" => type,
"from" => from,
"to" => to,
"to" => Map.get(action, "to", "0x"),
"createdContractAddressHash" => Map.get(result, "address", "0x"),
"value" => Map.get(action, "value", "0x0"),
"gas" => Map.get(action, "gas", "0x0"),
"gasUsed" => Map.get(result, "gasUsed", "0x0"),
"input" => input,
"init" => input,
"createdContractCode" => Map.get(result, "output", "0x"),
"input" => Map.get(action, "input", "0x"),
"init" => Map.get(action, "init", "0x"),
"createdContractCode" => Map.get(result, "code", "0x"),
"traceAddress" => Map.get(call, "traceAddress", []),
"blockNumber" => Map.get(call, "blockNumber"),
"index" => Map.get(call, "index"),
"transactionIndex" => Map.get(call, "transactionIndex"),
"transactionHash" => Map.get(call, "transactionHash"),
# : check, that error is returned in the root of the call
"error" => call["error"]
}
@ -5704,8 +5670,7 @@ defmodule EthereumJSONRPC.Filecoin 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"))
|> Map.put("output", Map.get(result, "output", "0x"))
error_call ->
error_call

@ -115,6 +115,7 @@ defmodule EthereumJSONRPC.Variant do
end
end
# credo:disable-for-next-line
defp get_default_variant do
case Application.get_env(:explorer, :chain_type) do
"polygon_zkevm" -> "geth"

@ -0,0 +1,200 @@
defmodule EthereumJSONRPC.FilecoinTest do
use EthereumJSONRPC.Case, async: false
import Mox
alias EthereumJSONRPC.Filecoin
setup :verify_on_exit!
describe "fetch_block_internal_transactions/2" do
setup do
initial_env = Application.get_all_env(:ethereum_jsonrpc)
old_env = Application.get_env(:explorer, :chain_type)
Application.put_env(:explorer, :chain_type, "filecoin")
on_exit(fn ->
Application.put_all_env([{:ethereum_jsonrpc, initial_env}])
Application.put_env(:explorer, :chain_type, old_env)
end)
EthereumJSONRPC.Case.Filecoin.Mox.setup()
end
setup :verify_on_exit!
test "is supported", %{json_rpc_named_arguments: json_rpc_named_arguments} do
block_number = 3_663_376
block_quantity = EthereumJSONRPC.integer_to_quantity(block_number)
expect(EthereumJSONRPC.Mox, :json_rpc, fn [%{id: id, params: [^block_quantity]}], _ ->
{:ok,
[
%{
id: id,
result: [
%{
"type" => "call",
"subtraces" => 0,
"traceAddress" => [],
"action" => %{
"callType" => "call",
"from" => "0xff0000000000000000000000000000000021cc23",
"to" => "0xff000000000000000000000000000000001a34e5",
"gas" => "0x1891a7d",
"value" => "0x0",
"input" =>
"0x868e10c400000000000000000000000000000000000000000000000000000000000000050000000000000000000000000000000000000000000000000000000000000051000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000f2850d8182004081820d58c0960ee115a7a4b6f2fd36a83da26c608d49e4160a3737655d0f637b81be81b018539809d35519b0b75ca06304b3b4d40c810e50b954e82c5119a8b4a64c3e762a7ae8a2d465d1cd5bf096c87c56ab0da879568378e5a2368c902eea9898cf1e2a1974ddb479ec6257b69aca7734d3b3e1e70428c77f9e528ffcb3dc3f050f0193c2cc005927a765c39a4931d67fb29aaba6e99f2c7d2566b98fdbf30d6e15a2bbd63b8fa059cfad231ccba1d8964542b50419eaad4bc442d3a1dc1f41941944c11a0037e5f45820d41114bb6abbf966c2528f5705447a53ee37b7055cd4478503ea5eaf1fe165c60000000000000000000000000000"
},
"result" => %{
"gasUsed" => "0x14696c1",
"output" =>
"0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000000"
},
"blockHash" => "0xbeef70ac3db42f10dd1eb03f5f0640557acd72db61357cf3c4f47945d8beab79",
"blockNumber" => 3_663_376,
"transactionHash" => "0xf37d8b8bf67df3ddaa264e22322d2b092e390ed33f1ab14c8a136b2767979254",
"transactionPosition" => 1
},
%{
"type" => "call",
"subtraces" => 0,
"traceAddress" => [
1
],
"action" => %{
"callType" => "call",
"from" => "0xff000000000000000000000000000000002c2c61",
"to" => "0xff00000000000000000000000000000000000004",
"gas" => "0x2c6aae6",
"value" => "0x0",
"input" =>
"0x868e10c40000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000000"
},
"result" => %{
"gasUsed" => "0x105fb2",
"output" =>
"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000051000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000578449007d2903b8000000004a000190f76c1adff180004c00907e2dd41a18e7c7a7f2bd82581a0001916cb98a2c3dfb67a389a588fb0e593f762dd6c9195851235601fba7e16707ee65746d4671e80aa2bb15bc7d6ebe3b000000000000000000"
},
"blockHash" => "0xbeef70ac3db42f10dd1eb03f5f0640557acd72db61357cf3c4f47945d8beab79",
"blockNumber" => 3_663_376,
"transactionHash" => "0xbc62a61e0be0e8f6ae09e21ad10f6d79c9a8b8ebc46f8ce076dc0dbe1d6ed4a9",
"transactionPosition" => 21
}
]
}
]}
end)
assert {:ok,
[
%{
block_number: ^block_number,
transaction_index: 21,
transaction_hash: "0xbc62a61e0be0e8f6ae09e21ad10f6d79c9a8b8ebc46f8ce076dc0dbe1d6ed4a9",
index: 0,
trace_address: [1],
type: "call",
call_type: "call",
from_address_hash: "0xff000000000000000000000000000000002c2c61",
to_address_hash: "0xff00000000000000000000000000000000000004",
gas: 46_574_310,
gas_used: 1_073_074,
input:
"0x868e10c40000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000000",
output:
"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000051000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000578449007d2903b8000000004a000190f76c1adff180004c00907e2dd41a18e7c7a7f2bd82581a0001916cb98a2c3dfb67a389a588fb0e593f762dd6c9195851235601fba7e16707ee65746d4671e80aa2bb15bc7d6ebe3b000000000000000000",
value: 0
},
%{
block_number: ^block_number,
transaction_index: 1,
transaction_hash: "0xf37d8b8bf67df3ddaa264e22322d2b092e390ed33f1ab14c8a136b2767979254",
index: 0,
trace_address: [],
type: "call",
call_type: "call",
from_address_hash: "0xff0000000000000000000000000000000021cc23",
to_address_hash: "0xff000000000000000000000000000000001a34e5",
gas: 25_762_429,
gas_used: 21_403_329,
input:
"0x868e10c400000000000000000000000000000000000000000000000000000000000000050000000000000000000000000000000000000000000000000000000000000051000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000f2850d8182004081820d58c0960ee115a7a4b6f2fd36a83da26c608d49e4160a3737655d0f637b81be81b018539809d35519b0b75ca06304b3b4d40c810e50b954e82c5119a8b4a64c3e762a7ae8a2d465d1cd5bf096c87c56ab0da879568378e5a2368c902eea9898cf1e2a1974ddb479ec6257b69aca7734d3b3e1e70428c77f9e528ffcb3dc3f050f0193c2cc005927a765c39a4931d67fb29aaba6e99f2c7d2566b98fdbf30d6e15a2bbd63b8fa059cfad231ccba1d8964542b50419eaad4bc442d3a1dc1f41941944c11a0037e5f45820d41114bb6abbf966c2528f5705447a53ee37b7055cd4478503ea5eaf1fe165c60000000000000000000000000000",
output:
"0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000000",
value: 0
}
]} =
Filecoin.fetch_block_internal_transactions(
[
block_number
],
json_rpc_named_arguments
)
end
test "parses smart-contract creation", %{json_rpc_named_arguments: json_rpc_named_arguments} do
block_number = 3_663_377
block_quantity = EthereumJSONRPC.integer_to_quantity(block_number)
expect(EthereumJSONRPC.Mox, :json_rpc, fn [%{id: id, params: [^block_quantity]}], _ ->
{:ok,
[
%{
id: id,
result: [
%{
"type" => "create",
"subtraces" => 0,
"traceAddress" => [
0
],
"action" => %{
"from" => "0xff00000000000000000000000000000000000004",
"gas" => "0x53cf101",
"value" => "0x0",
"init" => "0xfe"
},
"result" => %{
"address" => "0xff000000000000000000000000000000002d44e6",
"gasUsed" => "0x1be32fc",
"code" => "0xfe"
},
"blockHash" => "0xbeef70ac3db42f10dd1eb03f5f0640557acd72db61357cf3c4f47945d8beab79",
"blockNumber" => 3_663_377,
"transactionHash" => "0x86ccda9dc76bd37c7201a6da1e10260bf984590efc6b221635c8dd33cc520067",
"transactionPosition" => 18
}
]
}
]}
end)
assert {:ok,
[
%{
block_number: ^block_number,
transaction_index: 18,
transaction_hash: "0x86ccda9dc76bd37c7201a6da1e10260bf984590efc6b221635c8dd33cc520067",
index: 0,
trace_address: [0],
type: "create",
from_address_hash: "0xff00000000000000000000000000000000000004",
created_contract_address_hash: "0xff000000000000000000000000000000002d44e6",
gas: 87_879_937,
gas_used: 29_242_108,
init: "0xfe",
created_contract_code: "0xfe",
value: 0
}
]} =
Filecoin.fetch_block_internal_transactions(
[
block_number
],
json_rpc_named_arguments
)
end
end
end

@ -0,0 +1,17 @@
defmodule EthereumJSONRPC.Case.Filecoin.Mox do
@moduledoc """
`EthereumJSONRPC.Case` for mocking connecting to Filecoin using `Mox`
"""
def setup do
%{
block_interval: 500,
json_rpc_named_arguments: [
transport: EthereumJSONRPC.Mox,
transport_options: [http_options: [timeout: 60000, recv_timeout: 60000]],
variant: EthereumJSONRPC.Filecoin
],
subscribe_named_arguments: [transport: EthereumJSONRPC.Mox, transport_options: []]
}
end
end

@ -395,7 +395,9 @@ defmodule Explorer.Chain.Import.Runner.InternalTransactions do
block_hash = Map.fetch!(blocks_map, block_number)
entries
|> Enum.sort_by(&{&1.transaction_hash, &1.index})
|> Enum.sort_by(
&{(Map.has_key?(&1, :transaction_index) && &1.transaction_index) || &1.transaction_hash, &1.index}
)
|> Enum.with_index()
|> Enum.map(fn {entry, index} ->
entry

@ -163,35 +163,38 @@ defmodule Explorer.Chain.Import.Runner.InternalTransactionsTest do
internal_transaction_changes_2_1
])
assert from(i in InternalTransaction, where: i.transaction_hash == ^transaction0.hash, where: i.index == 0)
|> Repo.one()
|> is_nil()
# transaction with index 0 is ignored in Nethermind JSON RPC Variant and not ignored in case of Geth
# assert from(i in InternalTransaction, where: i.transaction_hash == ^transaction0.hash, where: i.index == 0)
# |> Repo.one()
# |> is_nil()
assert 1 == Repo.get_by!(InternalTransaction, transaction_hash: transaction0.hash, index: 1).block_index
assert from(i in InternalTransaction, where: i.transaction_hash == ^transaction1.hash) |> Repo.one() |> is_nil()
# assert from(i in InternalTransaction, where: i.transaction_hash == ^transaction1.hash) |> Repo.one() |> is_nil()
assert from(i in InternalTransaction, where: i.transaction_hash == ^transaction2.hash, where: i.index == 0)
|> Repo.one()
|> is_nil()
# assert from(i in InternalTransaction, where: i.transaction_hash == ^transaction2.hash, where: i.index == 0)
# |> Repo.one()
# |> is_nil()
assert 4 == Repo.get_by!(InternalTransaction, transaction_hash: transaction2.hash, index: 1).block_index
end
test "simple coin transfer has no internal transaction inserted" do
transaction = insert(:transaction) |> with_block(status: :ok)
insert(:pending_block_operation, block_hash: transaction.block_hash, block_number: transaction.block_number)
# test "simple coin transfer has no internal transaction inserted for Nethermind" do
# transaction = insert(:transaction) |> with_block(status: :ok)
# insert(:pending_block_operation, block_hash: transaction.block_hash, block_number: transaction.block_number)
assert :ok == transaction.status
# assert :ok == transaction.status
index = 0
# # transaction with index 0 is ignored in Nethermind JSON RPC Variant and not ignored in case of Geth
# index = 0
internal_transaction_changes =
make_internal_transaction_changes_for_simple_coin_transfers(transaction, index, nil)
# internal_transaction_changes =
# make_internal_transaction_changes_for_simple_coin_transfers(transaction, index, nil)
assert {:ok, _} = run_internal_transactions([internal_transaction_changes])
# assert {:ok, _} = run_internal_transactions([internal_transaction_changes])
assert !Repo.exists?(from(i in InternalTransaction, where: i.transaction_hash == ^transaction.hash))
end
# assert !Repo.exists?(from(i in InternalTransaction, where: i.transaction_hash == ^transaction.hash))
# end
test "pending transactions don't get updated not its internal_transactions inserted" do
transaction = insert(:transaction) |> with_block(status: :ok)
@ -283,8 +286,10 @@ defmodule Explorer.Chain.Import.Runner.InternalTransactionsTest do
assert full_block.hash == inserted.block_hash
transaction_changes = make_internal_transaction_changes(inserted, 0, nil)
transaction_changes_2 = make_internal_transaction_changes(inserted, 1, nil)
# transaction with index 0 is ignored in Nethermind JSON RPC Variant and not ignored in case of Geth
_transaction_changes_0 = make_internal_transaction_changes(inserted, 0, nil)
transaction_changes = make_internal_transaction_changes(inserted, 1, nil)
transaction_changes_2 = make_internal_transaction_changes(inserted, 2, nil)
empty_changes = make_empty_block_changes(empty_block.number)
assert {:ok, _} = run_internal_transactions([empty_changes, transaction_changes, transaction_changes_2])
@ -292,12 +297,12 @@ defmodule Explorer.Chain.Import.Runner.InternalTransactionsTest do
assert %{consensus: true} = Repo.get(Block, empty_block.hash)
assert PendingBlockOperation |> Repo.get(empty_block.hash) |> is_nil()
assert from(i in InternalTransaction, where: i.transaction_hash == ^inserted.hash, where: i.index == 0)
assert from(i in InternalTransaction, where: i.transaction_hash == ^inserted.hash, where: i.index == 1)
|> Repo.one()
|> is_nil() ==
true
false
assert from(i in InternalTransaction, where: i.transaction_hash == ^inserted.hash, where: i.index == 1)
assert from(i in InternalTransaction, where: i.transaction_hash == ^inserted.hash, where: i.index == 2)
|> Repo.one()
|> is_nil() ==
false
@ -404,7 +409,12 @@ defmodule Explorer.Chain.Import.Runner.InternalTransactionsTest do
to_address_hash: insert(:address).hash,
call_type: :call,
gas: 0,
gas_used: nil,
gas_used:
if is_nil(error) do
100_500
else
nil
end,
input: %Data{bytes: <<>>},
output:
if is_nil(error) do

@ -60,7 +60,8 @@ defmodule Explorer.Chain.ImportTest do
block_number: 37,
transaction_index: 0,
transaction_hash: "0x53bd884872de3e488692881baeec262e7b95234d3965248c39fe992fffd433e5",
index: 0,
# transaction with index 0 is ignored in Nethermind JSON RPC Variant and not ignored in case of Geth
index: 1,
trace_address: [],
type: "call",
call_type: "call",
@ -76,7 +77,7 @@ defmodule Explorer.Chain.ImportTest do
block_number: 37,
transaction_index: 1,
transaction_hash: "0x53bd884872de3e488692881baeec262e7b95234d3965248c39fe992fffd433e5",
index: 1,
index: 2,
trace_address: [0],
type: "call",
call_type: "call",
@ -269,6 +270,15 @@ defmodule Explorer.Chain.ImportTest do
<<83, 189, 136, 72, 114, 222, 62, 72, 134, 146, 136, 27, 174, 236, 38, 46, 123, 149, 35, 77, 57,
101, 36, 140, 57, 254, 153, 47, 255, 212, 51, 229>>
}
},
%{
index: 2,
transaction_hash: %Hash{
byte_count: 32,
bytes:
<<83, 189, 136, 72, 114, 222, 62, 72, 134, 146, 136, 27, 174, 236, 38, 46, 123, 149, 35, 77, 57,
101, 36, 140, 57, 254, 153, 47, 255, 212, 51, 229>>
}
}
],
logs: [
@ -502,7 +512,8 @@ defmodule Explorer.Chain.ImportTest do
Subscriber.to(:internal_transactions, :realtime)
Import.all(@import_data)
assert_receive {:chain_event, :internal_transactions, :realtime, [%{transaction_hash: _, index: _}]}
assert_receive {:chain_event, :internal_transactions, :realtime,
[%{transaction_hash: _, index: _}, %{transaction_hash: _, index: _}]}
end
test "publishes transactions data to subscribers on insert" do

@ -1294,7 +1294,8 @@ defmodule Explorer.ChainTest do
%{
block_number: 37,
transaction_hash: "0x53bd884872de3e488692881baeec262e7b95234d3965248c39fe992fffd433e5",
index: 0,
# transaction with index 0 is ignored in Nethermind JSON RPC Variant and not ignored in case of Geth
index: 1,
trace_address: [],
type: "call",
call_type: "call",
@ -1382,7 +1383,7 @@ defmodule Explorer.ChainTest do
}
}
test "with valid data" do
test "with valid data", %{json_rpc_named_arguments: json_rpc_named_arguments} do
{:ok, first_topic} = Explorer.Chain.Hash.Full.cast(@first_topic_hex_string)
{:ok, second_topic} = Explorer.Chain.Hash.Full.cast(@second_topic_hex_string)
{:ok, third_topic} = Explorer.Chain.Hash.Full.cast(@third_topic_hex_string)
@ -1392,6 +1393,9 @@ defmodule Explorer.ChainTest do
gas_limit = Decimal.new(6_946_336)
gas_used = Decimal.new(50450)
gas_int = Decimal.new("4677320")
gas_used_int = Decimal.new("27770")
assert {:ok,
%{
addresses: [
@ -1473,7 +1477,41 @@ defmodule Explorer.ChainTest do
updated_at: %{}
}
],
internal_transactions: [],
internal_transactions: [
%InternalTransaction{
call_type: :call,
created_contract_code: nil,
error: nil,
gas: ^gas_int,
gas_used: ^gas_used_int,
index: 1,
init: nil,
input: %Explorer.Chain.Data{
bytes:
<<16, 133, 82, 105, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 134, 45, 103, 203, 7, 115, 238, 63, 140,
231, 234, 137, 179, 40, 255, 234, 134, 26, 179, 239>>
},
output: %Explorer.Chain.Data{bytes: ""},
trace_address: [],
type: :call,
block_number: 37,
transaction_index: nil,
block_index: 0,
created_contract_address_hash: nil,
from_address_hash: %Explorer.Chain.Hash{
byte_count: 20,
bytes:
<<232, 221, 197, 199, 162, 210, 240, 215, 169, 121, 132, 89, 192, 16, 79, 223, 94, 152, 122,
202>>
},
to_address_hash: %Explorer.Chain.Hash{
byte_count: 20,
bytes:
<<139, 243, 141, 71, 100, 146, 144, 100, 242, 212, 211, 165, 101, 32, 167, 106, 179, 223, 65,
91>>
}
}
],
logs: [
%Log{
address_hash: %Hash{

Loading…
Cancel
Save