- Backend REST/gateway/track routes, analytics, Blockscout proxy paths. - Frontend wallet and liquidity surfaces; MetaMask token list alignment. - Deployment docs, verification scripts, address inventory updates. Check: go build ./... under backend/ (pass). Made-with: Cursor
147 lines
3.7 KiB
Go
147 lines
3.7 KiB
Go
package track1
|
|
|
|
import (
|
|
"context"
|
|
"os"
|
|
"strings"
|
|
"time"
|
|
)
|
|
|
|
func relaySnapshotStatus(relay map[string]interface{}) string {
|
|
if relay == nil {
|
|
return ""
|
|
}
|
|
if probe, ok := relay["url_probe"].(map[string]interface{}); ok {
|
|
if okValue, exists := probe["ok"].(bool); exists && !okValue {
|
|
return "down"
|
|
}
|
|
if body, ok := probe["body"].(map[string]interface{}); ok {
|
|
if status, ok := body["status"].(string); ok {
|
|
return strings.ToLower(strings.TrimSpace(status))
|
|
}
|
|
}
|
|
}
|
|
if _, ok := relay["file_snapshot_error"].(string); ok {
|
|
return "down"
|
|
}
|
|
if snapshot, ok := relay["file_snapshot"].(map[string]interface{}); ok {
|
|
if status, ok := snapshot["status"].(string); ok {
|
|
return strings.ToLower(strings.TrimSpace(status))
|
|
}
|
|
}
|
|
return ""
|
|
}
|
|
|
|
func relayNeedsAttention(relay map[string]interface{}) bool {
|
|
status := relaySnapshotStatus(relay)
|
|
switch status {
|
|
case "degraded", "stale", "stopped", "down":
|
|
return true
|
|
default:
|
|
return false
|
|
}
|
|
}
|
|
|
|
// BuildBridgeStatusData builds the inner `data` object for bridge/status and SSE payloads.
|
|
func (s *Server) BuildBridgeStatusData(ctx context.Context) map[string]interface{} {
|
|
rpc138 := strings.TrimSpace(os.Getenv("RPC_URL"))
|
|
if rpc138 == "" {
|
|
rpc138 = "http://localhost:8545"
|
|
}
|
|
|
|
var probes []RPCProbeResult
|
|
p138 := ProbeEVMJSONRPC(ctx, "chain-138", "138", rpc138)
|
|
probes = append(probes, p138)
|
|
|
|
if eth := strings.TrimSpace(os.Getenv("ETH_MAINNET_RPC_URL")); eth != "" {
|
|
probes = append(probes, ProbeEVMJSONRPC(ctx, "ethereum-mainnet", "1", eth))
|
|
}
|
|
|
|
for _, row := range ParseExtraRPCProbes() {
|
|
name, u, ck := row[0], row[1], row[2]
|
|
probes = append(probes, ProbeEVMJSONRPC(ctx, name, ck, u))
|
|
}
|
|
|
|
overall := "operational"
|
|
if !p138.OK {
|
|
overall = "degraded"
|
|
} else {
|
|
for _, p := range probes {
|
|
if !p.OK {
|
|
overall = "degraded"
|
|
break
|
|
}
|
|
}
|
|
}
|
|
|
|
now := time.Now().UTC().Format(time.RFC3339)
|
|
chains := map[string]interface{}{
|
|
"138": map[string]interface{}{
|
|
"name": "Defi Oracle Meta Mainnet",
|
|
"status": chainStatusFromProbe(p138),
|
|
"last_sync": now,
|
|
"latency_ms": p138.LatencyMs,
|
|
"head_age_sec": p138.HeadAgeSeconds,
|
|
"block_number": p138.BlockNumberDec,
|
|
"endpoint": p138.Endpoint,
|
|
"probe_error": p138.Error,
|
|
},
|
|
}
|
|
|
|
for _, p := range probes {
|
|
if p.ChainKey != "1" && p.Name != "ethereum-mainnet" {
|
|
continue
|
|
}
|
|
chains["1"] = map[string]interface{}{
|
|
"name": "Ethereum Mainnet",
|
|
"status": chainStatusFromProbe(p),
|
|
"last_sync": now,
|
|
"latency_ms": p.LatencyMs,
|
|
"head_age_sec": p.HeadAgeSeconds,
|
|
"block_number": p.BlockNumberDec,
|
|
"endpoint": p.Endpoint,
|
|
"probe_error": p.Error,
|
|
}
|
|
break
|
|
}
|
|
|
|
probeJSON := make([]map[string]interface{}, 0, len(probes))
|
|
for _, p := range probes {
|
|
probeJSON = append(probeJSON, map[string]interface{}{
|
|
"name": p.Name,
|
|
"chainKey": p.ChainKey,
|
|
"endpoint": p.Endpoint,
|
|
"ok": p.OK,
|
|
"latencyMs": p.LatencyMs,
|
|
"blockNumber": p.BlockNumber,
|
|
"blockNumberDec": p.BlockNumberDec,
|
|
"headAgeSeconds": p.HeadAgeSeconds,
|
|
"error": p.Error,
|
|
})
|
|
}
|
|
|
|
data := map[string]interface{}{
|
|
"status": overall,
|
|
"chains": chains,
|
|
"rpc_probe": probeJSON,
|
|
"checked_at": now,
|
|
}
|
|
if ov := readOptionalVerifyJSON(); ov != nil {
|
|
data["operator_verify"] = ov
|
|
}
|
|
if relays := FetchCCIPRelayHealths(ctx); relays != nil {
|
|
data["ccip_relays"] = relays
|
|
if ccip := primaryRelayHealth(relays); ccip != nil {
|
|
data["ccip_relay"] = ccip
|
|
}
|
|
for _, value := range relays {
|
|
relay, ok := value.(map[string]interface{})
|
|
if ok && relayNeedsAttention(relay) {
|
|
data["status"] = "degraded"
|
|
break
|
|
}
|
|
}
|
|
}
|
|
return data
|
|
}
|