Skip to content

Commit 956cfdb

Browse files
committed
Review feedback
1 parent e2586b4 commit 956cfdb

File tree

2 files changed

+3
-275
lines changed

2 files changed

+3
-275
lines changed

pkg/rpc/server/da_visualization.go

Lines changed: 3 additions & 262 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package server
22

33
import (
44
"context"
5+
_ "embed"
56
"encoding/hex"
67
"encoding/json"
78
"fmt"
@@ -16,268 +17,8 @@ import (
1617
"github.com/rs/zerolog"
1718
)
1819

19-
// daVisualizationHTML contains the DA visualization dashboard template.
20-
// Inlined as a constant instead of using go:embed to avoid file-access issues
21-
// in sandboxed build environments.
22-
const daVisualizationHTML = `<!DOCTYPE html>
23-
<html>
24-
<head>
25-
<title>Evolve DA Layer Visualization</title>
26-
<style>
27-
body { font-family: Arial, sans-serif; margin: 20px; }
28-
.header { background-color: #f5f5f5; padding: 20px; border-radius: 5px; margin-bottom: 20px; }
29-
.api-section { background-color: #e8f4f8; padding: 20px; border-radius: 5px; margin-bottom: 20px; border: 1px solid #b3d9e6; }
30-
.api-endpoint { background-color: #fff; padding: 15px; margin: 10px 0; border-radius: 5px; border: 1px solid #ddd; }
31-
.api-endpoint h4 { margin: 0 0 10px 0; color: #007cba; }
32-
.api-endpoint code { background-color: #f4f4f4; padding: 4px 8px; border-radius: 3px; font-size: 14px; }
33-
.api-response { background-color: #f9f9f9; padding: 10px; margin-top: 10px; border-radius: 3px; border-left: 3px solid #007cba; }
34-
.submission { border: 1px solid #ddd; margin: 10px 0; padding: 15px; border-radius: 5px; }
35-
.success { border-left: 4px solid #4CAF50; }
36-
.error { border-left: 4px solid #f44336; }
37-
.pending { border-left: 4px solid #ff9800; }
38-
.blob-ids { margin-top: 10px; }
39-
.blob-id { background-color: #f0f0f0; padding: 2px 6px; margin: 2px; border-radius: 3px; font-family: monospace; font-size: 12px; }
40-
.meta { color: #666; font-size: 14px; }
41-
table { border-collapse: collapse; width: 100%; }
42-
th, td { border: 1px solid #ddd; padding: 8px; text-align: left; }
43-
th { background-color: #f2f2f2; }
44-
.blob-link { color: #007cba; text-decoration: none; }
45-
.blob-link:hover { text-decoration: underline; }
46-
.method { display: inline-block; padding: 2px 6px; border-radius: 3px; font-weight: bold; font-size: 12px; margin-right: 8px; }
47-
.method-get { background-color: #61b5ff; color: white; }
48-
.method-post { background-color: #49cc90; color: white; }
49-
.example-link { color: #007cba; text-decoration: none; font-size: 13px; }
50-
.example-link:hover { text-decoration: underline; }
51-
.blob-ids { margin-top: 5px; }
52-
.blob-ids-preview { display: inline; }
53-
.blob-ids-full { display: none; max-height: 200px; overflow-y: auto; margin-top: 5px; padding: 5px; background: #fafafa; border-radius: 3px; }
54-
.blob-ids-full.expanded { display: block; }
55-
.blob-toggle { background: none; border: 1px solid #007cba; color: #007cba; padding: 2px 8px; border-radius: 3px; cursor: pointer; font-size: 11px; margin-left: 5px; }
56-
.blob-toggle:hover { background: #007cba; color: white; }
57-
</style>
58-
</head>
59-
<body>
60-
<div class="header">
61-
<h1>DA Layer Visualization</h1>
62-
<p>Real-time view of blob submissions from the sequencer node to the Data Availability layer.</p>
63-
{{if .IsAggregator}}
64-
{{if .Submissions}}
65-
<p><strong>Recent Submissions:</strong> {{len .Submissions}} (last 100) | <strong>Last Update:</strong> {{.LastUpdate}}</p>
66-
{{else}}
67-
<p><strong>Node Type:</strong> Aggregator | <strong>Recent Submissions:</strong> 0 | <strong>Last Update:</strong> {{.LastUpdate}}</p>
68-
{{end}}
69-
{{else}}
70-
<p><strong>Node Type:</strong> Non-aggregator | This node does not submit data to the DA layer.</p>
71-
{{end}}
72-
</div>
73-
74-
{{if .IsAggregator}}
75-
<div class="api-section">
76-
<h2>Available API Endpoints</h2>
77-
78-
<div class="api-endpoint">
79-
<h4><span class="method method-get">GET</span> /da</h4>
80-
<p>Returns this HTML visualization dashboard with real-time DA submission data.</p>
81-
<p><strong>Example:</strong> <a href="/da" class="example-link">View Dashboard</a></p>
82-
</div>
83-
84-
<div class="api-endpoint">
85-
<h4><span class="method method-get">GET</span> /da/submissions</h4>
86-
<p>Returns a JSON array of the most recent DA submissions (up to 100) with metadata.</p>
87-
<p><strong>Note:</strong> Only aggregator nodes submit to the DA layer.</p>
88-
<p><strong>Example:</strong> <code>curl http://localhost:8080/da/submissions</code></p>
89-
<div class="api-response">
90-
<strong>Response:</strong>
91-
<pre>{
92-
"submissions": [
93-
{
94-
"id": "submission_1234_1699999999",
95-
"height": 1234,
96-
"blob_size": 2048,
97-
"timestamp": "2023-11-15T10:30:00Z",
98-
"gas_price": 0.000001,
99-
"status_code": "Success",
100-
"num_blobs": 1,
101-
"blob_ids": ["a1b2c3d4..."]
102-
}
103-
],
104-
"total": 42
105-
}</pre>
106-
</div>
107-
</div>
108-
109-
<div class="api-endpoint">
110-
<h4><span class="method method-get">GET</span> /da/blob?id={blob_id}</h4>
111-
<p>Returns detailed information about a specific blob including its content.</p>
112-
<p><strong>Parameters:</strong> <code>id</code> - Hexadecimal blob ID</p>
113-
<p><strong>Example:</strong> <code>curl http://localhost:8080/da/blob?id=a1b2c3d4...</code></p>
114-
<div class="api-response">
115-
<strong>Response:</strong>
116-
<pre>{
117-
"id": "a1b2c3d4...",
118-
"height": 1234,
119-
"commitment": "deadbeef...",
120-
"size": 2048,
121-
"content": "0x1234...",
122-
"content_preview": "..."
123-
}</pre>
124-
</div>
125-
</div>
126-
127-
<div class="api-endpoint">
128-
<h4><span class="method method-get">GET</span> /da/stats</h4>
129-
<p>Returns aggregated statistics about DA submissions.</p>
130-
<p><strong>Example:</strong> <code>curl http://localhost:8080/da/stats</code></p>
131-
<div class="api-response">
132-
<strong>Response:</strong>
133-
<pre>{
134-
"total_submissions": 42,
135-
"success_count": 40,
136-
"error_count": 2,
137-
"success_rate": "95.24%",
138-
"total_blob_size": 86016,
139-
"avg_blob_size": 2048,
140-
"avg_gas_price": 0.000001,
141-
"time_range": {
142-
"first": "2023-11-15T10:00:00Z",
143-
"last": "2023-11-15T10:30:00Z"
144-
}
145-
}</pre>
146-
</div>
147-
</div>
148-
149-
<div class="api-endpoint">
150-
<h4><span class="method method-get">GET</span> /da/health</h4>
151-
<p>Returns health status of the DA layer connection.</p>
152-
<p><strong>Example:</strong> <code>curl http://localhost:8080/da/health</code></p>
153-
<div class="api-response">
154-
<strong>Response:</strong>
155-
<pre>{
156-
"status": "healthy",
157-
"is_healthy": true,
158-
"connection_status": "connected",
159-
"connection_healthy": true,
160-
"metrics": {
161-
"recent_error_rate": "10.0%",
162-
"recent_errors": 1,
163-
"recent_successes": 9,
164-
"recent_sample_size": 10,
165-
"total_submissions": 42,
166-
"last_submission_time": "2023-11-15T10:30:00Z",
167-
"last_success_time": "2023-11-15T10:29:45Z",
168-
"last_error_time": "2023-11-15T10:25:00Z"
169-
},
170-
"issues": [],
171-
"timestamp": "2023-11-15T10:30:15Z"
172-
}</pre>
173-
<p style="margin-top: 15px;"><strong>Health Status Values:</strong></p>
174-
<ul style="margin-left: 20px; font-size: 13px; line-height: 1.8;">
175-
<li><code>healthy</code> - System operating normally</li>
176-
<li><code>degraded</code> - Elevated error rate but still functional</li>
177-
<li><code>unhealthy</code> - Critical issues detected</li>
178-
<li><code>warning</code> - Potential issues that need attention</li>
179-
<li><code>unknown</code> - Insufficient data to determine health</li>
180-
</ul>
181-
</div>
182-
</div>
183-
{{end}}
184-
185-
{{if .IsAggregator}}
186-
<h2>Recent Submissions</h2>
187-
{{if .Submissions}}
188-
<table>
189-
<tr>
190-
<th>Timestamp</th>
191-
<th>Height</th>
192-
<th>Status</th>
193-
<th>Blobs</th>
194-
<th>Size (bytes)</th>
195-
<th>Gas Price</th>
196-
<th>Message</th>
197-
</tr>
198-
{{range .Submissions}}
199-
<tr class="{{if eq .StatusCode "Success"}}success{{else if eq .StatusCode "Error"}}error{{else}}pending{{end}}">
200-
<td>{{if not .Timestamp.IsZero}}{{.Timestamp.Format "15:04:05"}}{{else}}--:--:--{{end}}</td>
201-
<td>{{.Height}}</td>
202-
<td>{{.StatusCode}}</td>
203-
<td>
204-
{{.NumBlobs}}
205-
{{if .BlobIDs}}
206-
{{$namespace := .Namespace}}
207-
{{$numBlobs := len .BlobIDs}}
208-
{{if le $numBlobs 5}}
209-
<div class="blob-ids">
210-
{{range .BlobIDs}}
211-
<a href="/da/blob?id={{.}}&namespace={{$namespace}}" class="blob-link blob-id" title="Click to view blob details">{{slice . 0 8}}...</a>
212-
{{end}}
213-
</div>
214-
{{else}}
215-
<div class="blob-ids">
216-
<span class="blob-ids-preview">
217-
{{range $i, $id := .BlobIDs}}{{if lt $i 3}}<a href="/da/blob?id={{$id}}&namespace={{$namespace}}" class="blob-link blob-id" title="Click to view blob details">{{slice $id 0 8}}...</a>{{end}}{{end}}
218-
</span>
219-
<button class="blob-toggle" onclick="toggleBlobs(this)">+{{subtract $numBlobs 3}} more</button>
220-
<div class="blob-ids-full">
221-
{{range .BlobIDs}}
222-
<a href="/da/blob?id={{.}}&namespace={{$namespace}}" class="blob-link blob-id" title="Click to view blob details">{{slice . 0 8}}...</a>
223-
{{end}}
224-
</div>
225-
</div>
226-
{{end}}
227-
{{end}}
228-
</td>
229-
<td>{{.BlobSize}}</td>
230-
<td>{{printf "%.6f" .GasPrice}}</td>
231-
<td>{{.Message}}</td>
232-
</tr>
233-
{{end}}
234-
</table>
235-
{{else}}
236-
<p>No submissions recorded yet. This aggregator node has not submitted any data to the DA layer yet.</p>
237-
{{end}}
238-
{{else}}
239-
<h2>Node Information</h2>
240-
<p>This is a non-aggregator node. Non-aggregator nodes do not submit data to the DA layer and therefore do not have submission statistics, health metrics, or DA-related API endpoints available.</p>
241-
<p>Only aggregator nodes that actively produce blocks and submit data to the DA layer will display this information.</p>
242-
{{end}}
243-
244-
<div style="margin-top: 30px; padding-top: 20px; border-top: 1px solid #ddd; color: #666;">
245-
<p><em>Auto-refresh: <span id="countdown">30</span>s</em> | <a href="javascript:location.reload()" style="color: #007cba;">Refresh Now</a></p>
246-
</div>
247-
248-
<script>
249-
// Auto-refresh page every 30 seconds
250-
let countdown = 30;
251-
const countdownEl = document.getElementById('countdown');
252-
setInterval(() => {
253-
countdown--;
254-
countdownEl.textContent = countdown;
255-
if (countdown <= 0) {
256-
location.reload();
257-
}
258-
}, 1000);
259-
260-
// Toggle blob list expansion
261-
function toggleBlobs(btn) {
262-
const container = btn.parentElement;
263-
const fullList = container.querySelector('.blob-ids-full');
264-
const preview = container.querySelector('.blob-ids-preview');
265-
const isExpanded = fullList.classList.contains('expanded');
266-
267-
if (isExpanded) {
268-
fullList.classList.remove('expanded');
269-
preview.style.display = 'inline';
270-
btn.textContent = btn.dataset.expandText;
271-
} else {
272-
fullList.classList.add('expanded');
273-
preview.style.display = 'none';
274-
btn.dataset.expandText = btn.textContent;
275-
btn.textContent = 'Show less';
276-
}
277-
}
278-
</script>
279-
</body>
280-
</html>`
20+
//go:embed templates/da_visualization.html
21+
var daVisualizationHTML string
28122

28223
// DASubmissionInfo represents information about a DA submission
28324
type DASubmissionInfo struct {

test/testda/dummy.go

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -72,19 +72,6 @@ func New(opts ...Option) *DummyDA {
7272
return d
7373
}
7474

75-
// BlobCount returns the total number of blobs stored across all heights and namespaces.
76-
func (d *DummyDA) BlobCount() int {
77-
d.mu.Lock()
78-
defer d.mu.Unlock()
79-
count := 0
80-
for _, nss := range d.blobs {
81-
for _, blobs := range nss {
82-
count += len(blobs)
83-
}
84-
}
85-
return count
86-
}
87-
8875
// Submit stores blobs and returns success or simulated failure.
8976
func (d *DummyDA) Submit(_ context.Context, data [][]byte, _ float64, namespace []byte, _ []byte) datypes.ResultSubmit {
9077
if d.failSubmit.Load() {

0 commit comments

Comments
 (0)