Implement controller
This commit is contained in:
parent
085d2afd06
commit
7470fbfa66
121
internal/controller/controller.go
Normal file
121
internal/controller/controller.go
Normal file
|
|
@ -0,0 +1,121 @@
|
|||
package controller
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"hash-of-wisdom/internal/pow/challenge"
|
||||
"hash-of-wisdom/internal/protocol"
|
||||
"hash-of-wisdom/internal/quotes"
|
||||
)
|
||||
|
||||
// WisdomService defines the interface for the wisdom service
|
||||
type WisdomService interface {
|
||||
GenerateChallenge(ctx context.Context, resource string) (*challenge.Challenge, error)
|
||||
VerifySolution(ctx context.Context, solution *challenge.Solution) error
|
||||
GetQuote(ctx context.Context) (*quotes.Quote, error)
|
||||
}
|
||||
|
||||
// WisdomController handles the Word of Wisdom protocol flow
|
||||
type WisdomController struct {
|
||||
wisdomService WisdomService
|
||||
codec *protocol.Codec
|
||||
}
|
||||
|
||||
// NewWisdomController creates a new wisdom protocol controller
|
||||
func NewWisdomController(wisdomService WisdomService) *WisdomController {
|
||||
return &WisdomController{
|
||||
wisdomService: wisdomService,
|
||||
codec: protocol.NewCodec(),
|
||||
}
|
||||
}
|
||||
|
||||
// HandleMessage processes a protocol message and returns a response
|
||||
func (c *WisdomController) HandleMessage(ctx context.Context, msg *protocol.Message) (*protocol.Message, error) {
|
||||
switch msg.Type {
|
||||
case protocol.ChallengeRequest:
|
||||
return c.handleChallengeRequest(ctx, msg)
|
||||
case protocol.SolutionRequest:
|
||||
return c.handleSolutionRequest(ctx, msg)
|
||||
default:
|
||||
return c.createErrorResponse(protocol.ErrMalformedMessage,
|
||||
fmt.Sprintf("unsupported message type: 0x%02x", msg.Type))
|
||||
}
|
||||
}
|
||||
|
||||
// handleChallengeRequest processes challenge requests
|
||||
func (c *WisdomController) handleChallengeRequest(ctx context.Context, _ *protocol.Message) (*protocol.Message, error) {
|
||||
challenge, err := c.wisdomService.GenerateChallenge(ctx, "quotes")
|
||||
if err != nil {
|
||||
return c.createErrorResponse(protocol.ErrServerError, "failed to generate challenge")
|
||||
}
|
||||
|
||||
// Protocol requires direct challenge JSON (not wrapped)
|
||||
payload := (*protocol.ChallengeResponsePayload)(challenge)
|
||||
jsonData, err := json.Marshal(payload)
|
||||
if err != nil {
|
||||
return c.createErrorResponse(protocol.ErrServerError, "failed to marshal challenge")
|
||||
}
|
||||
|
||||
return &protocol.Message{
|
||||
Type: protocol.ChallengeResponse,
|
||||
Payload: jsonData,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// handleSolutionRequest processes solution requests
|
||||
func (c *WisdomController) handleSolutionRequest(ctx context.Context, msg *protocol.Message) (*protocol.Message, error) {
|
||||
// Parse solution request
|
||||
var solutionReq protocol.SolutionRequestPayload
|
||||
if err := json.Unmarshal(msg.Payload, &solutionReq); err != nil {
|
||||
return c.createErrorResponse(protocol.ErrMalformedMessage, "invalid solution format")
|
||||
}
|
||||
|
||||
// Create solution object
|
||||
solution := &challenge.Solution{
|
||||
Challenge: solutionReq.Challenge,
|
||||
Nonce: solutionReq.Nonce,
|
||||
}
|
||||
|
||||
// Verify solution
|
||||
if err := c.wisdomService.VerifySolution(ctx, solution); err != nil {
|
||||
return c.createErrorResponse(protocol.ErrInvalidSolution, "solution verification failed")
|
||||
}
|
||||
|
||||
// Get quote
|
||||
quote, err := c.wisdomService.GetQuote(ctx)
|
||||
if err != nil {
|
||||
return c.createErrorResponse(protocol.ErrServerError, "failed to get quote")
|
||||
}
|
||||
|
||||
// Protocol requires direct quote JSON (not wrapped)
|
||||
payload := (*protocol.QuoteResponsePayload)(quote)
|
||||
jsonData, err := json.Marshal(payload)
|
||||
if err != nil {
|
||||
return c.createErrorResponse(protocol.ErrServerError, "failed to marshal quote")
|
||||
}
|
||||
|
||||
return &protocol.Message{
|
||||
Type: protocol.QuoteResponse,
|
||||
Payload: jsonData,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// createErrorResponse creates a protocol error response
|
||||
func (c *WisdomController) createErrorResponse(code, message string) (*protocol.Message, error) {
|
||||
errorPayload := &protocol.ErrorResponsePayload{
|
||||
Code: code,
|
||||
Message: message,
|
||||
}
|
||||
|
||||
jsonData, err := json.Marshal(errorPayload)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to marshal error: %w", err)
|
||||
}
|
||||
|
||||
return &protocol.Message{
|
||||
Type: protocol.ErrorResponse,
|
||||
Payload: jsonData,
|
||||
}, nil
|
||||
}
|
||||
Loading…
Reference in a new issue