Switch Chain.import options to maps

1. Allows for easier composing with put_in than Keyword.t
2. Allows more precise specs as individal options can be marked as
optional or required while the Keyword.t pattern makes it seem like
everything is optional.
pull/489/head
Luke Imhoff 6 years ago
parent 68229420b4
commit 12f70945da
  1. 258
      apps/explorer/lib/explorer/chain/import.ex
  2. 26
      apps/explorer/test/explorer/chain_test.exs
  3. 28
      apps/explorer/test/explorer/import_test.exs
  4. 12
      apps/explorer_web/test/explorer_web/features/viewing_addresses_test.exs
  5. 8
      apps/indexer/lib/indexer/balance_fetcher.ex
  6. 20
      apps/indexer/lib/indexer/block_fetcher.ex
  7. 8
      apps/indexer/lib/indexer/internal_transaction_fetcher.ex
  8. 8
      apps/indexer/lib/indexer/pending_transaction_fetcher.ex

@ -9,32 +9,45 @@ defmodule Explorer.Chain.Import do
alias Explorer.Chain.{Address, Balance, Block, Hash, InternalTransaction, Log, Transaction, Wei} alias Explorer.Chain.{Address, Balance, Block, Hash, InternalTransaction, Log, Transaction, Wei}
alias Explorer.Repo alias Explorer.Repo
@typep addresses_option :: {:addresses, [params_option | timeout_option | with_option]} @type changeset_function_name :: atom
@typep balances_option :: {:balances, [params_option | timeout_option]} @type on_conflict :: :nothing | :replace_all
@typep blocks_option :: {:blocks, [params_option | timeout_option]} @type params :: [map()]
@typep broadcast_option :: {:broadcast, Boolean}
@typep internal_transactions_option :: {:internal_transactions, [params_option | timeout_option]} @type all_options :: %{
@typep logs_option :: {:logs, [params_option | timeout_option]} optional(:addresses) => %{
@typep on_conflict_option :: {:on_conflict, :nothing | :replace_all} required(:params) => params,
@typep params_option :: {:params, [map()]} optional(:timeout) => timeout,
@typep receipts_option :: {:receipts, [params_option | timeout_option]} optional(:with) => changeset_function_name
@typep timeout_option :: {:timeout, timeout} },
@typep timestamps :: %{inserted_at: DateTime.t(), updated_at: DateTime.t()} optional(:balances) => %{
@typep timestamps_option :: {:timestamps, timestamps} required(:params) => params,
@typep transactions_option :: {:transactions, [on_conflict_option | params_option | timeout_option | with_option]} optional(:timeout) => timeout
@typep with_option :: {:with, changeset_function_name :: atom} },
optional(:blocks) => %{
@type all_options :: [ required(:params) => params,
addresses_option optional(:timeout) => timeout
| balances_option },
| blocks_option optional(:broadcast) => boolean,
| broadcast_option optional(:internal_transactions) => %{
| internal_transactions_option required(:params) => params,
| logs_option optional(:timeout) => timeout
| receipts_option },
| timeout_option optional(:logs) => %{
| transactions_option required(:params) => params,
] optional(:timeout) => timeout
},
optional(:receipts) => %{
required(:params) => params,
optional(:timeout) => timeout
},
optional(:timeout) => timeout,
optional(:transactions) => %{
required(:params) => params,
optional(:with) => changeset_function_name,
optional(:on_conflict) => :nothing | :replace_all,
optional(:timeout) => timeout
}
}
@type all_result :: @type all_result ::
{:ok, {:ok,
%{ %{
@ -54,23 +67,7 @@ defmodule Explorer.Chain.Import do
| {:error, step :: Ecto.Multi.name(), failed_value :: any(), | {:error, step :: Ecto.Multi.name(), failed_value :: any(),
changes_so_far :: %{optional(Ecto.Multi.name()) => any()}} changes_so_far :: %{optional(Ecto.Multi.name()) => any()}}
@type internal_transactions_options :: [ @typep timestamps :: %{inserted_at: DateTime.t(), updated_at: DateTime.t()}
addresses_option
| internal_transactions_option
| timeout_option
| {:transactions, [{:hashes, [String.t()]} | timeout_option]}
]
@type internal_transactions_result ::
{:ok,
%{
optional(:addresses) => [Hash.Address.t()],
optional(:internal_transactions) => [
%{required(:index) => non_neg_integer(), required(:transaction_hash) => Hash.Full.t()}
]
}}
| {:error, [Changeset.t()]}
| {:error, step :: Ecto.Multi.name(), failed_value :: any(),
changes_so_far :: %{optional(Ecto.Multi.name()) => any()}}
# timeouts all in milliseconds # timeouts all in milliseconds
@ -148,19 +145,13 @@ defmodule Explorer.Chain.Import do
* `:with` - the changeset function on `Explorer.Chain.Transaction` to use validate `:params`. * `:with` - the changeset function on `Explorer.Chain.Transaction` to use validate `:params`.
""" """
@spec all(all_options()) :: all_result() @spec all(all_options()) :: all_result()
def all(options) when is_list(options) do def all(options) when is_map(options) do
broadcast =
case Keyword.fetch(options, :broadcast) do
{:ok, broadcast} -> broadcast
:error -> false
end
changes_list_arguments_list = import_options_to_changes_list_arguments_list(options) changes_list_arguments_list = import_options_to_changes_list_arguments_list(options)
with {:ok, ecto_schema_module_to_changes_list_map} <- with {:ok, ecto_schema_module_to_changes_list_map} <-
changes_list_arguments_list_to_ecto_schema_module_to_changes_list_map(changes_list_arguments_list), changes_list_arguments_list_to_ecto_schema_module_to_changes_list_map(changes_list_arguments_list),
{:ok, data} <- insert_ecto_schema_module_to_changes_list_map(ecto_schema_module_to_changes_list_map, options) do {:ok, data} <- insert_ecto_schema_module_to_changes_list_map(ecto_schema_module_to_changes_list_map, options) do
if broadcast, do: broadcast_events(data) if Map.get(options, :broadcast, false), do: broadcast_events(data)
{:ok, data} {:ok, data}
end end
end end
@ -236,9 +227,9 @@ defmodule Explorer.Chain.Import do
} }
defp ecto_schema_module_to_changes_list_map_to_multi(ecto_schema_module_to_changes_list_map, options) defp ecto_schema_module_to_changes_list_map_to_multi(ecto_schema_module_to_changes_list_map, options)
when is_list(options) do when is_map(options) do
timestamps = timestamps() timestamps = timestamps()
full_options = Keyword.put(options, :timestamps, timestamps) full_options = Map.put(options, :timestamps, timestamps)
Multi.new() Multi.new()
|> run_addresses(ecto_schema_module_to_changes_list_map, full_options) |> run_addresses(ecto_schema_module_to_changes_list_map, full_options)
@ -250,16 +241,18 @@ defmodule Explorer.Chain.Import do
end end
defp run_addresses(multi, ecto_schema_module_to_changes_list_map, options) defp run_addresses(multi, ecto_schema_module_to_changes_list_map, options)
when is_map(ecto_schema_module_to_changes_list_map) and is_list(options) do when is_map(ecto_schema_module_to_changes_list_map) and is_map(options) do
case ecto_schema_module_to_changes_list_map do case ecto_schema_module_to_changes_list_map do
%{Address => addresses_changes} -> %{Address => addresses_changes} ->
timestamps = Keyword.fetch!(options, :timestamps) timestamps = Map.fetch!(options, :timestamps)
Multi.run(multi, :addresses, fn _ -> Multi.run(multi, :addresses, fn _ ->
insert_addresses( insert_addresses(
addresses_changes, addresses_changes,
timeout: options[:addresses][:timeout] || @insert_addresses_timeout, %{
timestamps: timestamps timeout: options[:addresses][:timeout] || @insert_addresses_timeout,
timestamps: timestamps
}
) )
end) end)
@ -269,16 +262,18 @@ defmodule Explorer.Chain.Import do
end end
defp run_balances(multi, ecto_schema_module_to_changes_list_map, options) defp run_balances(multi, ecto_schema_module_to_changes_list_map, options)
when is_map(ecto_schema_module_to_changes_list_map) and is_list(options) do when is_map(ecto_schema_module_to_changes_list_map) and is_map(options) do
case ecto_schema_module_to_changes_list_map do case ecto_schema_module_to_changes_list_map do
%{Balance => balances_changes} -> %{Balance => balances_changes} ->
timestamps = Keyword.fetch!(options, :timestamps) timestamps = Map.fetch!(options, :timestamps)
Multi.run(multi, :balances, fn _ -> Multi.run(multi, :balances, fn _ ->
insert_balances( insert_balances(
balances_changes, balances_changes,
timeout: options[:balances][:timeout] || @insert_balances_timeout, %{
timestamps: timestamps timeout: options[:balances][:timeout] || @insert_balances_timeout,
timestamps: timestamps
}
) )
end) end)
@ -288,16 +283,18 @@ defmodule Explorer.Chain.Import do
end end
defp run_blocks(multi, ecto_schema_module_to_changes_list_map, options) defp run_blocks(multi, ecto_schema_module_to_changes_list_map, options)
when is_map(ecto_schema_module_to_changes_list_map) and is_list(options) do when is_map(ecto_schema_module_to_changes_list_map) and is_map(options) do
case ecto_schema_module_to_changes_list_map do case ecto_schema_module_to_changes_list_map do
%{Block => blocks_changes} -> %{Block => blocks_changes} ->
timestamps = Keyword.fetch!(options, :timestamps) timestamps = Map.fetch!(options, :timestamps)
Multi.run(multi, :blocks, fn _ -> Multi.run(multi, :blocks, fn _ ->
insert_blocks( insert_blocks(
blocks_changes, blocks_changes,
timeout: options[:blocks][:timeout] || @insert_blocks_timeout, %{
timestamps: timestamps timeout: options[:blocks][:timeout] || @insert_blocks_timeout,
timestamps: timestamps
}
) )
end) end)
@ -307,20 +304,20 @@ defmodule Explorer.Chain.Import do
end end
defp run_transactions(multi, ecto_schema_module_to_changes_list_map, options) defp run_transactions(multi, ecto_schema_module_to_changes_list_map, options)
when is_map(ecto_schema_module_to_changes_list_map) and is_list(options) do when is_map(ecto_schema_module_to_changes_list_map) and is_map(options) do
case ecto_schema_module_to_changes_list_map do case ecto_schema_module_to_changes_list_map do
%{Transaction => transactions_changes} -> %{Transaction => transactions_changes} ->
# check required options as early as possible # check required options as early as possible
transactions_options = Keyword.fetch!(options, :transactions) %{timestamps: timestamps, transactions: %{on_conflict: on_conflict} = transactions_options} = options
on_conflict = Keyword.fetch!(transactions_options, :on_conflict)
timestamps = Keyword.fetch!(options, :timestamps)
Multi.run(multi, :transactions, fn _ -> Multi.run(multi, :transactions, fn _ ->
insert_transactions( insert_transactions(
transactions_changes, transactions_changes,
on_conflict: on_conflict, %{
timeout: transactions_options[:timeout] || @insert_transactions_timeout, on_conflict: on_conflict,
timestamps: timestamps timeout: transactions_options[:timeout] || @insert_transactions_timeout,
timestamps: timestamps
}
) )
end) end)
@ -330,25 +327,29 @@ defmodule Explorer.Chain.Import do
end end
defp run_internal_transactions(multi, ecto_schema_module_to_changes_list_map, options) defp run_internal_transactions(multi, ecto_schema_module_to_changes_list_map, options)
when is_map(ecto_schema_module_to_changes_list_map) and is_list(options) do when is_map(ecto_schema_module_to_changes_list_map) and is_map(options) do
case ecto_schema_module_to_changes_list_map do case ecto_schema_module_to_changes_list_map do
%{InternalTransaction => internal_transactions_changes} -> %{InternalTransaction => internal_transactions_changes} ->
timestamps = Keyword.fetch!(options, :timestamps) timestamps = Map.fetch!(options, :timestamps)
multi multi
|> Multi.run(:internal_transactions, fn _ -> |> Multi.run(:internal_transactions, fn _ ->
insert_internal_transactions( insert_internal_transactions(
internal_transactions_changes, internal_transactions_changes,
timeout: options[:internal_transactions][:timeout] || @insert_internal_transactions_timeout, %{
timestamps: timestamps timeout: options[:internal_transactions][:timeout] || @insert_internal_transactions_timeout,
timestamps: timestamps
}
) )
end) end)
|> Multi.run(:internal_transactions_indexed_at_transactions, fn %{internal_transactions: internal_transactions} |> Multi.run(:internal_transactions_indexed_at_transactions, fn %{internal_transactions: internal_transactions}
when is_list(internal_transactions) -> when is_list(internal_transactions) ->
update_transactions_internal_transactions_indexed_at( update_transactions_internal_transactions_indexed_at(
internal_transactions, internal_transactions,
timeout: options[:transactions][:timeout] || @insert_transactions_timeout, %{
timestamps: timestamps timeout: options[:transactions][:timeout] || @insert_transactions_timeout,
timestamps: timestamps
}
) )
end) end)
@ -358,16 +359,18 @@ defmodule Explorer.Chain.Import do
end end
defp run_logs(multi, ecto_schema_module_to_changes_list_map, options) defp run_logs(multi, ecto_schema_module_to_changes_list_map, options)
when is_map(ecto_schema_module_to_changes_list_map) and is_list(options) do when is_map(ecto_schema_module_to_changes_list_map) and is_map(options) do
case ecto_schema_module_to_changes_list_map do case ecto_schema_module_to_changes_list_map do
%{Log => logs_changes} -> %{Log => logs_changes} ->
timestamps = Keyword.fetch!(options, :timestamps) timestamps = Map.fetch!(options, :timestamps)
Multi.run(multi, :logs, fn _ -> Multi.run(multi, :logs, fn _ ->
insert_logs( insert_logs(
logs_changes, logs_changes,
timeout: options[:logs][:timeout] || @insert_logs_timeout, %{
timestamps: timestamps timeout: options[:logs][:timeout] || @insert_logs_timeout,
timestamps: timestamps
}
) )
end) end)
@ -376,13 +379,11 @@ defmodule Explorer.Chain.Import do
end end
end end
@spec insert_addresses([%{hash: Hash.Address.t()}], [timeout_option | timestamps_option | with_option]) :: @spec insert_addresses([%{hash: Hash.Address.t()}], %{
{:ok, [Hash.Address.t()]} required(:timeout) => timeout,
defp insert_addresses(changes_list, named_arguments) required(:timestamps) => timestamps
when is_list(changes_list) and is_list(named_arguments) do }) :: {:ok, [Hash.Address.t()]}
timestamps = Keyword.fetch!(named_arguments, :timestamps) defp insert_addresses(changes_list, %{timeout: timeout, timestamps: timestamps}) when is_list(changes_list) do
timeout = Keyword.fetch!(named_arguments, :timeout)
# order so that row ShareLocks are grabbed in a consistent order # order so that row ShareLocks are grabbed in a consistent order
ordered_changes_list = sort_address_changes_list(changes_list) ordered_changes_list = sort_address_changes_list(changes_list)
@ -447,14 +448,14 @@ defmodule Explorer.Chain.Import do
required(:value) => Wei.t() required(:value) => Wei.t()
} }
], ],
[timeout_option] %{
required(:timeout) => timeout,
required(:timestamps) => timestamps
}
) :: ) ::
{:ok, [%{required(:address_hash) => Hash.Address.t(), required(:block_number) => Block.block_number()}]} {:ok, [%{required(:address_hash) => Hash.Address.t(), required(:block_number) => Block.block_number()}]}
| {:error, [Changeset.t()]} | {:error, [Changeset.t()]}
defp insert_balances(changes_list, named_arguments) when is_list(changes_list) and is_list(named_arguments) do defp insert_balances(changes_list, %{timeout: timeout, timestamps: timestamps}) when is_list(changes_list) do
timestamps = Keyword.fetch!(named_arguments, :timestamps)
timeout = Keyword.fetch!(named_arguments, :timeout)
# order so that row ShareLocks are grabbed in a consistent order # order so that row ShareLocks are grabbed in a consistent order
ordered_changes_list = Enum.sort_by(changes_list, &{&1.address_hash, &1.block_number}) ordered_changes_list = Enum.sort_by(changes_list, &{&1.address_hash, &1.block_number})
@ -490,12 +491,10 @@ defmodule Explorer.Chain.Import do
{:ok, Enum.map(ordered_changes_list, &Map.take(&1, ~w(address_hash block_number)a))} {:ok, Enum.map(ordered_changes_list, &Map.take(&1, ~w(address_hash block_number)a))}
end end
@spec insert_blocks([map()], [timeout_option | timestamps_option]) :: {:ok, [Block.t()]} | {:error, [Changeset.t()]} @spec insert_blocks([map()], %{required(:timeout) => timeout, required(:timestamps) => timestamps}) ::
defp insert_blocks(changes_list, named_arguments) {:ok, [Block.t()]} | {:error, [Changeset.t()]}
when is_list(changes_list) and is_list(named_arguments) do defp insert_blocks(changes_list, %{timeout: timeout, timestamps: timestamps})
timestamps = Keyword.fetch!(named_arguments, :timestamps) when is_list(changes_list) do
timeout = Keyword.fetch!(named_arguments, :timeout)
# order so that row ShareLocks are grabbed in a consistent order # order so that row ShareLocks are grabbed in a consistent order
ordered_changes_list = Enum.sort_by(changes_list, &{&1.number, &1.hash}) ordered_changes_list = Enum.sort_by(changes_list, &{&1.number, &1.hash})
@ -513,13 +512,11 @@ defmodule Explorer.Chain.Import do
{:ok, blocks} {:ok, blocks}
end end
@spec insert_internal_transactions([map], [timeout_option | timestamps_option]) :: @spec insert_internal_transactions([map], %{required(:timeout) => timeout, required(:timestamps) => timestamps}) ::
{:ok, [%{index: non_neg_integer, transaction_hash: Hash.t()}]} {:ok, [%{index: non_neg_integer, transaction_hash: Hash.t()}]}
| {:error, [Changeset.t()]} | {:error, [Changeset.t()]}
defp insert_internal_transactions(changes_list, named_arguments) defp insert_internal_transactions(changes_list, %{timeout: timeout, timestamps: timestamps})
when is_list(changes_list) and is_list(named_arguments) do when is_list(changes_list) do
timestamps = Keyword.fetch!(named_arguments, :timestamps)
# order so that row ShareLocks are grabbed in a consistent order # order so that row ShareLocks are grabbed in a consistent order
ordered_changes_list = Enum.sort_by(changes_list, &{&1.transaction_hash, &1.index}) ordered_changes_list = Enum.sort_by(changes_list, &{&1.transaction_hash, &1.index})
@ -530,6 +527,7 @@ defmodule Explorer.Chain.Import do
for: InternalTransaction, for: InternalTransaction,
on_conflict: :replace_all, on_conflict: :replace_all,
returning: [:index, :transaction_hash], returning: [:index, :transaction_hash],
timeout: timeout,
timestamps: timestamps timestamps: timestamps
) )
@ -540,14 +538,11 @@ defmodule Explorer.Chain.Import do
)} )}
end end
@spec insert_logs([map()], [timeout_option | timestamps_option]) :: @spec insert_logs([map()], %{required(:timeout) => timeout, required(:timestamps) => timestamps}) ::
{:ok, [Log.t()]} {:ok, [Log.t()]}
| {:error, [Changeset.t()]} | {:error, [Changeset.t()]}
defp insert_logs(changes_list, named_arguments) defp insert_logs(changes_list, %{timeout: timeout, timestamps: timestamps})
when is_list(changes_list) and is_list(named_arguments) do when is_list(changes_list) do
timestamps = Keyword.fetch!(named_arguments, :timestamps)
timeout = Keyword.fetch!(named_arguments, :timeout)
# order so that row ShareLocks are grabbed in a consistent order # order so that row ShareLocks are grabbed in a consistent order
ordered_changes_list = Enum.sort_by(changes_list, &{&1.transaction_hash, &1.index}) ordered_changes_list = Enum.sort_by(changes_list, &{&1.transaction_hash, &1.index})
@ -563,14 +558,13 @@ defmodule Explorer.Chain.Import do
) )
end end
@spec insert_transactions([map()], [on_conflict_option | timeout_option | timestamps_option]) :: @spec insert_transactions([map()], %{
{:ok, [Hash.t()]} | {:error, [Changeset.t()]} required(:on_conflict) => on_conflict,
defp insert_transactions(changes_list, named_arguments) required(:timeout) => timeout,
when is_list(changes_list) and is_list(named_arguments) do required(:timestamps) => timestamps
timestamps = Keyword.fetch!(named_arguments, :timestamps) }) :: {:ok, [Hash.t()]} | {:error, [Changeset.t()]}
timeout = Keyword.fetch!(named_arguments, :timeout) defp insert_transactions(changes_list, %{on_conflict: on_conflict, timeout: timeout, timestamps: timestamps})
on_conflict = Keyword.fetch!(named_arguments, :on_conflict) when is_list(changes_list) do
# order so that row ShareLocks are grabbed in a consistent order # order so that row ShareLocks are grabbed in a consistent order
ordered_changes_list = Enum.sort_by(changes_list, & &1.hash) ordered_changes_list = Enum.sort_by(changes_list, & &1.hash)
@ -603,11 +597,11 @@ defmodule Explorer.Chain.Import do
{:ok, inserted} {:ok, inserted}
end end
defp update_transactions_internal_transactions_indexed_at(internal_transactions, named_arguments) defp update_transactions_internal_transactions_indexed_at(internal_transactions, %{
when is_list(internal_transactions) and is_list(named_arguments) do timeout: timeout,
timeout = Keyword.fetch!(named_arguments, :timeout) timestamps: timestamps
timestamps = Keyword.fetch!(named_arguments, :timestamps) })
when is_list(internal_transactions) do
ordered_transaction_hashes = ordered_transaction_hashes =
internal_transactions internal_transactions
|> MapSet.new(& &1.transaction_hash) |> MapSet.new(& &1.transaction_hash)
@ -637,12 +631,12 @@ defmodule Explorer.Chain.Import do
defp import_options_to_changes_list_arguments_list(options) do defp import_options_to_changes_list_arguments_list(options) do
Enum.flat_map(@import_option_key_to_ecto_schema_module, fn {option_key, ecto_schema_module} -> Enum.flat_map(@import_option_key_to_ecto_schema_module, fn {option_key, ecto_schema_module} ->
case Keyword.fetch(options, option_key) do case Map.fetch(options, option_key) do
{:ok, option_value} when is_list(option_value) -> {:ok, option_value} when is_map(option_value) ->
[ [
[ [
Keyword.fetch!(option_value, :params), Map.fetch!(option_value, :params),
[for: ecto_schema_module, with: Keyword.get(option_value, :with, :changeset)] [for: ecto_schema_module, with: Map.get(option_value, :with, :changeset)]
] ]
] ]
@ -652,15 +646,13 @@ defmodule Explorer.Chain.Import do
end) end)
end end
defp import_transaction(multi, options) when is_list(options) do defp import_transaction(multi, options) when is_map(options) do
Repo.transaction(multi, timeout: Keyword.get(options, :timeout, @transaction_timeout)) Repo.transaction(multi, timeout: Map.get(options, :timeout, @transaction_timeout))
end end
defp insert_ecto_schema_module_to_changes_list_map(ecto_schema_module_to_changes_list_map, options) do defp insert_ecto_schema_module_to_changes_list_map(ecto_schema_module_to_changes_list_map, options) do
timestamps = timestamps()
ecto_schema_module_to_changes_list_map ecto_schema_module_to_changes_list_map
|> ecto_schema_module_to_changes_list_map_to_multi(Keyword.put(options, :timestamps, timestamps)) |> ecto_schema_module_to_changes_list_map_to_multi(options)
|> import_transaction(options) |> import_transaction(options)
end end

@ -1520,8 +1520,8 @@ defmodule Explorer.ChainTest do
end end
describe "import" do describe "import" do
@import_data [ @import_data %{
blocks: [ blocks: %{
params: [ params: [
%{ %{
difficulty: 340_282_366_920_938_463_463_374_607_431_768_211_454, difficulty: 340_282_366_920_938_463_463_374_607_431_768_211_454,
@ -1537,9 +1537,9 @@ defmodule Explorer.ChainTest do
total_difficulty: 12_590_447_576_074_723_148_144_860_474_975_121_280_509 total_difficulty: 12_590_447_576_074_723_148_144_860_474_975_121_280_509
} }
] ]
], },
broadcast: true, broadcast: true,
internal_transactions: [ internal_transactions: %{
params: [ params: [
%{ %{
call_type: "call", call_type: "call",
@ -1555,8 +1555,8 @@ defmodule Explorer.ChainTest do
value: 0 value: 0
} }
] ]
], },
logs: [ logs: %{
params: [ params: [
%{ %{
address_hash: "0x8bf38d4764929064f2d4d3a56520a76ab3df415b", address_hash: "0x8bf38d4764929064f2d4d3a56520a76ab3df415b",
@ -1570,8 +1570,8 @@ defmodule Explorer.ChainTest do
type: "mined" type: "mined"
} }
] ]
], },
transactions: [ transactions: %{
on_conflict: :replace_all, on_conflict: :replace_all,
params: [ params: [
%{ %{
@ -1597,14 +1597,14 @@ defmodule Explorer.ChainTest do
value: 0 value: 0
} }
] ]
], },
addresses: [ addresses: %{
params: [ params: [
%{hash: "0x8bf38d4764929064f2d4d3a56520a76ab3df415b"}, %{hash: "0x8bf38d4764929064f2d4d3a56520a76ab3df415b"},
%{hash: "0xe8ddc5c7a2d2f0d7a9798459c0104fdf5e987aca"} %{hash: "0xe8ddc5c7a2d2f0d7a9798459c0104fdf5e987aca"}
] ]
] }
] }
test "publishes addresses with updated fetched_balance data to subscribers on insert" do test "publishes addresses with updated fetched_balance data to subscribers on insert" do
Chain.subscribe_to_events(:addresses) Chain.subscribe_to_events(:addresses)
@ -1631,7 +1631,7 @@ defmodule Explorer.ChainTest do
end end
test "does not broadcast if broadcast option is false" do test "does not broadcast if broadcast option is false" do
non_broadcast_data = Keyword.merge(@import_data, broadcast: false) non_broadcast_data = Map.put(@import_data, :broadcast, false)
Chain.subscribe_to_events(:logs) Chain.subscribe_to_events(:logs)
Chain.import(non_broadcast_data) Chain.import(non_broadcast_data)

@ -19,16 +19,16 @@ defmodule Explorer.Chain.ImportTest do
transaction_string_hash = "0x0705ea0a5b997d9aafd5c531e016d9aabe3297a28c0bd4ef005fe6ea329d301b" transaction_string_hash = "0x0705ea0a5b997d9aafd5c531e016d9aabe3297a28c0bd4ef005fe6ea329d301b"
insert(:transaction, from_address: from_address, hash: transaction_string_hash) insert(:transaction, from_address: from_address, hash: transaction_string_hash)
options = [ options = %{
addresses: [ addresses: %{
params: [ params: [
%{ %{
contract_code: smart_contract_bytecode, contract_code: smart_contract_bytecode,
hash: address_hash hash: address_hash
} }
] ]
], },
internal_transactions: [ internal_transactions: %{
params: [ params: [
%{ %{
created_contract_address_hash: address_hash, created_contract_address_hash: address_hash,
@ -45,8 +45,8 @@ defmodule Explorer.Chain.ImportTest do
value: 0 value: 0
} }
] ]
] }
] }
assert {:ok, _} = Import.all(options) assert {:ok, _} = Import.all(options)
@ -60,14 +60,14 @@ defmodule Explorer.Chain.ImportTest do
to_address_hash = "0x8bf38d4764929064f2d4d3a56520a76ab3df415b" to_address_hash = "0x8bf38d4764929064f2d4d3a56520a76ab3df415b"
transaction_hash = "0x3a3eb134e6792ce9403ea4188e5e79693de9e4c94e499db132be086400da79e6" transaction_hash = "0x3a3eb134e6792ce9403ea4188e5e79693de9e4c94e499db132be086400da79e6"
options = [ options = %{
addresses: [ addresses: %{
params: [ params: [
%{hash: from_address_hash}, %{hash: from_address_hash},
%{hash: to_address_hash} %{hash: to_address_hash}
] ]
], },
transactions: [ transactions: %{
params: [ params: [
%{ %{
from_address_hash: from_address_hash, from_address_hash: from_address_hash,
@ -83,8 +83,8 @@ defmodule Explorer.Chain.ImportTest do
} }
], ],
on_conflict: :replace_all on_conflict: :replace_all
], },
internal_transactions: [ internal_transactions: %{
params: [ params: [
%{ %{
block_number: 35, block_number: 35,
@ -101,8 +101,8 @@ defmodule Explorer.Chain.ImportTest do
value: 0 value: 0
} }
] ]
] }
] }
refute Enum.any?(options[:transactions][:params], &Map.has_key?(&1, :internal_transactions_indexed_at)) refute Enum.any?(options[:transactions][:params], &Map.has_key?(&1, :internal_transactions_indexed_at))

@ -281,8 +281,8 @@ defmodule ExplorerWeb.ViewingAddressesTest do
], ],
balances: [%{address_hash: ^hash}] balances: [%{address_hash: ^hash}]
}} = }} =
Chain.import( Chain.import(%{
addresses: [ addresses: %{
params: [ params: [
%{ %{
fetched_balance: 100, fetched_balance: 100,
@ -291,8 +291,8 @@ defmodule ExplorerWeb.ViewingAddressesTest do
} }
], ],
with: :balance_changeset with: :balance_changeset
], },
balances: [ balances: %{
params: [ params: [
%{ %{
value: 100, value: 100,
@ -300,8 +300,8 @@ defmodule ExplorerWeb.ViewingAddressesTest do
address_hash: hash address_hash: hash
} }
] ]
] }
) })
Notifier.handle_event({:chain_event, :addresses, [updated_address]}) Notifier.handle_event({:chain_event, :addresses, [updated_address]})

@ -75,10 +75,10 @@ defmodule Indexer.BalanceFetcher do
addresses_params = balances_params_to_address_params(balances_params) addresses_params = balances_params_to_address_params(balances_params)
{:ok, _} = {:ok, _} =
Chain.import( Chain.import(%{
addresses: [params: addresses_params, with: :balance_changeset], addresses: %{params: addresses_params, with: :balance_changeset},
balances: [params: balances_params] balances: %{params: balances_params}
) })
:ok :ok

@ -90,13 +90,13 @@ defmodule Indexer.BlockFetcher do
:ok :ok
end end
defp insert(%__MODULE__{broadcast: broadcast, sequence: sequence}, options) when is_list(options) do defp insert(%__MODULE__{broadcast: broadcast, sequence: sequence}, options) when is_map(options) do
{address_hash_to_fetched_balance_block_number, import_options} = {address_hash_to_fetched_balance_block_number, import_options} =
pop_address_hash_to_fetched_balance_block_number(options) pop_address_hash_to_fetched_balance_block_number(options)
transaction_hash_to_block_number = get_transaction_hash_to_block_number(import_options) transaction_hash_to_block_number = get_transaction_hash_to_block_number(import_options)
options_with_broadcast = Keyword.merge(import_options, broadcast: broadcast) options_with_broadcast = Map.put(import_options, :broadcast, broadcast)
with {:ok, results} <- Chain.import(options_with_broadcast) do with {:ok, results} <- Chain.import(options_with_broadcast) do
async_import_remaining_block_data( async_import_remaining_block_data(
@ -108,7 +108,7 @@ defmodule Indexer.BlockFetcher do
{:ok, results} {:ok, results}
else else
{:error, step, failed_value, _changes_so_far} = error -> {:error, step, failed_value, _changes_so_far} = error ->
range = Keyword.fetch!(options, :range) %{range: range} = options
debug(fn -> debug(fn ->
"failed to insert blocks during #{step} #{inspect(range)}: #{inspect(failed_value)}. Retrying" "failed to insert blocks during #{step} #{inspect(range)}: #{inspect(failed_value)}. Retrying"
@ -188,12 +188,14 @@ defmodule Indexer.BlockFetcher do
insert( insert(
state, state,
range: range, %{
addresses: [params: addresses], range: range,
blocks: [params: blocks], addresses: %{params: addresses},
logs: [params: logs], blocks: %{params: blocks},
receipts: [params: receipts], logs: %{params: logs},
transactions: [on_conflict: :replace_all, params: transactions_with_receipts] receipts: %{params: receipts},
transactions: %{params: transactions_with_receipts, on_conflict: :replace_all}
}
) )
else else
{step, {:error, reason}} -> {step, {:error, reason}} ->

@ -100,10 +100,10 @@ defmodule Indexer.InternalTransactionFetcher do
end) end)
with {:ok, %{addresses: address_hashes}} <- with {:ok, %{addresses: address_hashes}} <-
Chain.import( Chain.import(%{
addresses: [params: addresses_params], addresses: %{params: addresses_params},
internal_transactions: [params: internal_transactions_params] internal_transactions: %{params: internal_transactions_params}
) do }) do
address_hashes address_hashes
|> Enum.map(fn address_hash -> |> Enum.map(fn address_hash ->
block_number = Map.fetch!(address_hash_to_block_number, to_string(address_hash)) block_number = Map.fetch!(address_hash_to_block_number, to_string(address_hash))

@ -97,10 +97,10 @@ defmodule Indexer.PendingTransactionFetcher do
# affected the address balance yet since address balance is a balance at a give block and these transactions are # affected the address balance yet since address balance is a balance at a give block and these transactions are
# blockless. # blockless.
{:ok, _} = {:ok, _} =
Chain.import( Chain.import(%{
addresses: [params: addresses_params], addresses: %{params: addresses_params},
transactions: [on_conflict: :nothing, params: transactions_params] transactions: %{params: transactions_params, on_conflict: :nothing}
) })
:ignore -> :ignore ->
:ok :ok

Loading…
Cancel
Save