Separate usage of max consensus block number and block height

The block height should be used when calculating confirmations while
the max consensus block number when a block number is needed and you
want to tell if the chain is empty or only the genesis block is
available.  The block height is 0 if there are no blocks or if there is
only the genesis block.
pull/1332/head
Luke Imhoff 6 years ago
parent cb7bc384e8
commit 57808d6b23
  1. 2
      apps/block_scout_web/lib/block_scout_web/controllers/api/rpc/logs_controller.ex
  2. 11
      apps/block_scout_web/lib/block_scout_web/controllers/api/rpc/transaction_controller.ex
  3. 8
      apps/block_scout_web/lib/block_scout_web/controllers/block_transaction_controller.ex
  4. 11
      apps/block_scout_web/lib/block_scout_web/controllers/transaction_internal_transaction_controller.ex
  5. 9
      apps/block_scout_web/lib/block_scout_web/controllers/transaction_log_controller.ex
  6. 11
      apps/block_scout_web/lib/block_scout_web/controllers/transaction_token_transfer_controller.ex
  7. 2
      apps/block_scout_web/lib/block_scout_web/templates/transaction/overview.html.eex
  8. 8
      apps/block_scout_web/lib/block_scout_web/views/api/rpc/transaction_view.ex
  9. 8
      apps/block_scout_web/lib/block_scout_web/views/transaction_view.ex
  10. 28
      apps/block_scout_web/priv/gettext/default.pot
  11. 28
      apps/block_scout_web/priv/gettext/en/LC_MESSAGES/default.po
  12. 4
      apps/block_scout_web/test/block_scout_web/controllers/api/rpc/address_controller_test.exs
  13. 6
      apps/block_scout_web/test/block_scout_web/controllers/api/rpc/logs_controller_test.exs
  14. 2
      apps/block_scout_web/test/block_scout_web/controllers/api/rpc/transaction_controller_test.exs
  15. 2
      apps/block_scout_web/test/block_scout_web/views/transaction_view_test.exs
  16. 110
      apps/explorer/lib/explorer/chain.ex
  17. 12
      apps/explorer/lib/explorer/chain/supply/proof_of_authority.ex
  18. 12
      apps/explorer/lib/explorer/etherscan.ex
  19. 18
      apps/explorer/test/explorer/chain_test.exs
  20. 8
      apps/explorer/test/explorer/etherscan_test.exs
  21. 50
      apps/indexer/lib/indexer.ex

@ -183,7 +183,7 @@ defmodule BlockScoutWeb.API.RPC.LogsController do
defp to_block_number(params, param_key) do
case params[param_key] do
"latest" ->
Chain.consensus_block_number(:max)
Chain.max_consensus_block_number()
_ ->
to_integer(params, param_key)

@ -7,10 +7,8 @@ defmodule BlockScoutWeb.API.RPC.TransactionController do
with {:txhash_param, {:ok, txhash_param}} <- fetch_txhash(params),
{:format, {:ok, transaction_hash}} <- to_transaction_hash(txhash_param),
{:transaction, {:ok, transaction}} <- transaction_from_hash(transaction_hash) do
max_block_number = max_block_number()
logs = Chain.transaction_to_logs(transaction)
render(conn, :gettxinfo, %{transaction: transaction, max_block_number: max_block_number, logs: logs})
render(conn, :gettxinfo, %{transaction: transaction, block_height: Chain.block_height(), logs: logs})
else
{:transaction, :error} ->
render(conn, :error, error: "Transaction not found")
@ -81,11 +79,4 @@ defmodule BlockScoutWeb.API.RPC.TransactionController do
_ -> ""
end
end
defp max_block_number do
case Chain.consensus_block_number(:max) do
{:ok, number} -> number
{:error, :not_found} -> 0
end
end
end

@ -82,11 +82,7 @@ defmodule BlockScoutWeb.BlockTransactionController do
defp block_above_tip?("0x" <> _), do: nil
defp block_above_tip?(block_hash_or_number) when is_binary(block_hash_or_number) do
with {:ok, max_block_number} <- Chain.consensus_block_number(:max) do
{block_number, _} = Integer.parse(block_hash_or_number)
block_number > max_block_number
else
_ -> true
end
{block_number, ""} = Integer.parse(block_hash_or_number)
block_number > Chain.block_height()
end
end

@ -37,14 +37,12 @@ defmodule BlockScoutWeb.TransactionInternalTransactionController do
{internal_transactions, next_page} = split_list_by_page(internal_transactions_plus_one)
max_block_number = max_block_number()
render(
conn,
"index.html",
exchange_rate: Market.get_exchange_rate(Explorer.coin()) || Token.null(),
internal_transactions: internal_transactions,
max_block_number: max_block_number,
block_height: Chain.block_height(),
show_token_transfers: Chain.transaction_has_token_transfers?(hash),
next_page_params: next_page_params(next_page, internal_transactions, params),
transaction: transaction
@ -63,11 +61,4 @@ defmodule BlockScoutWeb.TransactionInternalTransactionController do
|> render("not_found.html", transaction_hash: hash_string)
end
end
defp max_block_number do
case Chain.consensus_block_number(:max) do
{:ok, number} -> number
{:error, :not_found} -> 0
end
end
end

@ -39,7 +39,7 @@ defmodule BlockScoutWeb.TransactionLogController do
conn,
"index.html",
logs: logs,
max_block_number: max_block_number(),
block_height: Chain.block_height(),
show_token_transfers: Chain.transaction_has_token_transfers?(transaction_hash),
next_page_params: next_page_params(next_page, logs, params),
transaction: transaction,
@ -59,11 +59,4 @@ defmodule BlockScoutWeb.TransactionLogController do
|> render("not_found.html", transaction_hash: transaction_hash_string)
end
end
defp max_block_number do
case Chain.consensus_block_number(:max) do
{:ok, number} -> number
{:error, :not_found} -> 0
end
end
end

@ -37,13 +37,11 @@ defmodule BlockScoutWeb.TransactionTokenTransferController do
{token_transfers, next_page} = split_list_by_page(token_transfers_plus_one)
max_block_number = max_block_number()
render(
conn,
"index.html",
exchange_rate: Market.get_exchange_rate(Explorer.coin()) || Token.null(),
max_block_number: max_block_number,
block_height: Chain.block_height(),
next_page_params: next_page_params(next_page, token_transfers, params),
token_transfers: token_transfers,
show_token_transfers: true,
@ -63,11 +61,4 @@ defmodule BlockScoutWeb.TransactionTokenTransferController do
|> render("not_found.html", transaction_hash: hash_string)
end
end
defp max_block_number do
case Chain.consensus_block_number(:max) do
{:ok, number} -> number
{:error, :not_found} -> 0
end
end
end

@ -59,7 +59,7 @@
<dl class="row">
<dt class="col-sm-3 text-muted"> <%= gettext "Block Confirmations" %> </dt>
<dd class="col-sm-9">
<span data-selector="block-confirmations"><%= confirmations(@transaction, max_block_number: @max_block_number) %></span>
<span data-selector="block-confirmations"><%= confirmations(@transaction, block_height: @block_height) %></span>
</dd>
</dl>
<!-- Nonce -->

@ -3,8 +3,8 @@ defmodule BlockScoutWeb.API.RPC.TransactionView do
alias BlockScoutWeb.API.RPC.RPCView
def render("gettxinfo.json", %{transaction: transaction, max_block_number: max_block_number, logs: logs}) do
data = prepare_transaction(transaction, max_block_number, logs)
def render("gettxinfo.json", %{transaction: transaction, block_height: block_height, logs: logs}) do
data = prepare_transaction(transaction, block_height, logs)
RPCView.render("show.json", data: data)
end
@ -50,12 +50,12 @@ defmodule BlockScoutWeb.API.RPC.TransactionView do
}
end
defp prepare_transaction(transaction, max_block_number, logs) do
defp prepare_transaction(transaction, block_height, logs) do
%{
"hash" => "#{transaction.hash}",
"timeStamp" => "#{DateTime.to_unix(transaction.block.timestamp)}",
"blockNumber" => "#{transaction.block_number}",
"confirmations" => "#{max_block_number - transaction.block_number}",
"confirmations" => "#{block_height - transaction.block_number}",
"success" => if(transaction.status == :ok, do: true, else: false),
"from" => "#{transaction.from_address_hash}",
"to" => "#{transaction.to_address_hash}",

@ -31,8 +31,12 @@ defmodule BlockScoutWeb.TransactionView do
def confirmations(%Transaction{block: block}, named_arguments) when is_list(named_arguments) do
case block do
nil -> 0
_ -> block |> Chain.confirmations(named_arguments) |> Cldr.Number.to_string!(format: "#,###")
nil ->
0
%Block{consensus: true} ->
{:ok, confirmations} = Chain.confirmations(block, named_arguments)
Cldr.Number.to_string!(confirmations, format: "#,###")
end
end

@ -49,7 +49,7 @@ msgid "%{subnetwork} Explorer - BlockScout"
msgstr ""
#, elixir-format
#: lib/block_scout_web/views/transaction_view.ex:67
#: lib/block_scout_web/views/transaction_view.ex:71
msgid "(Awaiting internal transactions for status)"
msgstr ""
@ -278,12 +278,12 @@ msgid "Contract Address Pending"
msgstr ""
#, elixir-format
#: lib/block_scout_web/views/transaction_view.ex:144
#: lib/block_scout_web/views/transaction_view.ex:148
msgid "Contract Call"
msgstr ""
#, elixir-format
#: lib/block_scout_web/views/transaction_view.ex:143
#: lib/block_scout_web/views/transaction_view.ex:147
msgid "Contract Creation"
msgstr ""
@ -389,12 +389,12 @@ msgid "Error trying to fetch balances."
msgstr ""
#, elixir-format
#: lib/block_scout_web/views/transaction_view.ex:71
#: lib/block_scout_web/views/transaction_view.ex:75
msgid "Error: %{reason}"
msgstr ""
#, elixir-format
#: lib/block_scout_web/views/transaction_view.ex:69
#: lib/block_scout_web/views/transaction_view.ex:73
msgid "Error: (Awaiting internal transactions for reason)"
msgstr ""
@ -507,7 +507,7 @@ msgstr ""
#: lib/block_scout_web/templates/transaction/_tabs.html.eex:43
#: lib/block_scout_web/templates/transaction_internal_transaction/index.html.eex:10
#: lib/block_scout_web/views/address_view.ex:254
#: lib/block_scout_web/views/transaction_view.ex:197
#: lib/block_scout_web/views/transaction_view.ex:201
msgid "Internal Transactions"
msgstr ""
@ -533,7 +533,7 @@ msgstr ""
#: lib/block_scout_web/templates/transaction/_tabs.html.eex:21
#: lib/block_scout_web/templates/transaction/_tabs.html.eex:48
#: lib/block_scout_web/templates/transaction_log/index.html.eex:10
#: lib/block_scout_web/views/transaction_view.ex:198
#: lib/block_scout_web/views/transaction_view.ex:202
msgid "Logs"
msgstr ""
@ -545,7 +545,7 @@ msgid "Market Cap"
msgstr ""
#, elixir-format
#: lib/block_scout_web/views/transaction_view.ex:58
#: lib/block_scout_web/views/transaction_view.ex:62
msgid "Max of"
msgstr ""
@ -684,8 +684,8 @@ msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/layout/_topnav.html.eex:44
#: lib/block_scout_web/templates/transaction/overview.html.eex:55
#: lib/block_scout_web/views/transaction_view.ex:66
#: lib/block_scout_web/views/transaction_view.ex:100
#: lib/block_scout_web/views/transaction_view.ex:70
#: lib/block_scout_web/views/transaction_view.ex:104
msgid "Pending"
msgstr ""
@ -790,7 +790,7 @@ msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/transaction/_emission_reward_tile.html.eex:8
#: lib/block_scout_web/views/transaction_view.ex:68
#: lib/block_scout_web/views/transaction_view.ex:72
msgid "Success"
msgstr ""
@ -901,7 +901,7 @@ msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/tokens/transfer/_token_transfer.html.eex:4
#: lib/block_scout_web/templates/transaction_token_transfer/_token_transfer.html.eex:4
#: lib/block_scout_web/views/transaction_view.ex:142
#: lib/block_scout_web/views/transaction_view.ex:146
msgid "Token Transfer"
msgstr ""
@ -913,7 +913,7 @@ msgstr ""
#: lib/block_scout_web/templates/transaction/_tabs.html.eex:36
#: lib/block_scout_web/templates/transaction_token_transfer/index.html.eex:10
#: lib/block_scout_web/views/tokens/overview_view.ex:35
#: lib/block_scout_web/views/transaction_view.ex:196
#: lib/block_scout_web/views/transaction_view.ex:200
msgid "Token Transfers"
msgstr ""
@ -954,7 +954,7 @@ msgid "Total transactions"
msgstr ""
#, elixir-format
#: lib/block_scout_web/views/transaction_view.ex:145
#: lib/block_scout_web/views/transaction_view.ex:149
msgid "Transaction"
msgstr ""

@ -49,7 +49,7 @@ msgid "%{subnetwork} Explorer - BlockScout"
msgstr ""
#, elixir-format
#: lib/block_scout_web/views/transaction_view.ex:67
#: lib/block_scout_web/views/transaction_view.ex:71
msgid "(Awaiting internal transactions for status)"
msgstr ""
@ -278,12 +278,12 @@ msgid "Contract Address Pending"
msgstr ""
#, elixir-format
#: lib/block_scout_web/views/transaction_view.ex:144
#: lib/block_scout_web/views/transaction_view.ex:148
msgid "Contract Call"
msgstr ""
#, elixir-format
#: lib/block_scout_web/views/transaction_view.ex:143
#: lib/block_scout_web/views/transaction_view.ex:147
msgid "Contract Creation"
msgstr ""
@ -389,12 +389,12 @@ msgid "Error trying to fetch balances."
msgstr ""
#, elixir-format
#: lib/block_scout_web/views/transaction_view.ex:71
#: lib/block_scout_web/views/transaction_view.ex:75
msgid "Error: %{reason}"
msgstr ""
#, elixir-format
#: lib/block_scout_web/views/transaction_view.ex:69
#: lib/block_scout_web/views/transaction_view.ex:73
msgid "Error: (Awaiting internal transactions for reason)"
msgstr ""
@ -507,7 +507,7 @@ msgstr ""
#: lib/block_scout_web/templates/transaction/_tabs.html.eex:43
#: lib/block_scout_web/templates/transaction_internal_transaction/index.html.eex:10
#: lib/block_scout_web/views/address_view.ex:254
#: lib/block_scout_web/views/transaction_view.ex:197
#: lib/block_scout_web/views/transaction_view.ex:201
msgid "Internal Transactions"
msgstr ""
@ -533,7 +533,7 @@ msgstr ""
#: lib/block_scout_web/templates/transaction/_tabs.html.eex:21
#: lib/block_scout_web/templates/transaction/_tabs.html.eex:48
#: lib/block_scout_web/templates/transaction_log/index.html.eex:10
#: lib/block_scout_web/views/transaction_view.ex:198
#: lib/block_scout_web/views/transaction_view.ex:202
msgid "Logs"
msgstr ""
@ -545,7 +545,7 @@ msgid "Market Cap"
msgstr ""
#, elixir-format
#: lib/block_scout_web/views/transaction_view.ex:58
#: lib/block_scout_web/views/transaction_view.ex:62
msgid "Max of"
msgstr ""
@ -684,8 +684,8 @@ msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/layout/_topnav.html.eex:44
#: lib/block_scout_web/templates/transaction/overview.html.eex:55
#: lib/block_scout_web/views/transaction_view.ex:66
#: lib/block_scout_web/views/transaction_view.ex:100
#: lib/block_scout_web/views/transaction_view.ex:70
#: lib/block_scout_web/views/transaction_view.ex:104
msgid "Pending"
msgstr ""
@ -790,7 +790,7 @@ msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/transaction/_emission_reward_tile.html.eex:8
#: lib/block_scout_web/views/transaction_view.ex:68
#: lib/block_scout_web/views/transaction_view.ex:72
msgid "Success"
msgstr ""
@ -901,7 +901,7 @@ msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/tokens/transfer/_token_transfer.html.eex:4
#: lib/block_scout_web/templates/transaction_token_transfer/_token_transfer.html.eex:4
#: lib/block_scout_web/views/transaction_view.ex:142
#: lib/block_scout_web/views/transaction_view.ex:146
msgid "Token Transfer"
msgstr ""
@ -913,7 +913,7 @@ msgstr ""
#: lib/block_scout_web/templates/transaction/_tabs.html.eex:36
#: lib/block_scout_web/templates/transaction_token_transfer/index.html.eex:10
#: lib/block_scout_web/views/tokens/overview_view.ex:35
#: lib/block_scout_web/views/transaction_view.ex:196
#: lib/block_scout_web/views/transaction_view.ex:200
msgid "Token Transfers"
msgstr ""
@ -954,7 +954,7 @@ msgid "Total transactions"
msgstr ""
#, elixir-format
#: lib/block_scout_web/views/transaction_view.ex:145
#: lib/block_scout_web/views/transaction_view.ex:149
msgid "Transaction"
msgstr ""

@ -436,8 +436,8 @@ defmodule BlockScoutWeb.API.RPC.AddressControllerTest do
"address" => "#{address.hash}"
}
{:ok, max_block_number} = Chain.max_block_number()
expected_confirmations = max_block_number - transaction.block_number
block_height = Chain.block_height()
expected_confirmations = block_height - transaction.block_number
assert %{"result" => [returned_transaction]} =
conn

@ -741,11 +741,11 @@ defmodule BlockScoutWeb.API.RPC.LogsControllerTest do
# We insert a block, try again, and assert 'latest' points to the latest
# block number.
insert(:block)
{:ok, max_block_number} = Explorer.Chain.max_block_number()
{:ok, max_consensus_block_number} = Explorer.Chain.max_consensus_block_number()
assert {_, {:ok, validated_params}} = LogsController.to_valid_format(params)
assert validated_params.from_block == max_block_number
assert validated_params.to_block == max_block_number
assert validated_params.from_block == max_consensus_block_number
assert validated_params.to_block == max_consensus_block_number
end
end

@ -1,6 +1,8 @@
defmodule BlockScoutWeb.API.RPC.TransactionControllerTest do
use BlockScoutWeb.ConnCase
@moduletag capture_log: true
describe "gettxreceiptstatus" do
test "with missing txhash", %{conn: conn} do
params = %{

@ -62,7 +62,7 @@ defmodule BlockScoutWeb.TransactionViewTest do
|> insert()
|> with_block(block)
assert "1" == TransactionView.confirmations(transaction, max_block_number: block.number + 1)
assert "1" == TransactionView.confirmations(transaction, block_height: block.number + 1)
end
end

@ -52,6 +52,11 @@ defmodule Explorer.Chain do
"""
@type association :: atom()
@typedoc """
The max `t:Explorer.Chain.Block.block_number/0` for `consensus` `true` `t:Explorer.Chain.Block.t/0`s.
"""
@type block_height :: Block.block_number()
@typedoc """
Event type where data is broadcasted whenever data is inserted from chain indexing.
"""
@ -415,14 +420,48 @@ defmodule Explorer.Chain do
@doc """
How many blocks have confirmed `block` based on the current `max_block_number`
A consensus block's number of confirmations is the difference between its number and the current block height.
iex> block = insert(:block, number: 1)
iex> Explorer.Chain.confirmations(block, block_height: 2)
{:ok, 1}
The newest block at the block height has no confirmations.
iex> block = insert(:block, number: 1)
iex> Explorer.Chain.confirmations(block, block_height: 1)
{:ok, 0}
A non-consensus block has no confirmations and is orphaned even if there are child blocks of it on an orphaned chain.
iex> parent_block = insert(:block, consensus: false, number: 1)
iex> insert(
...> :block,
...> parent_hash: parent_block.hash,
...> consensus: false,
...> number: parent_block.number + 1
...> )
iex> Explorer.Chain.confirmations(parent_block, block_height: 3)
{:error, :non_consensus}
If you calculate the block height and then get a newer block, the confirmations will be `0` instead of negative.
iex> block = insert(:block, number: 1)
iex> Explorer.Chain.confirmations(block, block_height: 0)
{:ok, 0}
"""
@spec confirmations(Block.t(), [{:max_block_number, Block.block_number()}]) :: non_neg_integer()
def confirmations(%Block{number: number}, named_arguments) when is_list(named_arguments) do
max_block_number = Keyword.fetch!(named_arguments, :max_block_number)
@spec confirmations(Block.t(), [{:block_height, block_height()}]) ::
{:ok, non_neg_integer()} | {:error, :non_consensus}
def confirmations(%Block{consensus: true, number: number}, named_arguments) when is_list(named_arguments) do
max_consensus_block_number = Keyword.fetch!(named_arguments, :block_height)
max_block_number - number
{:ok, max(max_consensus_block_number - number, 0)}
end
def confirmations(%Block{consensus: false}, _), do: {:error, :non_consensus}
@doc """
Creates an address.
@ -1164,45 +1203,80 @@ defmodule Explorer.Chain do
end
@doc """
Aggregate of consensus block numbers.
Max consensus block numbers.
If blocks are skipped and inserted out of number order, the `:max` and `:min` numbers are still returned
If blocks are skipped and inserted out of number order, the max number is still returned
iex> insert(:block, number: 2)
iex> insert(:block, number: 1)
iex> Explorer.Chain.consensus_block_number(:min)
{:ok, 1}
iex> Explorer.Chain.consensus_block_number(:max)
iex> Explorer.Chain.max_consensus_block_number()
{:ok, 2}
Non-consensus blocks are ignored
iex> insert(:block, number: 3, consensus: false)
iex> insert(:block, number: 2, consensus: true)
iex> insert(:block, number: 1, consensus: false)
iex> Explorer.Chain.consensus_block_number(:min)
{:ok, 2}
iex> Explorer.Chain.consensus_block_number(:max)
iex> Explorer.Chain.max_consensus_block_number()
{:ok, 2}
If there are no blocks, `{:error, :not_found}` is returned
iex> Explorer.Chain.consensus_block_number(:min)
{:error, :not_found}
iex> Explorer.Chain.consensus_block_number(:max)
iex> Explorer.Chain.max_consensus_block_number()
{:error, :not_found}
"""
def consensus_block_number(aggregate) do
@spec max_consensus_block_number() :: {:ok, Block.block_number()} | {:error, :not_found}
def max_consensus_block_number do
Block
|> where(consensus: true)
|> Repo.aggregate(aggregate, :number)
|> Repo.aggregate(:max, :number)
|> case do
nil -> {:error, :not_found}
number -> {:ok, number}
end
end
@doc """
The height of the chain.
iex> insert(:block, number: 0)
iex> Explorer.Chain.block_height()
0
iex> insert(:block, number: 1)
iex> Explorer.Chain.block_height()
1
If there are no blocks, then the `t:block_height/0` is `0`, unlike `max_consensus_block_chain/0` where it is not found.
iex> Explorer.Chain.block_height()
0
iex> Explorer.Chain.max_consensus_block_number()
{:error, :not_found}
It is not possible to differentiate only the genesis block (`number` `0`) and no blocks. Use
`max_consensus_block_chain/0` if you need to differentiate those two scenarios.
iex> Explorer.Chain.block_height()
0
iex> insert(:block, number: 0)
iex> Explorer.Chain.block_height()
0
Non-consensus blocks are ignored.
iex> insert(:block, number: 2, consensus: false)
iex> insert(:block, number: 1, consensus: true)
iex> Explorer.Chain.block_height()
1
"""
@spec block_height() :: block_height()
def block_height do
query = from(block in Block, select: coalesce(max(block.number), 0), where: block.consensus == true)
Repo.one!(query)
end
@doc """
Calculates the ranges of missing consensus blocks in `range`.

@ -34,17 +34,7 @@ defmodule Explorer.Chain.Supply.ProofOfAuthority do
end
def total do
initial_supply = initial_supply()
block_height = block_height()
initial_supply + block_height
end
defp block_height do
case Chain.consensus_block_number(:max) do
{:ok, height} -> height
_ -> 0
end
initial_supply() + Chain.block_height()
end
@doc false

@ -43,7 +43,7 @@ defmodule Explorer.Etherscan do
%Hash{byte_count: unquote(Hash.Address.byte_count())} = address_hash,
options \\ @default_options
) do
case Chain.consensus_block_number(:max) do
case Chain.max_consensus_block_number() do
{:ok, max_block_number} ->
merged_options = Map.merge(@default_options, options)
list_transactions(address_hash, max_block_number, merged_options)
@ -152,10 +152,10 @@ defmodule Explorer.Etherscan do
contract_address_hash,
options \\ @default_options
) do
case Chain.consensus_block_number(:max) do
{:ok, max_block_number} ->
case Chain.max_consensus_block_number() do
{:ok, block_height} ->
merged_options = Map.merge(@default_options, options)
list_token_transfers(address_hash, contract_address_hash, max_block_number, merged_options)
list_token_transfers(address_hash, contract_address_hash, block_height, merged_options)
_ ->
[]
@ -319,7 +319,7 @@ defmodule Explorer.Etherscan do
amount
)a
defp list_token_transfers(address_hash, contract_address_hash, max_block_number, options) do
defp list_token_transfers(address_hash, contract_address_hash, block_height, options) do
query =
from(
t in Transaction,
@ -343,7 +343,7 @@ defmodule Explorer.Etherscan do
block_hash: b.hash,
block_number: b.number,
block_timestamp: b.timestamp,
confirmations: fragment("? - ?", ^max_block_number, t.block_number),
confirmations: fragment("? - ?", ^block_height, t.block_number),
token_id: tt.token_id,
token_name: tkn.name,
token_symbol: tkn.symbol,

@ -592,21 +592,21 @@ defmodule Explorer.ChainTest do
end
describe "confirmations/1" do
test "with block.number == max_block_number " do
test "with block.number == block_height " do
block = insert(:block)
{:ok, max_block_number} = Chain.consensus_block_number(:max)
block_height = Chain.block_height()
assert block.number == max_block_number
assert Chain.confirmations(block, max_block_number: max_block_number) == 0
assert block.number == block_height
assert {:ok, 0} = Chain.confirmations(block, block_height: block_height)
end
test "with block.number < max_block_number" do
test "with block.number < block_height" do
block = insert(:block)
max_block_number = block.number + 2
block_height = block.number + 2
assert block.number < max_block_number
assert Chain.confirmations(block, max_block_number: max_block_number) == max_block_number - block.number
assert block.number < block_height
assert {:ok, confirmations} = Chain.confirmations(block, block_height: block_height)
assert confirmations == block_height - block.number
end
end

@ -122,8 +122,8 @@ defmodule Explorer.EtherscanTest do
[found_transaction] = Etherscan.list_transactions(address.hash)
{:ok, max_block_number} = Chain.consensus_block_number(:max)
expected_confirmations = max_block_number - transaction.block_number
block_height = Chain.block_height()
expected_confirmations = block_height - transaction.block_number
assert found_transaction.confirmations == expected_confirmations
end
@ -888,8 +888,8 @@ defmodule Explorer.EtherscanTest do
[found_token_transfer] = Etherscan.list_token_transfers(token_transfer.from_address_hash, nil)
{:ok, max_block_number} = Chain.consensus_block_number(:max)
expected_confirmations = max_block_number - transaction.block_number
block_height = Chain.block_height()
expected_confirmations = block_height - transaction.block_number
assert found_token_transfer.confirmations == expected_confirmations
end

@ -2,54 +2,4 @@ defmodule Indexer do
@moduledoc """
Indexes an Ethereum-based chain using JSONRPC.
"""
alias Explorer.Chain
@doc """
The maximum `t:Explorer.Chain.Block.t/0` `number` that was indexed
If blocks are skipped and inserted out of number order, the max number is still returned
iex> insert(:block, number: 2)
iex> insert(:block, number: 1)
iex> Indexer.max_block_number()
2
If there are no blocks, `0` is returned to indicate to index from genesis block.
iex> Indexer.max_block_number()
0
"""
def max_block_number do
case Chain.consensus_block_number(:max) do
{:ok, number} -> number
{:error, :not_found} -> 0
end
end
@doc """
The next `t:Explorer.Chain.Block.t/0` `number` that needs to be indexed (excluding skipped blocks)
When there are no blocks the next block is the 0th block
iex> Indexer.max_block_number()
0
iex> Indexer.next_block_number()
0
When there is a block, it is the successive block number
iex> insert(:block, number: 2)
iex> insert(:block, number: 1)
iex> Indexer.next_block_number()
3
"""
def next_block_number do
case max_block_number() do
0 -> 0
num -> num + 1
end
end
end

Loading…
Cancel
Save