Merge pull request #4979 from blockscout/vb-save-gas-usage-in-db

Store total gas_used in addresses table
pull/4989/head
Victor Baranov 3 years ago committed by GitHub
commit 37d4de6f12
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 1
      CHANGELOG.md
  2. 19
      apps/block_scout_web/lib/block_scout_web/controllers/address_controller.ex
  3. 6
      apps/block_scout_web/lib/block_scout_web/templates/address/overview.html.eex
  4. 10
      apps/block_scout_web/priv/gettext/default.pot
  5. 10
      apps/block_scout_web/priv/gettext/en/LC_MESSAGES/default.po
  6. 8
      apps/explorer/lib/explorer/chain.ex
  7. 6
      apps/explorer/lib/explorer/chain/address.ex
  8. 20
      apps/explorer/lib/explorer/counters/address_gas_usage_counter.ex
  9. 10
      apps/explorer/lib/explorer/counters/address_token_transfers_counter.ex
  10. 10
      apps/explorer/lib/explorer/counters/address_transactions_counter.ex
  11. 10
      apps/explorer/lib/explorer/counters/token_holders_counter.ex
  12. 10
      apps/explorer/lib/explorer/counters/token_transfers_counter.ex
  13. 9
      apps/explorer/priv/repo/migrations/20211204184037_address_add_gas_used.exs
  14. 15
      apps/explorer/priv/repo/migrations/20211206071033_modify_address_gas_used_bigint.exs

@ -4,6 +4,7 @@
- [#4931](https://github.com/blockscout/blockscout/pull/4931) - Web3 modal with Wallet Connect for Write contract page and Staking Dapp
### Fixes
- [#4979](https://github.com/blockscout/blockscout/pull/4979) - Store total gas_used in addresses table
- [#4977](https://github.com/blockscout/blockscout/pull/4977) - Export token transfers on address: include transfers on contract itself
- [#4976](https://github.com/blockscout/blockscout/pull/4976) - Handle :econnrefused in pending transactions fetcher
- [#4965](https://github.com/blockscout/blockscout/pull/4965) - Fix search field appearance on medium size screens

@ -84,15 +84,14 @@ defmodule BlockScoutWeb.AddressController do
def address_counters(conn, %{"id" => address_hash_string}) do
with {:ok, address_hash} <- Chain.string_to_address_hash(address_hash_string),
{:ok, address} <- Chain.hash_to_address(address_hash) do
{transaction_count, token_transfer_count, gas_usage_count, validation_count, crc_total_worth} =
address_counters(address)
{transaction_count, token_transfer_count, validation_count, crc_total_worth} = address_counters(address)
gas_usage_count_formatted = if gas_usage_count, do: gas_usage_count, else: 0
address_gas_usage_from_db = address.gas_used || 0
json(conn, %{
transaction_count: transaction_count,
token_transfer_count: token_transfer_count,
gas_usage_count: gas_usage_count_formatted,
gas_usage_count: address_gas_usage_from_db,
validation_count: validation_count,
crc_total_worth: crc_total_worth
})
@ -119,11 +118,6 @@ defmodule BlockScoutWeb.AddressController do
token_transfers_count(address)
end)
gas_usage_count_task =
Task.async(fn ->
gas_usage_count(address)
end)
validation_count_task =
Task.async(fn ->
validation_count(address)
@ -134,14 +128,17 @@ defmodule BlockScoutWeb.AddressController do
crc_total_worth(address)
end)
Task.start_link(fn ->
gas_usage_count(address)
end)
[
transaction_count_task,
token_transfer_count_task,
gas_usage_count_task,
validation_count_task,
crc_total_worth_task
]
|> Task.yield_many(:timer.seconds(60))
|> Task.yield_many(:infinity)
|> Enum.map(fn {_task, res} ->
case res do
{:ok, result} ->

@ -242,7 +242,11 @@
</dt>
<dd class="col-sm-8 col-md-8 col-lg-9" data-test="address_gas_used">
<span data-selector="gas-usage-count">
<%= render BlockScoutWeb.CommonComponentsView, "_loading_spinner.html", loading_text: gettext("Fetching gas used...") %>
<%= if @address.gas_used do %>
<%= Number.Delimit.number_to_delimited(@address.gas_used, precision: 0) %>
<% else %>
<%= render BlockScoutWeb.CommonComponentsView, "_loading_spinner.html", loading_text: gettext("Fetching gas used...") %>
<% end %>
</span>
</dd>
</dl>

@ -398,7 +398,7 @@ msgid "Block number containing the transaction."
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address/overview.html.eex:254
#: lib/block_scout_web/templates/address/overview.html.eex:258
msgid "Block number in which the address was updated."
msgstr ""
@ -420,7 +420,7 @@ msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address/_tabs.html.eex:48
#: lib/block_scout_web/templates/address/overview.html.eex:271 lib/block_scout_web/templates/address_validation/index.html.eex:15
#: lib/block_scout_web/templates/address/overview.html.eex:275 lib/block_scout_web/templates/address_validation/index.html.eex:15
#: lib/block_scout_web/views/address_view.ex:356
msgid "Blocks Validated"
msgstr ""
@ -1151,7 +1151,7 @@ msgid "Favorites"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address/overview.html.eex:245
#: lib/block_scout_web/templates/address/overview.html.eex:248
msgid "Fetching gas used..."
msgstr ""
@ -1220,7 +1220,7 @@ msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address/overview.html.eex:240
#: lib/block_scout_web/templates/address/overview.html.eex:270
#: lib/block_scout_web/templates/address/overview.html.eex:274
msgid "Gas used by the address."
msgstr ""
@ -1377,7 +1377,7 @@ msgid "JSON RPC error"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address/overview.html.eex:255
#: lib/block_scout_web/templates/address/overview.html.eex:259
msgid "Last Balance Update"
msgstr ""

@ -398,7 +398,7 @@ msgid "Block number containing the transaction."
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address/overview.html.eex:254
#: lib/block_scout_web/templates/address/overview.html.eex:258
msgid "Block number in which the address was updated."
msgstr ""
@ -420,7 +420,7 @@ msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address/_tabs.html.eex:48
#: lib/block_scout_web/templates/address/overview.html.eex:271 lib/block_scout_web/templates/address_validation/index.html.eex:15
#: lib/block_scout_web/templates/address/overview.html.eex:275 lib/block_scout_web/templates/address_validation/index.html.eex:15
#: lib/block_scout_web/views/address_view.ex:356
msgid "Blocks Validated"
msgstr ""
@ -1151,7 +1151,7 @@ msgid "Favorites"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address/overview.html.eex:245
#: lib/block_scout_web/templates/address/overview.html.eex:248
msgid "Fetching gas used..."
msgstr ""
@ -1220,7 +1220,7 @@ msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address/overview.html.eex:240
#: lib/block_scout_web/templates/address/overview.html.eex:270
#: lib/block_scout_web/templates/address/overview.html.eex:274
msgid "Gas used by the address."
msgstr ""
@ -1377,7 +1377,7 @@ msgid "JSON RPC error"
msgstr ""
#, elixir-format
#: lib/block_scout_web/templates/address/overview.html.eex:255
#: lib/block_scout_web/templates/address/overview.html.eex:259
msgid "Last Balance Update"
msgstr ""

@ -867,7 +867,7 @@ defmodule Explorer.Chain do
Repo.aggregate(to_address_query, :count, :hash, timeout: :infinity)
end
@spec address_to_incoming_transaction_gas_usage(Hash.Address.t()) :: non_neg_integer()
@spec address_to_incoming_transaction_gas_usage(Hash.Address.t()) :: Decimal.t() | nil
def address_to_incoming_transaction_gas_usage(address_hash) do
to_address_query =
from(
@ -878,7 +878,7 @@ defmodule Explorer.Chain do
Repo.aggregate(to_address_query, :sum, :gas_used, timeout: :infinity)
end
@spec address_to_outcoming_transaction_gas_usage(Hash.Address.t()) :: non_neg_integer()
@spec address_to_outcoming_transaction_gas_usage(Hash.Address.t()) :: Decimal.t() | nil
def address_to_outcoming_transaction_gas_usage(address_hash) do
to_address_query =
from(
@ -2527,12 +2527,12 @@ defmodule Explorer.Chain do
Repo.aggregate(query, :count, timeout: :infinity)
end
@spec address_to_gas_usage_count(Address.t()) :: non_neg_integer()
@spec address_to_gas_usage_count(Address.t()) :: Decimal.t() | nil
def address_to_gas_usage_count(address) do
if contract?(address) do
incoming_transaction_gas_usage = address_to_incoming_transaction_gas_usage(address.hash)
if incoming_transaction_gas_usage == 0 do
if Decimal.cmp(incoming_transaction_gas_usage, 0) == :eq do
address_to_outcoming_transaction_gas_usage(address.hash)
else
incoming_transaction_gas_usage

@ -25,7 +25,7 @@ defmodule Explorer.Chain.Address do
alias Explorer.Chain.Cache.NetVersion
@optional_attrs ~w(contract_code fetched_coin_balance fetched_coin_balance_block_number nonce decompiled verified)a
@optional_attrs ~w(contract_code fetched_coin_balance fetched_coin_balance_block_number nonce decompiled verified gas_used)a
@required_attrs ~w(hash)a
@allowed_attrs @optional_attrs ++ @required_attrs
@ -58,7 +58,8 @@ defmodule Explorer.Chain.Address do
contracts_creation_transaction: %Ecto.Association.NotLoaded{} | Transaction.t(),
inserted_at: DateTime.t(),
updated_at: DateTime.t(),
nonce: non_neg_integer() | nil
nonce: non_neg_integer() | nil,
gas_used: non_neg_integer() | nil
}
@derive {Poison.Encoder,
@ -95,6 +96,7 @@ defmodule Explorer.Chain.Address do
field(:verified, :boolean, default: false)
field(:has_decompiled_code?, :boolean, virtual: true)
field(:stale?, :boolean, virtual: true)
field(:gas_used, :integer)
has_one(:smart_contract, SmartContract)
has_one(:token, Token, foreign_key: :contract_address_hash)

@ -4,7 +4,8 @@ defmodule Explorer.Counters.AddressTransactionsGasUsageCounter do
"""
use GenServer
alias Explorer.Chain
alias Ecto.Changeset
alias Explorer.{Chain, Repo}
@cache_name :address_transactions_gas_usage_counter
@last_update_key "last_update"
@ -16,7 +17,7 @@ defmodule Explorer.Counters.AddressTransactionsGasUsageCounter do
read_concurrency: true
]
config = Application.get_env(:explorer, Explorer.Counters.AddressTransactionsGasUsageCounter)
config = Application.get_env(:explorer, __MODULE__)
@enable_consolidation Keyword.get(config, :enable_consolidation)
@spec start_link(term()) :: GenServer.on_start()
@ -51,7 +52,7 @@ defmodule Explorer.Counters.AddressTransactionsGasUsageCounter do
update_cache(address)
end
address_hash_string = get_address_hash_string(address)
address_hash_string = to_string(address.hash)
fetch_from_cache("hash_#{address_hash_string}")
end
@ -59,7 +60,7 @@ defmodule Explorer.Counters.AddressTransactionsGasUsageCounter do
defp cache_expired?(address) do
cache_period = address_transactions_gas_usage_counter_cache_period()
address_hash_string = get_address_hash_string(address)
address_hash_string = to_string(address.hash)
updated_at = fetch_from_cache("hash_#{address_hash_string}_#{@last_update_key}")
cond do
@ -70,10 +71,11 @@ defmodule Explorer.Counters.AddressTransactionsGasUsageCounter do
end
defp update_cache(address) do
address_hash_string = get_address_hash_string(address)
address_hash_string = to_string(address.hash)
put_into_cache("hash_#{address_hash_string}_#{@last_update_key}", current_time())
new_data = Chain.address_to_gas_usage_count(address)
put_into_cache("hash_#{address_hash_string}", new_data)
put_into_db(address, new_data)
end
defp fetch_from_cache(key) do
@ -90,8 +92,12 @@ defmodule Explorer.Counters.AddressTransactionsGasUsageCounter do
:ets.insert(@cache_name, {key, value})
end
defp get_address_hash_string(address) do
Base.encode16(address.hash.bytes, case: :lower)
defp put_into_db(_address, value) when is_nil(value), do: :ignore
defp put_into_db(address, value) do
address
|> Changeset.change(%{gas_used: Decimal.to_integer(value)})
|> Repo.update()
end
defp current_time do

@ -51,7 +51,7 @@ defmodule Explorer.Counters.AddressTokenTransfersCounter do
update_cache(address)
end
address_hash_string = get_address_hash_string(address)
address_hash_string = to_string(address.hash)
fetch_from_cache("hash_#{address_hash_string}")
end
@ -59,7 +59,7 @@ defmodule Explorer.Counters.AddressTokenTransfersCounter do
defp cache_expired?(address) do
cache_period = address_token_transfers_counter_cache_period()
address_hash_string = get_address_hash_string(address)
address_hash_string = to_string(address.hash)
updated_at = fetch_from_cache("hash_#{address_hash_string}_#{@last_update_key}")
cond do
@ -70,7 +70,7 @@ defmodule Explorer.Counters.AddressTokenTransfersCounter do
end
defp update_cache(address) do
address_hash_string = get_address_hash_string(address)
address_hash_string = to_string(address.hash)
put_into_cache("hash_#{address_hash_string}_#{@last_update_key}", current_time())
new_data = Chain.address_to_token_transfer_count(address)
put_into_cache("hash_#{address_hash_string}", new_data)
@ -90,10 +90,6 @@ defmodule Explorer.Counters.AddressTokenTransfersCounter do
:ets.insert(@cache_name, {key, value})
end
defp get_address_hash_string(address) do
Base.encode16(address.hash.bytes, case: :lower)
end
defp current_time do
utc_now = DateTime.utc_now()

@ -51,7 +51,7 @@ defmodule Explorer.Counters.AddressTransactionsCounter do
update_cache(address)
end
address_hash_string = get_address_hash_string(address)
address_hash_string = to_string(address.hash)
fetch_from_cache("hash_#{address_hash_string}")
end
@ -59,7 +59,7 @@ defmodule Explorer.Counters.AddressTransactionsCounter do
defp cache_expired?(address) do
cache_period = address_transactions_counter_cache_period()
address_hash_string = get_address_hash_string(address)
address_hash_string = to_string(address.hash)
updated_at = fetch_from_cache("hash_#{address_hash_string}_#{@last_update_key}")
cond do
@ -70,7 +70,7 @@ defmodule Explorer.Counters.AddressTransactionsCounter do
end
defp update_cache(address) do
address_hash_string = get_address_hash_string(address)
address_hash_string = to_string(address.hash)
put_into_cache("hash_#{address_hash_string}_#{@last_update_key}", current_time())
new_data = Chain.address_to_transaction_count(address)
put_into_cache("hash_#{address_hash_string}", new_data)
@ -90,10 +90,6 @@ defmodule Explorer.Counters.AddressTransactionsCounter do
:ets.insert(@cache_name, {key, value})
end
defp get_address_hash_string(address) do
Base.encode16(address.hash.bytes, case: :lower)
end
defp current_time do
utc_now = DateTime.utc_now()

@ -53,7 +53,7 @@ defmodule Explorer.Counters.TokenHoldersCounter do
end)
end
address_hash_string = get_address_hash_string(address_hash)
address_hash_string = to_string(address_hash)
fetch_from_cache("hash_#{address_hash_string}")
end
@ -61,7 +61,7 @@ defmodule Explorer.Counters.TokenHoldersCounter do
defp cache_expired?(address_hash) do
cache_period = token_holders_counter_cache_period()
address_hash_string = get_address_hash_string(address_hash)
address_hash_string = to_string(address_hash)
updated_at = fetch_from_cache("hash_#{address_hash_string}_#{@last_update_key}")
cond do
@ -72,7 +72,7 @@ defmodule Explorer.Counters.TokenHoldersCounter do
end
defp update_cache(address_hash) do
address_hash_string = get_address_hash_string(address_hash)
address_hash_string = to_string(address_hash)
put_into_cache("hash_#{address_hash_string}_#{@last_update_key}", current_time())
new_data = Chain.count_token_holders_from_token_hash(address_hash)
put_into_cache("hash_#{address_hash_string}", new_data)
@ -92,10 +92,6 @@ defmodule Explorer.Counters.TokenHoldersCounter do
:ets.insert(@cache_name, {key, value})
end
defp get_address_hash_string(address_hash) do
Base.encode16(address_hash.bytes, case: :lower)
end
defp current_time do
utc_now = DateTime.utc_now()

@ -53,7 +53,7 @@ defmodule Explorer.Counters.TokenTransfersCounter do
end)
end
address_hash_string = get_address_hash_string(address_hash)
address_hash_string = to_string(address_hash)
fetch_from_cache("hash_#{address_hash_string}")
end
@ -61,7 +61,7 @@ defmodule Explorer.Counters.TokenTransfersCounter do
defp cache_expired?(address_hash) do
cache_period = token_transfers_counter_cache_period()
address_hash_string = get_address_hash_string(address_hash)
address_hash_string = to_string(address_hash)
updated_at = fetch_from_cache("hash_#{address_hash_string}_#{@last_update_key}")
cond do
@ -72,7 +72,7 @@ defmodule Explorer.Counters.TokenTransfersCounter do
end
defp update_cache(address_hash) do
address_hash_string = get_address_hash_string(address_hash)
address_hash_string = to_string(address_hash)
put_into_cache("hash_#{address_hash_string}_#{@last_update_key}", current_time())
new_data = Chain.count_token_transfers_from_token_hash(address_hash)
put_into_cache("hash_#{address_hash_string}", new_data)
@ -92,10 +92,6 @@ defmodule Explorer.Counters.TokenTransfersCounter do
:ets.insert(@cache_name, {key, value})
end
defp get_address_hash_string(address_hash) do
Base.encode16(address_hash.bytes, case: :lower)
end
defp current_time do
utc_now = DateTime.utc_now()

@ -0,0 +1,9 @@
defmodule Explorer.Repo.Migrations.AddressAddGasUsed do
use Ecto.Migration
def change do
alter table(:addresses) do
add(:gas_used, :integer, null: true)
end
end
end

@ -0,0 +1,15 @@
defmodule Explorer.Repo.Migrations.ModifyAddressGasUsedBignit do
use Ecto.Migration
def up do
alter table(:addresses) do
modify(:gas_used, :bigint)
end
end
def down do
alter table(:addresses) do
modify(:gas_used, :integer)
end
end
end
Loading…
Cancel
Save