Skip to content

Commit

Permalink
chore: OP modules improvements (blockscout#11073)
Browse files Browse the repository at this point in the history
* Add new envs for OP stack

* Fix updating logs filter in OP Deposits fetcher

* Add fallback envs for OP

* Add socket notifier for OP batches

* Update common-blockscout.env

* Set infinity timeout for select db queries

* Support transactions without `to` field

* Add some docs

* mix format

* Restore OP fetcher after reorg and restart

* Add specs and docs

* Fix spelling

* Refactoring and hardcode INDEXER_BEACON_BLOB_FETCHER_* envs

* mix format

* Update spelling

* Small fix for Indexer.Fetcher.Optimism.Deposit

* Rewrite Indexer.Fetcher.Optimism.Deposit

* Update common-blockscout.env

* Add todo comments for deprecated socket topic

* Fix for the new websocket channel

* Add todo comment

---------

Co-authored-by: POA <[email protected]>
  • Loading branch information
2 people authored and kyonRay committed Dec 25, 2024
1 parent c03f9d9 commit d0e1b6f
Show file tree
Hide file tree
Showing 30 changed files with 1,020 additions and 703 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
defmodule BlockScoutWeb.OptimismChannel do
@moduledoc """
Establishes pub/sub channel for live updates of OP related events.
"""
use BlockScoutWeb, :channel

def join("optimism:new_batch", _params, socket) do
{:ok, %{}, socket}
end

def join("optimism:new_deposits", _params, socket) do
{:ok, %{}, socket}
end

# todo: the `optimism_deposits:new_deposits` socket topic is for backward compatibility
# for the frontend and should be removed after the frontend starts to use the `optimism:new_deposits`
def join("optimism_deposits:new_deposits", _params, socket) do
{:ok, %{}, socket}
end
end

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ defmodule BlockScoutWeb.UserSocket do
channel("addresses:*", BlockScoutWeb.AddressChannel)
channel("blocks:*", BlockScoutWeb.BlockChannel)
channel("exchange_rate:*", BlockScoutWeb.ExchangeRateChannel)
channel("optimism_deposits:*", BlockScoutWeb.OptimismDepositChannel)
channel("rewards:*", BlockScoutWeb.RewardChannel)
channel("transactions:*", BlockScoutWeb.TransactionChannel)
channel("tokens:*", BlockScoutWeb.TokenChannel)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ defmodule BlockScoutWeb.UserSocketV2 do
channel("addresses:*", BlockScoutWeb.AddressChannel)
channel("blocks:*", BlockScoutWeb.BlockChannel)
channel("exchange_rate:*", BlockScoutWeb.ExchangeRateChannel)
channel("optimism_deposits:*", BlockScoutWeb.OptimismDepositChannel)
channel("rewards:*", BlockScoutWeb.RewardChannel)
channel("transactions:*", BlockScoutWeb.TransactionChannel)
channel("tokens:*", BlockScoutWeb.TokenChannel)
Expand All @@ -16,6 +15,8 @@ defmodule BlockScoutWeb.UserSocketV2 do

case Application.compile_env(:explorer, :chain_type) do
:arbitrum -> channel("arbitrum:*", BlockScoutWeb.ArbitrumChannel)
# todo: change `optimism*"` to `optimism:*` after the deprecated `optimism_deposits:new_deposits` topic is removed
:optimism -> channel("optimism*", BlockScoutWeb.OptimismChannel)
_ -> nil
end

Expand Down
16 changes: 8 additions & 8 deletions apps/block_scout_web/lib/block_scout_web/notifier.ex
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ defmodule BlockScoutWeb.Notifier do
:arbitrum ->
@chain_type_specific_events ~w(new_arbitrum_batches new_messages_to_arbitrum_amount)a

:optimism ->
@chain_type_specific_events ~w(new_optimism_batches new_optimism_deposits)a

_ ->
nil
end
Expand Down Expand Up @@ -275,10 +278,6 @@ defmodule BlockScoutWeb.Notifier do
Endpoint.broadcast("addresses:#{to_string(address_hash)}", "changed_bytecode", %{})
end

def handle_event({:chain_event, :optimism_deposits, :realtime, deposits}) do
broadcast_optimism_deposits(deposits, "optimism_deposits:new_deposits", "deposits")
end

def handle_event({:chain_event, :smart_contract_was_verified = event, :on_demand, [address_hash]}) do
broadcast_automatic_verification_events(event, address_hash)
end
Expand All @@ -303,6 +302,11 @@ defmodule BlockScoutWeb.Notifier do
# credo:disable-for-next-line Credo.Check.Design.AliasUsage
do: BlockScoutWeb.Notifiers.Arbitrum.handle_event(event)

:optimism ->
def handle_event({:chain_event, topic, _, _} = event) when topic in @chain_type_specific_events,
# credo:disable-for-next-line Credo.Check.Design.AliasUsage
do: BlockScoutWeb.Notifiers.Optimism.handle_event(event)

_ ->
nil
end
Expand Down Expand Up @@ -457,10 +461,6 @@ defmodule BlockScoutWeb.Notifier do
end
end

defp broadcast_optimism_deposits(deposits, deposit_channel, event) do
Endpoint.broadcast(deposit_channel, event, %{deposits: deposits})
end

defp broadcast_transactions_websocket_v2(transactions) do
pending_transactions =
Enum.filter(transactions, fn
Expand Down
40 changes: 40 additions & 0 deletions apps/block_scout_web/lib/block_scout_web/notifiers/optimism.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
defmodule BlockScoutWeb.Notifiers.Optimism do
@moduledoc """
Module to handle and broadcast OP related events.
"""

alias BlockScoutWeb.Endpoint

require Logger

def handle_event({:chain_event, :new_optimism_batches, :realtime, batches}) do
batches
|> Enum.sort_by(& &1.internal_id, :asc)
|> Enum.each(fn batch ->
Endpoint.broadcast("optimism:new_batch", "new_optimism_batch", %{
batch: batch
})
end)
end

def handle_event({:chain_event, :new_optimism_deposits, :realtime, deposits}) do
deposits_count = Enum.count(deposits)

if deposits_count > 0 do
Endpoint.broadcast("optimism:new_deposits", "new_optimism_deposits", %{
deposits: deposits_count
})

# todo: the `optimism_deposits:new_deposits` socket topic is for backward compatibility
# for the frontend and should be removed after the frontend starts to use the `optimism:new_deposits`
Endpoint.broadcast("optimism_deposits:new_deposits", "deposits", %{
deposits: deposits_count
})
end
end

def handle_event(event) do
Logger.warning("Unknown broadcasted event #{inspect(event)}.")
nil
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,12 @@ defmodule BlockScoutWeb.RealtimeEventHandler do
Subscriber.to(:new_messages_to_arbitrum_amount, :realtime)
end

:optimism ->
def chain_type_specific_subscriptions do
Subscriber.to(:new_optimism_batches, :realtime)
Subscriber.to(:new_optimism_deposits, :realtime)
end

_ ->
def chain_type_specific_subscriptions do
nil
Expand All @@ -32,7 +38,6 @@ defmodule BlockScoutWeb.RealtimeEventHandler do
Subscriber.to(:block_rewards, :realtime)
Subscriber.to(:internal_transactions, :realtime)
Subscriber.to(:internal_transactions, :on_demand)
Subscriber.to(:optimism_deposits, :realtime)
Subscriber.to(:token_transfers, :realtime)
Subscriber.to(:addresses, :on_demand)
Subscriber.to(:address_coin_balances, :on_demand)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ defmodule BlockScoutWeb.API.V2.OptimismView do
alias Explorer.{Chain, Repo}
alias Explorer.Helper, as: ExplorerHelper
alias Explorer.Chain.{Block, Transaction}
alias Explorer.Chain.Optimism.{FrameSequenceBlob, Withdrawal}
alias Explorer.Chain.Optimism.{FrameSequence, FrameSequenceBlob, Withdrawal}

@doc """
Function to render GET requests to `/api/v2/optimism/txn-batches` endpoint.
Expand Down Expand Up @@ -66,19 +66,7 @@ defmodule BlockScoutWeb.API.V2.OptimismView do
|> Enum.map(fn batch ->
from..to//_ = batch.l2_block_range

%{
"internal_id" => batch.id,
"l1_timestamp" => batch.l1_timestamp,
"l2_block_start" => from,
"l2_block_end" => to,
"transaction_count" => batch.transaction_count,
# todo: keep next line for compatibility with frontend and remove when new frontend is bound to `transaction_count` property
"tx_count" => batch.transaction_count,
"l1_transaction_hashes" => batch.l1_transaction_hashes,
# todo: keep next line for compatibility with frontend and remove when new frontend is bound to `l1_transaction_hashes` property
"l1_tx_hashes" => batch.l1_transaction_hashes,
"batch_data_container" => batch.batch_data_container
}
render_base_info_for_batch(batch.id, from, to, batch.transaction_count, batch)
end)

%{
Expand Down Expand Up @@ -272,6 +260,52 @@ defmodule BlockScoutWeb.API.V2.OptimismView do
count
end

# Transforms an L1 batch into a map format for HTTP response.
#
# This function processes an Optimism L1 batch and converts it into a map that
# includes basic batch information.
#
# ## Parameters
# - `internal_id`: The internal ID of the batch.
# - `l2_block_number_from`: Start L2 block number of the batch block range.
# - `l2_block_number_to`: End L2 block number of the batch block range.
# - `transaction_count`: The L2 transaction count included into the blocks of the range.
# - `batch`: Either an `Explorer.Chain.Optimism.FrameSequence` entry or a map with
# the corresponding fields.
#
# ## Returns
# - A map with detailed information about the batch formatted for use in JSON HTTP responses.
@spec render_base_info_for_batch(
non_neg_integer(),
non_neg_integer(),
non_neg_integer(),
non_neg_integer(),
FrameSequence.t()
| %{:l1_timestamp => DateTime.t(), :l1_transaction_hashes => list(), optional(any()) => any()}
) :: %{
:internal_id => non_neg_integer(),
:l1_timestamp => DateTime.t(),
:l2_block_start => non_neg_integer(),
:l2_block_end => non_neg_integer(),
:transaction_count => non_neg_integer(),
# todo: keep next line for compatibility with frontend and remove when new frontend is bound to `transaction_count` property
:tx_count => non_neg_integer(),
:l1_transaction_hashes => list(),
# todo: keep next line for compatibility with frontend and remove when new frontend is bound to `l1_transaction_hashes` property
:l1_tx_hashes => list(),
:batch_data_container => :in_blob4844 | :in_celestia | :in_calldata | nil
}
defp render_base_info_for_batch(internal_id, l2_block_number_from, l2_block_number_to, transaction_count, batch) do
FrameSequence.prepare_base_info_for_batch(
internal_id,
l2_block_number_from,
l2_block_number_to,
transaction_count,
batch.batch_data_container,
batch
)
end

@doc """
Extends the json output for a block using Optimism frame sequence (bound
with the provided L2 block) - adds info about L1 batch to the output.
Expand Down
Loading

0 comments on commit d0e1b6f

Please sign in to comment.