Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions explorer/lib/explorer/models/aggregated_proofs.ex
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,18 @@ defmodule AggregatedProofs do
Explorer.Repo.get_by(AggregatedProofs, id: id)
end

def get_newest_aggregated_proof_by_merkle_root(merkle_root) do
query =
from(proof in AggregatedProofs,
order_by: [desc: proof.block_number],
limit: 1,
where: proof.merkle_root == ^merkle_root,
select: proof
)

Explorer.Repo.one(query)
end

def get_paginated_proofs(%{page: page, page_size: size}) do
query =
from(proof in AggregatedProofs,
Expand Down
12 changes: 12 additions & 0 deletions explorer/lib/explorer/models/aggregation_mode_proof.ex
Original file line number Diff line number Diff line change
Expand Up @@ -58,4 +58,16 @@ defmodule AggregationModeProof do

Explorer.Repo.all(query)
end

def get_newest_proof_by_hash(hash) do
query =
from(proof in AggregationModeProof,
limit: 1,
order_by: [desc: proof.inserted_at],
where: proof.proof_hash == ^hash,
select: proof
)

Explorer.Repo.one(query)
end
end
34 changes: 25 additions & 9 deletions explorer/lib/explorer_web/components/search.ex
Original file line number Diff line number Diff line change
@@ -1,24 +1,40 @@
defmodule SearchComponent do
require Logger
use ExplorerWeb, :live_component

@impl true
def handle_event("search_batch", %{"batch" => %{"merkle_root" => input_hash}}, socket) do
input_hash
def handle_event("search_batch", %{"search" => search}, socket) do
search
|> (fn hash ->
if String.match?(hash, ~r/^0x[a-fA-F0-9]+$/), do: {:ok, hash}, else: :invalid_hash
end).()
|> case do
{:ok, hash} ->
case Proofs.get_number_of_batches_containing_proof(hash) do
0 -> {:noreply, push_navigate(socket, to: ~p"/batches/#{hash}")}
_ -> {:noreply, push_navigate(socket, to: ~p"/search?q=#{hash}")}
cond do
# See if the hash belongs to a proof
Proofs.get_number_of_batches_containing_proof(hash) > 0 ->
{:noreply, push_navigate(socket, to: ~p"/batches/#{hash}")}

# See if the hash belongs to an aggregated proof merkle root
(proof = AggregatedProofs.get_newest_aggregated_proof_by_merkle_root(hash)) != nil ->
Logger.debug(proof)
{:noreply, push_navigate(socket, to: ~p"/aggregated_proofs/#{proof.id}")}

# Finally, see if the hash belongs to a proof of an aggregated proof
(proof = AggregationModeProof.get_newest_proof_by_hash(hash)) != nil ->
{:noreply, push_navigate(socket, to: ~p"/aggregated_proofs/#{proof.agg_proof_id}")}

# Otherwise inform the user nothing was found
true ->
{:noreply,
socket
|> put_flash!(:error, "No batch or proof was found with the provided hash.")}
end

:invalid_hash ->
{:noreply,
socket
|> assign(batch_merkle_root: input_hash)
|> put_flash!(:error, "Please enter a valid proof batch hash (0x69...).")}
|> put_flash!(:error, "Please enter a valid hash (0x69...).")}
end
end

Expand All @@ -42,8 +58,8 @@ defmodule SearchComponent do
id={"input_#{assigns.id}"}
class="pr-10 w-full text-foreground rounded-lg border-foreground/20 bg-card focus:border-foreground/20 focus:ring-accent text-sm"
type="search"
placeholder="Search batch by batch hash or proof hash"
name="batch[merkle_root]"
placeholder="Search by batch hash or proof hash"
name="search"
/>
<.icon name="hero-magnifying-glass-solid" class="absolute right-3 text-foreground/20 size-5 hover:text-foreground" />
</form>
Expand Down
2 changes: 1 addition & 1 deletion explorer/mix.lock
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
"floki": {:hex, :floki, "0.36.2", "a7da0193538c93f937714a6704369711998a51a6164a222d710ebd54020aa7a3", [:mix], [], "hexpm", "a8766c0bc92f074e5cb36c4f9961982eda84c5d2b8e979ca67f5c268ec8ed580"},
"gettext": {:hex, :gettext, "0.24.0", "6f4d90ac5f3111673cbefc4ebee96fe5f37a114861ab8c7b7d5b30a1108ce6d8", [:mix], [{:expo, "~> 0.5.1", [hex: :expo, repo: "hexpm", optional: false]}], "hexpm", "bdf75cdfcbe9e4622dd18e034b227d77dd17f0f133853a1c73b97b3d6c770e8b"},
"hackney": {:hex, :hackney, "1.20.1", "8d97aec62ddddd757d128bfd1df6c5861093419f8f7a4223823537bad5d064e2", [:rebar3], [{:certifi, "~> 2.12.0", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "~> 6.1.0", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "~> 1.0.0", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "~> 1.1", [hex: :mimerl, repo: "hexpm", optional: false]}, {:parse_trans, "3.4.1", [hex: :parse_trans, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "~> 1.1.0", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}, {:unicode_util_compat, "~> 0.7.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "fe9094e5f1a2a2c0a7d10918fee36bfec0ec2a979994cff8cfe8058cd9af38e3"},
"heroicons": {:git, "https://github.com/tailwindlabs/heroicons.git", "88ab3a0d790e6a47404cba02800a6b25d2afae50", [tag: "v2.1.1", sparse: "optimized"]},
"heroicons": {:git, "https://github.com/tailwindlabs/heroicons.git", "88ab3a0d790e6a47404cba02800a6b25d2afae50", [tag: "v2.1.1", sparse: "optimized", depth: 1]},
"hpax": {:hex, :hpax, "0.2.0", "5a58219adcb75977b2edce5eb22051de9362f08236220c9e859a47111c194ff5", [:mix], [], "hexpm", "bea06558cdae85bed075e6c036993d43cd54d447f76d8190a8db0dc5893fa2f1"},
"httpoison": {:hex, :httpoison, "2.2.1", "87b7ed6d95db0389f7df02779644171d7319d319178f6680438167d7b69b1f3d", [:mix], [{:hackney, "~> 1.17", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm", "51364e6d2f429d80e14fe4b5f8e39719cacd03eb3f9a9286e61e216feac2d2df"},
"idna": {:hex, :idna, "6.1.1", "8a63070e9f7d0c62eb9d9fcb360a7de382448200fbbd1b106cc96d3d8099df8d", [:rebar3], [{:unicode_util_compat, "~> 0.7.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "92376eb7894412ed19ac475e4a86f7b413c1b9fbb5bd16dccd57934157944cea"},
Expand Down
Loading