From 8b46986c88d5895d07db36e4a6a20d31cb062437 Mon Sep 17 00:00:00 2001 From: zachdaniel Date: Thu, 14 Feb 2019 15:11:08 -0500 Subject: [PATCH 1/2] feat: show an approximation of transaction time --- .../templates/transaction/overview.html.eex | 14 ++++++ .../block_scout_web/views/transaction_view.ex | 49 ++++++++++++++++++- apps/block_scout_web/priv/gettext/default.pot | 47 ++++++++++-------- .../priv/gettext/en/LC_MESSAGES/default.po | 49 ++++++++++--------- .../views/transaction_view_test.exs | 48 ++++++++++++++++++ .../lib/explorer/chain/transaction.ex | 14 ++++-- .../average_block_time_duration_format.ex | 1 + ...liest_processing_start_to_transactions.exs | 9 ++++ .../indexer/pending_transaction/fetcher.ex | 18 +++++-- 9 files changed, 199 insertions(+), 50 deletions(-) create mode 100644 apps/explorer/priv/repo/migrations/20190213180502_add_earliest_processing_start_to_transactions.exs diff --git a/apps/block_scout_web/lib/block_scout_web/templates/transaction/overview.html.eex b/apps/block_scout_web/lib/block_scout_web/templates/transaction/overview.html.eex index 94d39e9d34..a22dabc755 100644 --- a/apps/block_scout_web/lib/block_scout_web/templates/transaction/overview.html.eex +++ b/apps/block_scout_web/lib/block_scout_web/templates/transaction/overview.html.eex @@ -74,6 +74,20 @@ <%= formatted_fee(@transaction, denomination: :ether) %> ( data-usd-exchange-rate=<%= @exchange_rate.usd_value %>>) + + <%= case processing_time_duration(@transaction) do %> + <% :pending -> %> + <% nil %> + <% :unknown -> %> + <% nil %> + <% {:ok, interval_string} -> %> +
+
<%= gettext "Transaction Speed" %>
+
+ <%= interval_string %> +
+
+ <% end %> <%= unless value_transfer?(@transaction) do %>
diff --git a/apps/block_scout_web/lib/block_scout_web/views/transaction_view.ex b/apps/block_scout_web/lib/block_scout_web/views/transaction_view.ex index f943e2b760..dd9a988b83 100644 --- a/apps/block_scout_web/lib/block_scout_web/views/transaction_view.ex +++ b/apps/block_scout_web/lib/block_scout_web/views/transaction_view.ex @@ -1,11 +1,12 @@ defmodule BlockScoutWeb.TransactionView do use BlockScoutWeb, :view + alias BlockScoutWeb.{AddressView, BlockView, TabHelpers} alias Cldr.Number alias Explorer.Chain alias Explorer.Chain.Block.Reward alias Explorer.Chain.{Address, Block, InternalTransaction, Transaction, Wei} - alias BlockScoutWeb.{AddressView, BlockView, TabHelpers} + alias Timex.Duration import BlockScoutWeb.Gettext @@ -29,6 +30,52 @@ defmodule BlockScoutWeb.TransactionView do 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 case block do nil -> diff --git a/apps/block_scout_web/priv/gettext/default.pot b/apps/block_scout_web/priv/gettext/default.pot index 8472653101..114e00bf53 100644 --- a/apps/block_scout_web/priv/gettext/default.pot +++ b/apps/block_scout_web/priv/gettext/default.pot @@ -49,7 +49,7 @@ msgid "%{subnetwork} Explorer - BlockScout" msgstr "" #, 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)" msgstr "" @@ -165,7 +165,7 @@ msgid "Block Number" msgstr "" #, elixir-format -#: lib/block_scout_web/views/transaction_view.ex:18 +#: lib/block_scout_web/views/transaction_view.ex:19 msgid "Block Pending" msgstr "" @@ -278,12 +278,12 @@ msgid "Contract Address Pending" msgstr "" #, elixir-format -#: lib/block_scout_web/views/transaction_view.ex:148 +#: lib/block_scout_web/views/transaction_view.ex:195 msgid "Contract Call" msgstr "" #, elixir-format -#: lib/block_scout_web/views/transaction_view.ex:147 +#: lib/block_scout_web/views/transaction_view.ex:194 msgid "Contract Creation" msgstr "" @@ -377,12 +377,12 @@ msgid "Error trying to fetch balances." msgstr "" #, elixir-format -#: lib/block_scout_web/views/transaction_view.ex:75 +#: lib/block_scout_web/views/transaction_view.ex:122 msgid "Error: %{reason}" msgstr "" #, 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)" msgstr "" @@ -392,7 +392,7 @@ msgstr "" #: 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/_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 msgid "Ether" msgstr "" @@ -431,7 +431,7 @@ msgid "GET" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/transaction/overview.html.eex:117 +#: lib/block_scout_web/templates/transaction/overview.html.eex:131 msgid "Gas" msgstr "" @@ -495,7 +495,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:270 -#: lib/block_scout_web/views/transaction_view.ex:201 +#: lib/block_scout_web/views/transaction_view.ex:248 msgid "Internal Transactions" msgstr "" @@ -513,7 +513,7 @@ msgid "Less than" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/transaction/overview.html.eex:129 +#: lib/block_scout_web/templates/transaction/overview.html.eex:143 msgid "Limit" 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:48 #: 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" msgstr "" @@ -533,7 +533,7 @@ msgid "Market Cap" msgstr "" #, elixir-format -#: lib/block_scout_web/views/transaction_view.ex:62 +#: lib/block_scout_web/views/transaction_view.ex:109 msgid "Max of" msgstr "" @@ -662,8 +662,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:70 -#: lib/block_scout_web/views/transaction_view.ex:104 +#: lib/block_scout_web/views/transaction_view.ex:117 +#: lib/block_scout_web/views/transaction_view.ex:151 msgid "Pending" msgstr "" @@ -768,7 +768,7 @@ msgstr "" #, elixir-format #: 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" msgstr "" @@ -879,7 +879,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:146 +#: lib/block_scout_web/views/transaction_view.ex:193 msgid "Token Transfer" msgstr "" @@ -891,7 +891,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:200 +#: lib/block_scout_web/views/transaction_view.ex:247 msgid "Token Transfers" msgstr "" @@ -932,7 +932,7 @@ msgid "Total transactions" msgstr "" #, elixir-format -#: lib/block_scout_web/views/transaction_view.ex:149 +#: lib/block_scout_web/views/transaction_view.ex:196 msgid "Transaction" msgstr "" @@ -999,7 +999,7 @@ msgid "Unique Token" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/transaction/overview.html.eex:122 +#: lib/block_scout_web/templates/transaction/overview.html.eex:136 msgid "Used" msgstr "" @@ -1020,7 +1020,7 @@ msgid "Validations" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/transaction/overview.html.eex:104 +#: lib/block_scout_web/templates/transaction/overview.html.eex:118 msgid "Value" msgstr "" @@ -1216,7 +1216,7 @@ msgid "This API is provided for developers transitioning their applications from msgstr "" #, 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" msgstr "" @@ -1637,3 +1637,8 @@ msgstr "" #: lib/block_scout_web/templates/address/overview.html.eex:41 msgid "Transactions Sent" msgstr "" + +#, elixir-format +#: lib/block_scout_web/templates/transaction/overview.html.eex:85 +msgid "Transaction Speed" +msgstr "" diff --git a/apps/block_scout_web/priv/gettext/en/LC_MESSAGES/default.po b/apps/block_scout_web/priv/gettext/en/LC_MESSAGES/default.po index 14ade55e6a..d010200547 100644 --- a/apps/block_scout_web/priv/gettext/en/LC_MESSAGES/default.po +++ b/apps/block_scout_web/priv/gettext/en/LC_MESSAGES/default.po @@ -49,7 +49,7 @@ msgid "%{subnetwork} Explorer - BlockScout" msgstr "" #, 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)" msgstr "" @@ -165,7 +165,7 @@ msgid "Block Number" msgstr "" #, elixir-format -#: lib/block_scout_web/views/transaction_view.ex:18 +#: lib/block_scout_web/views/transaction_view.ex:19 msgid "Block Pending" msgstr "" @@ -278,12 +278,12 @@ msgid "Contract Address Pending" msgstr "" #, elixir-format -#: lib/block_scout_web/views/transaction_view.ex:148 +#: lib/block_scout_web/views/transaction_view.ex:195 msgid "Contract Call" msgstr "" #, elixir-format -#: lib/block_scout_web/views/transaction_view.ex:147 +#: lib/block_scout_web/views/transaction_view.ex:194 msgid "Contract Creation" msgstr "" @@ -377,12 +377,12 @@ msgid "Error trying to fetch balances." msgstr "" #, elixir-format -#: lib/block_scout_web/views/transaction_view.ex:75 +#: lib/block_scout_web/views/transaction_view.ex:122 msgid "Error: %{reason}" msgstr "" #, 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)" msgstr "" @@ -392,7 +392,7 @@ msgstr "" #: 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/_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 msgid "Ether" msgstr "POA" @@ -431,7 +431,7 @@ msgid "GET" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/transaction/overview.html.eex:117 +#: lib/block_scout_web/templates/transaction/overview.html.eex:131 msgid "Gas" msgstr "" @@ -495,7 +495,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:270 -#: lib/block_scout_web/views/transaction_view.ex:201 +#: lib/block_scout_web/views/transaction_view.ex:248 msgid "Internal Transactions" msgstr "" @@ -513,7 +513,7 @@ msgid "Less than" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/transaction/overview.html.eex:129 +#: lib/block_scout_web/templates/transaction/overview.html.eex:143 msgid "Limit" 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:48 #: 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" msgstr "" @@ -533,7 +533,7 @@ msgid "Market Cap" msgstr "" #, elixir-format -#: lib/block_scout_web/views/transaction_view.ex:62 +#: lib/block_scout_web/views/transaction_view.ex:109 msgid "Max of" msgstr "" @@ -662,8 +662,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:70 -#: lib/block_scout_web/views/transaction_view.ex:104 +#: lib/block_scout_web/views/transaction_view.ex:117 +#: lib/block_scout_web/views/transaction_view.ex:151 msgid "Pending" msgstr "" @@ -768,7 +768,7 @@ msgstr "" #, elixir-format #: 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" msgstr "" @@ -879,7 +879,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:146 +#: lib/block_scout_web/views/transaction_view.ex:193 msgid "Token Transfer" msgstr "" @@ -891,7 +891,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:200 +#: lib/block_scout_web/views/transaction_view.ex:247 msgid "Token Transfers" msgstr "" @@ -932,7 +932,7 @@ msgid "Total transactions" msgstr "" #, elixir-format -#: lib/block_scout_web/views/transaction_view.ex:149 +#: lib/block_scout_web/views/transaction_view.ex:196 msgid "Transaction" msgstr "" @@ -999,7 +999,7 @@ msgid "Unique Token" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/transaction/overview.html.eex:122 +#: lib/block_scout_web/templates/transaction/overview.html.eex:136 msgid "Used" msgstr "" @@ -1020,7 +1020,7 @@ msgid "Validations" msgstr "" #, elixir-format -#: lib/block_scout_web/templates/transaction/overview.html.eex:104 +#: lib/block_scout_web/templates/transaction/overview.html.eex:118 msgid "Value" msgstr "" @@ -1216,7 +1216,7 @@ msgid "This API is provided for developers transitioning their applications from msgstr "" #, 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" msgstr "" @@ -1633,7 +1633,12 @@ msgstr "" msgid "Last Balance Update: Block #" msgstr "" -#, elixir-format, fuzzy +#, elixir-format #: lib/block_scout_web/templates/address/overview.html.eex:41 msgid "Transactions Sent" msgstr "" + +#, elixir-format, fuzzy +#: lib/block_scout_web/templates/transaction/overview.html.eex:85 +msgid "Transaction Speed" +msgstr "" diff --git a/apps/block_scout_web/test/block_scout_web/views/transaction_view_test.exs b/apps/block_scout_web/test/block_scout_web/views/transaction_view_test.exs index 52846bb057..d7320abfa8 100644 --- a/apps/block_scout_web/test/block_scout_web/views/transaction_view_test.exs +++ b/apps/block_scout_web/test/block_scout_web/views/transaction_view_test.exs @@ -47,6 +47,54 @@ defmodule BlockScoutWeb.TransactionViewTest do 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 test "returns 0 if pending transaction" do transaction = build(:transaction, block: nil) diff --git a/apps/explorer/lib/explorer/chain/transaction.ex b/apps/explorer/lib/explorer/chain/transaction.ex index 9f50aaeeb2..b9ed268c10 100644 --- a/apps/explorer/lib/explorer/chain/transaction.ex +++ b/apps/explorer/lib/explorer/chain/transaction.ex @@ -26,8 +26,10 @@ defmodule Explorer.Chain.Transaction do alias Explorer.Chain.Transaction.{Fork, Status} - @optional_attrs ~w(block_hash block_number created_contract_address_hash cumulative_gas_used error gas_used index - internal_transactions_indexed_at created_contract_code_indexed_at status to_address_hash)a + @optional_attrs ~w(block_hash block_number created_contract_address_hash cumulative_gas_used earliest_processing_start + 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 @typedoc """ @@ -80,7 +82,11 @@ defmodule Explorer.Chain.Transaction do * `created_contract_address_hash` - Denormalized `internal_transaction` `created_contract_address_hash` 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 - `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 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 @@ -132,6 +138,7 @@ defmodule Explorer.Chain.Transaction do created_contract_address_hash: Hash.Address.t() | nil, created_contract_code_indexed_at: DateTime.t() | nil, cumulative_gas_used: Gas.t() | nil, + earliest_processing_start: DateTime.t() | nil, error: String.t() | nil, forks: %Ecto.Association.NotLoaded{} | [Fork.t()], from_address: %Ecto.Association.NotLoaded{} | Address.t(), @@ -180,6 +187,7 @@ defmodule Explorer.Chain.Transaction do schema "transactions" do field(:block_number, :integer) field(:cumulative_gas_used, :decimal) + field(:earliest_processing_start, :utc_datetime_usec) field(:error, :string) field(:gas, :decimal) field(:gas_price, Wei) diff --git a/apps/explorer/lib/explorer/counters/average_block_time_duration_format.ex b/apps/explorer/lib/explorer/counters/average_block_time_duration_format.ex index 26536173df..84444cc5c3 100644 --- a/apps/explorer/lib/explorer/counters/average_block_time_duration_format.ex +++ b/apps/explorer/lib/explorer/counters/average_block_time_duration_format.ex @@ -67,6 +67,7 @@ defmodule Explorer.Counters.AverageBlockTimeDurationFormat do duration |> Duration.to_milliseconds() |> round() + |> abs() |> do_format(locale) end diff --git a/apps/explorer/priv/repo/migrations/20190213180502_add_earliest_processing_start_to_transactions.exs b/apps/explorer/priv/repo/migrations/20190213180502_add_earliest_processing_start_to_transactions.exs new file mode 100644 index 0000000000..cc895ae70b --- /dev/null +++ b/apps/explorer/priv/repo/migrations/20190213180502_add_earliest_processing_start_to_transactions.exs @@ -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 diff --git a/apps/indexer/lib/indexer/pending_transaction/fetcher.ex b/apps/indexer/lib/indexer/pending_transaction/fetcher.ex index 85844ae7f7..3c6e0dc620 100644 --- a/apps/indexer/lib/indexer/pending_transaction/fetcher.ex +++ b/apps/indexer/lib/indexer/pending_transaction/fetcher.ex @@ -22,6 +22,7 @@ defmodule Indexer.PendingTransaction.Fetcher do defstruct interval: @default_interval, json_rpc_named_arguments: [], + last_fetch_at: nil, task: nil def child_spec([init_arguments]) do @@ -84,10 +85,16 @@ defmodule Indexer.PendingTransaction.Fetcher do {:noreply, %PendingTransaction.Fetcher{state | task: task}} 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]) - {: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 def handle_info( @@ -109,10 +116,15 @@ defmodule Indexer.PendingTransaction.Fetcher do case fetch_pending_transactions(json_rpc_named_arguments) do {:ok, transactions_params} -> + new_last_fetched_at = NaiveDateTime.utc_now() + transactions_params + |> Stream.map(&Map.put(&1, :earliest_processing_start, new_last_fetched_at)) |> Stream.chunk_every(@chunk_size) |> Enum.each(&import_chunk/1) + {:ok, new_last_fetched_at} + :ignore -> :ok @@ -127,7 +139,7 @@ defmodule Indexer.PendingTransaction.Fetcher do 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 - # 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. case Chain.import(%{ addresses: %{params: addresses_params, on_conflict: :nothing}, From 3f17c1f6a5f2f72c51daa273689e3a59f5853ad6 Mon Sep 17 00:00:00 2001 From: zachdaniel Date: Wed, 20 Feb 2019 09:54:37 -0500 Subject: [PATCH 2/2] fix: add coin_balance_status to address_validations --- .../controllers/address_validation_controller.ex | 2 ++ 1 file changed, 2 insertions(+) diff --git a/apps/block_scout_web/lib/block_scout_web/controllers/address_validation_controller.ex b/apps/block_scout_web/lib/block_scout_web/controllers/address_validation_controller.ex index 031467feb7..87fb70ca40 100644 --- a/apps/block_scout_web/lib/block_scout_web/controllers/address_validation_controller.ex +++ b/apps/block_scout_web/lib/block_scout_web/controllers/address_validation_controller.ex @@ -12,6 +12,7 @@ defmodule BlockScoutWeb.AddressValidationController do alias BlockScoutWeb.BlockView alias Explorer.ExchangeRates.Token alias Explorer.{Chain, Market} + alias Indexer.CoinBalance.OnDemandFetcher alias Phoenix.View def index(conn, %{"address_id" => address_hash_string, "type" => "JSON"} = params) do @@ -75,6 +76,7 @@ defmodule BlockScoutWeb.AddressValidationController do conn, "index.html", address: address, + coin_balance_status: OnDemandFetcher.trigger_fetch(address), current_path: current_path(conn), transaction_count: transaction_count(address), validation_count: validation_count(address),