Fix token balances' query

This query was considering the next-to-last token balance when the last
one had the value 0.

In order to this work properly, I'm moving the query that gets token
balances from the last block to a sub-query and moving the condition to
consider just values greater than 0 to the main query.  This way we are
sure that we always are considering the last block and we are skipping
the ones that have the value equal to 0.
pull/702/head
Felipe Renan 6 years ago
parent ed983998d5
commit d9ff36c00d
  1. 18
      apps/explorer/lib/explorer/chain/address/token_balance.ex
  2. 23
      apps/explorer/test/explorer/chain_test.exs

@ -65,18 +65,20 @@ defmodule Explorer.Chain.Address.TokenBalance do
end end
@doc """ @doc """
Builds an `Ecto.Query` to fetch the last token balances. Builds an `Ecto.Query` to fetch the last token balances that have value greater than 0.
The last token balances from an Address is the last block indexed. The last token balances from an Address is the last block indexed.
""" """
def last_token_balances(address_hash) do def last_token_balances(address_hash) do
from( query =
tb in TokenBalance, from(
where: tb.address_hash == ^address_hash and tb.value > 0, tb in TokenBalance,
distinct: :token_contract_address_hash, where: tb.address_hash == ^address_hash,
order_by: [desc: :block_number], distinct: :token_contract_address_hash,
preload: :token order_by: [desc: :block_number]
) )
from(tb in subquery(query), where: tb.value > 0, preload: :token)
end end
@doc """ @doc """

@ -2665,6 +2665,29 @@ defmodule Explorer.ChainTest do
assert Chain.fetch_last_token_balances(address.hash) == [] assert Chain.fetch_last_token_balances(address.hash) == []
end end
test "does not consider other blocks when the last block has the value 0" do
address = insert(:address)
token = insert(:token, contract_address: build(:contract_address))
insert(
:token_balance,
address: address,
block_number: 1000,
token_contract_address_hash: token.contract_address_hash,
value: 5000
)
insert(
:token_balance,
address: address,
block_number: 1001,
token_contract_address_hash: token.contract_address_hash,
value: 0
)
assert Chain.fetch_last_token_balances(address.hash) == []
end
end end
describe "fetch_token_holders_from_token_hash/2" do describe "fetch_token_holders_from_token_hash/2" do

Loading…
Cancel
Save