Merge branch 'master' into release_build

pull/1131/head
Andrew Cravenho 6 years ago committed by GitHub
commit fe2fb08b34
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 1745
      apps/block_scout_web/assets/package-lock.json
  2. 38
      apps/block_scout_web/lib/block_scout_web/controllers/tokens/holder_controller.ex
  3. 39
      apps/block_scout_web/lib/block_scout_web/templates/tokens/holder/index.html.eex
  4. 7
      apps/block_scout_web/priv/gettext/default.pot
  5. 7
      apps/block_scout_web/priv/gettext/en/LC_MESSAGES/default.po
  6. 19
      apps/block_scout_web/test/block_scout_web/controllers/tokens/holder_controller_test.exs
  7. 1
      apps/block_scout_web/test/block_scout_web/features/viewing_tokens_test.exs
  8. 44
      apps/ethereum_jsonrpc/lib/ethereum_jsonrpc/transaction.ex

File diff suppressed because it is too large Load Diff

@ -1,7 +1,9 @@
defmodule BlockScoutWeb.Tokens.HolderController do defmodule BlockScoutWeb.Tokens.HolderController do
use BlockScoutWeb, :controller use BlockScoutWeb, :controller
alias BlockScoutWeb.Tokens.HolderView
alias Explorer.Chain alias Explorer.Chain
alias Phoenix.View
import BlockScoutWeb.Chain, import BlockScoutWeb.Chain,
only: [ only: [
@ -10,21 +12,47 @@ defmodule BlockScoutWeb.Tokens.HolderController do
next_page_params: 3 next_page_params: 3
] ]
def index(conn, %{"token_id" => address_hash_string} = params) do def index(conn, %{"token_id" => address_hash_string, "type" => "JSON"} = params) do
with {:ok, address_hash} <- Chain.string_to_address_hash(address_hash_string), with {:ok, address_hash} <- Chain.string_to_address_hash(address_hash_string),
{:ok, token} <- Chain.token_from_address_hash(address_hash), {:ok, token} <- Chain.token_from_address_hash(address_hash),
token_balances <- Chain.fetch_token_holders_from_token_hash(address_hash, paging_options(params)) do token_balances <- Chain.fetch_token_holders_from_token_hash(address_hash, paging_options(params)) do
{token_balances_paginated, next_page} = split_list_by_page(token_balances) {token_balances_paginated, next_page} = split_list_by_page(token_balances)
next_page_path =
case next_page_params(next_page, token_balances_paginated, params) do
nil ->
nil
next_page_params ->
token_holder_path(conn, :index, address_hash, Map.delete(next_page_params, "type"))
end
token_balances_json =
Enum.map(token_balances_paginated, fn token_balance ->
View.render_to_string(HolderView, "_token_balances.html", token_balance: token_balance, token: token)
end)
json(conn, %{items: token_balances_json, next_page_path: next_page_path})
else
:error ->
not_found(conn)
{:error, :not_found} ->
not_found(conn)
end
end
def index(conn, %{"token_id" => address_hash_string}) do
with {:ok, address_hash} <- Chain.string_to_address_hash(address_hash_string),
{:ok, token} <- Chain.token_from_address_hash(address_hash) do
render( render(
conn, conn,
"index.html", "index.html",
token: token, current_path: current_path(conn),
token_balances: token_balances_paginated,
holders_count_consolidation_enabled: Chain.token_holders_counter_consolidation_enabled?(), holders_count_consolidation_enabled: Chain.token_holders_counter_consolidation_enabled?(),
total_token_transfers: Chain.count_token_transfers_from_token_hash(address_hash), token: token,
total_token_holders: Chain.count_token_holders_from_token_hash(address_hash), total_token_holders: Chain.count_token_holders_from_token_hash(address_hash),
next_page_params: next_page_params(next_page, token_balances_paginated, params) total_token_transfers: Chain.count_token_transfers_from_token_hash(address_hash)
) )
else else
:error -> :error ->

@ -16,28 +16,37 @@
</div> </div>
<!-- Token Holders --> <!-- Token Holders -->
<div class="card-body"> <div class="card-body" data-async-listing="<%= @current_path %>">
<h2 class="card-title"><%= gettext "Token Holders" %></h2> <h2 class="card-title"><%= gettext "Token Holders" %></h2>
<%= if Enum.any?(@token_balances) do %> <button data-error-message class="alert alert-danger col-12 text-left" style="display: none;">
<%= for token_balance <- @token_balances do %> <span href="#" class="alert-link"><%= gettext("Something went wrong, click to reload.") %></span>
<%= render "_token_balances.html", token: @token, token_balance: token_balance %> </button>
<% end %> <div data-empty-response-message style="display: none;">
<% else %>
<div class="tile tile-muted text-center"> <div class="tile tile-muted text-center">
<span data-selector="empty-transactions-list"> <span data-selector="empty-transactions-list">
<%= gettext "There are no holders for this Token." %> <%= gettext "There are no holders for this Token." %>
</span> </span>
</div> </div>
<% end %> </div>
<div data-loading-message class="tile tile-muted text-center mt-3">
<%= if @next_page_params do %> <span class="loading-spinner-small mr-2">
<%= link( <span class="loading-spinner-block-1"></span>
gettext("Next Page"), <span class="loading-spinner-block-2"></span>
class: "button button-secondary button-small float-right mt-4", </span>
to: token_holder_path(@conn, :index, @token.contract_address_hash, @next_page_params) <%= gettext("Loading") %>...
) %> </div>
<% end %> <div data-items></div>
<a href="#" class="button button-secondary button-small float-right mt-4" data-next-page-button style="display: none;">
<%= gettext("Next Page") %>
</a>
<div class="button button-secondary button-small float-right mt-4" data-loading-button style="display: none;">
<span class="loading-spinner-small mr-2">
<span class="loading-spinner-block-1"></span>
<span class="loading-spinner-block-2"></span>
</span>
<%= gettext("Loading") %>...
</div>
</div> </div>
</div> </div>
</section> </section>

@ -614,7 +614,7 @@ msgid "Next"
msgstr "" msgstr ""
#, elixir-format #, elixir-format
#: lib/block_scout_web/templates/tokens/holder/index.html.eex:36 #: lib/block_scout_web/templates/tokens/holder/index.html.eex:41
#: lib/block_scout_web/templates/tokens/inventory/index.html.eex:35 #: lib/block_scout_web/templates/tokens/inventory/index.html.eex:35
msgid "Next Page" msgid "Next Page"
msgstr "" msgstr ""
@ -810,7 +810,7 @@ msgid "Telegram"
msgstr "" msgstr ""
#, elixir-format #, elixir-format
#: lib/block_scout_web/templates/tokens/holder/index.html.eex:29 #: lib/block_scout_web/templates/tokens/holder/index.html.eex:28
msgid "There are no holders for this Token." msgid "There are no holders for this Token."
msgstr "" msgstr ""
@ -1221,6 +1221,8 @@ msgstr ""
#: lib/block_scout_web/templates/address_transaction/index.html.eex:61 #: lib/block_scout_web/templates/address_transaction/index.html.eex:61
#: lib/block_scout_web/templates/block/index.html.eex:22 #: lib/block_scout_web/templates/block/index.html.eex:22
#: lib/block_scout_web/templates/pending_transaction/index.html.eex:33 #: lib/block_scout_web/templates/pending_transaction/index.html.eex:33
#: lib/block_scout_web/templates/tokens/holder/index.html.eex:37
#: lib/block_scout_web/templates/tokens/holder/index.html.eex:48
#: lib/block_scout_web/templates/tokens/transfer/index.html.eex:33 #: lib/block_scout_web/templates/tokens/transfer/index.html.eex:33
#: lib/block_scout_web/templates/tokens/transfer/index.html.eex:45 #: lib/block_scout_web/templates/tokens/transfer/index.html.eex:45
#: lib/block_scout_web/templates/transaction/index.html.eex:33 #: lib/block_scout_web/templates/transaction/index.html.eex:33
@ -1415,6 +1417,7 @@ msgstr ""
#, elixir-format #, elixir-format
#: lib/block_scout_web/templates/address_internal_transaction/index.html.eex:60 #: lib/block_scout_web/templates/address_internal_transaction/index.html.eex:60
#: lib/block_scout_web/templates/address_token_transfer/index.html.eex:26 #: lib/block_scout_web/templates/address_token_transfer/index.html.eex:26
#: lib/block_scout_web/templates/tokens/holder/index.html.eex:23
#: lib/block_scout_web/templates/tokens/transfer/index.html.eex:21 #: lib/block_scout_web/templates/tokens/transfer/index.html.eex:21
msgid "Something went wrong, click to reload." msgid "Something went wrong, click to reload."
msgstr "" msgstr ""

@ -614,7 +614,7 @@ msgid "Next"
msgstr "" msgstr ""
#, elixir-format #, elixir-format
#: lib/block_scout_web/templates/tokens/holder/index.html.eex:36 #: lib/block_scout_web/templates/tokens/holder/index.html.eex:41
#: lib/block_scout_web/templates/tokens/inventory/index.html.eex:35 #: lib/block_scout_web/templates/tokens/inventory/index.html.eex:35
msgid "Next Page" msgid "Next Page"
msgstr "" msgstr ""
@ -810,7 +810,7 @@ msgid "Telegram"
msgstr "" msgstr ""
#, elixir-format #, elixir-format
#: lib/block_scout_web/templates/tokens/holder/index.html.eex:29 #: lib/block_scout_web/templates/tokens/holder/index.html.eex:28
msgid "There are no holders for this Token." msgid "There are no holders for this Token."
msgstr "" msgstr ""
@ -1221,6 +1221,8 @@ msgstr ""
#: lib/block_scout_web/templates/address_transaction/index.html.eex:61 #: lib/block_scout_web/templates/address_transaction/index.html.eex:61
#: lib/block_scout_web/templates/block/index.html.eex:22 #: lib/block_scout_web/templates/block/index.html.eex:22
#: lib/block_scout_web/templates/pending_transaction/index.html.eex:33 #: lib/block_scout_web/templates/pending_transaction/index.html.eex:33
#: lib/block_scout_web/templates/tokens/holder/index.html.eex:37
#: lib/block_scout_web/templates/tokens/holder/index.html.eex:48
#: lib/block_scout_web/templates/tokens/transfer/index.html.eex:33 #: lib/block_scout_web/templates/tokens/transfer/index.html.eex:33
#: lib/block_scout_web/templates/tokens/transfer/index.html.eex:45 #: lib/block_scout_web/templates/tokens/transfer/index.html.eex:45
#: lib/block_scout_web/templates/transaction/index.html.eex:33 #: lib/block_scout_web/templates/transaction/index.html.eex:33
@ -1415,6 +1417,7 @@ msgstr ""
#, elixir-format #, elixir-format
#: lib/block_scout_web/templates/address_internal_transaction/index.html.eex:60 #: lib/block_scout_web/templates/address_internal_transaction/index.html.eex:60
#: lib/block_scout_web/templates/address_token_transfer/index.html.eex:26 #: lib/block_scout_web/templates/address_token_transfer/index.html.eex:26
#: lib/block_scout_web/templates/tokens/holder/index.html.eex:23
#: lib/block_scout_web/templates/tokens/transfer/index.html.eex:21 #: lib/block_scout_web/templates/tokens/transfer/index.html.eex:21
msgid "Something went wrong, click to reload." msgid "Something went wrong, click to reload."
msgstr "" msgstr ""

@ -48,7 +48,6 @@ defmodule BlockScoutWeb.Tokens.HolderControllerTest do
value: &1 + 1000 value: &1 + 1000
) )
) )
|> Enum.map(& &1.value)
token_balance = token_balance =
insert( insert(
@ -60,15 +59,17 @@ defmodule BlockScoutWeb.Tokens.HolderControllerTest do
conn = conn =
get(conn, token_holder_path(conn, :index, token.contract_address_hash), %{ get(conn, token_holder_path(conn, :index, token.contract_address_hash), %{
"value" => Decimal.to_integer(token_balance.value), "value" => Decimal.to_integer(token_balance.value),
"address_hash" => Hash.to_string(token_balance.address_hash) "address_hash" => Hash.to_string(token_balance.address_hash),
"type" => "JSON"
}) })
actual_token_balances = token_balance_tiles = json_response(conn, 200)["items"]
conn.assigns.token_balances
|> Enum.map(& &1.value)
|> Enum.reverse()
assert second_page_token_balances == actual_token_balances assert Enum.all?(second_page_token_balances, fn token_balance ->
Enum.any?(token_balance_tiles, fn tile ->
String.contains?(tile, to_string(token_balance.address_hash))
end)
end)
end end
test "next_page_params exists if not on last page", %{conn: conn} do test "next_page_params exists if not on last page", %{conn: conn} do
@ -84,9 +85,9 @@ defmodule BlockScoutWeb.Tokens.HolderControllerTest do
) )
) )
conn = get(conn, token_holder_path(conn, :index, token.contract_address_hash)) conn = get(conn, token_holder_path(conn, :index, token.contract_address_hash, %{"type" => "JSON"}))
assert conn.assigns.next_page_params assert json_response(conn, 200)["next_page_path"]
end end
end end
end end

@ -4,6 +4,7 @@ defmodule BlockScoutWeb.ViewingTokensTest do
alias BlockScoutWeb.TokenPage alias BlockScoutWeb.TokenPage
describe "viewing token holders" do describe "viewing token holders" do
@tag :skip
test "list the token holders", %{session: session} do test "list the token holders", %{session: session} do
token = insert(:token) token = insert(:token)

@ -103,8 +103,52 @@ defmodule EthereumJSONRPC.Transaction do
transaction_index: 0 transaction_index: 0
} }
Ganache bug: https://github.com/trufflesuite/ganache/issues/997
Invalid input of `0x0` is converted to `0x`.
iex> EthereumJSONRPC.Transaction.elixir_to_params(
...> %{
...> "blockHash" => "0x4e3a3754410177e6937ef1f84bba68ea139e8d1a2258c5f85db9f1cd715a1bdd",
...> "blockNumber" => 46147,
...> "from" => "0xa1e4380a3b1f749673e270229993ee55f35663b4",
...> "gas" => 21000,
...> "gasPrice" => 50000000000000,
...> "hash" => "0x5c504ed432cb51138bcf09aa5e8a410dd4a1e204ef84bfed1be16dfba1b22060",
...> "input" => "0x0",
...> "nonce" => 0,
...> "r" => 61965845294689009770156372156374760022787886965323743865986648153755601564112,
...> "s" => 31606574786494953692291101914709926755545765281581808821704454381804773090106,
...> "to" => "0x5df9b87991262f6ba471f09758cde1c0fc1de734",
...> "transactionIndex" => 0,
...> "v" => 28,
...> "value" => 31337
...> }
...> )
%{
block_hash: "0x4e3a3754410177e6937ef1f84bba68ea139e8d1a2258c5f85db9f1cd715a1bdd",
block_number: 46147,
from_address_hash: "0xa1e4380a3b1f749673e270229993ee55f35663b4",
gas: 21000,
gas_price: 50000000000000,
hash: "0x5c504ed432cb51138bcf09aa5e8a410dd4a1e204ef84bfed1be16dfba1b22060",
index: 0,
input: "0x",
nonce: 0,
r: 61965845294689009770156372156374760022787886965323743865986648153755601564112,
s: 31606574786494953692291101914709926755545765281581808821704454381804773090106,
to_address_hash: "0x5df9b87991262f6ba471f09758cde1c0fc1de734",
v: 28,
value: 31337,
transaction_index: 0
}
""" """
@spec elixir_to_params(elixir) :: params @spec elixir_to_params(elixir) :: params
def elixir_to_params(%{"input" => "0x0"} = transaction) do
elixir_to_params(%{transaction | "input" => "0x"})
end
def elixir_to_params(%{ def elixir_to_params(%{
"blockHash" => block_hash, "blockHash" => block_hash,
"blockNumber" => block_number, "blockNumber" => block_number,

Loading…
Cancel
Save