Skip to content

Commit 98b46c4

Browse files
committed
2025.08.08
1 parent 93ecc0c commit 98b46c4

2 files changed

Lines changed: 179 additions & 12 deletions

File tree

api/handlers.go

Lines changed: 124 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -147,22 +147,42 @@ func handleValidate(c *gin.Context) {
147147

148148
defer closeWebSocket(conn)
149149

150-
msg, err := readWebSocketMessage(conn)
151-
if err != nil {
150+
// First, try to read as a batch request
151+
var rawMsg json.RawMessage
152+
if err := conn.ReadJSON(&rawMsg); err != nil {
153+
log.Error(err)
154+
sendWsResponse(wsError, "Failed to read JSON from WebSocket connection", "0", conn)
152155
return
153156
}
154157

155-
//peerID, err := getPeerID(msg, conn)
156-
//if err != nil {
157-
// return
158-
//}
158+
// Check if it's a batch request
159+
var batchReq BatchRequest
160+
if err := json.Unmarshal(rawMsg, &batchReq); err == nil && batchReq.Type == "batch" {
161+
// Handle batch validation
162+
handleBatchValidation(batchReq, conn)
163+
return
164+
}
159165

160-
//err = connectToPeer(peerID, conn, msg)
161-
//if err != nil {
162-
// return
163-
//}
166+
// Otherwise, handle as single validation
167+
var msg message
168+
if err := json.Unmarshal(rawMsg, &msg); err != nil {
169+
log.Error(err)
170+
sendWsResponse(wsError, "Failed to parse validation request", "0", conn)
171+
return
172+
}
173+
174+
// Normalize the message to handle both uppercase and lowercase field names
175+
msg.Normalize()
176+
177+
// Process single validation
178+
processSingleValidation(&msg, conn)
179+
log.Info("Exiting handleValidate")
180+
}
164181

182+
// processSingleValidation handles a single validation request
183+
func processSingleValidation(msg *message, conn *websocket.Conn) {
165184
salt := msg.SALT
185+
var err error
166186
if salt == "" {
167187
salt, err = createRandomHash(conn)
168188
if err != nil {
@@ -187,8 +207,100 @@ func handleValidate(c *gin.Context) {
187207
if err != nil {
188208
return
189209
}
190-
sendWsResponse(status, status, formatElapsed(elapsed), conn)
191-
log.Info("Exiting handleValidate")
210+
211+
// Send response with context for honeycomb-spkcc compatibility
212+
if msg.Bn > 0 || msg.Name != "" || msg.CID != "" {
213+
sendWsResponseWithContext(status, status, formatElapsed(elapsed), msg.Name, msg.CID, msg.Bn, conn)
214+
} else {
215+
sendWsResponse(status, status, formatElapsed(elapsed), conn)
216+
}
217+
}
218+
219+
// handleBatchValidation processes multiple validation requests
220+
func handleBatchValidation(batchReq BatchRequest, conn *websocket.Conn) {
221+
results := make([]ExampleResponse, 0, len(batchReq.Validations))
222+
223+
for _, msg := range batchReq.Validations {
224+
// Normalize the message to handle both uppercase and lowercase field names
225+
msg.Normalize()
226+
salt := msg.SALT
227+
var err error
228+
if salt == "" {
229+
salt, err = createRandomHash(conn)
230+
if err != nil {
231+
results = append(results, ExampleResponse{
232+
Status: wsError,
233+
Message: "Failed to create hash",
234+
Elapsed: "0",
235+
Name: msg.Name,
236+
CID: msg.CID,
237+
Bn: msg.Bn,
238+
})
239+
continue
240+
}
241+
} else {
242+
salt = salt + msg.CID + msg.Name
243+
}
244+
245+
proofJson, err := createProofRequest(salt, msg.CID, conn, msg.Name)
246+
if err != nil {
247+
results = append(results, ExampleResponse{
248+
Status: wsError,
249+
Message: "Failed to create proof request",
250+
Elapsed: "0",
251+
Name: msg.Name,
252+
CID: msg.CID,
253+
Bn: msg.Bn,
254+
})
255+
continue
256+
}
257+
258+
err = sendProofRequest(salt, proofJson, msg.Name, conn)
259+
if err != nil {
260+
results = append(results, ExampleResponse{
261+
Status: wsError,
262+
Message: "Failed to send proof request",
263+
Elapsed: "0",
264+
Name: msg.Name,
265+
CID: msg.CID,
266+
Bn: msg.Bn,
267+
})
268+
continue
269+
}
270+
271+
status, elapsed, err := waitForProofStatus(salt, msg.CID, conn)
272+
if err != nil {
273+
results = append(results, ExampleResponse{
274+
Status: wsError,
275+
Message: "Validation timeout",
276+
Elapsed: "0",
277+
Name: msg.Name,
278+
CID: msg.CID,
279+
Bn: msg.Bn,
280+
})
281+
continue
282+
}
283+
284+
results = append(results, ExampleResponse{
285+
Status: status,
286+
Message: status,
287+
Elapsed: formatElapsed(elapsed),
288+
Name: msg.Name,
289+
CID: msg.CID,
290+
Bn: msg.Bn,
291+
})
292+
}
293+
294+
// Send batch response
295+
localdata.Lock.Lock()
296+
err := conn.WriteJSON(BatchResponse{
297+
Type: "batch",
298+
Results: results,
299+
})
300+
localdata.Lock.Unlock()
301+
if err != nil {
302+
log.Println("Error writing batch response:", err)
303+
}
192304
}
193305

194306
func handleMessaging(c *gin.Context) {

api/websocket.go

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@ type ExampleResponse struct {
1313
Status string `json:"Status"`
1414
Message string `json:"Message"`
1515
Elapsed string `json:"Elapsed"`
16+
// Add context fields for honeycomb-spkcc compatibility
17+
Name string `json:"Name,omitempty"`
18+
CID string `json:"CID,omitempty"`
19+
Bn int `json:"bn,omitempty"`
1620
}
1721

1822
var upgrader = websocket.Upgrader{
@@ -24,12 +28,46 @@ var upgrader = websocket.Upgrader{
2428
}
2529

2630
type message struct {
31+
// Support both uppercase and lowercase field names for compatibility
2732
Name string `json:"name"`
33+
NameUC string `json:"Name"` // Uppercase variant
2834
CID string `json:"cid"`
35+
CIDUC string `json:"CID"` // Uppercase variant
2936
SALT string `json:"salt"`
37+
SALTUC string `json:"SALT"` // Uppercase variant
3038
PEERID string `json:"peerid"`
3139
Page int `json:"page"`
3240
User string `json:"username"`
41+
Bn int `json:"bn,omitempty"` // Add block number for context
42+
43+
// Additional fields from honeycomb-spkcc
44+
Timestamp int64 `json:"timestamp,omitempty"`
45+
Validator string `json:"validator,omitempty"`
46+
}
47+
48+
// Normalize message fields to handle both uppercase and lowercase
49+
func (m *message) Normalize() {
50+
if m.Name == "" && m.NameUC != "" {
51+
m.Name = m.NameUC
52+
}
53+
if m.CID == "" && m.CIDUC != "" {
54+
m.CID = m.CIDUC
55+
}
56+
if m.SALT == "" && m.SALTUC != "" {
57+
m.SALT = m.SALTUC
58+
}
59+
}
60+
61+
// BatchRequest handles batch validation requests from honeycomb-spkcc
62+
type BatchRequest struct {
63+
Type string `json:"type"`
64+
Validations []message `json:"validations"`
65+
}
66+
67+
// BatchResponse for batch validation results
68+
type BatchResponse struct {
69+
Type string `json:"type"`
70+
Results []ExampleResponse `json:"results"`
3371
}
3472

3573
var wsMutex = &sync.Mutex{}
@@ -80,6 +118,23 @@ func sendWsResponse(status string, message string, elapsed string, conn *websock
80118
}
81119
}
82120

121+
// sendWsResponseWithContext sends a response with additional context for honeycomb-spkcc
122+
func sendWsResponseWithContext(status string, message string, elapsed string, name string, cid string, bn int, conn *websocket.Conn) {
123+
localdata.Lock.Lock()
124+
err := conn.WriteJSON(ExampleResponse{
125+
Status: status,
126+
Message: message,
127+
Elapsed: elapsed,
128+
Name: name,
129+
CID: cid,
130+
Bn: bn,
131+
})
132+
localdata.Lock.Unlock()
133+
if err != nil {
134+
log.Println("Error writing JSON to websocket:", err)
135+
}
136+
}
137+
83138
func sendJsonWS(conn *websocket.Conn, json gin.H) {
84139
err := conn.WriteJSON(json)
85140
if err != nil {

0 commit comments

Comments
 (0)