Merge pull request #505 from poanetwork/491
Use nil Balance value to indicate unfetchedpull/528/head
commit
3e4a48785e
@ -0,0 +1,90 @@ |
||||
defmodule Indexer.Balances do |
||||
@moduledoc """ |
||||
Extracts `Explorer.Chain.Balance` params from other schema's params |
||||
""" |
||||
|
||||
def params_set(%{} = import_options) do |
||||
Enum.reduce(import_options, MapSet.new(), &reducer/2) |
||||
end |
||||
|
||||
defp reducer({:blocks_params, blocks_params}, acc) when is_list(blocks_params) do |
||||
# a block MUST have a miner_hash and number |
||||
Enum.into(blocks_params, acc, fn %{miner_hash: address_hash, number: block_number} |
||||
when is_binary(address_hash) and is_integer(block_number) -> |
||||
%{address_hash: address_hash, block_number: block_number} |
||||
end) |
||||
end |
||||
|
||||
defp reducer({:internal_transactions_params, internal_transactions_params}, initial) |
||||
when is_list(internal_transactions_params) do |
||||
Enum.reduce(internal_transactions_params, initial, &internal_transactions_params_reducer/2) |
||||
end |
||||
|
||||
defp reducer({:logs_params, logs_params}, acc) when is_list(logs_params) do |
||||
# a log MUST have and address_hash |
||||
Enum.into(logs_params, acc, fn %{address_hash: address_hash, block_number: block_number} |
||||
when is_binary(address_hash) and is_integer(block_number) -> |
||||
%{address_hash: address_hash, block_number: block_number} |
||||
end) |
||||
end |
||||
|
||||
defp reducer({:token_transfers_params, token_transfers_params}, initial) when is_list(token_transfers_params) do |
||||
Enum.reduce(token_transfers_params, initial, fn %{ |
||||
block_number: block_number, |
||||
from_address_hash: from_address_hash, |
||||
to_address_hash: to_address_hash, |
||||
token_contract_address_hash: token_contract_address_hash |
||||
}, |
||||
acc |
||||
when is_integer(block_number) and is_binary(from_address_hash) and |
||||
is_binary(to_address_hash) and |
||||
is_binary(token_contract_address_hash) -> |
||||
acc |
||||
|> MapSet.put(%{address_hash: from_address_hash, block_number: block_number}) |
||||
|> MapSet.put(%{address_hash: to_address_hash, block_number: block_number}) |
||||
|> MapSet.put(%{address_hash: token_contract_address_hash, block_number: block_number}) |
||||
end) |
||||
end |
||||
|
||||
defp reducer({:transactions_params, transactions_params}, initial) when is_list(transactions_params) do |
||||
Enum.reduce(transactions_params, initial, &transactions_params_reducer/2) |
||||
end |
||||
|
||||
defp internal_transactions_params_reducer(%{block_number: block_number} = internal_transaction_params, acc) |
||||
when is_integer(block_number) do |
||||
case internal_transaction_params do |
||||
%{type: "call"} -> |
||||
acc |
||||
|
||||
%{type: "create", error: _} -> |
||||
acc |
||||
|
||||
%{type: "create", created_contract_address_hash: address_hash} when is_binary(address_hash) -> |
||||
MapSet.put(acc, %{address_hash: address_hash, block_number: block_number}) |
||||
|
||||
%{type: "suicide", from_address_hash: from_address_hash, to_address_hash: to_address_hash} |
||||
when is_binary(from_address_hash) and is_binary(to_address_hash) -> |
||||
acc |
||||
|> MapSet.put(%{address_hash: from_address_hash, block_number: block_number}) |
||||
|> MapSet.put(%{address_hash: to_address_hash, block_number: block_number}) |
||||
end |
||||
end |
||||
|
||||
defp transactions_params_reducer( |
||||
%{block_number: block_number, from_address_hash: from_address_hash} = transaction_params, |
||||
initial |
||||
) |
||||
when is_integer(block_number) and is_binary(from_address_hash) do |
||||
# a transaction MUST have a `from_address_hash` |
||||
acc = MapSet.put(initial, %{address_hash: from_address_hash, block_number: block_number}) |
||||
|
||||
# `to_address_hash` is optional |
||||
case transaction_params do |
||||
%{to_address_hash: to_address_hash} when is_binary(to_address_hash) -> |
||||
MapSet.put(acc, %{address_hash: to_address_hash, block_number: block_number}) |
||||
|
||||
_ -> |
||||
acc |
||||
end |
||||
end |
||||
end |
@ -0,0 +1,184 @@ |
||||
defmodule Indexer.BalancesTest do |
||||
use ExUnit.Case, async: true |
||||
|
||||
alias Explorer.Factory |
||||
alias Indexer.Balances |
||||
|
||||
describe "params_set/1" do |
||||
test "with block extracts miner_hash" do |
||||
miner_hash = |
||||
Factory.address_hash() |
||||
|> to_string() |
||||
|
||||
block_number = 1 |
||||
params_set = Balances.params_set(%{blocks_params: [%{miner_hash: miner_hash, number: block_number}]}) |
||||
|
||||
assert MapSet.size(params_set) == 1 |
||||
assert %{address_hash: miner_hash, block_number: block_number} |
||||
end |
||||
|
||||
test "with call internal transaction extracts nothing" do |
||||
internal_transaction_params = |
||||
:internal_transaction |
||||
|> Factory.params_for() |
||||
|> Map.update!(:type, &to_string/1) |
||||
|> Map.put(:block_number, 1) |
||||
|
||||
params_set = Balances.params_set(%{internal_transactions_params: [internal_transaction_params]}) |
||||
|
||||
assert MapSet.size(params_set) == 0 |
||||
end |
||||
|
||||
test "with create internal transaction with error extracts nothing" do |
||||
internal_transaction_params = |
||||
:internal_transaction_create |
||||
|> Factory.params_for() |
||||
|> Map.update!(:type, &to_string/1) |
||||
|> Map.put(:block_number, 1) |
||||
|> Map.put(:error, "illegal operation") |
||||
|
||||
params_set = Balances.params_set(%{internal_transactions_params: [internal_transaction_params]}) |
||||
|
||||
assert MapSet.size(params_set) == 0 |
||||
end |
||||
|
||||
test "with create internal transaction without error extracts created_contract_address_hash" do |
||||
block_number = 1 |
||||
|
||||
created_contract_address_hash = |
||||
Factory.address_hash() |
||||
|> to_string() |
||||
|
||||
internal_transaction_params = |
||||
:internal_transaction_create |
||||
|> Factory.params_for() |
||||
|> Map.update!(:type, &to_string/1) |
||||
|> Map.put(:block_number, block_number) |
||||
|> Map.put(:created_contract_address_hash, created_contract_address_hash) |
||||
|
||||
params_set = Balances.params_set(%{internal_transactions_params: [internal_transaction_params]}) |
||||
|
||||
assert MapSet.size(params_set) == 1 |
||||
assert %{address_hash: created_contract_address_hash, block_number: block_number} |
||||
end |
||||
|
||||
test "with suicide internal transaction extracts from_address_hash and to_address_hash" do |
||||
block_number = 1 |
||||
|
||||
from_address_hash = |
||||
Factory.address_hash() |
||||
|> to_string() |
||||
|
||||
to_address_hash = |
||||
Factory.address_hash() |
||||
|> to_string() |
||||
|
||||
internal_transaction_params = |
||||
:internal_transaction_suicide |
||||
|> Factory.params_for() |
||||
|> Map.update!(:type, &to_string/1) |
||||
|> Map.put(:block_number, block_number) |
||||
|> Map.put(:from_address_hash, from_address_hash) |
||||
|> Map.put(:to_address_hash, to_address_hash) |
||||
|
||||
params_set = Balances.params_set(%{internal_transactions_params: [internal_transaction_params]}) |
||||
|
||||
assert MapSet.size(params_set) == 2 |
||||
assert %{address_hash: from_address_hash, block_number: block_number} |
||||
assert %{address_hash: to_address_hash, block_number: block_number} |
||||
end |
||||
|
||||
test "with log extracts address_hash" do |
||||
block_number = 1 |
||||
|
||||
address_hash = |
||||
Factory.address_hash() |
||||
|> to_string() |
||||
|
||||
log_params = |
||||
:log |
||||
|> Factory.params_for() |
||||
|> Map.put(:block_number, block_number) |
||||
|> Map.put(:address_hash, address_hash) |
||||
|
||||
params_set = Balances.params_set(%{logs_params: [log_params]}) |
||||
|
||||
assert MapSet.size(params_set) == 1 |
||||
assert %{address_hash: address_hash, block_number: block_number} |
||||
end |
||||
|
||||
test "with token transfer extract from_address, to_address, and token_contract_address_hash" do |
||||
block_number = 1 |
||||
|
||||
from_address_hash = |
||||
Factory.address_hash() |
||||
|> to_string() |
||||
|
||||
to_address_hash = |
||||
Factory.address_hash() |
||||
|> to_string() |
||||
|
||||
token_contract_address_hash = |
||||
Factory.address_hash() |
||||
|> to_string() |
||||
|
||||
token_transfer_params = %{ |
||||
block_number: block_number, |
||||
from_address_hash: from_address_hash, |
||||
to_address_hash: to_address_hash, |
||||
token_contract_address_hash: token_contract_address_hash |
||||
} |
||||
|
||||
params_set = Balances.params_set(%{token_transfers_params: [token_transfer_params]}) |
||||
|
||||
assert MapSet.size(params_set) == 3 |
||||
assert %{address_hash: from_address_hash, block_number: block_number} |
||||
assert %{address_hash: to_address_hash, block_number: block_number} |
||||
assert %{address_hash: token_contract_address_hash, block_number: block_number} |
||||
end |
||||
|
||||
test "with transaction without to_address_hash extracts from_address_hash" do |
||||
block_number = 1 |
||||
|
||||
from_address_hash = |
||||
Factory.address_hash() |
||||
|> to_string() |
||||
|
||||
transaction_params = |
||||
:transaction |
||||
|> Factory.params_for() |
||||
|> Map.put(:block_number, block_number) |
||||
|> Map.put(:from_address_hash, from_address_hash) |
||||
|
||||
params_set = Balances.params_set(%{transactions_params: [transaction_params]}) |
||||
|
||||
assert MapSet.size(params_set) == 1 |
||||
assert %{address_hash: from_address_hash, block_number: block_number} |
||||
end |
||||
|
||||
test "with transaction with to_address_hash extracts from_address_hash and to_address_hash" do |
||||
block_number = 1 |
||||
|
||||
from_address_hash = |
||||
Factory.address_hash() |
||||
|> to_string() |
||||
|
||||
to_address_hash = |
||||
Factory.address_hash() |
||||
|> to_string() |
||||
|
||||
transaction_params = |
||||
:transaction |
||||
|> Factory.params_for() |
||||
|> Map.put(:block_number, block_number) |
||||
|> Map.put(:from_address_hash, from_address_hash) |
||||
|> Map.put(:to_address_hash, to_address_hash) |
||||
|
||||
params_set = Balances.params_set(%{transactions_params: [transaction_params]}) |
||||
|
||||
assert MapSet.size(params_set) == 2 |
||||
assert %{address_hash: from_address_hash, block_number: block_number} |
||||
assert %{address_hash: to_address_hash, block_number: block_number} |
||||
end |
||||
end |
||||
end |
Loading…
Reference in new issue