We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
1 parent d2c297b commit c4b5f75Copy full SHA for c4b5f75
7 files changed
explorer/lib/explorer/contract_managers/aligned_proof_aggregation_service.ex
@@ -2,6 +2,8 @@ defmodule AlignedProofAggregationService do
2
require Logger
3
4
@aligned_config_file System.get_env("ALIGNED_PROOF_AGG_CONFIG_FILE")
5
+ @verifyRisc0_solidity_signature "0x015f8668"
6
+ @verifySp1_solidity_signature "0x39c94cbf"
7
8
config_file_path =
9
case @aligned_config_file do
@@ -66,6 +68,23 @@ defmodule AlignedProofAggregationService do
66
68
end
67
69
70
71
+ # From a given aggregated proof event, it fetches the transaction
72
+ # and returns the aggregator (:sp1, :risc0) based on the function signature
73
+ def get_aggregator!(agg_proof) do
74
+ tx_hash = agg_proof.tx_hash
75
+ {:ok, tx} = Explorer.EthClient.get_transaction_by_hash(tx_hash)
76
+ input = Map.get(tx, "input")
77
+ # In solidity, the function signatures are the first 4 bytes of the input
78
+ # Note: first two characters are the 0x
79
+ function_signature = String.slice(input, 0..9)
80
+
81
+ case function_signature do
82
+ @verifyRisc0_solidity_signature -> :risc0
83
+ @verifySp1_solidity_signature -> :sp1
84
+ _ -> nil
85
+ end
86
87
88
def get_block_timestamp(block_number) do
89
case Ethers.Utils.get_block_timestamp(block_number) do
90
{:ok, timestamp} -> DateTime.from_unix!(timestamp)
explorer/lib/explorer/eth_client.ex
@@ -6,6 +6,10 @@ defmodule Explorer.EthClient do
eth_send("eth_getBlockByNumber", [block_number, false])
+ def get_transaction_by_hash(tx_hash) do
10
+ eth_send("eth_getTransactionByHash", [tx_hash])
11
12
13
defp eth_send(method, params, id \\ 1) do
14
headers = [{"Content-Type", "application/json"}]
15
body = Jason.encode!(%{jsonrpc: "2.0", method: method, params: params, id: id})
@@ -15,9 +19,14 @@ defmodule Explorer.EthClient do
19
case response do
16
20
{:ok, %Finch.Response{status: 200, body: body}} ->
17
21
case Jason.decode(body) do
18
- {:ok, %{error: error} = _} -> {:error, error.message}
- {:ok, body} -> {:ok, Map.get(body, "result")}
- {:error, _} -> {:error, :invalid_json}
22
+ {:ok, %{"error" => %{"message" => message}}} ->
23
+ {:error, message}
24
25
+ {:ok, body} ->
26
+ {:ok, Map.get(body, "result")}
27
28
+ {:error, _} ->
29
+ {:error, :invalid_json}
30
31
32
{:ok, %Finch.Response{status: status}} ->
explorer/lib/explorer/models/aggregated_proofs.ex
@@ -12,6 +12,7 @@ defmodule AggregatedProofs do
field(:block_timestamp, :utc_datetime)
field(:tx_hash, :string)
field(:number_of_proofs, :integer)
+ field(:aggregator, Ecto.Enum, values: [:sp1, :risc0])
has_many(:proofs_agg_mode, AggregationModeProof,
foreign_key: :agg_proof_id,
@@ -33,7 +34,8 @@ defmodule AggregatedProofs do
33
34
:block_number,
35
:block_timestamp,
36
:tx_hash,
- :number_of_proofs
37
+ :number_of_proofs,
38
+ :aggregator
39
])
40
|> validate_required([
41
:merkle_root,
explorer/lib/explorer/periodically.ex
@@ -113,8 +113,11 @@ defmodule Explorer.Periodically do
113
proofs
114
|> Enum.zip(proof_hashes)
115
|> Enum.map(fn {agg_proof, hashes} ->
116
+ aggregator = AlignedProofAggregationService.get_aggregator!(agg_proof)
117
118
agg_proof =
119
agg_proof
120
+ |> Map.merge(%{aggregator: aggregator})
121
|> Map.merge(%{number_of_proofs: length(hashes)})
122
123
{:ok, %{id: id}} = AggregatedProofs.insert_or_update(agg_proof)
explorer/lib/explorer_web/components/agg_proofs_table.ex
@@ -44,7 +44,34 @@ defmodule ExplorerWeb.AggProofsTable do
44
<:col :let={proof} label="Number of proofs">
45
<%= proof.number_of_proofs |> Helpers.format_number() %>
46
</:col>
47
48
+ <:col :let={proof} label="Aggregator">
49
+ <%= case proof.aggregator do %>
50
+ <% :sp1 -> %>
51
+ <.sp1_badge />
52
+ <% :risc0 -> %>
53
+ <.risc0_badge />
54
+ <% _ -> %>
55
+ <span>Unknown</span>
56
+ <% end %>
57
+ </:col>
58
</.table>
59
"""
60
61
62
+ defp sp1_badge(assigns) do
63
+ ~H"""
64
+ <div class="rounded-full p-1 px-5 border w-fit" style="border-color: #FE11C5">
65
+ <p style="color: #FE11C5">SP1</p>
+ </div>
+ """
+ defp risc0_badge(assigns) do
+ <div class="rounded-full p-1 px-5 w-fit" style="background-color: #FEFF9D">
+ <p class="text-black">RISC0</p>
explorer/lib/explorer_web/live/pages/agg_proof/index.html.heex
@@ -22,6 +22,18 @@
</p>
</div>
+ <div>
+ <h3>
+ Aggregator:
+ </h3>
+ <%= case @agg_proof.aggregator do %>
+ <p>SP1</p>
+ <p>RISC0</p>
<div>
<h3>
Number of Proofs included:
@@ -110,7 +122,7 @@
110
<div class="flex flex-col space-y-6 justify-center grow relative text-center md:pt-14">
111
<h1 class="text-5xl font-semibold">Oops!</h1>
112
124
<h2 class="text-xl font-medium">
- The batch you are looking for <br /> doesn't exist.
125
+ The aggregated proof you are looking for <br /> doesn't exist.
126
</h2>
127
<img
128
class="z-0 w-64 rounded-xl mx-auto"
explorer/priv/repo/migrations/20250428144500_add_aggegator_to_agg_proofs.exs
@@ -0,0 +1,9 @@
1
+defmodule Explorer.Repo.Migrations.AddAggregatorToAggProofs do
+ use Ecto.Migration
+ def change do
+ alter table(:aggregated_proofs) do
+ add(:aggregator, :string, default: nil)
+end
0 commit comments