Merge branch 'master' into ab-requry-tokens

pull/1896/head
Ayrat Badykov 6 years ago committed by GitHub
commit 544609baed
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 3
      CHANGELOG.md
  2. 53
      apps/block_scout_web/assets/css/theme/_ethereum_variables.scss
  3. 41
      apps/block_scout_web/assets/static/images/ethereum_logo.svg
  4. 17
      apps/block_scout_web/lib/block_scout_web/chain.ex
  5. 57
      apps/block_scout_web/lib/block_scout_web/controllers/address_controller.ex
  6. 29
      apps/block_scout_web/lib/block_scout_web/templates/address/index.html.eex
  7. 42
      apps/block_scout_web/priv/gettext/default.pot
  8. 42
      apps/block_scout_web/priv/gettext/en/LC_MESSAGES/default.po
  9. 22
      apps/explorer/lib/explorer/chain.ex
  10. 27
      apps/explorer/test/explorer/chain_test.exs

@ -2,6 +2,8 @@
### Features
- [#1812](https://github.com/poanetwork/blockscout/pull/1812) - add pagination to addresses page
- [#1874](https://github.com/poanetwork/blockscout/pull/1874) - add changes to ethereum theme and ethereum logo
- [#1815](https://github.com/poanetwork/blockscout/pull/1815) - able to search without prefix "0x"
- [#1813](https://github.com/poanetwork/blockscout/pull/1813) - add total blocks counter to the main page
- [#1806](https://github.com/poanetwork/blockscout/pull/1806) - verify contracts with a post request
@ -200,3 +202,4 @@
- [https://github.com/poanetwork/blockscout/pull/1532](https://github.com/poanetwork/blockscout/pull/1532) - Upgrade elixir to 1.8.1
- [https://github.com/poanetwork/blockscout/pull/1553](https://github.com/poanetwork/blockscout/pull/1553) - Dockerfile: remove 1.7.1 version pin FROM bitwalker/alpine-elixir-phoenix
- [https://github.com/poanetwork/blockscout/pull/1465](https://github.com/poanetwork/blockscout/pull/1465) - Resolve lodash security alert

@ -1,3 +1,50 @@
$primary: #16465b;
$secondary: #5ab3ff;
$tertiary: #77a4c5;
// general
$primary: #153550;
$secondary: #49a2ee;
$tertiary: #4ad7a7;
$additional-font: #89cae6;
// footer
$footer-background-color: $primary;
$footer-title-color: #fff;
$footer-text-color: #89cae6;
$footer-item-disc-color: $secondary;
.footer-logo { filter: brightness(0) invert(1); }
// dashboard
$dashboard-line-color-price: $tertiary; // price left border
$dashboard-banner-chart-legend-value-color: $additional-font; // chart labels
$dashboard-stats-item-value-color: $additional-font; // stat values
$dashboard-stats-item-border-color: $secondary; // stat border
$dashboard-banner-gradient-start: $primary; // gradient begin
$dashboard-banner-gradient-end: lighten($primary, 5); // gradient end
$dashboard-banner-network-plain-container-background-color: #1c476c; // stats bg
// navigation
.navbar { box-shadow: 0px 0px 30px 0px rgba(21, 53, 80, 0.12); } // header shadow
$header-icon-border-color-hover: $secondary; // top border on hover
$header-icon-color-hover: $secondary; // nav icon on hover
.dropdown-item:hover, .dropdown-item:focus { background-color: $secondary !important; } // dropdown item on hover
// buttons
$btn-line-bg: #fff; // button bg
$btn-line-color: $secondary; // button border and font color && hover bg color
$btn-copy-color: $secondary; // btn copy
$btn-qr-color: $secondary; // btn qr-code
//links & tile
.tile a { color: $secondary !important; } // links color for badges
.tile-type-block {
border-left: 4px solid $secondary;
} // tab active bg
// card
$card-background-1: $secondary;
$card-tab-active: $secondary;

@ -1,40 +1 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 532.5 106" style="enable-background:new 0 0 532.5 106;" xml:space="preserve">
<style type="text/css">
.st0{fill:#FFFFFF;}
</style>
<title>ethereum-logo</title>
<g>
<path class="st0" d="M121.6,73.1c-2.9,0-5.6-0.7-7.9-2.2c-2.4-1.4-4.2-3.4-5.5-6c-1.3-2.6-2-5.5-2-8.6v-1.4c0-3.3,0.6-6.3,1.9-8.9
c1.3-2.6,3.1-4.7,5.3-6.2s4.8-2.3,7.4-2.3c4.2,0,7.5,1.4,9.9,4.3c2.4,2.8,3.7,6.7,3.7,11.7v2.1H110v0.7c0,3.9,1.1,7.1,3.3,9.7
c2.2,2.6,5,3.9,8.4,3.9c2,0,3.8-0.4,5.4-1.1c1.6-0.7,3-1.9,4.2-3.6l2.4,1.8C131,71,126.9,73.1,121.6,73.1z M120.9,40.7
c-2.9,0-5.3,1-7.2,3.1c-2,2.1-3.1,4.9-3.6,8.4h20.6v-0.4c-0.1-3.3-1-6-2.8-8.1C126.1,41.7,123.8,40.7,120.9,40.7z"/>
<path class="st0" d="M164.6,29.3v8.8h7.1v3.1h-7.1v22.9c0,1.9,0.3,3.3,1,4.3c0.7,0.9,1.8,1.4,3.4,1.4c0.6,0,1.7-0.1,3.1-0.3
l0.2,3.1c-1,0.4-2.3,0.5-4.1,0.5c-2.6,0-4.5-0.8-5.7-2.3c-1.2-1.5-1.8-3.7-1.8-6.7V41.2h-6.3v-3.1h6.3v-8.8H164.6z"/>
<path class="st0" d="M200.2,43.9c1.2-2.1,2.8-3.6,4.8-4.8c1.9-1.1,4.1-1.7,6.4-1.7c3.7,0,6.4,1,8.2,3.1c1.8,2.1,2.7,5.2,2.7,9.3
v22.5h-3.8V49.9c0-3.1-0.7-5.4-2-6.9c-1.3-1.5-3.3-2.3-6.1-2.3c-2.3,0-4.4,0.7-6.2,2.2c-1.8,1.5-3.1,3.5-4,6v23.5h-3.8V23.7h3.8
V43.9z"/>
<path class="st0" d="M262.3,73.1c-2.9,0-5.6-0.7-7.9-2.2c-2.4-1.4-4.2-3.4-5.5-6c-1.3-2.6-2-5.5-2-8.6v-1.4c0-3.3,0.6-6.3,1.9-8.9
c1.3-2.6,3.1-4.7,5.3-6.2s4.8-2.3,7.4-2.3c4.2,0,7.5,1.4,9.9,4.3c2.4,2.8,3.7,6.7,3.7,11.7v2.1h-24.5v0.7c0,3.9,1.1,7.1,3.3,9.7
c2.2,2.6,5,3.9,8.4,3.9c2,0,3.8-0.4,5.4-1.1c1.6-0.7,3-1.9,4.2-3.6l2.4,1.8C271.6,71,267.6,73.1,262.3,73.1z M261.6,40.7
c-2.9,0-5.3,1-7.2,3.1c-2,2.1-3.1,4.9-3.6,8.4h20.6v-0.4c-0.1-3.3-1-6-2.8-8.1C266.8,41.7,264.4,40.7,261.6,40.7z"/>
<path class="st0" d="M315.2,41.3c-0.8-0.1-1.7-0.2-2.6-0.2c-2.4,0-4.4,0.7-6,2s-2.8,3.2-3.5,5.8v23.6h-3.8V38.1h3.7l0.1,5.5
c2-4.1,5.2-6.1,9.7-6.1c1.1,0,1.9,0.1,2.5,0.4L315.2,41.3z"/>
<path class="st0" d="M350.8,73.1c-2.9,0-5.6-0.7-7.9-2.2c-2.4-1.4-4.2-3.4-5.5-6c-1.3-2.6-2-5.5-2-8.6v-1.4c0-3.3,0.6-6.3,1.9-8.9
c1.3-2.6,3.1-4.7,5.3-6.2s4.8-2.3,7.4-2.3c4.2,0,7.5,1.4,9.9,4.3c2.4,2.8,3.7,6.7,3.7,11.7v2.1h-24.5v0.7c0,3.9,1.1,7.1,3.3,9.7
c2.2,2.6,5,3.9,8.4,3.9c2,0,3.8-0.4,5.4-1.1c1.6-0.7,3-1.9,4.2-3.6l2.4,1.8C360.1,71,356.1,73.1,350.8,73.1z M350.1,40.7
c-2.9,0-5.3,1-7.2,3.1s-3.1,4.9-3.6,8.4h20.6v-0.4c-0.1-3.3-1-6-2.8-8.1C355.3,41.7,353,40.7,350.1,40.7z"/>
<path class="st0" d="M410,68.1c-2.3,3.3-5.9,5-10.9,5c-3.7,0-6.4-1.1-8.3-3.2s-2.9-5.3-2.9-9.4V38.1h3.8v21.9
c0,6.5,2.6,9.8,7.9,9.8c5.5,0,9-2.3,10.4-6.8V38.1h3.8v34.3H410L410,68.1z"/>
<path class="st0" d="M443.9,38.1l0.1,5.6c1.3-2.1,2.9-3.6,4.8-4.7c1.9-1,4-1.6,6.3-1.6c5.4,0,8.9,2.2,10.3,6.7
c1.2-2.1,2.9-3.8,4.9-4.9c2.1-1.2,4.3-1.7,6.8-1.7c7.4,0,11.1,4,11.3,12.1v22.9h-3.8V49.8c0-3.1-0.7-5.3-2-6.8
c-1.3-1.5-3.4-2.2-6.4-2.2c-2.7,0-5,0.9-6.9,2.7c-1.9,1.7-2.9,3.8-3.1,6.3v22.7h-3.8V49.5c0-2.9-0.7-5.1-2.1-6.6
c-1.4-1.4-3.5-2.2-6.3-2.2c-2.4,0-4.4,0.7-6.2,2c-1.7,1.4-3,3.4-3.8,6.1v23.5h-3.8V38.1H443.9z"/>
</g>
<path class="st0" d="M57.5,17.7l21.7,36c-7,4.2-13.9,8.3-20.9,12.3c-0.6,0.2-1.3,0.2-1.8-0.1c-6.9-4-13.7-8-20.7-12.2
C43.1,41.7,50.2,29.8,57.5,17.7z"/>
<path class="st0" d="M78.1,58.9L57.2,88.3L36.3,58.9l0.4-0.4c1.7,1,3.4,2,5.1,3c4.5,2.6,9,5.2,13.4,7.9c1.2,0.9,2.9,1,4.1,0
c5.4-3.3,10.9-6.5,16.4-9.7c0.7-0.4,1.4-0.8,2.2-1.2L78.1,58.9z"/>
</svg>
<svg data-name="-e-eth_logo_top" xmlns="http://www.w3.org/2000/svg" width="106.094" height="30"><g data-name="1" fill-rule="evenodd"><path data-name="Фигура 1" d="M9 11.2l-9 4.4L9 0v11.2z" fill="#828083"/><path data-name="Фигура 1 копия" d="M9 10.783L0 15.2l9 5.215v-9.632z" fill="#353336"/><path data-name="Фигура 1 копия 2" d="M9 22.568l-9-5.78L9 30v-7.432z" fill="#848285"/><path data-name="Фигура 1 копия 3" d="M9 11.2l9 4.4L9 0v11.2z" fill="#2f2d30"/><path data-name="Фигура 1 копия 3" d="M9 10.783l9 4.412-9 5.215v-9.627z" fill="#121212"/><path data-name="Фигура 1 копия 3" d="M9 22.568l9-5.78L9 30v-7.432z" fill="#302e31"/></g><path d="M29.675 13.329a4.417 4.417 0 0 0 .012 5.856 3.867 3.867 0 0 0 6.084-.5.332.332 0 0 0-.289-.5.351.351 0 0 0-.289.165 3.239 3.239 0 0 1-2.77 1.395 2.9 2.9 0 0 1-2.168-.922 3.555 3.555 0 0 1-1.012-2.2h6.719a.309.309 0 0 0 .361-.338 4.287 4.287 0 0 0-1.116-2.943 3.683 3.683 0 0 0-5.532-.013zm.58.377a2.994 2.994 0 0 1 4.336 0 3.6 3.6 0 0 1 1.012 2.215h-6.36a3.6 3.6 0 0 1 1.012-2.215zm11.2-4.046a.336.336 0 1 0-.672 0v2.613h-1.728a.35.35 0 0 0 0 .7h1.728v7.01a.336.336 0 0 0 .672 0v-7.01h1.8a.35.35 0 0 0 0-.7h-1.8V9.66zm5.664 4.173V5.889a.336.336 0 1 0-.672 0v14.04a.336.336 0 0 0 .672 0v-3.492a3.921 3.921 0 0 1 .6-2.512 2.52 2.52 0 0 1 2.222-1.124 2.113 2.113 0 0 1 1.792.909 3.075 3.075 0 0 1 .621 1.962v4.258a.336.336 0 0 0 .672 0v-4.273a3.766 3.766 0 0 0-.816-2.448 2.755 2.755 0 0 0-2.28-1.1 3.047 3.047 0 0 0-2.808 1.728zm10.08-.5a4.417 4.417 0 0 0 .012 5.856 3.867 3.867 0 0 0 6.084-.5.332.332 0 0 0-.289-.5.35.35 0 0 0-.289.165 3.24 3.24 0 0 1-2.771 1.395 2.9 2.9 0 0 1-2.167-.922 3.549 3.549 0 0 1-1.012-2.2h6.719a.309.309 0 0 0 .361-.338 4.287 4.287 0 0 0-1.116-2.943 3.683 3.683 0 0 0-5.531-.017zm.58.377a2.994 2.994 0 0 1 4.336 0 3.6 3.6 0 0 1 1.012 2.215h-6.36a3.592 3.592 0 0 1 1.016-2.219zm11.108-.888a4.025 4.025 0 0 0-1.176 1.255V12.6a.336.336 0 0 0-.672 0v7.3a.336.336 0 0 0 .672 0v-3.2a4.148 4.148 0 0 1 .7-2.464 2.951 2.951 0 0 1 2.16-1.292.329.329 0 0 0 .312-.359.3.3 0 0 0-.36-.311 2.919 2.919 0 0 0-1.632.545zm5.16.511a4.417 4.417 0 0 0 .012 5.856 3.867 3.867 0 0 0 6.084-.5.332.332 0 0 0-.289-.5.353.353 0 0 0-.29.165 3.237 3.237 0 0 1-2.77 1.395 2.9 2.9 0 0 1-2.167-.922 3.549 3.549 0 0 1-1.012-2.2h6.719a.309.309 0 0 0 .361-.338 4.287 4.287 0 0 0-1.116-2.943 3.683 3.683 0 0 0-5.528-.017zm.58.377a2.994 2.994 0 0 1 4.336 0 3.6 3.6 0 0 1 1.012 2.215h-6.36a3.592 3.592 0 0 1 1.016-2.219zm15.044-1.1v2.736q0 4.44-2.785 4.44a2.144 2.144 0 0 1-1.823-.912 3.159 3.159 0 0 1-.6-1.968v-4.3a.336.336 0 1 0-.672 0v4.308a3.779 3.779 0 0 0 .817 2.455 2.747 2.747 0 0 0 2.279 1.107 2.983 2.983 0 0 0 2.785-1.9v1.392a.336.336 0 1 0 .672 0V12.61a.336.336 0 1 0-.672 0zm10.295 1.632a2.8 2.8 0 0 0-2.856-2.136 3.052 3.052 0 0 0-2.808 1.7V12.6a.336.336 0 0 0-.672 0v7.33a.336.336 0 0 0 .672 0v-3.4a4.571 4.571 0 0 1 .6-2.679 2.529 2.529 0 0 1 2.208-1.053 2.146 2.146 0 0 1 1.8.885 3.067 3.067 0 0 1 .624 1.962v4.285a.336.336 0 0 0 .672 0v-3.3a5.018 5.018 0 0 1 .624-2.56 2.4 2.4 0 0 1 2.16-1.268 2.106 2.106 0 0 1 1.8.885 3.067 3.067 0 0 1 .624 1.962v4.281a.336.336 0 0 0 .672 0v-4.3a3.84 3.84 0 0 0-.84-2.484 2.746 2.746 0 0 0-2.256-1.044 3.142 3.142 0 0 0-3.024 2.136z" fill="#1b1635" fill-rule="evenodd"/></svg>

Before

Width:  |  Height:  |  Size: 3.5 KiB

After

Width:  |  Height:  |  Size: 3.2 KiB

@ -25,7 +25,8 @@ defmodule BlockScoutWeb.Chain do
InternalTransaction,
Log,
TokenTransfer,
Transaction
Transaction,
Wei
}
alias Explorer.PagingOptions
@ -87,6 +88,16 @@ defmodule BlockScoutWeb.Chain do
Map.merge(params, paging_params(List.last(list)))
end
def paging_options(%{"hash" => hash, "fetched_coin_balance" => fetched_coin_balance}) do
with {coin_balance, ""} <- Integer.parse(fetched_coin_balance),
{:ok, address_hash} <- string_to_address_hash(hash) do
[paging_options: %{@default_paging_options | key: {%Wei{value: Decimal.new(coin_balance)}, address_hash}}]
else
_ ->
[paging_options: @default_paging_options]
end
end
def paging_options(%{
"block_number" => block_number_string,
"transaction_index" => transaction_index_string,
@ -177,6 +188,10 @@ defmodule BlockScoutWeb.Chain do
end
end
defp paging_params({%Address{hash: hash, fetched_coin_balance: fetched_coin_balance}, _}) do
%{"hash" => hash, "fetched_coin_balance" => Decimal.to_string(fetched_coin_balance.value)}
end
defp paging_params({%Reward{block: %{number: number}}, _}) do
%{"block_number" => number, "index" => 0}
end

@ -1,16 +1,55 @@
defmodule BlockScoutWeb.AddressController do
use BlockScoutWeb, :controller
import BlockScoutWeb.Chain, only: [paging_options: 1, next_page_params: 3, split_list_by_page: 1]
alias Explorer.{Chain, Market}
alias Explorer.Chain.Address
alias Explorer.ExchangeRates.Token
def index(conn, _params) do
def index(conn, params) do
addresses =
params
|> paging_options()
|> Chain.list_top_addresses()
{addresses_page, next_page} = split_list_by_page(addresses)
cur_page_number =
cond do
!params["prev_page_number"] -> 1
params["next_page"] -> String.to_integer(params["prev_page_number"]) + 1
params["prev_page"] -> String.to_integer(params["prev_page_number"]) - 1
end
next_page_path =
case next_page_params(next_page, addresses_page, params) do
nil ->
nil
next_page_params ->
next_params =
next_page_params
|> Map.put("prev_page_path", cur_page_path(conn, params))
|> Map.put("next_page", true)
|> Map.put("prev_page_number", cur_page_number)
address_path(
conn,
:index,
next_params
)
end
render(conn, "index.html",
address_tx_count_pairs: Chain.list_top_addresses(),
address_tx_count_pairs: addresses_page,
page_address_count: Enum.count(addresses_page),
address_count: Chain.count_addresses_with_balance_from_cache(),
exchange_rate: Market.get_exchange_rate(Explorer.coin()) || Token.null(),
total_supply: Chain.total_supply()
total_supply: Chain.total_supply(),
next_page_path: next_page_path,
prev_page_path: params["prev_page_path"],
cur_page_number: cur_page_number
)
end
@ -25,4 +64,16 @@ defmodule BlockScoutWeb.AddressController do
def validation_count(%Address{} = address) do
Chain.address_to_validation_count(address)
end
defp cur_page_path(conn, %{"hash" => _hash, "fetched_coin_balance" => _balance} = params) do
new_params = Map.put(params, "next_page", false)
address_path(
conn,
:index,
new_params
)
end
defp cur_page_path(conn, _), do: address_path(conn, :index)
end

@ -1,12 +1,28 @@
<section class="container">
<div class="card">
<div class="card-body">
<%= if @next_page_path do %>
<a href="<%= "#{@next_page_path}" %>" class="button button-secondary button-small float-right ml-1">
<%= gettext("Next") %>
</a>
<% end %>
<%= if @prev_page_path do %>
<a href="<%= "#{@prev_page_path}" %>" class="button button-secondary button-small float-right">
<%= gettext("Back") %>
</a>
<% end %>
<h1 class="card-title margin-bottom-0"><%= gettext "Addresses" %></h1>
<p class="card-subtitle">
<%= gettext "Showing 250 addresses of" %>
<%= gettext "Showing " %>
<%= Cldr.Number.to_string!(@page_address_count, format: "#,###") %>
<%= gettext " addresses of" %>
<%= Cldr.Number.to_string!(@address_count, format: "#,###") %>
<%= gettext "total addresses with a balance" %>
<%= gettext " (page" %>
<%= Cldr.Number.to_string!(@cur_page_number, format: "#,###)") %>
</p>
<span data-selector="top-addresses-list">
<%= for {{address, tx_count}, index} <- Enum.with_index(@address_tx_count_pairs, 1) do %>
<%= render "_tile.html",
@ -14,6 +30,17 @@
total_supply: @total_supply, tx_count: tx_count,
validation_count: validation_count(address) %>
<% end %>
<br>
<%= if @next_page_path do %>
<a href="<%= "#{@next_page_path}" %>" class="button button-secondary button-small float-right mt-0 mb-0 ml-1">
<%= gettext("Next") %>
</a>
<% end %>
<%= if @prev_page_path do %>
<a href="<%= "#{@prev_page_path}" %>" class="button button-secondary button-small float-right mt-0 mb-0">
<%= gettext("Back") %>
</a>
<% end %>
</span>
</div>
</div>

@ -104,7 +104,7 @@ msgid "Address"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address/index.html.eex:4
#: lib/block_scout_web/templates/address/index.html.eex:15
#: lib/block_scout_web/templates/tokens/overview/_details.html.eex:59
msgid "Addresses"
msgstr ""
@ -578,6 +578,8 @@ msgid "Newer"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address/index.html.eex:6
#: lib/block_scout_web/templates/address/index.html.eex:36
#: lib/block_scout_web/templates/address_token/index.html.eex:22
msgid "Next"
msgstr ""
@ -739,11 +741,6 @@ msgstr ""
msgid "Showing"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address/index.html.eex:6
msgid "Showing 250 addresses of"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/transaction/_emission_reward_tile.html.eex:8
#: lib/block_scout_web/views/transaction_view.ex:210
@ -1078,7 +1075,7 @@ msgid "string"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address/index.html.eex:8
#: lib/block_scout_web/templates/address/index.html.eex:21
msgid "total addresses with a balance"
msgstr ""
@ -1708,11 +1705,6 @@ msgstr ""
msgid "ERC-721"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/chain/show.html.eex:64
msgid "Total blocks"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/api_docs/index.html.eex:4
msgid "API Documentation"
@ -1739,3 +1731,29 @@ msgstr ""
#: lib/block_scout_web/views/transaction_view.ex:341
msgid "Raw Trace"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address/index.html.eex:22
msgid " (page"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address/index.html.eex:19
msgid " addresses of"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address/index.html.eex:11
#: lib/block_scout_web/templates/address/index.html.eex:41
msgid "Back"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address/index.html.eex:17
msgid "Showing "
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/chain/show.html.eex:64
msgid "Total blocks"
msgstr ""

@ -104,7 +104,7 @@ msgid "Address"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address/index.html.eex:4
#: lib/block_scout_web/templates/address/index.html.eex:15
#: lib/block_scout_web/templates/tokens/overview/_details.html.eex:59
msgid "Addresses"
msgstr ""
@ -578,6 +578,8 @@ msgid "Newer"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address/index.html.eex:6
#: lib/block_scout_web/templates/address/index.html.eex:36
#: lib/block_scout_web/templates/address_token/index.html.eex:22
msgid "Next"
msgstr ""
@ -739,11 +741,6 @@ msgstr ""
msgid "Showing"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address/index.html.eex:6
msgid "Showing 250 addresses of"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/transaction/_emission_reward_tile.html.eex:8
#: lib/block_scout_web/views/transaction_view.ex:210
@ -1078,7 +1075,7 @@ msgid "string"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address/index.html.eex:8
#: lib/block_scout_web/templates/address/index.html.eex:21
msgid "total addresses with a balance"
msgstr ""
@ -1708,11 +1705,6 @@ msgstr ""
msgid "ERC-721"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/chain/show.html.eex:64
msgid "Total blocks"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/api_docs/index.html.eex:4
msgid "API Documentation"
@ -1739,3 +1731,29 @@ msgstr ""
#: lib/block_scout_web/views/transaction_view.ex:341
msgid "Raw Trace"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address/index.html.eex:22
msgid " (page"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address/index.html.eex:19
msgid " addresses of"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address/index.html.eex:11
#: lib/block_scout_web/templates/address/index.html.eex:41
msgid "Back"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address/index.html.eex:17
msgid "Showing "
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/chain/show.html.eex:64
msgid "Total blocks"
msgstr ""

@ -1143,21 +1143,25 @@ defmodule Explorer.Chain do
end
@doc """
Lists the top 250 `t:Explorer.Chain.Address.t/0`'s' in descending order based on coin balance.
Lists the top `t:Explorer.Chain.Address.t/0`'s' in descending order based on coin balance and address hash.
"""
@spec list_top_addresses :: [{Address.t(), non_neg_integer()}]
def list_top_addresses do
query =
def list_top_addresses(options \\ []) do
paging_options = Keyword.get(options, :paging_options, @default_paging_options)
base_query =
from(a in Address,
where: a.fetched_coin_balance > ^0,
order_by: [desc: a.fetched_coin_balance, asc: a.hash],
preload: [:names],
select: {a, fragment("coalesce(1 + ?, 0)", a.nonce)},
limit: 250
select: {a, fragment("coalesce(1 + ?, 0)", a.nonce)}
)
Repo.all(query)
base_query
|> page_addresses(paging_options)
|> limit(^paging_options.page_size)
|> Repo.all()
end
@doc """
@ -2293,6 +2297,12 @@ defmodule Explorer.Chain do
end)
end
defp page_addresses(query, %PagingOptions{key: nil}), do: query
defp page_addresses(query, %PagingOptions{key: {coin_balance, hash}}) do
where(query, [address], address.fetched_coin_balance <= ^coin_balance and address.hash > ^hash)
end
defp page_blocks(query, %PagingOptions{key: nil}), do: query
defp page_blocks(query, %PagingOptions{key: {block_number}}) do

@ -1415,6 +1415,33 @@ defmodule Explorer.ChainTest do
|> Enum.map(fn {address, _transaction_count} -> address end)
|> Enum.map(& &1.hash)
end
test "paginates addresses" do
test_hashes =
4..0
|> Enum.map(&Explorer.Chain.Hash.cast(Explorer.Chain.Hash.Address, &1))
|> Enum.map(&elem(&1, 1))
result =
4..1
|> Enum.map(&insert(:address, fetched_coin_balance: &1, hash: Enum.fetch!(test_hashes, &1 - 1)))
|> Enum.map(& &1.hash)
options = [paging_options: %PagingOptions{page_size: 1}]
[{top_address, _}] = Chain.list_top_addresses(options)
assert top_address.hash == List.first(result)
tail_options = [
paging_options: %PagingOptions{key: {top_address.fetched_coin_balance.value, top_address.hash}, page_size: 3}
]
tail_result = tail_options |> Chain.list_top_addresses() |> Enum.map(fn {address, _} -> address.hash end)
[_ | expected_tail] = result
assert tail_result == expected_tail
end
end
describe "stream_blocks_without_rewards/2" do

Loading…
Cancel
Save