Use address_current_token_balances in address tokens tab

pull/1226/head
fvictorio 6 years ago
parent 7a3dce7c8d
commit cd51e7cb29
  1. 2
      apps/block_scout_web/lib/block_scout_web/templates/address_token/_tokens.html.eex
  2. 4
      apps/block_scout_web/lib/block_scout_web/views/address_token_view.ex
  3. 19
      apps/block_scout_web/test/block_scout_web/controllers/address_token_controller_test.exs
  4. 2
      apps/block_scout_web/test/block_scout_web/features/viewing_addresses_test.exs
  5. 25
      apps/block_scout_web/test/block_scout_web/views/address_token_view_test.exs
  6. 30
      apps/explorer/lib/explorer/chain/address/token.ex
  7. 10
      apps/explorer/lib/explorer/chain/token.ex
  8. 73
      apps/explorer/test/explorer/chain/address/token_test.exs

@ -8,7 +8,7 @@
) do %>
<%= token_name(@token) %>
<% end %>
<span><%= @token.type %> - <%= number_of_transfers(@token) %></span>
<span><%= @token.type %> - <%= @token.contract_address_hash %></span>
</div>
<div class="col-md-5 d-flex flex-column text-md-right mt-3 mt-md-0">
<span class="tile-title-lg text-md-right align-bottom">

@ -1,7 +1,3 @@
defmodule BlockScoutWeb.AddressTokenView do
use BlockScoutWeb, :view
def number_of_transfers(token) do
ngettext("%{count} transfer", "%{count} transfers", token.transfers_count)
end
end

@ -33,14 +33,14 @@ defmodule BlockScoutWeb.AddressTokenControllerTest do
|> insert(name: "token2")
insert(
:token_balance,
:address_current_token_balance,
address: address,
token_contract_address_hash: token1.contract_address_hash,
value: 1000
)
insert(
:token_balance,
:address_current_token_balance,
address: address,
token_contract_address_hash: token2.contract_address_hash,
value: 0
@ -82,13 +82,12 @@ defmodule BlockScoutWeb.AddressTokenControllerTest do
token = insert(:token, name: "A Token#{i}", type: "ERC-20")
insert(
:token_balance,
:address_current_token_balance,
token_contract_address_hash: token.contract_address_hash,
address: address,
value: 1000
)
insert(:token_transfer, token_contract_address: token.contract_address, from_address: address)
acc ++ [token.name]
end)
|> Enum.sort()
@ -96,21 +95,21 @@ defmodule BlockScoutWeb.AddressTokenControllerTest do
token = insert(:token, name: "Another Token", type: "ERC-721")
insert(
:token_balance,
:address_current_token_balance,
token_contract_address_hash: token.contract_address_hash,
address: address,
value: 1000
)
insert(:token_transfer, token: token, from_address: address)
%Token{name: name, type: type} = token
%Token{name: name, type: type, inserted_at: inserted_at} = token
start_supervised!(BlockValidationCounter)
conn =
get(conn, address_token_path(BlockScoutWeb.Endpoint, :index, address.hash), %{
"name" => name,
"type" => type
"token_name" => name,
"token_type" => type,
"token_inserted_at" => inserted_at
})
actual_tokens =
@ -128,7 +127,7 @@ defmodule BlockScoutWeb.AddressTokenControllerTest do
token = insert(:token, name: "A Token#{i}", type: "ERC-20")
insert(
:token_balance,
:address_current_token_balance,
token_contract_address_hash: token.contract_address_hash,
address: address,
value: 1000

@ -429,7 +429,7 @@ defmodule BlockScoutWeb.ViewingAddressesTest do
token_contract_address: contract_address
)
insert(:token_balance, address: lincoln, token_contract_address_hash: contract_address.hash)
insert(:address_current_token_balance, address: lincoln, token_contract_address_hash: contract_address.hash)
start_supervised!(BlockValidationCounter)
BlockValidationCounter.consolidate_blocks()

@ -1,25 +0,0 @@
defmodule BlockScoutWeb.AddressTokenViewTest do
use BlockScoutWeb.ConnCase, async: true
alias BlockScoutWeb.AddressTokenView
describe "number_of_transfers/1" do
test "returns the singular form when there is only one transfer" do
token = %{transfers_count: 1}
assert AddressTokenView.number_of_transfers(token) == "1 transfer"
end
test "returns the plural form when there is more than one transfer" do
token = %{transfers_count: 2}
assert AddressTokenView.number_of_transfers(token) == "2 transfers"
end
test "returns the plural form when there are 0 transfers" do
token = %{transfers_count: 0}
assert AddressTokenView.number_of_transfers(token) == "0 transfers"
end
end
end

@ -16,9 +16,10 @@ defmodule Explorer.Chain.Address.Token do
import Ecto.Query
alias Explorer.{Chain, PagingOptions}
alias Explorer.Chain.{Address, Address.TokenBalance, Hash}
alias Explorer.Chain.{Address, Hash}
alias Explorer.Chain.Address.CurrentTokenBalance
@enforce_keys [:contract_address_hash, :inserted_at, :name, :symbol, :balance, :decimals, :type, :transfers_count]
@enforce_keys [:contract_address_hash, :inserted_at, :name, :symbol, :balance, :decimals, :type]
defstruct @enforce_keys
@default_paging_options %PagingOptions{page_size: 50}
@ -31,20 +32,18 @@ defmodule Explorer.Chain.Address.Token do
def list_address_tokens_with_balance(address_hash, options \\ []) do
paging_options = Keyword.get(options, :paging_options, @default_paging_options)
Chain.Token
|> Chain.Token.join_with_transfers()
|> join_with_last_balance(address_hash)
|> order_filter_and_group(address_hash)
address_hash
|> join_with_last_balance()
|> order_filter_and_group()
|> page_tokens(paging_options)
|> limit(^paging_options.page_size)
end
defp order_filter_and_group(query, address_hash) do
defp order_filter_and_group(query) do
from(
[token, transfer, balance] in query,
[token, balance] in query,
order_by: fragment("? DESC, LOWER(?) ASC NULLS LAST", token.type, token.name),
where:
(transfer.to_address_hash == ^address_hash or transfer.from_address_hash == ^address_hash) and balance.value > 0,
where: balance.value > 0,
group_by: [token.name, token.symbol, balance.value, token.type, token.contract_address_hash],
select: %Address.Token{
contract_address_hash: token.contract_address_hash,
@ -53,24 +52,21 @@ defmodule Explorer.Chain.Address.Token do
symbol: token.symbol,
balance: balance.value,
decimals: max(token.decimals),
type: token.type,
transfers_count: count(token.contract_address_hash)
type: token.type
}
)
end
defp join_with_last_balance(queryable, address_hash) do
defp join_with_last_balance(address_hash) do
last_balance_query =
from(
tb in TokenBalance,
tb in CurrentTokenBalance,
where: tb.address_hash == ^address_hash,
distinct: :token_contract_address_hash,
order_by: [desc: :block_number],
select: %{value: tb.value, token_contract_address_hash: tb.token_contract_address_hash}
)
from(
t in queryable,
t in Chain.Token,
join: tb in subquery(last_balance_query),
on: tb.token_contract_address_hash == t.contract_address_hash
)

@ -22,7 +22,7 @@ defmodule Explorer.Chain.Token do
import Ecto.{Changeset, Query}
alias Ecto.Changeset
alias Explorer.Chain.{Address, Hash, Token, TokenTransfer}
alias Explorer.Chain.{Address, Hash, Token}
@typedoc """
* `:name` - Name of the token
@ -87,14 +87,6 @@ defmodule Explorer.Chain.Token do
end
end
def join_with_transfers(queryable \\ Token) do
from(
t in queryable,
join: tt in TokenTransfer,
on: tt.token_contract_address_hash == t.contract_address_hash
)
end
@doc """
Builds an `Ecto.Query` to fetch the cataloged tokens.

@ -16,26 +16,12 @@ defmodule Explorer.Chain.Address.TokenTest do
|> Repo.preload(:contract_address)
insert(
:token_balance,
:address_current_token_balance,
address: address,
token_contract_address_hash: token.contract_address_hash,
value: 1000
)
insert(
:token_transfer,
token_contract_address: token.contract_address,
from_address: address,
to_address: build(:address)
)
insert(
:token_transfer,
token_contract_address: token.contract_address,
from_address: build(:address),
to_address: address
)
fetched_token =
address.hash
|> Address.Token.list_address_tokens_with_balance()
@ -49,8 +35,7 @@ defmodule Explorer.Chain.Address.TokenTest do
symbol: "TC",
balance: Decimal.new(1000),
decimals: Decimal.new(0),
type: "ERC-721",
transfers_count: 2
type: "ERC-721"
}
end
@ -63,7 +48,7 @@ defmodule Explorer.Chain.Address.TokenTest do
|> Repo.preload(:contract_address)
insert(
:token_balance,
:address_current_token_balance,
address: address,
token_contract_address_hash: token.contract_address_hash,
value: 1000
@ -82,7 +67,7 @@ defmodule Explorer.Chain.Address.TokenTest do
|> Repo.preload(:contract_address)
insert(
:token_balance,
:address_current_token_balance,
address: address,
token_contract_address_hash: token2.contract_address_hash,
value: 1000
@ -113,7 +98,7 @@ defmodule Explorer.Chain.Address.TokenTest do
|> Repo.preload(:contract_address)
insert(
:token_balance,
:address_current_token_balance,
address: address,
token_contract_address_hash: token.contract_address_hash,
value: 1000
@ -132,7 +117,7 @@ defmodule Explorer.Chain.Address.TokenTest do
|> Repo.preload(:contract_address)
insert(
:token_balance,
:address_current_token_balance,
address: address,
token_contract_address_hash: token2.contract_address_hash,
value: 1000
@ -151,7 +136,7 @@ defmodule Explorer.Chain.Address.TokenTest do
|> Repo.preload(:contract_address)
insert(
:token_balance,
:address_current_token_balance,
address: address,
token_contract_address_hash: token3.contract_address_hash,
value: 1000
@ -182,7 +167,7 @@ defmodule Explorer.Chain.Address.TokenTest do
|> Repo.preload(:contract_address)
insert(
:token_balance,
:address_current_token_balance,
address: address,
token_contract_address_hash: token.contract_address_hash,
value: 1000
@ -201,7 +186,7 @@ defmodule Explorer.Chain.Address.TokenTest do
|> Repo.preload(:contract_address)
insert(
:token_balance,
:address_current_token_balance,
address: address,
token_contract_address_hash: token2.contract_address_hash,
value: 1000
@ -220,7 +205,7 @@ defmodule Explorer.Chain.Address.TokenTest do
|> Repo.preload(:contract_address)
insert(
:token_balance,
:address_current_token_balance,
address: address,
token_contract_address_hash: token3.contract_address_hash,
value: 1000
@ -267,44 +252,6 @@ defmodule Explorer.Chain.Address.TokenTest do
assert fetched_token == nil
end
test "brings the value of the last balance" do
address = insert(:address)
token =
:token
|> insert(name: "atoken", type: "ERC-721", decimals: 0, symbol: "AT")
|> Repo.preload(:contract_address)
insert(
:token_balance,
address: address,
token_contract_address_hash: token.contract_address_hash,
value: 1000
)
insert(
:token_balance,
address: address,
token_contract_address_hash: token.contract_address_hash,
value: 1234
)
insert(
:token_transfer,
token_contract_address: token.contract_address,
from_address: address,
to_address: build(:address)
)
fetched_token =
address.hash
|> Address.Token.list_address_tokens_with_balance()
|> Repo.all()
|> List.first()
assert fetched_token.balance == Decimal.new(1234)
end
test "ignores token if the last balance is zero" do
address = insert(:address)

Loading…
Cancel
Save