Fix tokenlist API endpoint return only tokens with positive balance

pull/4028/head
Viktor Baranov 4 years ago
parent f580785518
commit 451d7c5f61
  1. 8
      apps/block_scout_web/test/block_scout_web/controllers/api/rpc/address_controller_test.exs
  2. 14
      apps/explorer/lib/explorer/etherscan.ex
  3. 52
      apps/explorer/test/explorer/etherscan_test.exs

@ -2560,7 +2560,7 @@ defmodule BlockScoutWeb.API.RPC.AddressControllerTest do
end end
test "with address with existing balance in token_balances table", %{conn: conn} do test "with address with existing balance in token_balances table", %{conn: conn} do
token_balance = :token_balance |> insert() |> Repo.preload(:token) token_balance = :address_current_token_balance |> insert() |> Repo.preload(:token)
params = %{ params = %{
"module" => "account", "module" => "account",
@ -2593,9 +2593,9 @@ defmodule BlockScoutWeb.API.RPC.AddressControllerTest do
test "with address with multiple tokens", %{conn: conn} do test "with address with multiple tokens", %{conn: conn} do
address = insert(:address) address = insert(:address)
other_address = insert(:address) other_address = insert(:address)
insert(:token_balance, address: address) insert(:address_current_token_balance, address: address)
insert(:token_balance, address: address) insert(:address_current_token_balance, address: address)
insert(:token_balance, address: other_address) insert(:address_current_token_balance, address: other_address)
params = %{ params = %{
"module" => "account", "module" => "account",

@ -7,7 +7,7 @@ defmodule Explorer.Etherscan do
alias Explorer.Etherscan.Logs alias Explorer.Etherscan.Logs
alias Explorer.{Chain, Repo} alias Explorer.{Chain, Repo}
alias Explorer.Chain.Address.TokenBalance alias Explorer.Chain.Address.{CurrentTokenBalance, TokenBalance}
alias Explorer.Chain.{Block, Hash, InternalTransaction, TokenTransfer, Transaction} alias Explorer.Chain.{Block, Hash, InternalTransaction, TokenTransfer, Transaction}
@default_options %{ @default_options %{
@ -312,14 +312,14 @@ defmodule Explorer.Etherscan do
def list_tokens(%Hash{byte_count: unquote(Hash.Address.byte_count())} = address_hash) do def list_tokens(%Hash{byte_count: unquote(Hash.Address.byte_count())} = address_hash) do
query = query =
from( from(
tb in TokenBalance, ctb in CurrentTokenBalance,
inner_join: t in assoc(tb, :token), inner_join: t in assoc(ctb, :token),
where: tb.address_hash == ^address_hash, where: ctb.address_hash == ^address_hash,
where: ctb.value > 0,
distinct: :token_contract_address_hash, distinct: :token_contract_address_hash,
order_by: [desc: :block_number],
select: %{ select: %{
balance: tb.value, balance: ctb.value,
contract_address_hash: tb.token_contract_address_hash, contract_address_hash: ctb.token_contract_address_hash,
name: t.name, name: t.name,
decimals: t.decimals, decimals: t.decimals,
symbol: t.symbol, symbol: t.symbol,

@ -1598,59 +1598,11 @@ defmodule Explorer.EtherscanTest do
address = insert(:address) address = insert(:address)
token_balance = token_balance =
:token_balance :address_current_token_balance
|> insert(address: address) |> insert(address: address)
|> Repo.preload(:token) |> Repo.preload(:token)
insert(:token_balance, address: build(:address)) insert(:address_current_token_balance, address: build(:address))
token_list = Etherscan.list_tokens(address.hash)
expected_tokens = [
%{
balance: token_balance.value,
contract_address_hash: token_balance.token_contract_address_hash,
name: token_balance.token.name,
decimals: token_balance.token.decimals,
symbol: token_balance.token.symbol,
type: token_balance.token.type
}
]
assert token_list == expected_tokens
end
test "returns the latest known balance per token" do
# The latest balance is the one with the latest block number
address = insert(:address)
token = insert(:token)
token_balance_details1 = %{
address: address,
token_contract_address_hash: token.contract_address.hash,
block_number: 1
}
token_balance_details2 = %{
address: address,
token_contract_address_hash: token.contract_address.hash,
block_number: 2
}
token_balance_details3 = %{
address: address,
token_contract_address_hash: token.contract_address.hash,
block_number: 3
}
insert(:token_balance, token_balance_details1)
token_balance =
:token_balance
|> insert(token_balance_details3)
|> Repo.preload(:token)
insert(:token_balance, token_balance_details2)
token_list = Etherscan.list_tokens(address.hash) token_list = Etherscan.list_tokens(address.hash)

Loading…
Cancel
Save