Merge pull request #830 from poanetwork/frg-skip-burn-address-fetching-ERC-721-balances

Ignore burn address token balance for Tokens ERC-721
pull/813/merge
Luke Imhoff 6 years ago committed by GitHub
commit a1da7ab00c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      apps/explorer/lib/explorer/chain.ex
  2. 20
      apps/explorer/lib/explorer/chain/address/token_balance.ex
  3. 79
      apps/explorer/test/explorer/chain/address/token_balance_test.ex
  4. 5
      apps/explorer/test/explorer/chain_test.exs
  5. 37
      apps/indexer/lib/indexer/address/token_balances.ex
  6. 9
      apps/indexer/lib/indexer/token_transfers.ex
  7. 38
      apps/indexer/test/indexer/address/token_balances_test.exs
  8. 9
      apps/indexer/test/indexer/token_transfers_test.exs

@ -938,7 +938,7 @@ defmodule Explorer.Chain do
def stream_unfetched_token_balances(initial, reducer) when is_function(reducer, 2) do
Repo.transaction(
fn ->
query = from(tb in TokenBalance, where: is_nil(tb.value_fetched_at))
query = TokenBalance.unfetched_token_balances()
query
|> Repo.stream(timeout: :infinity)

@ -129,4 +129,24 @@ defmodule Explorer.Chain.Address.TokenBalance do
tb.value < ^value or (tb.value == ^value and tb.address_hash < ^address_hash)
)
end
{:ok, burn_address_hash} = Chain.string_to_address_hash("0x0000000000000000000000000000000000000000")
@burn_address_hash burn_address_hash
@doc """
Builds an `Ecto.Query` to fetch the unfetched token balances.
Unfetched token balances are the ones that have the column `value_fetched_at` nil. This query also
ignores the burn_address for tokens ERC-721 since the most tokens ERC-721 don't allow get the
balance for burn_address.
"""
def unfetched_token_balances do
from(
tb in TokenBalance,
join: t in Token,
on: tb.token_contract_address_hash == t.contract_address_hash,
where: is_nil(tb.value_fetched_at),
where: (tb.address_hash != ^@burn_address_hash and t.type != "ERC-721") or t.type == "ERC-20"
)
end
end

@ -0,0 +1,79 @@
defmodule Explorer.Chain.Address.TokenBalanceTest do
use Explorer.DataCase
alias Explorer.Repo
alias Explorer.Chain.Address.TokenBalance
describe "unfetched_token_balances/0" do
test "returns only the token balances that have value_fetched_at nil" do
address = insert(:address, hash: "0xc45e4830dff873cf8b70de2b194d0ddd06ef651e")
token_balance = insert(:token_balance, value_fetched_at: nil, address: address)
insert(:token_balance)
result =
TokenBalance.unfetched_token_balances()
|> Repo.all()
|> List.first()
assert result.block_number == token_balance.block_number
end
test "does not ignore token balance when the address isn't the burn address with Token ERC-20" do
address = insert(:address, hash: "0xc45e4830dff873cf8b70de2b194d0ddd06ef651e")
token = insert(:token, type: "ERC-20")
token_balance =
insert(
:token_balance,
value_fetched_at: nil,
address: address,
token_contract_address_hash: token.contract_address_hash
)
result =
TokenBalance.unfetched_token_balances()
|> Repo.all()
|> List.first()
assert result.block_number == token_balance.block_number
end
test "ignores the burn_address when the token type is ERC-721" do
burn_address = insert(:address, hash: "0x0000000000000000000000000000000000000000")
token = insert(:token, type: "ERC-721")
insert(
:token_balance,
address: burn_address,
token_contract_address_hash: token.contract_address_hash,
value_fetched_at: nil
)
result =
TokenBalance.unfetched_token_balances()
|> Repo.all()
assert result == []
end
test "does not ignore the burn_address when the token type is ERC-20" do
burn_address = insert(:address, hash: "0x0000000000000000000000000000000000000000")
token = insert(:token, type: "ERC-20")
token_balance =
insert(
:token_balance,
address: burn_address,
token_contract_address_hash: token.contract_address_hash,
value_fetched_at: nil
)
result =
TokenBalance.unfetched_token_balances()
|> Repo.all()
|> List.first()
assert result.block_number == token_balance.block_number
end
end
end

@ -2326,8 +2326,9 @@ defmodule Explorer.ChainTest do
end
describe "stream_unfetched_token_balances/2" do
test "returns only the token balances that have value_fetched_at nil" do
token_balance = insert(:token_balance, value_fetched_at: nil)
test "executes the given reducer with the query result" do
address = insert(:address, hash: "0xc45e4830dff873cf8b70de2b194d0ddd06ef651e")
token_balance = insert(:token_balance, value_fetched_at: nil, address: address)
insert(:token_balance)
assert Chain.stream_unfetched_token_balances([], &[&1.block_number | &2]) == {:ok, [token_balance.block_number]}

@ -8,16 +8,17 @@ defmodule Indexer.Address.TokenBalances do
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) ->
token_transfers_params
|> ignore_burn_address_transfers_for_token_erc_721
|> Enum.reduce(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,
@ -36,4 +37,20 @@ defmodule Indexer.Address.TokenBalances do
})
end)
end
defp ignore_burn_address_transfers_for_token_erc_721(token_transfers_params) do
Enum.filter(token_transfers_params, &do_filter_burn_address/1)
end
def do_filter_burn_address(%{from_address_hash: "0x0000000000000000000000000000000000000000", token_type: "ERC-721"}) do
false
end
def do_filter_burn_address(%{to_address_hash: "0x0000000000000000000000000000000000000000", token_type: "ERC-721"}) do
false
end
def do_filter_burn_address(_token_balance_param) do
true
end
end

@ -44,7 +44,8 @@ defmodule Indexer.TokenTransfers do
from_address_hash: truncate_address_hash(log.second_topic),
to_address_hash: truncate_address_hash(log.third_topic),
token_contract_address_hash: log.address_hash,
transaction_hash: log.transaction_hash
transaction_hash: log.transaction_hash,
token_type: "ERC-20"
}
token = %{
@ -67,7 +68,8 @@ defmodule Indexer.TokenTransfers do
to_address_hash: truncate_address_hash(log.third_topic),
token_contract_address_hash: log.address_hash,
token_id: token_id || 0,
transaction_hash: log.transaction_hash
transaction_hash: log.transaction_hash,
token_type: "ERC-721"
}
token = %{
@ -90,7 +92,8 @@ defmodule Indexer.TokenTransfers do
to_address_hash: encode_address_hash(to_address_hash),
token_contract_address_hash: log.address_hash,
token_id: token_id,
transaction_hash: log.transaction_hash
transaction_hash: log.transaction_hash,
token_type: "ERC-721"
}
token = %{

@ -34,5 +34,43 @@ defmodule Indexer.Address.TokenBalancesTest do
assert %{address_hash: to_address_hash, block_number: block_number}
assert %{address_hash: token_contract_address_hash, block_number: block_number}
end
test "does not set params when the from_address_hash is the burn address for the Token ERC-721" do
block_number = 1
from_address_hash = "0x0000000000000000000000000000000000000000"
to_address_hash = "0x5b8410f67eb8040bb1cd1e8a4ff9d5f6ce678a15"
token_contract_address_hash = "0xe18035bf8712672935fdb4e5e431b1a0183d2dfc"
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,
token_type: "ERC-721"
}
params_set = TokenBalances.params_set(%{token_transfers_params: [token_transfer_params]})
assert MapSet.size(params_set) == 0
end
test "does not set params when the to_address_hash is the burn address for the Token ERC-721" do
block_number = 1
from_address_hash = "0x5b8410f67eb8040bb1cd1e8a4ff9d5f6ce678a15"
to_address_hash = "0x0000000000000000000000000000000000000000"
token_contract_address_hash = "0xe18035bf8712672935fdb4e5e431b1a0183d2dfc"
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,
token_type: "ERC-721"
}
params_set = TokenBalances.params_set(%{token_transfers_params: [token_transfer_params]})
assert MapSet.size(params_set) == 0
end
end
end

@ -66,7 +66,8 @@ defmodule Indexer.TokenTransfersTest do
to_address_hash: truncated_hash(log_3.third_topic),
token_contract_address_hash: log_3.address_hash,
token_id: 183,
transaction_hash: log_3.transaction_hash
transaction_hash: log_3.transaction_hash,
token_type: "ERC-721"
},
%{
amount: Decimal.new(17_000_000_000_000_000_000),
@ -75,7 +76,8 @@ defmodule Indexer.TokenTransfersTest do
from_address_hash: truncated_hash(log_1.second_topic),
to_address_hash: truncated_hash(log_1.third_topic),
token_contract_address_hash: log_1.address_hash,
transaction_hash: log_1.transaction_hash
transaction_hash: log_1.transaction_hash,
token_type: "ERC-20"
}
]
}
@ -113,7 +115,8 @@ defmodule Indexer.TokenTransfersTest do
to_address_hash: "0xbe8cdfc13ffda20c844ac3da2b53a23ac5787f1e",
token_contract_address_hash: log.address_hash,
token_id: 14_939,
transaction_hash: log.transaction_hash
transaction_hash: log.transaction_hash,
token_type: "ERC-721"
}
]
}

Loading…
Cancel
Save