From 69d28b60b77e5e4d64a82c9e1f3b6a19f6f47359 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juli=C3=A1n=20Gonz=C3=A1lez=20Calder=C3=B3n?= Date: Thu, 1 Aug 2024 12:39:56 -0300 Subject: [PATCH 1/7] Add error handling to block id parsing --- .../live/pages/block_detail.ex | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/lib/starknet_explorer_web/live/pages/block_detail.ex b/lib/starknet_explorer_web/live/pages/block_detail.ex index 02119dbc..8d9e5fae 100644 --- a/lib/starknet_explorer_web/live/pages/block_detail.ex +++ b/lib/starknet_explorer_web/live/pages/block_detail.ex @@ -9,8 +9,16 @@ defmodule StarknetExplorerWeb.BlockDetailLive do alias StarknetExplorer.Transaction alias StarknetExplorer.Events - defp num_or_hash(<<"0x", _rest::binary>>), do: :hash - defp num_or_hash(_num), do: :num + defp parse_block_id(block_id) + + defp parse_block_id(<<"0x", _::binary>> = hash), do: {:hash, hash} + + defp parse_block_id(number?) do + case Integer.parse(number?) do + {number, ""} -> {:num, number} + _ -> :error + end + end defp get_block_proof(block_hash) do try do @@ -159,15 +167,7 @@ defmodule StarknetExplorerWeb.BlockDetailLive do @impl true def mount(_params = %{"number_or_hash" => param}, _session, socket) do - {type, param} = - case num_or_hash(param) do - :hash -> - {:hash, param} - - :num -> - {num, ""} = Integer.parse(param) - {:num, num} - end + {type, param} = parse_block_id(param) {:ok, block} = case :timer.tc(fn -> From 887a3a509d2f2c11ce9baad44ea2edf850433adb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juli=C3=A1n=20Gonz=C3=A1lez=20Calder=C3=B3n?= Date: Thu, 1 Aug 2024 12:54:03 -0300 Subject: [PATCH 2/7] Abstract get_block --- .../live/pages/block_detail.ex | 85 ++++++++++--------- 1 file changed, 44 insertions(+), 41 deletions(-) diff --git a/lib/starknet_explorer_web/live/pages/block_detail.ex b/lib/starknet_explorer_web/live/pages/block_detail.ex index 8d9e5fae..4e4db958 100644 --- a/lib/starknet_explorer_web/live/pages/block_detail.ex +++ b/lib/starknet_explorer_web/live/pages/block_detail.ex @@ -83,6 +83,47 @@ defmodule StarknetExplorerWeb.BlockDetailLive do end end + defp get_block({type, block_id}, socket) do + case :timer.tc(fn -> + Enum.find( + StarknetExplorer.IndexCache.latest_blocks(socket.assigns.network), + fn block -> + block.number == block_id or block.hash == block_id + end + ) + end) do + {time, block} = {_, %StarknetExplorer.Block{}} -> + Logger.debug( + "[Block Detail] Found block #{block.number} in cache in #{time} microseconds" + ) + + {:ok, block} + + {time, _} -> + case type do + :hash -> + {query_time, res} = + :timer.tc(fn -> Data.block_by_hash(block_id, socket.assigns.network, false) end) + + Logger.debug( + "[Block Detail] Fetched block #{block_id} in #{query_time} microseconds, query took #{time} microseconds, using :hash" + ) + + res + + :num -> + {query_time, res} = + :timer.tc(fn -> Data.block_by_number(block_id, socket.assigns.network, false) end) + + Logger.debug( + "[Block Detail] Fetched block #{block_id} in #{query_time} microseconds, query took #{time} microsecond, using :num" + ) + + res + end + end + end + defp tab_name("transactions"), do: "Transactions" defp tab_name("messages"), do: "Messages" defp tab_name("events"), do: "Events" @@ -167,47 +208,9 @@ defmodule StarknetExplorerWeb.BlockDetailLive do @impl true def mount(_params = %{"number_or_hash" => param}, _session, socket) do - {type, param} = parse_block_id(param) - - {:ok, block} = - case :timer.tc(fn -> - Enum.find( - StarknetExplorer.IndexCache.latest_blocks(socket.assigns.network), - fn block -> - block.number == param or block.hash == param - end - ) - end) do - {time, block} = {_, %StarknetExplorer.Block{}} -> - Logger.debug( - "[Block Detail] Found block #{block.number} in cache in #{time} microseconds" - ) - - {:ok, block} - - {time, _} -> - case type do - :hash -> - {query_time, res} = - :timer.tc(fn -> Data.block_by_hash(param, socket.assigns.network, false) end) - - Logger.debug( - "[Block Detail] Fetched block #{param} in #{query_time} microseconds, query took #{time} microseconds, using :hash" - ) - - res - - :num -> - {query_time, res} = - :timer.tc(fn -> Data.block_by_number(param, socket.assigns.network, false) end) - - Logger.debug( - "[Block Detail] Fetched block #{param} in #{query_time} microseconds, query took #{time} microsecond, using :num" - ) - - res - end - end + block_id = parse_block_id(param) + + {:ok, block} = get_block(block_id, socket) socket = assign(socket, :block, block) From 9730567a6638a8c96ec8295ae99ead922ffedbaf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juli=C3=A1n=20Gonz=C3=A1lez=20Calder=C3=B3n?= Date: Thu, 1 Aug 2024 13:45:12 -0300 Subject: [PATCH 3/7] Add error handling --- .../live/pages/block_detail.ex | 99 +++++++++++-------- 1 file changed, 56 insertions(+), 43 deletions(-) diff --git a/lib/starknet_explorer_web/live/pages/block_detail.ex b/lib/starknet_explorer_web/live/pages/block_detail.ex index 4e4db958..230340c8 100644 --- a/lib/starknet_explorer_web/live/pages/block_detail.ex +++ b/lib/starknet_explorer_web/live/pages/block_detail.ex @@ -124,6 +124,48 @@ defmodule StarknetExplorerWeb.BlockDetailLive do end end + defp assign_block_data(socket, block) do + socket = assign(socket, :block, block) + + extra_assings = + if connected?(socket) do + transactions = block_transactions(socket) + + # note: most transactions receipt do not contain messages + l1_to_l2_messages = + transactions |> Enum.map(&Message.from_transaction/1) |> Enum.reject(&is_nil/1) + + messages = + (transactions + |> Enum.map(fn tx -> tx.receipt end) + |> Enum.flat_map(&Message.from_transaction_receipt/1)) ++ l1_to_l2_messages + + [ + transactions_count: length(transactions), + messages_count: length(messages), + events_count: Events.get_count_by_block(block.number, socket.assigns.network), + transactions: transactions, + messages: messages + ] + else + [] + end + + assigns = + [ + gas_price: Utils.hex_wei_to_eth(block.gas_fee_in_wei), + execution_resources: block.execution_resources, + block: block, + view: "overview", + verification: "Pending", + block_age: Utils.get_block_age(block), + tabs?: connected?(socket), + active_pagination_id: "" + ] ++ extra_assings + + assign(socket, assigns) + end + defp tab_name("transactions"), do: "Transactions" defp tab_name("messages"), do: "Messages" defp tab_name("events"), do: "Events" @@ -208,49 +250,16 @@ defmodule StarknetExplorerWeb.BlockDetailLive do @impl true def mount(_params = %{"number_or_hash" => param}, _session, socket) do - block_id = parse_block_id(param) - - {:ok, block} = get_block(block_id, socket) - - socket = assign(socket, :block, block) - - extra_assings = - if connected?(socket) do - transactions = block_transactions(socket) - - # note: most transactions receipt do not contain messages - l1_to_l2_messages = - transactions |> Enum.map(&Message.from_transaction/1) |> Enum.reject(&is_nil/1) - - messages = - (transactions - |> Enum.map(fn tx -> tx.receipt end) - |> Enum.flat_map(&Message.from_transaction_receipt/1)) ++ l1_to_l2_messages - - [ - transactions_count: length(transactions), - messages_count: length(messages), - events_count: Events.get_count_by_block(block.number, socket.assigns.network), - transactions: transactions, - messages: messages - ] + socket = + with {_, _} = block_id <- parse_block_id(param), + {:ok, block} <- + get_block(block_id, socket) do + assign_block_data(socket, block) else - [] + _ -> assign(socket, :block, :error) end - assigns = - [ - gas_price: Utils.hex_wei_to_eth(block.gas_fee_in_wei), - execution_resources: block.execution_resources, - block: block, - view: "overview", - verification: "Pending", - block_age: Utils.get_block_age(block), - tabs?: connected?(socket), - active_pagination_id: "" - ] ++ extra_assings - - {:ok, assign(socket, assigns)} + {:ok, socket} end @impl true @@ -484,9 +493,13 @@ defmodule StarknetExplorerWeb.BlockDetailLive do def render(assigns) do ~H"""
- <%= block_detail_header(assigns) %> - <%= if @view == "transactions", do: render_tx_filter(assigns) %> - <%= render_info(assigns) %> + <%= if @block == :error do %> +

Block Not Found

+ <% else %> + <%= block_detail_header(assigns) %> + <%= if @view == "transactions", do: render_tx_filter(assigns) %> + <%= render_info(assigns) %> + <% end %>
""" end From 537346f266076b0294cbe7b14a29d3a3db9a05cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juli=C3=A1n=20Gonz=C3=A1lez=20Calder=C3=B3n?= Date: Thu, 1 Aug 2024 18:22:31 -0300 Subject: [PATCH 4/7] Prettier error message --- .../live/pages/block_detail.ex | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/lib/starknet_explorer_web/live/pages/block_detail.ex b/lib/starknet_explorer_web/live/pages/block_detail.ex index 230340c8..c0d9275e 100644 --- a/lib/starknet_explorer_web/live/pages/block_detail.ex +++ b/lib/starknet_explorer_web/live/pages/block_detail.ex @@ -492,15 +492,17 @@ defmodule StarknetExplorerWeb.BlockDetailLive do @impl true def render(assigns) do ~H""" -
- <%= if @block == :error do %> -

Block Not Found

- <% else %> + <%= if @block == :error do %> +
+

Error: Block Not Found

+
+ <% else %> +
<%= block_detail_header(assigns) %> <%= if @view == "transactions", do: render_tx_filter(assigns) %> <%= render_info(assigns) %> - <% end %> -
+
+ <% end %> """ end From 9e5e8c4ae4a624178b2d368ff4c051c5ef33143d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juli=C3=A1n=20Gonz=C3=A1lez=20Calder=C3=B3n?= Date: Thu, 1 Aug 2024 18:31:27 -0300 Subject: [PATCH 5/7] Rescue database error --- lib/starknet_explorer/block/block.ex | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/lib/starknet_explorer/block/block.ex b/lib/starknet_explorer/block/block.ex index 5d29d1cd..49f4f1c1 100644 --- a/lib/starknet_explorer/block/block.ex +++ b/lib/starknet_explorer/block/block.ex @@ -499,19 +499,24 @@ defmodule StarknetExplorer.Block do end def get_by_num(num, network, preload_transactions \\ true) do - query = - from b in Block, - where: b.number == ^num and b.network == ^network + try do + query = + from b in Block, + where: b.number == ^num and b.network == ^network - block = Repo.one(query) + block = Repo.one(query) - if preload_transactions and not is_nil(block) do - preload_query = - from tx in Transaction, where: tx.block_number == ^block.number and tx.network == ^network + if preload_transactions and not is_nil(block) do + preload_query = + from tx in Transaction, + where: tx.block_number == ^block.number and tx.network == ^network - Repo.preload(block, transactions: preload_query) - else - block + Repo.preload(block, transactions: preload_query) + else + block + end + rescue + DBConnection.EncodeError -> nil end end From 6a36ad028a43898206e9404a0e85088eef402005 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juli=C3=A1n=20Gonz=C3=A1lez=20Calder=C3=B3n?= Date: Fri, 2 Aug 2024 11:48:39 -0300 Subject: [PATCH 6/7] Use :number instead of :num --- lib/starknet_explorer_web/live/pages/block_detail.ex | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/starknet_explorer_web/live/pages/block_detail.ex b/lib/starknet_explorer_web/live/pages/block_detail.ex index c0d9275e..4c6674ec 100644 --- a/lib/starknet_explorer_web/live/pages/block_detail.ex +++ b/lib/starknet_explorer_web/live/pages/block_detail.ex @@ -15,7 +15,7 @@ defmodule StarknetExplorerWeb.BlockDetailLive do defp parse_block_id(number?) do case Integer.parse(number?) do - {number, ""} -> {:num, number} + {number, ""} -> {:number, number} _ -> :error end end @@ -111,12 +111,12 @@ defmodule StarknetExplorerWeb.BlockDetailLive do res - :num -> + :number -> {query_time, res} = :timer.tc(fn -> Data.block_by_number(block_id, socket.assigns.network, false) end) Logger.debug( - "[Block Detail] Fetched block #{block_id} in #{query_time} microseconds, query took #{time} microsecond, using :num" + "[Block Detail] Fetched block #{block_id} in #{query_time} microseconds, query took #{time} microsecond, using :number" ) res From 58fa1b924385097eb9ff8d42e38f2b219ed336fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juli=C3=A1n=20Gonz=C3=A1lez=20Calder=C3=B3n?= Date: Fri, 2 Aug 2024 12:04:49 -0300 Subject: [PATCH 7/7] Prettier error message --- .../live/pages/block_detail.ex | 39 +++++++++++++------ 1 file changed, 28 insertions(+), 11 deletions(-) diff --git a/lib/starknet_explorer_web/live/pages/block_detail.ex b/lib/starknet_explorer_web/live/pages/block_detail.ex index 4c6674ec..81af81a3 100644 --- a/lib/starknet_explorer_web/live/pages/block_detail.ex +++ b/lib/starknet_explorer_web/live/pages/block_detail.ex @@ -490,19 +490,36 @@ defmodule StarknetExplorerWeb.BlockDetailLive do end @impl true + def render(assigns) + + def render(%{block: :error} = assigns) do + ~H""" +
+
404
+

Block Not Found

+

The block you are looking could not be found or is invalid

+ + Go home Go home + +
+ Error image + """ + end + def render(assigns) do ~H""" - <%= if @block == :error do %> -
-

Error: Block Not Found

-
- <% else %> -
- <%= block_detail_header(assigns) %> - <%= if @view == "transactions", do: render_tx_filter(assigns) %> - <%= render_info(assigns) %> -
- <% end %> +
+ <%= block_detail_header(assigns) %> + <%= if @view == "transactions", do: render_tx_filter(assigns) %> + <%= render_info(assigns) %> +
""" end