Add API v2 response for zkEVM list of batches page

pull/7584/head
POA 1 year ago
parent eadef3c01d
commit b4e7a12c6d
  1. 2
      apps/block_scout_web/lib/block_scout_web/api_router.ex
  2. 23
      apps/block_scout_web/lib/block_scout_web/chain.ex
  3. 41
      apps/block_scout_web/lib/block_scout_web/controllers/api/v2/zkevm_controller.ex
  4. 49
      apps/block_scout_web/lib/block_scout_web/views/api/v2/zkevm_view.ex
  5. 22
      apps/explorer/lib/explorer/chain.ex

@ -211,6 +211,8 @@ defmodule BlockScoutWeb.ApiRouter do
end
scope "/zkevm" do
get("/batches", V2.ZkevmController, :batches)
get("/batches/count", V2.ZkevmController, :batches_count)
get("/batches/:batch_number", V2.ZkevmController, :batch)
end
end

@ -34,7 +34,8 @@ defmodule BlockScoutWeb.Chain do
Transaction,
Transaction.StateChange,
Wei,
Withdrawal
Withdrawal,
ZkevmTxnBatch
}
alias Explorer.PagingOptions
@ -302,8 +303,22 @@ defmodule BlockScoutWeb.Chain do
[paging_options: %{@default_paging_options | key: {index}}]
end
def paging_options(%{"number" => number_string}) when is_binary(number_string) do
case Integer.parse(number_string) do
{number, ""} ->
[paging_options: %{@default_paging_options | key: {number}}]
_ ->
[paging_options: @default_paging_options]
end
end
def paging_options(%{"number" => number}) when is_integer(number) do
[paging_options: %{@default_paging_options | key: {number}}]
end
def paging_options(%{"inserted_at" => inserted_at_string, "hash" => hash_string})
when is_binary(inserted_at_string) and is_binary(hash_string) do
when is_binary(inserted_at_string) and is_binary(hash_string) do
with {:ok, inserted_at, _} <- DateTime.from_iso8601(inserted_at_string),
{:ok, hash} <- string_to_transaction_hash(hash_string) do
[paging_options: %{@default_paging_options | key: {inserted_at, hash}, is_pending_tx: true}]
@ -520,6 +535,10 @@ defmodule BlockScoutWeb.Chain do
%{"index" => index}
end
defp paging_params(%ZkevmTxnBatch{number: number}) do
%{"number" => number}
end
# clause for search results pagination
defp paging_params(%{
address_hash: address_hash,

@ -1,7 +1,15 @@
defmodule BlockScoutWeb.API.V2.ZkevmController do
use BlockScoutWeb, :controller
alias Explorer.Chain
import BlockScoutWeb.Chain,
only: [
next_page_params: 3,
paging_options: 1,
split_list_by_page: 1
]
alias Explorer.{Chain, Repo}
alias Explorer.Chain.ZkevmTxnBatch
action_fallback(BlockScoutWeb.API.V2.FallbackController)
@ -11,6 +19,10 @@ defmodule BlockScoutWeb.API.V2.ZkevmController do
:l2_transactions => :required
}
@batches_necessity_by_association %{
:sequence_transaction => :optional
}
def batch(conn, %{"batch_number" => batch_number} = _params) do
{:ok, batch} =
Chain.zkevm_batch(
@ -23,4 +35,31 @@ defmodule BlockScoutWeb.API.V2.ZkevmController do
|> put_status(200)
|> render(:zkevm_batch, %{batch: batch})
end
def batches(conn, params) do
{batches, next_page} =
params
|> paging_options()
|> Keyword.put(:necessity_by_association, @batches_necessity_by_association)
|> Keyword.put(:api?, true)
|> Chain.zkevm_batches()
|> split_list_by_page()
next_page_params = next_page_params(next_page, batches, params)
conn
|> put_status(200)
|> render(:zkevm_batches, %{
batches: batches,
next_page_params: next_page_params
})
end
def batches_count(conn, _params) do
count = Repo.replica().aggregate(ZkevmTxnBatch, :count, timeout: :infinity)
conn
|> put_status(200)
|> render(:zkevm_batches_count, %{count: count})
end
end

@ -1,6 +1,11 @@
defmodule BlockScoutWeb.API.V2.ZkevmView do
use BlockScoutWeb, :view
import Ecto.Query, only: [from: 2]
alias Explorer.Chain.ZkevmBatchTxn
alias Explorer.Repo
def render("zkevm_batch.json", %{batch: batch}) do
sequence_tx_hash =
if not is_nil(batch.sequence_transaction) do
@ -25,6 +30,50 @@ defmodule BlockScoutWeb.API.V2.ZkevmView do
}
end
def render("zkevm_batches.json", %{
batches: batches,
next_page_params: next_page_params
}) do
items =
batches
|> Enum.map(fn batch ->
Task.async(fn ->
tx_count =
Repo.replica().aggregate(
from(
t in ZkevmBatchTxn,
where: t.batch_number == ^batch.number
),
:count,
timeout: :infinity
)
sequence_tx_hash =
if not is_nil(batch.sequence_transaction) do
batch.sequence_transaction.hash
end
%{
"number" => batch.number,
"timestamp" => batch.timestamp,
"tx_count" => tx_count,
"sequence_tx_hash" => sequence_tx_hash
}
end)
end)
|> Task.yield_many(:infinity)
|> Enum.map(fn {_task, {:ok, item}} -> item end)
%{
items: items,
next_page_params: next_page_params
}
end
def render("zkevm_batches_count.json", %{count: count}) do
count
end
defp batch_status(batch) do
sequence_id = Map.get(batch, :sequence_id)
verify_id = Map.get(batch, :verify_id)

@ -6422,4 +6422,26 @@ defmodule Explorer.Chain do
def default_paging_options do
@default_paging_options
end
def zkevm_batches(options \\ []) do
paging_options = Keyword.get(options, :paging_options, @default_paging_options)
necessity_by_association = Keyword.get(options, :necessity_by_association, %{})
base_query =
from(tb in ZkevmTxnBatch,
order_by: [desc: tb.number]
)
base_query
|> join_associations(necessity_by_association)
|> page_zkevm_batches(paging_options)
|> limit(^paging_options.page_size)
|> select_repo(options).all()
end
defp page_zkevm_batches(query, %PagingOptions{key: nil}), do: query
defp page_zkevm_batches(query, %PagingOptions{key: {number}}) do
from(tb in query, where: tb.number < ^number)
end
end

Loading…
Cancel
Save