Skip to content

Commit a0d1afc

Browse files
author
tac0turtle
committed
fixes and addresses comments
1 parent d014f09 commit a0d1afc

File tree

5 files changed

+243
-225
lines changed

5 files changed

+243
-225
lines changed

pkg/cmd/run_node.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,9 +96,9 @@ func StartNode(
9696
return err
9797
}
9898

99+
// Resolve signer path relative to root directory if it's not an absolute path
99100
signerPath := nodeConfig.Signer.SignerPath
100101
if !filepath.IsAbs(signerPath) {
101-
// Resolve relative signer path relative to root directory
102102
signerPath = filepath.Join(nodeConfig.RootDir, signerPath)
103103
}
104104
signer, err = file.LoadFileSystemSigner(signerPath, []byte(passphrase))

pkg/cmd/run_node_test.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,12 +99,15 @@ func TestParseFlags(t *testing.T) {
9999
t.Errorf("Error: %v", err)
100100
}
101101

102+
// Convert relative path to absolute for comparison
103+
expectedRootDir, _ := filepath.Abs("custom/root/dir")
104+
102105
testCases := []struct {
103106
name string
104107
got any
105108
expected any
106109
}{
107-
{"RootDir", nodeConfig.RootDir, "custom/root/dir"},
110+
{"RootDir", nodeConfig.RootDir, expectedRootDir},
108111
{"DBPath", nodeConfig.DBPath, "custom/db/path"},
109112

110113
// P2P fields

pkg/config/config.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,13 @@ func Load(cmd *cobra.Command) (Config, error) {
320320
home, _ := cmd.Flags().GetString(FlagRootDir)
321321
if home == "" {
322322
home = DefaultRootDir
323+
} else if !filepath.IsAbs(home) {
324+
// Convert relative path to absolute path
325+
absHome, err := filepath.Abs(home)
326+
if err != nil {
327+
return Config{}, fmt.Errorf("failed to resolve home directory: %w", err)
328+
}
329+
home = absHome
323330
}
324331

325332
v := viper.New()
@@ -360,6 +367,13 @@ func LoadFromViper(inputViper *viper.Viper) (Config, error) {
360367
home := inputViper.GetString(FlagRootDir)
361368
if home == "" {
362369
home = DefaultRootDir
370+
} else if !filepath.IsAbs(home) {
371+
// Convert relative path to absolute path
372+
absHome, err := filepath.Abs(home)
373+
if err != nil {
374+
return Config{}, fmt.Errorf("failed to resolve home directory: %w", err)
375+
}
376+
home = absHome
363377
}
364378

365379
// create a new viper instance for reading the config file

pkg/rpc/server/da_visualization.go

Lines changed: 5 additions & 223 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"
@@ -14,6 +15,9 @@ import (
1415
"github.com/rs/zerolog"
1516
)
1617

18+
//go:embed templates/da_visualization.html
19+
var daVisualizationHTML string
20+
1721
// DASubmissionInfo represents information about a DA submission
1822
type DASubmissionInfo struct {
1923
ID string `json:"id"`
@@ -446,228 +450,6 @@ func (s *DAVisualizationServer) handleDAVisualizationHTML(w http.ResponseWriter,
446450
submissions[i], submissions[j] = submissions[j], submissions[i]
447451
}
448452

449-
tmpl := `
450-
<!DOCTYPE html>
451-
<html>
452-
<head>
453-
<title>Evolve DA Layer Visualization</title>
454-
<style>
455-
body { font-family: Arial, sans-serif; margin: 20px; }
456-
.header { background-color: #f5f5f5; padding: 20px; border-radius: 5px; margin-bottom: 20px; }
457-
.api-section { background-color: #e8f4f8; padding: 20px; border-radius: 5px; margin-bottom: 20px; border: 1px solid #b3d9e6; }
458-
.api-endpoint { background-color: #fff; padding: 15px; margin: 10px 0; border-radius: 5px; border: 1px solid #ddd; }
459-
.api-endpoint h4 { margin: 0 0 10px 0; color: #007cba; }
460-
.api-endpoint code { background-color: #f4f4f4; padding: 4px 8px; border-radius: 3px; font-size: 14px; }
461-
.api-response { background-color: #f9f9f9; padding: 10px; margin-top: 10px; border-radius: 3px; border-left: 3px solid #007cba; }
462-
.submission { border: 1px solid #ddd; margin: 10px 0; padding: 15px; border-radius: 5px; }
463-
.success { border-left: 4px solid #4CAF50; }
464-
.error { border-left: 4px solid #f44336; }
465-
.pending { border-left: 4px solid #ff9800; }
466-
.blob-ids { margin-top: 10px; }
467-
.blob-id { background-color: #f0f0f0; padding: 2px 6px; margin: 2px; border-radius: 3px; font-family: monospace; font-size: 12px; }
468-
.meta { color: #666; font-size: 14px; }
469-
table { border-collapse: collapse; width: 100%; }
470-
th, td { border: 1px solid #ddd; padding: 8px; text-align: left; }
471-
th { background-color: #f2f2f2; }
472-
.blob-link { color: #007cba; text-decoration: none; }
473-
.blob-link:hover { text-decoration: underline; }
474-
.method { display: inline-block; padding: 2px 6px; border-radius: 3px; font-weight: bold; font-size: 12px; margin-right: 8px; }
475-
.method-get { background-color: #61b5ff; color: white; }
476-
.method-post { background-color: #49cc90; color: white; }
477-
.example-link { color: #007cba; text-decoration: none; font-size: 13px; }
478-
.example-link:hover { text-decoration: underline; }
479-
</style>
480-
</head>
481-
<body>
482-
<div class="header">
483-
<h1>DA Layer Visualization</h1>
484-
<p>Real-time view of blob submissions from the sequencer node to the Data Availability layer.</p>
485-
{{if .IsAggregator}}
486-
{{if .Submissions}}
487-
<p><strong>Recent Submissions:</strong> {{len .Submissions}} (last 100) | <strong>Last Update:</strong> {{.LastUpdate}}</p>
488-
{{else}}
489-
<p><strong>Node Type:</strong> Aggregator | <strong>Recent Submissions:</strong> 0 | <strong>Last Update:</strong> {{.LastUpdate}}</p>
490-
{{end}}
491-
{{else}}
492-
<p><strong>Node Type:</strong> Non-aggregator | This node does not submit data to the DA layer.</p>
493-
{{end}}
494-
</div>
495-
496-
{{if .IsAggregator}}
497-
<div class="api-section">
498-
<h2>Available API Endpoints</h2>
499-
500-
<div class="api-endpoint">
501-
<h4><span class="method method-get">GET</span> /da</h4>
502-
<p>Returns this HTML visualization dashboard with real-time DA submission data.</p>
503-
<p><strong>Example:</strong> <a href="/da" class="example-link">View Dashboard</a></p>
504-
</div>
505-
506-
<div class="api-endpoint">
507-
<h4><span class="method method-get">GET</span> /da/submissions</h4>
508-
<p>Returns a JSON array of the most recent DA submissions (up to 100) with metadata.</p>
509-
<p><strong>Note:</strong> Only aggregator nodes submit to the DA layer.</p>
510-
<p><strong>Example:</strong> <code>curl http://localhost:8080/da/submissions</code></p>
511-
<div class="api-response">
512-
<strong>Response:</strong>
513-
<pre>{
514-
"submissions": [
515-
{
516-
"id": "submission_1234_1699999999",
517-
"height": 1234,
518-
"blob_size": 2048,
519-
"timestamp": "2023-11-15T10:30:00Z",
520-
"gas_price": 0.000001,
521-
"status_code": "Success",
522-
"num_blobs": 1,
523-
"blob_ids": ["a1b2c3d4..."]
524-
}
525-
],
526-
"total": 42
527-
}</pre>
528-
</div>
529-
</div>
530-
531-
<div class="api-endpoint">
532-
<h4><span class="method method-get">GET</span> /da/blob?id={blob_id}</h4>
533-
<p>Returns detailed information about a specific blob including its content.</p>
534-
<p><strong>Parameters:</strong> <code>id</code> - Hexadecimal blob ID</p>
535-
<p><strong>Example:</strong> <code>curl http://localhost:8080/da/blob?id=a1b2c3d4...</code></p>
536-
<div class="api-response">
537-
<strong>Response:</strong>
538-
<pre>{
539-
"id": "a1b2c3d4...",
540-
"height": 1234,
541-
"commitment": "deadbeef...",
542-
"size": 2048,
543-
"content": "0x1234...",
544-
"content_preview": "..."
545-
}</pre>
546-
</div>
547-
</div>
548-
549-
<div class="api-endpoint">
550-
<h4><span class="method method-get">GET</span> /da/stats</h4>
551-
<p>Returns aggregated statistics about DA submissions.</p>
552-
<p><strong>Example:</strong> <code>curl http://localhost:8080/da/stats</code></p>
553-
<div class="api-response">
554-
<strong>Response:</strong>
555-
<pre>{
556-
"total_submissions": 42,
557-
"success_count": 40,
558-
"error_count": 2,
559-
"success_rate": "95.24%",
560-
"total_blob_size": 86016,
561-
"avg_blob_size": 2048,
562-
"avg_gas_price": 0.000001,
563-
"time_range": {
564-
"first": "2023-11-15T10:00:00Z",
565-
"last": "2023-11-15T10:30:00Z"
566-
}
567-
}</pre>
568-
</div>
569-
</div>
570-
571-
<div class="api-endpoint">
572-
<h4><span class="method method-get">GET</span> /da/health</h4>
573-
<p>Returns health status of the DA layer connection.</p>
574-
<p><strong>Example:</strong> <code>curl http://localhost:8080/da/health</code></p>
575-
<div class="api-response">
576-
<strong>Response:</strong>
577-
<pre>{
578-
"status": "healthy",
579-
"is_healthy": true,
580-
"connection_status": "connected",
581-
"connection_healthy": true,
582-
"metrics": {
583-
"recent_error_rate": "10.0%",
584-
"recent_errors": 1,
585-
"recent_successes": 9,
586-
"recent_sample_size": 10,
587-
"total_submissions": 42,
588-
"last_submission_time": "2023-11-15T10:30:00Z",
589-
"last_success_time": "2023-11-15T10:29:45Z",
590-
"last_error_time": "2023-11-15T10:25:00Z"
591-
},
592-
"issues": [],
593-
"timestamp": "2023-11-15T10:30:15Z"
594-
}</pre>
595-
</div>
596-
<p style="margin-top: 15px;"><strong>Health Status Values:</strong></p>
597-
<ul style="margin-left: 20px; font-size: 13px; line-height: 1.8;">
598-
<li><code>healthy</code> - System operating normally</li>
599-
<li><code>degraded</code> - Elevated error rate but still functional</li>
600-
<li><code>unhealthy</code> - Critical issues detected</li>
601-
<li><code>warning</code> - Potential issues that need attention</li>
602-
<li><code>unknown</code> - Insufficient data to determine health</li>
603-
</ul>
604-
</div>
605-
</div>
606-
{{end}}
607-
608-
{{if .IsAggregator}}
609-
<h2>Recent Submissions</h2>
610-
{{if .Submissions}}
611-
<table>
612-
<tr>
613-
<th>Timestamp</th>
614-
<th>Height</th>
615-
<th>Status</th>
616-
<th>Blobs</th>
617-
<th>Size (bytes)</th>
618-
<th>Gas Price</th>
619-
<th>Message</th>
620-
</tr>
621-
{{range .Submissions}}
622-
<tr class="{{if eq .StatusCode "Success"}}success{{else if eq .StatusCode "Error"}}error{{else}}pending{{end}}">
623-
<td>{{if not .Timestamp.IsZero}}{{.Timestamp.Format "15:04:05"}}{{else}}--:--:--{{end}}</td>
624-
<td>{{.Height}}</td>
625-
<td>{{.StatusCode}}</td>
626-
<td>
627-
{{.NumBlobs}}
628-
{{if .BlobIDs}}
629-
<div class="blob-ids">
630-
{{range .BlobIDs}}
631-
<a href="/da/blob?id={{.}}" class="blob-link blob-id" title="Click to view blob details">{{slice . 0 8}}...</a>
632-
{{end}}
633-
</div>
634-
{{end}}
635-
</td>
636-
<td>{{.BlobSize}}</td>
637-
<td>{{printf "%.6f" .GasPrice}}</td>
638-
<td>{{.Message}}</td>
639-
</tr>
640-
{{end}}
641-
</table>
642-
{{else}}
643-
<p>No submissions recorded yet. This aggregator node has not submitted any data to the DA layer yet.</p>
644-
{{end}}
645-
{{else}}
646-
<h2>Node Information</h2>
647-
<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>
648-
<p>Only aggregator nodes that actively produce blocks and submit data to the DA layer will display this information.</p>
649-
{{end}}
650-
651-
<div style="margin-top: 30px; padding-top: 20px; border-top: 1px solid #ddd; color: #666;">
652-
<p><em>Auto-refresh: <span id="countdown">30</span>s</em> | <a href="javascript:location.reload()" style="color: #007cba;">Refresh Now</a></p>
653-
</div>
654-
655-
<script>
656-
// Auto-refresh page every 30 seconds
657-
let countdown = 30;
658-
const countdownEl = document.getElementById('countdown');
659-
setInterval(() => {
660-
countdown--;
661-
countdownEl.textContent = countdown;
662-
if (countdown <= 0) {
663-
location.reload();
664-
}
665-
}, 1000);
666-
</script>
667-
</body>
668-
</html>
669-
`
670-
671453
t, err := template.New("da").Funcs(template.FuncMap{
672454
"slice": func(s string, start, end int) string {
673455
if end > len(s) {
@@ -690,7 +472,7 @@ func (s *DAVisualizationServer) handleDAVisualizationHTML(w http.ResponseWriter,
690472
return 0
691473
}
692474
},
693-
}).Parse(tmpl)
475+
}).Parse(daVisualizationHTML)
694476

695477
if err != nil {
696478
s.logger.Error().Err(err).Msg("Failed to parse template")

0 commit comments

Comments
 (0)