commit
b036c23d63
@ -1,147 +0,0 @@ |
|||||||
defmodule Indexer.Temporary.AddressesWithoutCode do |
|
||||||
@moduledoc """ |
|
||||||
Temporary module to fetch contract code for addresses without it. |
|
||||||
""" |
|
||||||
|
|
||||||
use GenServer |
|
||||||
use Indexer.Fetcher |
|
||||||
|
|
||||||
require Logger |
|
||||||
|
|
||||||
import Ecto.Query |
|
||||||
|
|
||||||
alias Explorer.Chain.{Address, Block, Transaction} |
|
||||||
alias Explorer.Repo |
|
||||||
alias Indexer.Block.Realtime.Fetcher |
|
||||||
alias Indexer.Temporary.AddressesWithoutCode.TaskSupervisor |
|
||||||
|
|
||||||
@task_options [max_concurrency: 3, timeout: :infinity] |
|
||||||
@batch_size 500 |
|
||||||
@query_timeout :infinity |
|
||||||
|
|
||||||
def start_link([fetcher, gen_server_options]) do |
|
||||||
GenServer.start_link(__MODULE__, fetcher, gen_server_options) |
|
||||||
end |
|
||||||
|
|
||||||
@impl GenServer |
|
||||||
def init(fetcher) do |
|
||||||
schedule_work() |
|
||||||
|
|
||||||
{:ok, fetcher} |
|
||||||
end |
|
||||||
|
|
||||||
def schedule_work do |
|
||||||
Process.send_after(self(), :run, 1_000) |
|
||||||
end |
|
||||||
|
|
||||||
@impl GenServer |
|
||||||
def handle_info(:run, fetcher) do |
|
||||||
run(fetcher) |
|
||||||
|
|
||||||
{:noreply, fetcher} |
|
||||||
end |
|
||||||
|
|
||||||
def run(fetcher) do |
|
||||||
fix_transaction_without_to_address_and_created_contract_address(fetcher) |
|
||||||
fix_addresses_with_creation_transaction_but_without_code(fetcher) |
|
||||||
end |
|
||||||
|
|
||||||
def fix_transaction_without_to_address_and_created_contract_address(fetcher) do |
|
||||||
Logger.debug( |
|
||||||
[ |
|
||||||
"Started fix_transaction_without_to_address_and_created_contract_address" |
|
||||||
], |
|
||||||
fetcher: :addresses_without_code |
|
||||||
) |
|
||||||
|
|
||||||
query = |
|
||||||
from(block in Block, |
|
||||||
left_join: transaction in Transaction, |
|
||||||
on: block.hash == transaction.block_hash, |
|
||||||
where: |
|
||||||
is_nil(transaction.to_address_hash) and is_nil(transaction.created_contract_address_hash) and |
|
||||||
block.consensus == true and is_nil(transaction.error) and not is_nil(transaction.hash), |
|
||||||
distinct: block.hash |
|
||||||
) |
|
||||||
|
|
||||||
process_query(query, fetcher) |
|
||||||
|
|
||||||
Logger.debug( |
|
||||||
[ |
|
||||||
"Started fix_transaction_without_to_address_and_created_contract_address" |
|
||||||
], |
|
||||||
fetcher: :addresses_without_code |
|
||||||
) |
|
||||||
end |
|
||||||
|
|
||||||
def fix_addresses_with_creation_transaction_but_without_code(fetcher) do |
|
||||||
Logger.debug( |
|
||||||
[ |
|
||||||
"Started fix_addresses_with_creation_transaction_but_without_code" |
|
||||||
], |
|
||||||
fetcher: :addresses_without_code |
|
||||||
) |
|
||||||
|
|
||||||
second_query = |
|
||||||
from(block in Block, |
|
||||||
left_join: transaction in Transaction, |
|
||||||
on: transaction.block_hash == block.hash, |
|
||||||
left_join: address in Address, |
|
||||||
on: address.hash == transaction.created_contract_address_hash, |
|
||||||
where: |
|
||||||
not is_nil(transaction.block_hash) and not is_nil(transaction.created_contract_address_hash) and |
|
||||||
is_nil(address.contract_code) and |
|
||||||
block.consensus == true and is_nil(transaction.error) and not is_nil(transaction.hash), |
|
||||||
distinct: block.hash |
|
||||||
) |
|
||||||
|
|
||||||
process_query(second_query, fetcher) |
|
||||||
|
|
||||||
Logger.debug( |
|
||||||
[ |
|
||||||
"Finished fix_addresses_with_creation_transaction_but_without_code" |
|
||||||
], |
|
||||||
fetcher: :addresses_without_code |
|
||||||
) |
|
||||||
end |
|
||||||
|
|
||||||
defp process_query(query, fetcher) do |
|
||||||
query_stream = Repo.stream(query, max_rows: @batch_size, timeout: @query_timeout) |
|
||||||
|
|
||||||
stream = |
|
||||||
TaskSupervisor |
|
||||||
|> Task.Supervisor.async_stream_nolink( |
|
||||||
query_stream, |
|
||||||
fn block -> refetch_block(block, fetcher) end, |
|
||||||
@task_options |
|
||||||
) |
|
||||||
|
|
||||||
Repo.transaction(fn -> Stream.run(stream) end, timeout: @query_timeout) |
|
||||||
end |
|
||||||
|
|
||||||
def refetch_block(block, fetcher) do |
|
||||||
Logger.debug( |
|
||||||
[ |
|
||||||
"Processing block #{to_string(block.hash)} #{block.number}" |
|
||||||
], |
|
||||||
fetcher: :addresses_without_code |
|
||||||
) |
|
||||||
|
|
||||||
Fetcher.fetch_and_import_block(block.number, fetcher, false) |
|
||||||
|
|
||||||
Logger.debug( |
|
||||||
[ |
|
||||||
"Finished processing block #{to_string(block.hash)} #{block.number}" |
|
||||||
], |
|
||||||
fetcher: :addresses_without_code |
|
||||||
) |
|
||||||
rescue |
|
||||||
e -> |
|
||||||
Logger.debug( |
|
||||||
[ |
|
||||||
"Failed to fetch block #{to_string(block.hash)} #{block.number} because of #{inspect(e)}" |
|
||||||
], |
|
||||||
fetcher: :addresses_without_code |
|
||||||
) |
|
||||||
end |
|
||||||
end |
|
@ -1,132 +0,0 @@ |
|||||||
defmodule Indexer.Temporary.FailedCreatedAddresses do |
|
||||||
@moduledoc """ |
|
||||||
Temporary module to fix internal transactions and their created transactions if a parent transaction has failed. |
|
||||||
""" |
|
||||||
use GenServer |
|
||||||
use Indexer.Fetcher |
|
||||||
|
|
||||||
require Logger |
|
||||||
|
|
||||||
import Ecto.Query |
|
||||||
|
|
||||||
alias Explorer.Chain.{Address, Data, InternalTransaction, Transaction} |
|
||||||
alias Explorer.Repo |
|
||||||
alias Indexer.Fetcher.ContractCode |
|
||||||
alias Indexer.Temporary.FailedCreatedAddresses.TaskSupervisor |
|
||||||
|
|
||||||
@task_options [max_concurrency: 3, timeout: :infinity] |
|
||||||
@query_timeout :infinity |
|
||||||
|
|
||||||
def start_link([json_rpc_named_arguments, gen_server_options]) do |
|
||||||
GenServer.start_link(__MODULE__, json_rpc_named_arguments, gen_server_options) |
|
||||||
end |
|
||||||
|
|
||||||
@impl GenServer |
|
||||||
def init(json_rpc_named_arguments) do |
|
||||||
schedule_work() |
|
||||||
|
|
||||||
{:ok, json_rpc_named_arguments} |
|
||||||
end |
|
||||||
|
|
||||||
def schedule_work do |
|
||||||
Process.send_after(self(), :run, 1_000) |
|
||||||
end |
|
||||||
|
|
||||||
@impl GenServer |
|
||||||
def handle_info(:run, json_rpc_named_arguments) do |
|
||||||
run(json_rpc_named_arguments) |
|
||||||
|
|
||||||
{:noreply, json_rpc_named_arguments} |
|
||||||
end |
|
||||||
|
|
||||||
def run(json_rpc_named_arguments) do |
|
||||||
Logger.debug( |
|
||||||
[ |
|
||||||
"Started query to fetch internal transactions that need to be fixed" |
|
||||||
], |
|
||||||
fetcher: :failed_created_addresses |
|
||||||
) |
|
||||||
|
|
||||||
data = %Data{bytes: ""} |
|
||||||
|
|
||||||
query = |
|
||||||
from(t in Transaction, |
|
||||||
left_join: it in InternalTransaction, |
|
||||||
on: it.transaction_hash == t.hash, |
|
||||||
left_join: address in Address, |
|
||||||
on: address.hash == it.created_contract_address_hash, |
|
||||||
where: t.status == ^0 and not is_nil(it.created_contract_address_hash) and address.contract_code != ^data, |
|
||||||
distinct: t.hash |
|
||||||
) |
|
||||||
|
|
||||||
found_transactions = Repo.all(query, timeout: @query_timeout) |
|
||||||
|
|
||||||
Logger.debug( |
|
||||||
[ |
|
||||||
"Finished query to fetch internal transactions that need to be fixed. Number of records is #{ |
|
||||||
Enum.count(found_transactions) |
|
||||||
}" |
|
||||||
], |
|
||||||
fetcher: :failed_created_addresses |
|
||||||
) |
|
||||||
|
|
||||||
TaskSupervisor |
|
||||||
|> Task.Supervisor.async_stream_nolink( |
|
||||||
found_transactions, |
|
||||||
fn transaction -> fix_internal_transaction(transaction, json_rpc_named_arguments) end, |
|
||||||
@task_options |
|
||||||
) |
|
||||||
|> Enum.to_list() |
|
||||||
end |
|
||||||
|
|
||||||
def fix_internal_transaction(transaction, json_rpc_named_arguments) do |
|
||||||
# credo:disable-for-next-line |
|
||||||
try do |
|
||||||
Logger.debug( |
|
||||||
[ |
|
||||||
"Started fixing transaction #{to_string(transaction.hash)}" |
|
||||||
], |
|
||||||
fetcher: :failed_created_addresses |
|
||||||
) |
|
||||||
|
|
||||||
transaction_with_internal_transactions = Repo.preload(transaction, [:internal_transactions]) |
|
||||||
|
|
||||||
transaction_with_internal_transactions.internal_transactions |
|
||||||
|> Enum.filter(fn internal_transaction -> |
|
||||||
internal_transaction.created_contract_address_hash |
|
||||||
end) |
|
||||||
|> Enum.each(fn internal_transaction -> |
|
||||||
:ok = |
|
||||||
internal_transaction |
|
||||||
|> code_entry() |
|
||||||
|> ContractCode.run(json_rpc_named_arguments) |
|
||||||
end) |
|
||||||
|
|
||||||
Logger.debug( |
|
||||||
[ |
|
||||||
"Finished fixing transaction #{to_string(transaction.hash)}" |
|
||||||
], |
|
||||||
fetcher: :failed_created_addresses |
|
||||||
) |
|
||||||
rescue |
|
||||||
e -> |
|
||||||
Logger.debug( |
|
||||||
[ |
|
||||||
"Failed fixing transaction #{to_string(transaction.hash)} because of #{inspect(e)}" |
|
||||||
], |
|
||||||
fetcher: :failed_created_addresses |
|
||||||
) |
|
||||||
end |
|
||||||
end |
|
||||||
|
|
||||||
def code_entry(%InternalTransaction{ |
|
||||||
block_number: block_number, |
|
||||||
created_contract_address_hash: %{bytes: created_contract_bytes} |
|
||||||
}) do |
|
||||||
[{block_number, created_contract_bytes, <<>>}] |
|
||||||
end |
|
||||||
|
|
||||||
def transaction_entry(%Transaction{hash: %{bytes: bytes}, index: index, block_number: block_number}) do |
|
||||||
[{block_number, bytes, index}] |
|
||||||
end |
|
||||||
end |
|
@ -1,389 +0,0 @@ |
|||||||
defmodule Indexer.Temporary.AddressesWithoutCodeTest do |
|
||||||
use Explorer.DataCase, async: false |
|
||||||
use EthereumJSONRPC.Case, async: false |
|
||||||
|
|
||||||
import Mox |
|
||||||
|
|
||||||
import Ecto.Query |
|
||||||
|
|
||||||
alias Explorer.Repo |
|
||||||
alias Explorer.Chain.{Address, Transaction} |
|
||||||
alias Indexer.Block.Fetcher |
|
||||||
alias Indexer.Block.Realtime.Fetcher, as: RealtimeFetcher |
|
||||||
alias Indexer.Fetcher.{CoinBalance, ContractCode, InternalTransaction, ReplacedTransaction, Token, TokenBalance} |
|
||||||
alias Indexer.Temporary.AddressesWithoutCode.Supervisor |
|
||||||
|
|
||||||
@moduletag capture_log: true |
|
||||||
|
|
||||||
setup :set_mox_global |
|
||||||
|
|
||||||
setup :verify_on_exit! |
|
||||||
|
|
||||||
describe "run/1" do |
|
||||||
setup %{json_rpc_named_arguments: json_rpc_named_arguments} do |
|
||||||
CoinBalance.Supervisor.Case.start_supervised!(json_rpc_named_arguments: json_rpc_named_arguments) |
|
||||||
ContractCode.Supervisor.Case.start_supervised!(json_rpc_named_arguments: json_rpc_named_arguments) |
|
||||||
InternalTransaction.Supervisor.Case.start_supervised!(json_rpc_named_arguments: json_rpc_named_arguments) |
|
||||||
Token.Supervisor.Case.start_supervised!(json_rpc_named_arguments: json_rpc_named_arguments) |
|
||||||
TokenBalance.Supervisor.Case.start_supervised!(json_rpc_named_arguments: json_rpc_named_arguments) |
|
||||||
ReplacedTransaction.Supervisor.Case.start_supervised!() |
|
||||||
|
|
||||||
[name: Indexer.Block.Realtime.TaskSupervisor] |
|
||||||
|> Task.Supervisor.child_spec() |
|
||||||
|> ExUnit.Callbacks.start_supervised!() |
|
||||||
|
|
||||||
fetcher = %Fetcher{ |
|
||||||
broadcast: false, |
|
||||||
callback_module: RealtimeFetcher, |
|
||||||
json_rpc_named_arguments: json_rpc_named_arguments |
|
||||||
} |
|
||||||
|
|
||||||
{:ok, %{fetcher: fetcher}} |
|
||||||
end |
|
||||||
|
|
||||||
@tag :no_parity |
|
||||||
@tag :no_geth |
|
||||||
test "refetches blocks setting created address and code", %{ |
|
||||||
fetcher: %{json_rpc_named_arguments: json_rpc_named_arguments} = fetcher |
|
||||||
} do |
|
||||||
block = insert(:block, consensus: true) |
|
||||||
|
|
||||||
transaction = |
|
||||||
:transaction |
|
||||||
|> insert( |
|
||||||
status: 0, |
|
||||||
to_address: nil, |
|
||||||
created_contract_address_hash: nil, |
|
||||||
block: block, |
|
||||||
block_number: block.number, |
|
||||||
block_hash: block.hash, |
|
||||||
cumulative_gas_used: 200, |
|
||||||
gas_used: 100, |
|
||||||
index: 0 |
|
||||||
) |
|
||||||
|
|
||||||
address = insert(:address, contract_code: nil) |
|
||||||
|
|
||||||
if json_rpc_named_arguments[:transport] == EthereumJSONRPC.Mox do |
|
||||||
EthereumJSONRPC.Mox |
|
||||||
|> expect(:json_rpc, fn [%{id: id, method: "eth_getBlockByNumber", params: [_block_quantity, true]}], |
|
||||||
_options -> |
|
||||||
{:ok, |
|
||||||
[ |
|
||||||
%{ |
|
||||||
id: id, |
|
||||||
jsonrpc: "2.0", |
|
||||||
result: %{ |
|
||||||
"author" => "0xe8ddc5c7a2d2f0d7a9798459c0104fdf5e987aca", |
|
||||||
"difficulty" => "0xfffffffffffffffffffffffffffffffe", |
|
||||||
"extraData" => "0xd5830108048650617269747986312e32322e31826c69", |
|
||||||
"gasLimit" => "0x69fe20", |
|
||||||
"gasUsed" => "0xc512", |
|
||||||
"hash" => "0xf6b4b8c88df3ebd252ec476328334dc026cf66606a84fb769b3d3cbccc8471bd", |
|
||||||
"logsBloom" => |
|
||||||
"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000200000000000000000000020000000000000000200000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", |
|
||||||
"miner" => "0xe8ddc5c7a2d2f0d7a9798459c0104fdf5e987aca", |
|
||||||
"number" => "0x25", |
|
||||||
"parentHash" => "0xc37bbad7057945d1bf128c1ff009fb1ad632110bf6a000aac025a80f7766b66e", |
|
||||||
"receiptsRoot" => "0xd300311aab7dcc98c05ac3f1893629b2c9082c189a0a0c76f4f63e292ac419d5", |
|
||||||
"sealFields" => [ |
|
||||||
"0x84120a71de", |
|
||||||
"0xb841fcdb570511ec61edda93849bb7c6b3232af60feb2ea74e4035f0143ab66dfdd00f67eb3eda1adddbb6b572db1e0abd39ce00f9b3ccacb9f47973279ff306fe5401" |
|
||||||
], |
|
||||||
"sha3Uncles" => "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", |
|
||||||
"signature" => |
|
||||||
"fcdb570511ec61edda93849bb7c6b3232af60feb2ea74e4035f0143ab66dfdd00f67eb3eda1adddbb6b572db1e0abd39ce00f9b3ccacb9f47973279ff306fe5401", |
|
||||||
"size" => "0x2cf", |
|
||||||
"stateRoot" => "0x2cd84079b0d0c267ed387e3895fd1c1dc21ff82717beb1132adac64276886e19", |
|
||||||
"step" => "302674398", |
|
||||||
"timestamp" => "0x5a343956", |
|
||||||
"totalDifficulty" => "0x24ffffffffffffffffffffffffedf78dfd", |
|
||||||
"transactions" => [ |
|
||||||
%{ |
|
||||||
"blockHash" => "0xf6b4b8c88df3ebd252ec476328334dc026cf66606a84fb769b3d3cbccc8471bd", |
|
||||||
"blockNumber" => "0x25", |
|
||||||
"chainId" => "0x4d", |
|
||||||
"condition" => "0xe8ddc5c7a2d2f0d7a9798459c0104fdf5e987aca", |
|
||||||
"creates" => to_string(address.hash), |
|
||||||
"from" => "0xe8ddc5c7a2d2f0d7a9798459c0104fdf5e987aca", |
|
||||||
"to" => nil, |
|
||||||
"gas" => "0x47b760", |
|
||||||
"gasPrice" => "0x174876e800", |
|
||||||
"hash" => to_string(transaction.hash), |
|
||||||
"input" => "0x10855269000000000000000000000000862d67cb0773ee3f8ce7ea89b328ffea861ab3ef", |
|
||||||
"nonce" => "0x4", |
|
||||||
"publicKey" => |
|
||||||
"0xe5d196ad4ceada719d9e592f7166d0c75700f6eab2e3c3de34ba751ea786527cb3f6eb96ad9fdfdb9989ff572df50f1c42ef800af9c5207a38b929aff969b5c9", |
|
||||||
"r" => "0xa7f8f45cce375bb7af8750416e1b03e0473f93c256da2285d1134fc97a700e01", |
|
||||||
"raw" => |
|
||||||
"0xf88a0485174876e8008347b760948bf38d4764929064f2d4d3a56520a76ab3df415b80a410855269000000000000000000000000862d67cb0773ee3f8ce7ea89b328ffea861ab3ef81bea0a7f8f45cce375bb7af8750416e1b03e0473f93c256da2285d1134fc97a700e01a01f87a076f13824f4be8963e3dffd7300dae64d5f23c9a062af0c6ead347c135f", |
|
||||||
"s" => "0x1f87a076f13824f4be8963e3dffd7300dae64d5f23c9a062af0c6ead347c135f", |
|
||||||
"standardV" => "0x1", |
|
||||||
"transactionIndex" => "0x0", |
|
||||||
"v" => "0xbe", |
|
||||||
"value" => "0x0" |
|
||||||
} |
|
||||||
], |
|
||||||
"transactionsRoot" => "0x68e314a05495f390f9cd0c36267159522e5450d2adf254a74567b452e767bf34", |
|
||||||
"uncles" => [] |
|
||||||
} |
|
||||||
} |
|
||||||
]} |
|
||||||
end) |
|
||||||
|> expect(:json_rpc, fn [ |
|
||||||
%{ |
|
||||||
id: id, |
|
||||||
method: "eth_getTransactionReceipt", |
|
||||||
params: _ |
|
||||||
} |
|
||||||
], |
|
||||||
_options -> |
|
||||||
{:ok, |
|
||||||
[ |
|
||||||
%{ |
|
||||||
id: id, |
|
||||||
jsonrpc: "2.0", |
|
||||||
result: %{ |
|
||||||
"blockHash" => "0xf6b4b8c88df3ebd252ec476328334dc026cf66606a84fb769b3d3cbccc8471bd", |
|
||||||
"blockNumber" => "0x25", |
|
||||||
"contractAddress" => to_string(address.hash), |
|
||||||
"cumulativeGasUsed" => "0xc512", |
|
||||||
"gasUsed" => "0xc512", |
|
||||||
"logs" => [ |
|
||||||
%{ |
|
||||||
"address" => "0xe8ddc5c7a2d2f0d7a9798459c0104fdf5e987aca", |
|
||||||
"blockHash" => "0xf6b4b8c88df3ebd252ec476328334dc026cf66606a84fb769b3d3cbccc8471bd", |
|
||||||
"blockNumber" => "0x25", |
|
||||||
"data" => "0x000000000000000000000000862d67cb0773ee3f8ce7ea89b328ffea861ab3ef", |
|
||||||
"logIndex" => "0x0", |
|
||||||
"topics" => ["0x600bcf04a13e752d1e3670a5a9f1c21177ca2a93c6f5391d4f1298d098097c22"], |
|
||||||
"transactionHash" => to_string(transaction.hash), |
|
||||||
"transactionIndex" => "0x0", |
|
||||||
"transactionLogIndex" => "0x0", |
|
||||||
"type" => "mined" |
|
||||||
} |
|
||||||
], |
|
||||||
"logsBloom" => |
|
||||||
"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000200000000000000000000020000000000000000200000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", |
|
||||||
"root" => nil, |
|
||||||
"status" => "0x1", |
|
||||||
"transactionHash" => to_string(transaction.hash), |
|
||||||
"transactionIndex" => "0x0" |
|
||||||
} |
|
||||||
} |
|
||||||
]} |
|
||||||
end) |
|
||||||
|> expect(:json_rpc, fn [%{id: id, method: "trace_block", params: _}], _options -> |
|
||||||
{:ok, [%{id: id, result: []}]} |
|
||||||
end) |
|
||||||
|> expect(:json_rpc, fn [%{id: id, method: "trace_replayBlockTransactions", params: _}], _options -> |
|
||||||
{:ok, [%{id: id, result: []}]} |
|
||||||
end) |
|
||||||
|> expect(:json_rpc, fn [ |
|
||||||
%{ |
|
||||||
id: 0, |
|
||||||
jsonrpc: "2.0", |
|
||||||
method: "eth_getBalance", |
|
||||||
params: ["0x0000000000000000000000000000000000000003", "0x25"] |
|
||||||
}, |
|
||||||
%{ |
|
||||||
id: 1, |
|
||||||
jsonrpc: "2.0", |
|
||||||
method: "eth_getBalance", |
|
||||||
params: ["0xe8ddc5c7a2d2f0d7a9798459c0104fdf5e987aca", "0x25"] |
|
||||||
} |
|
||||||
], |
|
||||||
_options -> |
|
||||||
{:ok, [%{id: 0, jsonrpc: "2.0", result: "0x0"}, %{id: 1, jsonrpc: "2.0", result: "0x0"}]} |
|
||||||
end) |
|
||||||
end |
|
||||||
|
|
||||||
[fetcher, [name: AddressesWithoutCodeTest]] |
|
||||||
|> Supervisor.child_spec() |
|
||||||
|> ExUnit.Callbacks.start_supervised!() |
|
||||||
|
|
||||||
Process.sleep(5_000) |
|
||||||
|
|
||||||
updated_address = |
|
||||||
from(a in Address, where: a.hash == ^address.hash, preload: :contracts_creation_transaction) |> Repo.one() |
|
||||||
|
|
||||||
assert updated_address.contracts_creation_transaction.hash == transaction.hash |
|
||||||
|
|
||||||
updated_transaction = |
|
||||||
from(t in Transaction, where: t.hash == ^transaction.hash, preload: :created_contract_address) |> Repo.one() |
|
||||||
|
|
||||||
assert updated_transaction.created_contract_address.hash == address.hash |
|
||||||
|
|
||||||
assert updated_address.contract_code == updated_transaction.input |
|
||||||
end |
|
||||||
|
|
||||||
@tag :no_parity |
|
||||||
@tag :no_geth |
|
||||||
test "doesn't set contract code if contract wasn't create", %{ |
|
||||||
fetcher: %{json_rpc_named_arguments: json_rpc_named_arguments} = fetcher |
|
||||||
} do |
|
||||||
block = insert(:block, consensus: true) |
|
||||||
|
|
||||||
transaction = |
|
||||||
:transaction |
|
||||||
|> insert( |
|
||||||
status: 0, |
|
||||||
to_address: nil, |
|
||||||
created_contract_address_hash: nil, |
|
||||||
block: block, |
|
||||||
block_number: block.number, |
|
||||||
block_hash: block.hash, |
|
||||||
cumulative_gas_used: 200, |
|
||||||
gas_used: 100, |
|
||||||
index: 0 |
|
||||||
) |
|
||||||
|
|
||||||
address = insert(:address, contract_code: nil) |
|
||||||
|
|
||||||
if json_rpc_named_arguments[:transport] == EthereumJSONRPC.Mox do |
|
||||||
EthereumJSONRPC.Mox |
|
||||||
|> expect(:json_rpc, fn [%{id: id, method: "eth_getBlockByNumber", params: [_block_quantity, true]}], |
|
||||||
_options -> |
|
||||||
{:ok, |
|
||||||
[ |
|
||||||
%{ |
|
||||||
id: id, |
|
||||||
jsonrpc: "2.0", |
|
||||||
result: %{ |
|
||||||
"author" => "0xe8ddc5c7a2d2f0d7a9798459c0104fdf5e987aca", |
|
||||||
"difficulty" => "0xfffffffffffffffffffffffffffffffe", |
|
||||||
"extraData" => "0xd5830108048650617269747986312e32322e31826c69", |
|
||||||
"gasLimit" => "0x69fe20", |
|
||||||
"gasUsed" => "0xc512", |
|
||||||
"hash" => "0xf6b4b8c88df3ebd252ec476328334dc026cf66606a84fb769b3d3cbccc8471bd", |
|
||||||
"logsBloom" => |
|
||||||
"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000200000000000000000000020000000000000000200000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", |
|
||||||
"miner" => "0xe8ddc5c7a2d2f0d7a9798459c0104fdf5e987aca", |
|
||||||
"number" => "0x25", |
|
||||||
"parentHash" => "0xc37bbad7057945d1bf128c1ff009fb1ad632110bf6a000aac025a80f7766b66e", |
|
||||||
"receiptsRoot" => "0xd300311aab7dcc98c05ac3f1893629b2c9082c189a0a0c76f4f63e292ac419d5", |
|
||||||
"sealFields" => [ |
|
||||||
"0x84120a71de", |
|
||||||
"0xb841fcdb570511ec61edda93849bb7c6b3232af60feb2ea74e4035f0143ab66dfdd00f67eb3eda1adddbb6b572db1e0abd39ce00f9b3ccacb9f47973279ff306fe5401" |
|
||||||
], |
|
||||||
"sha3Uncles" => "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", |
|
||||||
"signature" => |
|
||||||
"fcdb570511ec61edda93849bb7c6b3232af60feb2ea74e4035f0143ab66dfdd00f67eb3eda1adddbb6b572db1e0abd39ce00f9b3ccacb9f47973279ff306fe5401", |
|
||||||
"size" => "0x2cf", |
|
||||||
"stateRoot" => "0x2cd84079b0d0c267ed387e3895fd1c1dc21ff82717beb1132adac64276886e19", |
|
||||||
"step" => "302674398", |
|
||||||
"timestamp" => "0x5a343956", |
|
||||||
"totalDifficulty" => "0x24ffffffffffffffffffffffffedf78dfd", |
|
||||||
"transactions" => [ |
|
||||||
%{ |
|
||||||
"blockHash" => "0xf6b4b8c88df3ebd252ec476328334dc026cf66606a84fb769b3d3cbccc8471bd", |
|
||||||
"blockNumber" => "0x25", |
|
||||||
"chainId" => "0x4d", |
|
||||||
"condition" => "0xe8ddc5c7a2d2f0d7a9798459c0104fdf5e987aca", |
|
||||||
"from" => "0xe8ddc5c7a2d2f0d7a9798459c0104fdf5e987aca", |
|
||||||
"to" => nil, |
|
||||||
"gas" => "0x47b760", |
|
||||||
"gasPrice" => "0x174876e800", |
|
||||||
"hash" => to_string(transaction.hash), |
|
||||||
"input" => "0x10855269000000000000000000000000862d67cb0773ee3f8ce7ea89b328ffea861ab3ef", |
|
||||||
"nonce" => "0x4", |
|
||||||
"publicKey" => |
|
||||||
"0xe5d196ad4ceada719d9e592f7166d0c75700f6eab2e3c3de34ba751ea786527cb3f6eb96ad9fdfdb9989ff572df50f1c42ef800af9c5207a38b929aff969b5c9", |
|
||||||
"r" => "0xa7f8f45cce375bb7af8750416e1b03e0473f93c256da2285d1134fc97a700e01", |
|
||||||
"raw" => |
|
||||||
"0xf88a0485174876e8008347b760948bf38d4764929064f2d4d3a56520a76ab3df415b80a410855269000000000000000000000000862d67cb0773ee3f8ce7ea89b328ffea861ab3ef81bea0a7f8f45cce375bb7af8750416e1b03e0473f93c256da2285d1134fc97a700e01a01f87a076f13824f4be8963e3dffd7300dae64d5f23c9a062af0c6ead347c135f", |
|
||||||
"s" => "0x1f87a076f13824f4be8963e3dffd7300dae64d5f23c9a062af0c6ead347c135f", |
|
||||||
"standardV" => "0x1", |
|
||||||
"transactionIndex" => "0x0", |
|
||||||
"v" => "0xbe", |
|
||||||
"value" => "0x0" |
|
||||||
} |
|
||||||
], |
|
||||||
"transactionsRoot" => "0x68e314a05495f390f9cd0c36267159522e5450d2adf254a74567b452e767bf34", |
|
||||||
"uncles" => [] |
|
||||||
} |
|
||||||
} |
|
||||||
]} |
|
||||||
end) |
|
||||||
|> expect(:json_rpc, fn [ |
|
||||||
%{ |
|
||||||
id: id, |
|
||||||
method: "eth_getTransactionReceipt", |
|
||||||
params: _ |
|
||||||
} |
|
||||||
], |
|
||||||
_options -> |
|
||||||
{:ok, |
|
||||||
[ |
|
||||||
%{ |
|
||||||
id: id, |
|
||||||
jsonrpc: "2.0", |
|
||||||
result: %{ |
|
||||||
"blockHash" => "0xf6b4b8c88df3ebd252ec476328334dc026cf66606a84fb769b3d3cbccc8471bd", |
|
||||||
"blockNumber" => "0x25", |
|
||||||
"contractAddress" => nil, |
|
||||||
"cumulativeGasUsed" => "0xc512", |
|
||||||
"gasUsed" => "0xc512", |
|
||||||
"logs" => [ |
|
||||||
%{ |
|
||||||
"address" => "0xe8ddc5c7a2d2f0d7a9798459c0104fdf5e987aca", |
|
||||||
"blockHash" => "0xf6b4b8c88df3ebd252ec476328334dc026cf66606a84fb769b3d3cbccc8471bd", |
|
||||||
"blockNumber" => "0x25", |
|
||||||
"data" => "0x000000000000000000000000862d67cb0773ee3f8ce7ea89b328ffea861ab3ef", |
|
||||||
"logIndex" => "0x0", |
|
||||||
"topics" => ["0x600bcf04a13e752d1e3670a5a9f1c21177ca2a93c6f5391d4f1298d098097c22"], |
|
||||||
"transactionHash" => to_string(transaction.hash), |
|
||||||
"transactionIndex" => "0x0", |
|
||||||
"transactionLogIndex" => "0x0", |
|
||||||
"type" => "mined" |
|
||||||
} |
|
||||||
], |
|
||||||
"logsBloom" => |
|
||||||
"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000200000000000000000000020000000000000000200000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", |
|
||||||
"root" => nil, |
|
||||||
"status" => "0x1", |
|
||||||
"transactionHash" => to_string(transaction.hash), |
|
||||||
"transactionIndex" => "0x0" |
|
||||||
} |
|
||||||
} |
|
||||||
]} |
|
||||||
end) |
|
||||||
|> expect(:json_rpc, fn [%{id: id, method: "trace_block", params: _}], _options -> |
|
||||||
{:ok, [%{id: id, result: []}]} |
|
||||||
end) |
|
||||||
|> expect(:json_rpc, fn [%{id: id, method: "trace_replayBlockTransactions", params: _}], _options -> |
|
||||||
{:ok, [%{id: id, result: []}]} |
|
||||||
end) |
|
||||||
|> expect(:json_rpc, fn [ |
|
||||||
%{ |
|
||||||
id: 1, |
|
||||||
jsonrpc: "2.0", |
|
||||||
method: "eth_getBalance", |
|
||||||
params: ["0xe8ddc5c7a2d2f0d7a9798459c0104fdf5e987aca", "0x25"] |
|
||||||
} |
|
||||||
], |
|
||||||
_options -> |
|
||||||
{:ok, [%{id: 1, jsonrpc: "2.0", result: "0x0"}]} |
|
||||||
end) |
|
||||||
end |
|
||||||
|
|
||||||
[fetcher, [name: AddressesWithoutCodeTest1]] |
|
||||||
|> Supervisor.child_spec() |
|
||||||
|> ExUnit.Callbacks.start_supervised!() |
|
||||||
|
|
||||||
Process.sleep(2_000) |
|
||||||
|
|
||||||
updated_address = |
|
||||||
from(a in Address, where: a.hash == ^address.hash, preload: :contracts_creation_transaction) |> Repo.one() |
|
||||||
|
|
||||||
assert is_nil(updated_address.contracts_creation_transaction) |
|
||||||
|
|
||||||
updated_transaction = |
|
||||||
from(t in Transaction, where: t.hash == ^transaction.hash, preload: :created_contract_address) |> Repo.one() |
|
||||||
|
|
||||||
assert is_nil(updated_transaction.created_contract_address) |
|
||||||
|
|
||||||
assert is_nil(updated_address.contract_code) |
|
||||||
end |
|
||||||
end |
|
||||||
end |
|
@ -1,78 +0,0 @@ |
|||||||
defmodule Indexer.Temporary.FailedCreatedAddressesTest do |
|
||||||
use Explorer.DataCase, async: false |
|
||||||
use EthereumJSONRPC.Case, async: false |
|
||||||
|
|
||||||
import Mox |
|
||||||
|
|
||||||
import Ecto.Query |
|
||||||
|
|
||||||
alias Explorer.Repo |
|
||||||
alias Explorer.Chain.Address |
|
||||||
alias Indexer.Fetcher.CoinBalance |
|
||||||
alias Indexer.Temporary.FailedCreatedAddresses.Supervisor |
|
||||||
|
|
||||||
@moduletag capture_log: true |
|
||||||
|
|
||||||
setup :set_mox_global |
|
||||||
|
|
||||||
setup :verify_on_exit! |
|
||||||
|
|
||||||
describe "run/1" do |
|
||||||
@tag :no_parity |
|
||||||
@tag :no_geth |
|
||||||
test "updates failed replaced transactions", %{json_rpc_named_arguments: json_rpc_named_arguments} do |
|
||||||
CoinBalance.Supervisor.Case.start_supervised!(json_rpc_named_arguments: json_rpc_named_arguments) |
|
||||||
|
|
||||||
block = insert(:block) |
|
||||||
|
|
||||||
transaction = |
|
||||||
:transaction |
|
||||||
|> insert( |
|
||||||
status: 0, |
|
||||||
error: "Reverted", |
|
||||||
internal_transactions_indexed_at: DateTime.utc_now(), |
|
||||||
block: block, |
|
||||||
block_number: block.number, |
|
||||||
cumulative_gas_used: 200, |
|
||||||
gas_used: 100, |
|
||||||
index: 0 |
|
||||||
) |
|
||||||
|
|
||||||
address = insert(:address, contract_code: "0x0102030405") |
|
||||||
|
|
||||||
insert(:internal_transaction, |
|
||||||
block_number: transaction.block_number, |
|
||||||
transaction: transaction, |
|
||||||
index: 0, |
|
||||||
created_contract_address_hash: address.hash |
|
||||||
) |
|
||||||
|
|
||||||
if json_rpc_named_arguments[:transport] == EthereumJSONRPC.Mox do |
|
||||||
EthereumJSONRPC.Mox |
|
||||||
|> expect(:json_rpc, fn _json, _options -> |
|
||||||
{:ok, [%{id: 0, jsonrpc: "2.0", result: "0x"}]} |
|
||||||
end) |
|
||||||
|> expect(:json_rpc, fn [%{id: id, method: "eth_getBalance", params: [_address, _block_quantity]}], _options -> |
|
||||||
{:ok, [%{id: id, result: "0x0"}]} |
|
||||||
end) |
|
||||||
end |
|
||||||
|
|
||||||
params = [json_rpc_named_arguments, [name: TestFailedCreatedAddresses]] |
|
||||||
|
|
||||||
params |
|
||||||
|> Supervisor.child_spec() |
|
||||||
|> ExUnit.Callbacks.start_supervised!() |
|
||||||
|
|
||||||
Process.sleep(3_000) |
|
||||||
|
|
||||||
fetched_address = |
|
||||||
Repo.one( |
|
||||||
from(a in Address, |
|
||||||
where: a.hash == ^address.hash |
|
||||||
) |
|
||||||
) |
|
||||||
|
|
||||||
assert fetched_address.contract_code == %Explorer.Chain.Data{bytes: ""} |
|
||||||
end |
|
||||||
end |
|
||||||
end |
|
Loading…
Reference in new issue