Merge pull request #940 from poanetwork/frg-fix-mint-balances

Considers mint transfers using logs to index the address
pull/936/head
Felipe Renan 6 years ago committed by GitHub
commit 4199999e63
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 17
      apps/indexer/lib/indexer/address_extraction.ex
  2. 4
      apps/indexer/lib/indexer/block/fetcher.ex
  3. 63
      apps/indexer/lib/indexer/mint_transfer.ex
  4. 57
      apps/indexer/test/indexer/mint_transfer_test.exs

@ -106,6 +106,16 @@ defmodule Indexer.AddressExtraction do
%{from: :block_number, to: :fetched_coin_balance_block_number}, %{from: :block_number, to: :fetched_coin_balance_block_number},
%{from: :token_contract_address_hash, to: :hash} %{from: :token_contract_address_hash, to: :hash}
] ]
],
mint_transfers: [
[
%{from: :block_number, to: :fetched_coin_balance_block_number},
%{from: :from_address_hash, to: :hash}
],
[
%{from: :block_number, to: :fetched_coin_balance_block_number},
%{from: :to_address_hash, to: :hash}
]
] ]
} }
@ -362,6 +372,13 @@ defmodule Indexer.AddressExtraction do
required(:token_contract_address_hash) => String.t(), required(:token_contract_address_hash) => String.t(),
required(:block_number) => non_neg_integer() required(:block_number) => non_neg_integer()
} }
],
optional(:mint_transfers) => [
%{
required(:from_address_hash) => String.t(),
required(:to_address_hash) => String.t(),
required(:block_number) => non_neg_integer()
}
] ]
}) :: [params] }) :: [params]
def extract_addresses(fetched_data, options \\ []) when is_map(fetched_data) and is_list(options) do def extract_addresses(fetched_data, options \\ []) when is_map(fetched_data) and is_list(options) do

@ -6,7 +6,7 @@ defmodule Indexer.Block.Fetcher do
require Logger require Logger
alias Explorer.Chain.{Address, Block, Import} alias Explorer.Chain.{Address, Block, Import}
alias Indexer.{CoinBalance, AddressExtraction, Token, TokenTransfers} alias Indexer.{AddressExtraction, CoinBalance, MintTransfer, Token, TokenTransfers}
alias Indexer.Address.{CoinBalances, TokenBalances} alias Indexer.Address.{CoinBalances, TokenBalances}
alias Indexer.Block.Fetcher.Receipts alias Indexer.Block.Fetcher.Receipts
@ -100,10 +100,12 @@ defmodule Indexer.Block.Fetcher do
%{logs: logs, receipts: receipts} = receipt_params, %{logs: logs, receipts: receipts} = receipt_params,
transactions_with_receipts = Receipts.put(transactions_without_receipts, receipts), transactions_with_receipts = Receipts.put(transactions_without_receipts, receipts),
%{token_transfers: token_transfers, tokens: tokens} = TokenTransfers.parse(logs), %{token_transfers: token_transfers, tokens: tokens} = TokenTransfers.parse(logs),
%{mint_transfers: mint_transfers} = MintTransfer.parse(logs),
addresses = addresses =
AddressExtraction.extract_addresses(%{ AddressExtraction.extract_addresses(%{
blocks: blocks, blocks: blocks,
logs: logs, logs: logs,
mint_transfers: mint_transfers,
token_transfers: token_transfers, token_transfers: token_transfers,
transactions: transactions_with_receipts transactions: transactions_with_receipts
}), }),

@ -0,0 +1,63 @@
defmodule Indexer.MintTransfer do
@moduledoc """
Helper functions to parse addresses from mint transfers.
When a network receives a mint coin, we can identify it using the `bridge_hash` in the first_topic.
Then we need to fetch the `from` and `to` address since there is no transaction or internal
transaction for it. Otherwise, those address may not be indexed.
"""
@bridge_hash "0x3c798bbcf33115b42c728b8504cff11dd58736e9fa789f1cda2738db7d696b2a"
@doc """
Parses logs to find mint transfers.
## Examples
iex> Indexer.MintTransfer.parse([
...> %{
...> address_hash: "0x867305d19606aadba405ce534e303d0e225f9556",
...> block_number: 137_194,
...> data: "0x0000000000000000000000000000000000000000000000001bc16d674ec80000",
...> first_topic: "0x3c798bbcf33115b42c728b8504cff11dd58736e9fa789f1cda2738db7d696b2a",
...> fourth_topic: nil,
...> index: 1,
...> second_topic: "0x0000000000000000000000009a4a90e2732f3fa4087b0bb4bf85c76d14833df1",
...> third_topic: "0x0000000000000000000000007301cfa0e1756b71869e93d4e4dca5c7d0eb0aa6",
...> transaction_hash: "0x1d5066d30ff3404a9306733136103ac2b0b989951c38df637f464f3667f8d4ee",
...> type: "mined"
...> }
...> ])
%{
mint_transfers: [
%{
block_number: 137194,
from_address_hash: "0x7301cfa0e1756b71869e93d4e4dca5c7d0eb0aa6",
to_address_hash: "0x9a4a90e2732f3fa4087b0bb4bf85c76d14833df1"
}
]
}
"""
def parse(logs) do
addresses =
logs
|> Enum.filter(&(&1.first_topic == @bridge_hash))
|> Enum.map(&parse_params/1)
%{mint_transfers: addresses}
end
defp parse_params(%{second_topic: second_topic, third_topic: third_topic, block_number: block_number})
when not is_nil(second_topic) and not is_nil(third_topic) do
%{
to_address_hash: truncate_address_hash(second_topic),
from_address_hash: truncate_address_hash(third_topic),
block_number: block_number
}
end
defp truncate_address_hash("0x000000000000000000000000" <> truncated_hash) do
"0x#{truncated_hash}"
end
end

@ -0,0 +1,57 @@
defmodule Indexer.MintTransferTest do
use ExUnit.Case, async: true
alias Indexer.MintTransfer
doctest Indexer.MintTransfer, import: true
describe "parse/1" do
test "parses logs for fetch the mint transfer" do
logs = [
%{
address_hash: "0x867305d19606aadba405ce534e303d0e225f9556",
block_number: 137_194,
data: "0x0000000000000000000000000000000000000000000000001bc16d674ec80000",
first_topic: "0x3c798bbcf33115b42c728b8504cff11dd58736e9fa789f1cda2738db7d696b2a",
fourth_topic: nil,
index: 1,
second_topic: "0x0000000000000000000000009a4a90e2732f3fa4087b0bb4bf85c76d14833df1",
third_topic: "0x0000000000000000000000007301cfa0e1756b71869e93d4e4dca5c7d0eb0aa6",
transaction_hash: "0x1d5066d30ff3404a9306733136103ac2b0b989951c38df637f464f3667f8d4ee",
type: "mined"
}
]
expected = %{
mint_transfers: [
%{
from_address_hash: "0x7301cfa0e1756b71869e93d4e4dca5c7d0eb0aa6",
to_address_hash: "0x9a4a90e2732f3fa4087b0bb4bf85c76d14833df1",
block_number: 137_194
}
]
}
assert MintTransfer.parse(logs) == expected
end
end
test "returns an empty list when the first topic isn't the brigde hash" do
logs = [
%{
address_hash: "0x867305d19606aadba405ce534e303d0e225f9556",
block_number: 137_194,
data: "0x0000000000000000000000000000000000000000000000001bc16d674ec80000",
first_topic: nil,
fourth_topic: nil,
index: 1,
second_topic: "0x0000000000000000000000009a4a90e2732f3fa4087b0bb4bf85c76d14833df1",
third_topic: "0x0000000000000000000000007301cfa0e1756b71869e93d4e4dca5c7d0eb0aa6",
transaction_hash: "0x1d5066d30ff3404a9306733136103ac2b0b989951c38df637f464f3667f8d4ee",
type: "mined"
}
]
assert MintTransfer.parse(logs) == %{mint_transfers: []}
end
end
Loading…
Cancel
Save