fix: Rework initialization of the `RollupL1ReorgMonitor` and fix `read_system_config` for fallback cases (#11275)

* Fix init in RollupL1ReorgMonitor

* Update PULL_REQUEST_TEMPLATE

* Fix init in RollupL1ReorgMonitor

* Update PULL_REQUEST_TEMPLATE

* Fix read_system_config function for fallback cases

* Update rollup_l1_reorg_monitor.ex

Co-authored-by: Victor Baranov <baranov.viktor.27@gmail.com>

---------

Co-authored-by: POA <33550681+poa@users.noreply.github.com>
Co-authored-by: Victor Baranov <baranov.viktor.27@gmail.com>
pull/11298/head
varasev 6 days ago committed by GitHub
parent 0134bd078a
commit 481547f356
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 2
      PULL_REQUEST_TEMPLATE.md
  2. 64
      apps/indexer/lib/indexer/fetcher/optimism.ex
  3. 70
      apps/indexer/lib/indexer/fetcher/optimism/transaction_batch.ex
  4. 6
      apps/indexer/lib/indexer/fetcher/polygon_zkevm/bridge_l1.ex
  5. 44
      apps/indexer/lib/indexer/fetcher/rollup_l1_reorg_monitor.ex
  6. 6
      apps/indexer/lib/indexer/fetcher/scroll/batch.ex
  7. 6
      apps/indexer/lib/indexer/fetcher/scroll/bridge_l1.ex
  8. 6
      apps/indexer/lib/indexer/fetcher/shibarium/l1.ex

@ -27,6 +27,6 @@
- [ ] If I added new functionality, I added tests covering it.
- [ ] If I fixed a bug, I added a regression test to prevent the bug from silently reappearing again.
- [ ] I checked whether I should update the docs and did so by submitting a PR to [docs repository](https://github.com/blockscout/docs).
- [ ] If I added/changed/removed ENV var, I submitted a PR to [docs repository](https://github.com/blockscout/docs) to update the list of [env vars](https://github.com/blockscout/docs/blob/master/for-developers/information-and-settings/env-variables.md) and I updated the version to `master` in the Version column. If I removed variable, I added it to [Deprecated ENV Variables](https://github.com/blockscout/docs/blob/master/for-developers/information-and-settings/env-variables/deprecated-env-variables/README.md) page. After merging docs PR, changes will be reflected in these [pages](https://docs.blockscout.com/for-developers/information-and-settings/env-variables).
- [ ] If I added/changed/removed ENV var, I submitted a PR to [docs repository](https://github.com/blockscout/docs) to update the list of [env vars](https://github.com/blockscout/docs/blob/master/setup/env-variables/README.md) and I updated the version to `master` in the Version column. If I removed variable, I added it to [Deprecated ENV Variables](https://github.com/blockscout/docs/blob/master/setup/env-variables/deprecated-env-variables/README.md) page. After merging docs PR, changes will be reflected in these [pages](https://docs.blockscout.com/setup/env-variables).
- [ ] If I added new DB indices, I checked, that they are not redundant, with PGHero or other tools.
- [ ] If I added/removed chain type, I modified the Github CI matrix and PR labels accordingly.

@ -20,6 +20,7 @@ defmodule Indexer.Fetcher.Optimism do
alias EthereumJSONRPC.Block.ByNumber
alias EthereumJSONRPC.Contract
alias Explorer.Repo
alias Indexer.Fetcher.RollupL1ReorgMonitor
alias Indexer.Helper
@fetcher_name :optimism
@ -238,8 +239,7 @@ defmodule Indexer.Fetcher.Optimism do
optimism_l1_rpc = l1_rpc_url()
with {:system_config_valid, true} <- {:system_config_valid, Helper.address_correct?(system_config)},
{:reorg_monitor_started, true} <-
{:reorg_monitor_started, !is_nil(Process.whereis(Indexer.Fetcher.RollupL1ReorgMonitor))},
_ <- RollupL1ReorgMonitor.wait_for_start(caller),
{:rpc_l1_undefined, false} <- {:rpc_l1_undefined, is_nil(optimism_l1_rpc)},
json_rpc_named_arguments = json_rpc_named_arguments(optimism_l1_rpc),
{optimism_portal, start_block_l1} <- read_system_config(system_config, json_rpc_named_arguments),
@ -275,13 +275,6 @@ defmodule Indexer.Fetcher.Optimism do
stop: false
}}
else
{:reorg_monitor_started, false} ->
Logger.error(
"Cannot start this process as reorg monitor in Indexer.Fetcher.RollupL1ReorgMonitor is not started."
)
{:stop, :normal, %{}}
{:rpc_l1_undefined, true} ->
Logger.error("L1 RPC URL is not defined.")
{:stop, :normal, %{}}
@ -353,23 +346,46 @@ defmodule Indexer.Fetcher.Optimism do
error_message = &"Cannot call public getters of SystemConfig. Error: #{inspect(&1)}"
case Helper.repeated_call(
&json_rpc/2,
[requests, json_rpc_named_arguments],
error_message,
Helper.finite_retries_number()
) do
{:ok, responses} ->
"0x000000000000000000000000" <> optimism_portal = Enum.at(responses, 0).result
start_block = quantity_to_integer(Enum.at(responses, 1).result)
{"0x" <> optimism_portal, start_block}
env = Application.get_all_env(:indexer)[__MODULE__]
fallback_start_block = env[:start_block_l1]
{optimism_portal, start_block} =
case Helper.repeated_call(
&json_rpc/2,
[requests, json_rpc_named_arguments],
error_message,
Helper.finite_retries_number()
) do
{:ok, responses} ->
optimism_portal_result = Map.get(Enum.at(responses, 0), :result)
optimism_portal =
with {:nil_result, true, _} <- {:nil_result, is_nil(optimism_portal_result), optimism_portal_result},
{:fallback_defined, true} <- {:fallback_defined, Helper.address_correct?(env[:portal])} do
env[:portal]
else
{:nil_result, false, portal} ->
"0x000000000000000000000000" <> optimism_portal = portal
"0x" <> optimism_portal
{:fallback_defined, false} ->
nil
end
start_block =
responses
|> Enum.at(1)
|> Map.get(:result, fallback_start_block)
|> quantity_to_integer()
{optimism_portal, start_block}
_ ->
env = Application.get_all_env(:indexer)[__MODULE__]
_ ->
{env[:portal], fallback_start_block}
end
if Helper.address_correct?(env[:portal]) and not is_nil(env[:start_block_l1]) do
{env[:portal], env[:start_block_l1]}
end
if Helper.address_correct?(optimism_portal) and !is_nil(start_block) do
{String.downcase(optimism_portal), start_block}
end
end

@ -102,8 +102,7 @@ defmodule Indexer.Fetcher.Optimism.TransactionBatch do
{:system_config_valid, Helper.address_correct?(system_config)},
{:genesis_block_l2_invalid, false} <-
{:genesis_block_l2_invalid, is_nil(env[:genesis_block_l2]) or env[:genesis_block_l2] < 0},
{:reorg_monitor_started, true} <-
{:reorg_monitor_started, !is_nil(Process.whereis(RollupL1ReorgMonitor))},
_ <- RollupL1ReorgMonitor.wait_for_start(__MODULE__),
{:rpc_l1_undefined, false} <- {:rpc_l1_undefined, is_nil(optimism_l1_rpc)},
json_rpc_named_arguments = Optimism.json_rpc_named_arguments(optimism_l1_rpc),
{:system_config_read, {start_block_l1, batch_inbox, batch_submitter}} <-
@ -160,13 +159,6 @@ defmodule Indexer.Fetcher.Optimism.TransactionBatch do
Logger.error("L2 genesis block number is undefined or invalid.")
{:stop, :normal, state}
{:reorg_monitor_started, false} ->
Logger.error(
"Cannot start this process as reorg monitor in Indexer.Fetcher.RollupL1ReorgMonitor is not started."
)
{:stop, :normal, state}
{:rpc_l1_undefined, true} ->
Logger.error("L1 RPC URL is not defined.")
{:stop, :normal, state}
@ -1447,25 +1439,51 @@ defmodule Indexer.Fetcher.Optimism.TransactionBatch do
error_message = &"Cannot call public getters of SystemConfig. Error: #{inspect(&1)}"
case Helper.repeated_call(
&json_rpc/2,
[requests, json_rpc_named_arguments],
error_message,
Helper.finite_retries_number()
) do
{:ok, responses} ->
start_block = quantity_to_integer(Enum.at(responses, 0).result)
"0x000000000000000000000000" <> batch_inbox = Enum.at(responses, 1).result
"0x000000000000000000000000" <> batch_submitter = Enum.at(responses, 2).result
{start_block, String.downcase("0x" <> batch_inbox), String.downcase("0x" <> batch_submitter)}
env = Application.get_all_env(:indexer)[__MODULE__]
fallback_start_block = Application.get_all_env(:indexer)[Indexer.Fetcher.Optimism][:start_block_l1]
{start_block, batch_inbox, batch_submitter} =
case Helper.repeated_call(
&json_rpc/2,
[requests, json_rpc_named_arguments],
error_message,
Helper.finite_retries_number()
) do
{:ok, responses} ->
start_block =
responses
|> Enum.at(0)
|> Map.get(:result, fallback_start_block)
|> quantity_to_integer()
inbox_result = Map.get(Enum.at(responses, 1), :result)
submitter_result = Map.get(Enum.at(responses, 2), :result)
{batch_inbox, batch_submitter} =
with {:nil_result, true, _, _} <-
{:nil_result, is_nil(inbox_result) or is_nil(submitter_result), inbox_result, submitter_result},
{:fallback_defined, true} <-
{:fallback_defined,
Helper.address_correct?(env[:inbox]) and Helper.address_correct?(env[:submitter])} do
{env[:inbox], env[:submitter]}
else
{:nil_result, false, inbox, submitter} ->
"0x000000000000000000000000" <> batch_inbox = inbox
"0x000000000000000000000000" <> batch_submitter = submitter
{"0x" <> batch_inbox, "0x" <> batch_submitter}
{:fallback_defined, false} ->
{nil, nil}
end
_ ->
start_block = Application.get_all_env(:indexer)[Indexer.Fetcher.Optimism][:start_block_l1]
env = Application.get_all_env(:indexer)[__MODULE__]
{start_block, batch_inbox, batch_submitter}
if not is_nil(start_block) and Helper.address_correct?(env[:inbox]) and Helper.address_correct?(env[:submitter]) do
{start_block, String.downcase(env[:inbox]), String.downcase(env[:submitter])}
end
_ ->
{fallback_start_block, env[:inbox], env[:submitter]}
end
if !is_nil(start_block) and Helper.address_correct?(batch_inbox) and Helper.address_correct?(batch_submitter) do
{start_block, String.downcase(batch_inbox), String.downcase(batch_submitter)}
end
end

@ -57,7 +57,7 @@ defmodule Indexer.Fetcher.PolygonZkevm.BridgeL1 do
env_l2 = Application.get_all_env(:indexer)[Indexer.Fetcher.PolygonZkevm.BridgeL2]
with {:start_block_undefined, false} <- {:start_block_undefined, is_nil(env[:start_block])},
{:reorg_monitor_started, true} <- {:reorg_monitor_started, !is_nil(Process.whereis(RollupL1ReorgMonitor))},
_ <- RollupL1ReorgMonitor.wait_for_start(__MODULE__),
rpc = env[:rpc],
{:rpc_undefined, false} <- {:rpc_undefined, is_nil(rpc)},
{:rollup_network_id_l1_is_valid, true} <-
@ -101,10 +101,6 @@ defmodule Indexer.Fetcher.PolygonZkevm.BridgeL1 do
# the process shouldn't start if the start block is not defined
{:stop, :normal, %{}}
{:reorg_monitor_started, false} ->
Logger.error("Cannot start this process as Indexer.Fetcher.RollupL1ReorgMonitor is not started.")
{:stop, :normal, %{}}
{:rpc_undefined, true} ->
Logger.error("L1 RPC URL is not defined.")
{:stop, :normal, %{}}

@ -16,6 +16,7 @@ defmodule Indexer.Fetcher.RollupL1ReorgMonitor do
alias Indexer.Helper
@fetcher_name :rollup_l1_reorg_monitor
@start_recheck_period_seconds 3
@modules_can_use_reorg_monitor (case Application.compile_env(:explorer, :chain_type) do
:optimism ->
@ -67,6 +68,11 @@ defmodule Indexer.Fetcher.RollupL1ReorgMonitor do
GenServer.start_link(__MODULE__, args, Keyword.put_new(gen_server_options, :name, __MODULE__))
end
@impl GenServer
def init(_args) do
{:ok, %{}, {:continue, :ok}}
end
@doc """
This function initializes L1 blocks reorg monitor for the current rollup
defined by CHAIN_TYPE. If the current chain is not a rollup, the module just doesn't start.
@ -84,10 +90,10 @@ defmodule Indexer.Fetcher.RollupL1ReorgMonitor do
## Returns
- `{:ok, state}` with the determined parameters for the monitor loop if at least one rollup module is launched.
- `:ignore` if the monitor is not needed.
- `{:stop, :normal, %{}}` if the monitor is not needed.
"""
@impl GenServer
def init(_args) do
def handle_continue(:ok, _state) do
Logger.metadata(fetcher: @fetcher_name)
modules_using_reorg_monitor =
@ -96,7 +102,7 @@ defmodule Indexer.Fetcher.RollupL1ReorgMonitor do
if Enum.empty?(modules_using_reorg_monitor) do
# don't start reorg monitor as there is no module which would use it
:ignore
{:stop, :normal, %{}}
else
l1_rpc = Enum.at(modules_using_reorg_monitor, 0).l1_rpc_url()
@ -106,7 +112,7 @@ defmodule Indexer.Fetcher.RollupL1ReorgMonitor do
Process.send(self(), :reorg_monitor, [])
{:ok,
{:noreply,
%{
block_check_interval: block_check_interval,
json_rpc_named_arguments: json_rpc_named_arguments,
@ -155,4 +161,34 @@ defmodule Indexer.Fetcher.RollupL1ReorgMonitor do
{:noreply, %{state | prev_latest: latest}}
end
@doc """
Infinitely waits for the module to be initialized and started.
## Parameters
- `waiting_module`: The module which called this function.
## Returns
- nothing
"""
@spec wait_for_start(module()) :: any()
def wait_for_start(waiting_module) do
state =
try do
__MODULE__
|> Process.whereis()
|> :sys.get_state()
catch
:exit, _ -> %{}
end
if map_size(state) == 0 do
Logger.warning(
"#{waiting_module} waits for #{__MODULE__} to start. Rechecking in #{@start_recheck_period_seconds} second(s)..."
)
:timer.sleep(@start_recheck_period_seconds * 1_000)
wait_for_start(waiting_module)
end
end
end

@ -78,7 +78,7 @@ defmodule Indexer.Fetcher.Scroll.Batch do
env = Application.get_all_env(:indexer)[__MODULE__]
with {:start_block_undefined, false} <- {:start_block_undefined, is_nil(env[:start_block])},
{:reorg_monitor_started, true} <- {:reorg_monitor_started, !is_nil(Process.whereis(RollupL1ReorgMonitor))},
_ <- RollupL1ReorgMonitor.wait_for_start(__MODULE__),
rpc = l1_rpc_url(),
{:rpc_undefined, false} <- {:rpc_undefined, is_nil(rpc)},
{:scroll_chain_contract_address_is_valid, true} <-
@ -114,10 +114,6 @@ defmodule Indexer.Fetcher.Scroll.Batch do
# the process shouldn't start if the start block is not defined
{:stop, :normal, %{}}
{:reorg_monitor_started, false} ->
Logger.error("Cannot start this process as Indexer.Fetcher.RollupL1ReorgMonitor is not started.")
{:stop, :normal, %{}}
{:rpc_undefined, true} ->
Logger.error("L1 RPC URL is not defined.")
{:stop, :normal, %{}}

@ -69,7 +69,7 @@ defmodule Indexer.Fetcher.Scroll.BridgeL1 do
env = Application.get_all_env(:indexer)[__MODULE__]
with {:start_block_undefined, false} <- {:start_block_undefined, is_nil(env[:start_block])},
{:reorg_monitor_started, true} <- {:reorg_monitor_started, !is_nil(Process.whereis(RollupL1ReorgMonitor))},
_ <- RollupL1ReorgMonitor.wait_for_start(__MODULE__),
rpc = l1_rpc_url(),
{:rpc_undefined, false} <- {:rpc_undefined, is_nil(rpc)},
{:messenger_contract_address_is_valid, true} <-
@ -104,10 +104,6 @@ defmodule Indexer.Fetcher.Scroll.BridgeL1 do
# the process shouldn't start if the start block is not defined
{:stop, :normal, %{}}
{:reorg_monitor_started, false} ->
Logger.error("Cannot start this process as Indexer.Fetcher.RollupL1ReorgMonitor is not started.")
{:stop, :normal, %{}}
{:rpc_undefined, true} ->
Logger.error("L1 RPC URL is not defined.")
{:stop, :normal, %{}}

@ -112,7 +112,7 @@ defmodule Indexer.Fetcher.Shibarium.L1 do
env = Application.get_all_env(:indexer)[__MODULE__]
with {:start_block_undefined, false} <- {:start_block_undefined, is_nil(env[:start_block])},
{:reorg_monitor_started, true} <- {:reorg_monitor_started, !is_nil(Process.whereis(RollupL1ReorgMonitor))},
_ <- RollupL1ReorgMonitor.wait_for_start(__MODULE__),
rpc = env[:rpc],
{:rpc_undefined, false} <- {:rpc_undefined, is_nil(rpc)},
{:deposit_manager_address_is_valid, true} <-
@ -164,10 +164,6 @@ defmodule Indexer.Fetcher.Shibarium.L1 do
# the process shouldn't start if the start block is not defined
{:stop, :normal, %{}}
{:reorg_monitor_started, false} ->
Logger.error("Cannot start this process as Indexer.Fetcher.RollupL1ReorgMonitor is not started.")
{:stop, :normal, %{}}
{:rpc_undefined, true} ->
Logger.error("L1 RPC URL is not defined.")
{:stop, :normal, %{}}

Loading…
Cancel
Save