Merge branch 'master' into fix-transactions-validations-view

pull/1462/head
Andrew Cravenho 6 years ago committed by GitHub
commit 2becf032be
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 14
      apps/block_scout_web/lib/block_scout_web/templates/transaction/overview.html.eex
  2. 49
      apps/block_scout_web/lib/block_scout_web/views/transaction_view.ex
  3. 47
      apps/block_scout_web/priv/gettext/default.pot
  4. 49
      apps/block_scout_web/priv/gettext/en/LC_MESSAGES/default.po
  5. 48
      apps/block_scout_web/test/block_scout_web/views/transaction_view_test.exs
  6. 14
      apps/explorer/lib/explorer/chain/transaction.ex
  7. 1
      apps/explorer/lib/explorer/counters/average_block_time_duration_format.ex
  8. 9
      apps/explorer/priv/repo/migrations/20190213180502_add_earliest_processing_start_to_transactions.exs
  9. 18
      apps/indexer/lib/indexer/pending_transaction/fetcher.ex

@ -74,6 +74,20 @@
<%= formatted_fee(@transaction, denomination: :ether) %> (<span data-wei-value=<%= fee(@transaction) %> data-usd-exchange-rate=<%= @exchange_rate.usd_value %>></span>) <%= formatted_fee(@transaction, denomination: :ether) %> (<span data-wei-value=<%= fee(@transaction) %> data-usd-exchange-rate=<%= @exchange_rate.usd_value %>></span>)
</dd> </dd>
</dl> </dl>
<!-- Processing Time -->
<%= case processing_time_duration(@transaction) do %>
<% :pending -> %>
<% nil %>
<% :unknown -> %>
<% nil %>
<% {:ok, interval_string} -> %>
<dl class="row">
<dt class="col-sm-3 text-muted"> <%= gettext "Transaction Speed" %> </dt>
<dd class="col-sm-9">
<%= interval_string %>
</dd>
</dl>
<% end %>
<%= unless value_transfer?(@transaction) do %> <%= unless value_transfer?(@transaction) do %>
<dl class="row"> <dl class="row">

@ -1,11 +1,12 @@
defmodule BlockScoutWeb.TransactionView do defmodule BlockScoutWeb.TransactionView do
use BlockScoutWeb, :view use BlockScoutWeb, :view
alias BlockScoutWeb.{AddressView, BlockView, TabHelpers}
alias Cldr.Number alias Cldr.Number
alias Explorer.Chain alias Explorer.Chain
alias Explorer.Chain.Block.Reward alias Explorer.Chain.Block.Reward
alias Explorer.Chain.{Address, Block, InternalTransaction, Transaction, Wei} alias Explorer.Chain.{Address, Block, InternalTransaction, Transaction, Wei}
alias BlockScoutWeb.{AddressView, BlockView, TabHelpers} alias Timex.Duration
import BlockScoutWeb.Gettext import BlockScoutWeb.Gettext
@ -29,6 +30,52 @@ defmodule BlockScoutWeb.TransactionView do
def value_transfer?(_), do: false def value_transfer?(_), do: false
def processing_time_duration(%Transaction{block: nil}) do
:pending
end
def processing_time_duration(%Transaction{earliest_processing_start: nil}) do
:unknown
end
def processing_time_duration(%Transaction{
block: %Block{timestamp: end_time},
earliest_processing_start: earliest_processing_start,
inserted_at: inserted_at
}) do
with {:ok, long_interval} <- humanized_diff(earliest_processing_start, end_time),
{:ok, short_interval} <- humanized_diff(inserted_at, end_time) do
{:ok, merge_intervals(short_interval, long_interval)}
else
_ ->
:ignore
end
end
defp merge_intervals(short, long) when short == long, do: short
defp merge_intervals(short, long) do
[short_time, short_unit] = String.split(short, " ")
[long_time, long_unit] = String.split(long, " ")
if short_unit == long_unit do
short_time <> "-" <> long_time <> " " <> short_unit
else
short <> " - " <> long
end
end
defp humanized_diff(left, right) do
left
|> Timex.diff(right, :milliseconds)
|> Duration.from_milliseconds()
|> Timex.format_duration(Explorer.Counters.AverageBlockTimeDurationFormat)
|> case do
{:error, _} = error -> error
duration -> {:ok, duration}
end
end
def confirmations(%Transaction{block: block}, named_arguments) when is_list(named_arguments) do def confirmations(%Transaction{block: block}, named_arguments) when is_list(named_arguments) do
case block do case block do
nil -> nil ->

@ -49,7 +49,7 @@ msgid "%{subnetwork} Explorer - BlockScout"
msgstr "" msgstr ""
#, elixir-format #, elixir-format
#: lib/block_scout_web/views/transaction_view.ex:71 #: lib/block_scout_web/views/transaction_view.ex:118
msgid "(Awaiting internal transactions for status)" msgid "(Awaiting internal transactions for status)"
msgstr "" msgstr ""
@ -165,7 +165,7 @@ msgid "Block Number"
msgstr "" msgstr ""
#, elixir-format #, elixir-format
#: lib/block_scout_web/views/transaction_view.ex:18 #: lib/block_scout_web/views/transaction_view.ex:19
msgid "Block Pending" msgid "Block Pending"
msgstr "" msgstr ""
@ -278,12 +278,12 @@ msgid "Contract Address Pending"
msgstr "" msgstr ""
#, elixir-format #, elixir-format
#: lib/block_scout_web/views/transaction_view.ex:148 #: lib/block_scout_web/views/transaction_view.ex:195
msgid "Contract Call" msgid "Contract Call"
msgstr "" msgstr ""
#, elixir-format #, elixir-format
#: lib/block_scout_web/views/transaction_view.ex:147 #: lib/block_scout_web/views/transaction_view.ex:194
msgid "Contract Creation" msgid "Contract Creation"
msgstr "" msgstr ""
@ -377,12 +377,12 @@ msgid "Error trying to fetch balances."
msgstr "" msgstr ""
#, elixir-format #, elixir-format
#: lib/block_scout_web/views/transaction_view.ex:75 #: lib/block_scout_web/views/transaction_view.ex:122
msgid "Error: %{reason}" msgid "Error: %{reason}"
msgstr "" msgstr ""
#, elixir-format #, elixir-format
#: lib/block_scout_web/views/transaction_view.ex:73 #: lib/block_scout_web/views/transaction_view.ex:120
msgid "Error: (Awaiting internal transactions for reason)" msgid "Error: (Awaiting internal transactions for reason)"
msgstr "" msgstr ""
@ -392,7 +392,7 @@ msgstr ""
#: lib/block_scout_web/templates/layout/app.html.eex:51 #: lib/block_scout_web/templates/layout/app.html.eex:51
#: lib/block_scout_web/templates/transaction/_pending_tile.html.eex:19 #: lib/block_scout_web/templates/transaction/_pending_tile.html.eex:19
#: lib/block_scout_web/templates/transaction/_tile.html.eex:26 #: lib/block_scout_web/templates/transaction/_tile.html.eex:26
#: lib/block_scout_web/templates/transaction/overview.html.eex:104 #: lib/block_scout_web/templates/transaction/overview.html.eex:118
#: lib/block_scout_web/views/wei_helpers.ex:72 #: lib/block_scout_web/views/wei_helpers.ex:72
msgid "Ether" msgid "Ether"
msgstr "" msgstr ""
@ -431,7 +431,7 @@ msgid "GET"
msgstr "" msgstr ""
#, elixir-format #, elixir-format
#: lib/block_scout_web/templates/transaction/overview.html.eex:117 #: lib/block_scout_web/templates/transaction/overview.html.eex:131
msgid "Gas" msgid "Gas"
msgstr "" msgstr ""
@ -495,7 +495,7 @@ msgstr ""
#: lib/block_scout_web/templates/transaction/_tabs.html.eex:43 #: 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/templates/transaction_internal_transaction/index.html.eex:10
#: lib/block_scout_web/views/address_view.ex:270 #: lib/block_scout_web/views/address_view.ex:270
#: lib/block_scout_web/views/transaction_view.ex:201 #: lib/block_scout_web/views/transaction_view.ex:248
msgid "Internal Transactions" msgid "Internal Transactions"
msgstr "" msgstr ""
@ -513,7 +513,7 @@ msgid "Less than"
msgstr "" msgstr ""
#, elixir-format #, elixir-format
#: lib/block_scout_web/templates/transaction/overview.html.eex:129 #: lib/block_scout_web/templates/transaction/overview.html.eex:143
msgid "Limit" msgid "Limit"
msgstr "" msgstr ""
@ -521,7 +521,7 @@ msgstr ""
#: lib/block_scout_web/templates/transaction/_tabs.html.eex:21 #: 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/_tabs.html.eex:48
#: lib/block_scout_web/templates/transaction_log/index.html.eex:10 #: lib/block_scout_web/templates/transaction_log/index.html.eex:10
#: lib/block_scout_web/views/transaction_view.ex:202 #: lib/block_scout_web/views/transaction_view.ex:249
msgid "Logs" msgid "Logs"
msgstr "" msgstr ""
@ -533,7 +533,7 @@ msgid "Market Cap"
msgstr "" msgstr ""
#, elixir-format #, elixir-format
#: lib/block_scout_web/views/transaction_view.ex:62 #: lib/block_scout_web/views/transaction_view.ex:109
msgid "Max of" msgid "Max of"
msgstr "" msgstr ""
@ -662,8 +662,8 @@ msgstr ""
#, elixir-format #, elixir-format
#: lib/block_scout_web/templates/layout/_topnav.html.eex:44 #: lib/block_scout_web/templates/layout/_topnav.html.eex:44
#: lib/block_scout_web/templates/transaction/overview.html.eex:55 #: lib/block_scout_web/templates/transaction/overview.html.eex:55
#: lib/block_scout_web/views/transaction_view.ex:70 #: lib/block_scout_web/views/transaction_view.ex:117
#: lib/block_scout_web/views/transaction_view.ex:104 #: lib/block_scout_web/views/transaction_view.ex:151
msgid "Pending" msgid "Pending"
msgstr "" msgstr ""
@ -768,7 +768,7 @@ msgstr ""
#, elixir-format #, elixir-format
#: lib/block_scout_web/templates/transaction/_emission_reward_tile.html.eex:8 #: lib/block_scout_web/templates/transaction/_emission_reward_tile.html.eex:8
#: lib/block_scout_web/views/transaction_view.ex:72 #: lib/block_scout_web/views/transaction_view.ex:119
msgid "Success" msgid "Success"
msgstr "" msgstr ""
@ -879,7 +879,7 @@ msgstr ""
#, elixir-format #, elixir-format
#: lib/block_scout_web/templates/tokens/transfer/_token_transfer.html.eex:4 #: 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/templates/transaction_token_transfer/_token_transfer.html.eex:4
#: lib/block_scout_web/views/transaction_view.ex:146 #: lib/block_scout_web/views/transaction_view.ex:193
msgid "Token Transfer" msgid "Token Transfer"
msgstr "" msgstr ""
@ -891,7 +891,7 @@ msgstr ""
#: lib/block_scout_web/templates/transaction/_tabs.html.eex:36 #: 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/templates/transaction_token_transfer/index.html.eex:10
#: lib/block_scout_web/views/tokens/overview_view.ex:35 #: lib/block_scout_web/views/tokens/overview_view.ex:35
#: lib/block_scout_web/views/transaction_view.ex:200 #: lib/block_scout_web/views/transaction_view.ex:247
msgid "Token Transfers" msgid "Token Transfers"
msgstr "" msgstr ""
@ -932,7 +932,7 @@ msgid "Total transactions"
msgstr "" msgstr ""
#, elixir-format #, elixir-format
#: lib/block_scout_web/views/transaction_view.ex:149 #: lib/block_scout_web/views/transaction_view.ex:196
msgid "Transaction" msgid "Transaction"
msgstr "" msgstr ""
@ -999,7 +999,7 @@ msgid "Unique Token"
msgstr "" msgstr ""
#, elixir-format #, elixir-format
#: lib/block_scout_web/templates/transaction/overview.html.eex:122 #: lib/block_scout_web/templates/transaction/overview.html.eex:136
msgid "Used" msgid "Used"
msgstr "" msgstr ""
@ -1020,7 +1020,7 @@ msgid "Validations"
msgstr "" msgstr ""
#, elixir-format #, elixir-format
#: lib/block_scout_web/templates/transaction/overview.html.eex:104 #: lib/block_scout_web/templates/transaction/overview.html.eex:118
msgid "Value" msgid "Value"
msgstr "" msgstr ""
@ -1216,7 +1216,7 @@ msgid "This API is provided for developers transitioning their applications from
msgstr "" msgstr ""
#, elixir-format #, elixir-format
#: lib/block_scout_web/templates/transaction/overview.html.eex:80 #: lib/block_scout_web/templates/transaction/overview.html.eex:94
msgid "Raw Input" msgid "Raw Input"
msgstr "" msgstr ""
@ -1637,3 +1637,8 @@ msgstr ""
#: lib/block_scout_web/templates/address/overview.html.eex:41 #: lib/block_scout_web/templates/address/overview.html.eex:41
msgid "Transactions Sent" msgid "Transactions Sent"
msgstr "" msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/transaction/overview.html.eex:85
msgid "Transaction Speed"
msgstr ""

@ -49,7 +49,7 @@ msgid "%{subnetwork} Explorer - BlockScout"
msgstr "" msgstr ""
#, elixir-format #, elixir-format
#: lib/block_scout_web/views/transaction_view.ex:71 #: lib/block_scout_web/views/transaction_view.ex:118
msgid "(Awaiting internal transactions for status)" msgid "(Awaiting internal transactions for status)"
msgstr "" msgstr ""
@ -165,7 +165,7 @@ msgid "Block Number"
msgstr "" msgstr ""
#, elixir-format #, elixir-format
#: lib/block_scout_web/views/transaction_view.ex:18 #: lib/block_scout_web/views/transaction_view.ex:19
msgid "Block Pending" msgid "Block Pending"
msgstr "" msgstr ""
@ -278,12 +278,12 @@ msgid "Contract Address Pending"
msgstr "" msgstr ""
#, elixir-format #, elixir-format
#: lib/block_scout_web/views/transaction_view.ex:148 #: lib/block_scout_web/views/transaction_view.ex:195
msgid "Contract Call" msgid "Contract Call"
msgstr "" msgstr ""
#, elixir-format #, elixir-format
#: lib/block_scout_web/views/transaction_view.ex:147 #: lib/block_scout_web/views/transaction_view.ex:194
msgid "Contract Creation" msgid "Contract Creation"
msgstr "" msgstr ""
@ -377,12 +377,12 @@ msgid "Error trying to fetch balances."
msgstr "" msgstr ""
#, elixir-format #, elixir-format
#: lib/block_scout_web/views/transaction_view.ex:75 #: lib/block_scout_web/views/transaction_view.ex:122
msgid "Error: %{reason}" msgid "Error: %{reason}"
msgstr "" msgstr ""
#, elixir-format #, elixir-format
#: lib/block_scout_web/views/transaction_view.ex:73 #: lib/block_scout_web/views/transaction_view.ex:120
msgid "Error: (Awaiting internal transactions for reason)" msgid "Error: (Awaiting internal transactions for reason)"
msgstr "" msgstr ""
@ -392,7 +392,7 @@ msgstr ""
#: lib/block_scout_web/templates/layout/app.html.eex:51 #: lib/block_scout_web/templates/layout/app.html.eex:51
#: lib/block_scout_web/templates/transaction/_pending_tile.html.eex:19 #: lib/block_scout_web/templates/transaction/_pending_tile.html.eex:19
#: lib/block_scout_web/templates/transaction/_tile.html.eex:26 #: lib/block_scout_web/templates/transaction/_tile.html.eex:26
#: lib/block_scout_web/templates/transaction/overview.html.eex:104 #: lib/block_scout_web/templates/transaction/overview.html.eex:118
#: lib/block_scout_web/views/wei_helpers.ex:72 #: lib/block_scout_web/views/wei_helpers.ex:72
msgid "Ether" msgid "Ether"
msgstr "POA" msgstr "POA"
@ -431,7 +431,7 @@ msgid "GET"
msgstr "" msgstr ""
#, elixir-format #, elixir-format
#: lib/block_scout_web/templates/transaction/overview.html.eex:117 #: lib/block_scout_web/templates/transaction/overview.html.eex:131
msgid "Gas" msgid "Gas"
msgstr "" msgstr ""
@ -495,7 +495,7 @@ msgstr ""
#: lib/block_scout_web/templates/transaction/_tabs.html.eex:43 #: 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/templates/transaction_internal_transaction/index.html.eex:10
#: lib/block_scout_web/views/address_view.ex:270 #: lib/block_scout_web/views/address_view.ex:270
#: lib/block_scout_web/views/transaction_view.ex:201 #: lib/block_scout_web/views/transaction_view.ex:248
msgid "Internal Transactions" msgid "Internal Transactions"
msgstr "" msgstr ""
@ -513,7 +513,7 @@ msgid "Less than"
msgstr "" msgstr ""
#, elixir-format #, elixir-format
#: lib/block_scout_web/templates/transaction/overview.html.eex:129 #: lib/block_scout_web/templates/transaction/overview.html.eex:143
msgid "Limit" msgid "Limit"
msgstr "" msgstr ""
@ -521,7 +521,7 @@ msgstr ""
#: lib/block_scout_web/templates/transaction/_tabs.html.eex:21 #: 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/_tabs.html.eex:48
#: lib/block_scout_web/templates/transaction_log/index.html.eex:10 #: lib/block_scout_web/templates/transaction_log/index.html.eex:10
#: lib/block_scout_web/views/transaction_view.ex:202 #: lib/block_scout_web/views/transaction_view.ex:249
msgid "Logs" msgid "Logs"
msgstr "" msgstr ""
@ -533,7 +533,7 @@ msgid "Market Cap"
msgstr "" msgstr ""
#, elixir-format #, elixir-format
#: lib/block_scout_web/views/transaction_view.ex:62 #: lib/block_scout_web/views/transaction_view.ex:109
msgid "Max of" msgid "Max of"
msgstr "" msgstr ""
@ -662,8 +662,8 @@ msgstr ""
#, elixir-format #, elixir-format
#: lib/block_scout_web/templates/layout/_topnav.html.eex:44 #: lib/block_scout_web/templates/layout/_topnav.html.eex:44
#: lib/block_scout_web/templates/transaction/overview.html.eex:55 #: lib/block_scout_web/templates/transaction/overview.html.eex:55
#: lib/block_scout_web/views/transaction_view.ex:70 #: lib/block_scout_web/views/transaction_view.ex:117
#: lib/block_scout_web/views/transaction_view.ex:104 #: lib/block_scout_web/views/transaction_view.ex:151
msgid "Pending" msgid "Pending"
msgstr "" msgstr ""
@ -768,7 +768,7 @@ msgstr ""
#, elixir-format #, elixir-format
#: lib/block_scout_web/templates/transaction/_emission_reward_tile.html.eex:8 #: lib/block_scout_web/templates/transaction/_emission_reward_tile.html.eex:8
#: lib/block_scout_web/views/transaction_view.ex:72 #: lib/block_scout_web/views/transaction_view.ex:119
msgid "Success" msgid "Success"
msgstr "" msgstr ""
@ -879,7 +879,7 @@ msgstr ""
#, elixir-format #, elixir-format
#: lib/block_scout_web/templates/tokens/transfer/_token_transfer.html.eex:4 #: 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/templates/transaction_token_transfer/_token_transfer.html.eex:4
#: lib/block_scout_web/views/transaction_view.ex:146 #: lib/block_scout_web/views/transaction_view.ex:193
msgid "Token Transfer" msgid "Token Transfer"
msgstr "" msgstr ""
@ -891,7 +891,7 @@ msgstr ""
#: lib/block_scout_web/templates/transaction/_tabs.html.eex:36 #: 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/templates/transaction_token_transfer/index.html.eex:10
#: lib/block_scout_web/views/tokens/overview_view.ex:35 #: lib/block_scout_web/views/tokens/overview_view.ex:35
#: lib/block_scout_web/views/transaction_view.ex:200 #: lib/block_scout_web/views/transaction_view.ex:247
msgid "Token Transfers" msgid "Token Transfers"
msgstr "" msgstr ""
@ -932,7 +932,7 @@ msgid "Total transactions"
msgstr "" msgstr ""
#, elixir-format #, elixir-format
#: lib/block_scout_web/views/transaction_view.ex:149 #: lib/block_scout_web/views/transaction_view.ex:196
msgid "Transaction" msgid "Transaction"
msgstr "" msgstr ""
@ -999,7 +999,7 @@ msgid "Unique Token"
msgstr "" msgstr ""
#, elixir-format #, elixir-format
#: lib/block_scout_web/templates/transaction/overview.html.eex:122 #: lib/block_scout_web/templates/transaction/overview.html.eex:136
msgid "Used" msgid "Used"
msgstr "" msgstr ""
@ -1020,7 +1020,7 @@ msgid "Validations"
msgstr "" msgstr ""
#, elixir-format #, elixir-format
#: lib/block_scout_web/templates/transaction/overview.html.eex:104 #: lib/block_scout_web/templates/transaction/overview.html.eex:118
msgid "Value" msgid "Value"
msgstr "" msgstr ""
@ -1216,7 +1216,7 @@ msgid "This API is provided for developers transitioning their applications from
msgstr "" msgstr ""
#, elixir-format #, elixir-format
#: lib/block_scout_web/templates/transaction/overview.html.eex:80 #: lib/block_scout_web/templates/transaction/overview.html.eex:94
msgid "Raw Input" msgid "Raw Input"
msgstr "" msgstr ""
@ -1633,7 +1633,12 @@ msgstr ""
msgid "Last Balance Update: Block #" msgid "Last Balance Update: Block #"
msgstr "" msgstr ""
#, elixir-format, fuzzy #, elixir-format
#: lib/block_scout_web/templates/address/overview.html.eex:41 #: lib/block_scout_web/templates/address/overview.html.eex:41
msgid "Transactions Sent" msgid "Transactions Sent"
msgstr "" msgstr ""
#, elixir-format, fuzzy
#: lib/block_scout_web/templates/transaction/overview.html.eex:85
msgid "Transaction Speed"
msgstr ""

@ -47,6 +47,54 @@ defmodule BlockScoutWeb.TransactionViewTest do
end end
end end
describe "processing_time_duration/2" do
test "returns :pending if the transaction has no block" do
transaction = build(:transaction, block: nil)
assert TransactionView.processing_time_duration(transaction) == :pending
end
test "returns :unknown if the transaction has no `earliest_processing_start`" do
block = insert(:block)
transaction =
:transaction
|> insert(earliest_processing_start: nil)
|> with_block(block)
assert TransactionView.processing_time_duration(transaction) == :unknown
end
test "returns a single number when the timestamps are the same" do
now = Timex.now()
ten_seconds_ago = Timex.shift(now, seconds: -10)
block = insert(:block, timestamp: now)
transaction =
:transaction
|> insert(earliest_processing_start: ten_seconds_ago, inserted_at: ten_seconds_ago)
|> with_block(block)
assert TransactionView.processing_time_duration(transaction) == {:ok, "10 seconds"}
end
test "returns a range when the timestamps are not the same" do
now = Timex.now()
ten_seconds_ago = Timex.shift(now, seconds: -10)
five_seconds_ago = Timex.shift(now, seconds: -5)
block = insert(:block, timestamp: now)
transaction =
:transaction
|> insert(earliest_processing_start: ten_seconds_ago, inserted_at: five_seconds_ago)
|> with_block(block)
assert TransactionView.processing_time_duration(transaction) == {:ok, "5-10 seconds"}
end
end
describe "confirmations/2" do describe "confirmations/2" do
test "returns 0 if pending transaction" do test "returns 0 if pending transaction" do
transaction = build(:transaction, block: nil) transaction = build(:transaction, block: nil)

@ -26,8 +26,10 @@ defmodule Explorer.Chain.Transaction do
alias Explorer.Chain.Transaction.{Fork, Status} alias Explorer.Chain.Transaction.{Fork, Status}
@optional_attrs ~w(block_hash block_number created_contract_address_hash cumulative_gas_used error gas_used index @optional_attrs ~w(block_hash block_number created_contract_address_hash cumulative_gas_used earliest_processing_start
internal_transactions_indexed_at created_contract_code_indexed_at status to_address_hash)a error gas_used index internal_transactions_indexed_at created_contract_code_indexed_at status
to_address_hash)a
@required_attrs ~w(from_address_hash gas gas_price hash input nonce r s v value)a @required_attrs ~w(from_address_hash gas gas_price hash input nonce r s v value)a
@typedoc """ @typedoc """
@ -80,7 +82,11 @@ defmodule Explorer.Chain.Transaction do
* `created_contract_address_hash` - Denormalized `internal_transaction` `created_contract_address_hash` * `created_contract_address_hash` - Denormalized `internal_transaction` `created_contract_address_hash`
populated only when `to_address_hash` is nil. populated only when `to_address_hash` is nil.
* `cumulative_gas_used` - the cumulative gas used in `transaction`'s `t:Explorer.Chain.Block.t/0` before * `cumulative_gas_used` - the cumulative gas used in `transaction`'s `t:Explorer.Chain.Block.t/0` before
`transaction`'s `index`. `nil` when transaction is pending. `transaction`'s `index`. `nil` when transaction is pending
* `earliest_processing_start` - If the pending transaction fetcher was alive and received this transaction, we can
be sure that this transaction did not start processing until after the last time we fetched pending transactions,
so we annotate that with this field. If it is `nil`, that means we don't have a lower bound for when it started
processing.
* `error` - the `error` from the last `t:Explorer.Chain.InternalTransaction.t/0` in `internal_transactions` that * `error` - the `error` from the last `t:Explorer.Chain.InternalTransaction.t/0` in `internal_transactions` that
caused `status` to be `:error`. Only set after `internal_transactions_index_at` is set AND if there was an error. caused `status` to be `:error`. Only set after `internal_transactions_index_at` is set AND if there was an error.
Also, `error` is set if transaction is replaced/dropped Also, `error` is set if transaction is replaced/dropped
@ -132,6 +138,7 @@ defmodule Explorer.Chain.Transaction do
created_contract_address_hash: Hash.Address.t() | nil, created_contract_address_hash: Hash.Address.t() | nil,
created_contract_code_indexed_at: DateTime.t() | nil, created_contract_code_indexed_at: DateTime.t() | nil,
cumulative_gas_used: Gas.t() | nil, cumulative_gas_used: Gas.t() | nil,
earliest_processing_start: DateTime.t() | nil,
error: String.t() | nil, error: String.t() | nil,
forks: %Ecto.Association.NotLoaded{} | [Fork.t()], forks: %Ecto.Association.NotLoaded{} | [Fork.t()],
from_address: %Ecto.Association.NotLoaded{} | Address.t(), from_address: %Ecto.Association.NotLoaded{} | Address.t(),
@ -180,6 +187,7 @@ defmodule Explorer.Chain.Transaction do
schema "transactions" do schema "transactions" do
field(:block_number, :integer) field(:block_number, :integer)
field(:cumulative_gas_used, :decimal) field(:cumulative_gas_used, :decimal)
field(:earliest_processing_start, :utc_datetime_usec)
field(:error, :string) field(:error, :string)
field(:gas, :decimal) field(:gas, :decimal)
field(:gas_price, Wei) field(:gas_price, Wei)

@ -67,6 +67,7 @@ defmodule Explorer.Counters.AverageBlockTimeDurationFormat do
duration duration
|> Duration.to_milliseconds() |> Duration.to_milliseconds()
|> round() |> round()
|> abs()
|> do_format(locale) |> do_format(locale)
end end

@ -0,0 +1,9 @@
defmodule Explorer.Repo.Migrations.AddEarliestProcessingStartToTransactions do
use Ecto.Migration
def change do
alter table(:transactions) do
add(:earliest_processing_start, :utc_datetime_usec)
end
end
end

@ -22,6 +22,7 @@ defmodule Indexer.PendingTransaction.Fetcher do
defstruct interval: @default_interval, defstruct interval: @default_interval,
json_rpc_named_arguments: [], json_rpc_named_arguments: [],
last_fetch_at: nil,
task: nil task: nil
def child_spec([init_arguments]) do def child_spec([init_arguments]) do
@ -84,10 +85,16 @@ defmodule Indexer.PendingTransaction.Fetcher do
{:noreply, %PendingTransaction.Fetcher{state | task: task}} {:noreply, %PendingTransaction.Fetcher{state | task: task}}
end end
def handle_info({ref, _}, %PendingTransaction.Fetcher{task: %Task{ref: ref}} = state) do def handle_info({ref, result}, %PendingTransaction.Fetcher{task: %Task{ref: ref}} = state) do
Process.demonitor(ref, [:flush]) Process.demonitor(ref, [:flush])
{:noreply, schedule_fetch(state)} case result do
{:ok, new_last_fetch_at} ->
{:noreply, schedule_fetch(%{state | last_fetch_at: new_last_fetch_at})}
_ ->
{:noreply, schedule_fetch(state)}
end
end end
def handle_info( def handle_info(
@ -109,10 +116,15 @@ defmodule Indexer.PendingTransaction.Fetcher do
case fetch_pending_transactions(json_rpc_named_arguments) do case fetch_pending_transactions(json_rpc_named_arguments) do
{:ok, transactions_params} -> {:ok, transactions_params} ->
new_last_fetched_at = NaiveDateTime.utc_now()
transactions_params transactions_params
|> Stream.map(&Map.put(&1, :earliest_processing_start, new_last_fetched_at))
|> Stream.chunk_every(@chunk_size) |> Stream.chunk_every(@chunk_size)
|> Enum.each(&import_chunk/1) |> Enum.each(&import_chunk/1)
{:ok, new_last_fetched_at}
:ignore -> :ignore ->
:ok :ok
@ -127,7 +139,7 @@ defmodule Indexer.PendingTransaction.Fetcher do
addresses_params = AddressExtraction.extract_addresses(%{transactions: transactions_params}, pending: true) addresses_params = AddressExtraction.extract_addresses(%{transactions: transactions_params}, pending: true)
# There's no need to queue up fetching the address balance since theses are pending transactions and cannot have # There's no need to queue up fetching the address balance since theses are pending transactions and cannot have
# affected the address balance yet since address balance is a balance at a give block and these transactions are # affected the address balance yet since address balance is a balance at a given block and these transactions are
# blockless. # blockless.
case Chain.import(%{ case Chain.import(%{
addresses: %{params: addresses_params, on_conflict: :nothing}, addresses: %{params: addresses_params, on_conflict: :nothing},

Loading…
Cancel
Save